I'm trying to save some audio data to a WAV file -- I have audio data that normally I've been using in RemoteIO but I'm now trying to implement a function to save the data. I know the audio data is valid, so that's not a concern -- if I can just get an empty WAV file set up of the correct length, I can fill it with data later.
Right now, the code creates the file and it looks to be the right length in bytes, but apparently it's not formatted correctly, because OSX, QuickTime, iTunes, etc can't recognize it (they see the file, can't determine a length, or play it)
NSURL * tvarFilename = [savePanel URL];
NSLog(@"doSaveAs filename = %@",tvarFilename);
//try to create an audio file there
AudioFileID mRecordFile;
AudioStreamBasicDescription audioFormat;
audioFormat.mSampleRate = 44100.00;
audioFormat.mFormatID = kAudioFormatLinearPCM;
audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
audioFormat.mFramesPerPacket = 1;
audioFormat.mChannelsPerFrame = 2;
audioFormat.mBitsPerChannel = 16;
audioFormat.mBytesPerPacket = 4;
audioFormat.mBytesPerFrame = 4;
OSStatus status = AudioFileCreateWithURL((CFURLRef)tvarFilename, kAudioFileWAVEType, &audioFormat, kAudioFileFlags_EraseFile, &mRecordFile);
int beatsToRecord = 4; //temporary
int bpm = 120;
double intervalInSamples = (double) 60 / bpm;
intervalInSamples *= (double)44100;
int inNumberFrames = (intervalInSamples * beatsToRecord);
UInt32 frameBuffer[inNumberFrames];
int sampleTime = 0;
UInt32 thisSubBuffer[inNumberFrames];
for (int i = 0; i < inNumberFrames; i++) { frameBuffer[i] = 0; }
UInt32 bytesToWrite = inNumberFrames * sizeof(UInt32);
status = AudioFileWriteBytes(mRecordFile, false, 0, &bytesToWrite, &frameBuffer);
A WAV file is really simple: it only consists of a (usually 44-byte long) header section, then the raw PCM data. I've written a library which needs to record WAV files, and I'm pretty sure you'll understand how I accomplish it. For clarifying:
/**
* CD quality: 44100 Hz sample rate, 16 bit per sample, 2 channels (stereo):
**/
struct sprec_wav_header *hdr = sprec_wav_header_from_params(44100, 16, 2);
int filesize = (obtain the filesize somehow here);
/**
* -8 bytes for the first part of the header, see the WAV specification
**/
hdr->filesize = filesize - 8;
int filedesc = open("/tmp/dummy.wav", O_WRONLY | O_CREAT, 0644);
if (sprec_wav_header_write(filedesc, hdr))
{
printf("Error writing WAV header!\n");
}
close(filedesc);
free(hdr);
And the library I've written: https://github.com/H2CO3/libsprec/
Hope this helps.