Commit 5e941d4b51dd0888f4003e838c7e7499aa9e8a62

Authored by bellard
1 parent 50903530

workaround for atexit - buffer size API change


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1635 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 94 additions and 44 deletions
audio/coreaudio.c
... ... @@ -33,17 +33,19 @@
33 33  
34 34 struct {
35 35 int buffer_frames;
  36 + int isAtexit;
36 37 } conf = {
37   - .buffer_frames = 512
  38 + .buffer_frames = 512,
  39 + .isAtexit = 0
38 40 };
39 41  
40 42 typedef struct coreaudioVoiceOut {
41 43 HWVoiceOut hw;
42 44 pthread_mutex_t mutex;
  45 + int isAtexit;
43 46 AudioDeviceID outputDeviceID;
44   - UInt32 audioDevicePropertyBufferSize;
  47 + UInt32 audioDevicePropertyBufferFrameSize;
45 48 AudioStreamBasicDescription outputStreamBasicDescription;
46   - int isPlaying;
47 49 int live;
48 50 int decr;
49 51 int rpos;
... ... @@ -139,6 +141,26 @@ static void GCC_FMT_ATTR (3, 4) coreaudio_logerr2 (
139 141 coreaudio_logstatus (status);
140 142 }
141 143  
  144 +static inline UInt32 isPlaying (AudioDeviceID outputDeviceID)
  145 +{
  146 + OSStatus status;
  147 + UInt32 result = 0;
  148 + UInt32 propertySize = sizeof(outputDeviceID);
  149 + status = AudioDeviceGetProperty(
  150 + outputDeviceID, 0, 0,
  151 + kAudioDevicePropertyDeviceIsRunning, &propertySize, &result);
  152 + if (status != kAudioHardwareNoError) {
  153 + coreaudio_logerr(status,
  154 + "Could not determine whether Device is playing\n");
  155 + }
  156 + return result;
  157 +}
  158 +
  159 +static void coreaudio_atexit (void)
  160 +{
  161 + conf.isAtexit = 1;
  162 +}
  163 +
142 164 static int coreaudio_lock (coreaudioVoiceOut *core, const char *fn_name)
143 165 {
144 166 int err;
... ... @@ -203,7 +225,7 @@ static OSStatus audioDeviceIOProc(
203 225 const AudioTimeStamp* inOutputTime,
204 226 void* hwptr)
205 227 {
206   - unsigned int frame, frameCount;
  228 + UInt32 frame, frameCount;
207 229 float *out = outOutputData->mBuffers[0].mData;
208 230 HWVoiceOut *hw = hwptr;
209 231 coreaudioVoiceOut *core = (coreaudioVoiceOut *) hwptr;
... ... @@ -222,7 +244,7 @@ static OSStatus audioDeviceIOProc(
222 244 return 0;
223 245 }
224 246  
225   - frameCount = conf.buffer_frames;
  247 + frameCount = core->audioDevicePropertyBufferFrameSize;
226 248 live = core->live;
227 249  
228 250 /* if there are not enough samples, set signal and return */
... ... @@ -254,7 +276,7 @@ static OSStatus audioDeviceIOProc(
254 276 /* cleanup */
255 277 mixeng_clear (src, frameCount);
256 278 rpos = (rpos + frameCount) % hw->samples;
257   - core->decr = frameCount;
  279 + core->decr += frameCount;
258 280 core->rpos = rpos;
259 281  
260 282 coreaudio_unlock (core, "audioDeviceIOProc");
... ... @@ -274,7 +296,8 @@ static int coreaudio_init_out (HWVoiceOut *hw, audsettings_t *as)
274 296 int err;
275 297 int bits = 8;
276 298 int endianess = 0;
277   - const char *typ = "DAC";
  299 + const char *typ = "playback";
  300 + AudioValueRange frameRange;
278 301  
279 302 /* create mutex */
280 303 err = pthread_mutex_init(&core->mutex, NULL);
... ... @@ -312,40 +335,65 @@ static int coreaudio_init_out (HWVoiceOut *hw, audsettings_t *as)
312 335 return -1;
313 336 }
314 337  
315   - /* set Buffersize to conf.buffer_frames frames */
316   - propertySize = sizeof(core->audioDevicePropertyBufferSize);
317   - core->audioDevicePropertyBufferSize =
318   - conf.buffer_frames * sizeof(float) << (as->nchannels == 2);
  338 + /* get minimum and maximum buffer frame sizes */
  339 + propertySize = sizeof(frameRange);
  340 + status = AudioDeviceGetProperty(
  341 + core->outputDeviceID,
  342 + 0,
  343 + 0,
  344 + kAudioDevicePropertyBufferFrameSizeRange,
  345 + &propertySize,
  346 + &frameRange);
  347 + if (status != kAudioHardwareNoError) {
  348 + coreaudio_logerr2 (status, typ,
  349 + "Could not get device buffer frame range\n");
  350 + return -1;
  351 + }
  352 +
  353 + if (frameRange.mMinimum > conf.buffer_frames) {
  354 + core->audioDevicePropertyBufferFrameSize = (UInt32) frameRange.mMinimum;
  355 + dolog ("warning: Upsizing Buffer Frames to %f\n", frameRange.mMinimum);
  356 + }
  357 + else if (frameRange.mMaximum < conf.buffer_frames) {
  358 + core->audioDevicePropertyBufferFrameSize = (UInt32) frameRange.mMaximum;
  359 + dolog ("warning: Downsizing Buffer Frames to %f\n", frameRange.mMaximum);
  360 + }
  361 + else {
  362 + core->audioDevicePropertyBufferFrameSize = conf.buffer_frames;
  363 + }
  364 +
  365 + /* set Buffer Frame Size */
  366 + propertySize = sizeof(core->audioDevicePropertyBufferFrameSize);
319 367 status = AudioDeviceSetProperty(
320 368 core->outputDeviceID,
321 369 NULL,
322 370 0,
323 371 false,
324   - kAudioDevicePropertyBufferSize,
  372 + kAudioDevicePropertyBufferFrameSize,
325 373 propertySize,
326   - &core->audioDevicePropertyBufferSize);
  374 + &core->audioDevicePropertyBufferFrameSize);
327 375 if (status != kAudioHardwareNoError) {
328 376 coreaudio_logerr2 (status, typ,
329   - "Could not set device buffer size %d\n",
330   - kAudioDevicePropertyBufferSize);
  377 + "Could not set device buffer frame size %ld\n",
  378 + core->audioDevicePropertyBufferFrameSize);
331 379 return -1;
332 380 }
333 381  
334   - /* get Buffersize */
335   - propertySize = sizeof(core->audioDevicePropertyBufferSize);
  382 + /* get Buffer Frame Size */
  383 + propertySize = sizeof(core->audioDevicePropertyBufferFrameSize);
336 384 status = AudioDeviceGetProperty(
337 385 core->outputDeviceID,
338 386 0,
339 387 false,
340   - kAudioDevicePropertyBufferSize,
  388 + kAudioDevicePropertyBufferFrameSize,
341 389 &propertySize,
342   - &core->audioDevicePropertyBufferSize);
  390 + &core->audioDevicePropertyBufferFrameSize);
