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.
Core Audio sine wave example
// To run:
// clang core-audio-sine-wave.c -framework AudioUnit && ./a.out
#include <AudioUnit/AudioUnit.h>
#define SAMPLE_RATE 48000
#define TONE_FREQUENCY 440
#define M_TAU 2.0 * M_PI
OSStatus RenderSineWave(
void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData)
{
static float theta;
float *left = (float *)ioData->mBuffers[0].mData;
for (UInt32 frame = 0; frame < inNumberFrames; ++frame) {
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 = {
.componentType = kAudioUnitType_Output,
.componentSubType = kAudioUnitSubType_DefaultOutput,
.componentManufacturer = kAudioUnitManufacturer_Apple,
};
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 = {0};
input.inputProc = RenderSineWave;
err = AudioUnitSetProperty(toneUnit, kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Input, 0, &input, sizeof(input));
if (err) printf("Error setting callback: %d\n", err);
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));
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);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment