WavPack input: Decode DSD without letting WavPack library decimate it. The supplied filter was rather noisy.
parent
903b457a28
commit
ec0b343596
|
@ -33,6 +33,11 @@
|
||||||
WavPackReader *wv;
|
WavPackReader *wv;
|
||||||
WavPackReader *wvc;
|
WavPackReader *wvc;
|
||||||
|
|
||||||
|
int32_t *inputBuffer;
|
||||||
|
size_t inputBufferSize;
|
||||||
|
|
||||||
|
BOOL isDSD;
|
||||||
|
|
||||||
int bitsPerSample;
|
int bitsPerSample;
|
||||||
int channels;
|
int channels;
|
||||||
BOOL floatingPoint;
|
BOOL floatingPoint;
|
||||||
|
|
|
@ -113,6 +113,8 @@ int32_t WriteBytesProc(void *ds, void *data, int32_t bcount)
|
||||||
if (self)
|
if (self)
|
||||||
{
|
{
|
||||||
wpc = NULL;
|
wpc = NULL;
|
||||||
|
inputBuffer = NULL;
|
||||||
|
inputBufferSize = 0;
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -153,7 +155,7 @@ int32_t WriteBytesProc(void *ds, void *data, int32_t bcount)
|
||||||
reader.can_seek = CanSeekProc;
|
reader.can_seek = CanSeekProc;
|
||||||
reader.write_bytes = WriteBytesProc;
|
reader.write_bytes = WriteBytesProc;
|
||||||
|
|
||||||
open_flags |= OPEN_DSD_AS_PCM | OPEN_ALT_TYPES;
|
open_flags |= OPEN_DSD_NATIVE | OPEN_ALT_TYPES;
|
||||||
|
|
||||||
if (![s seekable])
|
if (![s seekable])
|
||||||
open_flags |= OPEN_STREAMING;
|
open_flags |= OPEN_STREAMING;
|
||||||
|
@ -171,6 +173,17 @@ int32_t WriteBytesProc(void *ds, void *data, int32_t bcount)
|
||||||
|
|
||||||
totalFrames = WavpackGetNumSamples(wpc);
|
totalFrames = WavpackGetNumSamples(wpc);
|
||||||
|
|
||||||
|
isDSD = NO;
|
||||||
|
|
||||||
|
float nativeFrequency = WavpackGetNativeSampleRate(wpc);
|
||||||
|
|
||||||
|
if (nativeFrequency != frequency && bitsPerSample == 8) {
|
||||||
|
isDSD = YES;
|
||||||
|
frequency = nativeFrequency;
|
||||||
|
bitsPerSample = 1;
|
||||||
|
totalFrames *= 8;
|
||||||
|
}
|
||||||
|
|
||||||
bitrate = (int)(WavpackGetAverageBitrate(wpc, TRUE)/1000.0);
|
bitrate = (int)(WavpackGetAverageBitrate(wpc, TRUE)/1000.0);
|
||||||
|
|
||||||
floatingPoint = MODE_FLOAT & WavpackGetMode(wpc) && 127 == WavpackGetFloatNormExp(wpc);
|
floatingPoint = MODE_FLOAT & WavpackGetMode(wpc) && 127 == WavpackGetFloatNormExp(wpc);
|
||||||
|
@ -212,12 +225,31 @@ int32_t WriteBytesProc(void *ds, void *data, int32_t bcount)
|
||||||
int16_t *alias16;
|
int16_t *alias16;
|
||||||
int32_t *alias32;
|
int32_t *alias32;
|
||||||
|
|
||||||
int32_t *inputBuffer = malloc(frames*sizeof(int32_t));
|
UInt32 trueFrames = frames;
|
||||||
|
|
||||||
// Wavpack uses "complete" samples (one sample across all channels), i.e. a Core Audio frame
|
if (isDSD) trueFrames = (frames / 8) & ~7;
|
||||||
samplesRead = WavpackUnpackSamples(wpc, inputBuffer, frames/channels);
|
|
||||||
|
size_t newSize = trueFrames*sizeof(int32_t)*channels;
|
||||||
|
if (!inputBuffer || newSize > inputBufferSize) {
|
||||||
|
inputBuffer = realloc(inputBuffer, inputBufferSize = newSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
samplesRead = WavpackUnpackSamples(wpc, inputBuffer, trueFrames);
|
||||||
|
|
||||||
switch(bitsPerSample) {
|
switch(bitsPerSample) {
|
||||||
|
case 1:
|
||||||
|
alias8 = buf;
|
||||||
|
for (sample = 0; sample < samplesRead * channels;) {
|
||||||
|
for (int channel = 0; channel < channels; channel++) {
|
||||||
|
for (int i = 0, mask = 0x80; i < 8; ++i, mask >>= 1) {
|
||||||
|
alias8[i * channels] = (inputBuffer[sample] & mask) ? 127 : -128;
|
||||||
|
}
|
||||||
|
alias8 += 1;
|
||||||
|
sample++;
|
||||||
|
}
|
||||||
|
alias8 += 7 * channels;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
// No need for byte swapping
|
// No need for byte swapping
|
||||||
alias8 = buf;
|
alias8 = buf;
|
||||||
|
@ -253,14 +285,17 @@ int32_t WriteBytesProc(void *ds, void *data, int32_t bcount)
|
||||||
ALog(@"Unsupported sample size: %d", bitsPerSample);
|
ALog(@"Unsupported sample size: %d", bitsPerSample);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(inputBuffer);
|
if (isDSD)
|
||||||
|
samplesRead *= 8;
|
||||||
|
|
||||||
return samplesRead;
|
return samplesRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (long)seek:(long)frame
|
- (long)seek:(long)frame
|
||||||
{
|
{
|
||||||
WavpackSeekSample(wpc, (uint32_t) frame);
|
uint32_t trueFrame = (uint32_t) frame;
|
||||||
|
if (isDSD) { trueFrame /= 8; frame = trueFrame * 8; }
|
||||||
|
WavpackSeekSample(wpc, trueFrame);
|
||||||
|
|
||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
@ -271,6 +306,11 @@ int32_t WriteBytesProc(void *ds, void *data, int32_t bcount)
|
||||||
WavpackCloseFile(wpc);
|
WavpackCloseFile(wpc);
|
||||||
wpc = NULL;
|
wpc = NULL;
|
||||||
}
|
}
|
||||||
|
if (inputBuffer) {
|
||||||
|
free(inputBuffer);
|
||||||
|
inputBuffer = NULL;
|
||||||
|
inputBufferSize = 0;
|
||||||
|
}
|
||||||
wvc = nil;
|
wvc = nil;
|
||||||
wv = nil;
|
wv = nil;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue