Skip to content

Instantly share code, notes, and snippets.

@guidoschmidt
Forked from gcatlin/core-audio-sine-wave.c
Created May 23, 2025 19:27
Show Gist options
  • Select an option

  • Save guidoschmidt/7ce46c0368d6d7eebad49d28835b5904 to your computer and use it in GitHub Desktop.

Select an option

Save guidoschmidt/7ce46c0368d6d7eebad49d28835b5904 to your computer and use it in GitHub Desktop.

Revisions

  1. @gcatlin gcatlin revised this gist Dec 10, 2016. 1 changed file with 11 additions and 8 deletions.
    19 changes: 11 additions & 8 deletions core-audio-sine-wave.c
    Original file line number Diff line number Diff line change
    @@ -16,9 +16,9 @@ OSStatus RenderSineWave(
    {
    static float theta;

    float *left = (float *)ioData->mBuffers[0].mData;
    SInt16 *left = (SInt16 *)ioData->mBuffers[0].mData;
    for (UInt32 frame = 0; frame < inNumberFrames; ++frame) {
    left[frame] = sin(theta);
    left[frame] = (SInt16)(sin(theta) * 32767.0f);
    theta += M_TAU * TONE_FREQUENCY / SAMPLE_RATE;
    if (theta > M_TAU) {
    theta -= M_TAU;
    @@ -54,13 +54,16 @@ int main() {

    AudioStreamBasicDescription asbd = {
    .mFormatID = kAudioFormatLinearPCM,
    .mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kAudioFormatFlagIsNonInterleaved,
    .mFormatFlags = 0
    | kAudioFormatFlagIsSignedInteger
    | kAudioFormatFlagIsPacked
    | kAudioFormatFlagIsNonInterleaved,
    .mSampleRate = 48000,
    .mBitsPerChannel = 32,
    .mBitsPerChannel = 16,
    .mChannelsPerFrame = 2,
    .mFramesPerPacket = 1,
    .mBytesPerFrame = 4,
    .mBytesPerPacket = 4,
    .mBytesPerFrame = 2,
    .mBytesPerPacket = 2,
    };

    err = AudioUnitSetProperty(toneUnit, kAudioUnitProperty_StreamFormat,
    @@ -73,9 +76,9 @@ int main() {
    err = AudioOutputUnitStart(toneUnit);
    if (err) printf("Error starting unit: %d\n", err);

    usleep(2000000);
    usleep(500000);

    AudioOutputUnitStop(toneUnit);
    AudioUnitUninitialize(toneUnit);
    AudioComponentInstanceDispose(toneUnit);
    }
    }
  2. @gcatlin gcatlin revised this gist Dec 10, 2016. 1 changed file with 1 addition and 3 deletions.
    4 changes: 1 addition & 3 deletions core-audio-sine-wave.c
    Original file line number Diff line number Diff line change
    @@ -54,9 +54,7 @@ int main() {

    AudioStreamBasicDescription asbd = {
    .mFormatID = kAudioFormatLinearPCM,
    .mFormatFlags = 0
    | kAudioFormatFlagsNativeFloatPacked
    | kAudioFormatFlagIsNonInterleaved,
    .mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kAudioFormatFlagIsNonInterleaved,
    .mSampleRate = 48000,
    .mBitsPerChannel = 32,
    .mChannelsPerFrame = 2,
  3. @gcatlin gcatlin revised this gist Dec 10, 2016. 1 changed file with 1 addition and 2 deletions.
    3 changes: 1 addition & 2 deletions core-audio-sine-wave.c
    Original file line number Diff line number Diff line change
    @@ -47,8 +47,7 @@ int main() {
    err = AudioComponentInstanceNew(output, &toneUnit);
    if (err) fprintf(stderr, "Error creating unit: %d\n", err);

    AURenderCallbackStruct input = {0};
    input.inputProc = RenderSineWave;
    AURenderCallbackStruct input = { .inputProc = RenderSineWave };
    err = AudioUnitSetProperty(toneUnit, kAudioUnitProperty_SetRenderCallback,
    kAudioUnitScope_Input, 0, &input, sizeof(input));
    if (err) printf("Error setting callback: %d\n", err);
  4. @gcatlin gcatlin revised this gist Dec 10, 2016. 1 changed file with 28 additions and 22 deletions.
    50 changes: 28 additions & 22 deletions core-audio-sine-wave.c
    Original file line number Diff line number Diff line change
    @@ -2,9 +2,9 @@
    // clang core-audio-sine-wave.c -framework AudioUnit && ./a.out
    #include <AudioUnit/AudioUnit.h>

    #define SAMPLING_RATE 48000
    #define SAMPLE_RATE 48000
    #define TONE_FREQUENCY 440
    #define M_TAU 2 * M_PI
    #define M_TAU 2.0 * M_PI

    OSStatus RenderSineWave(
    void *inRefCon,
    @@ -15,26 +15,30 @@ OSStatus RenderSineWave(
    AudioBufferList *ioData)
    {
    static float theta;
    float *channel = (float *)ioData->mBuffers[0].mData;

    float *left = (float *)ioData->mBuffers[0].mData;
    for (UInt32 frame = 0; frame < inNumberFrames; ++frame) {
    channel[frame] = sin(theta);
    theta += M_TAU * TONE_FREQUENCY / SAMPLING_RATE;
    left[frame] = sin(theta);
    theta += M_TAU * TONE_FREQUENCY / SAMPLE_RATE;
    if (theta > M_TAU) {
    theta -= M_TAU;
    }
    }

    // Copy left channel to right channel
    memcpy(ioData->mBuffers[1].mData, left, ioData->mBuffers[1].mDataByteSize);

    return noErr;
    }

    int main() {
    OSErr err;

    AudioComponentDescription acd;
    acd.componentType = kAudioUnitType_Output;
    acd.componentSubType = kAudioUnitSubType_DefaultOutput;
    acd.componentManufacturer = kAudioUnitManufacturer_Apple;
    acd.componentFlags = 0;
    acd.componentFlagsMask = 0;
    AudioComponentDescription acd = {
    .componentType = kAudioUnitType_Output,
    .componentSubType = kAudioUnitSubType_DefaultOutput,
    .componentManufacturer = kAudioUnitManufacturer_Apple,
    };

    AudioComponent output = AudioComponentFindNext(NULL, &acd);
    if (!output) printf("Can't find default output\n");
    @@ -43,22 +47,24 @@ int main() {
    err = AudioComponentInstanceNew(output, &toneUnit);
    if (err) fprintf(stderr, "Error creating unit: %d\n", err);

    AURenderCallbackStruct input;
    AURenderCallbackStruct input = {0};
    input.inputProc = RenderSineWave;
    input.inputProcRefCon = NULL;
    err = AudioUnitSetProperty(toneUnit, kAudioUnitProperty_SetRenderCallback,
    kAudioUnitScope_Input, 0, &input, sizeof(input));
    if (err) printf("Error setting callback: %d\n", err);

    AudioStreamBasicDescription asbd;
    asbd.mFormatID = kAudioFormatLinearPCM;
    asbd.mFormatFlags = kAudioFormatFlagsNativeFloatPacked;
    asbd.mSampleRate = SAMPLING_RATE;
    asbd.mBitsPerChannel = 32;
    asbd.mChannelsPerFrame = 1;
    asbd.mFramesPerPacket = 1;
    asbd.mBytesPerFrame = asbd.mBitsPerChannel / 8 * asbd.mChannelsPerFrame;
    asbd.mBytesPerPacket = asbd.mBytesPerFrame * asbd.mFramesPerPacket;
    AudioStreamBasicDescription asbd = {
    .mFormatID = kAudioFormatLinearPCM,
    .mFormatFlags = 0
    | kAudioFormatFlagsNativeFloatPacked
    | kAudioFormatFlagIsNonInterleaved,
    .mSampleRate = 48000,
    .mBitsPerChannel = 32,
    .mChannelsPerFrame = 2,
    .mFramesPerPacket = 1,
    .mBytesPerFrame = 4,
    .mBytesPerPacket = 4,
    };

    err = AudioUnitSetProperty(toneUnit, kAudioUnitProperty_StreamFormat,
    kAudioUnitScope_Input, 0, &asbd, sizeof(asbd));
  5. @gcatlin gcatlin revised this gist Dec 10, 2016. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions core-audio-sine-wave.c
    Original file line number Diff line number Diff line change
    @@ -57,8 +57,8 @@ int main() {
    asbd.mBitsPerChannel = 32;
    asbd.mChannelsPerFrame = 1;
    asbd.mFramesPerPacket = 1;
    asbd.mBytesPerFrame = 4;
    asbd.mBytesPerPacket = 4;
    asbd.mBytesPerFrame = asbd.mBitsPerChannel / 8 * asbd.mChannelsPerFrame;
    asbd.mBytesPerPacket = asbd.mBytesPerFrame * asbd.mFramesPerPacket;

    err = AudioUnitSetProperty(toneUnit, kAudioUnitProperty_StreamFormat,
    kAudioUnitScope_Input, 0, &asbd, sizeof(asbd));
  6. @gcatlin gcatlin revised this gist Dec 10, 2016. No changes.
  7. @gcatlin gcatlin created this gist Dec 10, 2016.
    78 changes: 78 additions & 0 deletions core-audio-sine-wave.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,78 @@
    // To run:
    // clang core-audio-sine-wave.c -framework AudioUnit && ./a.out
    #include <AudioUnit/AudioUnit.h>

    #define SAMPLING_RATE 48000
    #define TONE_FREQUENCY 440
    #define M_TAU 2 * M_PI

    OSStatus RenderSineWave(
    void *inRefCon,
    AudioUnitRenderActionFlags *ioActionFlags,
    const AudioTimeStamp *inTimeStamp,
    UInt32 inBusNumber,
    UInt32 inNumberFrames,
    AudioBufferList *ioData)
    {
    static float theta;
    float *channel = (float *)ioData->mBuffers[0].mData;
    for (UInt32 frame = 0; frame < inNumberFrames; ++frame) {
    channel[frame] = sin(theta);
    theta += M_TAU * TONE_FREQUENCY / SAMPLING_RATE;
    if (theta > M_TAU) {
    theta -= M_TAU;
    }
    }
    return noErr;
    }

    int main() {
    OSErr err;

    AudioComponentDescription acd;
    acd.componentType = kAudioUnitType_Output;
    acd.componentSubType = kAudioUnitSubType_DefaultOutput;
    acd.componentManufacturer = kAudioUnitManufacturer_Apple;
    acd.componentFlags = 0;
    acd.componentFlagsMask = 0;

    AudioComponent output = AudioComponentFindNext(NULL, &acd);
    if (!output) printf("Can't find default output\n");

    AudioUnit toneUnit;
    err = AudioComponentInstanceNew(output, &toneUnit);
    if (err) fprintf(stderr, "Error creating unit: %d\n", err);

    AURenderCallbackStruct input;
    input.inputProc = RenderSineWave;
    input.inputProcRefCon = NULL;
    err = AudioUnitSetProperty(toneUnit, kAudioUnitProperty_SetRenderCallback,
    kAudioUnitScope_Input, 0, &input, sizeof(input));
    if (err) printf("Error setting callback: %d\n", err);

    AudioStreamBasicDescription asbd;
    asbd.mFormatID = kAudioFormatLinearPCM;
    asbd.mFormatFlags = kAudioFormatFlagsNativeFloatPacked;
    asbd.mSampleRate = SAMPLING_RATE;
    asbd.mBitsPerChannel = 32;
    asbd.mChannelsPerFrame = 1;
    asbd.mFramesPerPacket = 1;
    asbd.mBytesPerFrame = 4;
    asbd.mBytesPerPacket = 4;

    err = AudioUnitSetProperty(toneUnit, kAudioUnitProperty_StreamFormat,
    kAudioUnitScope_Input, 0, &asbd, sizeof(asbd));
    if (err) printf("Error setting stream format: %d\n", err);

    err = AudioUnitInitialize(toneUnit);
    if (err) printf("Error initializing unit: %d\n", err);

    err = AudioOutputUnitStart(toneUnit);
    if (err) printf("Error starting unit: %d\n", err);

    usleep(2000000);

    AudioOutputUnitStop(toneUnit);
    AudioUnitUninitialize(toneUnit);
    AudioComponentInstanceDispose(toneUnit);
    }