merged 15a_aqemu.patch audio patch (malc)
[qemu] / audio / coreaudio.c
1 /*
2  * QEMU OS X CoreAudio audio driver
3  *
4  * Copyright (c) 2005 Mike Kronenberg
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24
25 #include <CoreAudio/CoreAudio.h>
26 #include <string.h>             /* strerror */
27 #include <pthread.h>            /* pthread_X */
28
29 #include "vl.h"
30
31 #define AUDIO_CAP "coreaudio"
32 #include "audio_int.h"
33
34 #define DEVICE_BUFFER_FRAMES  (512)
35
36 struct {
37     int buffer_frames;
38 } conf = {
39     .buffer_frames = 512
40 };
41
42 typedef struct coreaudioVoiceOut {
43     HWVoiceOut hw;
44     pthread_mutex_t mutex;
45     AudioDeviceID outputDeviceID;
46     UInt32 audioDevicePropertyBufferSize;
47     AudioStreamBasicDescription outputStreamBasicDescription;
48     int isPlaying;
49     int live;
50     int decr;
51     int rpos;
52 } coreaudioVoiceOut;
53
54 static void coreaudio_logstatus (OSStatus status)
55 {
56     char *str = "BUG";
57
58     switch(status) {
59     case kAudioHardwareNoError:
60         str = "kAudioHardwareNoError";
61         break;
62
63     case kAudioHardwareNotRunningError:
64         str = "kAudioHardwareNotRunningError";
65         break;
66
67     case kAudioHardwareUnspecifiedError:
68         str = "kAudioHardwareUnspecifiedError";
69         break;
70
71     case kAudioHardwareUnknownPropertyError:
72         str = "kAudioHardwareUnknownPropertyError";
73         break;
74
75     case kAudioHardwareBadPropertySizeError:
76         str = "kAudioHardwareBadPropertySizeError";
77         break;
78
79     case kAudioHardwareIllegalOperationError:
80         str = "kAudioHardwareIllegalOperationError";
81         break;
82
83     case kAudioHardwareBadDeviceError:
84         str = "kAudioHardwareBadDeviceError";
85         break;
86
87     case kAudioHardwareBadStreamError:
88         str = "kAudioHardwareBadStreamError";
89         break;
90
91     case kAudioHardwareUnsupportedOperationError:
92         str = "kAudioHardwareUnsupportedOperationError";
93         break;
94
95     case kAudioDeviceUnsupportedFormatError:
96         str = "kAudioDeviceUnsupportedFormatError";
97         break;
98
99     case kAudioDevicePermissionsError:
100         str = "kAudioDevicePermissionsError";
101         break;
102
103     default:
104         AUD_log (AUDIO_CAP, "Reason: status code %ld\n", status);
105         return;
106     }
107
108     AUD_log (AUDIO_CAP, "Reason: %s\n", str);
109 }
110
111 static void GCC_FMT_ATTR (2, 3) coreaudio_logerr (
112     OSStatus status,
113     const char *fmt,
114     ...
115     )
116 {
117     va_list ap;
118
119     va_start (ap, fmt);
120     AUD_log (AUDIO_CAP, fmt, ap);
121     va_end (ap);
122
123     coreaudio_logstatus (status);
124 }
125
126 static void GCC_FMT_ATTR (3, 4) coreaudio_logerr2 (
127     OSStatus status,
128     const char *typ,
129     const char *fmt,
130     ...
131     )
132 {
133     va_list ap;
134
135     AUD_log (AUDIO_CAP, "Can not initialize %s\n", typ);
136
137     va_start (ap, fmt);
138     AUD_vlog (AUDIO_CAP, fmt, ap);
139     va_end (ap);
140
141     coreaudio_logstatus (status);
142 }
143
144 static int coreaudio_lock (coreaudioVoiceOut *core, const char *fn_name)
145 {
146     int err;
147
148     err = pthread_mutex_lock (&core->mutex);
149     if (err) {
150         dolog ("Can not lock voice for %s\nReason: %s\n",
151                fn_name, strerror (err));
152         return -1;
153     }
154     return 0;
155 }
156
157 static int coreaudio_unlock (coreaudioVoiceOut *core, const char *fn_name)
158 {
159     int err;
160
161     err = pthread_mutex_unlock (&core->mutex);
162     if (err) {
163         dolog ("Can not unlock voice for %s\nReason: %s\n",
164                fn_name, strerror (err));
165         return -1;
166     }
167     return 0;
168 }
169
170 static int coreaudio_run_out (HWVoiceOut *hw)
171 {
172     int live, decr;
173     coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
174
175     if (coreaudio_lock (core, "coreaudio_run_out")) {
176         return 0;
177     }
178
179     live = audio_pcm_hw_get_live_out (hw);
180
181     if (core->decr > live) {
182         ldebug ("core->decr %d live %d core->live %d\n",
183                 core->decr,
184                 live,
185                 core->live);
186     }
187
188     decr = audio_MIN (core->decr, live);
189     core->decr -= decr;
190
191     core->live = live - decr;
192     hw->rpos = core->rpos;
193
194     coreaudio_unlock (core, "coreaudio_run_out");
195     return decr;
196 }
197
198 /* callback to feed audiooutput buffer */
199 static OSStatus audioDeviceIOProc(
200     AudioDeviceID inDevice,
201     const AudioTimeStamp* inNow,
202     const AudioBufferList* inInputData,
203     const AudioTimeStamp* inInputTime,
204     AudioBufferList* outOutputData,
205     const AudioTimeStamp* inOutputTime,
206     void* hwptr)
207 {
208     unsigned int frame, frameCount;
209     float *out = outOutputData->mBuffers[0].mData;
210     HWVoiceOut *hw = hwptr;
211     coreaudioVoiceOut *core = (coreaudioVoiceOut *) hwptr;
212     int rpos, live;
213     st_sample_t *src;
214 #ifndef FLOAT_MIXENG
215 #ifdef RECIPROCAL
216     const float scale = 1.f / UINT_MAX;
217 #else
218     const float scale = UINT_MAX;
219 #endif
220 #endif
221
222     if (coreaudio_lock (core, "audioDeviceIOProc")) {
223         inInputTime = 0;
224         return 0;
225     }
226
227     frameCount = conf.buffer_frames;
228     live = core->live;
229
230     /* if there are not enough samples, set signal and return */
231     if (live < frameCount) {
232         inInputTime = 0;
233         coreaudio_unlock (core, "audioDeviceIOProc(empty)");
234         return 0;
235     }
236
237     rpos = core->rpos;
238     src = hw->mix_buf + rpos;
239
240     /* fill buffer */
241     for (frame = 0; frame < frameCount; frame++) {
242 #ifdef FLOAT_MIXENG
243         *out++ = src[frame].l; /* left channel */
244         *out++ = src[frame].r; /* right channel */
245 #else
246 #ifdef RECIPROCAL
247         *out++ = src[frame].l * scale; /* left channel */
248         *out++ = src[frame].r * scale; /* right channel */
249 #else
250         *out++ = src[frame].l / scale; /* left channel */
251         *out++ = src[frame].r / scale; /* right channel */
252 #endif
253 #endif
254     }
255
256     /* cleanup */
257     mixeng_clear (src, frameCount);
258     rpos = (rpos + frameCount) % hw->samples;
259     core->decr = frameCount;
260     core->rpos = rpos;
261
262     coreaudio_unlock (core, "audioDeviceIOProc");
263     return 0;
264 }
265
266 static int coreaudio_write (SWVoiceOut *sw, void *buf, int len)
267 {
268     return audio_pcm_sw_write (sw, buf, len);
269 }
270
271 static int coreaudio_init_out (HWVoiceOut *hw, int freq,
272                                int nchannels, audfmt_e fmt)
273 {
274     OSStatus status;
275     coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
276     UInt32 propertySize;
277     int err;
278     int bits = 8;
279     int endianess = 0;
280     const char *typ = "DAC";
281
282     /* create mutex */
283     err = pthread_mutex_init(&core->mutex, NULL);
284     if (err) {
285         dolog("Can not create mutex\nReason: %s\n", strerror (err));
286         return -1;
287     }
288
289     if (fmt == AUD_FMT_S16 || fmt == AUD_FMT_U16) {
290         bits = 16;
291         endianess = 1;
292     }
293
294     audio_pcm_init_info (
295         &hw->info,
296         freq,
297         nchannels,
298         fmt,
299         /* Following is irrelevant actually since we do not use
300            mixengs clipping routines */
301         audio_need_to_swap_endian (endianess)
302         );
303     hw->bufsize = 4 * conf.buffer_frames * nchannels * bits;
304
305     /* open default output device */
306     propertySize = sizeof(core->outputDeviceID);
307     status = AudioHardwareGetProperty(
308         kAudioHardwarePropertyDefaultOutputDevice,
309         &propertySize,
310         &core->outputDeviceID);
311     if (status != kAudioHardwareNoError) {
312         coreaudio_logerr2 (status, typ,
313                            "Can not get default output Device\n");
314         return -1;
315     }
316     if (core->outputDeviceID == kAudioDeviceUnknown) {
317         dolog ("Can not initialize %s - Unknown Audiodevice\n", typ);
318         return -1;
319     }
320
321     /* set Buffersize to conf.buffer_frames frames */
322     propertySize = sizeof(core->audioDevicePropertyBufferSize);
323     core->audioDevicePropertyBufferSize =
324         conf.buffer_frames * sizeof(float) * 2;
325     status = AudioDeviceSetProperty(
326         core->outputDeviceID,
327         NULL,
328         0,
329         false,
330         kAudioDevicePropertyBufferSize,
331         propertySize,
332         &core->audioDevicePropertyBufferSize);
333     if (status != kAudioHardwareNoError) {
334         coreaudio_logerr2 (status, typ,
335                            "Can not set device buffer size %d\n",
336                            kAudioDevicePropertyBufferSize);
337         return -1;
338     }
339
340     /* get Buffersize */
341     propertySize = sizeof(core->audioDevicePropertyBufferSize);
342     status = AudioDeviceGetProperty(
343         core->outputDeviceID,
344         0,
345         false,
346         kAudioDevicePropertyBufferSize,
347         &propertySize,
348         &core->audioDevicePropertyBufferSize);
349     if (status != kAudioHardwareNoError) {
350         coreaudio_logerr2 (status, typ, "Can not get device buffer size\n");
351         return -1;
352     }
353
354     /* get StreamFormat */
355     propertySize = sizeof(core->outputStreamBasicDescription);
356     status = AudioDeviceGetProperty(
357         core->outputDeviceID,
358         0,
359         false,
360         kAudioDevicePropertyStreamFormat,
361         &propertySize,
362         &core->outputStreamBasicDescription);
363     if (status != kAudioHardwareNoError) {
364         coreaudio_logerr2 (status, typ,
365                            "Can not get Device Stream properties\n");
366         core->outputDeviceID = kAudioDeviceUnknown;
367         return -1;
368     }
369
370     /* set Samplerate */
371     core->outputStreamBasicDescription.mSampleRate = (Float64)freq;
372     propertySize = sizeof(core->outputStreamBasicDescription);
373     status = AudioDeviceSetProperty(
374         core->outputDeviceID,
375         0,
376         0,
377         0,
378         kAudioDevicePropertyStreamFormat,
379         propertySize,
380         &core->outputStreamBasicDescription);
381     if (status != kAudioHardwareNoError) {
382         coreaudio_logerr2 (status, typ, "Can not set samplerate %d\n", freq);
383         core->outputDeviceID = kAudioDeviceUnknown;
384         return -1;
385     }
386
387     /* set Callback */
388     status = AudioDeviceAddIOProc(core->outputDeviceID, audioDeviceIOProc, hw);
389     if (status != kAudioHardwareNoError) {
390         coreaudio_logerr2 (status, typ, "Can not set IOProc\n");
391         core->outputDeviceID = kAudioDeviceUnknown;
392         return -1;
393     }
394
395     /* start Playback */
396     if (!core->isPlaying) {
397         status = AudioDeviceStart(core->outputDeviceID, audioDeviceIOProc);
398         if (status != kAudioHardwareNoError) {
399             coreaudio_logerr2 (status, typ, "Can not start playback\n");
400             AudioDeviceRemoveIOProc(core->outputDeviceID, audioDeviceIOProc);
401             core->outputDeviceID = kAudioDeviceUnknown;
402             return -1;
403         }
404         core->isPlaying = 1;
405     }
406
407     return 0;
408 }
409
410 static void coreaudio_fini_out (HWVoiceOut *hw)
411 {
412     OSStatus status;
413     int err;
414     coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
415
416     /* stop playback */
417     if (core->isPlaying) {
418         status = AudioDeviceStop(core->outputDeviceID, audioDeviceIOProc);
419         if (status != kAudioHardwareNoError) {
420             coreaudio_logerr (status, "Can not stop playback\n");
421         }
422         core->isPlaying = 0;
423     }
424
425     /* remove callback */
426     status = AudioDeviceRemoveIOProc(core->outputDeviceID, audioDeviceIOProc);
427     if (status != kAudioHardwareNoError) {
428         coreaudio_logerr (status, "Can not remove IOProc\n");
429     }
430     core->outputDeviceID = kAudioDeviceUnknown;
431
432     /* destroy mutex */
433     err = pthread_mutex_destroy(&core->mutex);
434     if (err) {
435         dolog("Can not destroy mutex\nReason: %s\n", strerror (err));
436     }
437 }
438
439 static int coreaudio_ctl_out (HWVoiceOut *hw, int cmd, ...)
440 {
441     OSStatus status;
442     coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
443
444     switch (cmd) {
445     case VOICE_ENABLE:
446         /* start playback */
447         if (!core->isPlaying) {
448             status = AudioDeviceStart(core->outputDeviceID, audioDeviceIOProc);
449             if (status != kAudioHardwareNoError) {
450                 coreaudio_logerr (status, "Can not unpause playback\n");
451             }
452             core->isPlaying = 1;
453         }
454         break;
455
456     case VOICE_DISABLE:
457         /* stop playback */
458         if (core->isPlaying) {
459             status = AudioDeviceStop(core->outputDeviceID, audioDeviceIOProc);
460             if (status != kAudioHardwareNoError) {
461                 coreaudio_logerr (status, "Can not pause playback\n");
462             }
463             core->isPlaying = 0;
464         }
465         break;
466     }
467     return 0;
468 }
469
470 static void *coreaudio_audio_init (void)
471 {
472     return &coreaudio_audio_init;
473 }
474
475 static void coreaudio_audio_fini (void *opaque)
476 {
477     (void) opaque;
478 }
479
480 static struct audio_option coreaudio_options[] = {
481     {"BUFFER_SIZE", AUD_OPT_INT, &conf.buffer_frames,
482      "Size of the buffer in frames", NULL, 0},
483     {NULL, 0, NULL, NULL, NULL, 0}
484 };
485
486 static struct audio_pcm_ops coreaudio_pcm_ops = {
487     coreaudio_init_out,
488     coreaudio_fini_out,
489     coreaudio_run_out,
490     coreaudio_write,
491     coreaudio_ctl_out,
492
493     NULL,
494     NULL,
495     NULL,
496     NULL,
497     NULL
498 };
499
500 struct audio_driver coreaudio_audio_driver = {
501     INIT_FIELD (name           = ) "coreaudio",
502     INIT_FIELD (descr          = )
503     "CoreAudio http://developer.apple.com/audio/coreaudio.html",
504     INIT_FIELD (options        = ) coreaudio_options,
505     INIT_FIELD (init           = ) coreaudio_audio_init,
506     INIT_FIELD (fini           = ) coreaudio_audio_fini,
507     INIT_FIELD (pcm_ops        = ) &coreaudio_pcm_ops,
508     INIT_FIELD (can_be_default = ) 1,
509     INIT_FIELD (max_voices_out = ) 1,
510     INIT_FIELD (max_voices_in  = ) 0,
511     INIT_FIELD (voice_size_out = ) sizeof (coreaudioVoiceOut),
512     INIT_FIELD (voice_size_in  = ) 0
513 };