wavaudiotoolboxaudioformat

Writing a 32-bit Float Wav File Using Audio File Services


I'm trying to save off some raw PCM values by writing them to a WAV file using Xcode and AudioFileServices, however I am having difficulty writing just a simple sine wave to the file.

Here's my code:

// Set up output file
AudioStreamBasicDescription outputFormat = {0};
outputFormat.mSampleRate = 44100;
outputFormat.mFormatID = kAudioFormatLinearPCM;
outputFormat.mBitsPerChannel = 32;
outputFormat.mFormatFlags = kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked;
outputFormat.mFramesPerPacket = 1;
outputFormat.mChannelsPerFrame = 1;
outputFormat.mBytesPerFrame = 4;
outputFormat.mBytesPerPacket = 4;

AudioFileID outputFile;
CFURLRef outputFileURL =
CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR("output.wav"), kCFURLPOSIXPathStyle, FALSE);
CheckError(AudioFileCreateWithURL(outputFileURL, kAudioFileWAVEType, &outputFormat, kAudioFileFlags_EraseFile, &outputFile), "Could not open output File");
CFRelease(outputFileURL);

Float32 duration = 3.0;
Float32 freq = 261.37;
Float32 amplitude = 0.3;
UInt32 sizeOfBuffer = (UInt32)(outputFormat.mSampleRate*duration)*sizeof(Float32);
Float32 *audioBuffer = (Float32*)malloc(sizeOfBuffer);
printf("Creating Buffer.... \n");
for (int i = 0; i<(int)(outputFormat.mSampleRate*duration); i++)
    audioBuffer[i] = amplitude*sinf(i*freq/outputFormat.mSampleRate*2*M_PI);

printf("Writing to File.... \n");
// Write to Output File
CheckError(AudioFileWriteBytes(outputFile, FALSE, 0, &sizeOfBuffer, &audioBuffer), "Could not write bytes to file");

printf("Write Succesful!\n");
CheckError(AudioFileClose(outputFile), "Could not close file");

The code successfully writes a file that is the right duration, but it sounds really distorted. Am I missing something?


Solution

  • Answered my own question. When using AudioFileWriteBytes I was passing &audioBuffer when I should have just passed audioBuffer since it was already a pointer.

    Here's the correct code:

    // Set up output file
    AudioStreamBasicDescription outputFormat = {0};
    outputFormat.mSampleRate = 44100;
    outputFormat.mFormatID = kAudioFormatLinearPCM;
    outputFormat.mBitsPerChannel = 32;
    outputFormat.mFormatFlags = kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked;
    outputFormat.mFramesPerPacket = 1;
    outputFormat.mChannelsPerFrame = 1;
    outputFormat.mBytesPerFrame = 4;
    outputFormat.mBytesPerPacket = 4;
    
    AudioFileID outputFile;
    CFURLRef outputFileURL =
    CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR("output.wav"), kCFURLPOSIXPathStyle, FALSE);
    CheckError(AudioFileCreateWithURL(outputFileURL, kAudioFileWAVEType, &outputFormat, kAudioFileFlags_EraseFile, &outputFile), "Could not open output File");
    CFRelease(outputFileURL);
    
    Float32 duration = 3.0;
    Float32 freq = 261.37;
    Float32 amplitude = 0.3;
    UInt32 sizeOfBuffer = (UInt32)(outputFormat.mSampleRate*duration)*sizeof(Float32);
    Float32 *audioBuffer = (Float32*)malloc(sizeOfBuffer);
    printf("Creating Buffer.... \n");
    for (int i = 0; i<(int)(outputFormat.mSampleRate*duration); i++)
        audioBuffer[i] = amplitude*sinf(i*freq/outputFormat.mSampleRate*2*M_PI);
    
    printf("Writing to File.... \n");
    // Write to Output File
    CheckError(AudioFileWriteBytes(outputFile, FALSE, 0, &sizeOfBuffer, audioBuffer), "Could not write bytes to file");
    
    printf("Write Succesful!\n");
    CheckError(AudioFileClose(outputFile), "Could not close file");