Initial community commit

This commit is contained in:
Jef
2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit 20d28e80a5
16810 changed files with 4640254 additions and 2 deletions

View File

@ -0,0 +1,714 @@
#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;
}

View File

@ -0,0 +1,168 @@
#ifndef _NJBDEVICE_H_
#define _NJBDEVICE_H_
#ifndef _UNICODE
#define _UNICODE
#endif
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
#include <windowsx.h>
#include <Objbase.h>
#include <initguid.h>
#include <stdio.h>
#include <shlobj.h>
#include <wchar.h>
#include "../Plugins/General/gen_ml/ml.h"
#include "../Plugins/Library/ml_pmp/pmp.h"
#include "../Plugins/Library/ml_pmp/transcoder.h"
#include "../Plugins/General/gen_ml/itemlist.h"
#include "Nmsdk.h"
#include "resource.h"
#include "../Agave/Language/api_language.h"
#include <api/service/waServiceFactory.h>
extern PMPDevicePlugin plugin;
extern LRESULT CALLBACK CallbackWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
extern C_ItemList devices;
extern ICTJukebox2 * m_pCTJukebox2;
#define fieldlen 256
class Playlist {
public:
bool dirty;
int plid;
wchar_t name[fieldlen];
C_ItemList songs;
};
class Song {
public:
char codec[5];
int trackid;
wchar_t artist[fieldlen];
wchar_t album[fieldlen];
wchar_t title[fieldlen];
wchar_t genre[fieldlen];
int year,track,size,length;
};
class TransferItem {
public:
const itemRecordW * track;
void* callbackContext;
void (*callback)(void * callbackContext, wchar_t * status);
songid_t * songid;
int * killswitch;
int status;
BYTE * meta;
wchar_t * file;
};
class NJBDevice : public Device {
public:
Transcoder * transcoder;
BYTE serial[16];
__int64 transferQueueLength;
DAPSDK_ID playlistRoot;
C_ItemList playlists;
int id;
HWND messageWindow;
TransferItem transferItem;
TransferItem revTransferItem;
CRITICAL_SECTION csTransfer;
CRITICAL_SECTION csRevTransfer;
NJBDevice(long id);
virtual ~NJBDevice();
virtual BOOL WindowMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
virtual __int64 getDeviceCapacityAvailable(); // in bytes
virtual __int64 getDeviceCapacityTotal(); // in bytes
virtual void Eject(); // if you ejected successfully, you MUST call plugin.deviceDisconnected(this) and delete this;
virtual void Close(); // save any changes, and call plugin.deviceDisconnected(this) AND delete this;
// return 0 for success, -1 for failed or cancelled
virtual int transferTrackToDevice(const itemRecordW * track, // the track to transfer
void * callbackContext, //pass this to the callback
void (*callback)(void * callbackContext, wchar_t * status), // call this every so often so the GUI can be updated. Including when finished!
songid_t * songid, // fill in the songid when you are finished
int * killswitch // if this gets set to anything other than zero, the transfer has been cancelled by the user
);
virtual int trackAddedToTransferQueue(const itemRecordW * track); // return 0 to accept, -1 for "not enough space", -2 for "incorrect format"
virtual void trackRemovedFromTransferQueue(const itemRecordW * track);
virtual __int64 getTrackSizeOnDevice(const itemRecordW * track); // return the amount of space taken up on the device by the track, or 0 for incompatable (usually the filesize, unless you are transcoding)
virtual void deleteTrack(songid_t songid); // physically remove from device. Be sure to remove it from all the playlists!
virtual void commitChanges(); // optional. Will be called at a good time to save changes
virtual int getPlaylistCount(); // always at least 1. playlistnumber 0 is the Master Playlist containing all tracks.
// PlaylistName(0) should return the name of the device.
virtual void getPlaylistName(int playlistnumber, wchar_t * buf, int len);
virtual int getPlaylistLength(int playlistnumber);
virtual songid_t getPlaylistTrack(int playlistnumber,int songnum); // returns a songid
virtual void setPlaylistName(int playlistnumber, const wchar_t * buf); // with playlistnumber={}, set the name of the device.
virtual void playlistSwapItems(int playlistnumber, int posA, int posB); // swap the songs at position posA and posB
virtual void sortPlaylist(int playlistnumber, int sortBy); // only implement if you are a non-cached device!!!
virtual void addTrackToPlaylist(int playlistnumber, songid_t songid); // adds songid to the end of the playlist
virtual void removeTrackFromPlaylist(int playlistnumber, int songnum); //where songnum is the position of the track in the playlist
virtual void deletePlaylist(int playlistnumber);
virtual int newPlaylist(const wchar_t * name); // create empty playlist, returns playlistnumber
virtual void getTrackArtist(songid_t songid, wchar_t * buf, int len);
virtual void getTrackAlbum(songid_t songid, wchar_t * buf, int len);
virtual void getTrackTitle(songid_t songid, wchar_t * buf, int len);
virtual int getTrackTrackNum(songid_t songid);
virtual int getTrackDiscNum(songid_t songid);
virtual void getTrackGenre(songid_t songid, wchar_t * buf, int len);
virtual int getTrackYear(songid_t songid);
virtual __int64 getTrackSize(songid_t songid); // in bytes
virtual int getTrackLength(songid_t songid); // in millisecs
virtual int getTrackBitrate(songid_t songid); // in kbps
virtual int getTrackPlayCount(songid_t songid);
virtual int getTrackRating(songid_t songid); //0-5
virtual __time64_t getTrackLastPlayed(songid_t songid); // in unix time format
virtual __time64_t getTrackLastUpdated(songid_t songid); // in unix time format
virtual void getTrackExtraInfo(songid_t songid, const wchar_t * field, wchar_t * buf, int len); //optional
// feel free to ignore any you don't support
virtual void setTrackArtist(songid_t songid, const wchar_t * value);
virtual void setTrackAlbum(songid_t songid, const wchar_t * value);
virtual void setTrackTitle(songid_t songid, const wchar_t * value);
virtual void setTrackTrackNum(songid_t songid, int value);
virtual void setTrackDiscNum(songid_t songid, int value){};
virtual void setTrackGenre(songid_t songid, const wchar_t * value);
virtual void setTrackYear(songid_t songid, int year);
virtual void setTrackPlayCount(songid_t songid, int value){};
virtual void setTrackRating(songid_t songid, int value){};
virtual void setTrackLastPlayed(songid_t songid, __time64_t value){}; // in unix time format
virtual void setTrackLastUpdated(songid_t songid, __time64_t value){}; // in unix time format
virtual void setTrackExtraInfo(songid_t songid, const wchar_t * field, const wchar_t * value) {}; //optional
virtual bool playTracks(songid_t * songidList, int listLength, int startPlaybackAt, bool enqueue){return false;}; // return false if unsupported
virtual intptr_t extraActions(intptr_t param1, intptr_t param2, intptr_t param3,intptr_t param4);
virtual bool copyToHardDriveSupported() {return true;} // for now...
virtual __int64 songSizeOnHardDrive(songid_t song) {return getTrackSize(song);} // how big a song will be when copied back. Return -1 for not supported.
virtual int copyToHardDrive(songid_t song, // the song to copy
wchar_t * path, // path to copy to, in the form "c:\directory\song". The directory will already be created, you must append ".mp3" or whatever to this string! (there is space for at least 10 new characters).
void * callbackContext, //pass this to the callback
void (*callback)(void * callbackContext, wchar_t * status), // call this every so often so the GUI can be updated. Including when finished!
int * killswitch // if this gets set to anything other than zero, the transfer has been cancelled by the user
); // -1 for failed/not supported. 0 for success.
};
#endif //_NJBDEVICE_H_

