111 |
return x & 0x800000 ? x - 0x1000000 : x; |
return x & 0x800000 ? x - 0x1000000 : x; |
112 |
} |
} |
113 |
|
|
114 |
|
inline void store24(unsigned char* pDst, int x) |
115 |
|
{ |
116 |
|
pDst[0] = x; |
117 |
|
pDst[1] = x >> 8; |
118 |
|
pDst[2] = x >> 16; |
119 |
|
} |
120 |
|
|
121 |
void Decompress16(int compressionmode, const unsigned char* params, |
void Decompress16(int compressionmode, const unsigned char* params, |
122 |
int srcStep, int dstStep, |
int srcStep, int dstStep, |
123 |
const unsigned char* pSrc, int16_t* pDst, |
const unsigned char* pSrc, int16_t* pDst, |
157 |
} |
} |
158 |
|
|
159 |
void Decompress24(int compressionmode, const unsigned char* params, |
void Decompress24(int compressionmode, const unsigned char* params, |
160 |
int dstStep, const unsigned char* pSrc, int16_t* pDst, |
int dstStep, const unsigned char* pSrc, uint8_t* pDst, |
161 |
unsigned long currentframeoffset, |
unsigned long currentframeoffset, |
162 |
unsigned long copysamples, int truncatedBits) |
unsigned long copysamples, int truncatedBits) |
163 |
{ |
{ |
|
// Note: The 24 bits are truncated to 16 bits for now. |
|
|
|
|
164 |
int y, dy, ddy, dddy; |
int y, dy, ddy, dddy; |
|
const int shift = 8 - truncatedBits; |
|
165 |
|
|
166 |
#define GET_PARAMS(params) \ |
#define GET_PARAMS(params) \ |
167 |
y = get24(params); \ |
y = get24(params); \ |
177 |
|
|
178 |
#define COPY_ONE(x) \ |
#define COPY_ONE(x) \ |
179 |
SKIP_ONE(x); \ |
SKIP_ONE(x); \ |
180 |
*pDst = y >> shift; \ |
store24(pDst, y << truncatedBits); \ |
181 |
pDst += dstStep |
pDst += dstStep |
182 |
|
|
183 |
switch (compressionmode) { |
switch (compressionmode) { |
184 |
case 2: // 24 bit uncompressed |
case 2: // 24 bit uncompressed |
185 |
pSrc += currentframeoffset * 3; |
pSrc += currentframeoffset * 3; |
186 |
while (copysamples) { |
while (copysamples) { |
187 |
*pDst = get24(pSrc) >> shift; |
store24(pDst, get24(pSrc) << truncatedBits); |
188 |
pDst += dstStep; |
pDst += dstStep; |
189 |
pSrc += 3; |
pSrc += 3; |
190 |
copysamples--; |
copysamples--; |
895 |
* have to use an external decompression buffer for <b>EACH</b> |
* have to use an external decompression buffer for <b>EACH</b> |
896 |
* streaming thread to avoid race conditions and crashes! |
* streaming thread to avoid race conditions and crashes! |
897 |
* |
* |
898 |
|
* For 16 bit samples, the data in the buffer will be int16_t |
899 |
|
* (using native endianness). For 24 bit, the buffer will |
900 |
|
* contain three bytes per sample, little-endian. |
901 |
|
* |
902 |
* @param pBuffer destination buffer |
* @param pBuffer destination buffer |
903 |
* @param SampleCount number of sample points to read |
* @param SampleCount number of sample points to read |
904 |
* @param pExternalDecompressionBuffer (optional) external buffer to use for decompression |
* @param pExternalDecompressionBuffer (optional) external buffer to use for decompression |
909 |
if (SampleCount == 0) return 0; |
if (SampleCount == 0) return 0; |
910 |
if (!Compressed) { |
if (!Compressed) { |
911 |
if (BitDepth == 24) { |
if (BitDepth == 24) { |
912 |
// 24 bit sample. For now just truncate to 16 bit. |
return pCkData->Read(pBuffer, SampleCount * FrameSize, 1) / FrameSize; |
|
unsigned char* pSrc = (unsigned char*) ((pExternalDecompressionBuffer) ? pExternalDecompressionBuffer->pStart : this->InternalDecompressionBuffer.pStart); |
|
|
int16_t* pDst = static_cast<int16_t*>(pBuffer); |
|
|
if (Channels == 2) { // Stereo |
|
|
unsigned long readBytes = pCkData->Read(pSrc, SampleCount * 6, 1); |
|
|
pSrc++; |
|
|
for (unsigned long i = readBytes ; i > 0 ; i -= 3) { |
|
|
*pDst++ = get16(pSrc); |
|
|
pSrc += 3; |
|
|
} |
|
|
return (pDst - static_cast<int16_t*>(pBuffer)) >> 1; |
|
|
} |
|
|
else { // Mono |
|
|
unsigned long readBytes = pCkData->Read(pSrc, SampleCount * 3, 1); |
|
|
pSrc++; |
|
|
for (unsigned long i = readBytes ; i > 0 ; i -= 3) { |
|
|
*pDst++ = get16(pSrc); |
|
|
pSrc += 3; |
|
|
} |
|
|
return pDst - static_cast<int16_t*>(pBuffer); |
|
|
} |
|
913 |
} |
} |
914 |
else { // 16 bit |
else { // 16 bit |
915 |
// (pCkData->Read does endian correction) |
// (pCkData->Read does endian correction) |
939 |
|
|
940 |
unsigned char* pSrc = (unsigned char*) pDecompressionBuffer->pStart; |
unsigned char* pSrc = (unsigned char*) pDecompressionBuffer->pStart; |
941 |
int16_t* pDst = static_cast<int16_t*>(pBuffer); |
int16_t* pDst = static_cast<int16_t*>(pBuffer); |
942 |
|
uint8_t* pDst24 = static_cast<uint8_t*>(pBuffer); |
943 |
remainingbytes = pCkData->Read(pSrc, assumedsize, 1); |
remainingbytes = pCkData->Read(pSrc, assumedsize, 1); |
944 |
|
|
945 |
while (remainingsamples && remainingbytes) { |
while (remainingsamples && remainingbytes) { |
1021 |
const unsigned char* const param_r = pSrc; |
const unsigned char* const param_r = pSrc; |
1022 |
if (mode_r != 2) pSrc += 12; |
if (mode_r != 2) pSrc += 12; |
1023 |
|
|
1024 |
Decompress24(mode_l, param_l, 2, pSrc, pDst, |
Decompress24(mode_l, param_l, 6, pSrc, pDst24, |
1025 |
skipsamples, copysamples, TruncatedBits); |
skipsamples, copysamples, TruncatedBits); |
1026 |
Decompress24(mode_r, param_r, 2, pSrc + rightChannelOffset, pDst + 1, |
Decompress24(mode_r, param_r, 6, pSrc + rightChannelOffset, pDst24 + 3, |
1027 |
skipsamples, copysamples, TruncatedBits); |
skipsamples, copysamples, TruncatedBits); |
1028 |
pDst += copysamples << 1; |
pDst24 += copysamples * 6; |
1029 |
} |
} |
1030 |
else { // Mono |
else { // Mono |
1031 |
Decompress24(mode_l, param_l, 1, pSrc, pDst, |
Decompress24(mode_l, param_l, 3, pSrc, pDst24, |
1032 |
skipsamples, copysamples, TruncatedBits); |
skipsamples, copysamples, TruncatedBits); |
1033 |
pDst += copysamples; |
pDst24 += copysamples * 3; |
1034 |
} |
} |
1035 |
} |
} |
1036 |
else { // 16 bit |
else { // 16 bit |
2108 |
// load sample references |
// load sample references |
2109 |
for (uint i = 0; i < DimensionRegions; i++) { |
for (uint i = 0; i < DimensionRegions; i++) { |
2110 |
uint32_t wavepoolindex = _3lnk->ReadUint32(); |
uint32_t wavepoolindex = _3lnk->ReadUint32(); |
2111 |
pDimensionRegions[i]->pSample = GetSampleFromWavePool(wavepoolindex); |
if (file->pWavePoolTable) pDimensionRegions[i]->pSample = GetSampleFromWavePool(wavepoolindex); |
2112 |
} |
} |
2113 |
} |
} |
2114 |
|
|
2486 |
Sample* Region::GetSampleFromWavePool(unsigned int WavePoolTableIndex, progress_t* pProgress) { |
Sample* Region::GetSampleFromWavePool(unsigned int WavePoolTableIndex, progress_t* pProgress) { |
2487 |
if ((int32_t)WavePoolTableIndex == -1) return NULL; |
if ((int32_t)WavePoolTableIndex == -1) return NULL; |
2488 |
File* file = (File*) GetParent()->GetParent(); |
File* file = (File*) GetParent()->GetParent(); |
2489 |
|
if (!file->pWavePoolTable) return NULL; |
2490 |
unsigned long soughtoffset = file->pWavePoolTable[WavePoolTableIndex]; |
unsigned long soughtoffset = file->pWavePoolTable[WavePoolTableIndex]; |
2491 |
unsigned long soughtfileno = file->pWavePoolTableHi[WavePoolTableIndex]; |
unsigned long soughtfileno = file->pWavePoolTableHi[WavePoolTableIndex]; |
2492 |
Sample* sample = file->GetFirstSample(pProgress); |
Sample* sample = file->GetFirstSample(pProgress); |