343 391 if (status != kAudioHardwareNoError) {
344   - coreaudio_logerr2 (status, typ, "Could not get device buffer size\n");
  392 + coreaudio_logerr2 (status, typ,
  393 + "Could not get device buffer frame size\n");
345 394 return -1;
346 395 }
347   - hw->samples = (core->audioDevicePropertyBufferSize / sizeof (float))
348   - >> (as->nchannels == 2);
  396 + hw->samples = 4 * core->audioDevicePropertyBufferFrameSize;
349 397  
350 398 /* get StreamFormat */
351 399 propertySize = sizeof(core->outputStreamBasicDescription);
... ... @@ -364,7 +412,7 @@ static int coreaudio_init_out (HWVoiceOut *hw, audsettings_t *as)
364 412 }
365 413  
366 414 /* set Samplerate */
367   - core->outputStreamBasicDescription.mSampleRate = (Float64)as->freq;
  415 + core->outputStreamBasicDescription.mSampleRate = (Float64) as->freq;
368 416 propertySize = sizeof(core->outputStreamBasicDescription);
369 417 status = AudioDeviceSetProperty(
370 418 core->outputDeviceID,
... ... @@ -390,7 +438,7 @@ static int coreaudio_init_out (HWVoiceOut *hw, audsettings_t *as)
390 438 }
391 439  
392 440 /* start Playback */
393   - if (!core->isPlaying) {
  441 + if (!isPlaying(core->outputDeviceID)) {
394 442 status = AudioDeviceStart(core->outputDeviceID, audioDeviceIOProc);
395 443 if (status != kAudioHardwareNoError) {
396 444 coreaudio_logerr2 (status, typ, "Could not start playback\n");
... ... @@ -398,7 +446,6 @@ static int coreaudio_init_out (HWVoiceOut *hw, audsettings_t *as)
398 446 core->outputDeviceID = kAudioDeviceUnknown;
399 447 return -1;
400 448 }
401   - core->isPlaying = 1;
402 449 }
403 450  
404 451 return 0;
... ... @@ -410,19 +457,21 @@ static void coreaudio_fini_out (HWVoiceOut *hw)
410 457 int err;
411 458 coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
412 459  
413   - /* stop playback */
414   - if (core->isPlaying) {
415   - status = AudioDeviceStop(core->outputDeviceID, audioDeviceIOProc);
416   - if (status != kAudioHardwareNoError) {
417   - coreaudio_logerr (status, "Could not stop playback\n");
  460 + if (!conf.isAtexit) {
  461 + /* stop playback */
  462 + if (isPlaying(core->outputDeviceID)) {
  463 + status = AudioDeviceStop(core->outputDeviceID, audioDeviceIOProc);
  464 + if (status != kAudioHardwareNoError) {
  465 + coreaudio_logerr (status, "Could not stop playback\n");
  466 + }
418 467 }
419   - core->isPlaying = 0;
420   - }
421 468  
422   - /* remove callback */
423   - status = AudioDeviceRemoveIOProc(core->outputDeviceID, audioDeviceIOProc);
424   - if (status != kAudioHardwareNoError) {
425   - coreaudio_logerr (status, "Could not remove IOProc\n");
  469 + /* remove callback */
  470 + status = AudioDeviceRemoveIOProc(core->outputDeviceID,
  471 + audioDeviceIOProc);
  472 + if (status != kAudioHardwareNoError) {
  473 + coreaudio_logerr (status, "Could not remove IOProc\n");
  474 + }
426 475 }
427 476 core->outputDeviceID = kAudioDeviceUnknown;
428 477  
... ... @@ -441,23 +490,23 @@ static int coreaudio_ctl_out (HWVoiceOut *hw, int cmd, ...)
441 490 switch (cmd) {
442 491 case VOICE_ENABLE:
443 492 /* start playback */
444   - if (!core->isPlaying) {
  493 + if (!isPlaying(core->outputDeviceID)) {
445 494 status = AudioDeviceStart(core->outputDeviceID, audioDeviceIOProc);
446 495 if (status != kAudioHardwareNoError) {
447   - coreaudio_logerr (status, "Could not unpause playback\n");
  496 + coreaudio_logerr (status, "Could not resume playback\n");
448 497 }
449   - core->isPlaying = 1;
450 498 }
451 499 break;
452 500  
453 501 case VOICE_DISABLE:
454 502 /* stop playback */
455   - if (core->isPlaying) {
456   - status = AudioDeviceStop(core->outputDeviceID, audioDeviceIOProc);
457   - if (status != kAudioHardwareNoError) {
458   - coreaudio_logerr (status, "Could not pause playback\n");
  503 + if (!conf.isAtexit) {
  504 + if (isPlaying(core->outputDeviceID)) {
  505 + status = AudioDeviceStop(core->outputDeviceID, audioDeviceIOProc);
  506 + if (status != kAudioHardwareNoError) {
  507 + coreaudio_logerr (status, "Could not pause playback\n");
  508 + }
459 509 }
460   - core->isPlaying = 0;
461 510 }
462 511 break;
463 512 }
... ... @@ -466,6 +515,7 @@ static int coreaudio_ctl_out (HWVoiceOut *hw, int cmd, ...)
466 515  
467 516 static void *coreaudio_audio_init (void)
468 517 {
  518 + atexit(coreaudio_atexit);
469 519 return &coreaudio_audio_init;
470 520 }
471 521  
... ...