wa2core.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930
  1. #include <precomp.h>
  2. #include "wa2core.h"
  3. #include "wa2frontend.h"
  4. #include "../winamp/wa_ipc.h"
  5. #include "wa2pledit.h"
  6. #include "../nu/AutoWide.h"
  7. #include "gen.h"
  8. #include "../nu/ns_wc.h"
  9. #include "../Agave/Language/api_language.h"
  10. #include "../Winamp/in2.h"
  11. #include "resource.h"
  12. #include "../nu/AutoChar.h"
  13. #include <shlwapi.h>
  14. // {72409F84-BAF1-4448-8211-D84A30A1591A}
  15. static const GUID eqConfigGroupGUID =
  16. { 0x72409f84, 0xbaf1, 0x4448, { 0x82, 0x11, 0xd8, 0x4a, 0x30, 0xa1, 0x59, 0x1a } };
  17. // -----------------------------------------------------------------------------------------------------------------
  18. // Core implementation for wa2
  19. // -----------------------------------------------------------------------------------------------------------------
  20. #define TIMER_POLL 0x8971
  21. Core *g_Core = NULL;
  22. api_core *g_core = NULL;
  23. int g_coreref = 0;
  24. // this is called by the library when api->core_create is called
  25. api_core *createCustomCoreApi()
  26. {
  27. g_coreref++;
  28. if (g_core == NULL) { g_Core = new Core(); g_core = g_Core; }
  29. return g_core;
  30. }
  31. // this is called when api->core_destroy is called
  32. void destroyCustomCoreApi(api_core *core)
  33. {
  34. if (--g_coreref == 0)
  35. {
  36. delete g_Core;
  37. g_Core = NULL;
  38. g_core = NULL;
  39. }
  40. }
  41. Core::Core()
  42. {
  43. waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(Agave::AgaveConfigGUID);
  44. if (sf)
  45. config = (Agave::api_config *)sf->getInterface();
  46. m_lastpeentry = -1;
  47. m_laststatus = -1;
  48. m_lastpos = -1;
  49. m_lastvol = -1;
  50. m_lastpan = -1;
  51. m_lasttitle = L"";
  52. m_lastsamplerate = -1;
  53. m_lastchan = -1;
  54. m_lastbitrate = -1;
  55. for (int i = 0;i < 10;i++)
  56. m_lasteqband[i] = 0xdead;
  57. m_lasteq = -1;
  58. m_lasteqauto = -1;
  59. m_lasteqpreamp = -1;
  60. m_lastfreqband = -1;
  61. // timerclient_setTimer(TIMER_POLL, 250);
  62. gotCallback(IPC_CB_MISC_TITLE, 1);
  63. gotCallback(IPC_CB_MISC_VOLUME, 1);
  64. gotCallback(IPC_CB_MISC_STATUS, 1);
  65. gotCallback(IPC_CB_MISC_EQ, 1);
  66. gotCallback(IPC_CB_MISC_INFO, 1);
  67. gotCallback(IPC_CB_MISC_TITLE_RATING, 1);
  68. }
  69. Core::~Core()
  70. {
  71. waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(Agave::AgaveConfigGUID);
  72. if (sf)
  73. sf->releaseInterface(config);
  74. //timerclient_killTimer(TIMER_POLL);
  75. }
  76. void Core::addCallback(CoreCallback *cb)
  77. {
  78. if (cb == NULL) return ;
  79. if (callbacks.haveItem(cb)) return ;
  80. callbacks.addItem(cb);
  81. cb->ccb_notify(CoreCallback::REGISTER);
  82. }
  83. void Core::delCallback(CoreCallback *cb)
  84. {
  85. if (cb == NULL) return ;
  86. if (callbacks.haveItem(cb))
  87. {
  88. cb->ccb_notify(CoreCallback::DEREGISTER);
  89. callbacks.removeItem(cb);
  90. }
  91. }
  92. void Core::sendCoreCallback(int message, int param1, int param2)
  93. {
  94. ReentryFilter filter(&rf, message);
  95. int l = callbacks.getNumItems();
  96. for (int i = 0; i < l;i++)
  97. callbacks[i]->ccb_notify(message, param1, param2);
  98. }
  99. int Core::getStatus()
  100. {
  101. return m_laststatus;
  102. }
  103. void Core::gotCallback(int wParam, int forcecb)
  104. {
  105. if(wParam == IPC_CB_MISC_TITLE_RATING){
  106. forcecb = 1;
  107. }
  108. switch (wParam)
  109. {
  110. case IPC_CB_MISC_TITLE:
  111. case IPC_CB_MISC_TITLE_RATING:
  112. {
  113. // check for title change
  114. wa2.invalidateCache();
  115. StringW cur_title=wa2.GetCurrentTitle();
  116. if (cur_title.isempty())
  117. cur_title = L"";
  118. StringW cur_file = wa2.GetCurrentFile();
  119. if (!m_lastfile.iscaseequal(cur_file) || forcecb)
  120. {
  121. m_lastfile.swap(cur_file);
  122. sendCoreCallback(CoreCallback::URLCHANGE, (intptr_t)m_lastfile.getValue());
  123. }
  124. if (!m_lasttitle.iscaseequal(cur_title) || forcecb)
  125. {
  126. m_lasttitle.swap(cur_title);
  127. //Martin> i dunno why we send a INFOCHANGE Callback here, but if we want to send this
  128. // callback try to deliver the correct data
  129. //sendCoreCallback((forcecb==2?CoreCallback::INFOCHANGE:CoreCallback::TITLECHANGE),
  130. // (int)m_lasttitle.getValue(),(wParam == IPC_CB_MISC_TITLE_RATING));
  131. if (forcecb==2) // this has led to INFOCHANGE Callback
  132. {
  133. sendCoreCallback(CoreCallback::INFOCHANGE, (intptr_t)getSongInfoText(), (wParam == IPC_CB_MISC_TITLE_RATING));
  134. }
  135. sendCoreCallback(CoreCallback::TITLECHANGE, (intptr_t)m_lasttitle.getValue(), (wParam == IPC_CB_MISC_TITLE_RATING));
  136. }
  137. int plentry = wa2.getCurPlaylistEntry();
  138. int curpeentry = plentry + 1;
  139. if (curpeentry != m_lastpeentry)
  140. {
  141. Wa2PlaylistEditor::_onNewCurrentIndex(curpeentry);
  142. m_lastpeentry = curpeentry;
  143. }
  144. }
  145. break;
  146. case IPC_CB_MISC_STATUS:
  147. {
  148. int cur_status;
  149. int resume = 0;
  150. if (wa2.isPaused()) cur_status = STATUS_PAUSE;
  151. else if (wa2.isPlaying())
  152. {
  153. if (m_laststatus == STATUS_PAUSE)
  154. resume = 1;
  155. else
  156. {
  157. m_lastsamplerate = -1;
  158. m_lastbitrate = -1;
  159. m_lastchan = -1;
  160. }
  161. cur_status = STATUS_PLAY;
  162. }
  163. else cur_status = STATUS_STOP;
  164. if (m_laststatus != cur_status || forcecb)
  165. {
  166. m_laststatus = cur_status;
  167. switch (cur_status)
  168. {
  169. case STATUS_PLAY: sendCoreCallback(resume ? CoreCallback::UNPAUSED : CoreCallback::STARTED); break;
  170. case STATUS_STOP:
  171. {
  172. m_lastsamplerate = 0;
  173. m_lastchan = 0;
  174. m_lastbitrate = 0;
  175. sendCoreCallback(CoreCallback::STOPPED);
  176. break;
  177. }
  178. case STATUS_PAUSE: sendCoreCallback(CoreCallback::PAUSED); break;
  179. }
  180. }
  181. }
  182. break;
  183. case IPC_CB_MISC_VOLUME:
  184. {
  185. // check for volume change
  186. int cur_vol = wa2.getVolume();
  187. if (m_lastvol != cur_vol || forcecb)
  188. {
  189. m_lastvol = cur_vol;
  190. sendCoreCallback(CoreCallback::VOLCHANGE, cur_vol);
  191. }
  192. int cur_pan = wa2.getPanning();
  193. if (m_lastpan != cur_pan || forcecb)
  194. {
  195. m_lastpan = cur_pan;
  196. sendCoreCallback(CoreCallback::PANCHANGE, cur_pan);
  197. }
  198. }
  199. break;
  200. case IPC_CB_MISC_EQ:
  201. {
  202. // check if the band frequencies changed (winamp vs ISO)
  203. int new_freqband = config->GetInt(eqConfigGroupGUID, L"frequencies", 0);
  204. if (m_lastfreqband != new_freqband)
  205. {
  206. bool sendCallback = m_lastfreqband != -1;
  207. m_lastfreqband = new_freqband; // set before the callback so we don't run into any issues if the callback triggers another EQ change message
  208. if (sendCallback)
  209. sendCoreCallback(CoreCallback::EQFREQCHANGE, new_freqband, 0);
  210. }
  211. // check for eq change
  212. for (int i = 0;i < 10;i++)
  213. {
  214. int cur_band = wa2.getEqData(WA2_EQDATA_FIRSTBAND + i);
  215. if (cur_band == 63 - ((m_lasteqband[i] + 127) / 4)) cur_band = m_lasteqband[i];
  216. else cur_band = (63 - cur_band) * 4 - 127;
  217. if (m_lasteqband[i] != cur_band || forcecb)
  218. {
  219. m_lasteqband[i] = cur_band;
  220. sendCoreCallback(CoreCallback::EQBANDCHANGE, i, cur_band);
  221. }
  222. }
  223. int cur_eq = wa2.getEqData(WA2_EQDATA_ENABLED);
  224. if (m_lasteq != cur_eq)
  225. {
  226. m_lasteq = cur_eq;
  227. sendCoreCallback(CoreCallback::EQSTATUSCHANGE, cur_eq);
  228. }
  229. int cur_eqauto = wa2.getEqData(WA2_EQDATA_AUTO);
  230. if (m_lasteqauto != cur_eqauto || forcecb)
  231. {
  232. m_lasteqauto = cur_eqauto;
  233. sendCoreCallback(CoreCallback::EQAUTOCHANGE, cur_eqauto);
  234. }
  235. int cur_eqpreamp = wa2.getEqData(WA2_EQDATA_PREAMP);
  236. if (cur_eqpreamp == 63 - ((cur_eqpreamp + 127) / 4)) { /*cur_eqpreamp = cur_eqpreamp;*/ }
  237. else cur_eqpreamp = (63 - cur_eqpreamp) * 4 - 127;
  238. if (m_lasteqpreamp != cur_eqpreamp || forcecb)
  239. {
  240. m_lasteqpreamp = cur_eqpreamp;
  241. sendCoreCallback(CoreCallback::EQPREAMPCHANGE, cur_eqpreamp);
  242. }
  243. }
  244. break;
  245. case IPC_CB_MISC_INFO:
  246. {
  247. int realrate = wa2.getSamplerate();
  248. int brate = wa2.getBitrate();
  249. int ch = wa2.getChannels();
  250. int any = 0;
  251. if (realrate != m_lastsamplerate || forcecb)
  252. {
  253. m_lastsamplerate = realrate;
  254. sendCoreCallback(CoreCallback::SAMPLERATECHANGE, realrate);
  255. any = 1;
  256. }
  257. if (brate != m_lastbitrate || forcecb)
  258. {
  259. m_lastbitrate = brate;
  260. sendCoreCallback(CoreCallback::BITRATECHANGE, m_lastbitrate);
  261. any = 1;
  262. }
  263. if (ch != m_lastchan || forcecb)
  264. {
  265. m_lastchan = ch;
  266. sendCoreCallback(CoreCallback::CHANNELSCHANGE, m_lastchan);
  267. any = 1;
  268. }
  269. //DebugString("Got IPC_CB_MISC_INFO callback, numchans = %d, samplerate = %d, bitrate = %d\n", m_lastchan, m_lastsamplerate, m_lastbitrate);
  270. if (any)
  271. {
  272. StringW txt = getSongInfoText();
  273. sendCoreCallback(CoreCallback::INFOCHANGE, (intptr_t)txt.getValue());
  274. }
  275. break;
  276. }
  277. }
  278. }
  279. StringW infotext;
  280. const wchar_t *Core::getSongInfoText()
  281. {
  282. infotext = L"";
  283. int srate = wa2.getSamplerate();
  284. int brate = wa2.getBitrate();
  285. int ch = wa2.getChannels();
  286. if (srate == 0 && brate == 0)
  287. {
  288. return L"";
  289. }
  290. infotext = StringPrintfW(L"%dkbps", brate);
  291. if (ch == 1)
  292. {
  293. infotext += L" mono";
  294. }
  295. else if (ch == 2)
  296. {
  297. infotext += L" stereo";
  298. }
  299. else if (ch > 2)
  300. {
  301. infotext += StringPrintfW(L" %d Channels", ch);
  302. }
  303. infotext += StringPrintfW(L" %.1fkHz", (float)srate/1000.0f);
  304. if (wa2.isPlayingVideo())
  305. {
  306. infotext.prepend(L"Video ");
  307. }
  308. return infotext;
  309. }
  310. StringW infotextTranslated;
  311. const wchar_t *Core::getSongInfoTextTranslated()
  312. {
  313. infotextTranslated = L"";
  314. int srate = wa2.getSamplerate();
  315. int brate = wa2.getBitrate();
  316. int ch = wa2.getChannels();
  317. if (srate == 0 && brate == 0)
  318. {
  319. return L"";
  320. }
  321. infotextTranslated = StringPrintfW(L"%d%s", brate,WASABI_API_LNGSTRINGW(IDS_KBPS));
  322. if (ch == 1)
  323. {
  324. infotextTranslated += WASABI_API_LNGSTRINGW(IDS_MONO);
  325. }
  326. else if (ch == 2)
  327. {
  328. infotextTranslated += WASABI_API_LNGSTRINGW(IDS_STEREO);
  329. }
  330. else if (ch > 2)
  331. {
  332. infotextTranslated += StringPrintfW(WASABI_API_LNGSTRINGW(IDS_X_CHANNELS), ch);
  333. }
  334. infotextTranslated += StringPrintfW(L" %.1f", (float)srate/1000.0f);
  335. infotextTranslated += WASABI_API_LNGSTRINGW(IDS_KHZ);// (doing this in the StringPrintfW(..) above causes a crash even in a seperate buffer)
  336. if (wa2.isPlayingVideo())
  337. {
  338. infotextTranslated.prepend(StringPrintfW(L"%s ",WASABI_API_LNGSTRINGW(IDS_VIDEO)));
  339. }
  340. return infotextTranslated;
  341. }
  342. void Core::userButton(int button)
  343. {
  344. int mod = Std::keyDown(VK_SHIFT) ? WA2_USERBUTTONMOD_SHIFT : (Std::keyDown(VK_SHIFT) ? WA2_USERBUTTONMOD_CTRL : WA2_USERBUTTONMOD_NONE);
  345. switch (button)
  346. {
  347. case UserButton::PLAY: wa2.userButton(WA2_USERBUTTON_PLAY, mod); break;
  348. case UserButton::STOP: wa2.userButton(WA2_USERBUTTON_STOP, mod); break;
  349. case UserButton::PAUSE: wa2.userButton(WA2_USERBUTTON_PAUSE, mod); break;
  350. case UserButton::NEXT: wa2.userButton(WA2_USERBUTTON_NEXT, mod); break;
  351. case UserButton::PREV: wa2.userButton(WA2_USERBUTTON_PREV, mod); break;
  352. }
  353. }
  354. void Core::setVolume(int vol)
  355. {
  356. wa2.setVolume(vol);
  357. }
  358. int Core::getVolume()
  359. {
  360. return wa2.getVolume();
  361. }
  362. void Core::setPosition(int ms)
  363. {
  364. wa2.seekTo(ms);
  365. sendCoreCallback(CoreCallback::SEEKED, ms);
  366. }
  367. int Core::getPosition()
  368. {
  369. if (m_laststatus == STATUS_STOP) return -1;
  370. return wa2.getPosition();
  371. }
  372. int Core::getLength()
  373. {
  374. if (m_laststatus == STATUS_STOP) return -1;
  375. return wa2.getLength();
  376. }
  377. void Core::setPanning(int p)
  378. {
  379. if (p > 127) p = 127;
  380. wa2.setPanning(p);
  381. }
  382. int Core::getPanning()
  383. {
  384. return wa2.getPanning();
  385. }
  386. void Core::setShuffle(int shuffle)
  387. {
  388. wa2.setShuffle(shuffle);
  389. }
  390. int Core::getShuffle()
  391. {
  392. return wa2.getShuffle();
  393. }
  394. void Core::setRepeat(int repeat)
  395. {
  396. static int myset = 0;
  397. if (!myset)
  398. {
  399. myset = 1;
  400. int manadv = 0;
  401. int rep = 0;
  402. if (repeat == 0)
  403. {
  404. rep = 0;
  405. manadv = 0;
  406. }
  407. else if (repeat > 0)
  408. {
  409. rep = 1;
  410. manadv = 0;
  411. }
  412. else if (repeat < 0)
  413. {
  414. rep = 1;
  415. manadv = 1;
  416. }
  417. if (!!wa2.getRepeat() != !!rep) wa2.setRepeat(rep);
  418. if (!!wa2.getManualPlaylistAdvance() != !!manadv) wa2.setManualPlaylistAdvance(manadv);
  419. myset = 0;
  420. }
  421. }
  422. int Core::getRepeat()
  423. {
  424. int manadv = wa2.getManualPlaylistAdvance();
  425. int rep = wa2.getRepeat();
  426. int _v = (rep && manadv) ? -1 : rep;
  427. return _v;
  428. }
  429. int Core::getSamplerate(int wa2_getinfo)
  430. {
  431. return wa2.getInfo(WA2_GETINFO_SAMPLERATE);
  432. }
  433. int Core::getBitrate(int wa2_getinfo)
  434. {
  435. return wa2.getInfo(WA2_GETINFO_BITRATE);
  436. }
  437. int Core::getChannels(int wa2_getinfo)
  438. {
  439. return wa2.getInfo(WA2_GETINFO_CHANNELS);
  440. }
  441. int Core::getEqBand(int band)
  442. {
  443. // int v = 63-wa2.getEqData(WA2_EQDATA_FIRSTBAND+band) * 4 - 127;
  444. // v = MIN(-127, v);
  445. // v = MAX(127, v);
  446. return m_lasteqband[band]; //(v);
  447. }
  448. void Core::setEqBand(int band, int val)
  449. {
  450. val = MIN(127, MAX( -127, val));
  451. m_lasteqband[band] = val;
  452. int v = 63 - ((val + 127) / 4);
  453. v = MIN(63, v);
  454. v = MAX(0, v);
  455. wa2.setEqData(WA2_EQDATA_FIRSTBAND + band, v);
  456. sendCoreCallback(CoreCallback::EQBANDCHANGE, band, val);
  457. }
  458. int Core::getEQStatus()
  459. {
  460. return wa2.getEqData(WA2_EQDATA_ENABLED);
  461. }
  462. void Core::setEQStatus(int enable)
  463. {
  464. wa2.setEqData(WA2_EQDATA_ENABLED, enable);
  465. }
  466. int Core::getEQAuto()
  467. {
  468. return wa2.getEqData(WA2_EQDATA_AUTO);
  469. }
  470. void Core::setEQAuto(int enable)
  471. {
  472. wa2.setEqData(WA2_EQDATA_AUTO, enable);
  473. }
  474. int Core::getEQPreamp()
  475. {
  476. // int v = 63-wa2.getEqData(WA2_EQDATA_PREAMP) * 4 - 127;
  477. // v = MIN(-127, v);
  478. // v = MAX(127, v);
  479. return m_lasteqpreamp;
  480. }
  481. void Core::setEQPreamp(int val)
  482. {
  483. val = MIN(127, MAX( -127, val));
  484. m_lasteqpreamp = val;
  485. int v = 63 - ((val + 127) / 4);
  486. v = MIN(63, v);
  487. v = MAX(0, v);
  488. wa2.setEqData(WA2_EQDATA_PREAMP, v);
  489. sendCoreCallback(CoreCallback::EQPREAMPCHANGE, val);
  490. }
  491. const wchar_t *Core::getTitle()
  492. {
  493. return m_lasttitle; // faster to use our cached ver
  494. // int plentry = wa2.getCurPlaylistEntry();
  495. // if (plentry == -1) return NULL;
  496. // return wa2.getTitle(plentry);
  497. }
  498. void Core::setTitle(const wchar_t * new_title)
  499. {
  500. StringW title = new_title;
  501. if(title.isempty())
  502. title = L"";
  503. m_lasttitle = title;
  504. }
  505. const wchar_t *Core::getPlaystring()
  506. {
  507. m_playstring = wa2.GetCurrentFile();
  508. if (m_playstring.getValue() == NULL) m_playstring = L"";
  509. return m_playstring;
  510. }
  511. int Core::getCurPlaylistEntry()
  512. {
  513. return wa2.getCurPlaylistEntry();
  514. }
  515. // -----------------------------------------------------------------------------------------------------------------
  516. // api_core implementation
  517. // -----------------------------------------------------------------------------------------------------------------
  518. // this pointer is set automagically by ApiInit
  519. api_core *coreApi = NULL;
  520. const wchar_t *Core::core_getSupportedExtensions()
  521. {
  522. return L"mp3\x0";
  523. }
  524. const wchar_t *Core::core_getExtSupportedExtensions()
  525. {
  526. return L"mp3\x0";
  527. }
  528. CoreToken Core::core_create()
  529. {
  530. return 0;
  531. }
  532. int Core::core_free(CoreToken core)
  533. {
  534. return 0;
  535. }
  536. int Core::core_setNextFile(CoreToken core, const wchar_t *playstring)
  537. {
  538. return 0;
  539. }
  540. int Core::core_getStatus(CoreToken core)
  541. {
  542. switch (getStatus())
  543. {
  544. case STATUS_STOP : return 0;
  545. case STATUS_PLAY : return 1;
  546. case STATUS_PAUSE : return -1;
  547. }
  548. return 0; // dunno, stopped i guess...
  549. }
  550. const wchar_t *Core::core_getCurrent(CoreToken core)
  551. {
  552. return getPlaystring();
  553. }
  554. int Core::core_getCurPlaybackNumber(CoreToken core)
  555. {
  556. return getCurPlaylistEntry();
  557. }
  558. int Core::core_getPosition(CoreToken core)
  559. {
  560. return getPosition();
  561. }
  562. int Core::core_getWritePosition(CoreToken core)
  563. {
  564. return getPosition();
  565. }
  566. int Core::core_setPosition(CoreToken core, int ms)
  567. {
  568. setPosition(ms);
  569. return 1;
  570. }
  571. int Core::core_getLength(CoreToken core)
  572. {
  573. return getLength();
  574. }
  575. int Core::core_getPluginData(const wchar_t *playstring, const wchar_t *name, wchar_t *data, int data_len, int data_type)
  576. {
  577. return 0;
  578. }
  579. unsigned int Core::core_getVolume(CoreToken core)
  580. {
  581. return getVolume();
  582. }
  583. void Core::core_setVolume(CoreToken core, unsigned int vol)
  584. {
  585. setVolume(vol);
  586. }
  587. int Core::core_getPan(CoreToken core)
  588. {
  589. return getPanning();
  590. }
  591. void Core::core_setPan(CoreToken core, int val)
  592. {
  593. setPanning(val);
  594. }
  595. void Core::core_addCallback(CoreToken core, CoreCallback *cb)
  596. {
  597. addCallback(cb);
  598. }
  599. void Core::core_delCallback(CoreToken core, CoreCallback *cb)
  600. {
  601. delCallback(cb);
  602. }
  603. int Core::core_getVisData(CoreToken core, void *dataptr, int sizedataptr)
  604. {
  605. int ret = 75*2;
  606. // added this to attempt to cope with some poor / old input plug-ins
  607. // which keep cropping up in the plug-in crash reports from users...
  608. try
  609. {
  610. // todo
  611. if (wa2.export_sa_get)
  612. {
  613. if (sizedataptr >= (75*2 + 8))
  614. wa2.export_sa_get((char *)dataptr);
  615. else
  616. {
  617. char data[75*2 + 8];
  618. char *p = wa2.export_sa_get(data);
  619. if (p) memcpy(dataptr, p, min(2*75, sizedataptr));
  620. }
  621. }
  622. else if (wa2.export_sa_get_deprecated)
  623. {
  624. char *p = wa2.export_sa_get_deprecated();
  625. if (p) memcpy(dataptr, p, min(2*75, sizedataptr));
  626. }
  627. }
  628. catch(...)
  629. {
  630. ret = 0;
  631. }
  632. return ret;
  633. }
  634. int Core::core_getLeftVuMeter(CoreToken core)
  635. {
  636. if (wa2.export_vu_get)
  637. {
  638. int vu = wa2.export_vu_get(0);
  639. if (vu != -1)
  640. return vu;
  641. }
  642. if (wa2.export_sa_get)
  643. {
  644. char data[75*2 + 8] = {0};
  645. char *p = (char *)wa2.export_sa_get(data);
  646. if (!p) return 0;
  647. int m = 0;
  648. for (int i = 75;i < 150;i++) // this is very gay but workish
  649. m = max(abs(m), p[i]);
  650. return MIN(255, m*16);
  651. }
  652. else if (wa2.export_sa_get_deprecated)
  653. {
  654. char *p = (char *)wa2.export_sa_get_deprecated();
  655. if (!p) return 0;
  656. int m = 0;
  657. for (int i = 75;i < 150;i++) // this is very gay but workish
  658. m = max(abs(m), p[i]);
  659. return MIN(255, m*16);
  660. }
  661. else return 0;
  662. }
  663. int Core::core_getRightVuMeter(CoreToken core)
  664. {
  665. if (wa2.export_vu_get)
  666. {
  667. int vu = wa2.export_vu_get(1);
  668. if (vu == -1)
  669. vu = wa2.export_vu_get(0);
  670. if (vu != -1)
  671. return vu;
  672. }
  673. return core_getLeftVuMeter(core);
  674. }
  675. int Core::core_registerSequencer(CoreToken core, ItemSequencer *seq)
  676. {
  677. return 0;
  678. }
  679. int Core::core_deregisterSequencer(CoreToken core, ItemSequencer *seq)
  680. {
  681. return 0;
  682. }
  683. void Core::core_userButton(CoreToken core, int button)
  684. {
  685. userButton(button);
  686. }
  687. int Core::core_getEqStatus(CoreToken core)
  688. {
  689. return getEQStatus();
  690. }
  691. void Core::core_setEqStatus(CoreToken core, int enable)
  692. {
  693. setEQStatus(enable);
  694. }
  695. int Core::core_getEqPreamp(CoreToken core)
  696. {
  697. return getEQPreamp();
  698. }
  699. void Core::core_setEqPreamp(CoreToken core, int pre)
  700. {
  701. setEQPreamp(pre);
  702. }
  703. int Core::core_getEqBand(CoreToken core, int band)
  704. {
  705. return getEqBand(band);
  706. }
  707. void Core::core_setEqBand(CoreToken core, int band, int val)
  708. {
  709. setEqBand(band, val);
  710. }
  711. int Core::core_getEqAuto(CoreToken core)
  712. {
  713. return getEQAuto();
  714. }
  715. void Core::core_setEqAuto(CoreToken core, int enable)
  716. {
  717. setEQAuto(enable);
  718. }
  719. void Core::core_setCustomMsg(CoreToken core, const wchar_t *text)
  720. {}
  721. void Core::core_registerExtension(const wchar_t *extensions, const wchar_t *extension_name, const wchar_t *family)
  722. {}
  723. const wchar_t *Core::core_getDecoderName(const wchar_t *filename)
  724. {
  725. wchar_t fn[MAX_PATH+3] = {0};
  726. WCSNPRINTF(fn, MAX_PATH, L"hi.%s", filename);
  727. In_Module *player = (In_Module *)wa2.CanPlay(fn);
  728. if (player)
  729. {
  730. // cope nicely with the 5.64+ input plug-ins with unicode descriptions
  731. static wchar_t decoder_name[512];
  732. int ver = ((player->version & ~IN_UNICODE) & ~IN_INIT_RET);
  733. if (ver == IN_VER)
  734. {
  735. StringCchCopyW(decoder_name, 512, (wchar_t *)player->description);
  736. }
  737. else
  738. {
  739. MultiByteToWideCharSZ(CP_ACP, 0, player->description, -1, decoder_name, 512);
  740. }
  741. return decoder_name;
  742. }
  743. return NULL;
  744. }
  745. const wchar_t *Core::core_getExtensionFamily(const wchar_t *extension)
  746. {
  747. wchar_t fn[MAX_PATH] = {0};
  748. WCSNPRINTF(fn, MAX_PATH, L"hi.%s", extension);
  749. In_Module *player = (In_Module *)wa2.CanPlay(fn);
  750. if (player)
  751. {
  752. /*
  753. char *p = player->FileExtensions;
  754. const wchar_t *realExt = PathFindExtensionW(fn);
  755. if (realExt && *realExt)
  756. realExt++;
  757. AutoChar ext(realExt);
  758. while (p && *p)
  759. {
  760. char *b = p;
  761. char *c;
  762. do
  763. {
  764. char d[20] = {0};
  765. lstrcpyn(d, b, 15);
  766. if ((c = strstr(b, ";")))
  767. {
  768. if ((c-b)<15)
  769. d[c - b] = 0;
  770. }
  771. if (!_stricmp(ext, d))
  772. {
  773. p += lstrlen(p) + 1; // skip to the name
  774. MultiByteToWideCharSZ(CP_ACP, 0, p, -1, family, 512);
  775. return family;
  776. }
  777. b = c + 1;
  778. }
  779. while (c);
  780. p += lstrlen(p) + 1;
  781. if (!*p) break;
  782. p += lstrlen(p) + 1;
  783. }
  784. */
  785. static wchar_t family[512];
  786. MultiByteToWideCharSZ(CP_ACP, 0, player->description, -1, family, 512);
  787. return family;
  788. }
  789. return NULL;
  790. }
  791. void Core::core_unregisterExtension(const wchar_t *extensions)
  792. {}
  793. const wchar_t *Core::core_getTitle(CoreToken core)
  794. {
  795. return getTitle();
  796. }
  797. void Core::core_setTitle(const wchar_t *new_title)
  798. {
  799. setTitle(new_title);
  800. }
  801. int Core::core_getRating()
  802. {
  803. return wa2.getCurTrackRating();
  804. }
  805. void Core::core_setRating(int newRating)
  806. {
  807. wa2.setCurTrackRating(newRating);
  808. }