po: Update the English (neutral / Great Britain) translation.
[wine/multimedia.git] / dlls / winecoreaudio.drv / audiounit.c
blob6968719ff3035fe1c6e4504b1f6ca1e1ad84309a
1 /*
2 * Wine Driver for CoreAudio / AudioUnit
4 * Copyright 2005, 2006 Emmanuel Maillard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "config.h"
23 #define ULONG CoreFoundation_ULONG
24 #define HRESULT CoreFoundation_HRESULT
25 #ifndef HAVE_AUDIOUNIT_AUDIOCOMPONENT_H
26 #include <CoreServices/CoreServices.h>
27 #endif
28 #include <AudioUnit/AudioUnit.h>
29 #include <AudioToolbox/AudioToolbox.h>
30 #undef ULONG
31 #undef HRESULT
33 #undef DPRINTF
34 #undef STDMETHODCALLTYPE
35 #include "coreaudio.h"
36 #include "wine/debug.h"
38 #ifndef HAVE_AUDIOUNIT_AUDIOCOMPONENT_H
39 /* Define new AudioComponent Manager functions for compatibility's sake */
40 typedef Component AudioComponent;
41 typedef ComponentDescription AudioComponentDescription;
42 typedef ComponentInstance AudioComponentInstance;
44 static inline AudioComponent AudioComponentFindNext(AudioComponent ac, AudioComponentDescription *desc)
46 return FindNextComponent(ac, desc);
49 static inline OSStatus AudioComponentInstanceNew(AudioComponent ac, AudioComponentInstance *aci)
51 return OpenAComponent(ac, aci);
54 static inline OSStatus AudioComponentInstanceDispose(AudioComponentInstance aci)
56 return CloseComponent(aci);
58 #endif
60 #ifndef HAVE_AUGRAPHADDNODE
61 static inline OSStatus AUGraphAddNode(AUGraph graph, const AudioComponentDescription *desc, AUNode *node)
63 return AUGraphNewNode(graph, desc, 0, NULL, node);
66 static inline OSStatus AUGraphNodeInfo(AUGraph graph, AUNode node, AudioComponentDescription *desc, AudioUnit *au)
68 return AUGraphGetNodeInfo(graph, node, desc, 0, NULL, au);
70 #endif
72 WINE_DEFAULT_DEBUG_CHANNEL(wave);
73 WINE_DECLARE_DEBUG_CHANNEL(midi);
75 static const char *streamDescription(const AudioStreamBasicDescription* stream)
77 return wine_dbg_sprintf("\n mSampleRate : %f\n mFormatID : %s\n mFormatFlags : %lX\n mBytesPerPacket : %lu\n mFramesPerPacket : %lu\n mBytesPerFrame : %lu\n mChannelsPerFrame : %lu\n mBitsPerChannel : %lu\n",
78 stream->mSampleRate,
79 wine_dbgstr_fourcc(stream->mFormatID),
80 stream->mFormatFlags,
81 stream->mBytesPerPacket,
82 stream->mFramesPerPacket,
83 stream->mBytesPerFrame,
84 stream->mChannelsPerFrame,
85 stream->mBitsPerChannel);
88 int AudioUnit_CloseAudioUnit(AudioUnit au)
90 OSStatus err = AudioComponentInstanceDispose(au);
91 return (err == noErr);
94 int AudioUnit_InitializeWithStreamDescription(AudioUnit au, AudioStreamBasicDescription *stream)
96 OSStatus err = noErr;
98 TRACE("input format: %s\n", streamDescription(stream));
100 err = AudioUnitSetProperty(au, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input,
101 0, stream, sizeof(*stream));
103 if (err != noErr)
105 ERR("AudioUnitSetProperty return an error %s\n", wine_dbgstr_fourcc(err));
106 return 0;
109 err = AudioUnitInitialize(au);
110 if (err != noErr)
112 ERR("AudioUnitInitialize return an error %s\n", wine_dbgstr_fourcc(err));
113 return 0;
115 return 1;
118 int AudioUnit_SetVolume(AudioUnit au, float left, float right)
120 OSStatus err = noErr;
121 static int once;
123 if (!once++) FIXME("independent left/right volume not implemented (%f, %f)\n", left, right);
125 err = AudioUnitSetParameter(au, kHALOutputParam_Volume, kAudioUnitParameterFlag_Output, 0, left, 0);
127 if (err != noErr)
129 ERR("AudioUnitSetParameter return an error %s\n", wine_dbgstr_fourcc(err));
130 return 0;
132 return 1;
135 int AudioUnit_GetVolume(AudioUnit au, float *left, float *right)
137 OSStatus err = noErr;
138 static int once;
140 if (!once++) FIXME("independent left/right volume not implemented\n");
142 err = AudioUnitGetParameter(au, kHALOutputParam_Volume, kAudioUnitParameterFlag_Output, 0, left);
143 if (err != noErr)
145 ERR("AudioUnitGetParameter return an error %s\n", wine_dbgstr_fourcc(err));
146 return 0;
148 *right = *left;
149 return 1;
153 /* FIXME: implement sample rate conversion on input */
154 int AudioUnit_GetInputDeviceSampleRate(void)
156 AudioDeviceID defaultInputDevice;
157 UInt32 param;
158 AudioObjectPropertyAddress propertyAddress;
159 Float64 sampleRate;
160 OSStatus err;
162 param = sizeof(defaultInputDevice);
163 propertyAddress.mSelector = kAudioHardwarePropertyDefaultInputDevice;
164 propertyAddress.mScope = kAudioObjectPropertyScopeGlobal;
165 propertyAddress.mElement = kAudioObjectPropertyElementMaster;
166 err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &param, &defaultInputDevice);
167 if (err != noErr || defaultInputDevice == kAudioDeviceUnknown)
169 ERR("Couldn't get the default audio input device ID: %08lx\n", err);
170 return 0;
173 param = sizeof(sampleRate);
174 propertyAddress.mSelector = kAudioDevicePropertyNominalSampleRate;
175 propertyAddress.mScope = kAudioDevicePropertyScopeInput;
176 err = AudioObjectGetPropertyData(defaultInputDevice, &propertyAddress, 0, NULL, &param, &sampleRate);
177 if (err != noErr)
179 ERR("Couldn't get the device sample rate: %08lx\n", err);
180 return 0;
183 return sampleRate;
187 * MIDI Synth Unit
189 int SynthUnit_CreateDefaultSynthUnit(AUGraph *graph, AudioUnit *synth)
191 OSStatus err;
192 AudioComponentDescription desc;
193 AUNode synthNode;
194 AUNode outNode;
196 err = NewAUGraph(graph);
197 if (err != noErr)
199 ERR_(midi)("NewAUGraph return %s\n", wine_dbgstr_fourcc(err));
200 return 0;
203 desc.componentManufacturer = kAudioUnitManufacturer_Apple;
204 desc.componentFlags = 0;
205 desc.componentFlagsMask = 0;
207 /* create synth node */
208 desc.componentType = kAudioUnitType_MusicDevice;
209 desc.componentSubType = kAudioUnitSubType_DLSSynth;
211 err = AUGraphAddNode(*graph, &desc, &synthNode);
212 if (err != noErr)
214 ERR_(midi)("AUGraphAddNode cannot create synthNode : %s\n", wine_dbgstr_fourcc(err));
215 return 0;
218 /* create out node */
219 desc.componentType = kAudioUnitType_Output;
220 desc.componentSubType = kAudioUnitSubType_DefaultOutput;
222 err = AUGraphAddNode(*graph, &desc, &outNode);
223 if (err != noErr)
225 ERR_(midi)("AUGraphAddNode cannot create outNode %s\n", wine_dbgstr_fourcc(err));
226 return 0;
229 err = AUGraphOpen(*graph);
230 if (err != noErr)
232 ERR_(midi)("AUGraphOpen return %s\n", wine_dbgstr_fourcc(err));
233 return 0;
236 /* connecting the nodes */
237 err = AUGraphConnectNodeInput(*graph, synthNode, 0, outNode, 0);
238 if (err != noErr)
240 ERR_(midi)("AUGraphConnectNodeInput cannot connect synthNode to outNode : %s\n", wine_dbgstr_fourcc(err));
241 return 0;
244 /* Get the synth unit */
245 err = AUGraphNodeInfo(*graph, synthNode, 0, synth);
246 if (err != noErr)
248 ERR_(midi)("AUGraphNodeInfo return %s\n", wine_dbgstr_fourcc(err));
249 return 0;
252 return 1;
255 int SynthUnit_Initialize(AudioUnit synth, AUGraph graph)
257 OSStatus err = noErr;
259 err = AUGraphInitialize(graph);
260 if (err != noErr)
262 ERR_(midi)("AUGraphInitialize(%p) return %s\n", graph, wine_dbgstr_fourcc(err));
263 return 0;
266 err = AUGraphStart(graph);
267 if (err != noErr)
269 ERR_(midi)("AUGraphStart(%p) return %s\n", graph, wine_dbgstr_fourcc(err));
270 return 0;
273 return 1;
276 int SynthUnit_Close(AUGraph graph)
278 OSStatus err = noErr;
280 err = AUGraphStop(graph);
281 if (err != noErr)
283 ERR_(midi)("AUGraphStop(%p) return %s\n", graph, wine_dbgstr_fourcc(err));
284 return 0;
287 err = DisposeAUGraph(graph);
288 if (err != noErr)
290 ERR_(midi)("DisposeAUGraph(%p) return %s\n", graph, wine_dbgstr_fourcc(err));
291 return 0;
294 return 1;