Binary file not shown.

View File

@ -0,0 +1,922 @@
/////////////////////////////////////////////////////////////////////////////////////
//
// File: nmsdk.h
//
// Purpose: Combination of the Jukebox SDK2 header file and the NomadII SDK2 header file.
//
// Notes: Please make sure to include the COM Stuffs <Objbase.h> and <initguid.h>
// at the beginning of the application programs. Otherwise, it will get Link Errors.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Creative Technology Ltd., 2001. All rights reserved.
//
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// nmsdk.h : main header file for export
// Version: 1.0.7.0
/////////////////////////////////////////////////////////////////////////////
#ifndef __nmsdk_h__
#define __nmsdk_h__
//
// COM Interface Declaration
//
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
//////////////////////////////////////////////////////////////////////////
// Class ID //
//////////////////////////////////////////////////////////////////////////
//CLSID CLSID_CTJukeBox2:
// {BD1A6357-3E9B-4f1b-8375-AEE989ED6C5E}
DEFINE_GUID(CLSID_CTJukeBox2,
0xbd1a6357, 0x3e9b, 0x4f1b, 0x83, 0x75, 0xae, 0xe9, 0x89, 0xed, 0x6c, 0x5e);
//CLSID CLSID_CTNOMAD2:
// {0EBE3156-FD3A-4f5c-ABDB-71E3BEEAD091}
DEFINE_GUID(CLSID_CTNOMAD2,
0xebe3156, 0xfd3a, 0x4f5c, 0xab, 0xdb, 0x71, 0xe3, 0xbe, 0xea, 0xd0, 0x91);
//////////////////////////////////////////////////////////////////////////
// return codes //
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////
// JukeBox & NomadII shared stuffs //
//////////////////////////////////////////////////////
// Additional Error codes
#define DAPSDK_SUCCESS 0x00
// General Error
#define DAPSDK_FAILED 0x01
#define DAPSDK_E_DEVICE_BUSY 0x02
#define DAPSDK_E_STORAGE_FULL 0x03
#define DAPSDK_E_SETTIME_REJECTED 0x05
#define DAPSDK_E_ITEM_SIZE_MISSING 0x14 //NMJB_E_TRACK_SIZE_MISSING
#define DAPSDK_E_ITEM_UPLOAD_DENIED 0x18 //NMJB_E_TRACK_UPLOAD_DENIED
#define DAPSDK_E_PLAYER_NOT_CONNECTED 0x80
#define DAPSDK_E_CANCELLED 0x81
#define DAPSDK_E_PORT_UNAVAILABLE 0x82
#define DAPSDK_E_OUT_OF_MEMORY 0x83
#define DAPSDK_E_FILEOPEN_ERR 0x84
#define DAPSDK_E_ITEM_NOT_FOUND 0x85
#define DAPSDK_E_LOAD_COMPONENTS_FAILED 0x86
#define DAPSDK_E_ID_INVALID 0x87
#define DAPSDK_E_FILETYPE_ILLEGAL 0x88
#define DAPSDK_E_LOADRES_FAIL 0x89
#define DAPSDK_E_FORMAT_NOT_FOUND 0x8a
#define DAPSDK_E_FILE_ALREADY_EXISTS 0x8b
#define DAPSDK_E_LIB_CORRUPTED 0x8c
#define DAPSDK_E_LIB_BUSY 0x8d
#define DAPSDK_E_FILE_READ_WRITE_FAILED 0x8e //NMJB_E_FILE_WRITE_FAILED
#define DAPSDK_E_INVALID_FILEPATH 0x8f
#define DAPSDK_E_UNSUPPORTED 0x91
#define DAPSDK_E_NORIGHTS 0x95
#define DAPSDK_E_UNDEFINED_ERR 0xff
//////////////////////////////////////////////////////
// NomadII stuffs //
//////////////////////////////////////////////////////
#define DAPSDK_E_SMARTMEDIA_WRITE_PROTECTED 0x98
#define DAPSDK_E_NO_STORAGE 0x99 //No internal media or smart media
//////////////////////////////////////////////////////
// JukeBox stuffs //
//////////////////////////////////////////////////////
// General Error
#define DAPSDK_E_HD_GENERAL_ERROR 0x04
// Track Management Error
#define DAPSDK_E_TRACK_NOT_FOUND 0x10
#define DAPSDK_E_TRACK_ALREADY_EXIST 0x11
#define DAPSDK_E_TRACK_TITLE_MISSING 0x12
#define DAPSDK_E_TRACK_CODEC_MISSING 0x13
#define DAPSDK_E_TRACK_IO_OPERATION_ABORTED 0x15
#define DAPSDK_E_TRACK_READ_WRITE_ERROR 0x16
#define DAPSDK_E_TRACK_NOT_OPENED 0x17
// Playlist Error
#define DAPSDK_E_PL_NOT_FOUND 0x20
#define DAPSDK_E_PL_ALREADY_EXIST 0x21
#define DAPSDK_E_PL_ITEM_NOT_FOUND 0x22
#define DAPSDK_E_PL_ITEM_ALREADY_EXIST 0x23
//Additional
#define DAPSDK_E_DISKFULL_FOR_DOWNLOAD 0x90
#define DAPSDK_E_STATUS_TIMEOUT 0x06
// Transport Control Error
#define DAPSDK_E_END_OF_TRACK 0x30
#define DAPSDK_E_END_OF_LIST 0x31
#define DAPSDK_E_CODEC_NOT_SUPPORTED 0x32
#define DAPSDK_E_DATA_CORRUPTED 0x33
#define DAPSDK_E_SAMPLING_RATE_NOT_SUPPORTED 0x34
#define DAPSDK_E_DECODING_ERROR 0x35
#define DAPSDK_E_POSITION_OUTOF_RANGE 0x36
#define DAPSDK_E_NOT_STOPPED 0x37
// Audio Control Error
#define DAPSDK_E_UNKNOW_PROPERTY 0x40
#define DAPSDK_E_VALUE_OUTOF_RANGE 0x41
// USB Transaction Error
#define DAPSDK_E_DATA_FILE_NOT_FOUND 0x60
#define DAPSDK_E_DATA_FILE_TOO_BIG 0x61
#define DAPSDK_E_DATA_FILE_ALREADY_EXIST 0x62
#define DAPSDK_E_TOO_MANY_DATA_FILES 0x63
//additional
#define DAPSDK_E_WMDM_INIT_FAILED 0x92
#define DAPSDK_E_INVALID_ARGUMENT 0x93
#define DAPSDK_E_PARENTNODE_NOT_EXIST 0x94
#define DAPSDK_E_NORIGHTS 0x95
#define DAPSDK_E_PATH_EXCESS_LEN 0x96
#define DAPSDK_E_LOAD_PROC_FAILED 0x97
// New Error code for MultiApplication assess of Nomad Jukebox 2/3/Zen
#define DAPSDK_E_PMSMAN_CREATEDIRECTORY_FAILED 0x0100
#define DAPSDK_E_DEVICE_WRITE_FAILED 0x0200
#define DAPSDK_E_DEVICE_READ_FAILED 0x0300
#define DAPSDK_E_DB_INVALID_REQUEST_ID 0x0400
#define DAPSDK_E_DB_INVALID_NODE_ID 0x0500
#define DAPSDK_E_DWNTHRD_CREATEMETADATA_FAILED 0x0600
#define DAPSDK_E_DEVINFO_INVALID_INDEX 0x0700
#define DAPSDK_E_INVALID_DEVICESETTINGTYPE 0x0800
#define DAPSDK_E_FILESIZE_TOO_BIG 0x0900
#define DAPSDK_E_AUDIOFILE_FORMAT 0x0A00
#define DAPSDK_E_AUDIOFILE_INVALID 0x0B00
#define DAPSDK_E_ACCESS_DENIED 0x0C00
#define DAPSDK_E_FILE_NOT_FOUND 0x0D00
#define DAPSDK_E_EOF 0x0E00
#define DAPSDK_E_COOKIE 0x0F00
#define DAPSDK_E_PLAYBACK_INPROGRESS 0x1000
#define DAPSDK_E_TRANSFER_INPROGRESS 0x1100
#define DAPSDK_E_BUFFER_NOT_ENOUGH 0x1200
// New Error code for Data Folder of Nomad Jukebox 2/3/Zen
#define DAPSDK_E_NOT_A_FOLDER 0x1400 // the target file is not a folder
#define DAPSDK_E_FOLDER_NOT_EMPTY 0x1600 // the target folder is not empty
#define DAPSDK_E_FOLDER_EXIST 0x1700 // the target folder exist
#define DAPSDK_E_FOLDER_NOTEXIST 0x1800 // the target folder does not exist
#define DAPSDK_E_PARENTFOLDER_NOTEXIST 0x1900 // the target parent folder does not exist
#define DAPSDK_E_FILEPATH_TOOLONG 0x1A00 // the target file path is too long
#define DAPSDK_E_FILENAME_TOOLONG 0x1B00 // the target file name is too long
#define DAPSDK_E_INVALID_OPERATION 0x1E00 // the operation cannot be perform
//////////////////////////////////////////////////////////////////////////
// Definitions for WM Messages //
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////
// JukeBox & NomadII shared stuffs //
//////////////////////////////////////////////////////
// Download message
#define WM_DAPSDK_DOWNLOAD_PROGRESS WM_USER+500
#define WM_DAPSDK_DOWNLOAD_COMPLETE WM_USER+501
// Upload message
#define WM_DAPSDK_GETITEM_PROGRESS WM_USER+502
#define WM_DAPSDK_GETITEM_COMPLETE WM_USER+503
//////////////////////////////////////////////////////
// JukeBox stuffs //
//////////////////////////////////////////////////////
// Device change message
#define WM_DAPSDK_JUKEBOX_REMOVAL WM_USER+508
#define WM_DAPSDK_JUKEBOX_ARRIVAL WM_USER+509
// Playback message
#define WM_DAPSDK_PLAYBACK_COMPLETE WM_USER+504
#define WM_DAPSDK_PLAYLIST_COMPLETE WM_USER+505
#define WM_DAPSDK_PLAYBACK_ERROR WM_USER+506
#define WM_DAPSDK_PLAYBACK_PROGRESS WM_USER+507
// New callback messages for MultiApplication assess of Hotcake
// Notification Messages for database change
#define WM_DAPSDK_CHANGE_BASE WM_USER + 200
#define WM_DAPSDK_MUSIC_ADD_FILE WM_DAPSDK_CHANGE_BASE + 0 // wParam = NodeId added, lParam = nil
#define WM_DAPSDK_MUSIC_DEL_FILE WM_DAPSDK_CHANGE_BASE + 1 // wParam = NodeId deleted, lParam = nil
#define WM_DAPSDK_MUSIC_SETATTR_FILE WM_DAPSDK_CHANGE_BASE + 2 // wParam = NodeId edited, lParam = nil
#define WM_DAPSDK_DATA_ADD_FILE WM_DAPSDK_CHANGE_BASE + 3 // wParam = NodeId added, lParam = nil
#define WM_DAPSDK_DATA_DEL_FILE WM_DAPSDK_CHANGE_BASE + 4 // wParam = NodeId deleted, lParam = nil
#define WM_DAPSDK_DATA_SETATTR_FILE WM_DAPSDK_CHANGE_BASE + 5 // wParam = NodeId edited, lParam = nil
#define WM_DAPSDK_PLAYLIST_ADD_FILE WM_DAPSDK_CHANGE_BASE + 6 // wParam = NodeId added, lParam = nil
#define WM_DAPSDK_PLAYLIST_DEL_FILE WM_DAPSDK_CHANGE_BASE + 7 // wParam = NodeId deleted, lParam = nil
#define WM_DAPSDK_PLAYLIST_SETATTR_FILE WM_DAPSDK_CHANGE_BASE + 8 // wParam = NodeId edited, lParam = nil
#define WM_DAPSDK_PLAYLIST_ITEM_CHANGE WM_DAPSDK_CHANGE_BASE + 9 // wParam = PlaylistNodeId affected, lParam = nil
#define WM_DAPSDK_STORAGEINFO_CHANGE WM_DAPSDK_CHANGE_BASE + 10 // wParam = deviceIndex that change occurred, lParam = nil
#define WM_DAPSDK_ADDITEM_PROGRESS WM_USER+500
#define WM_DAPSDK_ADDITEM_COMPLETE WM_USER+501
/////////////////////////////////////////////////////////////////////////
// struct defines //
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////
// JukeBox & NomadII shared stuffs //
//////////////////////////////////////////////////////
typedef struct _DAPSDK_DATE_TIME
{
short Year, Month, Day, DayOfWeek;
short Hour, Min, Sec, MilliSec;
} DATE_TIME, *PDATE_TIME;
typedef struct _DAPSDK_FORMAT_INFO
{
long lCodecID;
UCHAR szCodecName[128];
long lSamplingRate;
long lNumChannel;
} FORMAT_INFO, *PFORMAT_INFO;
//-- SDK and firmware version info structure --//
//
// used in GetSDKVersion()
// used in GetDeviceProperties( kFirmwareVersion, kHardwareVersion)
typedef struct _DAPSDK_VERSION
{
WORD major;
WORD minor;
WORD build;
WORD specialBuild;
} DAPSDK_VERSION, *PDAPSDK_VERSION;
//-- Memory Storage Information Structure --//
typedef struct _DAPSDK_STORAGE_INFO
{
ULONG totalH;
ULONG totalL;
ULONG freeH;
ULONG freeL;
} DAPSDK_STORAGE_INFO, *PDAPSDK_STORAGE_INFO;
//-- Identification structure --//
// same for RootItem, ParentItem and Item now //
typedef struct _DAPSDK_ID
{
long lID; // stores the unique ID
long lType; // stores the type (see enum above)
BSTR bstrName; // stores the name
} DAPSDK_ID, *PDAPSDK_ID;
//////////////////////////////////////////////////////
// NomadII stuffs //
//////////////////////////////////////////////////////
typedef struct _DAPSDK_RADIOPRESET
{
DWORD dwPresetIndex;
DWORD dwPresetValue;
} RADIOPRESET, *PRADIOPRESET;
// device info struct
typedef struct _DAPSDK_DEVICE_INFO
{
BYTE cDeviceId[16]; // player's ID
long dwFirmwareVersion; // player's firmware version
long dwHardwareVersion; // player's hardware version
char cDeviceName[32]; // player's name w/o NULL terminator
BYTE byPowerSource; // player's power source status in percent
} DAPSDK_DEVICE_INFO, *PDAPSDK_DEVICE_INFO;
enum
{
kASCII = 0,
kBINARY,
kUNICODE,
};
//////////////////////////////////////////////////////
// Item type for Jukebox (used by lRootItemType, //
// lParentItemType, lItemType parameter) //
//////////////////////////////////////////////////////
enum
{
kAudioTrackType = 1, // this is a audio track
kPlaylistType, // this is a track in the playlist
kDataFileType, // this is a data file
kDataFolderType, // this is a data file folder
};
/////////////////////////////////////////////////////////
// Item type for NomadII (used in lItemType parameter) //
/////////////////////////////////////////////////////////
enum
{
kInternalMemType = 0, // this item resides in internal memory
kExternalMemType, // this item resides in external (removeable) media
};
// Device Property Type Constant
//-- Device Property type (used by lDevicePropertyType parameter in --//
// GetDeviceProperties/SetDeviceProperties --//
enum
{
//////////////////////////////////////////////////////
// JukeBox & NomadII shared stuffs //
//////////////////////////////////////////////////////
kDeviceSerialNumberValue = 1, // GET, <NOMAD II>given the Item type
// in "lpValue" parameter, the return value
// is a pointer to the serial number
// of the specified media.
kFirmwareVersion, // GET, return value is a pointer to
// DAPSDK_VERSION structure indicating the
// current firmware version in the device.
kDeviceNameString, // GET, return value is a pointer to
// BSTR string.
kPowerSourceValue,
kStorageInfoStruct, // GET, return value is a pointer to
// DAPSDK_STORAGE_INFO structure indicating
// the current memory usage.
kDateTimeStruct, // GET/SET, return/set value is a pointer to
// DATE_TIME structure (defined in SDK 1.0)
kOwnerNameString, // GET/SET, return/set value is a pointer to BSTR
// string.
kAudioFormatCount, // GET, return value is a pointer to the number of
// audio format supported by device.
kAudioFormatInfoStruct, // GET, given the index value in "lpValue"
// parameter, the return value is a pointer to
// FORMATINFO structure (defined in SDK 1.0).
kLangEncodeSupport, // GET, returns unsigned long value
// 0x01 == Latin 1(CP1252), 0x80000000 == UNICODE
//////////////////////////////////////////////////////
// JukeBox stuffs //
//////////////////////////////////////////////////////
kHardwareVersion, // GET, return value is a pointer to
// DAPSDK_VERSION structure indicating the
// current hardware version in the device.
kAudioVolumeValue, // GET/SET, return/set value is the pointer to the
// volume level in percentage.
kAudioMuteValue, // GET/SET, return/set value is the pointer to the
// Mute status (1=on, 0=off).
// Treble level in percentage.
kEAXCount, // GET, return value is the pointer to the number
// of EAX settings.
kEAXNameString, // GET, given the index value in "lpValue"
// parameter, the return value is a pointer to
// a BSTR string.
kEAXAmountValue, // GET/SET, given the index value in "lpValue"
// parameter, the return value is the effect
// amount in percentage.
kEAXCurrentIndex, // GET/SET, the value in "lpValue" is used to set
// or retrieve the current EAX selection.
kAudioEQPresetCount, // GET, return value is the pointer to the number
// of EQ settings.
kAudioEQNameString, // GET, given the index value in "lpValue"
// parameter, the return value is a pointer to
// a BSTR string.
kAudioEQAmountValue, // GET/SET, return/set value is the pointer to the
// EQ amount in percentage.
kAudioEQCurrentIndex, // GET/SET, the value in "lpValue" is used to set
// or retrieve the current EQ selection.
//////////////////////////////////////////////////////
// NomadII stuffs //
//////////////////////////////////////////////////////
kFMRadioPresetCount, // GET, returns pointer to number of FM radio
// presets available in the player.
kFMRadioPresetValue, // GET/SET, given the preset index value,
// returns an existing value or sets a new
// preset FM preset. Value in kHz.
kFormatStorage // SET, Do format storage.
};
//Note that all index value is zero-based. Client should call the "kxxxxxxCount" property first before trying to get the value for individual settings in list-type of properties, i.e. kEAXNameString, kAudioFormatInfoStruct...
//Not all properties are readable and writable, some are read-only attributes. Those properties that are read-only are marked with the "GET" strings and those that are read and writable are marked as "GET/SET". Client should not call SetDeviceProperties() with the read-only property type, such call would fail.
//New Property types maybe supported in future by simply adding into the enum list, and publish to developers.
//////////////////////////////////////////////////////
// JukeBox stuffs //
//////////////////////////////////////////////////////
//-- Playback operation type (used by lPlayOperationType parameter in --//
//-- PlayControl() & QueueControl()) --//
enum
{
kPlayTrack = 1, // lpValue stores the pointer to the
// DAPSDK_ITEM_ID structure.
kStopTrack, // lpValue is not used, stop current track, no op
// if no track is currently playing.
kPauseTrack, // lpValue is not used, pause current track, no op
// if no track is currently playing.
kSetPlaybackPosition, // lpValue stores the pointer to the new playback
// position.
kQueueTrack, // lpValue stores the pointer to the
// DAPSDK_ITEM_ID structure.
kClearQueue, // lpValue is not used, clear existing queue.
};
#define TITLE "TITLE"
#define FILESIZE "FILE SIZE"
#define CODEC "CODEC"
#define ALBUM "ALBUM"
#define ARTIST "ARTIST"
#define GENRE "GENRE"
#define LENGTH "LENGTH"
#define TRACKNUM "TRACK NUM"
#define YEAR "YEAR"
#define PLAYONLY "PLAYONLY"
#define TRACKID "TRACK ID"
// new attribute for datafile and datafolder
#define MOD_FILETIME "MODIFIED FILETIME"
#define FILE_ATTRIB "FILE ATTRIB"
#define PARENT_FOLDER "PARENT FOLDER"
#define FOLDERNAME "FOLDER NAME" // data folder name for Nomad Jukebox
#define MULTI_ATTRIB "MULTI ATTRIB" // this is for user to change multiple file attribute at one time.
#define FILENAME "FILE NAME" // file name for Nomad II, data file name for Nomad Jukebox
#define ALLTRACKSKEY -1
//////////////////////////////////////////////////////
// NomadII stuffs //
//////////////////////////////////////////////////////
#define DOS_FILEATTRIB "DOS_FILEATTRIB"
#define DOS_DATETIME "DOS_DATETIME"
//////////////////////////////////////////////////////////////////////////
// ICTJukebox (Interface 1) Methods //
//////////////////////////////////////////////////////////////////////////
// {DFC9207F-4B64-11D4-A4ED-00A0C98E46CC}
DEFINE_GUID(IID_ICTJukebox,
0xdfc9207f, 0x4b64, 0x11d4, 0xa4, 0xed, 0x00, 0xa0, 0xc9, 0x8e, 0x46, 0xcc);
interface ICTJukebox : public IUnknown
{
virtual HRESULT STDMETHODCALLTYPE CancelTransfer(
/*[in]*/long lDeviceID) = 0;
virtual HRESULT STDMETHODCALLTYPE RenamePlaylist(
/*[in]*/long lDeviceID,
/*[in]*/long lPlaylistID,
/*[in]*/BSTR bstrName) = 0;
virtual HRESULT STDMETHODCALLTYPE RemoveTracksFromPlaylist(
/*[in]*/long lDeviceID,
/*[in]*/long lTrackCount,
/*[in]*/long* lpTrackList,
/*[in]*/long lPlaylist) = 0;
virtual HRESULT STDMETHODCALLTYPE AddTracksToPlaylist(
/*[in]*/long lDeviceID,
/*[in]*/long lTrackCount,
/*[in]*/long* lpTrackList,
/*[in]*/long lPlaylist) = 0;
virtual HRESULT STDMETHODCALLTYPE InsertPlaylist(
/*[in]*/long lDeviceID,
/*[in]*/BSTR bstrPlaylistName,
/*[out]*/long* lpPlaylistID) = 0;
virtual HRESULT STDMETHODCALLTYPE DeletePlaylist(
/*[in]*/long lDeviceID,
/*[in]*/long lPlaylistID) = 0;
virtual HRESULT STDMETHODCALLTYPE FindNextTrackInPlaylist(
/*[in]*/long lDeviceID,
/*[in]*/long lPlaylistID,
/*[out]*/long* lpTrackID,
/*[out]*/BSTR* lpbstrTrackName) = 0;
virtual HRESULT STDMETHODCALLTYPE FindFirstTrackInPlaylist(
/*[in]*/long lDeviceID,
/*[in]*/long lPlaylistID,
/*[out]*/long* lpTrackID,
/*[out]*/BSTR* lpbstrTrackName) = 0;
virtual HRESULT STDMETHODCALLTYPE FindNextPlaylist(
/*[in]*/long lDeviceID,
/*[out]*/long* lpPlaylistID,
/*[out]*/BSTR* lpbstrPlaylistName) = 0;
virtual HRESULT STDMETHODCALLTYPE FindFirstPlaylist(
/*[in]*/long lDeviceID,
/*[out]*/long* lpPlaylistID,
/*[out]*/BSTR* lpbstrPlaylistName) = 0;
virtual HRESULT STDMETHODCALLTYPE ChangeTrackInfo(
/*[in]*/long lDeviceID,
/*[in]*/long lTarckID,
/*[in]*/long lSize,
/*[in]*/IUnknown* lpTrackInfo) = 0;
virtual HRESULT STDMETHODCALLTYPE DeleteTrack(
/*[in]*/long lDeviceID,
/*[in]*/long lTrackID) = 0;
virtual HRESULT STDMETHODCALLTYPE InsertTrack(
/*[in]*/long lDeviceID,
/*[in]*/BSTR bstrFilePath,
/*[in]*/long lSize,
/*[in]*/IUnknown* lpTrackInfo,
/*[out]*/long* lpTrackID) = 0;
virtual HRESULT STDMETHODCALLTYPE GetTrackInfo(
/*[in]*/long lDeviceID,
/*[in]*/long lTrackID,
/*[in]*/long lInSize,
/*[out]*/long* lpOutSize,
/*[out]*/IUnknown* lpTrackInfo) = 0;
virtual HRESULT STDMETHODCALLTYPE FindNextTrack(
/*[in]*/long lDeviceID,
/*[in]*/long lKeyID,
/*[out]*/long* lpTrackID,
/*[out]*/BSTR* lpbstrName) = 0;
virtual HRESULT STDMETHODCALLTYPE FindFirstTrack(
/*[in]*/long lDeviceID,
/*[in]*/long lKeyID,
/*[out]*/long* lpTrackID,
/*[out]*/BSTR* lpbstrName) = 0;
virtual HRESULT STDMETHODCALLTYPE FindNextKey(
/*[in]*/long lDeviceID,
/*[in]*/long lRootKeyID,
/*[out]*/long* lpKeyID,
/*[out]*/BSTR* lpbstrName) = 0;
virtual HRESULT STDMETHODCALLTYPE FindFirstKey(
/*[in]*/long lDeviceID,
/*[in]*/long lRootKeyID,
/*[out]*/long* lpKeyID,
/*[out]*/BSTR* lpbstrName) = 0;
virtual HRESULT STDMETHODCALLTYPE FindNextRootKey(
/*[in]*/long lDeviceID,
/*[out]*/long* lpRootKeyID,
/*[out]*/BSTR* lpbstrName) = 0;
virtual HRESULT STDMETHODCALLTYPE FindFirstRootKey(
/*[in]*/long lDeviceID,
/*[out]*/long* lpRootKeyID,
/*[out]*/BSTR* lpbstrName) = 0;
virtual HRESULT STDMETHODCALLTYPE SetOwnerName(
/*[in]*/long lDeviceID,
/*[in]*/BSTR bstrName) = 0;
virtual HRESULT STDMETHODCALLTYPE GetOwnerName(
/*[in]*/long lDeviceID,
/*[out]*/BSTR* lpbstrName) = 0;
virtual HRESULT STDMETHODCALLTYPE SetDateTime(
/*[in]*/long lDeviceID,
/*[out]*/IUnknown* lpDateTime) = 0;
virtual HRESULT STDMETHODCALLTYPE GetDateTime(
/*[in]*/long lDeviceID,
/*[out]*/IUnknown* lpDateTime) = 0;
virtual HRESULT STDMETHODCALLTYPE FindNextFormatSupport(
/*[in]*/long lDeviceID,
/*[out]*/IUnknown* lpFormatInfo) = 0;
virtual HRESULT STDMETHODCALLTYPE FindFirstFormatSupport(
/*[in]*/long lDeviceID,
/*[out]*/IUnknown* lpFormatInfo) = 0;
virtual HRESULT STDMETHODCALLTYPE GetStorageInfo(
/*[in]*/long lDeviceID,
/*[out]*/unsigned long* lpTotalMemHigh,
/*[out]*/unsigned long* lpTotalMemLow,
/*[out]*/unsigned long* lpFreeMemHigh,
/*[out]*/unsigned long* lpFreeMemLow ) = 0;
virtual HRESULT STDMETHODCALLTYPE GetDeviceInfo(
/*[in]*/long lDeviceID,
/*[out]*/IUnknown* lpDeviceInfo) = 0;
virtual HRESULT STDMETHODCALLTYPE GetDeviceCount(
/*[out]*/long* lpDeviceCount) = 0;
virtual HRESULT STDMETHODCALLTYPE SetCallbackWindow(
/*[in]*/long lDeviceID,
/*[in]*/long hWnd) = 0;
virtual HRESULT STDMETHODCALLTYPE GetSDKVersion(
/*[out]*/long* lpVersion) = 0;
virtual HRESULT STDMETHODCALLTYPE ShutDown() = 0;
virtual HRESULT STDMETHODCALLTYPE Initialize() = 0;
};
//////////////////////////////////////////////////////////////////////////
// ICTJukebox2 (Interface 2) Methods //
//////////////////////////////////////////////////////////////////////////
DEFINE_GUID(IID_ICTJukebox2,
0xdfc92080, 0x4b64, 0x11d4, 0xa4, 0xed, 0x00, 0xa0, 0xc9, 0x8e, 0x46, 0xcc);
interface ICTJukebox2 : public IUnknown
{
virtual HRESULT STDMETHODCALLTYPE Initialize2() = 0;
virtual HRESULT STDMETHODCALLTYPE ShutDown2() = 0;
virtual HRESULT STDMETHODCALLTYPE SetCallbackWindow2(
long lDeviceID,
long hWnd ) = 0;
virtual HRESULT STDMETHODCALLTYPE GetDeviceCount2(
long* lpDeviceCount ) = 0;
//-- Canceling I/O --//
virtual HRESULT STDMETHODCALLTYPE CancelTransfer2(
long lDeviceID ) = 0;
//-- GetSDKVersion2() Fucntion Descriptions --//
// This function overides the same function in interface 1, this is to
// return a more meaningful version information to the client which is
// clearly specified in the DAPSDK_VERSION structure
virtual HRESULT STDMETHODCALLTYPE GetSDKVersion2(
IUnknown* lpSDKVersion ) = 0;
//_______________________ Querying RootItem __________________________//
virtual HRESULT STDMETHODCALLTYPE FindFirstRootItem (
long lDeviceID,
IUnknown* lpRootItemID ) = 0;
virtual HRESULT STDMETHODCALLTYPE FindNextRootItem (
long lDeviceID,
IUnknown* lpRootItemID ) = 0;
//______________________ Querying ParentItem __________________________//
virtual HRESULT STDMETHODCALLTYPE FindFirstParentItem (
long lDeviceID,
IUnknown* lRootItemID,
IUnknown* lpParentItemID ) = 0;
virtual HRESULT STDMETHODCALLTYPE FindNextParentItem (
long lDeviceID,
IUnknown* lRootItemID,
IUnknown* lpParentItemID ) = 0;
//______________________ ParentItem Management __________________________ //
//-- AddParentItem() Fucntion Descriptions --//
// Client can only add Parent Item of the same type as the RootItem. For
// example, client cannot add a kDataFileType Parent item into a RootItem
// type of kAudioTrackType.
//
// As of current firmware implementation, client can only add ParentItem
// into a RootItem that has a type of kPlaylistType. Adding ParentItem into
// other RootItem type will fail.
virtual HRESULT STDMETHODCALLTYPE AddParentItem (
long lDeviceID,
IUnknown* lRootItemID,
IUnknown* lParentItemID ) = 0;
//-- DeleteParentItem() Function Description --//
// Client can only delete ParentItem of type kPlaylistType. Deleting other
// ParentItem type will fail.
virtual HRESULT STDMETHODCALLTYPE DeleteParentItem (
long lDeviceID,
IUnknown* lParentItemID ) = 0;
//-- RenameParentItem() Function Description --//
// Client can only rename ParentItem of type kPlaylistType. Renaming other
// ParentItem type will fail.
//
// The updated DAPSDK_PARENTITEM_ID structure is returned in lParentItemID
// parameter.
virtual HRESULT STDMETHODCALLTYPE RenameParentItem (
long lDeviceID,
IUnknown* lParentItemID,
BSTR bstrNewParentItemName ) = 0;
//__________________________ Querying Item ______________________________//
virtual HRESULT STDMETHODCALLTYPE FindFirstItem (
long lDeviceID,
IUnknown* lParentItemID,
IUnknown* lpItemID ) = 0;
virtual HRESULT STDMETHODCALLTYPE FindNextItem (
long lDeviceID,
IUnknown* lParentItemID,
IUnknown* lpItemID ) = 0;
//_____________________ Getting Item Attributes __________________________//
//-- GetItemAttribute() Function Description --//
// This function returns the TrackInfo data for all Item type. But for
// kDataFileType and kPlaylistFileType, the TrackInfo data contain only
// file name, file type and file size. In contrast, the item attribute
// for a kAudioTrackType may contain all information similar to the ID3tag
// information that a typical MP3 file has.
virtual HRESULT STDMETHODCALLTYPE GetItemAttribute (
long lDeviceID,
IUnknown* lpItemID,
long lInItemInfoSize,
long* lOutItemInfoSize,
IUnknown* lpItemInfo ) = 0;
//-- SetItemAttribute() Function Description --//
// This function allows client to set TrackInfo attributes of a
// kAudioTrackItem only. Setting other item type will fail.
//
// It allows client to set a particular attribute data according to the name
// and type given in the parameters. Note that only one attribute can be set
// at a time.
virtual HRESULT STDMETHODCALLTYPE SetItemAttribute (
long lDeviceID,
IUnknown* lpItemID,
BSTR bstrAttributeName,
long lAttributeType,
long lAttributeDataSize,
IUnknown* lpAttributeData ) = 0;
//____________________________ Item Management ___________________________//
//-- AddItem() Function Description --//
// This function initiates the file download from the computer to the
// device. Client should call this function to download audio tracks
// like MP3, WMA and WAVE and data files. Client are not allow
// to download an item of kPlaylistType, use AddItemsToParentItem to add
// item of type kPlaylistType.
virtual HRESULT STDMETHODCALLTYPE AddItem (
long lDeviceID,
long lItemType,
BSTR bstrSrcFileName,
long lItemInfoSize,
IUnknown* lpItemInfo) = 0;
//-- AddItemsToParentItem() Function Description --//
// Client call this function to add kAudioTrackType item into the ParentItem
// of type kPlaylistType. Only kAudioTrackType items are accepted, and only
// ParentItem of type kPlaylistType can accept such addition.
virtual HRESULT STDMETHODCALLTYPE AddItemsToParentItem(
long lDeviceID,
IUnknown* lpParentItemID,
long lItemIDCount,
IUnknown* lpItemIDList ) = 0;
//-- DeleteItem() Function Description --//
// Client can call this function to remove item of type kAudioTrackType and
// kDataFileType. You cannot remove kPlaylistType item here.
virtual HRESULT STDMETHODCALLTYPE DeleteItem (
long lDeviceID,
IUnknown* lpItemID ) = 0;
//-- GetItem() Function Description --//
// Client can call this function to retrieve item that are kAudioTrackType
// and kDataFileType from the device to the computer. Note that client
// cannot retrieve item of type kPlaylistItem
virtual HRESULT STDMETHODCALLTYPE GetItem (
long lDeviceID,
BSTR bstrDestinationFileName,
IUnknown* lpItemID ) = 0;
//________________________ Device Properties ____________________________//
virtual HRESULT STDMETHODCALLTYPE GetDeviceProperties (
long lDeviceID,
long lDevicePropertyType,
IUnknown* lpValue ) = 0;
virtual HRESULT STDMETHODCALLTYPE SetDeviceProperties (
long lDeviceID,
long lDevicePropertyType,
IUnknown* lpValue ) = 0;
//_______________________ Playback control ______________________________//
virtual HRESULT STDMETHODCALLTYPE PlayControl (
long lDeviceID,
long lPlayOperationType,
IUnknown* lpValue ) = 0;
virtual HRESULT STDMETHODCALLTYPE QueueControl (
long lDeviceID,
long lQueueOperationType,
IUnknown* lpValue ) = 0;
};
//////////////////////////////////////////////////////////////
// ICTNomad2 Methods //
//////////////////////////////////////////////////////////////
// {368953D4-6A2F-4787-BC6F-4047A39A7557}
DEFINE_GUID(IID_ICTNomad2,
0x368953d4, 0x6a2f, 0x4787, 0xbc, 0x6f, 0x40, 0x47, 0xa3, 0x9a, 0x75, 0x57);
interface ICTNomad2 : public IUnknown
{
virtual HRESULT STDMETHODCALLTYPE Initialize() = 0;
virtual HRESULT STDMETHODCALLTYPE ShutDown() = 0;
virtual HRESULT STDMETHODCALLTYPE SetCallbackWindow(
/*[in]*/long lDeviceID,
/*[in]*/long hWnd) = 0;
virtual HRESULT STDMETHODCALLTYPE GetDeviceCount(
/*[out]*/long* lpDeviceCount) = 0;
virtual HRESULT STDMETHODCALLTYPE CancelTransfer(
/*[in]*/long lDeviceID) = 0;
virtual HRESULT STDMETHODCALLTYPE GetSDKVersion(
/*[out]*/IUnknown* lpVersion) = 0;
//__________________________ Querying Item ______________________________//
virtual HRESULT STDMETHODCALLTYPE FindFirstItem (
long lDeviceID,
IUnknown* lParentItemID,
IUnknown* lpItemID ) = 0;
virtual HRESULT STDMETHODCALLTYPE FindNextItem (
long lDeviceID,
IUnknown* lParentItemID,
IUnknown* lpItemID ) = 0;
//_____________________ Getting Item Attributes __________________________//
//-- GetItemAttribute() Function Description --//
// This function returns the TrackInfo data for all Item type. But for
// kDataFileType and kPlaylistFileType, the TrackInfo data contain only
// file name, file type and file size. In contrast, the item attribute
// for a kAudioTrackType may contain all information similar to the ID3tag
// information that a typical MP3 file has.
virtual HRESULT STDMETHODCALLTYPE GetItemAttribute (
long lDeviceID,
IUnknown* lpItemID,
long lInItemInfoSize,
long* lOutItemInfoSize,
IUnknown* lpItemInfo ) = 0;
//____________________________ Item Management ___________________________//
//-- AddItem() Function Description --//
// This function initiates the file download from the computer to the
// device. Client should call this function to download audio tracks
// like MP3, WMA and WAVE and data files. Client are not allow
// to download an item of kPlaylistType, use AddItemsToParentItem to add
// item of type kPlaylistType.
virtual HRESULT STDMETHODCALLTYPE AddItem (
long lDeviceID,
long lItemType,
BSTR bstrSrcFileName,
long lItemInfoSize,
IUnknown* lpItemInfo) = 0;
//-- DeleteItem() Function Description --//
// Client can call this function to remove item of type kAudioTrackType and
// kDataFileType. You cannot remove kPlaylistType item here.
virtual HRESULT STDMETHODCALLTYPE DeleteItem (
long lDeviceID,
IUnknown* lpItemID ) = 0;
//-- GetItem() Function Description --//
// Client can call this function to retrieve item that are kAudioTrackType
// and kDataFileType from the device to the computer. Note that client
// cannot retrieve item of type kPlaylistItem
virtual HRESULT STDMETHODCALLTYPE GetItem (
long lDeviceID,
BSTR bstrDestinationFileName,
IUnknown* lpItemID ) = 0;
//________________________ Device Properties ____________________________//
virtual HRESULT STDMETHODCALLTYPE GetDeviceProperties (
long lDeviceID,
long lDevicePropertyType,
IUnknown* lpValue ) = 0;
virtual HRESULT STDMETHODCALLTYPE SetDeviceProperties (
long lDeviceID,
long lDevicePropertyType,
IUnknown* lpValue ) = 0;
};
#ifdef __cplusplus
}
#endif // __cplusplus
#endif

