diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/burnlib/playlist.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/burnlib/playlist.cpp')
-rw-r--r-- | Src/burnlib/playlist.cpp | 686 |
1 files changed, 686 insertions, 0 deletions
diff --git a/Src/burnlib/playlist.cpp b/Src/burnlib/playlist.cpp new file mode 100644 index 00000000..56e32a43 --- /dev/null +++ b/Src/burnlib/playlist.cpp @@ -0,0 +1,686 @@ +#include "./playlist.h" +#include "../Agave/DecodeFile/ifc_audiostream.h" +#include <strsafe.h> +#include "../winamp/wa_ipc.h" + +BurnerPlaylist::BurnerPlaylist() +{ + evntCancel = NULL; +} + +BurnerPlaylist::~BurnerPlaylist() +{ + if (manager.GetDecodeAPI()) + { + waServiceFactory *factory = WASABI_API_SVC->service_getServiceByGuid(decodeFileGUID); + factory->releaseInterface(manager.GetDecodeAPI()); + manager.SetDecodeAPI(NULL); + } + clear(); +} + +HRESULT BurnerPlaylist::Load(const wchar_t *filename) +{ + if (!WASABI_API_SVC) return PLAYLISTMANAGER_FAILED; + waServiceFactory *plmFactory = WASABI_API_SVC->service_getServiceByGuid(api_playlistmanagerGUID); + if (!plmFactory) return 0; + api_playlistmanager *plManager = (api_playlistmanager*)plmFactory->getInterface(); + if (!plManager) return 0; + length = 0; + int retCode = plManager->Load(filename, this); + return (PLAYLISTMANAGER_SUCCESS == retCode); +} + +DWORD BurnerPlaylist::GetTotalSectors(void) +{ + DWORD ts = 0; + for(size_t i = 0; i < GetCount(); i++) + { + ts += BurnerVector::at(i)->GetSizeInSectors(); + } + return ts; +} +DWORD BurnerPlaylist::GetStatus(DWORD *retCode) +{ + if(retCode) *retCode = errorCode; + return statusCode; +} + +size_t BurnerPlaylist::GetStateCount(DWORD state, DWORD code) +{ + size_t count = 0; + for (size_t i = 0; i < GetCount(); i++) + { + if (BurnerVector::at(i)->itemStatus == state && BurnerVector::at(i)->errorCode == code) count++; + } + return count; +} + +DWORD BurnerPlaylist::GetStateLengthMS(DWORD state, DWORD code) +{ + DWORD len = 0; + for (size_t i = 0; i < GetCount(); i++) + { + if (BurnerVector::at(i)->itemStatus == state && BurnerVector::at(i)->errorCode == code) len += BurnerVector::at(i)->GetLength(); + } + return len; +} + +DWORD BurnerPlaylist::GetStateSectors(DWORD state, DWORD code) +{ + DWORD ts = 0; + for(size_t i = 0; i < GetCount(); i++) + { + if (BurnerVector::at(i)->itemStatus == state && BurnerVector::at(i)->errorCode == code) ts += BurnerVector::at(i)->GetSizeInSectors(); + } + return ts; +} + +HRESULT BurnerPlaylist::CheckLicense(BURNERPLAYLISTCALLBACK notifyCB, void *userparam) +{ + this->notifyCB = notifyCB; + this->userparam = userparam; + + statusCode = BURNERPLAYLIST_LICENSINGSTARTING; + errorCode = BURNERPLAYLIST_SUCCESS; + OnNotify(statusCode, errorCode, 0); + + size_t count = BurnerVector::size(); + size_t realCount = 0; + manager.CancelBurn(); // ha-ha + wchar_t **filenames = (count) ? (wchar_t**)malloc(count*sizeof(wchar_t*)) : NULL; + DWORD nc, ec; + + for (size_t i = 0; i < count; i++) + { + nc = BurnerVector::at(i)->GetStatus(&ec); + if (nc == BURNERITEM_READY || + ((nc == BURNERITEM_LICENSED || nc == BURNERITEM_DECODED) && ec == BURNERITEM_SUCCESS)) + { + filenames[realCount] = (wchar_t*)BurnerVector::at(i)->GetFullName(); + BurnerVector::at(i)->itemStatus = BURNERITEM_LICENSING; + errorCode = BURNERPLAYLIST_ITEMADDED; + realCount++; + } + else + { + BurnerVector::at(i)->itemStatus = BURNERITEM_SKIPPED; + errorCode = BURNERPLAYLIST_ADDITEMSKIPPED; + } + OnNotify(statusCode, errorCode, i); + } + if (realCount == 0) + { + statusCode = BURNERPLAYLIST_LICENSINGFINISHED; + errorCode = BURNERPLAYLIST_NOFILES; + OnNotify(statusCode, errorCode, 0); + if (filenames) free(filenames); + return statusCode; + } + if (!manager.GetDecodeAPI()) + { + api_decodefile *decoder = NULL; + waServiceFactory *factory = WASABI_API_SVC->service_getServiceByGuid(decodeFileGUID); + if (factory) decoder = (api_decodefile *)factory->getInterface(); + if (!factory || !decoder) + { + statusCode = BURNERPLAYLIST_LICENSINGFINISHED; + errorCode = BURNERPLAYLIST_DECODESERVICEFAILED; + OnNotify(statusCode, errorCode, 0); + free(filenames); + return statusCode; + } + manager.SetDecodeAPI(decoder); + } + + manager.SetFiles(realCount, (const wchar_t**)filenames, this); + free(filenames); + return statusCode; +} + +HRESULT BurnerPlaylist::Decode(void* hFile, BURNERPLAYLISTCALLBACK notifyCB, void *userparam, BOOL block) +{ + this->notifyCB = notifyCB; + this->userparam = userparam; + this->hFile = hFile; + hThread = NULL; + + statusCode = BURNERPLAYLIST_DECODESTARTING; + errorCode = BURNERPLAYLIST_SUCCESS; + OnNotify(statusCode, errorCode, 0); + + if (!manager.GetDecodeAPI()) + { + api_decodefile *decoder = NULL; + waServiceFactory *factory = WASABI_API_SVC->service_getServiceByGuid(decodeFileGUID); + if (factory) decoder = (api_decodefile *)factory->getInterface(); + if (!factory || !decoder) + { + statusCode = BURNERPLAYLIST_DECODEFINISHED; + errorCode = BURNERPLAYLIST_DECODESERVICEFAILED; + OnNotify(statusCode, errorCode, 0); + return statusCode; + } + manager.SetDecodeAPI(decoder); + } + + if (block) + { + statusCode = DecodeWorker(this); + OnNotify(statusCode, errorCode, 100); + if (manager.GetDecodeAPI()) + { + waServiceFactory *factory = WASABI_API_SVC->service_getServiceByGuid(decodeFileGUID); + factory->releaseInterface(manager.GetDecodeAPI()); + manager.SetDecodeAPI(NULL); + } + + } + else + { + DWORD id; + hThread = CreateThread(NULL, 0, DecodeWorker, this, 0, &id); + if (NULL == hThread) + { + statusCode = BURNERPLAYLIST_DECODEFINISHED; + errorCode = BURNERPLAYLIST_THREADCREATEFAILED; + OnNotify(statusCode, errorCode, 0); + } + } + return statusCode; +} + +HRESULT BurnerPlaylist::Burn(obj_primo *primoSDK, DWORD drive, DWORD maxspeed, DWORD burnFlags, void* hFile, + BURNERPLAYLISTCALLBACK notifyCB, void *userparam, BOOL block) +{ + this->primoSDK = primoSDK; + this->drive = drive; + this->hFile = hFile; + this->maxspeed = maxspeed; + this->burnFlags = burnFlags; + this->notifyCB = notifyCB; + this->userparam = userparam; + statusCode = BURNERPLAYLIST_BURNSTARTING; + errorCode = BURNERPLAYLIST_SUCCESS; + evntCancel = CreateEvent(NULL, FALSE, FALSE, NULL); + OnNotify(statusCode, errorCode, 0); // here we go + + DWORD retCode; + DWORD dwUnits[2]; + dwUnits[0] = drive; + dwUnits[1] = 0xFFFFFFFF; + retCode = primoSDK->NewAudio(dwUnits); + if (PRIMOSDK_OK != retCode) + { + statusCode = BURNERPLAYLIST_BURNFINISHED; + errorCode = BURNERPLAYLIST_NEWAUDIOFAILED; + OnNotify(statusCode, errorCode, retCode); + return statusCode; + } + + if (BurnerVector::size() == 0) + { + statusCode = BURNERPLAYLIST_BURNFINISHED; + errorCode = BURNERPLAYLIST_NOFILES; + OnNotify(statusCode, errorCode, retCode); + return statusCode; + } + size_t i; + for(i = 0; i < BurnerVector::size(); i++) + { + DWORD ec; + if (BURNERITEM_DECODED == BurnerVector::at(i)->GetStatus(&ec) && BURNERITEM_SUCCESS == ec) + { + BurnerVector::at(i)->itemStatus = BURNERITEM_READY; + retCode = BurnerVector::at(i)->AddStream(primoSDK, hFile); + if (PRIMOSDK_OK != retCode) + { + BurnerVector::at(i)->itemStatus = BURNERITEM_BURNED; + BurnerVector::at(i)->errorCode = BURNERITEM_FAILED; + errorCode = BURNERPLAYLIST_ADDITEMFAILED; + break; + } + else errorCode = BURNERPLAYLIST_ITEMADDED; + } + else + { + errorCode = BURNERPLAYLIST_ADDITEMSKIPPED; + BurnerVector::at(i)->itemStatus = BURNERITEM_SKIPPED; + } + OnNotify(statusCode, errorCode, i); + + } + + if (PRIMOSDK_OK != retCode || (WAIT_OBJECT_0 == WaitForSingleObject(evntCancel, 0))) + { + + statusCode = (PRIMOSDK_OK == retCode) ? BURNERPLAYLIST_BURNCANCELING : BURNERPLAYLIST_BURNFINISHING; + errorCode = (PRIMOSDK_OK == retCode) ? BURNERPLAYLIST_ABORTED : BURNERPLAYLIST_ADDITEMFAILED; + BPLRUNSTATUS burnStatus; + + for(i = 0; i < BurnerVector::size(); i++) + { + burnStatus.iIndex = (int)i; + if (BURNERITEM_SKIPPED == BurnerVector::at(burnStatus.iIndex)->itemStatus) continue; + + BurnerVector::at(burnStatus.iIndex)->itemStatus = (PRIMOSDK_OK == retCode) ? BURNERITEM_ABORTED : BURNERITEM_FAILED; + OnNotify(statusCode, errorCode, (ULONG_PTR)&burnStatus); + } + + CloseHandle(evntCancel); + evntCancel = NULL; + primoSDK->CloseAudio(); + statusCode = BURNERPLAYLIST_BURNFINISHED; + OnNotify(statusCode, errorCode, i); + return statusCode; + } + + if (block) + { + DWORD notifyCode = BurnerWorker(this); + OnNotify(BURNERPLAYLIST_BURNFINISHED, notifyCode, errorCode); + } + else + { + DWORD id; + hThread = CreateThread(NULL, 0, BurnerWorker, this, 0, &id); + if (NULL == hThread) + { + statusCode = BURNERPLAYLIST_BURNFINISHED; + errorCode = BURNERPLAYLIST_THREADCREATEFAILED; + OnNotify(statusCode, errorCode, i); + } + } + + return statusCode; +} + +DWORD BurnerPlaylist::AddCompilationToCDDB(void) +{ + wchar_t buf[64] = {0}; + wchar_t albumbuf[256]= L"Mix CD "; + + wchar_t dateString[128] = {0}; + GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOTIMEMARKER, NULL, NULL, dateString, 128); + StringCchCatW(albumbuf, 256, dateString); + + StringCchPrintfW(buf, 64, L"cda://%c.cda", (char)drive); + extendedFileInfoStructW efis = { buf, L"album", albumbuf, 256, }; + + if (SendMessageW(winampWnd, WM_WA_IPC, (WPARAM)&efis, IPC_SET_EXTENDED_FILE_INFOW)) + { + efis.metadata = L"albumartist"; + efis.ret = L"Various Artists"; + SendMessageW(winampWnd, WM_WA_IPC, (WPARAM)&efis, IPC_SET_EXTENDED_FILE_INFOW); + efis.metadata = L"genre"; + efis.ret = L"Mix"; + SendMessageW(winampWnd, WM_WA_IPC, (WPARAM)&efis, IPC_SET_EXTENDED_FILE_INFOW); + SYSTEMTIME syst; + GetLocalTime(&syst); + if (syst.wYear) + { + wchar_t yearbuf[64] = {0}; + StringCchPrintfW(yearbuf, 64, L"%04d", syst.wYear); + efis.metadata = L"year"; + efis.ret = yearbuf; + SendMessageW(winampWnd, WM_WA_IPC, (WPARAM)&efis, IPC_SET_EXTENDED_FILE_INFOW); + } + wchar_t buf2[32] = {0}; + int index = 1; + for (size_t i = 0;i < GetCount();i++) + { + DWORD is, ec; + is = BurnerVector::at(i)->GetStatus(&ec); + if (BURNERITEM_BURNED == is && BURNERITEM_SUCCESS == ec) + { + StringCchPrintfW(buf, 64, L"cda://%c,%d.cda", (char)drive, i); + lstrcpynW(buf2, L"title", 32); + efis.metadata = buf2; + efis.ret = const_cast<wchar_t*>(BurnerVector::at(i)->GetTitle()); + SendMessageW(winampWnd, WM_WA_IPC, (WPARAM)&efis, IPC_SET_EXTENDED_FILE_INFOW); + + lstrcpynW(buf2, L"artist", 32); + efis.ret=L"Various Artists"; // TODO: use actual track artist + SendMessageW(winampWnd, WM_WA_IPC, (WPARAM)&efis, IPC_SET_EXTENDED_FILE_INFOW); + + index++; + } + } + SendMessageW(winampWnd, WM_WA_IPC, (WPARAM)0, IPC_WRITE_EXTENDED_FILE_INFO); + } + return 1; +} +DWORD WINAPI BurnerPlaylist::DecodeWorker(void* param) +{ + DWORD retCode; + BurnerPlaylist *playlist = (BurnerPlaylist*)param; + + playlist->percentStep = (float)(1.f / ((double)playlist->GetCount())); + playlist->activeDecode = NULL; + DWORD itemError = BURNERITEM_SUCCESS; + + // for nice ui reason lets do it twice + playlist->statusCode = BURNERPLAYLIST_DECODESTARTING; + for(size_t i = 0; i < playlist->GetCount(); i++) + { + DWORD ec; + if (BURNERITEM_LICENSED == playlist->at(i)->GetStatus(&ec) && BURN_OK == ec) + { + playlist->errorCode = BURNERPLAYLIST_ITEMADDED; + playlist->at(i)->itemStatus = BURNERITEM_READY; + } + else + { + + playlist->errorCode = BURNERPLAYLIST_ADDITEMSKIPPED; + playlist->at(i)->itemStatus = BURNERITEM_SKIPPED; + + } + playlist->OnNotify(playlist->statusCode, playlist->errorCode, i); + } + + // actual work + for(size_t i = 0; i < playlist->GetCount(); i++) + { + if (BURNERITEM_READY == playlist->at(i)->GetStatus(NULL)) + { + BPLDECODEINFO info; + info.iInstance = playlist->at(i); + info.iIndex = (int)i; + info.iNotifyCode = 0; + info.iErrorCode = 0; + info.percentCompleted = (playlist->activeDecode) ? playlist->percentStep*i*100.0f : 0; + playlist->activeDecode = &info; + playlist->statusCode = BURNERPLAYLIST_DECODEPROGRESS; + playlist->errorCode = BURNERPLAYLIST_DECODENEXTITEM; + playlist->OnNotify(playlist->statusCode, playlist->errorCode, (ULONG_PTR)playlist->activeDecode); + retCode = playlist->at(i)->Decode(&playlist->manager, playlist->hFile, OnItemDecode, playlist); + if (BURNERITEM_SUCCESS != retCode) + { + itemError = retCode; + } + if (BURNERITEM_ABORTED == retCode) + { + playlist->statusCode = BURNERPLAYLIST_DECODECANCELING; + playlist->errorCode = BURNERPLAYLIST_ABORTED; + DWORD notifyCode = BURNERITEM_DECODEFINISHED; + for(size_t k = i; k < playlist->GetCount(); k++) + { + info.iIndex = (int)k; + info.iInstance = playlist->at(k); + info.iInstance->errorCode = BURNERITEM_ABORTED; + info.iInstance->itemStatus = BURNERITEM_ABORTED; + OnItemDecode(info.iInstance, playlist, notifyCode, info.iInstance->errorCode); + } + break; + } + } + } + + // release decoderAPI + waServiceFactory *factory = WASABI_API_SVC->service_getServiceByGuid(decodeFileGUID); + factory->releaseInterface(playlist->manager.GetDecodeAPI()); + playlist->manager.SetDecodeAPI(NULL); + + if (playlist->hThread) + { + CloseHandle(playlist->hThread); + playlist->hThread = NULL; + } + + playlist->statusCode = BURNERPLAYLIST_DECODEFINISHED; + if (playlist->GetCount() == 0) playlist->errorCode = BURNERPLAYLIST_NOFILES; + else if (BURNERITEM_ABORTED == itemError) playlist->errorCode = BURNERPLAYLIST_ABORTED; + else if (BURNERITEM_SUCCESS == itemError) playlist->errorCode = BURNERPLAYLIST_SUCCESS; + else playlist->errorCode = BURNERPLAYLIST_FAILED; + + playlist->OnNotify(playlist->statusCode , playlist->errorCode, (ULONG_PTR)playlist->activeDecode); + playlist->activeDecode = NULL; + return playlist->statusCode; +} +DWORD WINAPI BurnerPlaylist::BurnerWorker(void* param) +{ + DWORD primoCode; + BurnerPlaylist *playlist = (BurnerPlaylist*)param; + + WABURNSTRUCT bs; + playlist->statusCode = BURNERPLAYLIST_BURNSTARTING; + playlist->errorCode = BURNERPLAYLIST_BEGINBURN; + playlist->OnNotify(playlist->statusCode, playlist->errorCode, 0); + primoCode = BeginBurn(playlist->primoSDK, playlist->drive, &bs); + bs.eject = TRUE; + DWORD leadin = 0; + BPLRUNSTATUS burnStatus; + ZeroMemory(&burnStatus, sizeof(BPLRUNSTATUS)); + burnStatus.iIndex = -1; + + BOOL canceled = FALSE; + DWORD itemSector = 0; + BOOL cp1 = FALSE; + if (PRIMOSDK_OK != primoCode) + { + playlist->errorCode = BURNERPLAYLIST_BEGINBURNFAILED; + } + else + { + playlist->statusCode = BURNERPLAYLIST_BURNPROGRESS; + primoCode = playlist->primoSDK->WriteAudioEx(playlist->burnFlags, playlist->maxspeed, 0x00); + if (PRIMOSDK_OK == primoCode) + { + DWORD waitResult; + while(BURNERPLAYLIST_BURNPROGRESS == playlist->statusCode && WAIT_TIMEOUT == (waitResult = WaitForSingleObject(playlist->evntCancel, 500))) + { + primoCode = playlist->primoSDK->RunningStatus(PRIMOSDK_GETSTATUS, &burnStatus.sCurrent, &burnStatus.sTotal); + if (PRIMOSDK_RUNNING == primoCode) + { + playlist->statusCode = BURNERPLAYLIST_BURNPROGRESS; + if (burnStatus.sCurrent == 0) + { + if (cp1) continue; // do not send anymore + playlist->errorCode = BURNERPLAYLIST_WRITELEADIN; //BURNERPLAYLIST_DISCOPEN + cp1 = TRUE; + } + else if (burnStatus.sCurrent > 0 && (!leadin || leadin == burnStatus.sCurrent)) + { + if (!leadin) + { + leadin = burnStatus.sCurrent; + playlist->errorCode = BURNERPLAYLIST_WRITELEADIN; // unreachable :) + } + continue; + } + else if (burnStatus.sCurrent == burnStatus.sTotal) + { + if (burnStatus.iIndex >= 0 && BURNERITEM_BURNING == playlist->at(burnStatus.iIndex)->itemStatus) + { + playlist->at(burnStatus.iIndex)->itemStatus = BURNERITEM_BURNED; + playlist->at(burnStatus.iIndex)->errorCode = BURNERITEM_SUCCESS; + playlist->at(burnStatus.iIndex)->percentCompleted = 100; + playlist->OnNotify(playlist->statusCode, BURNERPLAYLIST_WRITEITEMEND, (ULONG_PTR)&burnStatus); + } + if (burnStatus.iIndex == -1) continue; + playlist->errorCode = BURNERPLAYLIST_WRITELEADOUT; + burnStatus.iIndex = -1; + burnStatus.iInstance = NULL; + + } + else + { + playlist->errorCode = BURNERPLAYLIST_WRITEDATA; + while (itemSector < burnStatus.sCurrent && burnStatus.iIndex < (int)playlist->size()) + { if (burnStatus.iIndex >= 0 && BURNERITEM_BURNING == playlist->at(burnStatus.iIndex)->itemStatus) + { + playlist->at(burnStatus.iIndex)->itemStatus = BURNERITEM_BURNED; + playlist->at(burnStatus.iIndex)->errorCode = BURNERITEM_SUCCESS; + playlist->at(burnStatus.iIndex)->percentCompleted = 100; + playlist->OnNotify(playlist->statusCode, BURNERPLAYLIST_WRITEITEMEND, (ULONG_PTR)&burnStatus); + } + while (++burnStatus.iIndex < (int)playlist->size() && BURNERITEM_READY != playlist->at(burnStatus.iIndex)->itemStatus); + if (burnStatus.iIndex < (int)playlist->size()) itemSector += playlist->at(burnStatus.iIndex)->GetSizeInSectors(); + } + if ( burnStatus.iIndex >= 0 && burnStatus.iIndex < (int)playlist->size()) + { + BurnerItem *bi = playlist->at(burnStatus.iIndex); + burnStatus.iInstance = bi; + if (BURNERITEM_READY == bi->itemStatus) + { + bi->itemStatus = BURNERITEM_BURNING; + bi->percentCompleted = 0; + playlist->OnNotify(playlist->statusCode, BURNERPLAYLIST_WRITEITEMBEGIN, (ULONG_PTR)&burnStatus); + } + if (BURNERITEM_SUCCESS == bi->errorCode) + { + DWORD is = bi->GetSizeInSectors(); + bi->itemStatus = BURNERITEM_BURNING; + bi->percentCompleted = (is - (itemSector - burnStatus.sCurrent))*100 / is; + } + else + { + bi->itemStatus = BURNERITEM_BURNED; + bi->errorCode = BURNERITEM_SUCCESS; + bi->percentCompleted = 100; + } + } + + } + playlist->OnNotify(playlist->statusCode, playlist->errorCode, (ULONG_PTR)&burnStatus); + } + else + { + playlist->errorCode = BURNERPLAYLIST_WRITEAUDIOFAILED; + break; + } + } + + if (WAIT_OBJECT_0 == waitResult) + { // aborting + canceled = TRUE; + + playlist->statusCode = BURNERPLAYLIST_BURNCANCELING; + playlist->errorCode = BURNERPLAYLIST_ABORTED; + playlist->at(burnStatus.iIndex)->itemStatus = BURNERITEM_CANCELING; + playlist->OnNotify(playlist->statusCode, playlist->errorCode, (ULONG_PTR)&burnStatus); + DWORD test = playlist->primoSDK->RunningStatus(PRIMOSDK_ABORT, &burnStatus.sCurrent, &burnStatus.sTotal); + do + { + Sleep(1000); + primoCode = playlist->primoSDK->RunningStatus(PRIMOSDK_GETSTATUS, &burnStatus.sCurrent, &burnStatus.sTotal); + }while(PRIMOSDK_RUNNING == primoCode); + for (size_t i = 0; i < playlist->GetCount(); i++) + { + burnStatus.iIndex = (int)i; + DWORD cs = playlist->at(burnStatus.iIndex)->itemStatus; + if (BURNERITEM_BURNING != cs && BURNERITEM_READY != cs && BURNERITEM_CANCELING != cs) continue; + playlist->at(burnStatus.iIndex)->itemStatus = BURNERITEM_ABORTED; + playlist->OnNotify(playlist->statusCode, playlist->errorCode, (ULONG_PTR)&burnStatus); + } + } + + } + else + { + playlist->errorCode = BURNERPLAYLIST_WRITEAUDIOFAILED; + } + } + if (PRIMOSDK_USERABORT == primoCode) playlist->errorCode = BURNERPLAYLIST_ABORTED; + else if (PRIMOSDK_OK == primoCode) playlist->errorCode = BURNERPLAYLIST_SUCCESS; + playlist->statusCode = BURNERPLAYLIST_BURNFINISHING; + playlist->OnNotify(playlist->statusCode, playlist->errorCode, 0); + + // check unit status and notify later + DWORD statCode, cmd(0), sense(0), asc(0), ascq(0); + statCode = playlist->primoSDK->UnitStatus(&bs.drive, &cmd, &sense, &asc, &ascq); + + bs.eject = playlist->ejectDone; + + primoCode = EndBurn(&bs); + + if (PRIMOSDK_OK != primoCode) playlist->errorCode = BURNERPLAYLIST_ENDBURNFAILED; + + playlist->primoSDK->CloseAudio(); + + if (playlist->hThread) + { + CloseHandle(playlist->hThread); + playlist->hThread = NULL; + } + primoCode = (0xFF000000 & (statCode << 24)) | (0x00FF0000 & (sense << 16)) | (0x0000FF00 & (asc << 8)) | (0x000000FF & ascq); + if (BURNERPLAYLIST_SUCCESS == playlist->errorCode && statCode != PRIMOSDK_OK) playlist->errorCode = BURNERPLAYLIST_FAILED; + + if (BURNERPLAYLIST_SUCCESS == playlist->errorCode && (PRIMOSDK_WRITE == (playlist->burnFlags&PRIMOSDK_WRITE))) + { + playlist->manager.BurnFinished(); + } + else + { + playlist->manager.CancelBurn(); + } + + playlist->statusCode = BURNERPLAYLIST_BURNFINISHED; + playlist->OnNotify(playlist->statusCode, playlist->errorCode, primoCode); + return playlist->statusCode; +} + +DWORD BurnerPlaylist::OnNotify(DWORD notifyCode, DWORD errorCode, ULONG_PTR param) +{ + DWORD retCode = (notifyCB) ? notifyCB(this, userparam, notifyCode, errorCode, param) : BURNERPLAYLIST_CONTINUE; + if ( BURNERPLAYLIST_STOP == retCode && evntCancel) SetEvent(evntCancel); + return retCode; +} + + +void BurnerPlaylist::OnFile(const wchar_t *filename, const wchar_t *title, int lengthInMS, ifc_plentryinfo *info) +{ + if (NULL == filename) return; + BurnerItem *item = new BurnerItem(); + item->Create(filename,title, lengthInMS); + length += lengthInMS; + push_back(item); +} + +DWORD WINAPI BurnerPlaylist::OnItemDecode(void* sender, void *param, DWORD notifyCode, DWORD errorCode) +{ + BurnerPlaylist *pl = (BurnerPlaylist*)param; + pl->activeDecode->iNotifyCode = notifyCode; + pl->activeDecode->iErrorCode = errorCode; + pl->activeDecode->percentCompleted += pl->percentStep; + pl->statusCode = BURNERPLAYLIST_DECODEPROGRESS; + pl->errorCode = BURNERPLAYLIST_DECODEITEM; + DWORD retCode = pl->OnNotify(pl->statusCode , pl->errorCode , (ULONG_PTR)pl->activeDecode); + return (BURNERPLAYLIST_STOP == retCode) ? BURNERITEM_STOP : BURNERITEM_CONTINUE; +} + +void BurnerPlaylist::OnLicenseCallback(size_t numFiles, WRESULT *results) +{ + statusCode = BURNERPLAYLIST_LICENSINGPROGRESS; + DWORD errorCode = BURNERPLAYLIST_SUCCESS; + size_t realCount = 0; + size_t allowed = 0; + for (size_t i = 0; i < BurnerVector::size(); i++) + { + if (BURNERITEM_LICENSING == BurnerVector::at(i)->itemStatus) + { + if (realCount == numFiles) + { + statusCode = BURNERPLAYLIST_LICENSINGFINISHED; + errorCode = BURNERPLAYLIST_WRONGFILECOUNT; + break; + } + BurnerVector::at(i)->itemStatus = BURNERITEM_LICENSED; + BurnerVector::at(i)->errorCode = results[realCount]; + OnNotify(statusCode, results[realCount], (LPARAM)i); + if (BURN_OK != results[realCount]) errorCode = BURNERPLAYLIST_FILENOTLICENSED; + else allowed++; + realCount++; + } + + } + statusCode = BURNERPLAYLIST_LICENSINGFINISHED; + OnNotify(statusCode, errorCode, allowed); +} + +#define CBCLASS BurnerPlaylist +START_DISPATCH; +VCB(IFC_PLAYLISTLOADERCALLBACK_ONFILE, OnFile) +END_DISPATCH; +#undef CBCLASS
\ No newline at end of file |