From 66b7c198936cc7f07689d247356996959de80868 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Tue, 10 Nov 2020 23:53:54 +0100 Subject: [PATCH] Audio output group With subgroups Audio Driver and File Renderer --- include/fluidsynth/audio.h | 63 ++++++++++++++++++++++++------- src/bindings/fluid_filerenderer.c | 18 +++++---- src/drivers/fluid_adriver.c | 14 ++++--- 3 files changed, 68 insertions(+), 27 deletions(-) diff --git a/include/fluidsynth/audio.h b/include/fluidsynth/audio.h index f02b24ab..0ab5e596 100644 --- a/include/fluidsynth/audio.h +++ b/include/fluidsynth/audio.h @@ -26,12 +26,27 @@ extern "C" { #endif /** - * @defgroup Audio Audio Output - * @brief Functions for audio driver output. + * @defgroup audio_output Audio Output + * + * Functions for managing audio drivers and file renderers. + * + * The file renderer is used for fast rendering of MIDI files to + * audio files. The audio drivers are a high-level interface to + * connect the synthesizer with external audio sinks or to render + * real-time audio to files. + */ + +/** + * @defgroup audio_driver Audio Driver + * @ingroup audio_output + * + * Functions for managing audio drivers. * * Defines functions for creating audio driver output. Use * new_fluid_audio_driver() to create a new audio driver for a given synth - * and configuration settings. The function new_fluid_audio_driver2() can be + * and configuration settings. + * + * The function new_fluid_audio_driver2() can be * used if custom audio processing is desired before the audio is sent to the * audio driver (although it is not as efficient). * @@ -42,14 +57,8 @@ extern "C" { /** * Callback function type used with new_fluid_audio_driver2() to allow for - * custom user audio processing before the audio is sent to the driver. This - * function is responsible for rendering audio to the buffers. - * The buffers passed to this function are allocated and owned by the respective - * audio driver and are only valid during that specific call (do not cache them). - * For further details please refer to fluid_synth_process(). - * @note Whereas fluid_synth_process() allows aliasing buffers, there is the guarentee that @p out - * and @p fx buffers provided by fluidsynth's audio drivers never alias. This prevents downstream - * applications from e.g. applying a custom effect accidentially to the same buffer multiple times. + * custom user audio processing before the audio is sent to the driver. + * * @param data The user data parameter as passed to new_fluid_audio_driver2(). * @param len Count of audio frames to synthesize. * @param nfx Count of arrays in \c fx. @@ -57,6 +66,16 @@ extern "C" { * @param nout Count of arrays in \c out. * @param out Array of buffers to store (dry) audio to. Buffers may alias with buffers of \c fx. * @return Should return #FLUID_OK on success, #FLUID_FAILED if an error occurred. + * + * This function is responsible for rendering audio to the buffers. + * The buffers passed to this function are allocated and owned by the respective + * audio driver and are only valid during that specific call (do not cache them). + * For further details please refer to fluid_synth_process(). + * + * @note Whereas fluid_synth_process() allows aliasing buffers, there is the guarentee that @p out + * and @p fx buffers provided by fluidsynth's audio drivers never alias. This prevents downstream + * applications from e.g. applying a custom effect accidentially to the same buffer multiple times. + * */ typedef int (*fluid_audio_func_t)(void *data, int len, int nfx, float *fx[], @@ -71,13 +90,29 @@ FLUIDSYNTH_API fluid_audio_driver_t *new_fluid_audio_driver2(fluid_settings_t *s FLUIDSYNTH_API void delete_fluid_audio_driver(fluid_audio_driver_t *driver); +FLUIDSYNTH_API int fluid_audio_driver_register(const char **adrivers); +/* @} */ + +/** + * @defgroup file_renderer File Renderer + * @ingroup audio_output + * + * Functions for managing file renderers and triggering the rendering. + * + * The file renderer is only used to render a MIDI file to audio as fast + * as possible. Please see \ref FileRenderer for a full example. + * + * If you are looking for a way to write audio generated + * from real-time events (for example from an external sequencer or a MIDI controller) to a file, + * please have a look at the \c file \ref audio_driver instead. + * + * + * @{ + */ FLUIDSYNTH_API fluid_file_renderer_t *new_fluid_file_renderer(fluid_synth_t *synth); FLUIDSYNTH_API int fluid_file_renderer_process_block(fluid_file_renderer_t *dev); FLUIDSYNTH_API void delete_fluid_file_renderer(fluid_file_renderer_t *dev); FLUIDSYNTH_API int fluid_file_set_encoding_quality(fluid_file_renderer_t *dev, double q); - -FLUIDSYNTH_API int fluid_audio_driver_register(const char **adrivers); - /* @} */ #ifdef __cplusplus diff --git a/src/bindings/fluid_filerenderer.c b/src/bindings/fluid_filerenderer.c index 83805da0..8c244386 100644 --- a/src/bindings/fluid_filerenderer.c +++ b/src/bindings/fluid_filerenderer.c @@ -171,22 +171,24 @@ fluid_file_renderer_settings(fluid_settings_t *settings) /** * Create a new file renderer and open the file. + * * @param synth The synth that creates audio data. * @return the new object, or NULL on failure - * @since 1.1.0 * - * NOTE: Available file types and formats depends on if libfluidsynth was + * @note Available file types and formats depends on if libfluidsynth was * built with libsndfile support or not. If not then only RAW 16 bit output is * supported. * * Uses the following settings from the synth object: - * - audio.file.name: Output filename - * - audio.file.type: File type, "auto" tries to determine type from filename + * - \ref settings_audio_file_name : Output filename + * - \ref settings_audio_file_type : File type, "auto" tries to determine type from filename * extension with fallback to "wav". - * - audio.file.format: Audio format - * - audio.file.endian: Endian byte order, "auto" for file type's default byte order - * - audio.period-size: Size of audio blocks to process - * - synth.sample-rate: Sample rate to use + * - \ref settings_audio_file_format : Audio format + * - \ref settings_audio_file_endian : Endian byte order, "auto" for file type's default byte order + * - \ref settings_audio_period-size : Size of audio blocks to process + * - \ref settings_synth_sample-rate : Sample rate to use + * + * @since 1.1.0 */ fluid_file_renderer_t * new_fluid_file_renderer(fluid_synth_t *synth) diff --git a/src/drivers/fluid_adriver.c b/src/drivers/fluid_adriver.c index c2d1f093..369e23f5 100644 --- a/src/drivers/fluid_adriver.c +++ b/src/drivers/fluid_adriver.c @@ -288,6 +288,7 @@ find_fluid_audio_driver(fluid_settings_t *settings) /** * Create a new audio driver. + * * @param settings Configuration settings used to select and create the audio * driver. * @param synth Synthesizer instance for which the audio driver is created for. @@ -326,6 +327,7 @@ new_fluid_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth) /** * Create a new audio driver. + * * @param settings Configuration settings used to select and create the audio * driver. * @param func Function called to fill audio buffers for audio playback @@ -378,6 +380,7 @@ new_fluid_audio_driver2(fluid_settings_t *settings, fluid_audio_func_t func, voi /** * Deletes an audio driver instance. + * * @param driver Audio driver instance to delete * * Shuts down an audio driver and deletes its instance. @@ -391,7 +394,11 @@ delete_fluid_audio_driver(fluid_audio_driver_t *driver) /** - * @brief Registers audio drivers to use + * Registers audio drivers to use + * + * @param adrivers NULL-terminated array of audio drivers to register. Pass NULL to register all available drivers. + * @return #FLUID_OK if all the audio drivers requested by the user are supported by fluidsynth and have been + * successfully registered. Otherwise #FLUID_FAILED is returned and this function has no effect. * * When creating a settings instance with new_fluid_settings(), all audio drivers are initialized once. * In the past this has caused segfaults and application crashes due to buggy soundcard drivers. @@ -407,11 +414,8 @@ delete_fluid_audio_driver(fluid_audio_driver_t *driver) * are alive (e.g. as it would be the case right after fluidsynth's initial creation). Else the behaviour is undefined. * Furtermore any attempt of using audio drivers that have not been registered is undefined behaviour! * - * @param adrivers NULL-terminated array of audio drivers to register. Pass NULL to register all available drivers. - * @return #FLUID_OK if all the audio drivers requested by the user are supported by fluidsynth and have been - * successfully registered. Otherwise #FLUID_FAILED is returned and this function has no effect. - * * @note This function is not thread safe and will never be! + * * @since 1.1.9 */ int fluid_audio_driver_register(const char **adrivers)