From f4322508938ce570dd063471220e11b016040904 Mon Sep 17 00:00:00 2001 From: tmator Date: Fri, 23 Oct 2009 17:10:27 +0000 Subject: [PATCH] CoreAudio for osx : replace all deprecated functions, now it not block dolphin, but it not work, i'm not a sound specialist git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4457 8ced0084-cf51-0410-be5f-012b33b47a6e --- .../AudioCommon/Src/CoreAudioSoundStream.cpp | 138 ++++++++++++++---- .../AudioCommon/Src/CoreAudioSoundStream.h | 7 + 2 files changed, 115 insertions(+), 30 deletions(-) diff --git a/Source/Core/AudioCommon/Src/CoreAudioSoundStream.cpp b/Source/Core/AudioCommon/Src/CoreAudioSoundStream.cpp index 49c0af6f26..9a037c7058 100644 --- a/Source/Core/AudioCommon/Src/CoreAudioSoundStream.cpp +++ b/Source/Core/AudioCommon/Src/CoreAudioSoundStream.cpp @@ -17,17 +17,33 @@ #include "CoreAudioSoundStream.h" - -AudioDeviceID outputDeviceId; -AudioStreamBasicDescription outputStreamBasicDescription; -AudioDeviceIOProcID outputProcId; -UInt32 outputBufferByteCount; - -static OSStatus outputIoProc(AudioDeviceID inDevice, const AudioTimeStamp *inNow,const AudioBufferList *inInputData, const AudioTimeStamp *inInputTime, AudioBufferList *outOutputData, const AudioTimeStamp *inOutputTime, void *inClientData) +typedef struct internal { + AudioUnit audioUnit; + short realtimeBuffer[1024 * 1024]; +}; + + +OSStatus callback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) { + + UInt32 remaining, len; + void *ptr; + AudioBuffer *data; + + internal *soundStruct = (internal *)inRefCon; + + data = &ioData->mBuffers[0]; + len = data->mDataByteSize; + ptr = data->mData; + + memcpy(ptr, soundStruct->realtimeBuffer, len); + return 0; } + + + void CoreAudioSound::SoundLoop() { CoreAudioInit(); @@ -42,42 +58,104 @@ CoreAudioSound::~CoreAudioSound() } bool CoreAudioSound::CoreAudioInit() { + ComponentDescription desc; + OSStatus err; + UInt32 enableIO; + AURenderCallbackStruct callback_struct; + UInt32 shouldAllocateBuffer = 1; + AudioStreamBasicDescription format; - OSStatus status; - UInt32 size; - size = sizeof(outputDeviceId); - status = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &size, &outputDeviceId); - if (outputDeviceId == kAudioDeviceUnknown) { - printf("CoreAudioDevice Unknown\n"); - return false; + internal *soundStruct = (internal *)malloc(sizeof(internal)); + + desc.componentType = kAudioUnitType_Output; + desc.componentSubType = kAudioUnitSubType_HALOutput; + desc.componentManufacturer = kAudioUnitManufacturer_Apple; + + Component component = FindNextComponent(NULL, &desc); + if (component == NULL) + printf("error finding component\n"); + + err = OpenAComponent(component, &soundStruct->audioUnit); + if (err) + printf("error opening audio component\n"); + + //enable output device + enableIO = 1; + AudioUnitSetProperty(soundStruct->audioUnit, + kAudioOutputUnitProperty_EnableIO, + kAudioUnitScope_Output, + 0, + &enableIO, + sizeof(enableIO)); + + AudioUnitSetProperty(soundStruct->audioUnit, kAudioUnitProperty_ShouldAllocateBuffer, kAudioUnitScope_Global, 1, &shouldAllocateBuffer, sizeof(shouldAllocateBuffer)); + if (err) + printf("error while allocate audiounit buffer\n"); + + + format.mBitsPerChannel = 16; + format.mChannelsPerFrame = 2; + format.mBytesPerPacket = sizeof(float); + format.mBytesPerFrame = sizeof(float); + format.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; + format.mFormatID = kAudioFormatLinearPCM; + format.mFramesPerPacket = 1; + format.mSampleRate = m_mixer->GetSampleRate(); + + //set format to output scope + err = AudioUnitSetProperty(soundStruct->audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &format, sizeof(AudioStreamBasicDescription)); + if (err) + printf("error when setting output format\n"); + + + callback_struct.inputProc = callback; + callback_struct.inputProcRefCon = soundStruct; + + err = AudioUnitSetProperty(soundStruct->audioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Global, 0, &callback_struct, sizeof(callback_struct)); + if (err) + printf("error when setting output callback\n"); + + err = AudioUnitInitialize(soundStruct->audioUnit); + if (err) + printf("error when initiaising audiounit\n"); + + err = AudioOutputUnitStart(soundStruct->audioUnit); + if (err) + printf("error when stating audiounit\n"); + + while(!threadData) + { + m_mixer->Mix(soundStruct->realtimeBuffer, 2048); } - - size = sizeof(outputStreamBasicDescription); - status = AudioDeviceGetProperty(outputDeviceId, 0, false, kAudioDevicePropertyStreamFormat, &size, &outputStreamBasicDescription); - - size = sizeof(outputBufferByteCount); - - outputBufferByteCount = 8192; - status = AudioDeviceSetProperty(outputDeviceId, 0, 0, false, kAudioDevicePropertyBufferSize, size, &outputBufferByteCount); - - status = AudioDeviceGetProperty(outputDeviceId, 0, false, kAudioDevicePropertyBufferSize, &size, &outputBufferByteCount); - - - status = AudioDeviceCreateIOProcID( outputDeviceId, outputIoProc, NULL, &outputProcId ); - + return true; } +void *coreAudioThread(void *args) +{ + + ((CoreAudioSound *)args)->SoundLoop(); + return NULL; +} + + bool CoreAudioSound::Start() { - AudioDeviceStart(outputDeviceId,outputProcId); + + soundSyncEvent.Init(); + + thread = new Common::Thread(coreAudioThread, (void *)this); + return true; } void CoreAudioSound::Stop() { + delete thread; + thread = NULL; + return; } @@ -85,4 +163,4 @@ void CoreAudioSound::Update() { return; -} \ No newline at end of file +} diff --git a/Source/Core/AudioCommon/Src/CoreAudioSoundStream.h b/Source/Core/AudioCommon/Src/CoreAudioSoundStream.h index b336708a4a..f4ca2e8356 100644 --- a/Source/Core/AudioCommon/Src/CoreAudioSoundStream.h +++ b/Source/Core/AudioCommon/Src/CoreAudioSoundStream.h @@ -22,6 +22,8 @@ #include "SoundStream.h" #if defined(__APPLE__) #include +#include +#include #endif #include "Thread.h" @@ -29,6 +31,11 @@ class CoreAudioSound : public SoundStream { #if defined(__APPLE__) + + Common::Thread *thread; + Common::CriticalSection soundCriticalSection; + Common::Event soundSyncEvent; + public: CoreAudioSound(CMixer *mixer); virtual ~CoreAudioSound();