123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598 |
- //#define PLUGIN_NAME "Nullsoft CD Plug-in"
- #define PLUGIN_VERSION L"4.7"
- #include "main.h"
- #include "cddb.h"
- #include "CDPlay.h"
- #include "DAEPlay.h"
- #include "MCIPlay.h"
- #include "WindacPlay.h"
- #include "PlayStatus.h"
- #include "../nu/AutoWide.h"
- #include "../nu/AutoChar.h"
- #include "../Winamp/strutil.h"
- #include "../winamp/wa_ipc.h"
- #include <shlwapi.h>
- #include "api__in_cdda.h"
- #include "workorder.h"
- #include <strsafe.h>
- using namespace Nullsoft::Utility;
- Nullsoft::Utility::LockGuard *playDeviceGuard = 0;
- char * s_last_error = NULL;
- static wchar_t playDriveLetter;
- //extern int config_maxextractspeed;
- api_config *AGAVE_API_CONFIG=0;
- #ifndef _DEBUG
- BOOL WINAPI _DllMainCRTStartup(HINSTANCE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
- {
- DisableThreadLibraryCalls(hInst);
- return TRUE;
- }
- #endif
- #ifdef IGNORE_API_GRACENOTE
- static DINFO g_ps;
- #endif
- int g_ps_inuse = 0;
- int g_playtrack, g_playlength;
- wchar_t lastfn[1024] = {0};
- int paused;
- void _setvolume();
- DWORD MainThreadId;
- extern char INI_FILE[];
- extern char app_name[];
- int DoAboutMessageBox(HWND parent, wchar_t* title, wchar_t* message)
- {
- MSGBOXPARAMS msgbx = {sizeof(MSGBOXPARAMS),0};
- msgbx.lpszText = message;
- msgbx.lpszCaption = title;
- msgbx.lpszIcon = MAKEINTRESOURCE(102);
- msgbx.hInstance = GetModuleHandle(0);
- msgbx.dwStyle = MB_USERICON;
- msgbx.hwndOwner = parent;
- return MessageBoxIndirect(&msgbx);
- }
- void about(HWND hwndParent)
- {
- wchar_t message[1024] = {0}, text[1024] = {0};
- WASABI_API_LNGSTRINGW_BUF(IDS_NULLSOFT_CD_PLUGIN_OLD,text,1024);
- StringCchPrintf(message, 1024, WASABI_API_LNGSTRINGW(IDS_ABOUT_TEXT),
- line.description, TEXT(__DATE__));
- DoAboutMessageBox(hwndParent,text,message);
- }
- void quit();
- int init();
- int isourfile(const in_char *fn)
- {
- if (!_wcsnicmp(fn, L"cda://", 6)) return 1;
- return 0;
- }
- volatile int done = 0;
- int g_lastpos = 0;
- C_CDPlay *g_cdplay = 0;
- const wchar_t *filename(const wchar_t *fn)
- {
- const wchar_t *s = scanstr_backcW(fn, L"\\/", 0);
- if (!s) return fn;
- return (s + 1);
- }
- bool ParseName(const wchar_t *fn, wchar_t &device, int &trackNum)
- {
- wchar_t track[16] = L"1";
- if (!_wcsnicmp(fn, L"cda://", 6))
- {
- fn += 6;
- wchar_t d[16] = {0};
- wchar_t *p = d;
- while (fn && *fn && *fn != L',' && (p - d < 15)) *p++ = *fn++;
- if (p) *p = 0;
- device = toupper(d[0]);
- if (*fn == L',') fn++;
- lstrcpyn(track, fn, ARRAYSIZE(track));
- trackNum = _wtoi(track);
- return true;
- }
- else if (!_wcsicmp(extensionW(fn), L"cda"))
- {
- const wchar_t *f = filename(fn);
- if (!_wcsnicmp(f, L"track", 5)) f += 5;
- wchar_t t[16] = {0};
- wchar_t *p = t;
- while (f && *f && *f != L'.' && (p - t < 15)) *p++ = *f++;
- lstrcpyn(track, t, ARRAYSIZE(track));
- device = toupper(fn[0]);
- trackNum = _wtoi(track);
- return true;
- }
- return false;
- }
- WindacPlay *windacPlayer = 0;
- DAEPlay *daePlayer = 0;
- MciPlay *mciPlayer = 0;
- int play(const in_char *fn)
- {
- done = 0;
- lstrcpyn(lastfn, fn, 1024);
- line.is_seekable = 0;
- g_lastpos = 0;
- int track = -1;
- if (!ParseName(fn, playDriveLetter, track))
- return 1;
- if (playStatus[playDriveLetter].IsRipping() || (g_cdplay && g_cdplay->IsPlaying(playDriveLetter)))
- {
- wchar_t title[32] = {0};
- MessageBoxW(NULL, WASABI_API_LNGSTRINGW(IDS_CD_CURRENTLY_IN_USE),
- WASABI_API_LNGSTRINGW_BUF(IDS_DRIVE_IN_USE,title,32), MB_OK);
- return 1;
- }
- if (g_cdplay) delete g_cdplay; g_cdplay = NULL;
- //first, try DAE
- if (!daePlayer) daePlayer = new DAEPlay;
- g_cdplay = daePlayer;
- int ret = (g_cdplay ? g_cdplay->play(playDriveLetter, track) : 0);
- if (ret != 0)
- {
- if (g_cdplay) delete g_cdplay; g_cdplay = daePlayer = NULL;
- //second, try Windac
- if (!windacPlayer) windacPlayer = new WindacPlay;
- g_cdplay = windacPlayer;
- ret = (g_cdplay ? g_cdplay->play(playDriveLetter, track) : 0);
- if (ret != 0)
- {
- if (g_cdplay) delete g_cdplay; g_cdplay = windacPlayer = NULL;
- //try MCI
- if (!mciPlayer) mciPlayer = new MciPlay;
- g_cdplay = mciPlayer;
- int ret = (g_cdplay ? g_cdplay->play(playDriveLetter, track) : 1);
- if (ret != 0)
- {
- //no luck
- if (g_cdplay) delete g_cdplay; g_cdplay = mciPlayer = NULL;
- return ret;
- }
- }
- }
- paused = 0;
- return 0;
- }
- void pause()
- {
- if (g_cdplay) g_cdplay->pause();
- paused = 1;
- }
- void unpause()
- {
- if (g_cdplay) g_cdplay->unpause();
- paused = 0;
- }
- int ispaused()
- {
- return paused;
- }
- void stop()
- {
- if (g_cdplay)
- {
- g_cdplay->stop();
- g_cdplay = NULL;
- }
- done = 0;
- line.SAVSADeInit();
- }
- int getlength()
- {
- if (g_cdplay) return g_cdplay->getlength();
- return -1000;
- }
- int getoutputtime()
- {
- if (g_cdplay) return g_cdplay->getoutputtime();
- return 0;
- //return audioGetPos();
- }
- void setoutputtime(int time_in_ms)
- {
- if (g_cdplay) g_cdplay->setoutputtime(time_in_ms);
- }
- void setvolume(int volume)
- {
- if (volume != -666)
- {
- a_v = volume;
- }
- if (g_cdplay) g_cdplay->setvolume(a_v, a_p);
- }
- void setpan(int pan)
- {
- a_p = pan;
- if (g_cdplay) g_cdplay->setvolume(a_v, a_p);
- }
- int infoDlg(const in_char *fn, HWND hwnd)
- {
- return 0;
- #if 0 // switched to unified file info dialog in 5.53
- if (!_stricmp(extension(fn), "cda") || !_strnicmp(fn, "cda://", 6))
- {
- if (!g_ps_inuse)
- {
- char device;
- int res=1;
- MCIDEVICEID d = 0;
- g_ps_inuse = 1;
- device = fn[_strnicmp(fn, "cda://", 6) ? 0 : 6];
- if (device >= 'a' && device <= 'z') device += 'A' -'a';
- CDOpen(&d, device, L"infoDlg");
- memset(&g_ps, 0, sizeof(g_ps));
- res = GetDiscID(d, &g_ps);
- CDClose(&d);
- if (!res)
- res = GetCDDBInfo(&g_ps, device);
- //if (!res) DBEdit(&g_ps, hwnd, 0, device);
- //if (!res)
- {
- if (CDEdit(device, &g_ps, hwnd))
- {
- g_ps_inuse = 0;
- return INFOBOX_EDITED;
- }
- }
- g_ps_inuse = 0;
- }
- }
- return INFOBOX_UNCHANGED;
- #endif
- }
- void getfileinfo(const in_char *filename, in_char *title, int *length_in_ms)
- {
- #if 0
- int track;
- char device;
- MCIDEVICEID dev2 = 0;
- if (length_in_ms) *length_in_ms = -1000;
- if (!filename || !*filename) // currently playing
- {
- if (!_stricmp(extension(lastfn), "cda") || !_strnicmp(lastfn, "cda://", 6))
- {
- #ifdef IGNORE_API_GRACENOTE
- if (title)
- {
- lstrcpynA(title, "CD Track", GETFILEINFO_TITLE_LENGTH);
- if (!g_ps_inuse)
- {
- g_ps_inuse = 1;
- memset(&g_ps, 0, sizeof(g_ps));
- if (CDOpen(&dev2, playDriveLetter, L"getfileinfo"))
- {
- wchar_t wtitle[256] = {0};
- int ret = GetDiscID(dev2, &g_ps);
- CDClose(&dev2);
- if (!ret && GetCDDBInfo(&g_ps, 0)) // TODO: get device letter
- PostMessage(line.hMainWindow, WM_USER, (WPARAM) L"cda://", 247/*IPC_REFRESHPLCACHE*/);
- if (wtitle[0])
- lstrcpynA(title, AutoChar(wtitle), GETFILEINFO_TITLE_LENGTH);
-
- }
- g_ps_inuse = 0;
- }
- }
- if (length_in_ms) *length_in_ms = g_playlength;
- #endif
- }
- return ;
- }
- if (title)
- {
- const char *p = filename + strlen(filename);
- while (p >= filename && *p != '\\') p--;
- lstrcpynA(title, ++p, GETFILEINFO_TITLE_LENGTH);
- }
- track = 0;
- if (!_strnicmp(filename, "cda://", 6)) // determine length of cd track via MCI
- {
- track = atoi(filename + 8);
- device = filename[6];
- if (device >= 'a' && device <= 'z') device += 'A' -'a';
- if (length_in_ms)
- {
- if (CDOpen(&dev2, device, L"getfileinfo"))
- {
- MCI_SET_PARMS sMCISet;
- sMCISet.dwTimeFormat = MCI_FORMAT_MILLISECONDS;
- MCISendCommand(dev2, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD_PTR)(LPVOID) &sMCISet);
- *length_in_ms = CDGetTrackLength(dev2, track);
- sMCISet.dwTimeFormat = MCI_FORMAT_TMSF;
- MCISendCommand(dev2, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD_PTR)(LPVOID) &sMCISet);
- }
- }
- }
- else // determine from RIFF structure of .CDA
- {
- HMMIO hmmio;
- hmmio = mmioOpenA((char *)filename, NULL, MMIO_READ | MMIO_ALLOCBUF);
- device = filename[0];
- if (device >= 'a' && device <= 'z') device += 'A' -'a';
- if (hmmio)
- {
- MMCKINFO mmckinfoParent; // parent chunk information
- mmckinfoParent.fccType = mmioFOURCC('C', 'D', 'D', 'A');
- if (mmioDescend(hmmio, (LPMMCKINFO) &mmckinfoParent, NULL, MMIO_FINDRIFF) == MMSYSERR_NOERROR)
- {
- MMCKINFO mmckinfoSubchunk; // subchunk information structure
- mmckinfoSubchunk.ckid = mmioFOURCC('f', 'm', 't', ' ');
- if (mmioDescend(hmmio, &mmckinfoSubchunk, &mmckinfoParent, MMIO_FINDCHUNK) == MMSYSERR_NOERROR)
- {
- char *format;
- DWORD dwFmtSize; // size of "FMT" chunk
- dwFmtSize = mmckinfoSubchunk.cksize;
- format = (char *) GlobalAlloc(GPTR, dwFmtSize);
- if (mmioRead(hmmio, (HPSTR) format, dwFmtSize) == (int)dwFmtSize)
- {
- mmioAscend(hmmio, &mmckinfoSubchunk, 0);
- track = *((short int *)format + 1);
- if (length_in_ms)
- {
- int length = *((int *)format + 3);
- int l = length % 75;
- length /= 75;
- length *= 1000;
- length += (l * 1000) / 75;
- *length_in_ms = length;
- }
- }
- GlobalFree(format);
- }
- }
- mmioClose(hmmio, 0);
- }
- }
- #ifdef IGNORE_API_GRACENOTE
- if (title && track)
- {
- if (0 && !g_ps_inuse)
- {
- g_ps_inuse = 1;
- memset(&g_ps, 0, sizeof(g_ps));
- if (!dev2)
- {
- CDOpen(&dev2, device, L"getfileinfo");
- }
- if (dev2)
- {
- StringCchPrintfA(title, GETFILEINFO_TITLE_LENGTH, "CD Track %d", track);
- wchar_t wtitle[256] = L"";
- int ret = GetDiscID(dev2, &g_ps);
- CDClose(&dev2);
- dev2=0;
- if (!ret && GetCDDBInfo(&g_ps, device))
- PostMessage(line.hMainWindow, WM_USER, (WPARAM) L"cda://", 247 /*IPC_REFRESHPLCACHE*/);
- if (wtitle[0])
- lstrcpynA(title, AutoChar(wtitle), GETFILEINFO_TITLE_LENGTH);
- }
- g_ps_inuse = 0;
- }
- }
- #endif
- if (dev2) CDClose(&dev2);
- #endif
- }
- void eq_set(int on, char data[10], int preamp)
- {}
- In_Module line =
- {
- IN_VER_RET,
- "nullsoft(in_cdda.dll)",
- 0, // hMainWindow
- 0, // hDllInstance
- 0,
- 0, // is_seekable
- 1, // uses output plugins
- about,//config,
- about,
- init,
- quit,
- getfileinfo,
- infoDlg,
- isourfile,
- play,
- pause,
- unpause,
- ispaused,
- stop,
- getlength,
- getoutputtime,
- setoutputtime,
- setvolume,
- setpan,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, // dsp shit
- eq_set,
- NULL, // setinfo
- NULL // out_mod
- };
- int m_nblock = 0;
- extern "C"
- {
- __declspec(dllexport) In_Module * winampGetInModule2()
- {
- s_last_error = NULL;
- return &line;
- }
- #if 0 // TODO?
- __declspec(dllexport) int winampWriteExtendedFileInfo()
- {
- s_last_error = NULL;
- // write it out
- if (m_eiw_lastdrive)
- {
- AddToDatabase(&setInfo);
- m_eiw_lastdrive = 0;
- return 1;
- }
- return 0;
- }
- #endif
- };
- // wasabi based services for localisation support
- api_language *WASABI_API_LNG = 0;
- HINSTANCE WASABI_API_LNG_HINST = 0, WASABI_API_ORIG_HINST = 0;
- #ifndef IGNORE_API_GRACENOTE
- api_gracenote *AGAVE_API_GRACENOTE = 0;
- #endif
- api_application *WASABI_API_APP = 0;
- void SetFileExtensions(void)
- {
- static char fileExtensionsString[1200] = {0}; // "CDA\0CDDA Audio Tracks (*.CDA)\0"
- char* end = 0;
- StringCchCopyExA(fileExtensionsString, 1200, "CDA", &end, 0, 0);
- StringCchCopyExA(end+1, 1200, WASABI_API_LNGSTRING(IDS_CDDA_AUDIO_TRACKS), 0, 0, 0);
- line.FileExtensions = fileExtensionsString;
- }
- int init()
- {
- if (!IsWindow(line.hMainWindow))
- return IN_INIT_FAILURE;
- //CoInitialize(0);
- #ifndef IGNORE_API_GRACENOTE
- Cddb_Initialize();
- InitializeCddbCache();
- #endif
- // loader so that we can get the localisation service api for use
- waServiceFactory *sf = line.service->service_getServiceByGuid(languageApiGUID);
- if (sf) WASABI_API_LNG = reinterpret_cast<api_language*>(sf->getInterface());
- sf = line.service->service_getServiceByGuid(AgaveConfigGUID);
- if (sf) AGAVE_API_CONFIG = reinterpret_cast<api_config*>(sf->getInterface());
- #ifndef IGNORE_API_GRACENOTE
- sf = line.service->service_getServiceByGuid(gracenoteApiGUID);
- if (sf) AGAVE_API_GRACENOTE = reinterpret_cast<api_gracenote*>(sf->getInterface());
- #endif
- sf = line.service->service_getServiceByGuid(applicationApiServiceGuid);
- if (sf) WASABI_API_APP = reinterpret_cast<api_application*>(sf->getInterface());
- // need to have this initialised before we try to do anything with localisation features
- WASABI_API_START_LANG(line.hDllInstance,InCDDALangGUID);
- static wchar_t szDescription[256];
- StringCchPrintfW(szDescription,256,WASABI_API_LNGSTRINGW(IDS_NULLSOFT_CD_PLUGIN),PLUGIN_VERSION);
- line.description = (char*)szDescription;
- SetFileExtensions();
- playDeviceGuard = new Nullsoft::Utility::LockGuard;
- playStatusGuard = new Nullsoft::Utility::LockGuard;
- MainThreadId = GetCurrentThreadId();
- config_read();
- return IN_INIT_SUCCESS;
- }
- void quit()
- {
- #ifndef IGNORE_API_GRACENOTE
- ShutdownMusicIDWorkOrder();
- #endif
- if (playStatusGuard)
- {
- delete playStatusGuard;
- playStatusGuard = 0;
- }
- if (windacPlayer)
- {
- delete windacPlayer;
- windacPlayer = NULL;
- }
- if (daePlayer)
- {
- delete daePlayer;
- daePlayer = NULL;
- }
- if (mciPlayer)
- {
- delete mciPlayer;
- mciPlayer = NULL;
- }
- #ifndef IGNORE_API_GRACENOTE
- ShutDownCDDB();
- #endif
- waServiceFactory *sf = line.service->service_getServiceByGuid(languageApiGUID);
- if (sf) sf->releaseInterface(WASABI_API_LNG);
- sf = line.service->service_getServiceByGuid(AgaveConfigGUID);
- if (sf) sf->releaseInterface(AGAVE_API_CONFIG);
- #ifndef IGNORE_API_GRACENOTE
- sf = line.service->service_getServiceByGuid(gracenoteApiGUID);
- if (sf) sf->releaseInterface(AGAVE_API_GRACENOTE);
- Cddb_Uninitialize();
- UninitializeCddbCache();
- #endif
- CloseTables();
- //CoUninitialize();
- }
|