1
0

DB.Cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. #include "main.h"
  2. #include "cddb.h"
  3. #include "../Winamp/wa_ipc.h"
  4. #include "../nu/AutoChar.h"
  5. #include "../nu/AutoWide.h"
  6. #include "api__in_cdda.h"
  7. #include <api/service/waservicefactory.h>
  8. #include <shlwapi.h>
  9. #include <atlbase.h>
  10. #include "resource.h"
  11. #include <commctrl.h>
  12. #include <strsafe.h>
  13. char config_use_cddb = 1;
  14. #define MAX_CACHE_SIZE 8
  15. typedef struct _CBDATA
  16. {
  17. DINFO *ps;
  18. CHAR cLetter;
  19. DWORD cddbid;
  20. } CBDATA;
  21. typedef struct _CACHEREC
  22. {
  23. DINFO discInfo;
  24. HRESULT result;
  25. } CACHEREC;
  26. static CACHEREC cddb_cache[MAX_CACHE_SIZE];
  27. static int cddb_cache_cursor = 0;
  28. void DefaultValues(DINFO *ps)
  29. {
  30. ps->Reset();
  31. ps->compilation = false;
  32. ps->discnum = 0;
  33. ps->numdiscs = 0;
  34. ps->populated = true;
  35. }
  36. static bool IsInternetAvailable()
  37. {
  38. return !!SendMessage(line.hMainWindow, WM_WA_IPC, 0, IPC_INETAVAILABLE);
  39. }
  40. static DWORD failid[26] ={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  41. #define WRITEINFO(obj, field, name) { obj->get_ ## field(&str); fwprintf(fp, name L": %s\r\n", str.m_str); }
  42. #define WRITEINFO_LONG(obj, field, name) { long val; obj->get_ ## field(&val); fwprintf(fp, name L": %d\r\n", val); }
  43. #ifndef IGNORE_API_GRACENOTE
  44. static void DumpInfoFile(ICddbDiscPtr disc)
  45. {
  46. #if 0 // keep this code, but we'll wait until a later version to implement more data
  47. long numTracks;
  48. FILE *fp = fopen("c:\\cdinfo.txt", "wt");
  49. // wchar_t BOM[] = {0xFEFF, 0};
  50. // fwrite(BOM, 2, 1, fp);
  51. CComBSTR str;
  52. WRITEINFO(disc, Toc, L"Disc TOC");
  53. WRITEINFO(disc, Artist, L"Disc Artist");
  54. WRITEINFO(disc, Title, L"Disc Title");
  55. WRITEINFO(disc, Label, L"Disc Label");
  56. WRITEINFO(disc, Year, L"Disc Year");
  57. WRITEINFO(disc, MediaId, L"Disc MediaId");
  58. WRITEINFO(disc, Notes, L"Disc Notes");
  59. WRITEINFO(disc, GenreId, L"Disc GenreId");
  60. WRITEINFO(disc, SecondaryGenreId, L"Disc Secondary GenreId");
  61. WRITEINFO(disc, RegionId, L"Disc RegionId");
  62. WRITEINFO(disc, Revision, L"Disc Revision");
  63. WRITEINFO(disc, TotalInSet, L"Disc Discs");
  64. WRITEINFO(disc, NumberInSet, L"Disc Disc #");
  65. WRITEINFO(disc, LanguageId, L"Disc Language Id");
  66. WRITEINFO(disc, RevisionTag, L"Disc Revision Tag");
  67. WRITEINFO_LONG(disc, Compilation, L"Disc Compilation");
  68. ICddbDisc2 *disc2;
  69. disc->QueryInterface(&disc2);
  70. WRITEINFO(disc2, ReleaseDate, L"Disc Release Date");
  71. WRITEINFO(disc2, RecordingDate, L"Disc Recording Date");
  72. WRITEINFO(disc2, ProductCode, L"Disc Product Code");
  73. WRITEINFO(disc2, YearComposed, L"Disc Year Composed");
  74. disc2->Release();
  75. ICddbCredits *credits;
  76. disc->get_Credits(&credits);
  77. long creditCount;
  78. credits->get_Count(&creditCount);
  79. for (long c = 0;c < creditCount;c++)
  80. {
  81. ICddbCredit *credit;
  82. credits->GetCredit(c + 1, &credit);
  83. WRITEINFO(credit, Id, L"Credit ID");
  84. WRITEINFO(credit, Name, L"Credit Name");
  85. WRITEINFO(credit, Notes, L"Credit Notes");
  86. credit->Release();
  87. }
  88. credits->Release();
  89. ICddbTracks *tracks;
  90. disc->get_Tracks(&tracks);
  91. tracks->get_Count(&numTracks);
  92. for (int i = 0;i < numTracks;i++)
  93. {
  94. ICddbTrack *track;
  95. tracks->GetTrack(i + 1, &track);
  96. fputws(L"-----------------\r\n", fp);
  97. WRITEINFO(track, Title, L"Track Title");
  98. WRITEINFO(track, Artist, L"Track Artist");
  99. WRITEINFO(track, Year, L"Track Year");
  100. WRITEINFO(track, Label, L"Track Label");
  101. WRITEINFO(track, Notes, L"Track Notes");
  102. WRITEINFO(track, GenreId, L"Track GenreId");
  103. WRITEINFO(track, SecondaryGenreId, L"Track SecondaryGenreId");
  104. WRITEINFO(track, Lyrics, L"Track Lyrics");
  105. WRITEINFO(track, BeatsPerMinute, L"Track BPM");
  106. WRITEINFO(track, ISRC, L"Track ISRC");
  107. ICddbTrack2 *track2;
  108. track->QueryInterface(&track2);
  109. WRITEINFO(track2, ReleaseDate, L"Release Date");
  110. WRITEINFO(track2, RecordingDate, L"Recording Date");
  111. WRITEINFO(track2, YearComposed, L"Year Composed");
  112. track2->Release();
  113. ICddbCredits *credits;
  114. track->get_Credits(&credits);
  115. if (credits)
  116. {
  117. long creditCount;
  118. credits->get_Count(&creditCount);
  119. for (long c = 0;c < creditCount;c++)
  120. {
  121. ICddbCredit *credit;
  122. credits->GetCredit(c + 1, &credit);
  123. WRITEINFO(credit, Id, L"Credit ID");
  124. WRITEINFO(credit, Name, L"Credit Name");
  125. WRITEINFO(credit, Notes, L"Credit Notes");
  126. credit->Release();
  127. }
  128. credits->Release();
  129. }
  130. track->Release();
  131. }
  132. tracks->Release();
  133. fclose(fp);
  134. #endif
  135. }
  136. #endif
  137. #ifdef IGNORE_API_GRACENOTE
  138. static HRESULT CALLBACK Cddb_ResultCallback(HRESULT result, ICddbDisc *pDisc, DWORD *pdwAutoCloseDelay, ULONG_PTR user)
  139. {
  140. int index;
  141. CACHEREC *pRec;
  142. CBDATA *pData = (CBDATA*)user;
  143. if (!pData) return E_POINTER;
  144. DINFO *pDI = NULL;
  145. for (index = 0, pRec = &cddb_cache[0]; index < MAX_CACHE_SIZE && 0 != pRec->discInfo.CDDBID; pRec++, index++)
  146. {
  147. if (pRec->discInfo.CDDBID == pData->cddbid)
  148. {
  149. pDI = &pRec->discInfo;
  150. break;
  151. }
  152. }
  153. if (!pDI) return S_OK;
  154. if (S_OK == result)
  155. {
  156. #ifndef IGNORE_API_GRACENOTE
  157. if (pDisc)
  158. {
  159. DumpInfoFile(pDisc);
  160. GetDiscInfo(pDisc, pDI);
  161. StoreDisc(pDI->CDDBID, pDisc);
  162. ICddbCacheManager* pCache;
  163. HRESULT hr = Cddb_GetICacheManger((void**)&pCache);
  164. if (SUCCEEDED(hr))
  165. {
  166. CComBSTR toc;
  167. pDisc->get_Toc(&toc);
  168. pCache->StoreDiscByToc(toc, pDisc);
  169. pCache->Release();
  170. }
  171. pDI->populated = true;
  172. }
  173. #endif
  174. }
  175. else
  176. {
  177. #ifndef IGNORE_API_GRACENOTE
  178. if (DoCDText(pDI, pData->cLetter))
  179. {
  180. StoreCDText(pDI->CDDBID, pData->cLetter);
  181. result = S_OK;
  182. }
  183. #endif
  184. }
  185. CddbCache_SetDisc(pDI, result);
  186. if (pData->ps->CDDBID == pDI->CDDBID)
  187. {
  188. *pData->ps = *pDI;
  189. }
  190. return S_OK;
  191. }
  192. #endif
  193. void InitializeCddbCache(void)
  194. {
  195. ZeroMemory(cddb_cache, sizeof(CACHEREC)*MAX_CACHE_SIZE);
  196. cddb_cache_cursor = 0;
  197. }
  198. void UninitializeCddbCache(void)
  199. {
  200. ZeroMemory(cddb_cache, sizeof(CACHEREC)*MAX_CACHE_SIZE);
  201. cddb_cache_cursor = 0;
  202. }
  203. HRESULT CddbCache_SetDisc(DINFO *pDiscInfo, HRESULT lookupResult)
  204. {
  205. int index;
  206. CACHEREC *pRec;
  207. if (!pDiscInfo || 0 == pDiscInfo->CDDBID) return E_FAIL;
  208. for (index = 0, pRec = &cddb_cache[0]; index < MAX_CACHE_SIZE && 0 != pRec->discInfo.CDDBID; pRec++, index++)
  209. {
  210. if (pRec->discInfo.CDDBID == pDiscInfo->CDDBID) break;
  211. }
  212. if (0 == pRec->discInfo.CDDBID || MAX_CACHE_SIZE == index)
  213. {
  214. pRec = &cddb_cache[cddb_cache_cursor];
  215. cddb_cache_cursor++;
  216. if (cddb_cache_cursor >= MAX_CACHE_SIZE) cddb_cache_cursor = 0;
  217. }
  218. if (pRec)
  219. {
  220. pRec->result = lookupResult;
  221. pRec->discInfo = *pDiscInfo;
  222. }
  223. return S_OK;
  224. }
  225. int GetCDDBInfo(DINFO *ps, wchar_t device)
  226. {
  227. int index;
  228. CACHEREC *pRec;
  229. //HRESULT hr;
  230. //wchar_t szTOC[2048] = {0};
  231. if (ps->populated) return 0;
  232. /* first, look in our memory cache */
  233. for (index = 0, pRec = &cddb_cache[0]; index < MAX_CACHE_SIZE && 0 != pRec->discInfo.CDDBID; pRec++, index++)
  234. {
  235. if (pRec->discInfo.CDDBID == ps->CDDBID)
  236. {
  237. if (S_OK == pRec->result)
  238. *ps = pRec->discInfo;
  239. else
  240. DefaultValues(ps);
  241. return 0; // no need to notify about changes
  242. }
  243. }
  244. /* look it up in the local database */
  245. if (QueryDINFO(ps->CDDBID, ps))
  246. {
  247. CddbCache_SetDisc(ps, S_OK);
  248. return 0;
  249. }
  250. /* check CDDB & CD-Text */
  251. /*CddbCache_SetDisc(ps, E_PENDING);
  252. if (Cddb_CalculateTOC(ps, szTOC, sizeof(szTOC)/sizeof(wchar_t)))
  253. {
  254. ULONG flags;
  255. CBDATA data;
  256. data.ps = ps;
  257. data.cLetter = device;
  258. data.cddbid = ps->CDDBID;
  259. flags = CDDB_UI_MODAL | CDDB_UI_MULTIPLE | CDDB_UI_NOMATCH;
  260. if (!config_use_cddb || !IsInternetAvailable()) flags |= CDDB_NOINET;
  261. hr = Cddb_DoLookup(szTOC, line.hMainWindow, Cddb_ResultCallback, flags, (ULONG_PTR)&data);
  262. if (FAILED(hr)) Cddb_DisplayResultDlg(line.hMainWindow, hr, AUTOCLOSE_NEVER, flags);
  263. }
  264. else hr = CDDB_E_BADTOC;
  265. if (FAILED(hr)) CddbCache_SetDisc(ps, hr);*/
  266. return 1;//SUCCEEDED(hr);
  267. }