Can't get float files to decode properly
2007-05-04 00:12:55
I've been pulling my hair out trying to get decoding of float wavpack files to work correctly. I'm working off of a custom framework build of the library (4.40) on OS X (I'm not using the tinydecoder). I am able to decode all bit depths of integer files successfully (8, 12, 16, 24, and 32), so I don't think it is an issue with my build. The code I'm using is fairly straightforward; but no matter what I try float files are decoded to nothing but white noise. I figured I would paste the relevant code excerpt here and see if anyone notices anything that looks funky in the float processing. I tried swab'ing the buffer, but still got white noise. It is worth mentioning that the command-line client (wvunpack) produces a silent WAV from the same 32-bit float input file (32bit_float.wv from the test suite).- (void) fillPCMBuffer { void *writePointer; int32_t inputBuffer [WP_INPUT_BUFFER_LEN]; uint32_t sample; for(;;) { UInt32 bytesToWrite = RING_BUFFER_WRITE_CHUNK_SIZE; UInt32 bytesAvailableToWrite = [[self pcmBuffer] lengthAvailableToWriteReturningPointer:&writePointer]; UInt32 spaceRequired = WP_INPUT_BUFFER_LEN /* * [self pcmFormat].mChannelsPerFrame */ * (32 / 8); if(bytesAvailableToWrite < bytesToWrite || spaceRequired > bytesAvailableToWrite) { break; } // Wavpack uses "complete" samples (one sample across all channels), i.e. a Core Audio frame uint32_t samplesRead = WavpackUnpackSamples(_wpc, inputBuffer, WP_INPUT_BUFFER_LEN / [self pcmFormat].mChannelsPerFrame); // Handle floating point files if(MODE_FLOAT & WavpackGetMode(_wpc)) { if(127 != WavpackGetFloatNormExp(_wpc)) { NSLog(@"Floating point data not scaled to +/- 1.0"); return; } float *inputFloatBuffer = (float *)inputBuffer; float *floatBuffer = (float *)writePointer; float audioSample = 0; for(sample = 0; sample < samplesRead * [self pcmFormat].mChannelsPerFrame; ++sample) { audioSample = inputFloatBuffer[sample]; *floatBuffer++ = (audioSample < -1.0 ? -1.0 : (audioSample > 1.0 ? 1.0 : audioSample)); } [[self pcmBuffer] didWriteLength:samplesRead * [self pcmFormat].mChannelsPerFrame * (32 / 8)]; } else { float *floatBuffer = (float *)writePointer; double scaleFactor = (1LL << WavpackGetBitsPerSample(_wpc)); double audioSample = 0; for(sample = 0; sample < samplesRead * [self pcmFormat].mChannelsPerFrame; ++sample) { if(0 <= inputBuffer[sample]) { audioSample = (double)(inputBuffer[sample] / (scaleFactor - 1)); } else { audioSample = (double)(inputBuffer[sample] / scaleFactor); } *floatBuffer++ = (float)(audioSample < -1.0 ? -1.0 : (audioSample > 1.0 ? 1.0 : audioSample)); } [[self pcmBuffer] didWriteLength:samplesRead * [self pcmFormat].mChannelsPerFrame * (32 / 8)]; } // EOS? if(0 == samplesRead) { [self setAtEndOfStream:YES]; break; } } }