fluid_coreaudio.c
上传用户:tjmskj2
上传日期:2020-08-17
资源大小:577k
文件大小:7k
源码类别:

midi

开发平台:

C/C++

  1. /* FluidSynth - A Software Synthesizer
  2.  *
  3.  * Copyright (C) 2003  Peter Hanappe and others.
  4.  *
  5.  * This library is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU Library General Public License
  7.  * as published by the Free Software Foundation; either version 2 of
  8.  * the License, or (at your option) any later version.
  9.  *
  10.  * This library is distributed in the hope that it will be useful, but
  11.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * Library General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU Library General Public
  16.  * License along with this library; if not, write to the Free
  17.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  18.  * 02111-1307, USA
  19.  */
  20. /* fluid_coreaudio.c
  21.  *
  22.  * Driver for the Apple's CoreAudio on MacOS X
  23.  *
  24.  */
  25. #include "fluid_synth.h"
  26. #include "fluid_midi.h"
  27. #include "fluid_adriver.h"
  28. #include "fluid_mdriver.h"
  29. #include "fluid_settings.h"
  30. #include "config.h"
  31. #if COREAUDIO_SUPPORT
  32. #include <CoreAudio/AudioHardware.h>
  33. #include <CoreAudio/CoreAudioTypes.h>
  34. /*
  35.  * fluid_core_audio_driver_t
  36.  *
  37.  */
  38. typedef struct {
  39.   fluid_audio_driver_t driver;
  40.   AudioDeviceID id;
  41.   AudioStreamBasicDescription format;
  42.   fluid_audio_func_t callback;
  43.   void* data;
  44.   unsigned int buffer_size;
  45.   float* buffers[2];
  46.   double phase;
  47. } fluid_core_audio_driver_t;
  48. fluid_audio_driver_t* new_fluid_core_audio_driver(fluid_settings_t* settings, fluid_synth_t* synth);
  49. fluid_audio_driver_t* new_fluid_core_audio_driver2(fluid_settings_t* settings,
  50.       fluid_audio_func_t func,
  51.       void* data);
  52. OSStatus fluid_core_audio_callback(AudioDeviceID dev,
  53.    const AudioTimeStamp* now,
  54.    const AudioBufferList* in,
  55.    const AudioTimeStamp* intime,
  56.    AudioBufferList* out,
  57.    const AudioTimeStamp* outtime,
  58.    void* data);
  59. int delete_fluid_core_audio_driver(fluid_audio_driver_t* p);
  60. /**************************************************************
  61.  *
  62.  *        CoreAudio audio driver
  63.  *
  64.  */
  65. void
  66. fluid_core_audio_driver_settings(fluid_settings_t* settings)
  67. {
  68. /*   fluid_settings_register_str(settings, "audio.coreaudio.device", "default", 0, NULL, NULL); */
  69. }
  70. /*
  71.  * new_fluid_core_audio_driver
  72.  */
  73. fluid_audio_driver_t*
  74. new_fluid_core_audio_driver(fluid_settings_t* settings, fluid_synth_t* synth)
  75. {
  76.   return new_fluid_core_audio_driver2(settings,
  77.   (fluid_audio_func_t) fluid_synth_process,
  78.   (void*) synth);
  79. }
  80. /*
  81.  * new_fluid_core_audio_driver2
  82.  */
  83. fluid_audio_driver_t*
  84. new_fluid_core_audio_driver2(fluid_settings_t* settings, fluid_audio_func_t func, void* data)
  85. {
  86.   fluid_core_audio_driver_t* dev = NULL;
  87.   UInt32 size;
  88.   OSStatus status;
  89.   dev = FLUID_NEW(fluid_core_audio_driver_t);
  90.   if (dev == NULL) {
  91.     FLUID_LOG(FLUID_ERR, "Out of memory");
  92.     return NULL;
  93.   }
  94.   FLUID_MEMSET(dev, 0, sizeof(fluid_core_audio_driver_t));
  95.   dev->callback = func;
  96.   dev->data = data;
  97.   size = sizeof(AudioDeviceID);
  98.   status = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice,  &size, (void*) &dev->id);
  99.   if (status != noErr) {
  100.     FLUID_LOG(FLUID_ERR, "Failed to get the default audio device");
  101.     goto error_recovery;
  102.   }
  103.   size = sizeof(UInt32);
  104.   status = AudioDeviceGetProperty(dev->id, 0, false,
  105.   kAudioDevicePropertyBufferSize,
  106.   &size, &dev->buffer_size);
  107.   if (status != noErr) {
  108.     FLUID_LOG(FLUID_ERR, "Failed to get the default buffer size");
  109.     goto error_recovery;
  110.   }
  111.   size = sizeof(AudioStreamBasicDescription);
  112.   status = AudioDeviceGetProperty(dev->id, 0, false,
  113.   kAudioDevicePropertyStreamFormat,
  114.   &size, &dev->format);
  115.   if (status != noErr) {
  116.     FLUID_LOG(FLUID_ERR, "Failed to get the default audio format");
  117.     goto error_recovery;
  118.   }
  119.   FLUID_LOG(FLUID_DBG, "sampleRate %g", dev->format.mSampleRate);
  120.   FLUID_LOG(FLUID_DBG, "mFormatFlags %08X", dev->format.mFormatFlags);
  121.   FLUID_LOG(FLUID_DBG, "mBytesPerPacket %d", dev->format.mBytesPerPacket);
  122.   FLUID_LOG(FLUID_DBG, "mFramesPerPacket %d", dev->format.mFramesPerPacket);
  123.   FLUID_LOG(FLUID_DBG, "mChannelsPerFrame %d", dev->format.mChannelsPerFrame);
  124.   FLUID_LOG(FLUID_DBG, "mBytesPerFrame %d", dev->format.mBytesPerFrame);
  125.   FLUID_LOG(FLUID_DBG, "mBitsPerChannel %d", dev->format.mBitsPerChannel);
  126.   if (dev->format.mFormatID != kAudioFormatLinearPCM) {
  127.     FLUID_LOG(FLUID_ERR, "The default audio format is not PCM");
  128.     goto error_recovery;
  129.   }
  130.   if (!(dev->format.mFormatFlags & kLinearPCMFormatFlagIsFloat)) {
  131.     FLUID_LOG(FLUID_ERR, "The default audio format is not float");
  132.     goto error_recovery;
  133.   }
  134.   dev->buffers[0] = FLUID_ARRAY(float, dev->buffer_size);
  135.   dev->buffers[1] = FLUID_ARRAY(float, dev->buffer_size);
  136.   status = AudioDeviceAddIOProc(dev->id, fluid_core_audio_callback, (void*) dev);
  137.   if (status != noErr) {
  138.     FLUID_LOG(FLUID_ERR, "The default audio format is not PCM");
  139.     goto error_recovery;
  140.   }
  141.   status = AudioDeviceStart(dev->id, fluid_core_audio_callback);
  142.   if (status != noErr) {
  143.     FLUID_LOG(FLUID_ERR, "The default audio format is not PCM");
  144.     goto error_recovery;
  145.   }
  146.   return (fluid_audio_driver_t*) dev;
  147. error_recovery:
  148.   delete_fluid_core_audio_driver((fluid_audio_driver_t*) dev);
  149.   return NULL;
  150. }
  151. /*
  152.  * delete_fluid_core_audio_driver
  153.  */
  154. int
  155. delete_fluid_core_audio_driver(fluid_audio_driver_t* p)
  156. {
  157.   fluid_core_audio_driver_t* dev = (fluid_core_audio_driver_t*) p;
  158.   if (dev == NULL) {
  159.     return FLUID_OK;
  160.   }
  161.   if (AudioDeviceStop(dev->id, fluid_core_audio_callback) == noErr) {
  162.     AudioDeviceRemoveIOProc(dev->id, fluid_core_audio_callback);
  163.   }
  164.   if (dev->buffers[0]) {
  165.     FLUID_FREE(dev->buffers[0]);
  166.   }
  167.   if (dev->buffers[1]) {
  168.     FLUID_FREE(dev->buffers[1]);
  169.   }
  170.   FLUID_FREE(dev);
  171.   return FLUID_OK;
  172. }
  173. OSStatus
  174. fluid_core_audio_callback(AudioDeviceID id,
  175.   const AudioTimeStamp* now,
  176.   const AudioBufferList* in,
  177.   const AudioTimeStamp* intime,
  178.   AudioBufferList* out,
  179.   const AudioTimeStamp* outtime,
  180.   void* data)
  181. {
  182.   int i, k;
  183.   fluid_core_audio_driver_t* dev = (fluid_core_audio_driver_t*) data;
  184.   int len = dev->buffer_size / dev->format.mBytesPerFrame;
  185.   float* buffer = out->mBuffers[0].mData;
  186.   if (dev->callback)
  187.   {
  188.     float* left = dev->buffers[0];
  189.     float* right = dev->buffers[1];
  190.     (*dev->callback)(dev->data, len, 0, NULL, 2, dev->buffers);
  191.     for (i = 0, k = 0; i < len; i++) {
  192.       buffer[k++] = left[i];
  193.       buffer[k++] = right[i];
  194.     }
  195.   }
  196.   else fluid_synth_write_float((fluid_synth_t*) dev->data, len, buffer, 0, 2,
  197.        buffer, 1, 2);
  198.   return noErr;
  199. }
  200. #endif /* #if COREAUDIO_SUPPORT */