aboutsummaryrefslogtreecommitdiff
path: root/Src/burnlib/item.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Src/burnlib/item.cpp')
-rw-r--r--Src/burnlib/item.cpp252
1 files changed, 252 insertions, 0 deletions
diff --git a/Src/burnlib/item.cpp b/Src/burnlib/item.cpp
new file mode 100644
index 00000000..bd3122f3
--- /dev/null
+++ b/Src/burnlib/item.cpp
@@ -0,0 +1,252 @@
+#include "./item.h"
+#include <strsafe.h>
+
+#define DECODEBUFFER_SIZE 4096*4
+
+DWORD BurnerItem::zeroMem[] = {0x00,};
+
+BurnerItem::BurnerItem(void)
+{
+ fullname = NULL;
+ title = NULL;
+ length = 0;
+ sizeBytes = 0;
+ sizeSectors = 0;
+ preGap = 0;
+ fposition = 0;
+ fhandle = NULL;
+ heap = GetProcessHeap();
+ ZeroMemory(ISRC, 12);
+ itemStatus = BURNERITEM_READY;
+ percentCompleted = 0;
+ errorCode = BURNERITEM_SUCCESS;
+ if (zeroMem[0] == 0x00) FillMemory(zeroMem, ZEROMEM_SIZE, 0xFFFFFFFF);
+
+}
+
+BurnerItem::~BurnerItem(void)
+{
+ Destroy();
+}
+
+HRESULT BurnerItem::Create(const wchar_t* fullname, const wchar_t *title, int length)
+{
+ if (this->fullname)
+ {
+ errorCode = BURNERITEM_ALREADYCREATED;
+ return errorCode;
+ }
+ this->fullname = DuplicateString(heap, fullname, lstrlenW(fullname));
+ this->title = DuplicateString(heap, title, lstrlenW(title));
+ this->length = length;
+ itemStatus = BURNERITEM_READY;
+ errorCode = BURNERITEM_SUCCESS;
+ return errorCode;
+}
+
+void BurnerItem::Destroy(void)
+{
+ if (fullname)
+ {
+ HeapFree(heap, NULL, fullname);
+ fullname = NULL;
+ }
+ if (title)
+ {
+ HeapFree(heap, NULL, title);
+ title = NULL;
+ }
+
+ length = 0;
+ sizeBytes = 0;
+ sizeSectors = 0;
+ preGap = 0;
+ fposition = 0;
+ fhandle = NULL;
+ ZeroMemory(ISRC, 12);
+
+}
+
+HRESULT BurnerItem::Decode(BurnManager *manager, void *fileHandle, BURNERITEMCALLBACK notifyCB, void *userparam)
+{
+ itemStatus = BURNERITEM_DECODING;
+ if (notifyCB) notifyCB(this, userparam, BURNERITEM_DECODESTARTING, BURNERITEM_SUCCESS);
+ if (!fullname)
+ {
+ errorCode = BURNERITEM_BADFILENAME;
+ itemStatus = BURNERITEM_DECODED;
+ if (notifyCB) notifyCB(this, userparam, BURNERITEM_DECODEFINISHED, errorCode);
+
+ return errorCode;
+ }
+
+ ifc_audiostream *stream = manager->CreateDecoder(fullname);
+ if (!stream)
+ {
+ errorCode = BURNERITEM_UNABLEOPENFILE;
+ itemStatus = BURNERITEM_DECODED;
+ if (notifyCB) notifyCB(this, userparam, BURNERITEM_DECODEFINISHED, errorCode);
+ return errorCode;
+ }
+
+ fposition = 0;
+ LONG fposLow(0), fposHigh(0);
+ fposLow = SetFilePointer(fileHandle, 0, &fposHigh, FILE_CURRENT);
+ fposition = (((__int64)fposHigh) << 32) | fposLow;
+ DWORD decoded = 0;
+ sizeBytes = 0;
+ sizeSectors = 0;
+ double percent = 0.0;
+ int iopercent = -1;
+ percentCompleted = 0;
+
+ errorCode = BURNERITEM_DECODEPROGRESS;
+ do
+ {
+ unsigned __int8 buffer[DECODEBUFFER_SIZE] = {0};
+ int decode_killswitch=0, decode_error;
+ decoded = (DWORD)stream->ReadAudio(buffer, DECODEBUFFER_SIZE, &decode_killswitch, &decode_error);
+ if (decoded > 0)
+ {
+ DWORD written = 0;
+ if (!WriteFile(fileHandle, buffer, decoded, &written, NULL))
+ {
+ errorCode = BURNERITEM_WRITEERROR;
+ break;
+ }
+ sizeBytes += decoded;
+ double step = ((double)decoded) / (((double)length) * 176.4f)*100.0f;
+ percent += step;
+ percentCompleted = (int)percent;
+ if (iopercent != percentCompleted)
+ {
+ iopercent = percentCompleted;
+ if (notifyCB)
+ {
+ if (BURNERITEM_CONTINUE != notifyCB(this, userparam, BURNERITEM_DECODEPROGRESS, percentCompleted))
+ {
+ errorCode = BURNERITEM_DECODECANCELING;
+ break;
+ }
+ }
+
+ }
+ }
+ } while(decoded);
+ if (stream) manager->CloseDecoder(stream);
+ itemStatus = BURNERITEM_DECODED;
+ DWORD notifyCode = BURNERITEM_DECODEFINISHED;
+ switch(errorCode)
+ {
+ case BURNERITEM_DECODECANCELING:
+ errorCode = BURNERITEM_ABORTED;
+ itemStatus = BURNERITEM_ABORTED;
+ break;
+ case BURNERITEM_DECODEPROGRESS:
+ sizeSectors = (DWORD)(sizeBytes/2352 + ((sizeBytes%2352) ? 1 : 0));
+ errorCode = BURNERITEM_SUCCESS;
+ break;
+ }
+ if (notifyCB) notifyCB(this, userparam, notifyCode, errorCode);
+ return errorCode;
+}
+
+
+HRESULT BurnerItem::AddStream(obj_primo *primoSDK, void *fileHandle)
+{
+ fhandle = fileHandle;
+ needSetFilePos = TRUE;
+ streamedSize = 0;
+
+ errorCode = primoSDK->AddAudioStream(StreamFiller, this, 0, GetSizeInSectors());
+ return errorCode;
+}
+void BurnerItem::SetPreGap(unsigned int preGap)
+{
+ this->preGap = preGap;
+}
+void BurnerItem::SetISRC(unsigned __int8 *ISRC)
+{
+ CopyMemory(this->ISRC, ISRC, 12);
+}
+
+int BurnerItem::GetStatus(DWORD *retCode)
+{
+ if(retCode)
+ {
+ switch(itemStatus)
+ {
+ case BURNERITEM_DECODING:
+ case BURNERITEM_BURNING:
+ *retCode = percentCompleted;
+ break;
+ default:
+ *retCode = errorCode;
+ }
+ }
+ return itemStatus;
+}
+
+DWORD BurnerItem::StreamFiller(PBYTE pBuffer, DWORD dwBytesRequested, PDWORD pdwBytesWritten, PVOID pContext)
+{
+ BurnerItem *item = (BurnerItem*) pContext;
+
+ if (item->needSetFilePos)
+ {
+ LONG fposLow = (LONG) item->fposition;
+ LONG fposHigh = (LONG) (item->fposition >> 32);
+ SetFilePointer(item->fhandle, fposLow, &fposHigh, FILE_BEGIN);
+ item->streamedSize = 0;
+ item->needSetFilePos = FALSE;
+ }
+
+ DWORD needToRead;
+ item->streamedSize += dwBytesRequested;
+ // check if we need to fill with zero
+ if (item->streamedSize > item->sizeBytes)
+ {
+ needToRead = (DWORD)min(0, ((long)item->sizeBytes) - long(item->streamedSize - dwBytesRequested));
+ }
+ else
+ {
+ needToRead = dwBytesRequested;
+ }
+ // read from file
+ if (needToRead)
+ {
+ *pdwBytesWritten = 0;
+ if (!ReadFile(item->fhandle, pBuffer, needToRead, pdwBytesWritten, NULL))
+ {
+ DWORD le = GetLastError();
+ item->itemStatus = BURNERITEM_BURNED;
+ item->errorCode = BURNERITEM_READSTREAMERROR;
+ }
+ //else
+ //{
+ // LONG fposLow(0), fposHigh(0);
+ // fposLow = SetFilePointer(item->fhandle, 0, &fposHigh, FILE_CURRENT);
+ // SetFilePointer(item->fhandle, -((LONG)*pdwBytesWritten), NULL, FILE_CURRENT);
+ // DWORD written(0);
+ // long needToZerro(*pdwBytesWritten)l
+ // while(needToZerro > 0)
+ // {
+ // DWORD write = min(ZEROMEM_SIZE*sizeof(DWORD), needToZerro);
+ // if (!WriteFile(item->fhandle, &zeroMem, write, &written, NULL)) break;
+ // needToZerro -= written;
+ // }
+ // SetFilePointer(item->fhandle, fposLow, &fposHigh, FILE_BEGIN);
+ //}
+ }
+ else
+ {
+ *pdwBytesWritten = 0;
+ }
+ return (BURNERITEM_SUCCESS == item->errorCode) ? PRIMOSDK_OK : PRIMOSDK_ERROR;
+}
+wchar_t* BurnerItem::DuplicateString(void *heap, const wchar_t *source, unsigned int cchSource)
+{
+ wchar_t *dest = (wchar_t*) HeapAlloc(heap, NULL, (cchSource + 1) * sizeof(wchar_t));
+ CopyMemory(dest, source, cchSource * sizeof(wchar_t));
+ dest[cchSource] = 0x0000;
+ return dest;
+} \ No newline at end of file