123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714 |
- #include "NJBDevice.h"
- #include "../nu/AutoWide.h"
- #include "../nu/AutoChar.h"
- HWND CreateDummyWindow();
- extern HWND mainMessageWindow;
- static __int64 fileSize(wchar_t * filename)
- {
- WIN32_FIND_DATA f={0};
- HANDLE h = FindFirstFileW(filename,&f);
- if(h == INVALID_HANDLE_VALUE) return -1;
- FindClose(h);
- ULARGE_INTEGER i;
- i.HighPart = f.nFileSizeHigh;
- i.LowPart = f.nFileSizeLow;
- return i.QuadPart;
- }
- static void FillSongFromMeta(BYTE * buf,Song * song) {
- BYTE * ptr = buf;
- short count = 0;
- short type = 0;
- short NameLen = 0;
- long DataLen = 0;
- long lData;
- memcpy(&count, ptr, sizeof(short));
- ptr += sizeof(short);
-
- for(int i=0; i<count; i++)
- {
- memcpy(&type, ptr, sizeof(short));
- ptr += sizeof(short);
- memcpy(&NameLen, ptr, sizeof(short));
- ptr += sizeof(short);
- memcpy(&DataLen, ptr, sizeof(long));
- ptr += sizeof(long);
- char itemname[MAX_PATH] = {0};
- memcpy(itemname, ptr, NameLen);
- itemname[NameLen]=0;
- ptr += NameLen;
- if(type == 1) { // binary
- memcpy(&lData, ptr, min(DataLen,4));
- if (!_stricmp(itemname,LENGTH)) song->length = lData * 1000;
- else if (!_stricmp(itemname,FILESIZE)) song->size = lData;
- else if (!_stricmp(itemname,TRACKNUM)) song->track = lData;
- else if (!_stricmp(itemname,YEAR)) song->year = lData;
- else if (!_stricmp(itemname,TRACKID)) song->trackid = lData;
- } else if(type == 2) { // unicode
- if (!_stricmp(itemname,TITLE)) lstrcpyn(song->title,(WCHAR*)ptr,min((DataLen+2)/2,fieldlen));
- else if (!_stricmp(itemname,ARTIST)) lstrcpyn(song->artist,(WCHAR*)ptr,min((DataLen+2)/2,fieldlen));
- else if (!_stricmp(itemname,ALBUM)) lstrcpyn(song->album,(WCHAR*)ptr,min((DataLen+2)/2,fieldlen));
- else if (!_stricmp(itemname,GENRE)) lstrcpyn(song->genre,(WCHAR*)ptr,min((DataLen+2)/2,fieldlen));
- } else if(type == 0) { // ASCII
- if (!_stricmp(itemname,CODEC)) {
- int l=min(sizeof(song->codec)-1,DataLen);
- memcpy(song->codec,ptr,l);
- song->codec[l]=0;
- }
- }
- ptr += DataLen;
- }
- }
- static bool GetSong(DAPSDK_ID * item, long id, Song * song) {
- long size;
- if(m_pCTJukebox2->GetItemAttribute(id,(IUnknown*)item,0,&size,NULL) != S_OK) return false;
- BYTE * buf = (BYTE*)calloc(size,sizeof(BYTE));
- if(!buf) return false;
- if(m_pCTJukebox2->GetItemAttribute(id,(IUnknown*)item,size,&size,(IUnknown*)buf) != S_OK) { free(buf); return false; }
- FillSongFromMeta(buf,song);
- free(buf);
- return true;
- }
- static int song_sortfunc(const void *elem1, const void *elem2) {
- Song *a=(Song *)*(void **)elem1;
- Song *b=(Song *)*(void **)elem2;
- return a->trackid - b->trackid;
- }
- static Song *BinaryChopFind(int id,Playlist * mpl) {
- Song s;
- s.trackid=id;
- Song * d = &s;
- Song ** ret = (Song**)bsearch(&d,mpl->songs.GetAll(),mpl->songs.GetSize(),sizeof(void*),song_sortfunc);
- return ret?*ret:NULL;
- }
- static bool GetPlaylist(long id, DAPSDK_ID * item,Playlist * pl, Playlist * mpl)
- {
- pl->dirty=false;
- pl->plid = item->lID;
- lstrcpyn(pl->name,item->bstrName,fieldlen);
- SysFreeString(item->bstrName);
- DAPSDK_ID song;
- HRESULT hr = m_pCTJukebox2->FindFirstItem(id,(IUnknown*)item,(IUnknown*)&song);
- while(hr == S_OK) {
- Song * s = BinaryChopFind(song.lID,mpl);
- if(s) pl->songs.Add(s);
- hr = m_pCTJukebox2->FindNextItem(id,(IUnknown*)item,(IUnknown*)&song);
- }
- return true;
- }
- NJBDevice::NJBDevice(long id) : transcoder(NULL)
- {
- InitializeCriticalSection(&csRevTransfer);
- InitializeCriticalSection(&csTransfer);
- devices.Add(this);
-
- pmpDeviceLoading load;
- load.dev = this;
- load.UpdateCaption = NULL;
- SendMessage(plugin.hwndPortablesParent,WM_PMP_IPC,(intptr_t)&load,PMP_IPC_DEVICELOADING);
- if(load.UpdateCaption) {
- load.UpdateCaption(WASABI_API_LNGSTRINGW(IDS_NJB_LOADING),load.context);
- }
- this->id = id;
- transferQueueLength = 0;
- messageWindow = CreateDummyWindow();
- m_pCTJukebox2->SetCallbackWindow2(id,(long)messageWindow);
- BYTE * ptr = NULL;
- if(m_pCTJukebox2->GetDeviceProperties(id,kDeviceSerialNumberValue,(IUnknown*)ptr) == S_OK) {
- memcpy(serial,ptr,16);
- //free(ptr);
- }
- DAPSDK_ID item,parent,root;
- Playlist * mpl = new Playlist;
- BSTR name=NULL;
- m_pCTJukebox2->GetDeviceProperties(id,kDeviceNameString,(IUnknown*)&name);
- lstrcpyn(mpl->name,name?name:L"Creative Jukebox",fieldlen);
- SysFreeString(name);
- // search for tracks...
- parent.lID = ALLTRACKSKEY;
- parent.lType = kAudioTrackType;
- HRESULT hr = m_pCTJukebox2->FindFirstItem(id,(IUnknown*)&parent,(IUnknown*)&item);
-
- while(hr == S_OK) {
- // add track
- Song * song = new Song;
- if(GetSong(&item,id,song)) {
- mpl->songs.Add(song);
- song->trackid = item.lID;
- }
- else delete song;
- hr = m_pCTJukebox2->FindNextItem(id,(IUnknown*)&parent,(IUnknown*)&item);
- }
- qsort(mpl->songs.GetAll(),mpl->songs.GetSize(),sizeof(void*),song_sortfunc); // sort the master playlist by trackid, so we can find stuff later using binary chop
- playlists.Add(mpl);
- // search for playlists...
- hr = m_pCTJukebox2->FindFirstRootItem(id,(IUnknown*)&root);
- while(hr == S_OK) {
- if(_wcsicmp(root.bstrName,L"PLAY LISTS")==0) {
- playlistRoot.bstrName = L"PLAY LISTS";
- playlistRoot.lID = root.lID;
- playlistRoot.lType = root.lType;
- HRESULT hr = m_pCTJukebox2->FindFirstParentItem(id,(IUnknown*)&root,(IUnknown*)&parent);
- while(hr == S_OK) {
- Playlist * pl = new Playlist;
- if(GetPlaylist(id,&parent,pl,mpl)) playlists.Add(pl);
- else delete pl;
- hr = m_pCTJukebox2->FindNextParentItem(id,(IUnknown*)&root,(IUnknown*)&parent);
- }
- }
- SysFreeString(root.bstrName);
- hr = m_pCTJukebox2->FindNextRootItem(id,(IUnknown*)&root);
- }
-
- SendMessage(plugin.hwndPortablesParent,WM_PMP_IPC,(intptr_t)this,PMP_IPC_DEVICECONNECTED);
- //transcoder = NULL;
- transcoder = (Transcoder*)SendMessage(plugin.hwndPortablesParent,WM_PMP_IPC,(intptr_t)this,PMP_IPC_GET_TRANSCODER);
- if(transcoder) {
- transcoder->AddAcceptableFormat(L"mp3");
- //transcoder->AddAcceptableFormat(L"wav");
- transcoder->AddAcceptableFormat(L"wma");
- }
- }
- NJBDevice::~NJBDevice()
- {
- m_pCTJukebox2->SetCallbackWindow2(id, (long)mainMessageWindow);
- DestroyWindow(messageWindow);
- messageWindow = NULL;
- Playlist * mpl = (Playlist *)playlists.Get(0);
- int l = mpl->songs.GetSize();
- for(int i=0; i<l; i++) delete (Song *)mpl->songs.Get(i);
- l = playlists.GetSize();
- for(int i=0; i<l; i++) delete (Playlist *)playlists.Get(i);
- for(int i=0; i<devices.GetSize(); i++) if(devices.Get(i) == this) { devices.Del(i); break; }
- DeleteCriticalSection(&csRevTransfer);
- DeleteCriticalSection(&csTransfer);
- if(transcoder) SendMessage(plugin.hwndPortablesParent,WM_PMP_IPC,(WPARAM)transcoder,PMP_IPC_RELEASE_TRANSCODER);
- }
- __int64 NJBDevice::getDeviceCapacityAvailable() {
- DAPSDK_STORAGE_INFO s;
- ULARGE_INTEGER ret;
- m_pCTJukebox2->GetDeviceProperties(id,kStorageInfoStruct,(IUnknown*)&s);
- ret.LowPart = s.freeL;
- ret.HighPart = s.freeH;
- return ret.QuadPart;
- }
- __int64 NJBDevice::getDeviceCapacityTotal() {
- DAPSDK_STORAGE_INFO s;
- ULARGE_INTEGER ret;
- m_pCTJukebox2->GetDeviceProperties(id,kStorageInfoStruct,(IUnknown*)&s);
- ret.LowPart = s.totalL;
- ret.HighPart = s.totalH;
- return ret.QuadPart;
- }
- void NJBDevice::Eject() {
- Close();
- }
- void NJBDevice::Close()
- {
- commitChanges();
- SendMessage(plugin.hwndPortablesParent,WM_PMP_IPC,(intptr_t)this,PMP_IPC_DEVICEDISCONNECTED);
- if(devices.GetSize() == 1)
- m_pCTJukebox2->SetCallbackWindow2(0,(long)mainMessageWindow);
- delete this;
- }
- static BYTE * setAttrib(BYTE * ptr,short type, char * name, BYTE * data, int datalen) {
- short namelen = (short)strlen(name);
- memcpy(ptr,&type,2); ptr += 2;
- memcpy(ptr,&namelen,2); ptr += 2;
- memcpy(ptr,&datalen,4); ptr += 4;
- memcpy(ptr,name,namelen); ptr += namelen;
- memcpy(ptr,data,datalen); ptr += datalen;
- return ptr;
- }
- static BYTE * makeMetaFromItemRecord(itemRecordW * item, wchar_t * file, long * size) {
- char codec[4]="WAV";
- wchar_t * ext = wcsrchr(file,L'.') + 1;
- if(!_wcsicmp(ext,L"mp3")) strncpy(codec,"MP3",3);
- else if(!_wcsicmp(ext,L"wma")) strncpy(codec,"WMA",3);
- if(!item->album) item->album = _wcsdup(L"");
- if(!item->artist) item->artist = _wcsdup(L"");
- if(!item->title) item->title = _wcsdup(L"");
- *size = (long)(2/*count*/+2/*type*/+6/*namelen+datalen*/+strlen(TITLE)+2*wcslen(item->title)
- +2+6+strlen(ALBUM)+2*wcslen(item->album)
- +2+6+strlen(ARTIST)+2*wcslen(item->artist)
- +2+6+strlen(CODEC)+strlen(codec)
- +2+6+strlen(FILESIZE)+sizeof(long)
- +2+6+strlen(LENGTH)+sizeof(long));
-
- int count = 6;
- if (item->year > 0 ){
- *size+=2+6+(long)strlen(YEAR)+sizeof(short);
- count++;
- }
- if (item->genre) {
- *size+=(long)(2+6+strlen(GENRE)+2*wcslen(item->genre));
- count++;
- }
- if (item->track>0) {
- *size+= (long)(2+6+strlen(TRACKNUM)+sizeof(short));
- count++;
- }
- BYTE *buf = (BYTE*)calloc(1,*size);
- BYTE *ptr = buf;
- memcpy(ptr, &count, sizeof(short));
- ptr += sizeof(short);
-
- ptr = setAttrib(ptr,2,TITLE,(BYTE*)((wchar_t*)(item->title)),(int)wcslen(item->title)*2);
- ptr = setAttrib(ptr,2,ARTIST,(BYTE*)((wchar_t*)(item->artist)), (int)wcslen(item->artist)*2);
- ptr = setAttrib(ptr,2,ALBUM,(BYTE*)((wchar_t*)(item->album)), (int)wcslen(item->album)*2);
- if(item->genre) ptr = setAttrib(ptr,2,GENRE,(BYTE*)((wchar_t*)(item->genre)), (int)wcslen(item->genre)*2);
- short v = item->track;
- if(item->track>0) ptr = setAttrib(ptr,1,TRACKNUM,(BYTE*)&v,2);
- v = item->year;
- if(item->year>0) ptr = setAttrib(ptr,1,YEAR,(BYTE*)&v,2);
- ptr = setAttrib(ptr,0,CODEC,(BYTE*)codec,(int)strlen(codec));
- ptr = setAttrib(ptr,1,LENGTH,(BYTE*)&item->length,4);
- __int64 filesize = fileSize(file);
- ptr = setAttrib(ptr,1,FILESIZE,(BYTE*)&filesize,4);
- return buf;
- }
- BOOL NJBDevice::WindowMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- switch(uMsg) {
- case WM_USER: // start add item
- if(transferItem.status == 0) {
- long size;
- BYTE * buf = makeMetaFromItemRecord(const_cast<itemRecordW *>(transferItem.track),transferItem.file,&size);
- HRESULT hr = m_pCTJukebox2->AddItem(id,kAudioTrackType,SysAllocString(transferItem.file),size,(IUnknown*)buf);
- transferItem.meta = buf;
- if(hr != S_OK) this->WindowMessage(hwnd,WM_DAPSDK_ADDITEM_COMPLETE,-1,0);
- }
- break;
- case WM_DAPSDK_ADDITEM_PROGRESS:
- {
- wchar_t buf[100] = {0};
- wsprintf(buf,WASABI_API_LNGSTRINGW(IDS_TRANSFERRING_PERCENT),(int)wParam);
- transferItem.callback(transferItem.callbackContext,buf);
- }
- break;
- case WM_DAPSDK_ADDITEM_COMPLETE:
- if(wParam == 0) {
- transferItem.callback(transferItem.callbackContext,WASABI_API_LNGSTRINGW(IDS_DONE));
- Song * song = new Song;
- song->trackid = (int)lParam;
- FillSongFromMeta(transferItem.meta,song);
- song->track = transferItem.track->track;
- song->year = transferItem.track->year;
- *transferItem.songid = (songid_t)song;
- }
- else {
- transferItem.callback(transferItem.callbackContext,WASABI_API_LNGSTRINGW(IDS_ERROR));
- }
- transferItem.status = (wParam==0?1:2);
- free(transferItem.meta);
- break;
- case WM_USER+1: // start get item
- if(revTransferItem.status == 0) {
- Song * song = (Song*)*revTransferItem.songid;
- DAPSDK_ID item = {song->trackid,kAudioTrackType,song->title};
- // memory allocated by SysAllocString is freed by COM (why, i don't know)
- HRESULT hr = m_pCTJukebox2->GetItem(id,SysAllocString(revTransferItem.file),(IUnknown*)&item);
- if(hr != S_OK) WindowMessage(hwnd,WM_DAPSDK_GETITEM_COMPLETE,-1,0);
- }
- break;
- case WM_DAPSDK_GETITEM_PROGRESS:
- {
- wchar_t buf[100] = {0};
- wsprintf(buf,WASABI_API_LNGSTRINGW(IDS_TRANSFERRING_PERCENT),(int)wParam);
- revTransferItem.callback(revTransferItem.callbackContext,buf);
- }
- break;
- case WM_DAPSDK_GETITEM_COMPLETE:
- revTransferItem.callback(revTransferItem.callbackContext,
- WASABI_API_LNGSTRINGW((wParam==0?IDS_DONE:IDS_ERROR)));
- revTransferItem.status = (wParam==0?1:2);
- break;
- }
- return 0;
- }
- //p75
- int NJBDevice::transferTrackToDevice(const itemRecordW * track,void * callbackContext,void (*callback)(void * callbackContext, wchar_t * status),songid_t * songid,int * killswitch) {
- wchar_t file[2048] = {0};
- wcsncpy(file,track->filename,2048);
- bool deletefile = false;
- if(transcoder) if(transcoder->ShouldTranscode(file)) {
- wchar_t newfile[MAX_PATH] = {0};
- wchar_t ext[10] = {0};
- transcoder->CanTranscode(file,ext);
- transcoder->GetTempFilePath(ext,newfile);
- if(transcoder->TranscodeFile(file,newfile,killswitch,callback,callbackContext)) return -1;
- wcsncpy(file,newfile,2048);
- deletefile=true;
- }
- EnterCriticalSection(&csTransfer);
- callback(callbackContext,WASABI_API_LNGSTRINGW(IDS_TRANSFERRING));
- transferItem.file = file;
- transferItem.callback = callback;
- transferItem.callbackContext = callbackContext;
- transferItem.status=0; // in progress
- transferItem.killswitch = killswitch;
- transferItem.songid = songid;
- transferItem.track = track;
- //now start the transfer
- PostMessage(messageWindow,WM_USER,0,0);
- while(transferItem.status==0) Sleep(10); // wait for transfer
- // transfer completed
- int ret = transferItem.status==1?0:-1;
- LeaveCriticalSection(&csTransfer);
- if(deletefile) _wunlink(file);
- return ret;
- }
- int NJBDevice::trackAddedToTransferQueue(const itemRecordW * track) {
- __int64 l;
- if(transcoder && transcoder->ShouldTranscode(track->filename)) {
- int k = transcoder->CanTranscode(track->filename);
- if(k == -1) return -2;
- if(k == 0) l = fileSize(track->filename);
- else l = (__int64)k;
- } else {
- wchar_t * ext = wcsrchr(track->filename,L'.');
- if(!ext) return -2;
- if(_wcsicmp(ext,L".mp3") && _wcsicmp(ext,L".wma") && _wcsicmp(ext,L".wav")) return -2;
- l = fileSize(track->filename);
- }
- if(transferQueueLength + l + 1000000 > getDeviceCapacityAvailable())
- return -1;
- else {
- transferQueueLength += l;
- return 0;
- }
- }
- void NJBDevice::trackRemovedFromTransferQueue(const itemRecordW * track) {
- __int64 l = (__int64)fileSize(track->filename);
- if(transcoder && transcoder->ShouldTranscode(track->filename)) {
- int k = transcoder->CanTranscode(track->filename);
- if(k != -1 && k != 0) l = (__int64)k;
- }
- transferQueueLength -= l;
- }
- __int64 NJBDevice::getTrackSizeOnDevice(const itemRecordW * track) {
- if(transcoder && transcoder->ShouldTranscode(track->filename)) {
- int k = transcoder->CanTranscode(track->filename);
- if(k != -1 && k != 0) return k;
- }
- wchar_t * ext = wcsrchr(track->filename,L'.');
- if(!ext) return 0;
- if(_wcsicmp(ext,L".mp3") && _wcsicmp(ext,L".wma") && _wcsicmp(ext,L".wav")) return 0;
- return fileSize(track->filename);
- }
- void NJBDevice::deleteTrack(songid_t songid) {
- Song * s = (Song*)songid;
- for(int i=0; i<playlists.GetSize(); i++) {
- Playlist * pl = (Playlist *)playlists.Get(i);
- int l = pl->songs.GetSize();
- while(l-- > 0) if(pl->songs.Get(l) == (void*)s) { pl->songs.Del(l); if(i>0) pl->dirty=true; }
- }
- DAPSDK_ID item = {s->trackid,kAudioTrackType,s->title};
- m_pCTJukebox2->DeleteItem(id,(IUnknown*)&item);
- delete s;
- }
- void NJBDevice::commitChanges() {
- for(int i=1; i<playlists.GetSize(); i++) {
- Playlist * pl = (Playlist *)playlists.Get(i);
- if(pl->dirty) {
- pl->dirty = false;
- DAPSDK_ID parentold = {pl->plid,kPlaylistType,pl->name};
- m_pCTJukebox2->DeleteParentItem(id,(IUnknown*)&parentold);
- DAPSDK_ID parent = {0,kPlaylistType,_wcsdup(pl->name)};
- m_pCTJukebox2->AddParentItem(id,(IUnknown*)&playlistRoot,(IUnknown*)&parent);
- pl->plid = parent.lID;
- long l = pl->songs.GetSize();
- DAPSDK_ID * list = (DAPSDK_ID *)calloc(sizeof(DAPSDK_ID),l);
- for(int j=0; j<l; j++) {
- Song * s = (Song*)pl->songs.Get(j);
- if(s) {
- list[j].lID = s->trackid;
- list[j].lType = kAudioTrackType;
- list[j].bstrName = SysAllocString(s->title);
- }
- }
- m_pCTJukebox2->AddItemsToParentItem(id,(IUnknown*)&parent,l,(IUnknown*)list);
- free(list);
- }
- }
- }
- int NJBDevice::getPlaylistCount() {
- return playlists.GetSize();
- }
- void NJBDevice::getPlaylistName(int playlistnumber, wchar_t * buf, int len) {
- Playlist * pl = (Playlist *)playlists.Get(playlistnumber);
- lstrcpyn(buf,pl->name,len);
- }
- int NJBDevice::getPlaylistLength(int playlistnumber) {
- Playlist * pl = (Playlist *)playlists.Get(playlistnumber);
- return pl->songs.GetSize();
- }
- songid_t NJBDevice::getPlaylistTrack(int playlistnumber,int songnum) {
- Playlist * pl = (Playlist *)playlists.Get(playlistnumber);
- return (songid_t) pl->songs.Get(songnum);
- }
- void NJBDevice::setPlaylistName(int playlistnumber, const wchar_t * buf) {
- Playlist * pl = (Playlist *)playlists.Get(playlistnumber);
- lstrcpyn(pl->name,buf,fieldlen);
- DAPSDK_ID item = {pl->plid,kPlaylistType,pl->name};
- BSTR name = SysAllocString(buf);
- m_pCTJukebox2->RenameParentItem(id,(IUnknown*)&item, name);
- SysFreeString(name);
- }
- void NJBDevice::playlistSwapItems(int playlistnumber, int posA, int posB) {
- Playlist * pl = (Playlist *)playlists.Get(playlistnumber);
- void * a = pl->songs.Get(posA);
- void * b = pl->songs.Get(posB);
- pl->songs.Set(posA,b);
- pl->songs.Set(posB,a);
- pl->dirty = true;
- }
- static int sortby;
- #define RETIFNZ(v) if ((v)!=0) return v;
- #define STRCMP_NULLOK _wcsicmp
- static int sortFunc(const void *elem1, const void *elem2)
- {
- int use_by = sortby;
- Song *a=(Song *)*(void **)elem1;
- Song *b=(Song *)*(void **)elem2;
- // this might be too slow, but it'd be nice
- int x;
- for (x = 0; x < 5; x ++)
- {
- if (use_by == SORTBY_TITLE) // title -> artist -> album -> disc -> track
- {
- int v=STRCMP_NULLOK(a->title,b->title);
- RETIFNZ(v)
- use_by=SORTBY_ARTIST;
- }
- else if (use_by == SORTBY_ARTIST) // artist -> album -> disc -> track -> title
- {
- int v=STRCMP_NULLOK(a->artist,b->artist);
- RETIFNZ(v)
- use_by=SORTBY_ALBUM;
- }
- else if (use_by == SORTBY_ALBUM) // album -> disc -> track -> title -> artist
- {
- int v=STRCMP_NULLOK(a->album,b->album);
- RETIFNZ(v)
- use_by=SORTBY_DISCNUM;
- }
- else if (use_by == SORTBY_TRACKNUM) // track -> title -> artist -> album -> disc
- {
- int v1=a->track;
- int v2=b->track;
- if (v1<0)v1=0;
- if (v2<0)v2=0;
- RETIFNZ(v1-v2)
- use_by=SORTBY_TITLE;
- }
- else if (use_by == SORTBY_GENRE) // genre -> artist -> album -> disc -> track
- {
- int v=STRCMP_NULLOK(a->genre,b->genre);
- RETIFNZ(v)
- use_by=SORTBY_ARTIST;
- }
- else break; // no sort order?
- }
- return 0;
- }
- #undef RETIFNZ
- #undef STRCMP_NULLOK
- void NJBDevice::sortPlaylist(int playlistnumber, int sortBy) {
- sortby = sortBy;
- Playlist * pl = (Playlist *)playlists.Get(playlistnumber);
- qsort(pl->songs.GetAll(),pl->songs.GetSize(),sizeof(void*),sortFunc);
- pl->dirty=true;
- }
- void NJBDevice::addTrackToPlaylist(int playlistnumber, songid_t songid) {
- Playlist * pl = (Playlist *)playlists.Get(playlistnumber);
- pl->songs.Add((void*)songid);
- pl->dirty = true;
- }
- void NJBDevice::removeTrackFromPlaylist(int playlistnumber, int songnum) {
- Playlist * pl = (Playlist *)playlists.Get(playlistnumber);
- pl->songs.Del(songnum);
- pl->dirty = true;
- }
- void NJBDevice::deletePlaylist(int playlistnumber) {
- Playlist * pl = (Playlist *)playlists.Get(playlistnumber);
- DAPSDK_ID parent = {pl->plid,kPlaylistType,pl->name};
- m_pCTJukebox2->DeleteParentItem(id,(IUnknown*)&parent);
- playlists.Del(playlistnumber);
- delete pl;
- }
- int NJBDevice::newPlaylist(const wchar_t * name) {
- Playlist * pl = new Playlist;
- pl->dirty = false;
- lstrcpyn(pl->name,name,fieldlen);
- DAPSDK_ID parent = {0,kPlaylistType,pl->name};
- m_pCTJukebox2->AddParentItem(id,(IUnknown*)&playlistRoot,(IUnknown*)&parent);
- pl->plid = parent.lID;
- playlists.Add(pl);
- return playlists.GetSize() - 1;
- }
- void NJBDevice::getTrackArtist(songid_t songid, wchar_t * buf, int len) {lstrcpyn(buf,((Song*)songid)->artist,len);}
- void NJBDevice::getTrackAlbum(songid_t songid, wchar_t * buf, int len) {lstrcpyn(buf,((Song*)songid)->album,len);}
- void NJBDevice::getTrackTitle(songid_t songid, wchar_t * buf, int len) {lstrcpyn(buf,((Song*)songid)->title,len);}
- void NJBDevice::getTrackGenre(songid_t songid, wchar_t * buf, int len) {lstrcpyn(buf,((Song*)songid)->genre,len);}
- int NJBDevice::getTrackTrackNum(songid_t songid) {return ((Song*)songid)->track;}
- int NJBDevice::getTrackDiscNum(songid_t songid) {return -1;}
- int NJBDevice::getTrackYear(songid_t songid) {return ((Song*)songid)->year;}
- __int64 NJBDevice::getTrackSize(songid_t songid) {return ((Song*)songid)->size;}
- int NJBDevice::getTrackLength(songid_t songid) {return ((Song*)songid)->length;}
- int NJBDevice::getTrackBitrate(songid_t songid) {return -1;}
- int NJBDevice::getTrackPlayCount(songid_t songid) {return -1;}
- int NJBDevice::getTrackRating(songid_t songid) {return -1;}
- __time64_t NJBDevice::getTrackLastPlayed(songid_t songid) {return -1;}
- __time64_t NJBDevice::getTrackLastUpdated(songid_t songid) {return -1;}
- void NJBDevice::getTrackExtraInfo(songid_t songid, const wchar_t * field, wchar_t * buf, int len) {
- if(!wcscmp(field,L"ext")) {
- Song * s = (Song *)songid;
- lstrcpyn(buf,(wchar_t*)AutoWide(s->codec),len);
- wchar_t * p = buf;
- while(p && *p) { *p=towlower(*p); p++; }
- }
- }
- void NJBDevice::setTrackArtist(songid_t songid, const wchar_t * value) {
- Song * s = (Song *)songid;
- lstrcpyn(s->artist,value,fieldlen);
- DAPSDK_ID item = {s->trackid,kAudioTrackType,s->title};
- m_pCTJukebox2->SetItemAttribute(id,(IUnknown*)&item,L"ARTIST",2,(long)wcslen(value)*2+2,(IUnknown*)value);
- }
- void NJBDevice::setTrackAlbum(songid_t songid, const wchar_t * value) {
- Song * s = (Song *)songid;
- lstrcpyn(s->album,value,fieldlen);
- DAPSDK_ID item = {s->trackid,kAudioTrackType,s->title};
- m_pCTJukebox2->SetItemAttribute(id,(IUnknown*)&item,L"ALBUM",2, (long)wcslen(value)*2+2,(IUnknown*)value);
- }
- void NJBDevice::setTrackTitle(songid_t songid, const wchar_t * value) {
- Song * s = (Song *)songid;
- lstrcpyn(s->title,value,fieldlen);
- DAPSDK_ID item = {s->trackid,kAudioTrackType,s->title};
- m_pCTJukebox2->SetItemAttribute(id,(IUnknown*)&item,L"TITLE",2, (long)wcslen(value)*2+2,(IUnknown*)value);
- }
- void NJBDevice::setTrackGenre(songid_t songid, const wchar_t * value) {
- Song * s = (Song *)songid;
- lstrcpyn(s->genre,value,fieldlen);
- DAPSDK_ID item = {s->trackid,kAudioTrackType,s->title};
- m_pCTJukebox2->SetItemAttribute(id,(IUnknown*)&item,L"GENRE",2, (long)wcslen(value)*2+2,(IUnknown*)value);
- }
- void NJBDevice::setTrackTrackNum(songid_t songid, int value) {
- Song * s = (Song *)songid;
- s->track = value;
- DAPSDK_ID item = {s->trackid,kAudioTrackType,s->title};
- m_pCTJukebox2->SetItemAttribute(id,(IUnknown*)&item,L"TRACK NUM",1,sizeof(short),(IUnknown*)&value);
- }
- void NJBDevice::setTrackYear(songid_t songid, int value) {
- Song * s = (Song *)songid;
- s->year = value;
- DAPSDK_ID item = {s->trackid,kAudioTrackType,s->title};
- m_pCTJukebox2->SetItemAttribute(id,(IUnknown*)&item,L"YEAR",1,sizeof(short),(IUnknown*)&value);
- }
- int NJBDevice::copyToHardDrive(songid_t s,wchar_t * path,void * callbackContext,void (*callback)(void * callbackContext, wchar_t * status),int * killswitch) {
- EnterCriticalSection(&csRevTransfer);
- callback(callbackContext,WASABI_API_LNGSTRINGW(IDS_TRANSFERRING));
- Song * song = (Song*)s;
- wcscat(path,L".");
- wcscat(path,AutoWide(song->codec));
- wchar_t *p = wcsrchr(path,L'.');
- while(p && *p) { *p = towlower(*p); p++; }
- revTransferItem.callback = callback;
- revTransferItem.callbackContext = callbackContext;
- revTransferItem.killswitch = killswitch;
- revTransferItem.songid = &s;
- revTransferItem.file = path;
- revTransferItem.status = 0;
- PostMessage(messageWindow,WM_USER+1,0,0);
-
- while(revTransferItem.status==0) Sleep(10); // wait for transfer
-
- int ret = revTransferItem.status==1?0:-1;
-
- LeaveCriticalSection(&csRevTransfer);
- return ret;
- }
- intptr_t NJBDevice::extraActions(intptr_t param1, intptr_t param2, intptr_t param3,intptr_t param4) {
- switch(param1) {
- case DEVICE_SET_ICON:
- {
- MLTREEIMAGE * i = (MLTREEIMAGE*)param2;
- i->hinst = plugin.hDllInstance;
- i->resourceId = IDR_ZEN_ICON;
- }
- break;
- case DEVICE_SUPPORTED_METADATA:
- return 0x3ef;
- }
- return 0;
- }
|