diff --git a/src/contrib/cddadecoder/CddaDataStream.cpp b/src/contrib/cddadecoder/CddaDataStream.cpp index 8e77a3087..c6f62bb3d 100755 --- a/src/contrib/cddadecoder/CddaDataStream.cpp +++ b/src/contrib/cddadecoder/CddaDataStream.cpp @@ -38,31 +38,16 @@ #include #include +#define FRAMES_PER_SECOND 75 +#define FRAMES_PER_MINUTE (60 * FRAMES_PER_SECOND) +#define FRAMES_PER_PREGAP (2 * FRAMES_PER_SECOND) + #define RAW_SECTOR_SIZE 2352 -#define MSF2UINT(hgs) ((hgs[1]*4500) + (hgs[2]*75) + (hgs[3])) +#define MSF2UINT(hgs) ((hgs[1] * FRAMES_PER_MINUTE) + (hgs[2] * FRAMES_PER_SECOND) + (hgs[3])) static CddaDataStream* active = NULL; static std::mutex activeMutex; -static void setActive(CddaDataStream* stream) { - std::unique_lock lock(activeMutex); - - if (active != NULL) { - active->Close(); - active = NULL; - } - - active = stream; -} - -static void resetIfActive(CddaDataStream* stream) { - std::unique_lock lock(activeMutex); - - if (stream == active) { - active = NULL; - } -} - CddaDataStream::CddaDataStream() { this->closed = false; this->drive = INVALID_HANDLE_VALUE; @@ -73,7 +58,6 @@ CddaDataStream::CddaDataStream() { CddaDataStream::~CddaDataStream() { this->Close(); - resetIfActive(this); } int CddaDataStream::GetChannelCount() { @@ -107,10 +91,10 @@ bool CddaDataStream::Open(const char *uri, unsigned int options) { drivePath.c_str(), GENERIC_READ, FILE_SHARE_READ, - NULL, + nullptr, OPEN_EXISTING, - FILE_ATTRIBUTE_READONLY | FILE_FLAG_SEQUENTIAL_SCAN, - (HANDLE) NULL); + 0, + (HANDLE) nullptr); if (this->drive == INVALID_HANDLE_VALUE) { return false; @@ -134,7 +118,7 @@ bool CddaDataStream::Open(const char *uri, unsigned int options) { this->toc.FirstTrack <= trackIndex && trackIndex <= this->toc.LastTrack; - if (!canReadFromDevice && !trackIndexValid) { + if (!canReadFromDevice || !trackIndexValid) { this->Close(); return false; } @@ -154,12 +138,9 @@ bool CddaDataStream::Open(const char *uri, unsigned int options) { this->channels = 4; } - this->startSector = MSF2UINT(this->toc.TrackData[trackIndex - 1].Address) - 150; - this->stopSector = MSF2UINT(this->toc.TrackData[trackIndex].Address) - 150; + this->startSector = MSF2UINT(this->toc.TrackData[trackIndex - 1].Address) - FRAMES_PER_PREGAP; + this->stopSector = MSF2UINT(this->toc.TrackData[trackIndex].Address) - FRAMES_PER_PREGAP; this->length = (this->stopSector - this->startSector) * RAW_SECTOR_SIZE; - - setActive(this); - this->uri = uri; return true; @@ -234,45 +215,33 @@ HRESULT CddaDataStream::Read(PBYTE pbBuffer, DWORD dwBytesToRead, BOOL bAlign, L return S_FALSE; } - BYTE buff[RAW_SECTOR_SIZE]; - - PBYTE pbBufferOrg = pbBuffer; LONGLONG pos = this->position; size_t len = (size_t) dwBytesToRead; - while (pos >= 0 && pos < this->length && len > 0) { - RAW_READ_INFO rawreadinfo; - rawreadinfo.SectorCount = 1; - rawreadinfo.TrackMode = CDDA; + UINT sectorOffset = this->startSector + (int)(pos / RAW_SECTOR_SIZE); - UINT sector = this->startSector + int(pos / RAW_SECTOR_SIZE); - __int64 offset = pos % RAW_SECTOR_SIZE; + RAW_READ_INFO rawReadInfo; + rawReadInfo.SectorCount = 1; + rawReadInfo.TrackMode = CDDA; + rawReadInfo.DiskOffset.QuadPart = sectorOffset * 2048; - rawreadinfo.DiskOffset.QuadPart = sector * 2048; - DWORD bytesRead = 0; + DWORD bytesActuallyRead = 0; - DeviceIoControl( - this->drive, - IOCTL_CDROM_RAW_READ, - &rawreadinfo, - sizeof(rawreadinfo), - buff, RAW_SECTOR_SIZE, - &bytesRead, - 0); - - size_t l = (size_t)min(min(len, RAW_SECTOR_SIZE - offset), this->length - pos); - memcpy(pbBuffer, &buff[offset], l); - - pbBuffer += l; - pos += l; - len -= l; - } + DeviceIoControl( + this->drive, + IOCTL_CDROM_RAW_READ, + &rawReadInfo, + sizeof(rawReadInfo), + pbBuffer, + dwBytesToRead, + &bytesActuallyRead, + 0); if (pdwBytesRead) { - *pdwBytesRead = pbBuffer - pbBufferOrg; + *pdwBytesRead = bytesActuallyRead; } - this->position += pbBuffer - pbBufferOrg; + this->position += bytesActuallyRead; return S_OK; } diff --git a/src/contrib/cddadecoder/CddaDecoder.cpp b/src/contrib/cddadecoder/CddaDecoder.cpp index b131bb525..9348a244f 100644 --- a/src/contrib/cddadecoder/CddaDecoder.cpp +++ b/src/contrib/cddadecoder/CddaDecoder.cpp @@ -55,7 +55,6 @@ void CddaDecoder::Destroy() { bool CddaDecoder::Open(IDataStream* data) { this->data = (CddaDataStream *) data; - this->duration = (double)(data->Length() / sizeof(int)) / 44100.0f; return (data != NULL); } @@ -70,6 +69,10 @@ double CddaDecoder::SetPosition(double seconds) { } double CddaDecoder::GetDuration() { + if (this->duration == -1.0f) { + this->duration = (double)(data->Length() / data->GetChannelCount() / sizeof(short)) / 44100.0f; + } + return this->duration; } @@ -87,8 +90,7 @@ bool CddaDecoder::GetBuffer(IBuffer *buffer) { if (count > 0) { short* t = (short*) this->buffer; - for (int x = 0; x < (count / BYTES_PER_RAW_SAMPLE); x++) - { + for (int x = 0; x < (count / BYTES_PER_RAW_SAMPLE); x++) { target[x] = (float) t[x] / 16384.0f; } diff --git a/src/contrib/cddadecoder/CddaDecoder.h b/src/contrib/cddadecoder/CddaDecoder.h index 0505b2d0a..f1c3a1cb6 100644 --- a/src/contrib/cddadecoder/CddaDecoder.h +++ b/src/contrib/cddadecoder/CddaDecoder.h @@ -42,22 +42,19 @@ using namespace musik::core::sdk; -class CddaDecoder : public IDecoder -{ -private: +class CddaDecoder : public IDecoder { + public: + CddaDecoder(); + ~CddaDecoder(); -public: - CddaDecoder(); - ~CddaDecoder(); + bool Open(IDataStream* data); + void Destroy(); + double SetPosition(double seconds); + double GetDuration(); + bool GetBuffer(IBuffer *buffer); - bool Open(IDataStream* data); - void Destroy(); - double SetPosition(double seconds); - double GetDuration(); - bool GetBuffer(IBuffer *buffer); - -private: - CddaDataStream* data; - double duration; - BYTE* buffer; + private: + CddaDataStream* data; + double duration; + BYTE* buffer; };