sound/cocoa_s.c
changeset 2736 3d6487cbbb69
child 2743 a6c91eb763e8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sound/cocoa_s.c	Sat Dec 10 11:16:45 2005 +0000
@@ -0,0 +1,144 @@
+/******************************************************************************************
+ *                             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 */