diff options
Diffstat (limited to 'Src/Plugins/Input/in_cdda/CDText.cpp')
-rw-r--r-- | Src/Plugins/Input/in_cdda/CDText.cpp | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/Src/Plugins/Input/in_cdda/CDText.cpp b/Src/Plugins/Input/in_cdda/CDText.cpp new file mode 100644 index 00000000..21518a80 --- /dev/null +++ b/Src/Plugins/Input/in_cdda/CDText.cpp @@ -0,0 +1,265 @@ +#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
\ No newline at end of file |