Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00012
00013
00014
00015
00016
00017
00018 #ifdef WITH_COCOA
00019
00020 #include "../stdafx.h"
00021 #include "../debug.h"
00022 #include "../driver.h"
00023 #include "../mixer.h"
00024 #include "../core/endian_type.hpp"
00025 #include "cocoa_s.h"
00026
00027 #define Rect OTTDRect
00028 #define Point OTTDPoint
00029 #include <AudioUnit/AudioUnit.h>
00030 #undef Rect
00031 #undef Point
00032
00033 static FSoundDriver_Cocoa iFSoundDriver_Cocoa;
00034
00035 static AudioUnit _outputAudioUnit;
00036
00037
00038 static OSStatus audioCallback(void *inRefCon, AudioUnitRenderActionFlags *inActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList * ioData)
00039 {
00040 MxMixSamples(ioData->mBuffers[0].mData, ioData->mBuffers[0].mDataByteSize / 4);
00041
00042 return noErr;
00043 }
00044
00045
00046 const char *SoundDriver_Cocoa::Start(const char * const *parm)
00047 {
00048 Component comp;
00049 ComponentDescription desc;
00050 struct AURenderCallbackStruct callback;
00051 AudioStreamBasicDescription requestedDesc;
00052
00053
00054 requestedDesc.mFormatID = kAudioFormatLinearPCM;
00055 requestedDesc.mFormatFlags = kLinearPCMFormatFlagIsPacked;
00056 requestedDesc.mChannelsPerFrame = 2;
00057 requestedDesc.mSampleRate = GetDriverParamInt(parm, "hz", 44100);
00058
00059 requestedDesc.mBitsPerChannel = 16;
00060 requestedDesc.mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
00061
00062 #if TTD_ENDIAN == TTD_BIG_ENDIAN
00063 requestedDesc.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;
00064 #endif
00065
00066 requestedDesc.mFramesPerPacket = 1;
00067 requestedDesc.mBytesPerFrame = requestedDesc.mBitsPerChannel * requestedDesc.mChannelsPerFrame / 8;
00068 requestedDesc.mBytesPerPacket = requestedDesc.mBytesPerFrame * requestedDesc.mFramesPerPacket;
00069
00070 MxInitialize((uint)requestedDesc.mSampleRate);
00071
00072
00073 desc.componentType = kAudioUnitType_Output;
00074 desc.componentSubType = kAudioUnitSubType_HALOutput;
00075 desc.componentManufacturer = kAudioUnitManufacturer_Apple;
00076 desc.componentFlags = 0;
00077 desc.componentFlagsMask = 0;
00078
00079 comp = FindNextComponent (NULL, &desc);
00080 if (comp == NULL) {
00081 return "cocoa_s: Failed to start CoreAudio: FindNextComponent returned NULL";
00082 }
00083
00084
00085 if (OpenAComponent(comp, &_outputAudioUnit) != noErr) {
00086 return "cocoa_s: Failed to start CoreAudio: OpenAComponent";
00087 }
00088
00089 if (AudioUnitInitialize(_outputAudioUnit) != noErr) {
00090 return "cocoa_s: Failed to start CoreAudio: AudioUnitInitialize";
00091 }
00092
00093
00094 if (AudioUnitSetProperty(_outputAudioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &requestedDesc, sizeof(requestedDesc)) != noErr) {
00095 return "cocoa_s: Failed to start CoreAudio: AudioUnitSetProperty (kAudioUnitProperty_StreamFormat)";
00096 }
00097
00098
00099 callback.inputProc = audioCallback;
00100 callback.inputProcRefCon = NULL;
00101 if (AudioUnitSetProperty(_outputAudioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &callback, sizeof(callback)) != noErr) {
00102 return "cocoa_s: Failed to start CoreAudio: AudioUnitSetProperty (kAudioUnitProperty_SetRenderCallback)";
00103 }
00104
00105
00106 if (AudioOutputUnitStart(_outputAudioUnit) != noErr) {
00107 return "cocoa_s: Failed to start CoreAudio: AudioOutputUnitStart";
00108 }
00109
00110
00111 return NULL;
00112 }
00113
00114
00115 void SoundDriver_Cocoa::Stop()
00116 {
00117 struct AURenderCallbackStruct callback;
00118
00119
00120 if (AudioOutputUnitStop(_outputAudioUnit) != noErr) {
00121 DEBUG(driver, 0, "cocoa_s: Core_CloseAudio: AudioOutputUnitStop failed");
00122 return;
00123 }
00124
00125
00126 callback.inputProc = 0;
00127 callback.inputProcRefCon = 0;
00128 if (AudioUnitSetProperty(_outputAudioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &callback, sizeof(callback)) != noErr) {
00129 DEBUG(driver, 0, "cocoa_s: Core_CloseAudio: AudioUnitSetProperty (kAudioUnitProperty_SetRenderCallback) failed");
00130 return;
00131 }
00132
00133 if (CloseComponent(_outputAudioUnit) != noErr) {
00134 DEBUG(driver, 0, "cocoa_s: Core_CloseAudio: CloseComponent failed");
00135 return;
00136 }
00137 }
00138
00139 #endif