nde_cd.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720
  1. #include "../nde/nde_c.h"
  2. #include "main.h"
  3. #include <shlwapi.h>
  4. #include "../nu/AutoLock.h"
  5. #include "../nu/AutoWide.h"
  6. #include "cddbinterface.h"
  7. #include "cddb.h"
  8. #include "api__in_cdda.h"
  9. #include <api/service/waservicefactory.h>
  10. #include <atlbase.h>
  11. #include <strsafe.h>
  12. using namespace Nullsoft::Utility;
  13. static nde_database_t discDB=0;
  14. static nde_table_t discTable=0, trackTable=0;
  15. static Nullsoft::Utility::LockGuard dbcs;
  16. static int g_dirty;
  17. enum
  18. {
  19. NDE_CD_SUCCESS=0,
  20. NDE_CD_FAILURE=1,
  21. };
  22. enum
  23. {
  24. DISCTABLE_ID_DISCID = 0,
  25. DISCTABLE_ID_ALBUM=1,
  26. DISCTABLE_ID_ARTIST=2,
  27. DISCTABLE_ID_TUID=3,
  28. DISCTABLE_ID_YEAR=4,
  29. DISCTABLE_ID_GENRE=5,
  30. DISCTABLE_ID_COMMENT=6,
  31. DISCTABLE_ID_DISC=7,
  32. DISCTABLE_ID_COMPOSER=8,
  33. DISCTABLE_ID_PUBLISHER=9,
  34. DISCTABLE_ID_CONDUCTOR=10,
  35. DISCTABLE_ID_REMIXING=10,
  36. };
  37. enum
  38. {
  39. TRACKTABLE_ID_DISCID = 0,
  40. TRACKTABLE_ID_TRACK = 1,
  41. TRACKTABLE_ID_ARTIST=2,
  42. TRACKTABLE_ID_TITLE=3,
  43. TRACKTABLE_ID_TAGID=4,
  44. TRACKTABLE_ID_COMPOSER=5,
  45. TRACKTABLE_ID_CONDUCTOR=6,
  46. TRACKTABLE_ID_EXTENDED_DATA=7,
  47. TRACKTABLE_ID_REMIXING=8,
  48. TRACKTABLE_ID_ISRC=9,
  49. };
  50. static void CreateDiscFields(nde_table_t table)
  51. {
  52. // create defaults
  53. NDE_Table_NewColumnW(table, DISCTABLE_ID_DISCID, L"discid", FIELD_INTEGER);
  54. NDE_Table_NewColumnW(table, DISCTABLE_ID_ALBUM, L"title", FIELD_STRING);
  55. NDE_Table_NewColumnW(table, DISCTABLE_ID_ARTIST, L"artist", FIELD_STRING);
  56. NDE_Table_NewColumnW(table, DISCTABLE_ID_TUID, L"tuid", FIELD_STRING);
  57. NDE_Table_NewColumnW(table, DISCTABLE_ID_YEAR, L"year", FIELD_STRING);
  58. NDE_Table_NewColumnW(table, DISCTABLE_ID_GENRE, L"genre", FIELD_STRING);
  59. NDE_Table_NewColumnW(table, DISCTABLE_ID_COMMENT, L"comment", FIELD_STRING);
  60. NDE_Table_NewColumnW(table, DISCTABLE_ID_DISC, L"disc", FIELD_STRING);
  61. NDE_Table_NewColumnW(table, DISCTABLE_ID_COMPOSER, L"composer", FIELD_STRING);
  62. NDE_Table_NewColumnW(table, DISCTABLE_ID_PUBLISHER, L"publisher", FIELD_STRING);
  63. NDE_Table_NewColumnW(table, DISCTABLE_ID_CONDUCTOR, L"conductor", FIELD_STRING);
  64. NDE_Table_NewColumnW(table, DISCTABLE_ID_REMIXING, L"remixing", FIELD_STRING);
  65. NDE_Table_PostColumns(table);
  66. NDE_Table_AddIndexByIDW(table, DISCTABLE_ID_DISCID, L"discid");
  67. }
  68. static void CreateTrackFields(nde_table_t table)
  69. {
  70. // create defaults
  71. NDE_Table_NewColumnW(table, TRACKTABLE_ID_DISCID, L"discid", FIELD_INTEGER);
  72. NDE_Table_NewColumnW(table, TRACKTABLE_ID_TRACK, L"track", FIELD_INTEGER);
  73. NDE_Table_NewColumnW(table, TRACKTABLE_ID_ARTIST, L"artist", FIELD_STRING);
  74. NDE_Table_NewColumnW(table, TRACKTABLE_ID_TITLE, L"title", FIELD_STRING);
  75. NDE_Table_NewColumnW(table, TRACKTABLE_ID_TAGID, L"tagid", FIELD_STRING);
  76. NDE_Table_NewColumnW(table, TRACKTABLE_ID_COMPOSER, L"composer", FIELD_STRING);
  77. NDE_Table_NewColumnW(table, TRACKTABLE_ID_CONDUCTOR, L"conductor", FIELD_STRING);
  78. NDE_Table_NewColumnW(table, TRACKTABLE_ID_EXTENDED_DATA, L"extendeddata", FIELD_STRING);
  79. NDE_Table_NewColumnW(table, TRACKTABLE_ID_REMIXING, L"remixing", FIELD_STRING);
  80. NDE_Table_NewColumnW(table, TRACKTABLE_ID_ISRC, L"ISRC", FIELD_STRING);
  81. NDE_Table_PostColumns(table);
  82. NDE_Table_AddIndexByIDW(table, TRACKTABLE_ID_DISCID, L"discid");
  83. NDE_Table_AddIndexByIDW(table, TRACKTABLE_ID_TRACK, L"track");
  84. }
  85. static int OpenDiscDatabase()
  86. {
  87. AutoLock lock(dbcs);
  88. if (!discDB)
  89. {
  90. discDB = NDE_CreateDatabase();
  91. }
  92. return NDE_CD_SUCCESS;
  93. }
  94. static int OpenDiscTable()
  95. {
  96. AutoLock lock(dbcs);
  97. int ret = OpenDiscDatabase();
  98. if (ret != NDE_CD_SUCCESS)
  99. {
  100. return ret;
  101. }
  102. if (!discTable)
  103. {
  104. const wchar_t *inidir = WASABI_API_APP->path_getUserSettingsPath();
  105. wchar_t discTablePath[MAX_PATH] = {0}, discIndexPath[MAX_PATH] = {0};
  106. PathCombineW(discTablePath, inidir, L"plugins");
  107. PathAppendW(discTablePath, L"cddiscs.dat");
  108. PathCombineW(discIndexPath, inidir, L"plugins");
  109. PathAppendW(discIndexPath, L"cddiscs.idx");
  110. discTable = NDE_Database_OpenTable(discDB, discTablePath, discIndexPath, NDE_OPEN_ALWAYS, NDE_CACHE);
  111. if (discTable)
  112. {
  113. CreateDiscFields(discTable);
  114. }
  115. }
  116. return (discTable ? NDE_CD_SUCCESS : NDE_CD_FAILURE);
  117. }
  118. static int OpenTrackTable()
  119. {
  120. AutoLock lock(dbcs);
  121. int ret = OpenDiscDatabase();
  122. if (ret != NDE_CD_SUCCESS)
  123. {
  124. return ret;
  125. }
  126. if (!trackTable)
  127. {
  128. const wchar_t *inidir = WASABI_API_APP->path_getUserSettingsPath();
  129. wchar_t trackTablePath[MAX_PATH] = {0}, trackIndexPath[MAX_PATH] = {0};
  130. PathCombineW(trackTablePath, inidir, L"plugins");
  131. PathAppendW(trackTablePath, L"cdtracks.dat");
  132. PathCombineW(trackIndexPath, inidir, L"plugins");
  133. PathAppendW(trackIndexPath, L"cdtracks.idx");
  134. trackTable = NDE_Database_OpenTable(discDB, trackTablePath, trackIndexPath, NDE_OPEN_ALWAYS, NDE_CACHE);
  135. if (trackTable)
  136. {
  137. CreateTrackFields(trackTable);
  138. }
  139. }
  140. return (trackTable ? NDE_CD_SUCCESS : NDE_CD_FAILURE);
  141. }
  142. void CloseTables()
  143. {
  144. if (discTable)
  145. {
  146. if (g_dirty & 1) NDE_Table_Sync(discTable);
  147. NDE_Database_CloseTable(discDB, discTable);
  148. discTable = 0;
  149. }
  150. if (trackTable)
  151. {
  152. if (g_dirty & 2) NDE_Table_Sync(trackTable);
  153. NDE_Database_CloseTable(discDB, trackTable);
  154. trackTable = 0;
  155. }
  156. if (discDB)
  157. {
  158. NDE_DestroyDatabase(discDB);
  159. discDB = 0;
  160. }
  161. g_dirty = 0;
  162. }
  163. static void db_setFieldInt(nde_scanner_t s, unsigned char id, int data)
  164. {
  165. nde_field_t f = NDE_Scanner_GetFieldByID(s, id);
  166. if (!f) f = NDE_Scanner_NewFieldByID(s, id);
  167. NDE_IntegerField_SetValue(f, data);
  168. }
  169. static void db_setFieldString(nde_scanner_t s, unsigned char id, const wchar_t *data)
  170. {
  171. nde_field_t f = NDE_Scanner_GetFieldByID(s, id);
  172. if (!f) f = NDE_Scanner_NewFieldByID(s, id);
  173. NDE_StringField_SetString(f, data);
  174. }
  175. static void db_removeField(nde_scanner_t s, unsigned char id)
  176. {
  177. nde_field_t f = NDE_Scanner_GetFieldByID(s, id);
  178. if (f)
  179. {
  180. NDE_Scanner_DeleteField(s, f);
  181. }
  182. }
  183. static int db_getFieldInt(nde_scanner_t s, unsigned char id, int defaultVal)
  184. {
  185. nde_field_t f = NDE_Scanner_GetFieldByID(s, id);
  186. if (f)
  187. return NDE_IntegerField_GetValue(f);
  188. else
  189. return defaultVal;
  190. }
  191. static wchar_t *db_getFieldString(nde_scanner_t s, unsigned char id)
  192. {
  193. nde_field_t f = NDE_Scanner_GetFieldByID(s, id);
  194. if (f)
  195. return NDE_StringField_GetString(f);
  196. else
  197. return 0;
  198. }
  199. static void SeekToDisc(nde_scanner_t s, unsigned int cddb_id)
  200. {
  201. if (!NDE_Scanner_LocateInteger(s, DISCTABLE_ID_DISCID, FIRST_RECORD, cddb_id))
  202. {
  203. NDE_Scanner_New(s);
  204. db_setFieldInt(s,DISCTABLE_ID_DISCID,cddb_id);
  205. }
  206. }
  207. static void SeekToTrack(nde_scanner_t s, unsigned int cddb_id, int track)
  208. {
  209. nde_field_t f_id = NDE_IntegerField_Create(cddb_id);
  210. NDE_Scanner_AddFilterByID(s, TRACKTABLE_ID_DISCID, f_id, FILTER_EQUALS);
  211. if (!NDE_Scanner_LocateInteger(s, TRACKTABLE_ID_TRACK, FIRST_RECORD, track))
  212. {
  213. NDE_Scanner_New(s);
  214. db_setFieldInt(s,TRACKTABLE_ID_DISCID,cddb_id);
  215. db_setFieldInt(s,TRACKTABLE_ID_TRACK,track);
  216. }
  217. NDE_Scanner_RemoveFilters(s);
  218. }
  219. #ifndef IGNORE_API_GRACENOTE
  220. void StoreDisc(unsigned int cddb_id, ICddbDiscPtr pDisc)
  221. {
  222. AutoLock lock(dbcs);
  223. CComBSTR str, disc_artist, disc_composer, disc_conductor, disc_remixing;
  224. BSTR composerRole=L"3", conductorRole=L"12", remixingRole=L"147";
  225. /*
  226. for (int i=100;i<300;i++)
  227. {
  228. wchar_t id[256] = {0};
  229. _itow(i, id, 10);
  230. ICddbRolePtr role;
  231. pCDDBControl->GetRoleInfo(id, &role);
  232. if (role)
  233. {
  234. BSTR name, description;
  235. role->get_Name(&name);
  236. role->get_Description(&description);
  237. wchar_t str[4096] = {0};
  238. wsprintf(str, L"ID: %s\r\nName: %s\r\nDescription: %s\r\n", id, name, description);
  239. MessageBoxW(NULL, str, L"CDDB Role", MB_OK);
  240. }
  241. }
  242. */
  243. OpenDiscTable();
  244. nde_scanner_t s = NDE_Table_CreateScanner(discTable);
  245. SeekToDisc(s, cddb_id);
  246. ICddbDisc2Ptr pDisc2;
  247. pDisc->QueryInterface(&pDisc2);
  248. ICddbDisc2_5Ptr pDisc2_5;
  249. pDisc->QueryInterface(&pDisc2_5);
  250. if (GetRole(pDisc, conductorRole, &disc_conductor) && disc_conductor && disc_conductor.m_str[0])
  251. db_setFieldString(s, DISCTABLE_ID_CONDUCTOR, disc_conductor);
  252. else
  253. db_removeField(s, DISCTABLE_ID_CONDUCTOR);
  254. if (GetRole(pDisc, composerRole, &disc_composer) && disc_composer && disc_composer.m_str[0])
  255. db_setFieldString(s, DISCTABLE_ID_COMPOSER, disc_composer);
  256. else
  257. db_removeField(s, DISCTABLE_ID_COMPOSER);
  258. if (GetRole(pDisc, remixingRole, &disc_remixing) && disc_remixing && disc_remixing.m_str[0])
  259. db_setFieldString(s, DISCTABLE_ID_REMIXING, disc_remixing);
  260. else
  261. db_removeField(s, DISCTABLE_ID_REMIXING);
  262. if (SUCCEEDED(pDisc->get_Artist(&disc_artist)) && disc_artist && disc_artist.m_str[0])
  263. db_setFieldString(s, DISCTABLE_ID_ARTIST, disc_artist);
  264. else
  265. db_removeField(s, DISCTABLE_ID_ARTIST);
  266. if (SUCCEEDED(pDisc->get_Year(&str)) && str && str.m_str[0])
  267. db_setFieldString(s, DISCTABLE_ID_YEAR, str);
  268. else
  269. db_removeField(s, DISCTABLE_ID_YEAR);
  270. if (pDisc2_5 == NULL
  271. || (FAILED(pDisc2_5->get_V2GenreStringPrimaryByLevel(3, &str))
  272. && FAILED(pDisc2_5->get_V2GenreStringPrimaryByLevel(2, &str))
  273. && FAILED(pDisc2_5->get_V2GenreStringPrimaryByLevel(1, &str))
  274. && FAILED(pDisc2_5->get_V2GenreStringPrimary(&str)))
  275. )
  276. {
  277. pDisc->get_GenreId(&str);
  278. ICddbGenre *poop = 0;
  279. if (SUCCEEDED(pCDDBControl->GetGenreInfo(str, &poop)) && poop)
  280. {
  281. poop->get_Name(&str);
  282. poop->Release();
  283. }
  284. else
  285. str.Empty();
  286. }
  287. if (str && str.m_str[0])
  288. db_setFieldString(s, DISCTABLE_ID_GENRE, str);
  289. else
  290. db_removeField(s, DISCTABLE_ID_GENRE);
  291. if (SUCCEEDED(pDisc->get_Title(&str)) && str && str.m_str[0])
  292. db_setFieldString(s, DISCTABLE_ID_ALBUM, str);
  293. else
  294. db_removeField(s, DISCTABLE_ID_ALBUM);
  295. if (SUCCEEDED(pDisc->get_TitleUId(&str)) && str && str.m_str[0])
  296. db_setFieldString(s, DISCTABLE_ID_TUID, str);
  297. else
  298. db_removeField(s, DISCTABLE_ID_TUID);
  299. if (SUCCEEDED(pDisc->get_Label(&str)) && str && str.m_str[0])
  300. db_setFieldString(s, DISCTABLE_ID_PUBLISHER, str);
  301. else
  302. db_removeField(s, DISCTABLE_ID_PUBLISHER);
  303. if (SUCCEEDED(pDisc->get_Notes(&str)) && str && str.m_str[0])
  304. db_setFieldString(s, DISCTABLE_ID_COMMENT, str);
  305. else
  306. db_removeField(s, DISCTABLE_ID_COMMENT);
  307. /*
  308. long val;
  309. pDisc->get_Compilation(&val);
  310. ps->compilation = !!val;
  311. */
  312. int numdiscs = 0;
  313. if (SUCCEEDED(pDisc->get_TotalInSet(&str)) && str && str.m_str[0])
  314. numdiscs = _wtoi(str.m_str);
  315. int discnum =0;
  316. if (SUCCEEDED(pDisc->get_NumberInSet(&str)) && str && str.m_str[0])
  317. discnum = _wtoi(str.m_str);
  318. if (discnum)
  319. {
  320. wchar_t disc_temp[64] = {0};
  321. if (numdiscs)
  322. StringCchPrintfW(disc_temp, 64, L"%d/%d", discnum, numdiscs);
  323. else
  324. StringCchPrintfW(disc_temp, 64, L"%d", discnum);
  325. db_setFieldString(s, DISCTABLE_ID_DISC, disc_temp);
  326. }
  327. else
  328. db_removeField(s, DISCTABLE_ID_DISC);
  329. long tracks=0;
  330. if (FAILED(pDisc->get_NumTracks(&tracks)))
  331. tracks=0;
  332. NDE_Scanner_Post(s);
  333. NDE_Table_DestroyScanner(discTable, s);
  334. OpenTrackTable();
  335. s = NDE_Table_CreateScanner(trackTable);
  336. for (int x = 0; x < tracks; x ++)
  337. {
  338. ICddbTrack *t=0;
  339. ICddbTrack2_5Ptr track2_5;
  340. if (FAILED(pDisc->GetTrack(x + 1, &t)) || !t)
  341. break;
  342. SeekToTrack(s, cddb_id, x+1);
  343. // don't store if it's the same as the disc artist
  344. if (SUCCEEDED(t->get_Artist(&str)) && str && str.m_str[0] && (!disc_artist || !disc_artist.m_str[0] || wcscmp(str.m_str, disc_artist.m_str)))
  345. db_setFieldString(s, TRACKTABLE_ID_ARTIST, str);
  346. else
  347. db_removeField(s, TRACKTABLE_ID_ARTIST);
  348. if (SUCCEEDED(t->get_Title(&str)) && str && str.m_str[0])
  349. db_setFieldString(s, TRACKTABLE_ID_TITLE, str);
  350. else
  351. db_removeField(s, TRACKTABLE_ID_TITLE);
  352. if (SUCCEEDED(t->get_ISRC(&str)) && str && str.m_str[0])
  353. db_setFieldString(s, TRACKTABLE_ID_ISRC, str);
  354. else
  355. db_removeField(s, TRACKTABLE_ID_ISRC);
  356. if (SUCCEEDED(pCDDBControl->GetDiscTagId(pDisc, x + 1, &str)) && str && str.m_str[0])
  357. db_setFieldString(s, TRACKTABLE_ID_TAGID, str);
  358. else
  359. db_removeField(s, TRACKTABLE_ID_TAGID);
  360. // don't store if it's the same as the disc conductor
  361. if (GetRole(t, conductorRole, &str) && str && str.m_str[0] && (!disc_conductor || !disc_conductor.m_str[0] || wcscmp(str.m_str, disc_conductor.m_str)))
  362. db_setFieldString(s, TRACKTABLE_ID_CONDUCTOR, str);
  363. else
  364. db_removeField(s, TRACKTABLE_ID_CONDUCTOR);
  365. // don't store if it's the same as the disc composer
  366. if (GetRole(t, composerRole, &str) && str && str.m_str[0] && (!disc_composer || !disc_composer.m_str[0] || wcscmp(str.m_str, disc_composer.m_str)))
  367. db_setFieldString(s, TRACKTABLE_ID_COMPOSER, str);
  368. else
  369. db_removeField(s, TRACKTABLE_ID_COMPOSER);
  370. // don't store if it's the same as the disc remixer
  371. if (GetRole(t, remixingRole, &str) && str && str.m_str[0] && (!disc_remixing || !disc_remixing.m_str[0] || wcscmp(str.m_str, disc_remixing.m_str)))
  372. db_setFieldString(s, TRACKTABLE_ID_REMIXING, str);
  373. else
  374. db_removeField(s, TRACKTABLE_ID_REMIXING);
  375. t->QueryInterface(&track2_5);
  376. if (track2_5 != NULL && (SUCCEEDED(track2_5->get_ExtDataSerialized(&str)) && str && str.m_str[0]) // try track first
  377. || (pDisc2_5 != NULL && SUCCEEDED(pDisc2_5->get_ExtDataSerialized(&str)) && str && str.m_str[0])) // then disc
  378. db_setFieldString(s, TRACKTABLE_ID_EXTENDED_DATA, str);
  379. else
  380. db_removeField(s, TRACKTABLE_ID_EXTENDED_DATA);
  381. NDE_Scanner_Post(s);
  382. t->Release();
  383. }
  384. NDE_Table_DestroyScanner(trackTable, s);
  385. NDE_Table_Sync(trackTable);
  386. NDE_Table_Sync(discTable);
  387. }
  388. #endif
  389. static void CDText_Process(unsigned int cddb_id, const char *title, const char *performers, const char *composers, int codepage)
  390. {
  391. AutoLock lock(dbcs);
  392. OpenDiscTable();
  393. nde_scanner_t s = NDE_Table_CreateScanner(discTable);
  394. SeekToDisc(s, cddb_id);
  395. char thisTitle[1024] = {0};
  396. const char *titles = title;
  397. // first, get disc title
  398. thisTitle[0] = 0;
  399. titles = ReadLine(titles, thisTitle, 1024, codepage);
  400. db_setFieldString(s, DISCTABLE_ID_ALBUM, AutoWide(thisTitle, codepage));
  401. // now get track titles
  402. OpenTrackTable();
  403. nde_scanner_t tableScanner = NDE_Table_CreateScanner(trackTable);
  404. int trackNum = 1;
  405. while (titles && *titles)
  406. {
  407. SeekToTrack(tableScanner, cddb_id, trackNum++);
  408. thisTitle[0] = 0;
  409. titles = ReadLine(titles, thisTitle, 1024, codepage);
  410. db_setFieldString(tableScanner, TRACKTABLE_ID_TITLE, AutoWide(thisTitle, codepage));
  411. NDE_Scanner_Post(tableScanner);
  412. }
  413. titles = performers;
  414. // now get disc artist
  415. thisTitle[0] = 0;
  416. titles = ReadLine(titles, thisTitle, 1024, codepage);
  417. db_setFieldString(s, DISCTABLE_ID_ARTIST, AutoWide(thisTitle, codepage));
  418. // now get track artists
  419. trackNum = 1;
  420. while (titles && *titles)
  421. {
  422. SeekToTrack(tableScanner, cddb_id, trackNum++);
  423. thisTitle[0] = 0;
  424. titles = ReadLine(titles, thisTitle, 1024, codepage);
  425. db_setFieldString(tableScanner, TRACKTABLE_ID_ARTIST, AutoWide(thisTitle, codepage));
  426. NDE_Scanner_Post(tableScanner);
  427. }
  428. titles = composers;
  429. // now get disc composer
  430. thisTitle[0] = 0;
  431. titles = ReadLine(titles, thisTitle, 1024, codepage);
  432. db_setFieldString(s, DISCTABLE_ID_COMPOSER, AutoWide(thisTitle, codepage));
  433. // now get track composers
  434. trackNum = 1;
  435. while (titles && *titles)
  436. {
  437. SeekToTrack(tableScanner, cddb_id, trackNum++);
  438. thisTitle[0] = 0;
  439. titles = ReadLine(titles, thisTitle, 1024, codepage);
  440. db_setFieldString(tableScanner, TRACKTABLE_ID_COMPOSER, AutoWide(thisTitle, codepage));
  441. NDE_Scanner_Post(tableScanner);
  442. }
  443. NDE_Table_DestroyScanner(trackTable, tableScanner);
  444. NDE_Scanner_Post(s);
  445. NDE_Table_DestroyScanner(discTable, s);
  446. }
  447. /* returns true if there was CD text */
  448. bool StoreCDText(unsigned int cddb_id, wchar_t device)
  449. {
  450. if (!device)
  451. return false;
  452. #ifndef IGNORE_API_GRACENOTE
  453. if (config_use_veritas)
  454. {
  455. obj_primo *primo=0;
  456. waServiceFactory *sf = line.service->service_getServiceByGuid(obj_primo::getServiceGuid());
  457. if (sf) primo = reinterpret_cast<obj_primo *>(sf->getInterface());
  458. if (primo)
  459. {
  460. DWORD unit = device;
  461. if (primo->DiscInfoEx(&unit, 0, NULL, NULL, NULL, NULL, NULL, NULL) != PRIMOSDK_OK) // CDTextInfoEJ suggest that this needs to be called first
  462. {
  463. sf->releaseInterface(primo);
  464. return false;
  465. }
  466. char titleE[8192] = "", performerE[8192] = "", composerE[8192] = "", titleJ[2000] = "", performerJ[2000] = "", composerJ[2000] = "";
  467. if (primo->CDTextInfoEJ(&unit, (PBYTE)titleE, (PBYTE)performerE, (PBYTE)composerE, (PBYTE)titleJ, (PBYTE)performerJ, (PBYTE)composerJ) == PRIMOSDK_OK)
  468. {
  469. sf->releaseInterface(primo);
  470. // read titles
  471. if (titleE[0])
  472. {
  473. CDText_Process(cddb_id, titleE, performerE, composerE, 28591 /* Latin1 */);
  474. return true;
  475. }
  476. else if (titleJ[0])
  477. {
  478. CDText_Process(cddb_id, titleJ, performerJ, composerJ, 932 /* SHIFT-JIS */);
  479. return true;
  480. }
  481. }
  482. }
  483. }
  484. #endif
  485. return false;
  486. }
  487. void StoreCDNoInfo(unsigned int cddb_id)
  488. {
  489. AutoLock lock(dbcs);
  490. OpenDiscTable();
  491. nde_scanner_t s = NDE_Table_CreateScanner(discTable);
  492. SeekToDisc(s, cddb_id);
  493. NDE_Scanner_Post(s);
  494. NDE_Table_DestroyScanner(discTable, s);
  495. g_dirty |= 1;
  496. }
  497. // sets part and parts to 0 on fail/missing
  498. void ParseIntSlashInt(const wchar_t *string, int *part, int *parts)
  499. {
  500. *part = 0;
  501. *parts = 0;
  502. if (string && string[0])
  503. {
  504. *part = _wtoi(string);
  505. while (string && *string && *string != '/')
  506. {
  507. string++;
  508. }
  509. if (string && *string == '/')
  510. {
  511. string++;
  512. *parts = _wtoi(string);
  513. }
  514. }
  515. }
  516. bool QueryDINFO(unsigned int cddb_id, DINFO *info)
  517. {
  518. info->Reset();
  519. AutoLock lock(dbcs);
  520. if (OpenDiscTable() != NDE_CD_SUCCESS)
  521. return false;
  522. nde_scanner_t s = NDE_Table_CreateScanner(discTable);
  523. if (NDE_Scanner_LocateInteger(s, DISCTABLE_ID_DISCID, FIRST_RECORD, cddb_id))
  524. {
  525. ndestring_retain(info->title = db_getFieldString(s, DISCTABLE_ID_ALBUM));
  526. ndestring_retain(info->artist = db_getFieldString(s, DISCTABLE_ID_ARTIST));
  527. ndestring_retain(info->tuid = db_getFieldString(s, DISCTABLE_ID_TUID));
  528. ndestring_retain(info->year = db_getFieldString(s, DISCTABLE_ID_YEAR));
  529. ndestring_retain(info->genre = db_getFieldString(s, DISCTABLE_ID_GENRE));
  530. ndestring_retain(info->notes = db_getFieldString(s, DISCTABLE_ID_COMMENT));
  531. const wchar_t *disc_str = db_getFieldString(s, DISCTABLE_ID_DISC);
  532. ParseIntSlashInt(disc_str , &info->discnum, &info->numdiscs);
  533. ndestring_retain(info->composer = db_getFieldString(s, DISCTABLE_ID_COMPOSER));
  534. ndestring_retain(info->label = db_getFieldString(s, DISCTABLE_ID_PUBLISHER));
  535. ndestring_retain(info->conductor = db_getFieldString(s, DISCTABLE_ID_CONDUCTOR));
  536. /* Read tracks */
  537. OpenTrackTable();
  538. nde_scanner_t trackScanner = NDE_Table_CreateScanner(trackTable);
  539. nde_field_t f_id = NDE_IntegerField_Create(cddb_id);
  540. NDE_Scanner_AddFilterByID(trackScanner, TRACKTABLE_ID_DISCID, f_id, FILTER_EQUALS);
  541. int trackNum=1;
  542. while (trackNum < 100)
  543. {
  544. TRACKINFO &trackInfo = info->tracks[trackNum-1];
  545. if (!NDE_Scanner_LocateInteger(trackScanner, TRACKTABLE_ID_TRACK, FIRST_RECORD, trackNum))
  546. break;
  547. trackNum++;
  548. ndestring_retain(trackInfo.artist = db_getFieldString(trackScanner, TRACKTABLE_ID_ARTIST));
  549. ndestring_retain(trackInfo.title = db_getFieldString(trackScanner, TRACKTABLE_ID_TITLE));
  550. ndestring_retain(trackInfo.tagID = db_getFieldString(trackScanner, TRACKTABLE_ID_TAGID));
  551. ndestring_retain(trackInfo.composer = db_getFieldString(trackScanner, TRACKTABLE_ID_COMPOSER));
  552. ndestring_retain(trackInfo.conductor = db_getFieldString(trackScanner, TRACKTABLE_ID_CONDUCTOR));
  553. ndestring_retain(trackInfo.extData = db_getFieldString(trackScanner, TRACKTABLE_ID_EXTENDED_DATA));
  554. }
  555. NDE_Table_DestroyScanner(trackTable, trackScanner);
  556. NDE_Table_DestroyScanner(discTable, s);
  557. info->populated = true;
  558. return true;
  559. }
  560. NDE_Table_DestroyScanner(discTable, s);
  561. return false;
  562. }
  563. static void db_add_or_set(nde_scanner_t s, unsigned char id, wchar_t *data)
  564. {
  565. nde_field_t f = NDE_Scanner_GetFieldByID(s, id);
  566. if (data)
  567. {
  568. if (!f) f = NDE_Scanner_NewFieldByID(s, id);
  569. NDE_StringField_SetNDEString(f, data);
  570. }
  571. else if (f)
  572. {
  573. NDE_Scanner_DeleteField(s, f);
  574. }
  575. }
  576. static void db_compare_add_or_set(nde_scanner_t s, unsigned char id, const wchar_t *disc_data, wchar_t *data)
  577. {
  578. if (disc_data && data && !wcscmp(disc_data, data))
  579. db_removeField(s, id);
  580. else
  581. db_add_or_set(s, id, data);
  582. }
  583. //#ifndef IGNORE_API_GRACENOTE
  584. bool StoreDINFO(unsigned cddb_id, DINFO *info)
  585. {
  586. AutoLock lock(dbcs);
  587. if (OpenDiscTable() != NDE_CD_SUCCESS)
  588. return false;
  589. nde_scanner_t s = NDE_Table_CreateScanner(discTable);
  590. SeekToDisc(s, cddb_id);
  591. db_add_or_set(s, DISCTABLE_ID_ALBUM, info->title);
  592. db_add_or_set(s, DISCTABLE_ID_ARTIST, info->artist);
  593. db_add_or_set(s, DISCTABLE_ID_TUID, info->tuid);
  594. db_add_or_set(s, DISCTABLE_ID_YEAR, info->year);
  595. db_add_or_set(s, DISCTABLE_ID_GENRE, info->genre);
  596. db_add_or_set(s, DISCTABLE_ID_PUBLISHER, info->label);
  597. db_add_or_set(s, DISCTABLE_ID_COMMENT, info->notes);
  598. if (info->discnum)
  599. {
  600. wchar_t disc_temp[64] = {0};
  601. if (info->numdiscs)
  602. StringCchPrintfW(disc_temp, 64, L"%d/%d", info->discnum, info->numdiscs);
  603. else
  604. StringCchPrintfW(disc_temp, 64, L"%d", info->discnum);
  605. db_setFieldString(s, DISCTABLE_ID_DISC, disc_temp);
  606. }
  607. else
  608. db_removeField(s, DISCTABLE_ID_DISC);
  609. db_add_or_set(s, DISCTABLE_ID_CONDUCTOR, info->conductor);
  610. db_add_or_set(s, DISCTABLE_ID_COMPOSER, info->composer);
  611. NDE_Scanner_Post(s);
  612. NDE_Table_DestroyScanner(discTable, s);
  613. OpenTrackTable();
  614. s = NDE_Table_CreateScanner(trackTable);
  615. for (int x=0;x<info->ntracks;x++)
  616. {
  617. SeekToTrack(s, cddb_id, x+1);
  618. TRACKINFO &trackInfo = info->tracks[x];
  619. db_compare_add_or_set(s, TRACKTABLE_ID_ARTIST, info->artist, trackInfo.artist);
  620. db_add_or_set(s, TRACKTABLE_ID_TITLE, trackInfo.title);
  621. db_add_or_set(s, TRACKTABLE_ID_TAGID, trackInfo.tagID);
  622. db_compare_add_or_set(s, TRACKTABLE_ID_COMPOSER, info->composer, trackInfo.composer);
  623. db_compare_add_or_set(s, TRACKTABLE_ID_CONDUCTOR, info->conductor, trackInfo.conductor);
  624. db_add_or_set(s, TRACKTABLE_ID_EXTENDED_DATA, trackInfo.extData);
  625. NDE_Scanner_Post(s);
  626. }
  627. NDE_Table_DestroyScanner(trackTable, s);
  628. NDE_Table_Sync(trackTable);
  629. NDE_Table_Sync(discTable);
  630. g_dirty = 0;
  631. return true;
  632. }
  633. //#endif