I'm trying to write raw audio bytes to a file using AudioFileWriteBytes(). Here's what I'm doing:
void writeSingleChannelRingBufferDataToFileAsSInt16(AudioFileID audioFileID, AudioConverterRef audioConverter, ringBuffer *rb, SInt16 *holdingBuffer) {
// First, figure out which bits of audio we'll be
// writing to file from the ring buffer
UInt32 lastFreshSample = rb->lastWrittenIndex;
OSStatus status;
int numSamplesToWrite;
UInt32 numBytesToWrite;
if (lastFreshSample < rb->lastReadIndex) {
numSamplesToWrite = kNumPointsInWave + lastFreshSample - rb->lastReadIndex - 1;
}
else {
numSamplesToWrite = lastFreshSample - rb->lastReadIndex;
}
numBytesToWrite = numSamplesToWrite*sizeof(SInt16);
Then we copy the audio data (stored as floats) to a holding buffer (SInt16) that will be written directly to the file. The copying looks funky because it's from a ring buffer.
UInt32 buffLen = rb->sizeOfBuffer - 1;
for (int i=0; i < numSamplesToWrite; ++i) {
holdingBuffer[i] = rb->data[(i + rb->lastReadIndex) & buffLen];
}
Okay, now we actually try to write开发者_如何学Go the audio from the SInt16 buffer "holdingBuffer" to the audio file. The NSLog will spit out an error -40, but also claims that it's writing bytes. No data is written to file.
status = AudioFileWriteBytes(audioFileID, NO, 0, &numBytesToWrite, &holdingBuffer);
rb->lastReadIndex = lastFreshSample;
NSLog(@"Error = %d, wrote %d bytes", status, numBytesToWrite);
return;
What is this error -40? By the way, everything works fine if I write straight from the ringBuffer to the file. Of course it sounds like junk, because I'm writing floats, not SInt16s, but AudioFileWriteBytes doesn't complain.
The key is to explicitly change the endianness of the incoming data to big endian. All I had to do was wrap CFSwapInt16HostToBig around my data to get:
float audioVal = rb->data[(i + rb->lastReadIndex) & buffLen];
holdingBuffer[i] = CFSwapInt16HostToBig((SInt16) audioVal );
精彩评论