#include #include #include #include #include constexpr double SAMPLE_RATE = 44100.0; constexpr double FREQUENCY = 440.0; // A4 constexpr double AMPLITUDE = 0.25; struct SineState { double phase = 0.0; }; OSStatus renderCallback( void* inRefCon, AudioUnitRenderActionFlags* ioActionFlags, const AudioTimeStamp* inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList* ioData) { auto* state = static_cast(inRefCon); double phase = state->phase; double phaseIncrement = 2.0 * M_PI * FREQUENCY / SAMPLE_RATE; for (UInt32 frame = 0; frame < inNumberFrames; ++frame) { float sample = static_cast(std::sin(phase) * AMPLITUDE); phase += phaseIncrement; if (phase >= 2.0 * M_PI) phase -= 2.0 * M_PI; // Write same sample to all channels for (UInt32 buffer = 0; buffer < ioData->mNumberBuffers; ++buffer) { float* data = static_cast(ioData->mBuffers[buffer].mData); data[frame] = sample; } } state->phase = phase; return noErr; } int main() { AudioUnit audioUnit; SineState state; // Describe output unit AudioComponentDescription desc{}; desc.componentType = kAudioUnitType_Output; desc.componentSubType = kAudioUnitSubType_DefaultOutput; desc.componentManufacturer = kAudioUnitManufacturer_Apple; AudioComponent comp = AudioComponentFindNext(nullptr, &desc); if (!comp) { std::cerr << "Failed to find audio component\n"; return 1; } AudioComponentInstanceNew(comp, &audioUnit); // Set stream format AudioStreamBasicDescription format{}; format.mSampleRate = SAMPLE_RATE; format.mFormatID = kAudioFormatLinearPCM; format.mFormatFlags = kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked; format.mBitsPerChannel = 32; format.mChannelsPerFrame = 2; format.mBytesPerFrame = sizeof(float) * format.mChannelsPerFrame; format.mFramesPerPacket = 1; format.mBytesPerPacket = format.mBytesPerFrame; AudioUnitSetProperty( audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &format, sizeof(format) ); // Set render callback AURenderCallbackStruct callback{}; callback.inputProc = renderCallback; callback.inputProcRefCon = &state; AudioUnitSetProperty( audioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &callback, sizeof(callback) ); AudioUnitInitialize(audioUnit); AudioOutputUnitStart(audioUnit); std::cout << "Playing sine wave (Ctrl+C to quit)...\n"; while (true) { sleep(1); } AudioOutputUnitStop(audioUnit); AudioUnitUninitialize(audioUnit); AudioComponentInstanceDispose(audioUnit); return 0; }