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