Binary file not shown.

View File

@ -0,0 +1,181 @@
//#define PLUGIN_NAME "Nullsoft Creative NJB Plug-in"
#define PLUGIN_VERSION L"0.57"
#include "NJBDevice.h"
#include "../Winamp/wa_ipc.h"
#define WM_PMP_NJB_DEVICE_CONNECTED (WM_USER+23)
int init();
void quit();
intptr_t MessageProc(int msg, intptr_t param1, intptr_t param2, intptr_t param3);
PMPDevicePlugin plugin = {PMPHDR_VER, 0, init, quit, MessageProc};
LRESULT CALLBACK CallbackWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
C_ItemList devices;
// wasabi based services for localisation support
api_language *WASABI_API_LNG = 0;
HINSTANCE WASABI_API_LNG_HINST = 0, WASABI_API_ORIG_HINST = 0;
ICTJukebox2 * m_pCTJukebox2 = NULL;
HWND mainMessageWindow = 0;
static bool classRegistered = 0;
HWND CreateDummyWindow()
{
if (!classRegistered)
{
WNDCLASSW wc = {0, };
wc.style = 0;
wc.lpfnWndProc = CallbackWndProc;
wc.hInstance = plugin.hDllInstance;
wc.hIcon = 0;
wc.hCursor = NULL;
wc.lpszClassName = L"pmp_njb_window";
if (!RegisterClassW(&wc))
return 0;
classRegistered = true;
}
HWND dummy = CreateWindowW(L"pmp_njb_window", L"pmp_njb_window", 0, 0, 0, 0, 0, NULL, NULL, plugin.hDllInstance, NULL);
return dummy;
}
int init()
{
waServiceFactory *sf = plugin.service->service_getServiceByGuid(languageApiGUID);
if (sf) WASABI_API_LNG = reinterpret_cast<api_language*>(sf->getInterface());
// need to have this initialised before we try to do anything with localisation features
WASABI_API_START_LANG(plugin.hDllInstance,PmpNJBLangGUID);
static wchar_t szDescription[256];
swprintf(szDescription, ARRAYSIZE(szDescription),
WASABI_API_LNGSTRINGW(IDS_NULLSOFT_CREATIVE_NJB), PLUGIN_VERSION);
plugin.description = szDescription;
OleInitialize(NULL);
HRESULT hr = CoCreateInstance(CLSID_CTJukeBox2, NULL, CLSCTX_ALL, IID_ICTJukebox2, (void**) & m_pCTJukebox2);
if (hr != S_OK) return 0;
hr = m_pCTJukebox2->Initialize2();
if (hr != S_OK)
{
m_pCTJukebox2->Release();
m_pCTJukebox2=0;
return 0;
}
mainMessageWindow = CreateDummyWindow();
m_pCTJukebox2->SetCallbackWindow2(0, (long)mainMessageWindow);
long devCount = 0;
m_pCTJukebox2->GetDeviceCount2(&devCount);
for (long i = 1; i <= devCount; i++)
PostMessage(mainMessageWindow, WM_PMP_NJB_DEVICE_CONNECTED, i, 0);
return 0;
}
void quit()
{
if (m_pCTJukebox2)
{
m_pCTJukebox2->ShutDown2();
m_pCTJukebox2->Release();
m_pCTJukebox2 = 0;
}
DestroyWindow(mainMessageWindow);
OleUninitialize();
}
LRESULT CALLBACK CallbackWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_PMP_NJB_DEVICE_CONNECTED:
{
new NJBDevice((int)wParam);
}
break;
case WM_DAPSDK_JUKEBOX_REMOVAL:
{
long devCount = 0;
if (m_pCTJukebox2->GetDeviceCount2(&devCount) == S_OK)
{
if (devCount == 0) // TODO benski> shouldn't we always register for messages?
m_pCTJukebox2->SetCallbackWindow2(0, (long)mainMessageWindow);
for (long i = 0; i < devices.GetSize(); /*i++*/)
{
NJBDevice * dev = (NJBDevice *)devices.Get(i);
bool attached = false;
for (long j = 1; j <= devCount; j++)
{
BYTE * ptr = NULL;
if (m_pCTJukebox2->GetDeviceProperties(j, kDeviceSerialNumberValue, (IUnknown*)ptr) == S_OK)
{
if (memcmp(ptr, dev->serial, 16) == 0)
{
attached = true;
dev->id = j;
break;
}
//free(ptr);
}
}
if (!attached)
{
SendMessage(plugin.hwndPortablesParent,WM_PMP_IPC,(intptr_t)dev,PMP_IPC_DEVICEDISCONNECTED);
delete dev;
}
else
i++;
}
}
}
break;
case WM_DAPSDK_JUKEBOX_ARRIVAL:
{
long devCount = 0;
if (m_pCTJukebox2->GetDeviceCount2(&devCount) == S_OK)
new NJBDevice(devCount);
}
break;
default:
{
for (int i = 0; i < devices.GetSize(); i++)
{
NJBDevice * dev = (NJBDevice *)devices.Get(i);
if (dev->messageWindow == hwnd)
return dev->WindowMessage(hwnd, uMsg, wParam, lParam);
}
}
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);;
}
intptr_t MessageProc(int msg, intptr_t param1, intptr_t param2, intptr_t param3) {
switch(msg) {
case PMP_DEVICECHANGE:
return 0;
case PMP_NO_CONFIG:
return TRUE;
case PMP_CONFIG:
return 0;
}
return 0;
}
extern "C" {
__declspec( dllexport ) PMPDevicePlugin * winampGetPMPDevicePlugin(){return &plugin;}
__declspec( dllexport ) int winampUninstallPlugin(HINSTANCE hDllInst, HWND hwndDlg, int param) {
int i = devices.GetSize();
while(i-- > 0) ((Device*)devices.Get(i))->Close();
return PMP_PLUGIN_UNINSTALL_NOW;
}
};

