| 
									
										
										
										
											2015-05-24 06:55:12 +02:00
										 |  |  | // Copyright 2009 Dolphin Emulator Project
 | 
					
						
							| 
									
										
										
										
											2015-05-18 01:08:10 +02:00
										 |  |  | // Licensed under GPLv2+
 | 
					
						
							| 
									
										
										
										
											2013-04-21 02:17:03 -04:00
										 |  |  | // Refer to the license.txt file included.
 | 
					
						
							| 
									
										
										
										
											2009-09-24 21:35:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 16:30:30 -05:00
										 |  |  | #include <AudioUnit/AudioUnit.h>
 | 
					
						
							| 
									
										
										
										
											2011-01-27 05:01:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-17 05:18:15 -05:00
										 |  |  | #include "AudioCommon/CoreAudioSoundStream.h"
 | 
					
						
							| 
									
										
										
										
											2015-09-26 17:13:07 -04:00
										 |  |  | #include "Common/Logging/Log.h"
 | 
					
						
							| 
									
										
										
										
											2009-09-24 21:35:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | OSStatus CoreAudioSound::callback(void* inRefCon, AudioUnitRenderActionFlags* ioActionFlags, | 
					
						
							|  |  |  |                                   const AudioTimeStamp* inTimeStamp, UInt32 inBusNumber, | 
					
						
							|  |  |  |                                   UInt32 inNumberFrames, AudioBufferList* ioData) | 
					
						
							| 
									
										
										
										
											2010-05-30 04:21:01 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   for (UInt32 i = 0; i < ioData->mNumberBuffers; i++) | 
					
						
							|  |  |  |     ((CoreAudioSound*)inRefCon) | 
					
						
							|  |  |  |         ->m_mixer->Mix((short*)ioData->mBuffers[i].mData, ioData->mBuffers[i].mDataByteSize / 4); | 
					
						
							| 
									
										
										
										
											2010-05-30 04:21:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   return noErr; | 
					
						
							| 
									
										
										
										
											2009-09-24 21:35:06 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-31 05:05:53 +00:00
										 |  |  | bool CoreAudioSound::Start() | 
					
						
							| 
									
										
										
										
											2009-09-24 21:35:06 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   OSStatus err; | 
					
						
							|  |  |  |   AURenderCallbackStruct callback_struct; | 
					
						
							|  |  |  |   AudioStreamBasicDescription format; | 
					
						
							|  |  |  |   AudioComponentDescription desc; | 
					
						
							|  |  |  |   AudioComponent component; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   desc.componentType = kAudioUnitType_Output; | 
					
						
							|  |  |  |   desc.componentSubType = kAudioUnitSubType_DefaultOutput; | 
					
						
							|  |  |  |   desc.componentFlags = 0; | 
					
						
							|  |  |  |   desc.componentFlagsMask = 0; | 
					
						
							|  |  |  |   desc.componentManufacturer = kAudioUnitManufacturer_Apple; | 
					
						
							|  |  |  |   component = AudioComponentFindNext(nullptr, &desc); | 
					
						
							|  |  |  |   if (component == nullptr) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     ERROR_LOG(AUDIO, "error finding audio component"); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   err = AudioComponentInstanceNew(component, &audioUnit); | 
					
						
							|  |  |  |   if (err != noErr) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     ERROR_LOG(AUDIO, "error opening audio component"); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   FillOutASBDForLPCM(format, m_mixer->GetSampleRate(), 2, 16, 16, false, false, false); | 
					
						
							|  |  |  |   err = AudioUnitSetProperty(audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, | 
					
						
							|  |  |  |                              &format, sizeof(AudioStreamBasicDescription)); | 
					
						
							|  |  |  |   if (err != noErr) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     ERROR_LOG(AUDIO, "error setting audio format"); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   callback_struct.inputProc = callback; | 
					
						
							|  |  |  |   callback_struct.inputProcRefCon = this; | 
					
						
							|  |  |  |   err = AudioUnitSetProperty(audioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, | 
					
						
							|  |  |  |                              0, &callback_struct, sizeof callback_struct); | 
					
						
							|  |  |  |   if (err != noErr) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     ERROR_LOG(AUDIO, "error setting audio callback"); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   err = AudioUnitSetParameter(audioUnit, kHALOutputParam_Volume, kAudioUnitScope_Output, 0, | 
					
						
							|  |  |  |                               m_volume / 100., 0); | 
					
						
							|  |  |  |   if (err != noErr) | 
					
						
							|  |  |  |     ERROR_LOG(AUDIO, "error setting volume"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   err = AudioUnitInitialize(audioUnit); | 
					
						
							|  |  |  |   if (err != noErr) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     ERROR_LOG(AUDIO, "error initializing audiounit"); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   err = AudioOutputUnitStart(audioUnit); | 
					
						
							|  |  |  |   if (err != noErr) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     ERROR_LOG(AUDIO, "error starting audiounit"); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return true; | 
					
						
							| 
									
										
										
										
											2009-09-24 21:35:06 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-02 02:49:30 +00:00
										 |  |  | void CoreAudioSound::SetVolume(int volume) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   OSStatus err; | 
					
						
							|  |  |  |   m_volume = volume; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   err = AudioUnitSetParameter(audioUnit, kHALOutputParam_Volume, kAudioUnitScope_Output, 0, | 
					
						
							|  |  |  |                               volume / 100., 0); | 
					
						
							|  |  |  |   if (err != noErr) | 
					
						
							|  |  |  |     ERROR_LOG(AUDIO, "error setting volume"); | 
					
						
							| 
									
										
										
										
											2011-01-02 02:49:30 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-31 05:05:53 +00:00
										 |  |  | void CoreAudioSound::SoundLoop() | 
					
						
							| 
									
										
										
										
											2009-09-24 21:35:06 +00:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CoreAudioSound::Stop() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   OSStatus err; | 
					
						
							| 
									
										
										
										
											2009-10-23 17:10:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   err = AudioOutputUnitStop(audioUnit); | 
					
						
							|  |  |  |   if (err != noErr) | 
					
						
							|  |  |  |     ERROR_LOG(AUDIO, "error stopping audiounit"); | 
					
						
							| 
									
										
										
										
											2010-05-31 05:05:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   err = AudioUnitUninitialize(audioUnit); | 
					
						
							|  |  |  |   if (err != noErr) | 
					
						
							|  |  |  |     ERROR_LOG(AUDIO, "error uninitializing audiounit"); | 
					
						
							| 
									
										
										
										
											2010-05-31 05:05:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   err = AudioComponentInstanceDispose(audioUnit); | 
					
						
							|  |  |  |   if (err != noErr) | 
					
						
							|  |  |  |     ERROR_LOG(AUDIO, "error closing audio component"); | 
					
						
							| 
									
										
										
										
											2009-09-24 21:35:06 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2010-05-30 04:21:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-24 21:35:06 +00:00
										 |  |  | void CoreAudioSound::Update() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-10-23 17:10:27 +00:00
										 |  |  | } |