Add qemu 2.4.0
[kvmfornfv.git] / 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 "qemu-common.h"
30 #include "audio.h"
31
32 #define AUDIO_CAP "coreaudio"
33 #include "audio_int.h"
34
35 static int isAtexit;
36
37 typedef struct {
38     int buffer_frames;
39     int nbuffers;
40 } CoreaudioConf;
41
42 typedef struct coreaudioVoiceOut {
43     HWVoiceOut hw;
44     pthread_mutex_t mutex;
45     AudioDeviceID outputDeviceID;
46     UInt32 audioDevicePropertyBufferFrameSize;
47     AudioStreamBasicDescription outputStreamBasicDescription;
48     int live;
49     int decr;
50     int rpos;
51 } coreaudioVoiceOut;
52
53 static void coreaudio_logstatus (OSStatus status)
54 {
55     const char *str = "BUG";
56
57     switch(status) {
58     case kAudioHardwareNoError:
59         str = "kAudioHardwareNoError";
60         break;
61
62     case kAudioHardwareNotRunningError:
63         str = "kAudioHardwareNotRunningError";
64         break;
65
66     case kAudioHardwareUnspecifiedError:
67         str = "kAudioHardwareUnspecifiedError";
68         break;
69
70     case kAudioHardwareUnknownPropertyError:
71         str = "kAudioHardwareUnknownPropertyError";
72         break;
73
74     case kAudioHardwareBadPropertySizeError:
75         str = "kAudioHardwareBadPropertySizeError";
76         break;
77
78     case kAudioHardwareIllegalOperationError:
79         str = "kAudioHardwareIllegalOperationError";
80         break;
81
82     case kAudioHardwareBadDeviceError:
83         str = "kAudioHardwareBadDeviceError";
84         break;
85
86     case kAudioHardwareBadStreamError:
87         str = "kAudioHardwareBadStreamError";
88         break;
89
90     case kAudioHardwareUnsupportedOperationError:
91         str = "kAudioHardwareUnsupportedOperationError";
92         break;
93
94     case kAudioDeviceUnsupportedFormatError:
95         str = "kAudioDeviceUnsupportedFormatError";
96         break;
97
98     case kAudioDevicePermissionsError:
99         str = "kAudioDevicePermissionsError";
100         break;
101
102     default:
103         AUD_log (AUDIO_CAP, "Reason: status code %" PRId32 "\n", (int32_t)status);
104         return;
105     }
106
107     AUD_log (AUDIO_CAP, "Reason: %s\n", str);
108 }
109
110 static void GCC_FMT_ATTR (2, 3) coreaudio_logerr (
111     OSStatus status,
112     const char *fmt,
113     ...
114     )
115 {
116     va_list ap;
117
118     va_start (ap, fmt);
119     AUD_log (AUDIO_CAP, fmt, ap);
120     va_end (ap);
121
122     coreaudio_logstatus (status);
123 }
124
125 static void GCC_FMT_ATTR (3, 4) coreaudio_logerr2 (
126     OSStatus status,
127     const char *typ,
128     const char *fmt,
129     ...
130     )
131 {
132     va_list ap;
133
134     AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ);
135
136     va_start (ap, fmt);
137     AUD_vlog (AUDIO_CAP, fmt, ap);
138     va_end (ap);
139
140     coreaudio_logstatus (status);
141 }
142
143 static inline UInt32 isPlaying (AudioDeviceID outputDeviceID)
144 {
145     OSStatus status;
146     UInt32 result = 0;
147     UInt32 propertySize = sizeof(outputDeviceID);
148     status = AudioDeviceGetProperty(
149         outputDeviceID, 0, 0,
150         kAudioDevicePropertyDeviceIsRunning, &propertySize, &result);
151     if (status != kAudioHardwareNoError) {
152         coreaudio_logerr(status,
153                          "Could not determine whether Device is playing\n");
154     }
155     return result;
156 }
157
158 static void coreaudio_atexit (void)
159 {
160     isAtexit = 1;
161 }
162
163 static int coreaudio_lock (coreaudioVoiceOut *core, const char *fn_name)
164 {
165     int err;
166
167     err = pthread_mutex_lock (&core->mutex);
168     if (err) {
169         dolog ("Could not lock voice for %s\nReason: %s\n",
170                fn_name, strerror (err));
171         return -1;
172     }
173     return 0;
174 }
175
176 static int coreaudio_unlock (coreaudioVoiceOut *core, const char *fn_name)
177 {
178     int err;
179
180     err = pthread_mutex_unlock (&core->mutex);
181     if (err) {
182         dolog ("Could not unlock voice for %s\nReason: %s\n",
183                fn_name, strerror (err));
184         return -1;
185     }
186     return 0;
187 }
188
189 static int coreaudio_run_out (HWVoiceOut *hw, int live)
190 {
191     int decr;
192     coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
193
194     if (coreaudio_lock (core, "coreaudio_run_out")) {
195         return 0;
196     }
197
198     if (core->decr > live) {
199         ldebug ("core->decr %d live %d core->live %d\n",
200                 core->decr,
201                 live,
202                 core->live);
203     }
204
205     decr = audio_MIN (core->decr, live);
206     core->decr -= decr;
207
208     core->live = live - decr;
209     hw->rpos = core->rpos;
210
211     coreaudio_unlock (core, "coreaudio_run_out");
212     return decr;
213 }
214
215 /* callback to feed audiooutput buffer */
216 static OSStatus audioDeviceIOProc(
217     AudioDeviceID inDevice,
218     const AudioTimeStamp* inNow,
219     const AudioBufferList* inInputData,
220     const AudioTimeStamp* inInputTime,
221     AudioBufferList* outOutputData,
222     const AudioTimeStamp* inOutputTime,
223     void* hwptr)
224 {
225     UInt32 frame, frameCount;
226     float *out = outOutputData->mBuffers[0].mData;
227     HWVoiceOut *hw = hwptr;
228     coreaudioVoiceOut *core = (coreaudioVoiceOut *) hwptr;
229     int rpos, live;
230     struct st_sample *src;
231 #ifndef FLOAT_MIXENG
232 #ifdef RECIPROCAL
233     const float scale = 1.f / UINT_MAX;
234 #else
235     const float scale = UINT_MAX;
236 #endif
237 #endif
238
239     if (coreaudio_lock (core, "audioDeviceIOProc")) {
240         inInputTime = 0;
241         return 0;
242     }
243
244     frameCount = core->audioDevicePropertyBufferFrameSize;
245     live = core->live;
246
247     /* if there are not enough samples, set signal and return */
248     if (live < frameCount) {
249         inInputTime = 0;
250         coreaudio_unlock (core, "audioDeviceIOProc(empty)");
251         return 0;
252     }
253
254     rpos = core->rpos;
255     src = hw->mix_buf + rpos;
256
257     /* fill buffer */
258     for (frame = 0; frame < frameCount; frame++) {
259 #ifdef FLOAT_MIXENG
260         *out++ = src[frame].l; /* left channel */
261         *out++ = src[frame].r; /* right channel */
262 #else
263 #ifdef RECIPROCAL
264         *out++ = src[frame].l * scale; /* left channel */
265         *out++ = src[frame].r * scale; /* right channel */
266 #else
267         *out++ = src[frame].l / scale; /* left channel */
268         *out++ = src[frame].r / scale; /* right channel */
269 #endif
270 #endif
271     }
272
273     rpos = (rpos + frameCount) % hw->samples;
274     core->decr += frameCount;
275     core->rpos = rpos;
276
277     coreaudio_unlock (core, "audioDeviceIOProc");
278     return 0;
279 }
280
281 static int coreaudio_write (SWVoiceOut *sw, void *buf, int len)
282 {
283     return audio_pcm_sw_write (sw, buf, len);
284 }
285
286 static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
287                               void *drv_opaque)
288 {
289     OSStatus status;
290     coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
291     UInt32 propertySize;
292     int err;
293     const char *typ = "playback";
294     AudioValueRange frameRange;
295     CoreaudioConf *conf = drv_opaque;
296
297     /* create mutex */
298     err = pthread_mutex_init(&core->mutex, NULL);
299     if (err) {
300         dolog("Could not create mutex\nReason: %s\n", strerror (err));
301         return -1;
302     }
303
304     audio_pcm_init_info (&hw->info, as);
305
306     /* open default output device */
307     propertySize = sizeof(core->outputDeviceID);
308     status = AudioHardwareGetProperty(
309         kAudioHardwarePropertyDefaultOutputDevice,
310         &propertySize,
311         &core->outputDeviceID);
312     if (status != kAudioHardwareNoError) {
313         coreaudio_logerr2 (status, typ,
314                            "Could not get default output Device\n");
315         return -1;
316     }
317     if (core->outputDeviceID == kAudioDeviceUnknown) {
318         dolog ("Could not initialize %s - Unknown Audiodevice\n", typ);
319         return -1;
320     }
321
322     /* get minimum and maximum buffer frame sizes */
323     propertySize = sizeof(frameRange);
324     status = AudioDeviceGetProperty(
325         core->outputDeviceID,
326         0,
327         0,
328         kAudioDevicePropertyBufferFrameSizeRange,
329         &propertySize,
330         &frameRange);
331     if (status != kAudioHardwareNoError) {
332         coreaudio_logerr2 (status, typ,
333                            "Could not get device buffer frame range\n");
334         return -1;
335     }
336
337     if (frameRange.mMinimum > conf->buffer_frames) {
338         core->audioDevicePropertyBufferFrameSize = (UInt32) frameRange.mMinimum;
339         dolog ("warning: Upsizing Buffer Frames to %f\n", frameRange.mMinimum);
340     }
341     else if (frameRange.mMaximum < conf->buffer_frames) {
342         core->audioDevicePropertyBufferFrameSize = (UInt32) frameRange.mMaximum;
343         dolog ("warning: Downsizing Buffer Frames to %f\n", frameRange.mMaximum);
344     }
345     else {
346         core->audioDevicePropertyBufferFrameSize = conf->buffer_frames;
347     }
348
349     /* set Buffer Frame Size */
350     propertySize = sizeof(core->audioDevicePropertyBufferFrameSize);
351     status = AudioDeviceSetProperty(
352         core->outputDeviceID,
353         NULL,
354         0,
355         false,
356         kAudioDevicePropertyBufferFrameSize,
357         propertySize,
358         &core->audioDevicePropertyBufferFrameSize);
359     if (status != kAudioHardwareNoError) {
360         coreaudio_logerr2 (status, typ,
361                            "Could not set device buffer frame size %" PRIu32 "\n",
362                            (uint32_t)core->audioDevicePropertyBufferFrameSize);
363         return -1;
364     }
365
366     /* get Buffer Frame Size */
367     propertySize = sizeof(core->audioDevicePropertyBufferFrameSize);
368     status = AudioDeviceGetProperty(
369         core->outputDeviceID,
370         0,
371         false,
372         kAudioDevicePropertyBufferFrameSize,
373         &propertySize,
374         &core->audioDevicePropertyBufferFrameSize);
375     if (status != kAudioHardwareNoError) {
376         coreaudio_logerr2 (status, typ,
377                            "Could not get device buffer frame size\n");
378         return -1;
379     }
380     hw->samples = conf->nbuffers * core->audioDevicePropertyBufferFrameSize;
381
382     /* get StreamFormat */
383     propertySize = sizeof(core->outputStreamBasicDescription);
384     status = AudioDeviceGetProperty(
385         core->outputDeviceID,
386         0,
387         false,
388         kAudioDevicePropertyStreamFormat,
389         &propertySize,
390         &core->outputStreamBasicDescription);
391     if (status != kAudioHardwareNoError) {
392         coreaudio_logerr2 (status, typ,
393                            "Could not get Device Stream properties\n");
394         core->outputDeviceID = kAudioDeviceUnknown;
395         return -1;
396     }
397
398     /* set Samplerate */
399     core->outputStreamBasicDescription.mSampleRate = (Float64) as->freq;
400     propertySize = sizeof(core->outputStreamBasicDescription);
401     status = AudioDeviceSetProperty(
402         core->outputDeviceID,
403         0,
404         0,
405         0,
406         kAudioDevicePropertyStreamFormat,
407         propertySize,
408         &core->outputStreamBasicDescription);
409     if (status != kAudioHardwareNoError) {
410         coreaudio_logerr2 (status, typ, "Could not set samplerate %d\n",
411                            as->freq);
412         core->outputDeviceID = kAudioDeviceUnknown;
413         return -1;
414     }
415
416     /* set Callback */
417     status = AudioDeviceAddIOProc(core->outputDeviceID, audioDeviceIOProc, hw);
418     if (status != kAudioHardwareNoError) {
419         coreaudio_logerr2 (status, typ, "Could not set IOProc\n");
420         core->outputDeviceID = kAudioDeviceUnknown;
421         return -1;
422     }
423
424     /* start Playback */
425     if (!isPlaying(core->outputDeviceID)) {
426         status = AudioDeviceStart(core->outputDeviceID, audioDeviceIOProc);
427         if (status != kAudioHardwareNoError) {
428             coreaudio_logerr2 (status, typ, "Could not start playback\n");
429             AudioDeviceRemoveIOProc(core->outputDeviceID, audioDeviceIOProc);
430             core->outputDeviceID = kAudioDeviceUnknown;
431             return -1;
432         }
433     }
434
435     return 0;
436 }
437
438 static void coreaudio_fini_out (HWVoiceOut *hw)
439 {
440     OSStatus status;
441     int err;
442     coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
443
444     if (!isAtexit) {
445         /* stop playback */
446         if (isPlaying(core->outputDeviceID)) {
447             status = AudioDeviceStop(core->outputDeviceID, audioDeviceIOProc);
448             if (status != kAudioHardwareNoError) {
449                 coreaudio_logerr (status, "Could not stop playback\n");
450             }
451         }
452
453         /* remove callback */
454         status = AudioDeviceRemoveIOProc(core->outputDeviceID,
455                                          audioDeviceIOProc);
456         if (status != kAudioHardwareNoError) {
457             coreaudio_logerr (status, "Could not remove IOProc\n");
458         }
459     }
460     core->outputDeviceID = kAudioDeviceUnknown;
461
462     /* destroy mutex */
463     err = pthread_mutex_destroy(&core->mutex);
464     if (err) {
465         dolog("Could not destroy mutex\nReason: %s\n", strerror (err));
466     }
467 }
468
469 static int coreaudio_ctl_out (HWVoiceOut *hw, int cmd, ...)
470 {
471     OSStatus status;
472     coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
473
474     switch (cmd) {
475     case VOICE_ENABLE:
476         /* start playback */
477         if (!isPlaying(core->outputDeviceID)) {
478             status = AudioDeviceStart(core->outputDeviceID, audioDeviceIOProc);
479             if (status != kAudioHardwareNoError) {
480                 coreaudio_logerr (status, "Could not resume playback\n");
481             }
482         }
483         break;
484
485     case VOICE_DISABLE:
486         /* stop playback */
487         if (!isAtexit) {
488             if (isPlaying(core->outputDeviceID)) {
489                 status = AudioDeviceStop(core->outputDeviceID, audioDeviceIOProc);
490                 if (status != kAudioHardwareNoError) {
491                     coreaudio_logerr (status, "Could not pause playback\n");
492                 }
493             }
494         }
495         break;
496     }
497     return 0;
498 }
499
500 static CoreaudioConf glob_conf = {
501     .buffer_frames = 512,
502     .nbuffers = 4,
503 };
504
505 static void *coreaudio_audio_init (void)
506 {
507     CoreaudioConf *conf = g_malloc(sizeof(CoreaudioConf));
508     *conf = glob_conf;
509
510     atexit(coreaudio_atexit);
511     return conf;
512 }
513
514 static void coreaudio_audio_fini (void *opaque)
515 {
516     g_free(opaque);
517 }
518
519 static struct audio_option coreaudio_options[] = {
520     {
521         .name  = "BUFFER_SIZE",
522         .tag   = AUD_OPT_INT,
523         .valp  = &glob_conf.buffer_frames,
524         .descr = "Size of the buffer in frames"
525     },
526     {
527         .name  = "BUFFER_COUNT",
528         .tag   = AUD_OPT_INT,
529         .valp  = &glob_conf.nbuffers,
530         .descr = "Number of buffers"
531     },
532     { /* End of list */ }
533 };
534
535 static struct audio_pcm_ops coreaudio_pcm_ops = {
536     .init_out = coreaudio_init_out,
537     .fini_out = coreaudio_fini_out,
538     .run_out  = coreaudio_run_out,
539     .write    = coreaudio_write,
540     .ctl_out  = coreaudio_ctl_out
541 };
542
543 struct audio_driver coreaudio_audio_driver = {
544     .name           = "coreaudio",
545     .descr          = "CoreAudio http://developer.apple.com/audio/coreaudio.html",
546     .options        = coreaudio_options,
547     .init           = coreaudio_audio_init,
548     .fini           = coreaudio_audio_fini,
549     .pcm_ops        = &coreaudio_pcm_ops,
550     .can_be_default = 1,
551     .max_voices_out = 1,
552     .max_voices_in  = 0,
553     .voice_size_out = sizeof (coreaudioVoiceOut),
554     .voice_size_in  = 0
555 };