mirror of
https://github.com/WinampDesktop/winamp.git
synced 2024-12-04 05:11:27 -05:00
265 lines
No EOL
6.7 KiB
C++
265 lines
No EOL
6.7 KiB
C++
#include "main.h"
|
|
#include "cddb.h"
|
|
#include "api__in_cdda.h"
|
|
#ifndef IGNORE_API_GRACENOTE
|
|
#include "../primo/obj_primo.h"
|
|
#endif
|
|
//#include "CDPlay.h"
|
|
#include "DAEPlay.h"
|
|
#include "../nu/ns_wc.h"
|
|
#include "../nde/ndestring.h"
|
|
|
|
#ifndef IGNORE_API_GRACENOTE
|
|
const char *ReadLine(const char *input, char *output, size_t size, int codepage)
|
|
{
|
|
size--; // leave room for null terminator
|
|
while (input && *input && *input != '\r' && size)
|
|
{
|
|
char *next = CharNextExA(codepage, input, 0);
|
|
while (input != next)
|
|
{
|
|
if (size)
|
|
{
|
|
*output = *input;
|
|
output++;
|
|
*output = 0; // safe because we left room for the null terminator
|
|
size--;
|
|
}
|
|
input++;
|
|
}
|
|
}
|
|
|
|
|
|
if (*input == '\r')
|
|
input++;
|
|
if (*input == '\n')
|
|
input++;
|
|
|
|
return input;
|
|
}
|
|
|
|
|
|
static bool CDText_Process(DINFO *ps, const char *title, const char *performers, const char *composers, int codepage)
|
|
{
|
|
char thisTitle[1024] = {0};
|
|
|
|
const char *titles = title;
|
|
// first, get disc title
|
|
thisTitle[0] = 0;
|
|
titles = ReadLine(titles, thisTitle, 1024, codepage);
|
|
|
|
if (thisTitle[0])
|
|
{
|
|
ndestring_release(ps->title);
|
|
int count = MultiByteToWideChar(codepage, 0, thisTitle, -1, 0, 0);
|
|
ps->title = ndestring_malloc(count*sizeof(wchar_t));
|
|
MultiByteToWideChar(codepage, 0, thisTitle, -1, ps->title, count);
|
|
}
|
|
|
|
// now get track titles
|
|
int trackNum = 0;
|
|
while (titles && *titles)
|
|
{
|
|
if (trackNum == ps->ntracks)
|
|
break;
|
|
TRACKINFO &trackInfo = ps->tracks[trackNum];
|
|
thisTitle[0] = 0;
|
|
titles = ReadLine(titles, thisTitle, 1024, codepage);
|
|
|
|
if (thisTitle[0])
|
|
{
|
|
ndestring_release(trackInfo.title);
|
|
int count = MultiByteToWideChar(codepage, 0, thisTitle, -1, 0, 0);
|
|
trackInfo.title = ndestring_malloc(count*sizeof(wchar_t));
|
|
MultiByteToWideChar(codepage, 0, thisTitle, -1, trackInfo.title, count);
|
|
}
|
|
|
|
trackNum++;
|
|
}
|
|
|
|
titles = performers;
|
|
// now get disc artist
|
|
thisTitle[0] = 0;
|
|
titles = ReadLine(titles, thisTitle, 1024, codepage);
|
|
|
|
if (thisTitle[0])
|
|
{
|
|
ndestring_release(ps->artist);
|
|
int count = MultiByteToWideChar(codepage, 0, thisTitle, -1, 0, 0);
|
|
ps->artist = ndestring_malloc(count*sizeof(wchar_t));
|
|
MultiByteToWideChar(codepage, 0, thisTitle, -1, ps->artist, count);
|
|
}
|
|
|
|
// now get track artists
|
|
trackNum = 0;
|
|
while (titles && *titles)
|
|
{
|
|
if (trackNum == ps->ntracks)
|
|
break;
|
|
TRACKINFO &trackInfo = ps->tracks[trackNum];
|
|
|
|
thisTitle[0] = 0;
|
|
titles = ReadLine(titles, thisTitle, 1024, codepage);
|
|
|
|
if (thisTitle[0])
|
|
{
|
|
ndestring_release(trackInfo.artist);
|
|
int count = MultiByteToWideChar(codepage, 0, thisTitle, -1, 0, 0);
|
|
trackInfo.artist = ndestring_malloc(count*sizeof(wchar_t));
|
|
MultiByteToWideChar(codepage, 0, thisTitle, -1, trackInfo.artist, count);
|
|
}
|
|
|
|
trackNum++;
|
|
}
|
|
|
|
titles = composers;
|
|
// now get disc composer
|
|
thisTitle[0] = 0;
|
|
titles = ReadLine(titles, thisTitle, 1024, codepage);
|
|
|
|
if (thisTitle[0])
|
|
{
|
|
ndestring_release(ps->composer);
|
|
int count = MultiByteToWideChar(codepage, 0, thisTitle, -1, 0, 0);
|
|
ps->composer = ndestring_malloc(count*sizeof(wchar_t));
|
|
MultiByteToWideChar(codepage, 0, thisTitle, -1, ps->composer, count);
|
|
}
|
|
|
|
// now get track composers
|
|
trackNum = 0;
|
|
while (titles && *titles)
|
|
{
|
|
if (trackNum == ps->ntracks)
|
|
break;
|
|
TRACKINFO &trackInfo = ps->tracks[trackNum];
|
|
|
|
thisTitle[0] = 0;
|
|
titles = ReadLine(titles, thisTitle, 1024, codepage);
|
|
|
|
if (thisTitle[0])
|
|
{
|
|
ndestring_release(trackInfo.composer);
|
|
int count = MultiByteToWideChar(codepage, 0, thisTitle, -1, 0, 0);
|
|
trackInfo.composer = ndestring_malloc(count*sizeof(wchar_t));
|
|
MultiByteToWideChar(codepage, 0, thisTitle, -1, trackInfo.composer, count);
|
|
}
|
|
|
|
trackNum++;
|
|
}
|
|
|
|
ps->populated = true;
|
|
return true;
|
|
}
|
|
|
|
bool DoCDText(DINFO *ps, char device)
|
|
{
|
|
if (!device)
|
|
return false;
|
|
|
|
if (config_use_veritas)
|
|
{
|
|
obj_primo *primo=0;
|
|
waServiceFactory *sf = line.service->service_getServiceByGuid(obj_primo::getServiceGuid());
|
|
if (sf) primo = reinterpret_cast<obj_primo *>(sf->getInterface());
|
|
|
|
if (!primo)
|
|
return false;
|
|
|
|
DWORD unit = device;
|
|
DWORD tracks;
|
|
if (primo->DiscInfoEx(&unit, 0, NULL, NULL, NULL, &tracks, NULL, NULL) != PRIMOSDK_OK) // CDTextInfoEJ suggest that this needs to be called first
|
|
{
|
|
sf->releaseInterface(primo);
|
|
return false;
|
|
}
|
|
if (ps->ntracks == 0) // go ahead and set if it's not set yet
|
|
ps->ntracks = tracks;
|
|
char titleE[8192] = "", performerE[8192] = "", composerE[8192] = "", titleJ[2000] = "", performerJ[2000] = "", composerJ[2000] = "";
|
|
if (primo->CDTextInfoEJ(&unit, (PBYTE)titleE, (PBYTE)performerE, (PBYTE)composerE, (PBYTE)titleJ, (PBYTE)performerJ, (PBYTE)composerJ) == PRIMOSDK_OK)
|
|
{
|
|
sf->releaseInterface(primo);
|
|
// read titles
|
|
if (titleE[0])
|
|
return CDText_Process(ps, titleE, performerE, composerE, 28591);
|
|
else
|
|
return CDText_Process(ps, titleJ, performerJ, composerJ, 932);
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
#else
|
|
bool DoCDText(DINFO *ps, wchar_t device)
|
|
{
|
|
if (!device)
|
|
return false;
|
|
|
|
DAEPlay *dae = (g_cdplay && g_cdplay == daePlayer && g_cdplay->g_drive == device ? daePlayer : new DAEPlay);
|
|
if (dae)
|
|
{
|
|
if (dae != daePlayer)
|
|
{
|
|
if (dae->open(device, 1))
|
|
{
|
|
delete(dae);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
DAEPlay::CDTextArray* cd_text = dae->getCDText();
|
|
if ((int)cd_text > 0)
|
|
{
|
|
if (ps)
|
|
{
|
|
ps->ntracks = cd_text->size() - 1;
|
|
|
|
ndestring_release(ps->title);
|
|
ps->title = ndestring_wcsdup(cd_text[DAEPlay::CD_TEXT_TITLE][0]);
|
|
|
|
ndestring_release(ps->artist);
|
|
ps->artist = ndestring_wcsdup(cd_text[DAEPlay::CD_TEXT_PERFORMER][0]);
|
|
|
|
// TODO match this to the supported list of genres...
|
|
/*ndestring_release(ps->genre);
|
|
ps->genre = ndestring_wcsdup(cd_text[DAEPlay::CD_TEXT_GENRE][0]);*/
|
|
|
|
ndestring_release(ps->composer);
|
|
ps->composer = ndestring_wcsdup(cd_text[DAEPlay::CD_TEXT_COMPOSER][0]);
|
|
|
|
for (size_t i = 1; i < cd_text->size(); i++)
|
|
{
|
|
if (i == ps->ntracks + 1)
|
|
break;
|
|
|
|
TRACKINFO &trackInfo = ps->tracks[i-1];
|
|
|
|
// TODO improve error handling
|
|
ndestring_release(trackInfo.artist);
|
|
trackInfo.artist = ndestring_wcsdup(cd_text[DAEPlay::CD_TEXT_PERFORMER][i]);
|
|
//free(cd_text[DAEPlay::CD_TEXT_PERFORMER][i]);
|
|
|
|
ndestring_release(trackInfo.title);
|
|
trackInfo.title = ndestring_wcsdup(cd_text[DAEPlay::CD_TEXT_TITLE][i]);
|
|
//free(cd_text[DAEPlay::CD_TEXT_TITLE][i]);
|
|
|
|
ndestring_release(trackInfo.genre);
|
|
trackInfo.genre = ndestring_wcsdup(cd_text[DAEPlay::CD_TEXT_GENRE][i]);
|
|
//free(cd_text[DAEPlay::CD_TEXT_GENRE][i]);
|
|
|
|
ndestring_release(trackInfo.composer);
|
|
trackInfo.composer = ndestring_wcsdup(cd_text[DAEPlay::CD_TEXT_COMPOSER][i]);
|
|
//free(cd_text[DAEPlay::CD_TEXT_COMPOSER][i]);
|
|
}
|
|
|
|
ps->populated = true;
|
|
}
|
|
|
|
if (dae != daePlayer) delete(dae);
|
|
return true;
|
|
}
|
|
if (dae != daePlayer) delete(dae);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
#endif |