OpenTTD-patches/sound/cocoa_s.c
bjarni 6a6e145010 (svn r3281) -Feature: [OSX] added native cocoa sound and video drivers (egladil)
you can still use SDL drivers if you like and you have to run "make upgradeconf" to start using the cocoa drivers (or manually write WITH_COCOA:=1)
	since SDL breaks the cocoa drivers, you can't compile with both SDL and cocoa support
	Using cocoa drivers makes it easier to make universal binaries and it solves:
	-FS#18 [OSX] SDL is weird in universal binaries
	-FS#2  [OSX] lazy pointer crash on exit
	-FS#10 [OSX] linking error when linking statically to SDL 1.2.8 (needless to explain this, but it means it should be able to compile statically with the default settings now)
	-[ 1215073 ] Switching to large size out of fullscreen crashes
	Using SDL drivers will still have those issues though
2005-12-10 11:16:45 +00:00

145 lines
4.6 KiB
C

/******************************************************************************************
* Cocoa sound driver *
* Known things left to do: *
* - Might need to do endian checking for it to work on both ppc and x86 *
******************************************************************************************/
#ifdef WITH_COCOA
#include <AudioUnit/AudioUnit.h>
/* Name conflict */
#define Rect OTTDRect
#define Point OTTDPoint
#define WindowClass OTTDWindowClass
/* Defined in stdbool.h */
#ifndef __cplusplus
# ifndef __BEOS__
# undef bool
# undef false
# undef true
# endif
#endif
#include "../stdafx.h"
#include "../openttd.h"
#include "../debug.h"
#include "../driver.h"
#include "../mixer.h"
#include "../sdl.h"
#include "cocoa_s.h"
#undef WindowClass
#undef Point
#undef Rect
static AudioUnit _outputAudioUnit;
/* The CoreAudio callback */
static OSStatus audioCallback (void *inRefCon, AudioUnitRenderActionFlags inActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, AudioBuffer *ioData)
{
MxMixSamples(_mixer, ioData->mData, ioData->mDataByteSize / 4);
return noErr;
}
static const char *CocoaSoundStart(const char * const *parm)
{
Component comp;
ComponentDescription desc;
struct AudioUnitInputCallback callback;
AudioStreamBasicDescription requestedDesc;
DEBUG(driver, 1)("cocoa_s: CocoaSoundStart");
/* Setup a AudioStreamBasicDescription with the requested format */
requestedDesc.mFormatID = kAudioFormatLinearPCM;
requestedDesc.mFormatFlags = kLinearPCMFormatFlagIsPacked;
requestedDesc.mChannelsPerFrame = 2;
requestedDesc.mSampleRate = GetDriverParamInt(parm, "hz", 11025);
requestedDesc.mBitsPerChannel = 16;
requestedDesc.mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
#if 1 // Big endian?
requestedDesc.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;
#endif
requestedDesc.mFramesPerPacket = 1;
requestedDesc.mBytesPerFrame = requestedDesc.mBitsPerChannel * requestedDesc.mChannelsPerFrame / 8;
requestedDesc.mBytesPerPacket = requestedDesc.mBytesPerFrame * requestedDesc.mFramesPerPacket;
/* Locate the default output audio unit */
desc.componentType = kAudioUnitComponentType;
desc.componentSubType = kAudioUnitSubType_Output;
desc.componentManufacturer = kAudioUnitID_DefaultOutput;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
comp = FindNextComponent (NULL, &desc);
if (comp == NULL)
return "cocoa_s: Failed to start CoreAudio: FindNextComponent returned NULL";
/* Open & initialize the default output audio unit */
if(OpenAComponent(comp, &_outputAudioUnit) != noErr)
return "cocoa_s: Failed to start CoreAudio: OpenAComponent";
if(AudioUnitInitialize(_outputAudioUnit) != noErr)
return "cocoa_s: Failed to start CoreAudio: AudioUnitInitialize";
/* Set the input format of the audio unit. */
if(AudioUnitSetProperty(_outputAudioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &requestedDesc, sizeof (requestedDesc)) != noErr)
return "cocoa_s: Failed to start CoreAudio: AudioUnitSetProperty (kAudioUnitProperty_StreamFormat)";
/* Set the audio callback */
callback.inputProc = audioCallback;
callback.inputProcRefCon = NULL;
if(AudioUnitSetProperty(_outputAudioUnit, kAudioUnitProperty_SetInputCallback, kAudioUnitScope_Input, 0, &callback, sizeof(callback)) != noErr)
return "cocoa_s: Failed to start CoreAudio: AudioUnitSetProperty (kAudioUnitProperty_SetInputCallback)";
/* Finally, start processing of the audio unit */
if(AudioOutputUnitStart (_outputAudioUnit) != noErr)
return "cocoa_s: Failed to start CoreAudio: AudioOutputUnitStart";
/* We're running! */
return NULL;
}
static void CocoaSoundStop(void)
{
struct AudioUnitInputCallback callback;
DEBUG(driver, 1)("cocoa_s: CocoaSoundStop");
/* stop processing the audio unit */
if(AudioOutputUnitStop(_outputAudioUnit) != noErr) {
DEBUG(driver, 1)("cocoa_s: Core_CloseAudio: AudioOutputUnitStop failed");
return;
}
/* Remove the input callback */
callback.inputProc = 0;
callback.inputProcRefCon = 0;
if(AudioUnitSetProperty(_outputAudioUnit, kAudioUnitProperty_SetInputCallback, kAudioUnitScope_Input, 0, &callback, sizeof(callback)) != noErr) {
DEBUG(driver, 1)("cocoa_s: Core_CloseAudio: AudioUnitSetProperty (kAudioUnitProperty_SetInputCallback) failed");
return;
}
if (CloseComponent(_outputAudioUnit) != noErr) {
DEBUG(driver, 1)("cocoa_s: Core_CloseAudio: CloseComponent failed");
return;
}
}
const HalSoundDriver _cocoa_sound_driver = {
CocoaSoundStart,
CocoaSoundStop,
};
#endif /* WITH_COCOA */