View File

@ -0,0 +1,109 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"#include ""version.rc2""\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
#if defined(APSTUDIO_INVOKED) || defined(DISABLED)
#if defined(APSTUDIO_INVOKED)
IDD_INVISI$(DISABLED) DIALOGEX 0, 0, 5, 5
#else
IDD_INVISI DIALOGEX 0, 0, 5, 5
#endif
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
END
#endif
/////////////////////////////////////////////////////////////////////////////
//
// RCDATA
//
IDR_ZEN_ICON RCDATA ".\\resources\\zenIcon.png"
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE
BEGIN
IDS_NULLSOFT_CREATIVE_NJB "Nullsoft Creative NJB Plug-in v%s"
65535 "{4F5B2300-19D1-4390-BE04-89019441100B}"
END
STRINGTABLE
BEGIN
IDS_NJB_LOADING "NJB Loading..."
IDS_TRANSFERRING_PERCENT "Transferring %d%%"
IDS_DONE "Done"
IDS_ERROR "Error"
IDS_TRANSFERRING "Transferring..."
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#include "version.rc2"
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@ -0,0 +1,30 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29709.97
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pmp_njb", "pmp_njb.vcxproj", "{0D2DCCBD-FF58-4A04-BC53-D6208D5EB3E4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0D2DCCBD-FF58-4A04-BC53-D6208D5EB3E4}.Debug|Win32.ActiveCfg = Debug|Win32
{0D2DCCBD-FF58-4A04-BC53-D6208D5EB3E4}.Debug|Win32.Build.0 = Debug|Win32
{0D2DCCBD-FF58-4A04-BC53-D6208D5EB3E4}.Debug|x64.ActiveCfg = Debug|x64
{0D2DCCBD-FF58-4A04-BC53-D6208D5EB3E4}.Debug|x64.Build.0 = Debug|x64
{0D2DCCBD-FF58-4A04-BC53-D6208D5EB3E4}.Release|Win32.ActiveCfg = Release|Win32
{0D2DCCBD-FF58-4A04-BC53-D6208D5EB3E4}.Release|Win32.Build.0 = Release|Win32
{0D2DCCBD-FF58-4A04-BC53-D6208D5EB3E4}.Release|x64.ActiveCfg = Release|x64
{0D2DCCBD-FF58-4A04-BC53-D6208D5EB3E4}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {651853BB-3138-4841-BD5B-ACF5165F9161}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,315 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{0D2DCCBD-FF58-4A04-BC53-D6208D5EB3E4}</ProjectGuid>
<RootNamespace>pmp_njb</RootNamespace>
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Label="Vcpkg">
<VcpkgEnableManifest>false</VcpkgEnableManifest>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgConfiguration>Debug</VcpkgConfiguration>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
<VcpkgConfiguration>Debug</VcpkgConfiguration>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\..\replicant;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;ML_ex_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>false</MinimalRebuild>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<FunctionLevelLinking>true</FunctionLevelLinking>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
<ObjectFileName>$(IntDir)</ObjectFileName>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x040c</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>odbc32.lib;odbccp32.lib;wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<GenerateMapFile>false</GenerateMapFile>
<MapExports>false</MapExports>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<MapFileName>$(IntDir)$(TargetName).map</MapFileName>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\..\replicant;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN64;_DEBUG;_WINDOWS;_USRDLL;ML_ex_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>false</MinimalRebuild>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<FunctionLevelLinking>true</FunctionLevelLinking>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
<ObjectFileName>$(IntDir)</ObjectFileName>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<DisableSpecificWarnings>4302;4311;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x040c</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>odbc32.lib;odbccp32.lib;wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<GenerateMapFile>false</GenerateMapFile>
<MapExports>false</MapExports>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<MapFileName>$(IntDir)$(TargetName).map</MapFileName>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MinSpace</Optimization>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<AdditionalIncludeDirectories>..\..\..\replicant;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;ML_ex_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
<ObjectFileName>$(IntDir)</ObjectFileName>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>None</DebugInformationFormat>
<DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x040c</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>odbc32.lib;odbccp32.lib;wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>false</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<MapFileName>$(IntDir)$(TargetName).map</MapFileName>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<Optimization>MinSpace</Optimization>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<AdditionalIncludeDirectories>..\..\..\replicant;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;_USRDLL;ML_ex_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
<ObjectFileName>$(IntDir)</ObjectFileName>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4302;4311;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x040c</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>odbc32.lib;odbccp32.lib;wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>false</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<MapFileName>$(IntDir)$(TargetName).map</MapFileName>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\General\gen_ml\itemlist.cpp" />
<ClCompile Include="..\..\General\gen_ml\ml_lib.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="NJBDevice.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\General\gen_ml\itemlist.h" />
<ClInclude Include="..\..\General\gen_ml\ml.h" />
<ClInclude Include="..\..\Library\ml_pmp\pmp.h" />
<ClInclude Include="NJBDevice.h" />
<ClInclude Include="Nmsdk.h" />
<ClInclude Include="resource.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="pmp_njb.rc" />
</ItemGroup>
<ItemGroup>
<Image Include="resources\zenIcon.png" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Wasabi\Wasabi.vcxproj">
<Project>{3e0bfa8a-b86a-42e9-a33f-ec294f823f7f}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="NJBDevice.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\General\gen_ml\itemlist.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\General\gen_ml\ml_lib.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="NJBDevice.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Nmsdk.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\General\gen_ml\itemlist.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\General\gen_ml\ml.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\Library\ml_pmp\pmp.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Header Files">
<UniqueIdentifier>{19f63d8f-2d94-424b-b8e5-1ae189920736}</UniqueIdentifier>
</Filter>
<Filter Include="Ressource Files">
<UniqueIdentifier>{675c67be-1ca6-4f01-aeb3-6b9329201724}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files">
<UniqueIdentifier>{df88e072-b108-4287-9243-92c4883b420e}</UniqueIdentifier>
</Filter>
<Filter Include="Image Files">
<UniqueIdentifier>{a2c922b0-d514-4e40-8e03-932a77c3e2fa}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<Image Include="resources\zenIcon.png">
<Filter>Image Files</Filter>
</Image>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="pmp_njb.rc">
<Filter>Ressource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,23 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by pmp_njb1.rc
//
#define IDS_NJB_LOADING 1
#define IDS_TRANSFERRING_PERCENT 2
#define IDS_DONE 3
#define IDS_ERROR 4
#define IDS_TRANSFERRING 5
#define IDD_INVISI 9
#define IDR_ZEN_ICON 103
#define IDS_NULLSOFT_CREATIVE_NJB 65534
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 108
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 B

View File

@ -0,0 +1,39 @@
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
#include "../../../Winamp/buildType.h"
VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,57,0,0
PRODUCTVERSION WINAMP_PRODUCTVER
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "Winamp SA"
VALUE "FileDescription", "Winamp Portable Device Plug-in"
VALUE "FileVersion", "0,57,0,0"
VALUE "InternalName", "Nullsoft Creative NJB"
VALUE "LegalCopyright", "Copyright <20> 2006-2023 Winamp SA"
VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
VALUE "OriginalFilename", "pmp_njb.dll"
VALUE "ProductName", "Winamp"
VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END