/[qemu]/qemu/audio/coreaudio.c
ViewVC logotype

Diff of /qemu/audio/coreaudio.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.3 by bellard, Fri Nov 11 00:03:20 2005 UTC revision 1.4 by bellard, Sun Nov 20 16:24:09 2005 UTC
# Line 33  Line 33 
33    
34  struct {  struct {
35      int buffer_frames;      int buffer_frames;
36        int isAtexit;
37  } conf = {  } conf = {
38      .buffer_frames = 512      .buffer_frames = 512,
39        .isAtexit = 0
40  };  };
41    
42  typedef struct coreaudioVoiceOut {  typedef struct coreaudioVoiceOut {
43      HWVoiceOut hw;      HWVoiceOut hw;
44      pthread_mutex_t mutex;      pthread_mutex_t mutex;
45        int isAtexit;
46      AudioDeviceID outputDeviceID;      AudioDeviceID outputDeviceID;
47      UInt32 audioDevicePropertyBufferSize;      UInt32 audioDevicePropertyBufferFrameSize;
48      AudioStreamBasicDescription outputStreamBasicDescription;      AudioStreamBasicDescription outputStreamBasicDescription;
     int isPlaying;  
49      int live;      int live;
50      int decr;      int decr;
51      int rpos;      int rpos;
# Line 139  static void GCC_FMT_ATTR (3, 4) coreaudi Line 141  static void GCC_FMT_ATTR (3, 4) coreaudi
141      coreaudio_logstatus (status);      coreaudio_logstatus (status);
142  }  }
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    
164  static int coreaudio_lock (coreaudioVoiceOut *core, const char *fn_name)  static int coreaudio_lock (coreaudioVoiceOut *core, const char *fn_name)
165  {  {
166      int err;      int err;
# Line 203  static OSStatus audioDeviceIOProc( Line 225  static OSStatus audioDeviceIOProc(
225      const AudioTimeStamp* inOutputTime,      const AudioTimeStamp* inOutputTime,
226      void* hwptr)      void* hwptr)
227  {  {
228      unsigned int frame, frameCount;      UInt32 frame, frameCount;
229      float *out = outOutputData->mBuffers[0].mData;      float *out = outOutputData->mBuffers[0].mData;
230      HWVoiceOut *hw = hwptr;      HWVoiceOut *hw = hwptr;
231      coreaudioVoiceOut *core = (coreaudioVoiceOut *) hwptr;      coreaudioVoiceOut *core = (coreaudioVoiceOut *) hwptr;
# Line 222  static OSStatus audioDeviceIOProc( Line 244  static OSStatus audioDeviceIOProc(
244          return 0;          return 0;
245      }      }
246    
247      frameCount = conf.buffer_frames;      frameCount = core->audioDevicePropertyBufferFrameSize;
248      live = core->live;      live = core->live;
249    
250      /* if there are not enough samples, set signal and return */      /* if there are not enough samples, set signal and return */
# Line 254  static OSStatus audioDeviceIOProc( Line 276  static OSStatus audioDeviceIOProc(
276      /* cleanup */      /* cleanup */
277      mixeng_clear (src, frameCount);      mixeng_clear (src, frameCount);
278      rpos = (rpos + frameCount) % hw->samples;      rpos = (rpos + frameCount) % hw->samples;
279      core->decr = frameCount;      core->decr += frameCount;
280      core->rpos = rpos;      core->rpos = rpos;
281    
282      coreaudio_unlock (core, "audioDeviceIOProc");      coreaudio_unlock (core, "audioDeviceIOProc");
# Line 274  static int coreaudio_init_out (HWVoiceOu Line 296  static int coreaudio_init_out (HWVoiceOu
296      int err;      int err;
297      int bits = 8;      int bits = 8;
298      int endianess = 0;      int endianess = 0;
299      const char *typ = "DAC";      const char *typ = "playback";
300        AudioValueRange frameRange;
301    
302      /* create mutex */      /* create mutex */
303      err = pthread_mutex_init(&core->mutex, NULL);      err = pthread_mutex_init(&core->mutex, NULL);
# Line 312  static int coreaudio_init_out (HWVoiceOu Line 335  static int coreaudio_init_out (HWVoiceOu
335          return -1;          return -1;
336      }      }
337    
338      /* set Buffersize to conf.buffer_frames frames */      /* get minimum and maximum buffer frame sizes */
339      propertySize = sizeof(core->audioDevicePropertyBufferSize);      propertySize = sizeof(frameRange);
340      core->audioDevicePropertyBufferSize =      status = AudioDeviceGetProperty(
341          conf.buffer_frames * sizeof(float) << (as->nchannels == 2);          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);
367      status = AudioDeviceSetProperty(      status = AudioDeviceSetProperty(
368          core->outputDeviceID,          core->outputDeviceID,
369          NULL,          NULL,
370          0,          0,
371          false,          false,
372          kAudioDevicePropertyBufferSize,          kAudioDevicePropertyBufferFrameSize,
373          propertySize,          propertySize,
374          &core->audioDevicePropertyBufferSize);          &core->audioDevicePropertyBufferFrameSize);
375      if (status != kAudioHardwareNoError) {      if (status != kAudioHardwareNoError) {
376          coreaudio_logerr2 (status, typ,          coreaudio_logerr2 (status, typ,
377                             "Could not set device buffer size %d\n",                             "Could not set device buffer frame size %ld\n",
378                             kAudioDevicePropertyBufferSize);                             core->audioDevicePropertyBufferFrameSize);
379          return -1;          return -1;
380      }      }
381    
382      /* get Buffersize */      /* get Buffer Frame Size */
383      propertySize = sizeof(core->audioDevicePropertyBufferSize);      propertySize = sizeof(core->audioDevicePropertyBufferFrameSize);
384      status = AudioDeviceGetProperty(      status = AudioDeviceGetProperty(
385          core->outputDeviceID,          core->outputDeviceID,
386          0,          0,
387          false,          false,
388          kAudioDevicePropertyBufferSize,          kAudioDevicePropertyBufferFrameSize,
389          &propertySize,          &propertySize,
390          &core->audioDevicePropertyBufferSize);          &core->audioDevicePropertyBufferFrameSize);
391      if (status != kAudioHardwareNoError) {      if (status != kAudioHardwareNoError) {
392          coreaudio_logerr2 (status, typ, "Could not get device buffer size\n");          coreaudio_logerr2 (status, typ,
393                               "Could not get device buffer frame size\n");
394          return -1;          return -1;
395      }      }
396      hw->samples = (core->audioDevicePropertyBufferSize / sizeof (float))      hw->samples = 4 * core->audioDevicePropertyBufferFrameSize;
         >> (as->nchannels == 2);  
