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 21#include "fluid_adriver.h" 22#include "fluid_settings.h" 23 24/* 25 * fluid_adriver_definition_t 26 */ 27 28typedef struct _fluid_audriver_definition_t 29{ 30 char* name; 31 fluid_audio_driver_t* (*new)(fluid_settings_t* settings, fluid_synth_t* synth); 32 fluid_audio_driver_t* (*new2)(fluid_settings_t* settings, 33 fluid_audio_func_t func, 34 void* data); 35 int (*free)(fluid_audio_driver_t* driver); 36 void (*settings)(fluid_settings_t* settings); 37} fluid_audriver_definition_t; 38 39 40#if PULSE_SUPPORT 41fluid_audio_driver_t* new_fluid_pulse_audio_driver(fluid_settings_t* settings, 42 fluid_synth_t* synth); 43fluid_audio_driver_t* new_fluid_pulse_audio_driver2(fluid_settings_t* settings, 44 fluid_audio_func_t func, void* data); 45int delete_fluid_pulse_audio_driver(fluid_audio_driver_t* p); 46void fluid_pulse_audio_driver_settings(fluid_settings_t* settings); 47#endif 48 49#if ALSA_SUPPORT 50fluid_audio_driver_t* new_fluid_alsa_audio_driver(fluid_settings_t* settings, 51 fluid_synth_t* synth); 52fluid_audio_driver_t* new_fluid_alsa_audio_driver2(fluid_settings_t* settings, 53 fluid_audio_func_t func, void* data); 54int delete_fluid_alsa_audio_driver(fluid_audio_driver_t* p); 55void fluid_alsa_audio_driver_settings(fluid_settings_t* settings); 56#endif 57 58#if OSS_SUPPORT 59fluid_audio_driver_t* new_fluid_oss_audio_driver(fluid_settings_t* settings, 60 fluid_synth_t* synth); 61fluid_audio_driver_t* new_fluid_oss_audio_driver2(fluid_settings_t* settings, 62 fluid_audio_func_t func, void* data); 63int delete_fluid_oss_audio_driver(fluid_audio_driver_t* p); 64void fluid_oss_audio_driver_settings(fluid_settings_t* settings); 65#endif 66 67#if COREAUDIO_SUPPORT 68fluid_audio_driver_t* new_fluid_core_audio_driver(fluid_settings_t* settings, 69 fluid_synth_t* synth); 70fluid_audio_driver_t* new_fluid_core_audio_driver2(fluid_settings_t* settings, 71 fluid_audio_func_t func, 72 void* data); 73int delete_fluid_core_audio_driver(fluid_audio_driver_t* p); 74void fluid_core_audio_driver_settings(fluid_settings_t* settings); 75#endif 76 77#if DSOUND_SUPPORT 78fluid_audio_driver_t* new_fluid_dsound_audio_driver(fluid_settings_t* settings, 79 fluid_synth_t* synth); 80int delete_fluid_dsound_audio_driver(fluid_audio_driver_t* p); 81void fluid_dsound_audio_driver_settings(fluid_settings_t* settings); 82#endif 83 84#if PORTAUDIO_SUPPORT 85void fluid_portaudio_driver_settings (fluid_settings_t *settings); 86fluid_audio_driver_t* new_fluid_portaudio_driver(fluid_settings_t* settings, 87 fluid_synth_t* synth); 88int delete_fluid_portaudio_driver(fluid_audio_driver_t* p); 89#endif 90 91#if JACK_SUPPORT 92fluid_audio_driver_t* new_fluid_jack_audio_driver(fluid_settings_t* settings, fluid_synth_t* synth); 93fluid_audio_driver_t* new_fluid_jack_audio_driver2(fluid_settings_t* settings, 94 fluid_audio_func_t func, void* data); 95int delete_fluid_jack_audio_driver(fluid_audio_driver_t* p); 96void fluid_jack_audio_driver_settings(fluid_settings_t* settings); 97#endif 98 99#if SNDMAN_SUPPORT 100fluid_audio_driver_t* new_fluid_sndmgr_audio_driver(fluid_settings_t* settings, 101 fluid_synth_t* synth); 102fluid_audio_driver_t* new_fluid_sndmgr_audio_driver2(fluid_settings_t* settings, 103 fluid_audio_func_t func, 104 void* data); 105int delete_fluid_sndmgr_audio_driver(fluid_audio_driver_t* p); 106#endif 107 108#if DART_SUPPORT 109fluid_audio_driver_t* new_fluid_dart_audio_driver(fluid_settings_t* settings, 110 fluid_synth_t* synth); 111int delete_fluid_dart_audio_driver(fluid_audio_driver_t* p); 112void fluid_dart_audio_driver_settings(fluid_settings_t* settings); 113#endif 114 115#define AUFILE_SUPPORT 1 116#if AUFILE_SUPPORT 117fluid_audio_driver_t* new_fluid_file_audio_driver(fluid_settings_t* settings, 118 fluid_synth_t* synth); 119int delete_fluid_file_audio_driver(fluid_audio_driver_t* p); 120void fluid_file_audio_driver_settings(fluid_settings_t* settings); 121#endif 122 123/* Available audio drivers, listed in order of preference */ 124fluid_audriver_definition_t fluid_audio_drivers[] = { 125#if JACK_SUPPORT 126 { "jack", 127 new_fluid_jack_audio_driver, 128 new_fluid_jack_audio_driver2, 129 delete_fluid_jack_audio_driver, 130 fluid_jack_audio_driver_settings }, 131#endif 132#if ALSA_SUPPORT 133 { "alsa", 134 new_fluid_alsa_audio_driver, 135 new_fluid_alsa_audio_driver2, 136 delete_fluid_alsa_audio_driver, 137 fluid_alsa_audio_driver_settings }, 138#endif 139#if OSS_SUPPORT 140 { "oss", 141 new_fluid_oss_audio_driver, 142 new_fluid_oss_audio_driver2, 143 delete_fluid_oss_audio_driver, 144 fluid_oss_audio_driver_settings }, 145#endif 146#if PULSE_SUPPORT 147 { "pulseaudio", 148 new_fluid_pulse_audio_driver, 149 new_fluid_pulse_audio_driver2, 150 delete_fluid_pulse_audio_driver, 151 fluid_pulse_audio_driver_settings }, 152#endif 153#if COREAUDIO_SUPPORT 154 { "coreaudio", 155 new_fluid_core_audio_driver, 156 new_fluid_core_audio_driver2, 157 delete_fluid_core_audio_driver, 158 fluid_core_audio_driver_settings }, 159#endif 160#if DSOUND_SUPPORT 161 { "dsound", 162 new_fluid_dsound_audio_driver, 163 NULL, 164 delete_fluid_dsound_audio_driver, 165 fluid_dsound_audio_driver_settings }, 166#endif 167#if PORTAUDIO_SUPPORT 168 { "portaudio", 169 new_fluid_portaudio_driver, 170 NULL, 171 delete_fluid_portaudio_driver, 172 fluid_portaudio_driver_settings }, 173#endif 174#if SNDMAN_SUPPORT 175 { "sndman", 176 new_fluid_sndmgr_audio_driver, 177 new_fluid_sndmgr_audio_driver2, 178 delete_fluid_sndmgr_audio_driver, 179 NULL }, 180#endif 181#if DART_SUPPORT 182 { "dart", 183 new_fluid_dart_audio_driver, 184 NULL, 185 delete_fluid_dart_audio_driver, 186 fluid_dart_audio_driver_settings }, 187#endif 188#if AUFILE_SUPPORT 189 { "file", 190 new_fluid_file_audio_driver, 191 NULL, 192 delete_fluid_file_audio_driver, 193 fluid_file_audio_driver_settings }, 194#endif 195 { NULL, NULL, NULL, NULL, NULL } 196}; 197 198 199 200 201void fluid_audio_driver_settings(fluid_settings_t* settings) 202{ 203 int i; 204 205 fluid_settings_register_str(settings, "audio.sample-format", "16bits", 0, NULL, NULL); 206 fluid_settings_add_option(settings, "audio.sample-format", "16bits"); 207 fluid_settings_add_option(settings, "audio.sample-format", "float"); 208 209 fluid_settings_register_int(settings, "audio.output-channels", 2, 2, 32, 0, NULL, NULL); 210 fluid_settings_register_int(settings, "audio.input-channels", 0, 0, 2, 0, NULL, NULL); 211 212 213#if defined(WIN32) 214 fluid_settings_register_int(settings, "audio.period-size", 512, 64, 8192, 0, NULL, NULL); 215 fluid_settings_register_int(settings, "audio.periods", 8, 2, 64, 0, NULL, NULL); 216#elif defined(MACOS9) 217 fluid_settings_register_int(settings, "audio.period-size", 64, 64, 8192, 0, NULL, NULL); 218 fluid_settings_register_int(settings, "audio.periods", 8, 2, 64, 0, NULL, NULL); 219#else 220 fluid_settings_register_int(settings, "audio.period-size", 64, 64, 8192, 0, NULL, NULL); 221 fluid_settings_register_int(settings, "audio.periods", 16, 2, 64, 0, NULL, NULL); 222#endif 223 224 /* Set the default driver */ 225#if JACK_SUPPORT 226 fluid_settings_register_str(settings, "audio.driver", "jack", 0, NULL, NULL); 227#elif ALSA_SUPPORT 228 fluid_settings_register_str(settings, "audio.driver", "alsa", 0, NULL, NULL); 229#elif PULSE_SUPPORT 230 fluid_settings_register_str(settings, "audio.driver", "pulseaudio", 0, NULL, NULL); 231#elif OSS_SUPPORT 232 fluid_settings_register_str(settings, "audio.driver", "oss", 0, NULL, NULL); 233#elif COREAUDIO_SUPPORT 234 fluid_settings_register_str(settings, "audio.driver", "coreaudio", 0, NULL, NULL); 235#elif DSOUND_SUPPORT 236 fluid_settings_register_str(settings, "audio.driver", "dsound", 0, NULL, NULL); 237#elif SNDMAN_SUPPORT 238 fluid_settings_register_str(settings, "audio.driver", "sndman", 0, NULL, NULL); 239#elif PORTAUDIO_SUPPORT 240 fluid_settings_register_str(settings, "audio.driver", "portaudio", 0, NULL, NULL); 241#elif DART_SUPPORT 242 fluid_settings_register_str(settings, "audio.driver", "dart", 0, NULL, NULL); 243#elif AUFILE_SUPPORT 244 fluid_settings_register_str(settings, "audio.driver", "file", 0, NULL, NULL); 245#else 246 fluid_settings_register_str(settings, "audio.driver", "", 0, NULL, NULL); 247#endif 248 249 /* Add all drivers to the list of options */ 250#if PULSE_SUPPORT 251 fluid_settings_add_option(settings, "audio.driver", "pulseaudio"); 252#endif 253#if ALSA_SUPPORT 254 fluid_settings_add_option(settings, "audio.driver", "alsa"); 255#endif 256#if OSS_SUPPORT 257 fluid_settings_add_option(settings, "audio.driver", "oss"); 258#endif 259#if COREAUDIO_SUPPORT 260 fluid_settings_add_option(settings, "audio.driver", "coreaudio"); 261#endif 262#if DSOUND_SUPPORT 263 fluid_settings_add_option(settings, "audio.driver", "dsound"); 264#endif 265#if SNDMAN_SUPPORT 266 fluid_settings_add_option(settings, "audio.driver", "sndman"); 267#endif 268#if PORTAUDIO_SUPPORT 269 fluid_settings_add_option(settings, "audio.driver", "portaudio"); 270#endif 271#if JACK_SUPPORT 272 fluid_settings_add_option(settings, "audio.driver", "jack"); 273#endif 274#if DART_SUPPORT 275 fluid_settings_add_option(settings, "audio.driver", "dart"); 276#endif 277#if AUFILE_SUPPORT 278 fluid_settings_add_option(settings, "audio.driver", "file"); 279#endif 280 281 for (i = 0; fluid_audio_drivers[i].name != NULL; i++) { 282 if (fluid_audio_drivers[i].settings != NULL) { 283 fluid_audio_drivers[i].settings(settings); 284 } 285 } 286} 287 288 289/** 290 * Create a new audio driver. 291 * @param settings Configuration settings used to select and create the audio 292 * driver. 293 * @param synth Synthesizer instance for which the audio driver is created for. 294 * @return The new audio driver instance. 295 * 296 * Creates a new audio driver for a given 'synth' instance with a defined set 297 * of configuration 'settings'. 298 */ 299fluid_audio_driver_t* 300new_fluid_audio_driver(fluid_settings_t* settings, fluid_synth_t* synth) 301{ 302 int i; 303 fluid_audio_driver_t* driver = NULL; 304 char* name; 305 306 fluid_settings_getstr(settings, "audio.driver", &name); 307 308 for (i = 0; fluid_audio_drivers[i].name != NULL; i++) { 309 if (fluid_settings_str_equal(settings, "audio.driver", fluid_audio_drivers[i].name)) { 310 FLUID_LOG(FLUID_DBG, "Using '%s' audio driver", fluid_audio_drivers[i].name); 311 driver = (*fluid_audio_drivers[i].new)(settings, synth); 312 if (driver) { 313 driver->name = fluid_audio_drivers[i].name; 314 } 315 return driver; 316 } 317 } 318 319 FLUID_LOG(FLUID_ERR, "Couldn't find the requested audio driver: %s", name); 320 return NULL; 321} 322 323/** 324 * Create a new audio driver. 325 * @param settings Configuration settings used to select and create the audio 326 * driver. 327 * @param func Function called to fill audio buffers for audio playback 328 * @param data User defined data pointer to pass to 'func' 329 * @return The new audio driver instance. 330 * 331 * Like new_fluid_audio_driver() but allows for custom audio processing before 332 * audio is sent to audio driver. It is the responsibility of the callback 333 * 'func' to render the audio into the buffers. 334 * NOTE: Not as efficient as new_fluid_audio_driver(). 335 */ 336fluid_audio_driver_t* 337new_fluid_audio_driver2(fluid_settings_t* settings, fluid_audio_func_t func, void* data) 338{ 339 int i; 340 fluid_audio_driver_t* driver = NULL; 341 char* name; 342 343 fluid_settings_getstr(settings, "audio.driver", &name); 344 345 for (i = 0; fluid_audio_drivers[i].name != NULL; i++) { 346 if (fluid_settings_str_equal(settings, "audio.driver", fluid_audio_drivers[i].name) && 347 (fluid_audio_drivers[i].new2 != NULL)) { 348 FLUID_LOG(FLUID_DBG, "Using '%s' audio driver", fluid_audio_drivers[i].name); 349 driver = (*fluid_audio_drivers[i].new2)(settings, func, data); 350 if (driver) { 351 driver->name = fluid_audio_drivers[i].name; 352 } 353 return driver; 354 } 355 } 356 357 FLUID_LOG(FLUID_ERR, "Couldn't find the requested audio driver: %s", name); 358 return NULL; 359} 360 361/** 362 * Deletes an audio driver instance. 363 * @param driver Audio driver instance to delete 364 * 365 * Shuts down an audio driver and deletes its instance. 366 */ 367void 368delete_fluid_audio_driver(fluid_audio_driver_t* driver) 369{ 370 int i; 371 372 for (i = 0; fluid_audio_drivers[i].name != NULL; i++) { 373 if (fluid_audio_drivers[i].name == driver->name) { 374 fluid_audio_drivers[i].free(driver); 375 return; 376 } 377 } 378} 379