commit 8ddb8f37ce2c412212502031a87497ad9dd306d4 parent 03796536a0751c52d8b14305f64671891b44aeb1 Author: Michael Savage <mikejsavage@gmail.com> Date: Mon Oct 24 23:11:48 +0300 Totally untested (not even compiled) OSX audio output code Diffstat:
darwin_audio_output.cc | | | 66 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
darwin_audio_output.h | | | 12 | ++++++++++++ |
diff --git a/darwin_audio_output.cc b/darwin_audio_output.cc @@ -0,0 +1,66 @@ +#include <AudioToolbox/AudioToolbox.h> + +#include "intrinsics.h" +#include "platform_audio_output.h" + +void audio_output_init() { } +void audio_output_term() { } + +static OSStatus audio_output_callback( + void * data, + AudioUnitRenderActionFlags * ioActionFlags, + const AudioTimeStamp * inTimeStamp, + u32 inBusNumber, u32 num_samples, + AudioBufferList * buffers +) { + AudioOutputDevice * device = ( AudioOutputDevice * ) data; + + s16 * samples = ( s16 * ) buffers->mBuffers[ 0 ].mData; + device->callback( samples, checked_cast< s32 >( num_samples ) ); + + return 0; +} + +void audio_output_open( AudioOutputDevice * device, AudioOutputCallback callback ) { + AudioComponentDescription desc = { }; + desc.componentType = kAudioUnitType_Output; + desc.componentSubType = kAudioUnitSubType_RemoteIO; + desc.componentManufacturer = kAudioUnitManufacturer_Apple; + + device->component = AudioComponentFindNext( NULL, &desc ); + if( device->component == NULL ) { + FATAL( "AudioComponentFindNext" ); + } + + if( AudioComponentInstanceNew( component, &unit ) ) { + FATAL( "AudioComponentInstanceNew" ); + } + + AudioUnitInitialize( unit ); + + const int rate = 44100; + const int channels = 1; + AudioStreamBasicDescription stream_format = { }; + stream_format.mSampleRate = rate; + stream_format.mFormatID = kAudioFormatLinearPCM; + stream_format.mFormatFlags = kAudioFormatFlagIsSignedInteger; + stream_format.mFramesPerPacket = 1; + stream_format.mChannelsPerFrame = channels; + stream_format.mBitsPerChannel = 16; + stream_format.mBytesPerPacket = channels * 2; + stream_format.mBytesPerFrame = channels * 2; + + AudioUnitSetProperty( unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &stream_format, sizeof( stream_format ) ); + + AURenderCallbackStruct cb = { }; + cb.inputProc = audio_output_callback; + cb.inputProcRefCon = device; + + AudioUnitSetProperty( unit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Global, 0, &cb, sizeof( AURenderCallbackStruct ) ); + + AudioOutputUnitStart( unit ); +} + +void audio_output_close( AudioOutputDevice * device ) { + FATAL( "need to implement audio_output_close" ); +} diff --git a/darwin_audio_output.h b/darwin_audio_output.h @@ -0,0 +1,12 @@ +#ifndef _DARWIN_AUDIO_OUTPUT_H_ +#define _DARWIN_AUDIO_OUTPUT_H_ + +#include <AudioToolbox/AudioToolbox.h> + +struct AudioOutputDevice { + AudioComponent component; + AudioUnit unit; + AudioOutputCallback * callback; +}; + +#endif // _DARWIN_AUDIO_OUTPUT_H_