397    
398      /* get StreamFormat */      /* get StreamFormat */
399      propertySize = sizeof(core->outputStreamBasicDescription);      propertySize = sizeof(core->outputStreamBasicDescription);
# Line 364  static int coreaudio_init_out (HWVoiceOu Line 412  static int coreaudio_init_out (HWVoiceOu
412      }      }
413    
414      /* set Samplerate */      /* set Samplerate */
415      core->outputStreamBasicDescription.mSampleRate = (Float64)as->freq;      core->outputStreamBasicDescription.mSampleRate = (Float64) as->freq;
416      propertySize = sizeof(core->outputStreamBasicDescription);      propertySize = sizeof(core->outputStreamBasicDescription);
417      status = AudioDeviceSetProperty(      status = AudioDeviceSetProperty(
418          core->outputDeviceID,          core->outputDeviceID,
# Line 390  static int coreaudio_init_out (HWVoiceOu Line 438  static int coreaudio_init_out (HWVoiceOu
438      }      }
439    
440      /* start Playback */      /* start Playback */
441      if (!core->isPlaying) {      if (!isPlaying(core->outputDeviceID)) {
442          status = AudioDeviceStart(core->outputDeviceID, audioDeviceIOProc);          status = AudioDeviceStart(core->outputDeviceID, audioDeviceIOProc);
443          if (status != kAudioHardwareNoError) {          if (status != kAudioHardwareNoError) {
444              coreaudio_logerr2 (status, typ, "Could not start playback\n");              coreaudio_logerr2 (status, typ, "Could not start playback\n");
# Line 398  static int coreaudio_init_out (HWVoiceOu Line 446  static int coreaudio_init_out (HWVoiceOu
446              core->outputDeviceID = kAudioDeviceUnknown;              core->outputDeviceID = kAudioDeviceUnknown;
447              return -1;              return -1;
448          }          }
         core->isPlaying = 1;  
449      }      }
450    
451      return 0;      return 0;
# Line 410  static void coreaudio_fini_out (HWVoiceO Line 457  static void coreaudio_fini_out (HWVoiceO
457      int err;      int err;
458      coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;      coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
459    
460      /* stop playback */      if (!conf.isAtexit) {
461      if (core->isPlaying) {          /* stop playback */
462          status = AudioDeviceStop(core->outputDeviceID, audioDeviceIOProc);          if (isPlaying(core->outputDeviceID)) {
463          if (status != kAudioHardwareNoError) {              status = AudioDeviceStop(core->outputDeviceID, audioDeviceIOProc);
464              coreaudio_logerr (status, "Could not stop playback\n");              if (status != kAudioHardwareNoError) {
465                    coreaudio_logerr (status, "Could not stop playback\n");
466                }
467          }          }
         core->isPlaying = 0;  
     }  
468    
469      /* remove callback */          /* remove callback */
470      status = AudioDeviceRemoveIOProc(core->outputDeviceID, audioDeviceIOProc);          status = AudioDeviceRemoveIOProc(core->outputDeviceID,
471      if (status != kAudioHardwareNoError) {                                           audioDeviceIOProc);
472          coreaudio_logerr (status, "Could not remove IOProc\n");          if (status != kAudioHardwareNoError) {
473                coreaudio_logerr (status, "Could not remove IOProc\n");
474            }
475      }      }
476      core->outputDeviceID = kAudioDeviceUnknown;      core->outputDeviceID = kAudioDeviceUnknown;
477    
# Line 441  static int coreaudio_ctl_out (HWVoiceOut Line 490  static int coreaudio_ctl_out (HWVoiceOut
490      switch (cmd) {      switch (cmd) {
491      case VOICE_ENABLE:      case VOICE_ENABLE:
492          /* start playback */          /* start playback */
493          if (!core->isPlaying) {          if (!isPlaying(core->outputDeviceID)) {
494              status = AudioDeviceStart(core->outputDeviceID, audioDeviceIOProc);              status = AudioDeviceStart(core->outputDeviceID, audioDeviceIOProc);
495              if (status != kAudioHardwareNoError) {              if (status != kAudioHardwareNoError) {
496                  coreaudio_logerr (status, "Could not unpause playback\n");                  coreaudio_logerr (status, "Could not resume playback\n");
497              }              }
             core->isPlaying = 1;  
498          }          }
499          break;          break;
500    
501      case VOICE_DISABLE:      case VOICE_DISABLE:
502          /* stop playback */          /* stop playback */
503          if (core->isPlaying) {          if (!conf.isAtexit) {
504              status = AudioDeviceStop(core->outputDeviceID, audioDeviceIOProc);              if (isPlaying(core->outputDeviceID)) {
505              if (status != kAudioHardwareNoError) {                  status = AudioDeviceStop(core->outputDeviceID, audioDeviceIOProc);
506                  coreaudio_logerr (status, "Could not pause playback\n");                  if (status != kAudioHardwareNoError) {
507                        coreaudio_logerr (status, "Could not pause playback\n");
508                    }
509              }              }
             core->isPlaying = 0;  
510          }          }
511          break;          break;
512      }      }
# Line 466  static int coreaudio_ctl_out (HWVoiceOut Line 515  static int coreaudio_ctl_out (HWVoiceOut
515    
516  static void *coreaudio_audio_init (void)  static void *coreaudio_audio_init (void)
517  {  {
518        atexit(coreaudio_atexit);
519      return &coreaudio_audio_init;      return &coreaudio_audio_init;
520  }  }
521    

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.4

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26