aboutsummaryrefslogtreecommitdiff
path: root/Src/burnlib/playlist.cpp
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/burnlib/playlist.cpp
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/burnlib/playlist.cpp')
-rw-r--r--Src/burnlib/playlist.cpp686
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