diff --git a/headers/libs/fluidsynth/fluidsynth.h b/headers/libs/fluidsynth/fluidsynth.h deleted file mode 100644 index ef40f824fe..0000000000 --- a/headers/libs/fluidsynth/fluidsynth.h +++ /dev/null @@ -1,102 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#ifndef _FLUIDSYNTH_H -#define _FLUIDSYNTH_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(WIN32) -#if defined(FLUIDSYNTH_DLL_EXPORTS) -#define FLUIDSYNTH_API __declspec(dllexport) -#elif defined(FLUIDSYNTH_NOT_A_DLL) -#define FLUIDSYNTH_API -#else -#define FLUIDSYNTH_API __declspec(dllimport) -#endif - -#elif defined(MACOS9) -#define FLUIDSYNTH_API __declspec(export) - -#else -#define FLUIDSYNTH_API -#endif - - -/** - * @file fluidsynth.h - * @brief FluidSynth is a real-time synthesizer designed for SoundFont(R) files. - * - * This is the header of the fluidsynth library and contains the - * synthesizer's public API. - * - * Depending on how you want to use or extend the synthesizer you - * will need different API functions. You probably do not need all - * of them. Here is what you might want to do: - * - * o Embedded synthesizer: create a new synthesizer and send MIDI - * events to it. The sound goes directly to the audio output of - * your system. - * - * o Plugin synthesizer: create a synthesizer and send MIDI events - * but pull the audio back into your application. - * - * o SoundFont plugin: create a new type of "SoundFont" and allow - * the synthesizer to load your type of SoundFonts. - * - * o MIDI input: Create a MIDI handler to read the MIDI input on your - * machine and send the MIDI events directly to the synthesizer. - * - * o MIDI files: Open MIDI files and send the MIDI events to the - * synthesizer. - * - * o Command lines: You can send textual commands to the synthesizer. - * - * SoundFont(R) is a registered trademark of E-mu Systems, Inc. - */ - -#include "fluidsynth/types.h" -#include "fluidsynth/settings.h" -#include "fluidsynth/synth.h" -#include "fluidsynth/shell.h" -#include "fluidsynth/sfont.h" -#include "fluidsynth/ramsfont.h" -#include "fluidsynth/audio.h" -#include "fluidsynth/event.h" -#include "fluidsynth/midi.h" -#include "fluidsynth/seq.h" -#include "fluidsynth/seqbind.h" -#include "fluidsynth/log.h" -#include "fluidsynth/misc.h" -#include "fluidsynth/mod.h" -#include "fluidsynth/gen.h" -#include "fluidsynth/voice.h" -#include "fluidsynth/version.h" - - -#ifdef __cplusplus -} -#endif - -#endif /* _FLUIDSYNTH_H */ diff --git a/headers/libs/fluidsynth/fluidsynth/audio.h b/headers/libs/fluidsynth/fluidsynth/audio.h deleted file mode 100644 index e2c9bd1d13..0000000000 --- a/headers/libs/fluidsynth/fluidsynth/audio.h +++ /dev/null @@ -1,70 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#ifndef _FLUIDSYNTH_AUDIO_H -#define _FLUIDSYNTH_AUDIO_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @file audio.h - * @brief Functions for audio driver output. - * - * 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 - * used if custom audio processing is desired before the audio is sent to the - * audio driver (although it is not as efficient). - */ - -/** - * 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 the audio to the buffers. - * @param data The user data parameter as passed to new_fluid_audio_driver2(). - * @param len Length of the audio in frames. - * @param nin Count of buffers in 'in' - * @param in FIXME - Not used currently? - * @param nout Count of arrays in 'out' (i.e., channel count) - * @param out Output buffers, one for each channel - * @return Should return 0 on success, non-zero if an error occured. - */ -typedef int (*fluid_audio_func_t)(void* data, int len, - int nin, float** in, - int nout, float** out); - -FLUIDSYNTH_API fluid_audio_driver_t* new_fluid_audio_driver(fluid_settings_t* settings, - fluid_synth_t* synth); - -FLUIDSYNTH_API fluid_audio_driver_t* new_fluid_audio_driver2(fluid_settings_t* settings, - fluid_audio_func_t func, - void* data); - -FLUIDSYNTH_API void delete_fluid_audio_driver(fluid_audio_driver_t* driver); - - - -#ifdef __cplusplus -} -#endif - -#endif /* _FLUIDSYNTH_AUDIO_H */ diff --git a/headers/libs/fluidsynth/fluidsynth/event.h b/headers/libs/fluidsynth/fluidsynth/event.h deleted file mode 100644 index 086a87809f..0000000000 --- a/headers/libs/fluidsynth/fluidsynth/event.h +++ /dev/null @@ -1,123 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#ifndef _FLUIDSYNTH_EVENT_H -#define _FLUIDSYNTH_EVENT_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @file event.h - * @brief Sequencer event functions and defines. - * - * Functions and constants for creating/processing sequencer events. - */ - -/** - * Sequencer event type enumeration. - */ -enum fluid_seq_event_type { - FLUID_SEQ_NOTE = 0, /**< Note event (DOCME) */ - FLUID_SEQ_NOTEON, /**< Note on event */ - FLUID_SEQ_NOTEOFF, /**< Note off event */ - FLUID_SEQ_ALLSOUNDSOFF, /**< All sounds off event */ - FLUID_SEQ_ALLNOTESOFF, /**< All notes off event */ - FLUID_SEQ_BANKSELECT, /**< Bank select message */ - FLUID_SEQ_PROGRAMCHANGE, /**< Program change message */ - FLUID_SEQ_PROGRAMSELECT, /**< Program select message (DOCME) */ - FLUID_SEQ_PITCHBEND, /**< Pitch bend message */ - FLUID_SEQ_PITCHWHHELSENS, /**< Pitch wheel sensitivity set message */ - FLUID_SEQ_MODULATION, /**< Modulation controller event */ - FLUID_SEQ_SUSTAIN, /**< Sustain controller event */ - FLUID_SEQ_CONTROLCHANGE, /**< MIDI control change event */ - FLUID_SEQ_PAN, /**< Stereo pan set event */ - FLUID_SEQ_VOLUME, /**< Volume set event */ - FLUID_SEQ_REVERBSEND, /**< Reverb send set event */ - FLUID_SEQ_CHORUSSEND, /**< Chorus send set event */ - FLUID_SEQ_TIMER, /**< Timer event (DOCME) */ - FLUID_SEQ_ANYCONTROLCHANGE, /**< DOCME (used for remove_events only) */ - FLUID_SEQ_LASTEVENT /**< Defines the count of event enums */ -}; - -/* Event alloc/free */ -FLUIDSYNTH_API fluid_event_t* new_fluid_event(void); -FLUIDSYNTH_API void delete_fluid_event(fluid_event_t* evt); - -/* Initializing events */ -FLUIDSYNTH_API void fluid_event_set_source(fluid_event_t* evt, short src); -FLUIDSYNTH_API void fluid_event_set_dest(fluid_event_t* evt, short dest); - -/* Timer events */ -FLUIDSYNTH_API void fluid_event_timer(fluid_event_t* evt, void* data); - -/* Note events */ -FLUIDSYNTH_API void fluid_event_note(fluid_event_t* evt, int channel, - short key, short vel, - unsigned int duration); - -FLUIDSYNTH_API void fluid_event_noteon(fluid_event_t* evt, int channel, short key, short vel); -FLUIDSYNTH_API void fluid_event_noteoff(fluid_event_t* evt, int channel, short key); -FLUIDSYNTH_API void fluid_event_all_sounds_off(fluid_event_t* evt, int channel); -FLUIDSYNTH_API void fluid_event_all_notes_off(fluid_event_t* evt, int channel); - -/* Instrument selection */ -FLUIDSYNTH_API void fluid_event_bank_select(fluid_event_t* evt, int channel, short bank_num); -FLUIDSYNTH_API void fluid_event_program_change(fluid_event_t* evt, int channel, short preset_num); -FLUIDSYNTH_API void fluid_event_program_select(fluid_event_t* evt, int channel, unsigned int sfont_id, short bank_num, short preset_num); - -/* Real-time generic instrument controllers */ -FLUIDSYNTH_API -void fluid_event_control_change(fluid_event_t* evt, int channel, short control, short val); - -/* Real-time instrument controllers shortcuts */ -FLUIDSYNTH_API void fluid_event_pitch_bend(fluid_event_t* evt, int channel, int val); -FLUIDSYNTH_API void fluid_event_pitch_wheelsens(fluid_event_t* evt, int channel, short val); -FLUIDSYNTH_API void fluid_event_modulation(fluid_event_t* evt, int channel, short val); -FLUIDSYNTH_API void fluid_event_sustain(fluid_event_t* evt, int channel, short val); -FLUIDSYNTH_API void fluid_event_pan(fluid_event_t* evt, int channel, short val); -FLUIDSYNTH_API void fluid_event_volume(fluid_event_t* evt, int channel, short val); -FLUIDSYNTH_API void fluid_event_reverb_send(fluid_event_t* evt, int channel, short val); -FLUIDSYNTH_API void fluid_event_chorus_send(fluid_event_t* evt, int channel, short val); - -/* Only for removing events */ -FLUIDSYNTH_API void fluid_event_any_control_change(fluid_event_t* evt, int channel); - -/* Accessing event data */ -FLUIDSYNTH_API int fluid_event_get_type(fluid_event_t* evt); -FLUIDSYNTH_API short fluid_event_get_source(fluid_event_t* evt); -FLUIDSYNTH_API short fluid_event_get_dest(fluid_event_t* evt); -FLUIDSYNTH_API int fluid_event_get_channel(fluid_event_t* evt); -FLUIDSYNTH_API short fluid_event_get_key(fluid_event_t* evt); -FLUIDSYNTH_API short fluid_event_get_velocity(fluid_event_t* evt); -FLUIDSYNTH_API short fluid_event_get_control(fluid_event_t* evt); -FLUIDSYNTH_API short fluid_event_get_value(fluid_event_t* evt); -FLUIDSYNTH_API short fluid_event_get_program(fluid_event_t* evt); -FLUIDSYNTH_API void* fluid_event_get_data(fluid_event_t* evt); -FLUIDSYNTH_API unsigned int fluid_event_get_duration(fluid_event_t* evt); -FLUIDSYNTH_API short fluid_event_get_bank(fluid_event_t* evt); -FLUIDSYNTH_API int fluid_event_get_pitch(fluid_event_t* evt); -FLUIDSYNTH_API unsigned int fluid_event_get_sfont_id(fluid_event_t* evt); - -#ifdef __cplusplus -} -#endif -#endif /* _FLUIDSYNTH_EVENT_H */ diff --git a/headers/libs/fluidsynth/fluidsynth/gen.h b/headers/libs/fluidsynth/fluidsynth/gen.h deleted file mode 100644 index 055ea753f2..0000000000 --- a/headers/libs/fluidsynth/fluidsynth/gen.h +++ /dev/null @@ -1,135 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#ifndef _FLUIDSYNTH_GEN_H -#define _FLUIDSYNTH_GEN_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @file gen.h - * @brief Functions and defines for SoundFont generator effects. - */ - -/** - * Generator (effect) numbers (Soundfont 2.01 specifications section 8.1.3) - */ -enum fluid_gen_type { - GEN_STARTADDROFS, /**< Sample start address offset (0-32767) */ - GEN_ENDADDROFS, /**< Sample end address offset (-32767-0) */ - GEN_STARTLOOPADDROFS, /**< Sample loop start address offset (-32767-32767) */ - GEN_ENDLOOPADDROFS, /**< Sample loop end address offset (-32767-32767) */ - GEN_STARTADDRCOARSEOFS, /**< Sample start address coarse offset (X 32768) */ - GEN_MODLFOTOPITCH, /**< Modulation LFO to pitch */ - GEN_VIBLFOTOPITCH, /**< Vibrato LFO to pitch */ - GEN_MODENVTOPITCH, /**< Modulation envelope to pitch */ - GEN_FILTERFC, /**< Filter cutoff */ - GEN_FILTERQ, /**< Filter Q */ - GEN_MODLFOTOFILTERFC, /**< Modulation LFO to filter cutoff */ - GEN_MODENVTOFILTERFC, /**< Modulation envelope to filter cutoff */ - GEN_ENDADDRCOARSEOFS, /**< Sample end address coarse offset (X 32768) */ - GEN_MODLFOTOVOL, /**< Modulation LFO to volume */ - GEN_UNUSED1, /**< Unused */ - GEN_CHORUSSEND, /**< Chorus send amount */ - GEN_REVERBSEND, /**< Reverb send amount */ - GEN_PAN, /**< Stereo panning */ - GEN_UNUSED2, /**< Unused */ - GEN_UNUSED3, /**< Unused */ - GEN_UNUSED4, /**< Unused */ - GEN_MODLFODELAY, /**< Modulation LFO delay */ - GEN_MODLFOFREQ, /**< Modulation LFO frequency */ - GEN_VIBLFODELAY, /**< Vibrato LFO delay */ - GEN_VIBLFOFREQ, /**< Vibrato LFO frequency */ - GEN_MODENVDELAY, /**< Modulation envelope delay */ - GEN_MODENVATTACK, /**< Modulation envelope attack */ - GEN_MODENVHOLD, /**< Modulation envelope hold */ - GEN_MODENVDECAY, /**< Modulation envelope decay */ - GEN_MODENVSUSTAIN, /**< Modulation envelope sustain */ - GEN_MODENVRELEASE, /**< Modulation envelope release */ - GEN_KEYTOMODENVHOLD, /**< Key to modulation envelope hold */ - GEN_KEYTOMODENVDECAY, /**< Key to modulation envelope decay */ - GEN_VOLENVDELAY, /**< Volume envelope delay */ - GEN_VOLENVATTACK, /**< Volume envelope attack */ - GEN_VOLENVHOLD, /**< Volume envelope hold */ - GEN_VOLENVDECAY, /**< Volume envelope decay */ - GEN_VOLENVSUSTAIN, /**< Volume envelope sustain */ - GEN_VOLENVRELEASE, /**< Volume envelope release */ - GEN_KEYTOVOLENVHOLD, /**< Key to volume envelope hold */ - GEN_KEYTOVOLENVDECAY, /**< Key to volume envelope decay */ - GEN_INSTRUMENT, /**< Instrument ID (shouldn't be set by user) */ - GEN_RESERVED1, /**< Reserved */ - GEN_KEYRANGE, /**< MIDI note range */ - GEN_VELRANGE, /**< MIDI velocity range */ - GEN_STARTLOOPADDRCOARSEOFS, /**< Sample start loop address coarse offset (X 32768) */ - GEN_KEYNUM, /**< Fixed MIDI note number */ - GEN_VELOCITY, /**< Fixed MIDI velocity value */ - GEN_ATTENUATION, /**< Initial volume attenuation */ - GEN_RESERVED2, /**< Reserved */ - GEN_ENDLOOPADDRCOARSEOFS, /**< Sample end loop address coarse offset (X 32768) */ - GEN_COARSETUNE, /**< Coarse tuning */ - GEN_FINETUNE, /**< Fine tuning */ - GEN_SAMPLEID, /**< Sample ID (shouldn't be set by user) */ - GEN_SAMPLEMODE, /**< Sample mode flags */ - GEN_RESERVED3, /**< Reserved */ - GEN_SCALETUNE, /**< Scale tuning */ - GEN_EXCLUSIVECLASS, /**< Exclusive class number */ - GEN_OVERRIDEROOTKEY, /**< Sample root note override */ - - /* the initial pitch is not a "standard" generator. It is not - * mentioned in the list of generator in the SF2 specifications. It - * is used, however, as the destination for the default pitch wheel - * modulator. */ - GEN_PITCH, /**< Pitch (NOTE: Not a real SoundFont generator) */ - GEN_LAST /**< Value defines the count of generators (#fluid_gen_type) */ -}; - - -/** - * SoundFont generator structure. - */ -typedef struct _fluid_gen_t -{ - unsigned char flags; /**< Is the generator set or not (#fluid_gen_flags) */ - double val; /**< The nominal value */ - double mod; /**< Change by modulators */ - double nrpn; /**< Change by NRPN messages */ -} fluid_gen_t; - -/** - * Enum value for 'flags' field of #_fluid_gen_t (not really flags). - */ -enum fluid_gen_flags -{ - GEN_UNUSED, /**< Generator value is not set */ - GEN_SET, /**< Generator value is set */ - GEN_ABS_NRPN /**< DOCME */ -}; - -FLUIDSYNTH_API int fluid_gen_set_default_values(fluid_gen_t* gen); - - - -#ifdef __cplusplus -} -#endif -#endif /* _FLUIDSYNTH_GEN_H */ - diff --git a/headers/libs/fluidsynth/fluidsynth/log.h b/headers/libs/fluidsynth/fluidsynth/log.h deleted file mode 100644 index 51fdebecec..0000000000 --- a/headers/libs/fluidsynth/fluidsynth/log.h +++ /dev/null @@ -1,83 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#ifndef _FLUIDSYNTH_LOG_H -#define _FLUIDSYNTH_LOG_H - - -#ifdef __cplusplus -extern "C" { -#endif - - -/** - * @file log.h - * @brief Logging interface - * - * The default logging function of the fluidsynth prints its messages - * to the stderr. The synthesizer uses five level of messages: #FLUID_PANIC, - * #FLUID_ERR, #FLUID_WARN, #FLUID_INFO, and #FLUID_DBG. - * - * A client application can install a new log function to handle the - * messages differently. In the following example, the application - * sets a callback function to display #FLUID_PANIC messages in a dialog, - * and ignores all other messages by setting the log function to - * NULL: - * - * DOCME (formatting) - * fluid_set_log_function(FLUID_PANIC, show_dialog, (void*) root_window); - * fluid_set_log_function(FLUID_ERR, NULL, NULL); - * fluid_set_log_function(FLUID_WARN, NULL, NULL); - * fluid_set_log_function(FLUID_DBG, NULL, NULL); - */ - -/** - * FluidSynth log levels. - */ -enum fluid_log_level { - FLUID_PANIC, /**< The synth can't function correctly any more */ - FLUID_ERR, /**< Serious error occurred */ - FLUID_WARN, /**< Warning */ - FLUID_INFO, /**< Verbose informational messages */ - FLUID_DBG, /**< Debugging messages */ - LAST_LOG_LEVEL -}; - -/** - * Log function handler callback type used by fluid_set_log_function(). - * @param level Log level (#fluid_log_level) - * @param message Log message text - * @param data User data pointer supplied to fluid_set_log_function(). - */ -typedef void (*fluid_log_function_t)(int level, char* message, void* data); - -FLUIDSYNTH_API -fluid_log_function_t fluid_set_log_function(int level, fluid_log_function_t fun, void* data); - -FLUIDSYNTH_API void fluid_default_log_function(int level, char* message, void* data); - -FLUIDSYNTH_API int fluid_log(int level, char * fmt, ...); - - -#ifdef __cplusplus -} -#endif - -#endif /* _FLUIDSYNTH_LOG_H */ diff --git a/headers/libs/fluidsynth/fluidsynth/midi.h b/headers/libs/fluidsynth/fluidsynth/midi.h deleted file mode 100644 index 822c56c1e1..0000000000 --- a/headers/libs/fluidsynth/fluidsynth/midi.h +++ /dev/null @@ -1,118 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#ifndef _FLUIDSYNTH_MIDI_H -#define _FLUIDSYNTH_MIDI_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @file midi.h - * @brief Functions for MIDI events, drivers and MIDI file playback. - */ - -FLUIDSYNTH_API fluid_midi_event_t* new_fluid_midi_event(void); -FLUIDSYNTH_API int delete_fluid_midi_event(fluid_midi_event_t* event); - -FLUIDSYNTH_API int fluid_midi_event_set_type(fluid_midi_event_t* evt, int type); -FLUIDSYNTH_API int fluid_midi_event_get_type(fluid_midi_event_t* evt); -FLUIDSYNTH_API int fluid_midi_event_set_channel(fluid_midi_event_t* evt, int chan); -FLUIDSYNTH_API int fluid_midi_event_get_channel(fluid_midi_event_t* evt); -FLUIDSYNTH_API int fluid_midi_event_get_key(fluid_midi_event_t* evt); -FLUIDSYNTH_API int fluid_midi_event_set_key(fluid_midi_event_t* evt, int key); -FLUIDSYNTH_API int fluid_midi_event_get_velocity(fluid_midi_event_t* evt); -FLUIDSYNTH_API int fluid_midi_event_set_velocity(fluid_midi_event_t* evt, int vel); -FLUIDSYNTH_API int fluid_midi_event_get_control(fluid_midi_event_t* evt); -FLUIDSYNTH_API int fluid_midi_event_set_control(fluid_midi_event_t* evt, int ctrl); -FLUIDSYNTH_API int fluid_midi_event_get_value(fluid_midi_event_t* evt); -FLUIDSYNTH_API int fluid_midi_event_set_value(fluid_midi_event_t* evt, int val); -FLUIDSYNTH_API int fluid_midi_event_get_program(fluid_midi_event_t* evt); -FLUIDSYNTH_API int fluid_midi_event_set_program(fluid_midi_event_t* evt, int val); -FLUIDSYNTH_API int fluid_midi_event_get_pitch(fluid_midi_event_t* evt); -FLUIDSYNTH_API int fluid_midi_event_set_pitch(fluid_midi_event_t* evt, int val); - - -/** - * Generic callback function for MIDI events. - * @param data User defined data pointer - * @param event The MIDI event - * @return DOCME - * - * Will be used between - * - MIDI driver and MIDI router - * - MIDI router and synth - * to communicate events. - * In the not-so-far future... - */ -typedef int (*handle_midi_event_func_t)(void* data, fluid_midi_event_t* event); - -/* - * MIDI router - * - * The MIDI handler forwards incoming MIDI events to the synthesizer - */ - -FLUIDSYNTH_API fluid_midi_router_t* new_fluid_midi_router(fluid_settings_t* settings, - handle_midi_event_func_t handler, - void* event_handler_data); - -FLUIDSYNTH_API int delete_fluid_midi_router(fluid_midi_router_t* handler); -FLUIDSYNTH_API int fluid_midi_router_handle_midi_event(void* data, fluid_midi_event_t* event); -FLUIDSYNTH_API int fluid_midi_dump_prerouter(void* data, fluid_midi_event_t* event); -FLUIDSYNTH_API int fluid_midi_dump_postrouter(void* data, fluid_midi_event_t* event); - -/* - * MIDI driver - * - * The MIDI handler forwards incoming MIDI events to the synthesizer - */ - -FLUIDSYNTH_API -fluid_midi_driver_t* new_fluid_midi_driver(fluid_settings_t* settings, - handle_midi_event_func_t handler, - void* event_handler_data); - -FLUIDSYNTH_API void delete_fluid_midi_driver(fluid_midi_driver_t* driver); - - - -/* - * MIDI file player - * - * The MIDI player allows you to play MIDI files with the FLUID Synth - */ - -FLUIDSYNTH_API fluid_player_t* new_fluid_player(fluid_synth_t* synth); -FLUIDSYNTH_API int delete_fluid_player(fluid_player_t* player); -FLUIDSYNTH_API int fluid_player_add(fluid_player_t* player, char* midifile); -FLUIDSYNTH_API int fluid_player_play(fluid_player_t* player); -FLUIDSYNTH_API int fluid_player_stop(fluid_player_t* player); -FLUIDSYNTH_API int fluid_player_join(fluid_player_t* player); -FLUIDSYNTH_API int fluid_player_set_loop(fluid_player_t* player, int loop); -FLUIDSYNTH_API int fluid_player_set_midi_tempo(fluid_player_t* player, int tempo); -FLUIDSYNTH_API int fluid_player_set_bpm(fluid_player_t* player, int bpm); - -#ifdef __cplusplus -} -#endif - -#endif /* _FLUIDSYNTH_MIDI_H */ diff --git a/headers/libs/fluidsynth/fluidsynth/misc.h b/headers/libs/fluidsynth/fluidsynth/misc.h deleted file mode 100644 index b7d4fdf7ad..0000000000 --- a/headers/libs/fluidsynth/fluidsynth/misc.h +++ /dev/null @@ -1,65 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#ifndef _FLUIDSYNTH_MISC_H -#define _FLUIDSYNTH_MISC_H - - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * - * Utility functions - */ - -/** - * fluid_is_soundfont returns 1 if the specified filename is a - * soundfont. It retuns 0 otherwise. The current implementation only - * checks for the "RIFF" header in the file. It is useful only to - * distinguish between SoundFonts and MIDI files. - */ -FLUIDSYNTH_API int fluid_is_soundfont(char* filename); - -/** - * fluid_is_midifile returns 1 if the specified filename is a MIDI - * file. It retuns 0 otherwise. The current implementation only checks - * for the "MThd" header in the file. - */ -FLUIDSYNTH_API int fluid_is_midifile(char* filename); - - - - -#ifdef WIN32 -/** Set the handle to the instance of the application on the Windows - platform. The handle is needed to open DirectSound. */ -FLUIDSYNTH_API void* fluid_get_hinstance(void); -FLUIDSYNTH_API void fluid_set_hinstance(void* hinstance); -#endif - - -#ifdef __cplusplus -} -#endif - -#endif /* _FLUIDSYNTH_MISC_H */ diff --git a/headers/libs/fluidsynth/fluidsynth/mod.h b/headers/libs/fluidsynth/fluidsynth/mod.h deleted file mode 100644 index 5fe86cda65..0000000000 --- a/headers/libs/fluidsynth/fluidsynth/mod.h +++ /dev/null @@ -1,112 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#ifndef _FLUIDSYNTH_MOD_H -#define _FLUIDSYNTH_MOD_H - -#ifdef __cplusplus -extern "C" { -#endif - - /* Modulator-related definitions */ - - /* Maximum number of modulators in a voice */ -#define FLUID_NUM_MOD 64 - - /* - * fluid_mod_t - */ -struct _fluid_mod_t -{ - unsigned char dest; - unsigned char src1; - unsigned char flags1; - unsigned char src2; - unsigned char flags2; - double amount; - /* The 'next' field allows to link modulators into a list. It is - * not used in fluid_voice.c, there each voice allocates memory for a - * fixed number of modulators. Since there may be a huge number of - * different zones, this is more efficient. - */ - fluid_mod_t * next; -}; - -/* Flags telling the polarity of a modulator. Compare with SF2.01 - section 8.2. Note: The numbers of the bits are different! (for - example: in the flags of a SF modulator, the polarity bit is bit - nr. 9) */ -enum fluid_mod_flags -{ - FLUID_MOD_POSITIVE = 0, - FLUID_MOD_NEGATIVE = 1, - FLUID_MOD_UNIPOLAR = 0, - FLUID_MOD_BIPOLAR = 2, - FLUID_MOD_LINEAR = 0, - FLUID_MOD_CONCAVE = 4, - FLUID_MOD_CONVEX = 8, - FLUID_MOD_SWITCH = 12, - FLUID_MOD_GC = 0, - FLUID_MOD_CC = 16 -}; - -/* Flags telling the source of a modulator. This corresponds to - * SF2.01 section 8.2.1 */ -enum fluid_mod_src -{ - FLUID_MOD_NONE = 0, - FLUID_MOD_VELOCITY = 2, - FLUID_MOD_KEY = 3, - FLUID_MOD_KEYPRESSURE = 10, - FLUID_MOD_CHANNELPRESSURE = 13, - FLUID_MOD_PITCHWHEEL = 14, - FLUID_MOD_PITCHWHEELSENS = 16 -}; - -/* Allocates memory for a new modulator */ -FLUIDSYNTH_API fluid_mod_t * fluid_mod_new(void); - -/* Frees the modulator */ -FLUIDSYNTH_API void fluid_mod_delete(fluid_mod_t * mod); - - -FLUIDSYNTH_API void fluid_mod_set_source1(fluid_mod_t* mod, int src, int flags); -FLUIDSYNTH_API void fluid_mod_set_source2(fluid_mod_t* mod, int src, int flags); -FLUIDSYNTH_API void fluid_mod_set_dest(fluid_mod_t* mod, int dst); -FLUIDSYNTH_API void fluid_mod_set_amount(fluid_mod_t* mod, double amount); - -FLUIDSYNTH_API int fluid_mod_get_source1(fluid_mod_t* mod); -FLUIDSYNTH_API int fluid_mod_get_flags1(fluid_mod_t* mod); -FLUIDSYNTH_API int fluid_mod_get_source2(fluid_mod_t* mod); -FLUIDSYNTH_API int fluid_mod_get_flags2(fluid_mod_t* mod); -FLUIDSYNTH_API int fluid_mod_get_dest(fluid_mod_t* mod); -FLUIDSYNTH_API double fluid_mod_get_amount(fluid_mod_t* mod); - - -/* Determines, if two modulators are 'identical' (all parameters - except the amount match) */ -FLUIDSYNTH_API int fluid_mod_test_identity(fluid_mod_t * mod1, fluid_mod_t * mod2); - - -#ifdef __cplusplus -} -#endif -#endif /* _FLUIDSYNTH_MOD_H */ - diff --git a/headers/libs/fluidsynth/fluidsynth/ramsfont.h b/headers/libs/fluidsynth/fluidsynth/ramsfont.h deleted file mode 100644 index 75a8d6761a..0000000000 --- a/headers/libs/fluidsynth/fluidsynth/ramsfont.h +++ /dev/null @@ -1,113 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#ifndef _FLUIDSYNTH_RAMSFONT_H -#define _FLUIDSYNTH_RAMSFONT_H - -#ifdef __cplusplus -extern "C" { -#endif - - -/********************************************************************************/ -/********************************************************************************/ -/* ram soundfonts: - October 2002 - Antoine Schmitt - - ram soundfonts live in ram. The samples are loaded from files - or from RAM. A minimal API manages a soundFont structure, - with presets, each preset having only one preset-zone, which - instrument has potentially many instrument-zones. No global - zones, and nor generator nor modulator other than the default - ones are permitted. This may be extensible in the future. -*/ -/********************************************************************************/ -/********************************************************************************/ - -/* - We are not using the sfloader protocol, as we need more arguments - than what it provides. -*/ - -/** Creates a fluid_sfont_t wrapping an fluid_ramsfont_t */ -FLUIDSYNTH_API fluid_sfont_t* fluid_ramsfont_create_sfont(void); - -/*********************** - * ramsfont specific API - ***********************/ -FLUIDSYNTH_API int fluid_ramsfont_set_name(fluid_ramsfont_t* sfont, char * name); - -/* Creates one instrument zone for the sample inside the preset defined - * by bank/num - * \returns 0 if success - */ -FLUIDSYNTH_API -int fluid_ramsfont_add_izone(fluid_ramsfont_t* sfont, - unsigned int bank, unsigned int num, fluid_sample_t* sample, - int lokey, int hikey); - -/* Removes the instrument zone corresponding to bank/num and to the sample - * \returns 0 if success - */ -FLUIDSYNTH_API -int fluid_ramsfont_remove_izone(fluid_ramsfont_t* sfont, - unsigned int bank, unsigned int num, fluid_sample_t* sample); - -/* Sets a generator on an instrument zone - * \returns 0 if success - */ -FLUIDSYNTH_API -int fluid_ramsfont_izone_set_gen(fluid_ramsfont_t* sfont, - unsigned int bank, unsigned int num, fluid_sample_t* sample, - int gen_type, float value); - -/* Utility : sets the loop start/end values - * \on = 0 or 1; if 0, loopstart and loopend are not used - * \loopstart and loopend are floats, in frames - * \loopstart is counted from frame 0 - * \loopend is counted from the last frame, thus is < 0 - * \returns 0 if success - */ -FLUIDSYNTH_API -int fluid_ramsfont_izone_set_loop(fluid_ramsfont_t* sfont, - unsigned int bank, unsigned int num, fluid_sample_t* sample, - int on, float loopstart, float loopend); - -/*************************************** - * sample_t specific API for ramsfont - ***************************************/ -FLUIDSYNTH_API fluid_sample_t* new_fluid_ramsample(void); -FLUIDSYNTH_API int delete_fluid_ramsample(fluid_sample_t* sample); -FLUIDSYNTH_API int fluid_sample_set_name(fluid_sample_t* sample, char * name); - -/* Sets the sound data of the sample - * Warning : if copy_data is FALSE, data should have 8 unused frames at start - * and 8 unused frames at the end. - */ -FLUIDSYNTH_API -int fluid_sample_set_sound_data(fluid_sample_t* sample, short *data, - unsigned int nbframes, short copy_data, int rootkey); - - -#ifdef __cplusplus -} -#endif - -#endif /* _FLUIDSYNTH_RAMSFONT_H */ diff --git a/headers/libs/fluidsynth/fluidsynth/seq.h b/headers/libs/fluidsynth/fluidsynth/seq.h deleted file mode 100644 index 25ab0598b6..0000000000 --- a/headers/libs/fluidsynth/fluidsynth/seq.h +++ /dev/null @@ -1,109 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#ifndef _FLUIDSYNTH_SEQ_H -#define _FLUIDSYNTH_SEQ_H - -#ifdef __cplusplus -extern "C" { -#endif - - -typedef void (*fluid_event_callback_t)(unsigned int time, fluid_event_t* event, - fluid_sequencer_t* seq, void* data); - - -/** Allocate a new sequencer structure */ -FLUIDSYNTH_API fluid_sequencer_t* new_fluid_sequencer(void); - -/** Free the sequencer structure */ -FLUIDSYNTH_API void delete_fluid_sequencer(fluid_sequencer_t* seq); - -/** clients can be sources or destinations of events. These functions ensure a unique ID for any -source or dest, for filtering purposes. -sources only dont need to register a callback. -*/ - -/** Register a client. The registration returns a unique client ID (-1 if error) */ -FLUIDSYNTH_API -short fluid_sequencer_register_client(fluid_sequencer_t* seq, char* name, - fluid_event_callback_t callback, void* data); - -/** Unregister a previously registered client. */ -FLUIDSYNTH_API void fluid_sequencer_unregister_client(fluid_sequencer_t* seq, short id); - -/** Returns the number of register clients. */ -FLUIDSYNTH_API int fluid_sequencer_count_clients(fluid_sequencer_t* seq); - -/** Returns the id of a registered client (-1 if non existing) */ -FLUIDSYNTH_API short fluid_sequencer_get_client_id(fluid_sequencer_t* seq, int index); - -/** Returns the name of a registered client, given its id. */ -FLUIDSYNTH_API char* fluid_sequencer_get_client_name(fluid_sequencer_t* seq, int id); - -/** Returns 1 if client is a destination (has a callback) */ -FLUIDSYNTH_API int fluid_sequencer_client_is_dest(fluid_sequencer_t* seq, int id); - - - -/** Sending an event immediately. */ -FLUIDSYNTH_API void fluid_sequencer_send_now(fluid_sequencer_t* seq, fluid_event_t* evt); - - -/** Schedule an event for later sending. If absolute is 0, the time of - the event will be offset with the current tick of the - sequencer. If absolute is different from 0, the time will assumed - to be absolute (starting from the creation of the sequencer). - MAKES A COPY */ -FLUIDSYNTH_API -int fluid_sequencer_send_at(fluid_sequencer_t* seq, fluid_event_t* evt, - unsigned int time, int absolute); - -/** Remove events from the event queue. The events can be filtered on - the source, the destination, and the type of the event. To avoid - filtering, set either source, dest, or type to -1. */ -FLUIDSYNTH_API -void fluid_sequencer_remove_events(fluid_sequencer_t* seq, short source, short dest, int type); - - -/** Get the current tick */ -FLUIDSYNTH_API unsigned int fluid_sequencer_get_tick(fluid_sequencer_t* seq); - -/** Set the conversion from tick to absolute time. scale should be - expressed as ticks per second. */ -FLUIDSYNTH_API void fluid_sequencer_set_time_scale(fluid_sequencer_t* seq, double scale); - -/** Set the conversion from tick to absolute time (ticks per - second). */ -FLUIDSYNTH_API double fluid_sequencer_get_time_scale(fluid_sequencer_t* seq); - -// compile in internal traceing functions -#define FLUID_SEQ_WITH_TRACE 0 - -#if FLUID_SEQ_WITH_TRACE -FLUIDSYNTH_API char * fluid_seq_gettrace(fluid_sequencer_t* seq); -FLUIDSYNTH_API void fluid_seq_cleartrace(fluid_sequencer_t* seq); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* _FLUIDSYNTH_SEQ_H */ diff --git a/headers/libs/fluidsynth/fluidsynth/seqbind.h b/headers/libs/fluidsynth/fluidsynth/seqbind.h deleted file mode 100644 index 09fb46ac55..0000000000 --- a/headers/libs/fluidsynth/fluidsynth/seqbind.h +++ /dev/null @@ -1,44 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#ifndef _FLUIDSYNTH_SEQBIND_H -#define _FLUIDSYNTH_SEQBIND_H - -#include "fluidsynth/seq.h" - -#ifdef __cplusplus -extern "C" { -#endif - - /** registers fluidsynth as a client of the given sequencer. - The fluidsynth is registered with the name "fluidsynth". - - \returns the fluidsynth destID. - */ -FLUIDSYNTH_API -short fluid_sequencer_register_fluidsynth(fluid_sequencer_t* seq, fluid_synth_t* synth); - - - -#ifdef __cplusplus -} -#endif -#endif /* _FLUIDSYNTH_SEQBIND_H */ - diff --git a/headers/libs/fluidsynth/fluidsynth/settings.h b/headers/libs/fluidsynth/fluidsynth/settings.h deleted file mode 100644 index 61f0431368..0000000000 --- a/headers/libs/fluidsynth/fluidsynth/settings.h +++ /dev/null @@ -1,223 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#ifndef _FLUIDSYNTH_SETTINGS_H -#define _FLUIDSYNTH_SETTINGS_H - -#ifdef __cplusplus -extern "C" { -#endif - - /** - * - * Synthesizer settings - * - * - * The create a synthesizer object you will have to specify its - * settings. These settings are stored in the structure below. - - * void my_synthesizer() - * { - * fluid_settings_t* settings; - * fluid_synth_t* synth; - * fluid_audio_driver_t* adriver; - * - * - * settings = new_fluid_settings(); - * fluid_settings_setstr(settings, "audio.driver", "alsa"); - * // ... change settings ... - * synth = new_fluid_synth(settings); - * adriver = new_fluid_audio_driver(settings, synth); - * - * ... - * - * } - * - * - */ - - - - -/* Hint FLUID_HINT_BOUNDED_BELOW indicates that the LowerBound field - of the FLUID_PortRangeHint should be considered meaningful. The - value in this field should be considered the (inclusive) lower - bound of the valid range. If FLUID_HINT_SAMPLE_RATE is also - specified then the value of LowerBound should be multiplied by the - sample rate. */ -#define FLUID_HINT_BOUNDED_BELOW 0x1 - -/* Hint FLUID_HINT_BOUNDED_ABOVE indicates that the UpperBound field - of the FLUID_PortRangeHint should be considered meaningful. The - value in this field should be considered the (inclusive) upper - bound of the valid range. If FLUID_HINT_SAMPLE_RATE is also - specified then the value of UpperBound should be multiplied by the - sample rate. */ -#define FLUID_HINT_BOUNDED_ABOVE 0x2 - -/* Hint FLUID_HINT_TOGGLED indicates that the data item should be - considered a Boolean toggle. Data less than or equal to zero should - be considered `off' or `false,' and data above zero should be - considered `on' or `true.' FLUID_HINT_TOGGLED may not be used in - conjunction with any other hint except FLUID_HINT_DEFAULT_0 or - FLUID_HINT_DEFAULT_1. */ -#define FLUID_HINT_TOGGLED 0x4 - -/* Hint FLUID_HINT_SAMPLE_RATE indicates that any bounds specified - should be interpreted as multiples of the sample rate. For - instance, a frequency range from 0Hz to the Nyquist frequency (half - the sample rate) could be requested by this hint in conjunction - with LowerBound = 0 and UpperBound = 0.5. Hosts that support bounds - at all must support this hint to retain meaning. */ -#define FLUID_HINT_SAMPLE_RATE 0x8 - -/* Hint FLUID_HINT_LOGARITHMIC indicates that it is likely that the - user will find it more intuitive to view values using a logarithmic - scale. This is particularly useful for frequencies and gains. */ -#define FLUID_HINT_LOGARITHMIC 0x10 - -/* Hint FLUID_HINT_INTEGER indicates that a user interface would - probably wish to provide a stepped control taking only integer - values. Any bounds set should be slightly wider than the actual - integer range required to avoid floating point rounding errors. For - instance, the integer set {0,1,2,3} might be described as [-0.1, - 3.1]. */ -#define FLUID_HINT_INTEGER 0x20 - - -#define FLUID_HINT_FILENAME 0x01 -#define FLUID_HINT_OPTIONLIST 0x02 - - - -enum fluid_types_enum { - FLUID_NO_TYPE = -1, - FLUID_NUM_TYPE, - FLUID_INT_TYPE, - FLUID_STR_TYPE, - FLUID_SET_TYPE -}; - - -FLUIDSYNTH_API fluid_settings_t* new_fluid_settings(void); -FLUIDSYNTH_API void delete_fluid_settings(fluid_settings_t* settings); - - - -FLUIDSYNTH_API -int fluid_settings_get_type(fluid_settings_t* settings, char* name); - -FLUIDSYNTH_API -int fluid_settings_get_hints(fluid_settings_t* settings, char* name); - -/** Returns whether the setting is changeable in real-time. */ -FLUIDSYNTH_API int fluid_settings_is_realtime(fluid_settings_t* settings, char* name); - - -/** returns 1 if the value has been set, 0 otherwise */ -FLUIDSYNTH_API -int fluid_settings_setstr(fluid_settings_t* settings, char* name, char* str); - -/** - Get the value of a string setting. If the value does not exists, - 'str' is set to NULL. Otherwise, 'str' will point to the - value. The application does not own the returned value. Instead, - the application should make a copy of the value if it needs it - later. - - \returns 1 if the value exists, 0 otherwise -*/ -FLUIDSYNTH_API -int fluid_settings_getstr(fluid_settings_t* settings, char* name, char** str); - -/** Get the default value of a string setting. */ -FLUIDSYNTH_API -char* fluid_settings_getstr_default(fluid_settings_t* settings, char* name); - -/** Get the value of a numeric setting. - - \returns 1 if the value exists and is equal to 'value', 0 - otherwise -*/ -FLUIDSYNTH_API -int fluid_settings_str_equal(fluid_settings_t* settings, char* name, char* value); - - -/** returns 1 if the value has been set, 0 otherwise */ -FLUIDSYNTH_API -int fluid_settings_setnum(fluid_settings_t* settings, char* name, double val); - -/** returns 1 if the value exists, 0 otherwise */ -FLUIDSYNTH_API -int fluid_settings_getnum(fluid_settings_t* settings, char* name, double* val); - -/** Get the default value of a string setting. */ -FLUIDSYNTH_API -double fluid_settings_getnum_default(fluid_settings_t* settings, char* name); - -/** Get the range of values of a numeric settings. */ -FLUIDSYNTH_API -void fluid_settings_getnum_range(fluid_settings_t* settings, char* name, - double* min, double* max); - - -/** returns 1 if the value has been set, 0 otherwise */ -FLUIDSYNTH_API -int fluid_settings_setint(fluid_settings_t* settings, char* name, int val); - -/** returns 1 if the value exists, 0 otherwise */ -FLUIDSYNTH_API -int fluid_settings_getint(fluid_settings_t* settings, char* name, int* val); - -/** Get the default value of a string setting. */ -FLUIDSYNTH_API -int fluid_settings_getint_default(fluid_settings_t* settings, char* name); - -/** Get the range of values of a numeric settings. */ -FLUIDSYNTH_API -void fluid_settings_getint_range(fluid_settings_t* settings, char* name, - int* min, int* max); - - - -typedef void (*fluid_settings_foreach_option_t)(void* data, char* name, char* option); - - - -FLUIDSYNTH_API -void fluid_settings_foreach_option(fluid_settings_t* settings, - char* name, void* data, - fluid_settings_foreach_option_t func); - - -typedef void (*fluid_settings_foreach_t)(void* data, char* s, int type); - -FLUIDSYNTH_API -void fluid_settings_foreach(fluid_settings_t* settings, void* data, - fluid_settings_foreach_t func); - - - - -#ifdef __cplusplus -} -#endif - -#endif /* _FLUIDSYNTH_SETTINGS_H */ diff --git a/headers/libs/fluidsynth/fluidsynth/sfont.h b/headers/libs/fluidsynth/fluidsynth/sfont.h deleted file mode 100644 index 84020ba305..0000000000 --- a/headers/libs/fluidsynth/fluidsynth/sfont.h +++ /dev/null @@ -1,193 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#ifndef _FLUIDSYNTH_SFONT_H -#define _FLUIDSYNTH_SFONT_H - -#ifdef __cplusplus -extern "C" { -#endif - - - - /** - * - * SoundFont plugins - * - * It is possible to add new SoundFont loaders to the - * synthesizer. The API uses a couple of "interfaces" (structures - * with callback functions): fluid_sfloader_t, fluid_sfont_t, and - * fluid_preset_t. - * - * To add a new SoundFont loader to the synthesizer, call - * fluid_synth_add_sfloader() and pass a pointer to an - * fluid_sfloader_t structure. The important callback function in - * this structure is "load", which should try to load a file and - * returns a fluid_sfont_t structure, or NULL if it fails. - * - * The fluid_sfont_t structure contains a callback to obtain the - * name of the soundfont. It contains two functions to iterate - * though the contained presets, and one function to obtain a - * preset corresponding to a bank and preset number. This - * function should return an fluid_preset_t structure. - * - * The fluid_preset_t structure contains some functions to obtain - * information from the preset (name, bank, number). The most - * important callback is the noteon function. The noteon function - * should call fluid_synth_alloc_voice() for every sample that has - * to be played. fluid_synth_alloc_voice() expects a pointer to a - * fluid_sample_t structure and returns a pointer to the opaque - * fluid_voice_t structure. To set or increments the values of a - * generator, use fluid_voice_gen_{set,incr}. When you are - * finished initializing the voice call fluid_voice_start() to - * start playing the synthesis voice. - * */ - - enum { - FLUID_PRESET_SELECTED, - FLUID_PRESET_UNSELECTED, - FLUID_SAMPLE_DONE - }; - - -/* - * fluid_sfloader_t - */ - -struct _fluid_sfloader_t { - /** Private data */ - void* data; - - /** The free must free the memory allocated for the loader in - * addition to any private data. It should return 0 if no error - * occured, non-zero otherwise.*/ - int (*free)(fluid_sfloader_t* loader); - - /** Load a file. Returns NULL if an error occured. */ - fluid_sfont_t* (*load)(fluid_sfloader_t* loader, const char* filename); -}; - - -/* - * fluid_sfont_t - */ - -struct _fluid_sfont_t { - void* data; - unsigned int id; - - /** The 'free' callback function should return 0 when it was able to - free all resources. It should return a non-zero value if some of - the samples could not be freed because they are still in use. */ - int (*free)(fluid_sfont_t* sfont); - - /** Return the name of the sfont */ - char* (*get_name)(fluid_sfont_t* sfont); - - /** Return the preset with the specified bank and preset number. All - * the fields, including the 'sfont' field, should * be filled - * in. If the preset cannot be found, the function returns NULL. */ - fluid_preset_t* (*get_preset)(fluid_sfont_t* sfont, unsigned int bank, unsigned int prenum); - - void (*iteration_start)(fluid_sfont_t* sfont); - - /* return 0 when no more presets are available, 1 otherwise */ - int (*iteration_next)(fluid_sfont_t* sfont, fluid_preset_t* preset); -}; - -#define fluid_sfont_get_id(_sf) ((_sf)->id) - - -/* - * fluid_preset_t - */ - -struct _fluid_preset_t { - void* data; - fluid_sfont_t* sfont; - int (*free)(fluid_preset_t* preset); - char* (*get_name)(fluid_preset_t* preset); - int (*get_banknum)(fluid_preset_t* preset); - int (*get_num)(fluid_preset_t* preset); - - /** handle a noteon event. Returns 0 if no error occured. */ - int (*noteon)(fluid_preset_t* preset, fluid_synth_t* synth, int chan, int key, int vel); - - /** Implement this function if the preset needs to be notified about - preset select and unselect events. */ - int (*notify)(fluid_preset_t* preset, int reason, int chan); -}; - - -/* - * fluid_sample_t - */ - -struct _fluid_sample_t -{ - char name[21]; - unsigned int start; - unsigned int end; /* Note: Index of last valid sample point (contrary to SF spec) */ - unsigned int loopstart; - unsigned int loopend; /* Note: first point following the loop (superimposed on loopstart) */ - unsigned int samplerate; - int origpitch; - int pitchadj; - int sampletype; - int valid; - short* data; - - /** The amplitude, that will lower the level of the sample's loop to - the noise floor. Needed for note turnoff optimization, will be - filled out automatically */ - /* Set this to zero, when submitting a new sample. */ - int amplitude_that_reaches_noise_floor_is_valid; - double amplitude_that_reaches_noise_floor; - - /** Count the number of playing voices that use this sample. */ - unsigned int refcount; - - /** Implement this function if the sample or SoundFont needs to be - notified when the sample is no longer used. */ - int (*notify)(fluid_sample_t* sample, int reason); - - /** Pointer to SoundFont specific data */ - void* userdata; -}; - - -#define fluid_sample_refcount(_sample) ((_sample)->refcount) - - -/** Sample types */ - -#define FLUID_SAMPLETYPE_MONO 1 -#define FLUID_SAMPLETYPE_RIGHT 2 -#define FLUID_SAMPLETYPE_LEFT 4 -#define FLUID_SAMPLETYPE_LINKED 8 -#define FLUID_SAMPLETYPE_ROM 0x8000 - - - -#ifdef __cplusplus -} -#endif - -#endif /* _FLUIDSYNTH_SFONT_H */ diff --git a/headers/libs/fluidsynth/fluidsynth/shell.h b/headers/libs/fluidsynth/fluidsynth/shell.h deleted file mode 100644 index 58151a849d..0000000000 --- a/headers/libs/fluidsynth/fluidsynth/shell.h +++ /dev/null @@ -1,137 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#ifndef _FLUIDSYNTH_SHELL_H -#define _FLUIDSYNTH_SHELL_H - - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * - * Shell interface - * - * The shell interface allows you to send simple textual commands to - * the synthesizer, to parse a command file, or to read commands - * from the stdin or other input streams. - * - * To find the list of currently supported commands, please check the - * fluid_cmd.c file. - * - */ - -FLUIDSYNTH_API fluid_istream_t fluid_get_stdin(void); -FLUIDSYNTH_API fluid_ostream_t fluid_get_stdout(void); - -FLUIDSYNTH_API char* fluid_get_userconf(char* buf, int len); -FLUIDSYNTH_API char* fluid_get_sysconf(char* buf, int len); - - -/** The command structure */ - -typedef int (*fluid_cmd_func_t)(void* data, int ac, char** av, fluid_ostream_t out); - -typedef struct { - char* name; /** The name of the command, as typed in in the shell */ - char* topic; /** The help topic group of this command */ - fluid_cmd_func_t handler; /** Pointer to the handler for this command */ - void* data; /** Pointer to the user data */ - char* help; /** A help string */ -} fluid_cmd_t; - - -/** The command handler */ - -/** - Create a new command handler. If the synth object passed as - argument is not NULL, the handler will add all the default - synthesizer commands to the command list. - - \param synth The synthesizer object - \returns A new command handler -*/ -FLUIDSYNTH_API -fluid_cmd_handler_t* new_fluid_cmd_handler(fluid_synth_t* synth); - -FLUIDSYNTH_API -void delete_fluid_cmd_handler(fluid_cmd_handler_t* handler); - -FLUIDSYNTH_API -void fluid_cmd_handler_set_synth(fluid_cmd_handler_t* handler, fluid_synth_t* synth); - -/** - Register a new command to the handler. The handler makes a private - copy of the 'cmd' structure passed as argument. - - \param handler A pointer to the command handler - \param cmd A pointer to the command structure - \returns 0 if the command was inserted, non-zero if error -*/ -FLUIDSYNTH_API -int fluid_cmd_handler_register(fluid_cmd_handler_t* handler, fluid_cmd_t* cmd); - -FLUIDSYNTH_API -int fluid_cmd_handler_unregister(fluid_cmd_handler_t* handler, char* cmd); - - -/** Command function */ - -FLUIDSYNTH_API -int fluid_command(fluid_cmd_handler_t* handler, char* cmd, fluid_ostream_t out); - -FLUIDSYNTH_API -int fluid_source(fluid_cmd_handler_t* handler, char* filename); - -FLUIDSYNTH_API -void fluid_usershell(fluid_settings_t* settings, fluid_cmd_handler_t* handler); - - -/** Shell */ - -FLUIDSYNTH_API -fluid_shell_t* new_fluid_shell(fluid_settings_t* settings, fluid_cmd_handler_t* handler, - fluid_istream_t in, fluid_ostream_t out, int thread); - -FLUIDSYNTH_API void delete_fluid_shell(fluid_shell_t* shell); - - - -/** TCP/IP server */ - -typedef fluid_cmd_handler_t* (*fluid_server_newclient_func_t)(void* data, char* addr); - -FLUIDSYNTH_API -fluid_server_t* new_fluid_server(fluid_settings_t* settings, - fluid_server_newclient_func_t func, - void* data); - -FLUIDSYNTH_API void delete_fluid_server(fluid_server_t* server); - -FLUIDSYNTH_API int fluid_server_join(fluid_server_t* server); - - -#ifdef __cplusplus -} -#endif - -#endif /* _FLUIDSYNTH_SHELL_H */ diff --git a/headers/libs/fluidsynth/fluidsynth/synth.h b/headers/libs/fluidsynth/fluidsynth/synth.h deleted file mode 100644 index 912e4c5601..0000000000 --- a/headers/libs/fluidsynth/fluidsynth/synth.h +++ /dev/null @@ -1,700 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#ifndef _FLUIDSYNTH_SYNTH_H -#define _FLUIDSYNTH_SYNTH_H - - -#ifdef __cplusplus -extern "C" { -#endif - - - /** Embedded synthesizer - * - * You create a new synthesizer with new_fluid_synth() and you destroy - * if with delete_fluid_synth(). Use the settings structure to specify - * the synthesizer characteristics. - * - * You have to load a SoundFont in order to hear any sound. For that - * you use the fluid_synth_sfload() function. - * - * You can use the audio driver functions described below to open - * the audio device and create a background audio thread. - * - * The API for sending MIDI events is probably what you expect: - * fluid_synth_noteon(), fluid_synth_noteoff(), ... - * - */ - - - /** Creates a new synthesizer object. - * - * Creates a new synthesizer object. As soon as the synthesizer is - * created, it will start playing. - * - * \param settings a pointer to a settings structure - * \return a newly allocated synthesizer or NULL in case of error - */ -FLUIDSYNTH_API fluid_synth_t* new_fluid_synth(fluid_settings_t* settings); - - - /** - * Deletes the synthesizer previously created with new_fluid_synth. - * - * \param synth the synthesizer object - * \return 0 if no error occured, -1 otherwise - */ -FLUIDSYNTH_API int delete_fluid_synth(fluid_synth_t* synth); - - - /** Get a reference to the settings of the synthesizer. - * - * \param synth the synthesizer object - * \return pointer to the settings - */ -FLUIDSYNTH_API fluid_settings_t* fluid_synth_get_settings(fluid_synth_t* synth); - - - /* - * - * MIDI channel messages - * - */ - - /** Send a noteon message. Returns 0 if no error occurred, -1 otherwise. */ -FLUIDSYNTH_API int fluid_synth_noteon(fluid_synth_t* synth, int chan, int key, int vel); - - /** Send a noteoff message. Returns 0 if no error occurred, -1 otherwise. */ -FLUIDSYNTH_API int fluid_synth_noteoff(fluid_synth_t* synth, int chan, int key); - - /** Send a control change message. Returns 0 if no error occurred, -1 otherwise. */ -FLUIDSYNTH_API int fluid_synth_cc(fluid_synth_t* synth, int chan, int ctrl, int val); - - /** Get a control value. Returns 0 if no error occurred, -1 otherwise. */ -FLUIDSYNTH_API int fluid_synth_get_cc(fluid_synth_t* synth, int chan, int ctrl, int* pval); - - /** Send a pitch bend message. Returns 0 if no error occurred, -1 otherwise. */ -FLUIDSYNTH_API int fluid_synth_pitch_bend(fluid_synth_t* synth, int chan, int val); - - /** Get the pitch bend value. Returns 0 if no error occurred, -1 otherwise. */ -FLUIDSYNTH_API -int fluid_synth_get_pitch_bend(fluid_synth_t* synth, int chan, int* ppitch_bend); - - /** Set the pitch wheel sensitivity. Returns 0 if no error occurred, -1 otherwise. */ -FLUIDSYNTH_API int fluid_synth_pitch_wheel_sens(fluid_synth_t* synth, int chan, int val); - - /** Get the pitch wheel sensitivity. Returns 0 if no error occurred, -1 otherwise. */ -FLUIDSYNTH_API int fluid_synth_get_pitch_wheel_sens(fluid_synth_t* synth, int chan, int* pval); - - /** Send a program change message. Returns 0 if no error occurred, -1 otherwise. */ -FLUIDSYNTH_API int fluid_synth_program_change(fluid_synth_t* synth, int chan, int program); - - /** Select a bank. Returns 0 if no error occurred, -1 otherwise. */ -FLUIDSYNTH_API -int fluid_synth_bank_select(fluid_synth_t* synth, int chan, unsigned int bank); - - /** Select a sfont. Returns 0 if no error occurred, -1 otherwise. */ -FLUIDSYNTH_API -int fluid_synth_sfont_select(fluid_synth_t* synth, int chan, unsigned int sfont_id); - - /** Select a preset for a channel. The preset is specified by the - SoundFont ID, the bank number, and the preset number. This - allows any preset to be selected and circumvents preset masking - due to previously loaded SoundFonts on the SoundFont stack. - - \param synth The synthesizer - \param chan The channel on which to set the preset - \param sfont_id The ID of the SoundFont - \param bank_num The bank number - \param preset_num The preset number - \return 0 if no errors occured, -1 otherwise - */ -FLUIDSYNTH_API -int fluid_synth_program_select(fluid_synth_t* synth, int chan, - unsigned int sfont_id, - unsigned int bank_num, - unsigned int preset_num); - - /** Returns the program, bank, and SoundFont number of the preset on - a given channel. Returns 0 if no error occurred, -1 otherwise. */ -FLUIDSYNTH_API -int fluid_synth_get_program(fluid_synth_t* synth, int chan, - unsigned int* sfont_id, - unsigned int* bank_num, - unsigned int* preset_num); - - /** Send a bank select and a program change to every channel to - * reinitialize the preset of the channel. This function is useful - * mainly after a SoundFont has been loaded, unloaded or - * reloaded. . Returns 0 if no error occurred, -1 otherwise. */ -FLUIDSYNTH_API int fluid_synth_program_reset(fluid_synth_t* synth); - - /** Send a reset. A reset turns all the notes off and resets the - controller values. */ -FLUIDSYNTH_API int fluid_synth_system_reset(fluid_synth_t* synth); - - - /* - * - * Low level access - * - */ - - /** Create and start voices using a preset. The id passed as - * argument will be used as the voice group id. */ -FLUIDSYNTH_API int fluid_synth_start(fluid_synth_t* synth, unsigned int id, - fluid_preset_t* preset, int audio_chan, - int midi_chan, int key, int vel); - - /** Stop the voices in the voice group defined by id. */ -FLUIDSYNTH_API int fluid_synth_stop(fluid_synth_t* synth, unsigned int id); - - /** Change the value of a generator of the voices in the voice group - * defined by id. */ -/* FLUIDSYNTH_API int fluid_synth_ctrl(fluid_synth_t* synth, int id, */ -/* int gen, float value, */ -/* int absolute, int normalized); */ - - - /* - * - * SoundFont management - * - */ - - /** Loads a SoundFont file and creates a new SoundFont. The newly - loaded SoundFont will be put on top of the SoundFont - stack. Presets are searched starting from the SoundFont on the - top of the stack, working the way down the stack until a preset - is found. - - \param synth The synthesizer object - \param filename The file name - \param reset_presets If non-zero, the presets on the channels will be reset - \returns The ID of the loaded SoundFont, or -1 in case of error - */ -FLUIDSYNTH_API -int fluid_synth_sfload(fluid_synth_t* synth, const char* filename, int reset_presets); - - /** Reload a SoundFont. The reloaded SoundFont retains its ID and - index on the stack. - - \param synth The synthesizer object - \param id The id of the SoundFont - \returns The ID of the loaded SoundFont, or -1 in case of error - */ -FLUIDSYNTH_API int fluid_synth_sfreload(fluid_synth_t* synth, unsigned int id); - - /** Removes a SoundFont from the stack and deallocates it. - - \param synth The synthesizer object - \param id The id of the SoundFont - \param reset_presets If TRUE then presets will be reset for all channels - \returns 0 if no error, -1 otherwise - */ -FLUIDSYNTH_API int fluid_synth_sfunload(fluid_synth_t* synth, unsigned int id, int reset_presets); - - /** Add a SoundFont. The SoundFont will be put on top of - the SoundFont stack. - - \param synth The synthesizer object - \param sfont The SoundFont - \returns The ID of the loaded SoundFont, or -1 in case of error - */ -FLUIDSYNTH_API int fluid_synth_add_sfont(fluid_synth_t* synth, fluid_sfont_t* sfont); - - /** Remove a SoundFont that was previously added using - * fluid_synth_add_sfont(). The synthesizer does not delete the - * SoundFont; this is responsability of the caller. - - \param synth The synthesizer object - \param sfont The SoundFont - */ -FLUIDSYNTH_API void fluid_synth_remove_sfont(fluid_synth_t* synth, fluid_sfont_t* sfont); - - /** Count the number of loaded SoundFonts. - - \param synth The synthesizer object - \returns The number of loaded SoundFonts - */ -FLUIDSYNTH_API int fluid_synth_sfcount(fluid_synth_t* synth); - - /** Get a SoundFont. The SoundFont is specified by its index on the - stack. The top of the stack has index zero. - - \param synth The synthesizer object - \param num The number of the SoundFont (0 <= num < sfcount) - \returns A pointer to the SoundFont - */ -FLUIDSYNTH_API fluid_sfont_t* fluid_synth_get_sfont(fluid_synth_t* synth, unsigned int num); - - /** Get a SoundFont. The SoundFont is specified by its ID. - - \param synth The synthesizer object - \param id The id of the sfont - \returns A pointer to the SoundFont - */ -FLUIDSYNTH_API fluid_sfont_t* fluid_synth_get_sfont_by_id(fluid_synth_t* synth, unsigned int id); - - - /** Get the preset of a channel */ -FLUIDSYNTH_API fluid_preset_t* fluid_synth_get_channel_preset(fluid_synth_t* synth, int chan); - - /** Offset the bank numbers in a SoundFont. Returns -1 if an error - * occured (out of memory or negative offset) */ -FLUIDSYNTH_API int fluid_synth_set_bank_offset(fluid_synth_t* synth, int sfont_id, int offset); - - /** Get the offset of the bank numbers in a SoundFont. */ -FLUIDSYNTH_API int fluid_synth_get_bank_offset(fluid_synth_t* synth, int sfont_id); - - - - /* - * - * Reverb - * - */ - - /** Set the parameters for the built-in reverb unit */ -FLUIDSYNTH_API void fluid_synth_set_reverb(fluid_synth_t* synth, double roomsize, - double damping, double width, double level); - - /** Turn on (1) / off (0) the built-in reverb unit */ -FLUIDSYNTH_API void fluid_synth_set_reverb_on(fluid_synth_t* synth, int on); - - - /** Query the current state of the reverb. */ -FLUIDSYNTH_API double fluid_synth_get_reverb_roomsize(fluid_synth_t* synth); -FLUIDSYNTH_API double fluid_synth_get_reverb_damp(fluid_synth_t* synth); -FLUIDSYNTH_API double fluid_synth_get_reverb_level(fluid_synth_t* synth); -FLUIDSYNTH_API double fluid_synth_get_reverb_width(fluid_synth_t* synth); - - /* Those are the default settings for the reverb */ -#define FLUID_REVERB_DEFAULT_ROOMSIZE 0.2f -#define FLUID_REVERB_DEFAULT_DAMP 0.0f -#define FLUID_REVERB_DEFAULT_WIDTH 0.5f -#define FLUID_REVERB_DEFAULT_LEVEL 0.9f - - - - /* - * - * Chorus - * - */ - -enum fluid_chorus_mod { - FLUID_CHORUS_MOD_SINE = 0, - FLUID_CHORUS_MOD_TRIANGLE = 1 -}; - - /** Set up the chorus. It should be turned on with fluid_synth_set_chorus_on. - * If faulty parameters are given, all new settings are discarded. - * Keep in mind, that the needed CPU time is proportional to 'nr'. - */ -FLUIDSYNTH_API void fluid_synth_set_chorus(fluid_synth_t* synth, int nr, double level, - double speed, double depth_ms, int type); - - /** Turn on (1) / off (0) the built-in chorus unit */ -FLUIDSYNTH_API void fluid_synth_set_chorus_on(fluid_synth_t* synth, int on); - - /** Query the current state of the chorus. */ -FLUIDSYNTH_API int fluid_synth_get_chorus_nr(fluid_synth_t* synth); -FLUIDSYNTH_API double fluid_synth_get_chorus_level(fluid_synth_t* synth); -FLUIDSYNTH_API double fluid_synth_get_chorus_speed_Hz(fluid_synth_t* synth); -FLUIDSYNTH_API double fluid_synth_get_chorus_depth_ms(fluid_synth_t* synth); -FLUIDSYNTH_API int fluid_synth_get_chorus_type(fluid_synth_t* synth); /* see fluid_chorus_mod */ - - /* Those are the default settings for the chorus. */ -#define FLUID_CHORUS_DEFAULT_N 3 -#define FLUID_CHORUS_DEFAULT_LEVEL 2.0f -#define FLUID_CHORUS_DEFAULT_SPEED 0.3f -#define FLUID_CHORUS_DEFAULT_DEPTH 8.0f -#define FLUID_CHORUS_DEFAULT_TYPE FLUID_CHORUS_MOD_SINE - - - - /* - * - * Audio and MIDI channels - * - */ - - /** Returns the number of MIDI channels that the synthesizer uses - internally */ -FLUIDSYNTH_API int fluid_synth_count_midi_channels(fluid_synth_t* synth); - - /** Returns the number of audio channels that the synthesizer uses - internally */ -FLUIDSYNTH_API int fluid_synth_count_audio_channels(fluid_synth_t* synth); - - /** Returns the number of audio groups that the synthesizer uses - internally. This is usually identical to audio_channels. */ -FLUIDSYNTH_API int fluid_synth_count_audio_groups(fluid_synth_t* synth); - - /** Returns the number of effects channels that the synthesizer uses - internally */ -FLUIDSYNTH_API int fluid_synth_count_effects_channels(fluid_synth_t* synth); - - - - /* - * - * Synthesis parameters - * - */ - - /** Set the master gain */ -FLUIDSYNTH_API void fluid_synth_set_gain(fluid_synth_t* synth, float gain); - - /** Get the master gain */ -FLUIDSYNTH_API float fluid_synth_get_gain(fluid_synth_t* synth); - - /** Set the polyphony limit (FluidSynth >= 1.0.6) */ -FLUIDSYNTH_API int fluid_synth_set_polyphony(fluid_synth_t* synth, int polyphony); - - /** Get the polyphony limit (FluidSynth >= 1.0.6) */ -FLUIDSYNTH_API int fluid_synth_get_polyphony(fluid_synth_t* synth); - - /** Get the internal buffer size. The internal buffer size if not the - same thing as the buffer size specified in the - settings. Internally, the synth *always* uses a specific buffer - size independent of the buffer size used by the audio driver. The - internal buffer size is normally 64 samples. The reason why it - uses an internal buffer size is to allow audio drivers to call the - synthesizer with a variable buffer length. The internal buffer - size is useful for client who want to optimize their buffer sizes. - */ -FLUIDSYNTH_API int fluid_synth_get_internal_bufsize(fluid_synth_t* synth); - - /** Set the interpolation method for one channel or all channels (chan = -1) */ -FLUIDSYNTH_API -int fluid_synth_set_interp_method(fluid_synth_t* synth, int chan, int interp_method); - - /* Flags to choose the interpolation method */ -enum fluid_interp { - /* no interpolation: Fastest, but questionable audio quality */ - FLUID_INTERP_NONE = 0, - /* Straight-line interpolation: A bit slower, reasonable audio quality */ - FLUID_INTERP_LINEAR = 1, - /* Fourth-order interpolation: Requires 50 % of the whole DSP processing time, good quality - * Default. */ - FLUID_INTERP_DEFAULT = 4, - FLUID_INTERP_4THORDER = 4, - FLUID_INTERP_7THORDER = 7, - FLUID_INTERP_HIGHEST=7 -}; - - - - - /* - * - * Generator interface - * - */ - - /** Change the value of a generator. This function allows to control - all synthesis parameters in real-time. The changes are additive, - i.e. they add up to the existing parameter value. This function is - similar to sending an NRPN message to the synthesizer. The - function accepts a float as the value of the parameter. The - parameter numbers and ranges are described in the SoundFont 2.01 - specification, paragraph 8.1.3, page 48. See also 'fluid_gen_type'. - - \param synth The synthesizer object. - \param chan The MIDI channel number. - \param param The parameter number. - \param value The parameter value. - \returns Your favorite dish. - */ -FLUIDSYNTH_API -int fluid_synth_set_gen(fluid_synth_t* synth, int chan, int param, float value); - - - /** Retreive the value of a generator. This function returns the value - set by a previous call 'fluid_synth_set_gen' or by an NRPN message. - - \param synth The synthesizer object. - \param chan The MIDI channel number. - \param param The generator number. - \returns The value of the generator. - */ -FLUIDSYNTH_API float fluid_synth_get_gen(fluid_synth_t* synth, int chan, int param); - - - - - /* - * - * Tuning - * - */ - - /** Create a new key-based tuning with given name, number, and - pitches. The array 'pitches' should have length 128 and contains - the pitch in cents of every key in cents. However, if 'pitches' is - NULL, a new tuning is created with the well-tempered scale. - - \param synth The synthesizer object - \param tuning_bank The tuning bank number [0-127] - \param tuning_prog The tuning program number [0-127] - \param name The name of the tuning - \param pitch The array of pitch values. The array length has to be 128. - */ -FLUIDSYNTH_API -int fluid_synth_create_key_tuning(fluid_synth_t* synth, int tuning_bank, int tuning_prog, - char* name, double* pitch); - - /** Create a new octave-based tuning with given name, number, and - pitches. The array 'pitches' should have length 12 and contains - derivation in cents from the well-tempered scale. For example, if - pitches[0] equals -33, then the C-keys will be tuned 33 cents - below the well-tempered C. - - \param synth The synthesizer object - \param tuning_bank The tuning bank number [0-127] - \param tuning_prog The tuning program number [0-127] - \param name The name of the tuning - \param pitch The array of pitch derivations. The array length has to be 12. - */ -FLUIDSYNTH_API -int fluid_synth_create_octave_tuning(fluid_synth_t* synth, int tuning_bank, int tuning_prog, - char* name, double* pitch); - - /** Request a note tuning changes. Both they 'keys' and 'pitches' - arrays should be of length 'num_pitches'. If 'apply' is non-zero, - the changes should be applied in real-time, i.e. sounding notes - will have their pitch updated. 'APPLY' IS CURRENTLY IGNORED. The - changes will be available for newly triggered notes only. - - \param synth The synthesizer object - \param tuning_bank The tuning bank number [0-127] - \param tuning_prog The tuning program number [0-127] - \param len The length of the keys and pitch arrays - \param keys The array of keys values. - \param pitch The array of pitch values. - \param apply Flag to indicate whether to changes should be applied in real-time. - */ -FLUIDSYNTH_API -int fluid_synth_tune_notes(fluid_synth_t* synth, int tuning_bank, int tuning_prog, - int len, int *keys, double* pitch, int apply); - - /** Select a tuning for a channel. - - \param synth The synthesizer object - \param chan The channel number [0-max channels] - \param tuning_bank The tuning bank number [0-127] - \param tuning_prog The tuning program number [0-127] - */ -FLUIDSYNTH_API -int fluid_synth_select_tuning(fluid_synth_t* synth, int chan, int tuning_bank, int tuning_prog); - - /** Set the tuning to the default well-tempered tuning on a channel. - - \param synth The synthesizer object - \param chan The channel number [0-max channels] - */ -FLUIDSYNTH_API int fluid_synth_reset_tuning(fluid_synth_t* synth, int chan); - - /** Start the iteration throught the list of available tunings. - - \param synth The synthesizer object - */ -FLUIDSYNTH_API void fluid_synth_tuning_iteration_start(fluid_synth_t* synth); - - - /** Get the next tuning in the iteration. This functions stores the - bank and program number of the next tuning in the pointers given as - arguments. - - \param synth The synthesizer object - \param bank Pointer to an int to store the bank number - \param prog Pointer to an int to store the program number - \returns 1 if there is a next tuning, 0 otherwise - */ -FLUIDSYNTH_API -int fluid_synth_tuning_iteration_next(fluid_synth_t* synth, int* bank, int* prog); - - - /** Dump the data of a tuning. This functions stores the name and - pitch values of a tuning in the pointers given as arguments. Both - name and pitch can be NULL is the data is not needed. - - \param synth The synthesizer object - \param bank The tuning bank number [0-127] - \param prog The tuning program number [0-127] - \param name Pointer to a buffer to store the name - \param len The length of the name buffer - \param pitch Pointer to buffer to store the pitch values - */ -FLUIDSYNTH_API int fluid_synth_tuning_dump(fluid_synth_t* synth, int bank, int prog, - char* name, int len, double* pitch); - - - - - /* - * - * Misc - * - */ - - /** Get an estimation of the CPU load due to the audio synthesis. - Returns a percentage (0-100). - - \param synth The synthesizer object - */ -FLUIDSYNTH_API double fluid_synth_get_cpu_load(fluid_synth_t* synth); - - /** Get a textual representation of the last error */ -FLUIDSYNTH_API char* fluid_synth_error(fluid_synth_t* synth); - - - /* - * - * Synthesizer plugin - * - * - * To create a synthesizer plugin, create the synthesizer as - * explained above. Once the synthesizer is created you can call - * any of the functions below to get the audio. - * - */ - - /** Generate a number of samples. This function expects two signed - * 16bits buffers (left and right channel) that will be filled with - * samples. - * - * \param synth The synthesizer - * \param len The number of samples to generate - * \param lout The sample buffer for the left channel - * \param loff The offset, in samples, in the left buffer where the writing pointer starts - * \param lincr The increment, in samples, of the writing pointer in the left buffer - * \param rout The sample buffer for the right channel - * \param roff The offset, in samples, in the right buffer where the writing pointer starts - * \param rincr The increment, in samples, of the writing pointer in the right buffer - * \returns 0 if no error occured, non-zero otherwise - */ - -FLUIDSYNTH_API int fluid_synth_write_s16(fluid_synth_t* synth, int len, - void* lout, int loff, int lincr, - void* rout, int roff, int rincr); - - - /** Generate a number of samples. This function expects two floating - * point buffers (left and right channel) that will be filled with - * samples. - * - * \param synth The synthesizer - * \param len The number of samples to generate - * \param lout The sample buffer for the left channel - * \param loff The offset, in samples, in the left buffer where the writing pointer starts - * \param lincr The increment, in samples, of the writing pointer in the left buffer - * \param rout The sample buffer for the right channel - * \param roff The offset, in samples, in the right buffer where the writing pointer starts - * \param rincr The increment, in samples, of the writing pointer in the right buffer - * \returns 0 if no error occured, non-zero otherwise - */ - -FLUIDSYNTH_API int fluid_synth_write_float(fluid_synth_t* synth, int len, - void* lout, int loff, int lincr, - void* rout, int roff, int rincr); - -FLUIDSYNTH_API int fluid_synth_nwrite_float(fluid_synth_t* synth, int len, - float** left, float** right, - float** fx_left, float** fx_right); - - /** Generate a number of samples. This function implements the - * default interface defined in fluidsynth/audio.h. This function - * ignores the input buffers and expects at least two output - * buffer. - * - * \param synth The synthesizer - * \param len The number of samples to generate - * \param nin The number of input buffers - * \param in The array of input buffers - * \param nout The number of output buffers - * \param out The array of output buffers - * \returns 0 if no error occured, non-zero otherwise - */ - -FLUIDSYNTH_API int fluid_synth_process(fluid_synth_t* synth, int len, - int nin, float** in, - int nout, float** out); - - - - /* Type definition of the synthesizer's audio callback function. */ -typedef int (*fluid_audio_callback_t)(fluid_synth_t* synth, int len, - void* out1, int loff, int lincr, - void* out2, int roff, int rincr); - - - - - - /* - * Synthesizer's interface to handle SoundFont loaders - */ - - - /** Add a SoundFont loader to the synthesizer. Note that SoundFont - loader don't necessarily load SoundFonts. They can load any type - of wavetable data but export a SoundFont interface. */ -FLUIDSYNTH_API void fluid_synth_add_sfloader(fluid_synth_t* synth, fluid_sfloader_t* loader); - - /** Allocate a synthesis voice. This function is called by a - soundfont's preset in response to a noteon event. - The returned voice comes with default modulators installed (velocity-to-attenuation, - velocity to filter, ...) - Note: A single noteon event may create any number of voices, when the preset is layered. - Typically 1 (mono) or 2 (stereo).*/ -FLUIDSYNTH_API fluid_voice_t* fluid_synth_alloc_voice(fluid_synth_t* synth, fluid_sample_t* sample, - int channum, int key, int vel); - - /** Start a synthesis voice. This function is called by a - soundfont's preset in response to a noteon event after the voice - has been allocated with fluid_synth_alloc_voice() and - initialized. - Exclusive classes are processed here.*/ -FLUIDSYNTH_API void fluid_synth_start_voice(fluid_synth_t* synth, fluid_voice_t* voice); - - - /** Write a list of all voices matching ID into buf, but not more than bufsize voices. - * If ID <0, return all voices. */ -FLUIDSYNTH_API void fluid_synth_get_voicelist(fluid_synth_t* synth, - fluid_voice_t* buf[], int bufsize, int ID); - - - /** Callback function for the MIDI router. Any event goes through this. */ -FLUIDSYNTH_API int fluid_synth_handle_midi_event(void* data, fluid_midi_event_t* event); - - - /** This is a hack to get command handlers working */ -FLUIDSYNTH_API void fluid_synth_set_midi_router(fluid_synth_t* synth, - fluid_midi_router_t* router); - -#ifdef __cplusplus -} -#endif - -#endif /* _FLUIDSYNTH_SYNTH_H */ diff --git a/headers/libs/fluidsynth/fluidsynth/types.h b/headers/libs/fluidsynth/fluidsynth/types.h deleted file mode 100644 index d36f2fb109..0000000000 --- a/headers/libs/fluidsynth/fluidsynth/types.h +++ /dev/null @@ -1,66 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#ifndef _FLUIDSYNTH_TYPES_H -#define _FLUIDSYNTH_TYPES_H - - - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - - Forward declarations - -*/ -typedef struct _fluid_hashtable_t fluid_settings_t; -typedef struct _fluid_synth_t fluid_synth_t; -typedef struct _fluid_voice_t fluid_voice_t; -typedef struct _fluid_sfloader_t fluid_sfloader_t; -typedef struct _fluid_sfont_t fluid_sfont_t; -typedef struct _fluid_preset_t fluid_preset_t; -typedef struct _fluid_sample_t fluid_sample_t; -typedef struct _fluid_mod_t fluid_mod_t; -typedef struct _fluid_audio_driver_t fluid_audio_driver_t; -typedef struct _fluid_player_t fluid_player_t; -typedef struct _fluid_midi_event_t fluid_midi_event_t; -typedef struct _fluid_midi_driver_t fluid_midi_driver_t; -typedef struct _fluid_midi_router_t fluid_midi_router_t; -typedef struct _fluid_midi_router_rule_t fluid_midi_router_rule_t; -typedef struct _fluid_hashtable_t fluid_cmd_handler_t; -typedef struct _fluid_shell_t fluid_shell_t; -typedef struct _fluid_server_t fluid_server_t; -typedef struct _fluid_event_t fluid_event_t; -typedef struct _fluid_sequencer_t fluid_sequencer_t; -typedef struct _fluid_ramsfont_t fluid_ramsfont_t; -typedef struct _fluid_rampreset_t fluid_rampreset_t; - -typedef int fluid_istream_t; -typedef int fluid_ostream_t; - - -#ifdef __cplusplus -} -#endif - -#endif /* _FLUIDSYNTH_TYPES_H */ diff --git a/headers/libs/fluidsynth/fluidsynth/version.h b/headers/libs/fluidsynth/fluidsynth/version.h deleted file mode 100644 index 8dc10160af..0000000000 --- a/headers/libs/fluidsynth/fluidsynth/version.h +++ /dev/null @@ -1,44 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#ifndef _FLUIDSYNTH_VERSION_H -#define _FLUIDSYNTH_VERSION_H - - -#ifdef __cplusplus -extern "C" { -#endif - -#define FLUIDSYNTH_VERSION "1.0.9" -#define FLUIDSYNTH_VERSION_MAJOR 1 -#define FLUIDSYNTH_VERSION_MINOR 0 -#define FLUIDSYNTH_VERSION_MICRO 9 - - -FLUIDSYNTH_API void fluid_version(int *major, int *minor, int *micro); - -FLUIDSYNTH_API char* fluid_version_str(void); - - -#ifdef __cplusplus -} -#endif - -#endif /* _FLUIDSYNTH_VERSION_H */ diff --git a/headers/libs/fluidsynth/fluidsynth/voice.h b/headers/libs/fluidsynth/fluidsynth/voice.h deleted file mode 100644 index 13b6b804a4..0000000000 --- a/headers/libs/fluidsynth/fluidsynth/voice.h +++ /dev/null @@ -1,97 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#ifndef _FLUIDSYNTH_VOICE_H -#define _FLUIDSYNTH_VOICE_H - -#ifdef __cplusplus -extern "C" { -#endif - - - /* - * The interface to the synthesizer's voices - * Examples on using them can be found in fluid_defsfont.c - */ - - /** Update all the synthesis parameters, which depend on generator gen. - This is only necessary after changing a generator of an already operating voice. - Most applications will not need this function.*/ - -FLUIDSYNTH_API void fluid_voice_update_param(fluid_voice_t* voice, int gen); - - - /* for fluid_voice_add_mod */ -enum fluid_voice_add_mod{ - FLUID_VOICE_OVERWRITE, - FLUID_VOICE_ADD, - FLUID_VOICE_DEFAULT -}; - - /* Add a modulator to a voice (SF2.1 only). */ -FLUIDSYNTH_API void fluid_voice_add_mod(fluid_voice_t* voice, fluid_mod_t* mod, int mode); - - /** Set the value of a generator */ -FLUIDSYNTH_API void fluid_voice_gen_set(fluid_voice_t* voice, int gen, float val); - - /** Get the value of a generator */ -FLUIDSYNTH_API float fluid_voice_gen_get(fluid_voice_t* voice, int gen); - - /** Modify the value of a generator by val */ -FLUIDSYNTH_API void fluid_voice_gen_incr(fluid_voice_t* voice, int gen, float val); - - - /** Return the unique ID of the noteon-event. A sound font loader - * may store the voice processes it has created for * real-time - * control during the operation of a voice (for example: parameter - * changes in sound font editor). The synth uses a pool of - * voices, which are 'recycled' and never deallocated. - * - * Before modifying an existing voice, check - * - that its state is still 'playing' - * - that the ID is still the same - * Otherwise the voice has finished playing. - */ -FLUIDSYNTH_API unsigned int fluid_voice_get_id(fluid_voice_t* voice); - - -FLUIDSYNTH_API int fluid_voice_is_playing(fluid_voice_t* voice); - - /** If the peak volume during the loop is known, then the voice can - * be released earlier during the release phase. Otherwise, the - * voice will operate (inaudibly), until the envelope is at the - * nominal turnoff point. In many cases the loop volume is many dB - * below the maximum volume. For example, the loop volume for a - * typical acoustic piano is 20 dB below max. Taking that into - * account in the turn-off algorithm we can save 20 dB / 100 dB => - * 1/5 of the total release time. - * So it's a good idea to call fluid_voice_optimize_sample - * on each sample once. - */ - -FLUIDSYNTH_API int fluid_voice_optimize_sample(fluid_sample_t* s); - - - -#ifdef __cplusplus -} -#endif -#endif /* _FLUIDSYNTH_VOICE_H */ - diff --git a/src/libs/fluidsynth/AUTHORS b/src/libs/fluidsynth/AUTHORS deleted file mode 100644 index d158852d4a..0000000000 --- a/src/libs/fluidsynth/AUTHORS +++ /dev/null @@ -1,130 +0,0 @@ -[:Team:] -Current development team - -Josh Green -Bernat Arlandis i Mañó -Pedro Lopez-Cabanillas - - -[:Idea:] - -* Samuel Bianchini, Peter Hanappe and Johnathan Lee - - -[:Development:] - -Many people contributed to FluidSynth, sent suggestions or bug -fixes. The project was started by Peter Hanappe who is the main -author. Josh Green is the current maintainer. Below you'll find a -summary of contributions. - - -* Peter Hanappe. Initiated the project. files: stuck his nose in all - files. - -* Josh Green is the current maintainer and contributed a lot of code - directly or indirectly through the Swami and Smurf code base. - The SoundFont loader is completely based on his code. He also wrote - the alsa sequencer driver. He made many changes and bug fixes, - but above all, he's one of the driving forces behind the synthesizer. - He also created the current FluidSynth graphic logo with Blender - (the blue waves with FluidSynth letters partially submerged). - -* Markus Nentwig (re-)designed the resonant filter, the chorus, the - LADSPA subsystem, the MIDI router, optimized for SSE, made many - changes and bug fixes and got the synthesizer to actually work. Most - importantly, he used it on stage to make music. - -* S. Christian Collins did much testing of FluidSynth in regards to - EMU10K1 compatibility and provided many synthesis fixes in that regard. - -* Stephane Letz from Grame wrote most of the MidiShare driver, all of - the PortAudio driver, ported iiwusynth to MacOS X, and sent in many - fixes. files: iiwu_midishare.c, iiwu_portaudio.c - -* Antoine Schmitt added the sequencer support, support for sample - loading (RAM Sfont), developed the - MacroMedia Director Xtra, and send in many many bug reports. Thanks - to Antoine, the synthesizer finds its way to multi-media - developers. files: in bindings/director/ and iiwu_seq.{c,h}, - iiwu_event.{c,h}, iiwu_event_priv.h, iiwu_seqbind.{c,h}, - iiwu_ramsfont.{c,h} - -* Bob Ham added the code for "bank select" MIDI messages and send code - to define the synth's ALSA sequencer client name. files: - iiwu_midi.c, iiwu_alsa.c, iiwusynth.c, iiwusynth.h. - -* Tim Goetze sent many patches and implemented the all_notes_off. He - also sent his code for the new ALSA driver. files: iiwu_synth.c, - iiwu_chan.c, iiwu_voice.c, iiwu_alsa.c - -* Norbert Schnell from Ircam's jMax Team wrote most of the jMax/FTS - interface in a record time. He also pointed me to the technique of - using a lookup table for the interpolation coefficients. file: - iiwu_fts.c, iiwu_synth.c - -* The initial alsa driver was based on the jMax alsa driver by - Francois Dechelle and his Real-time Team at Ircam - (http://www.ircam.fr/jmax). The jMax code was based upon Ardour's - alsa_device.cc by Paul Barton-Davis. file: iiwu_alsa.c - -* Code was borrowed from the glib library to the smurf files. The goal was - to make iiwusynth independent from any library for maximum - portability. - -* The midi device uses code from jMax's alsarawmidi.c file and from - Smurf's midi_alsaraw.c by Josh Green. file: iiwu_alsa.c - -* The reverb algorithm was written by Jezar - (http://www.dreampoint.co.uk). His code is public domain. The code - was translated to C by Peter Hanappe. file: iiwu_synth.c - -* The original code for the chorus effect was written by Juergen - Mueller and sundry contributors. - -* Bob Ham added LADCCA support. - -* Ebrahim Mayat made big efforts for compiling and running FluidSynth - on MacOS X. He also wrote the README-OSX file. - -* Martin Uddén's midi package was used. His files are integrated into - the iiwu_midi file. Martin Uddén file: - iiwu_midi.c - -* Ken Ellinwood send in a patch to add bank offsets to SoundFonts. An - adapted version was integrated in the source code. files: - fluid_cmd.c, fluidsynth/synth.h, fluid_synth.c. - -* Some interpolation algorihms were used that were found in - the music-dsp archives (http://www.smartelectronix.com/musicdsp). - They were written by Joshua Scholar and others. file: iiwu_synth.c - -* Macros to {increment,decrement} the 64-bit fixed point phase were - borrowed from Mozilla's macros to handle the Long-long type (64-bit - signed integer type). Mozilla NSPR library, www.mozilla.org. file: - iiwu_phase.h - -* KO Myung-Hun for OS/2 support with Dart audio driver. - -* Growing list of individuals who contributed bug fixes, corrections and minor features: -Pedro Lopez-Cabanillas for midi.winmidi.device setting. -Nicolas Boulicault for ALSA sequencer midi.portname setting. -Werner Schweer -Dave Philips -Anthony Green -Jake Commander -Fernando Pablo Lopez-Lezcano -Raoul Bonisch -Sergey Pavlishin -Eric Van Buggenhaut -Ken Ellinwood -Takashi Iwai -Bob Ham -Gerald Pye -Rui Nuno Capela -Frieder Bürzele -Henri Manson -Mihail Zenkov -Paul Millar -Nick Daly -David Hilvert diff --git a/src/libs/fluidsynth/COPYING b/src/libs/fluidsynth/COPYING deleted file mode 100644 index 03a4f9819f..0000000000 --- a/src/libs/fluidsynth/COPYING +++ /dev/null @@ -1,482 +0,0 @@ - - GNU LIBRARY GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the library GPL. It is - numbered 2 because it goes with version 2 of the ordinary GPL.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Library General Public License, applies to some -specially designated Free Software Foundation software, and to any -other libraries whose authors decide to use it. You can use it for -your libraries, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if -you distribute copies of the library, or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link a program with the library, you must provide -complete object files to the recipients so that they can relink them -with the library, after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - Our method of protecting your rights has two steps: (1) copyright -the library, and (2) offer you this license which gives you legal -permission to copy, distribute and/or modify the library. - - Also, for each distributor's protection, we want to make certain -that everyone understands that there is no warranty for this free -library. If the library is modified by someone else and passed on, we -want its recipients to know that what they have is not the original -version, so that any problems introduced by others will not reflect on -the original authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that companies distributing free -software will individually obtain patent licenses, thus in effect -transforming the program into proprietary software. To prevent this, -we have made it clear that any patent must be licensed for everyone's -free use or not licensed at all. - - Most GNU software, including some libraries, is covered by the ordinary -GNU General Public License, which was designed for utility programs. This -license, the GNU Library General Public License, applies to certain -designated libraries. This license is quite different from the ordinary -one; be sure to read it in full, and don't assume that anything in it is -the same as in the ordinary license. - - The reason we have a separate public license for some libraries is that -they blur the distinction we usually make between modifying or adding to a -program and simply using it. Linking a program with a library, without -changing the library, is in some sense simply using the library, and is -analogous to running a utility program or application program. However, in -a textual and legal sense, the linked executable is a combined work, a -derivative of the original library, and the ordinary General Public License -treats it as such. - - Because of this blurred distinction, using the ordinary General -Public License for libraries did not effectively promote software -sharing, because most developers did not use the libraries. We -concluded that weaker conditions might promote sharing better. - - However, unrestricted linking of non-free programs would deprive the -users of those programs of all benefit from the free status of the -libraries themselves. This Library General Public License is intended to -permit developers of non-free programs to use free libraries, while -preserving your freedom as a user of such programs to change the free -libraries that are incorporated in them. (We have not seen how to achieve -this as regards changes in header files, but we have achieved it as regards -changes in the actual functions of the Library.) The hope is that this -will lead to faster development of free libraries. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, while the latter only -works together with the library. - - Note that it is possible for a library to be covered by the ordinary -General Public License rather than by this special one. - - GNU LIBRARY GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library which -contains a notice placed by the copyright holder or other authorized -party saying it may be distributed under the terms of this Library -General Public License (also called "this License"). Each licensee is -addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also compile or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - c) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - d) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the source code distributed need not include anything that is normally -distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Library General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/src/libs/fluidsynth/Jamfile b/src/libs/fluidsynth/Jamfile deleted file mode 100644 index 1537accf23..0000000000 --- a/src/libs/fluidsynth/Jamfile +++ /dev/null @@ -1,3 +0,0 @@ -SubDir HAIKU_TOP src libs fluidsynth ; - -SubInclude HAIKU_TOP src libs fluidsynth src ; diff --git a/src/libs/fluidsynth/src/Jamfile b/src/libs/fluidsynth/src/Jamfile deleted file mode 100644 index 5aec16f3dd..0000000000 --- a/src/libs/fluidsynth/src/Jamfile +++ /dev/null @@ -1,45 +0,0 @@ -SubDir HAIKU_TOP src libs fluidsynth src ; - -SetSubDirSupportedPlatformsBeOSCompatible ; - -UseLibraryHeaders fluidsynth ; - -SubDirCcFlags -DHAVE_CONFIG_H ; - -local architectureObject ; -for architectureObject in [ MultiArchSubDirSetup ] { - on $(architectureObject) { - SharedLibrary [ MultiArchDefaultGristFiles libfluidsynth.so ] : - fluid_adriver.c - fluid_aufile.c - fluid_chan.c - fluid_chorus.c - fluid_cmd.c - fluid_conv.c - fluid_defsfont.c - fluid_dsp_float.c - fluid_event.c - fluid_gen.c - fluid_hash.c - fluid_io.c - fluid_list.c - fluid_mdriver.c - fluid_midi.c - fluid_midi_router.c - fluid_mod.c - fluid_ramsfont.c - fluid_rev.c - fluid_seq.c - fluid_seqbind.c - fluid_settings.c - fluid_synth.c - fluid_sys.c - fluid_tuning.c - fluid_voice.c - ; - } -} - -# // for testing purpose -#StdBinCommands fluidsynth.c : libfluidsynth.so ; - diff --git a/src/libs/fluidsynth/src/config.h b/src/libs/fluidsynth/src/config.h deleted file mode 100644 index c5a18ec6a7..0000000000 --- a/src/libs/fluidsynth/src/config.h +++ /dev/null @@ -1,191 +0,0 @@ -/* src/config.h. Generated by configure. */ -/* src/config.h.in. Generated from configure.ac by autoheader. */ - -/* Define to enable ALSA driver */ -/* #undef ALSA_SUPPORT */ - -/* whether or not we are supporting CoreAudio */ -/* #undef COREAUDIO_SUPPORT */ - -/* Define if building for Mac OS X Darwin */ -/* #undef DARWIN */ - -/* Define to activate debugging message */ -#define DEBUG 0 - -/* Use the SSE instructions of Pentium3+ (not recommended) */ -/* #undef ENABLE_SSE */ - -/* Define to 1 if you have the header file. */ -#ifdef HAIKU_TARGET_PLATFORM_HAIKU -#define HAVE_ARPA_INET_H 1 -#endif - -/* Define to 1 if you have the header file. */ -#define HAVE_DLFCN_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_ERRNO_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_FCNTL_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_INTTYPES_H 1 - -/* whether or not we are supporting ladcca */ -/* #undef HAVE_LADCCA */ - -/* whether or not we are supporting lash */ -/* #undef HAVE_LASH */ - -/* Define to 1 if you have the `dl' library (-ldl). */ -/* #undef HAVE_LIBDL */ - -/* Define to 1 if you have the `MidiShare' library (-lMidiShare). */ -/* #undef HAVE_LIBMIDISHARE */ - -/* Define to 1 if you have the `pthread' library (-lpthread). */ -/* #undef HAVE_LIBPTHREAD */ - -/* Define to 1 if you have the header file. */ -#define HAVE_LIMITS_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_MACHINE_SOUNDCARD_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_MATH_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_MIDISHARE_H */ - -/* Define to 1 if you have the header file. */ -#ifdef HAIKU_TARGET_PLATFORM_HAIKU -#define HAVE_NETINET_IN_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_NETINET_TCP_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_PTHREAD_H 1 -#endif - -/* Define to 1 if you have the header file. */ -#define HAVE_SIGNAL_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDARG_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDIO_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the header file. */ -#ifdef HAIKU_TARGET_PLATFORM_HAIKU -#define HAVE_SYS_IOCTL_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_MMAN_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_SOCKET_H 1 -#endif - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_SOUNDCARD_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TIME_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_WINDOWS_H */ - -/* Define to enable JACK driver */ -/* #undef JACK_SUPPORT */ - -/* Include the LADSPA Fx unit */ -/* #undef LADSPA */ - -/* Define to enable MidiShare driver */ -/* #undef MIDISHARE_SUPPORT */ - -/* Define if using the MinGW32 environment */ -/* #undef MINGW32 */ - -/* Define to enable OSS driver */ -/* #undef OSS_SUPPORT */ - -/* Name of package */ -#define PACKAGE "fluidsynth" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "" - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Version number of package */ -#define VERSION "1.0.9" - -/* Define to do all DSP in single floating point precision */ -#define WITH_FLOAT 1 - -/* Define to profile the DSP code */ -/* #undef WITH_PROFILING */ - -/* Define to use the readline library for line editing */ -/* #undef WITH_READLINE */ - -/* Define to 1 if your processor stores words with the most significant byte - first (like Motorola and SPARC, unlike Intel and VAX). */ -/* #undef WORDS_BIGENDIAN */ - -/* Define to `__inline__' or `__inline' if that's what the C compiler - calls it, or to nothing if 'inline' is not supported under any name. */ -#ifndef __cplusplus -/* #undef inline */ -#endif - -/* Additional config for us */ -#if (defined(__BEOS__) || defined(__HAIKU__)) - -#define WITHOUT_SERVER 1 -#include - -#endif diff --git a/src/libs/fluidsynth/src/fluid_adriver.c b/src/libs/fluidsynth/src/fluid_adriver.c deleted file mode 100644 index 2749fe4c9a..0000000000 --- a/src/libs/fluidsynth/src/fluid_adriver.c +++ /dev/null @@ -1,378 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#include "fluid_adriver.h" -#include "fluid_settings.h" - -/* - * fluid_adriver_definition_t - */ - -typedef struct _fluid_audriver_definition_t -{ - char* name; - fluid_audio_driver_t* (*new)(fluid_settings_t* settings, fluid_synth_t* synth); - fluid_audio_driver_t* (*new2)(fluid_settings_t* settings, - fluid_audio_func_t func, - void* data); - int (*free)(fluid_audio_driver_t* driver); - void (*settings)(fluid_settings_t* settings); -} fluid_audriver_definition_t; - - -#if PULSE_SUPPORT -fluid_audio_driver_t* new_fluid_pulse_audio_driver(fluid_settings_t* settings, - fluid_synth_t* synth); -fluid_audio_driver_t* new_fluid_pulse_audio_driver2(fluid_settings_t* settings, - fluid_audio_func_t func, void* data); -int delete_fluid_pulse_audio_driver(fluid_audio_driver_t* p); -void fluid_pulse_audio_driver_settings(fluid_settings_t* settings); -#endif - -#if ALSA_SUPPORT -fluid_audio_driver_t* new_fluid_alsa_audio_driver(fluid_settings_t* settings, - fluid_synth_t* synth); -fluid_audio_driver_t* new_fluid_alsa_audio_driver2(fluid_settings_t* settings, - fluid_audio_func_t func, void* data); -int delete_fluid_alsa_audio_driver(fluid_audio_driver_t* p); -void fluid_alsa_audio_driver_settings(fluid_settings_t* settings); -#endif - -#if OSS_SUPPORT -fluid_audio_driver_t* new_fluid_oss_audio_driver(fluid_settings_t* settings, - fluid_synth_t* synth); -fluid_audio_driver_t* new_fluid_oss_audio_driver2(fluid_settings_t* settings, - fluid_audio_func_t func, void* data); -int delete_fluid_oss_audio_driver(fluid_audio_driver_t* p); -void fluid_oss_audio_driver_settings(fluid_settings_t* settings); -#endif - -#if COREAUDIO_SUPPORT -fluid_audio_driver_t* new_fluid_core_audio_driver(fluid_settings_t* settings, - fluid_synth_t* synth); -fluid_audio_driver_t* new_fluid_core_audio_driver2(fluid_settings_t* settings, - fluid_audio_func_t func, - void* data); -int delete_fluid_core_audio_driver(fluid_audio_driver_t* p); -void fluid_core_audio_driver_settings(fluid_settings_t* settings); -#endif - -#if DSOUND_SUPPORT -fluid_audio_driver_t* new_fluid_dsound_audio_driver(fluid_settings_t* settings, - fluid_synth_t* synth); -int delete_fluid_dsound_audio_driver(fluid_audio_driver_t* p); -void fluid_dsound_audio_driver_settings(fluid_settings_t* settings); -#endif - -#if PORTAUDIO_SUPPORT -void fluid_portaudio_driver_settings (fluid_settings_t *settings); -fluid_audio_driver_t* new_fluid_portaudio_driver(fluid_settings_t* settings, - fluid_synth_t* synth); -int delete_fluid_portaudio_driver(fluid_audio_driver_t* p); -#endif - -#if JACK_SUPPORT -fluid_audio_driver_t* new_fluid_jack_audio_driver(fluid_settings_t* settings, fluid_synth_t* synth); -fluid_audio_driver_t* new_fluid_jack_audio_driver2(fluid_settings_t* settings, - fluid_audio_func_t func, void* data); -int delete_fluid_jack_audio_driver(fluid_audio_driver_t* p); -void fluid_jack_audio_driver_settings(fluid_settings_t* settings); -#endif - -#if SNDMAN_SUPPORT -fluid_audio_driver_t* new_fluid_sndmgr_audio_driver(fluid_settings_t* settings, - fluid_synth_t* synth); -fluid_audio_driver_t* new_fluid_sndmgr_audio_driver2(fluid_settings_t* settings, - fluid_audio_func_t func, - void* data); -int delete_fluid_sndmgr_audio_driver(fluid_audio_driver_t* p); -#endif - -#if DART_SUPPORT -fluid_audio_driver_t* new_fluid_dart_audio_driver(fluid_settings_t* settings, - fluid_synth_t* synth); -int delete_fluid_dart_audio_driver(fluid_audio_driver_t* p); -void fluid_dart_audio_driver_settings(fluid_settings_t* settings); -#endif - -#define AUFILE_SUPPORT 1 -#if AUFILE_SUPPORT -fluid_audio_driver_t* new_fluid_file_audio_driver(fluid_settings_t* settings, - fluid_synth_t* synth); -int delete_fluid_file_audio_driver(fluid_audio_driver_t* p); -void fluid_file_audio_driver_settings(fluid_settings_t* settings); -#endif - -/* Available audio drivers, listed in order of preference */ -fluid_audriver_definition_t fluid_audio_drivers[] = { -#if JACK_SUPPORT - { "jack", - new_fluid_jack_audio_driver, - new_fluid_jack_audio_driver2, - delete_fluid_jack_audio_driver, - fluid_jack_audio_driver_settings }, -#endif -#if ALSA_SUPPORT - { "alsa", - new_fluid_alsa_audio_driver, - new_fluid_alsa_audio_driver2, - delete_fluid_alsa_audio_driver, - fluid_alsa_audio_driver_settings }, -#endif -#if OSS_SUPPORT - { "oss", - new_fluid_oss_audio_driver, - new_fluid_oss_audio_driver2, - delete_fluid_oss_audio_driver, - fluid_oss_audio_driver_settings }, -#endif -#if PULSE_SUPPORT - { "pulseaudio", - new_fluid_pulse_audio_driver, - new_fluid_pulse_audio_driver2, - delete_fluid_pulse_audio_driver, - fluid_pulse_audio_driver_settings }, -#endif -#if COREAUDIO_SUPPORT - { "coreaudio", - new_fluid_core_audio_driver, - new_fluid_core_audio_driver2, - delete_fluid_core_audio_driver, - fluid_core_audio_driver_settings }, -#endif -#if DSOUND_SUPPORT - { "dsound", - new_fluid_dsound_audio_driver, - NULL, - delete_fluid_dsound_audio_driver, - fluid_dsound_audio_driver_settings }, -#endif -#if PORTAUDIO_SUPPORT - { "portaudio", - new_fluid_portaudio_driver, - NULL, - delete_fluid_portaudio_driver, - fluid_portaudio_driver_settings }, -#endif -#if SNDMAN_SUPPORT - { "sndman", - new_fluid_sndmgr_audio_driver, - new_fluid_sndmgr_audio_driver2, - delete_fluid_sndmgr_audio_driver, - NULL }, -#endif -#if DART_SUPPORT - { "dart", - new_fluid_dart_audio_driver, - NULL, - delete_fluid_dart_audio_driver, - fluid_dart_audio_driver_settings }, -#endif -#if AUFILE_SUPPORT - { "file", - new_fluid_file_audio_driver, - NULL, - delete_fluid_file_audio_driver, - fluid_file_audio_driver_settings }, -#endif - { NULL, NULL, NULL, NULL, NULL } -}; - - - - -void fluid_audio_driver_settings(fluid_settings_t* settings) -{ - int i; - - fluid_settings_register_str(settings, "audio.sample-format", "16bits", 0, NULL, NULL); - fluid_settings_add_option(settings, "audio.sample-format", "16bits"); - fluid_settings_add_option(settings, "audio.sample-format", "float"); - - fluid_settings_register_int(settings, "audio.output-channels", 2, 2, 32, 0, NULL, NULL); - fluid_settings_register_int(settings, "audio.input-channels", 0, 0, 2, 0, NULL, NULL); - - -#if defined(WIN32) - fluid_settings_register_int(settings, "audio.period-size", 512, 64, 8192, 0, NULL, NULL); - fluid_settings_register_int(settings, "audio.periods", 8, 2, 64, 0, NULL, NULL); -#elif defined(MACOS9) - fluid_settings_register_int(settings, "audio.period-size", 64, 64, 8192, 0, NULL, NULL); - fluid_settings_register_int(settings, "audio.periods", 8, 2, 64, 0, NULL, NULL); -#else - fluid_settings_register_int(settings, "audio.period-size", 64, 64, 8192, 0, NULL, NULL); - fluid_settings_register_int(settings, "audio.periods", 16, 2, 64, 0, NULL, NULL); -#endif - - /* Set the default driver */ -#if JACK_SUPPORT - fluid_settings_register_str(settings, "audio.driver", "jack", 0, NULL, NULL); -#elif ALSA_SUPPORT - fluid_settings_register_str(settings, "audio.driver", "alsa", 0, NULL, NULL); -#elif PULSE_SUPPORT - fluid_settings_register_str(settings, "audio.driver", "pulseaudio", 0, NULL, NULL); -#elif OSS_SUPPORT - fluid_settings_register_str(settings, "audio.driver", "oss", 0, NULL, NULL); -#elif COREAUDIO_SUPPORT - fluid_settings_register_str(settings, "audio.driver", "coreaudio", 0, NULL, NULL); -#elif DSOUND_SUPPORT - fluid_settings_register_str(settings, "audio.driver", "dsound", 0, NULL, NULL); -#elif SNDMAN_SUPPORT - fluid_settings_register_str(settings, "audio.driver", "sndman", 0, NULL, NULL); -#elif PORTAUDIO_SUPPORT - fluid_settings_register_str(settings, "audio.driver", "portaudio", 0, NULL, NULL); -#elif DART_SUPPORT - fluid_settings_register_str(settings, "audio.driver", "dart", 0, NULL, NULL); -#elif AUFILE_SUPPORT - fluid_settings_register_str(settings, "audio.driver", "file", 0, NULL, NULL); -#else - fluid_settings_register_str(settings, "audio.driver", "", 0, NULL, NULL); -#endif - - /* Add all drivers to the list of options */ -#if PULSE_SUPPORT - fluid_settings_add_option(settings, "audio.driver", "pulseaudio"); -#endif -#if ALSA_SUPPORT - fluid_settings_add_option(settings, "audio.driver", "alsa"); -#endif -#if OSS_SUPPORT - fluid_settings_add_option(settings, "audio.driver", "oss"); -#endif -#if COREAUDIO_SUPPORT - fluid_settings_add_option(settings, "audio.driver", "coreaudio"); -#endif -#if DSOUND_SUPPORT - fluid_settings_add_option(settings, "audio.driver", "dsound"); -#endif -#if SNDMAN_SUPPORT - fluid_settings_add_option(settings, "audio.driver", "sndman"); -#endif -#if PORTAUDIO_SUPPORT - fluid_settings_add_option(settings, "audio.driver", "portaudio"); -#endif -#if JACK_SUPPORT - fluid_settings_add_option(settings, "audio.driver", "jack"); -#endif -#if DART_SUPPORT - fluid_settings_add_option(settings, "audio.driver", "dart"); -#endif -#if AUFILE_SUPPORT - fluid_settings_add_option(settings, "audio.driver", "file"); -#endif - - for (i = 0; fluid_audio_drivers[i].name != NULL; i++) { - if (fluid_audio_drivers[i].settings != NULL) { - fluid_audio_drivers[i].settings(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. - * @return The new audio driver instance. - * - * Creates a new audio driver for a given 'synth' instance with a defined set - * of configuration 'settings'. - */ -fluid_audio_driver_t* -new_fluid_audio_driver(fluid_settings_t* settings, fluid_synth_t* synth) -{ - int i; - fluid_audio_driver_t* driver = NULL; - char* name; - - fluid_settings_getstr(settings, "audio.driver", &name); - - for (i = 0; fluid_audio_drivers[i].name != NULL; i++) { - if (fluid_settings_str_equal(settings, "audio.driver", fluid_audio_drivers[i].name)) { - FLUID_LOG(FLUID_DBG, "Using '%s' audio driver", fluid_audio_drivers[i].name); - driver = (*fluid_audio_drivers[i].new)(settings, synth); - if (driver) { - driver->name = fluid_audio_drivers[i].name; - } - return driver; - } - } - - FLUID_LOG(FLUID_ERR, "Couldn't find the requested audio driver: %s", name); - return NULL; -} - -/** - * 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 - * @param data User defined data pointer to pass to 'func' - * @return The new audio driver instance. - * - * Like new_fluid_audio_driver() but allows for custom audio processing before - * audio is sent to audio driver. It is the responsibility of the callback - * 'func' to render the audio into the buffers. - * NOTE: Not as efficient as new_fluid_audio_driver(). - */ -fluid_audio_driver_t* -new_fluid_audio_driver2(fluid_settings_t* settings, fluid_audio_func_t func, void* data) -{ - int i; - fluid_audio_driver_t* driver = NULL; - char* name; - - fluid_settings_getstr(settings, "audio.driver", &name); - - for (i = 0; fluid_audio_drivers[i].name != NULL; i++) { - if (fluid_settings_str_equal(settings, "audio.driver", fluid_audio_drivers[i].name) && - (fluid_audio_drivers[i].new2 != NULL)) { - FLUID_LOG(FLUID_DBG, "Using '%s' audio driver", fluid_audio_drivers[i].name); - driver = (*fluid_audio_drivers[i].new2)(settings, func, data); - if (driver) { - driver->name = fluid_audio_drivers[i].name; - } - return driver; - } - } - - FLUID_LOG(FLUID_ERR, "Couldn't find the requested audio driver: %s", name); - return NULL; -} - -/** - * Deletes an audio driver instance. - * @param driver Audio driver instance to delete - * - * Shuts down an audio driver and deletes its instance. - */ -void -delete_fluid_audio_driver(fluid_audio_driver_t* driver) -{ - int i; - - for (i = 0; fluid_audio_drivers[i].name != NULL; i++) { - if (fluid_audio_drivers[i].name == driver->name) { - fluid_audio_drivers[i].free(driver); - return; - } - } -} diff --git a/src/libs/fluidsynth/src/fluid_adriver.h b/src/libs/fluidsynth/src/fluid_adriver.h deleted file mode 100644 index c03937b2dc..0000000000 --- a/src/libs/fluidsynth/src/fluid_adriver.h +++ /dev/null @@ -1,39 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#ifndef _FLUID_AUDRIVER_H -#define _FLUID_AUDRIVER_H - -#include "fluidsynth_priv.h" - -void fluid_audio_driver_settings(fluid_settings_t* settings); - - -/* - * fluid_audio_driver_t - */ - -struct _fluid_audio_driver_t -{ - char* name; -}; - - -#endif /* _FLUID_AUDRIVER_H */ diff --git a/src/libs/fluidsynth/src/fluid_aufile.c b/src/libs/fluidsynth/src/fluid_aufile.c deleted file mode 100644 index 579844e831..0000000000 --- a/src/libs/fluidsynth/src/fluid_aufile.c +++ /dev/null @@ -1,183 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -/* fluid_aufile.c - * - * Audio driver, outputs the audio to a file (non real-time) - * - */ - -#include "fluid_adriver.h" -#include "fluid_settings.h" -#include "fluid_sys.h" -#include - - -/** fluid_file_audio_driver_t - * - * This structure should not be accessed directly. Use audio port - * functions instead. - */ -typedef struct { - fluid_audio_driver_t driver; - fluid_audio_func_t callback; - void* data; - int period_size; - double sample_rate; - FILE* file; - fluid_timer_t* timer; - float* left; - float* right; - short* buf; - int buf_size; - unsigned int samples; -} fluid_file_audio_driver_t; - - -fluid_audio_driver_t* new_fluid_file_audio_driver(fluid_settings_t* settings, - fluid_synth_t* synth); - -int delete_fluid_file_audio_driver(fluid_audio_driver_t* p); -void fluid_file_audio_driver_settings(fluid_settings_t* settings); -static int fluid_file_audio_run_s16(void* d, unsigned int msec); - -/************************************************************** - * - * 'file' audio driver - * - */ - -void fluid_file_audio_driver_settings(fluid_settings_t* settings) -{ - fluid_settings_register_str(settings, "audio.file.name", "fluidsynth.raw", 0, NULL, NULL); -} - - -fluid_audio_driver_t* -new_fluid_file_audio_driver(fluid_settings_t* settings, - fluid_synth_t* synth) -{ - fluid_file_audio_driver_t* dev; - int err; - char* filename; - int msec; - - dev = FLUID_NEW(fluid_file_audio_driver_t); - if (dev == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - FLUID_MEMSET(dev, 0, sizeof(fluid_file_audio_driver_t)); - - fluid_settings_getint(settings, "audio.period-size", &dev->period_size); - fluid_settings_getnum(settings, "synth.sample-rate", &dev->sample_rate); - - dev->data = synth; - dev->callback = (fluid_audio_func_t) fluid_synth_process; - dev->samples = 0; - dev->left = FLUID_ARRAY(float, dev->period_size); - dev->right = FLUID_ARRAY(float, dev->period_size); - dev->buf = FLUID_ARRAY(short, 2 * dev->period_size); - dev->buf_size = 2 * dev->period_size * sizeof(short); - - if (fluid_settings_getstr(settings, "audio.file.name", &filename) == 0) { - FLUID_LOG(FLUID_ERR, "No file name specified"); - goto error_recovery; - } - - dev->file = fopen(filename, "wb"); - if (dev->file == NULL) { - FLUID_LOG(FLUID_ERR, "Failed to open the file '%s'", filename); - goto error_recovery; - } - - msec = (int) (0.5 + dev->period_size / dev->sample_rate * 1000.0); - dev->timer = new_fluid_timer(msec, fluid_file_audio_run_s16, (void*) dev, 1, 0); - if (dev->timer == NULL) { - FLUID_LOG(FLUID_PANIC, "Couldn't create the audio thread."); - goto error_recovery; - } - - return (fluid_audio_driver_t*) dev; - - error_recovery: - delete_fluid_file_audio_driver((fluid_audio_driver_t*) dev); - return NULL; -} - -int delete_fluid_file_audio_driver(fluid_audio_driver_t* p) -{ - fluid_file_audio_driver_t* dev = (fluid_file_audio_driver_t*) p; - - if (dev == NULL) { - return FLUID_OK; - } - - if (dev->timer != NULL) { - delete_fluid_timer(dev->timer); - } - - if (dev->file != NULL) { - fclose(dev->file); - } - - if (dev->left != NULL) { - FLUID_FREE(dev->left); - } - - if (dev->right != NULL) { - FLUID_FREE(dev->right); - } - - if (dev->buf != NULL) { - FLUID_FREE(dev->buf); - } - - FLUID_FREE(dev); - return FLUID_OK; -} - -static int fluid_file_audio_run_s16(void* d, unsigned int clock_time) -{ - fluid_file_audio_driver_t* dev = (fluid_file_audio_driver_t*) d; - int n, offset; - unsigned int sample_time; - - sample_time = (unsigned int) (dev->samples / dev->sample_rate * 1000.0); - if (sample_time > clock_time) { - return 1; - } - - fluid_synth_write_s16(dev->data, dev->period_size, dev->buf, 0, 2, dev->buf, 1, 2); - - for (offset = 0; offset < dev->buf_size; offset += n) { - - n = fwrite((char*) dev->buf + offset, 1, dev->buf_size - offset, dev->file); - if (n < 0) { - FLUID_LOG(FLUID_ERR, "Audio output file write error: %s", - strerror (errno)); - return 0; - } - } - - dev->samples += dev->period_size; - - return 1; -} diff --git a/src/libs/fluidsynth/src/fluid_chan.c b/src/libs/fluidsynth/src/fluid_chan.c deleted file mode 100644 index d007e4d2e7..0000000000 --- a/src/libs/fluidsynth/src/fluid_chan.c +++ /dev/null @@ -1,404 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#include "fluid_chan.h" -#include "fluid_mod.h" -#include "fluid_synth.h" -#include "fluid_sfont.h" - -#define SETCC(_c,_n,_v) _c->cc[_n] = _v - -/* - * new_fluid_channel - */ -fluid_channel_t* -new_fluid_channel(fluid_synth_t* synth, int num) -{ - fluid_channel_t* chan; - - chan = FLUID_NEW(fluid_channel_t); - if (chan == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - - chan->synth = synth; - chan->channum = num; - chan->preset = NULL; - - fluid_channel_init(chan); - fluid_channel_init_ctrl(chan); - - return chan; -} - -void -fluid_channel_init(fluid_channel_t* chan) -{ - chan->prognum = (chan->channum == 9)? 0 : chan->channum; - chan->banknum = (chan->channum == 9)? 128 : 0; - chan->sfontnum = 0; - - if (chan->preset) delete_fluid_preset (chan->preset); - chan->preset = fluid_synth_find_preset(chan->synth, chan->banknum, chan->prognum); - - chan->interp_method = FLUID_INTERP_DEFAULT; - chan->tuning = NULL; - chan->nrpn_select = 0; - chan->nrpn_active = 0; -} - -void -fluid_channel_init_ctrl(fluid_channel_t* chan) -{ - int i; - - chan->key_pressure = 0; - chan->channel_pressure = 0; - chan->pitch_bend = 0x2000; /* Range is 0x4000, pitch bend wheel starts in centered position */ - chan->pitch_wheel_sensitivity = 2; /* two semi-tones */ - chan->bank_msb = 0; - - for (i = 0; i < GEN_LAST; i++) { - chan->gen[i] = 0.0f; - chan->gen_abs[i] = 0; - } - - for (i = 0; i < 128; i++) { - SETCC(chan, i, 0); - } - - /* Volume / initial attenuation (MSB & LSB) */ - SETCC(chan, VOLUME_MSB, 127); - SETCC(chan, VOLUME_LSB, 0); - - /* Pan (MSB & LSB) */ - SETCC(chan, PAN_MSB, 64); - SETCC(chan, PAN_LSB, 0); - - /* Expression (MSB & LSB) */ - SETCC(chan, EXPRESSION_MSB, 127); - SETCC(chan, EXPRESSION_LSB, 127); - - /* Set RPN controllers to NULL state */ - SETCC(chan, RPN_LSB, 127); - SETCC(chan, RPN_MSB, 127); -} - -void -fluid_channel_reset(fluid_channel_t* chan) -{ - fluid_channel_init(chan); - fluid_channel_init_ctrl(chan); -} - -/* - * delete_fluid_channel - */ -int -delete_fluid_channel(fluid_channel_t* chan) -{ - if (chan->preset) delete_fluid_preset (chan->preset); - FLUID_FREE(chan); - return FLUID_OK; -} - -/* - * fluid_channel_set_preset - */ -int -fluid_channel_set_preset(fluid_channel_t* chan, fluid_preset_t* preset) -{ - fluid_preset_notify(chan->preset, FLUID_PRESET_UNSELECTED, chan->channum); - fluid_preset_notify(preset, FLUID_PRESET_SELECTED, chan->channum); - - if (chan->preset) delete_fluid_preset (chan->preset); - chan->preset = preset; - return FLUID_OK; -} - -/* - * fluid_channel_get_preset - */ -fluid_preset_t* -fluid_channel_get_preset(fluid_channel_t* chan) -{ - return chan->preset; -} - -/* - * fluid_channel_get_banknum - */ -unsigned int -fluid_channel_get_banknum(fluid_channel_t* chan) -{ - return chan->banknum; -} - -/* - * fluid_channel_set_prognum - */ -int -fluid_channel_set_prognum(fluid_channel_t* chan, int prognum) -{ - chan->prognum = prognum; - return FLUID_OK; -} - -/* - * fluid_channel_get_prognum - */ -int -fluid_channel_get_prognum(fluid_channel_t* chan) -{ - return chan->prognum; -} - -/* - * fluid_channel_set_banknum - */ -int -fluid_channel_set_banknum(fluid_channel_t* chan, unsigned int banknum) -{ - chan->banknum = banknum; - return FLUID_OK; -} - -/* - * fluid_channel_cc - */ -int -fluid_channel_cc(fluid_channel_t* chan, int num, int value) -{ - chan->cc[num] = value; - - switch (num) { - - case SUSTAIN_SWITCH: - { - if (value < 64) { -/* printf("** sustain off\n"); */ - fluid_synth_damp_voices(chan->synth, chan->channum); - } else { -/* printf("** sustain on\n"); */ - } - } - break; - - case BANK_SELECT_MSB: - { - chan->bank_msb = (unsigned char) (value & 0x7f); -/* printf("** bank select msb recieved: %d\n", value); */ - - /* I fixed the handling of a MIDI bank select controller 0, - e.g., bank select MSB (or "coarse" bank select according to - my spec). Prior to this fix a channel's bank number was only - changed upon reception of MIDI bank select controller 32, - e.g, bank select LSB (or "fine" bank-select according to my - spec). [KLE] - - FIXME: is this correct? [PH] */ - fluid_channel_set_banknum(chan, (unsigned int)(value & 0x7f)); /* KLE */ - } - break; - - case BANK_SELECT_LSB: - { - /* FIXME: according to the Downloadable Sounds II specification, - bit 31 should be set when we receive the message on channel - 10 (drum channel) */ - fluid_channel_set_banknum(chan, (((unsigned int) value & 0x7f) - + ((unsigned int) chan->bank_msb << 7))); - } - break; - - case ALL_NOTES_OFF: - fluid_synth_all_notes_off(chan->synth, chan->channum); - break; - - case ALL_SOUND_OFF: - fluid_synth_all_sounds_off(chan->synth, chan->channum); - break; - - case ALL_CTRL_OFF: - fluid_channel_init_ctrl(chan); - fluid_synth_modulate_voices_all(chan->synth, chan->channum); - break; - - case DATA_ENTRY_MSB: - { - int data = (value << 7) + chan->cc[DATA_ENTRY_LSB]; - - if (chan->nrpn_active) /* NRPN is active? */ - { - /* SontFont 2.01 NRPN Message (Sect. 9.6, p. 74) */ - if ((chan->cc[NRPN_MSB] == 120) && (chan->cc[NRPN_LSB] < 100)) - { - if (chan->nrpn_select < GEN_LAST) - { - float val = fluid_gen_scale_nrpn(chan->nrpn_select, data); - fluid_synth_set_gen(chan->synth, chan->channum, chan->nrpn_select, val); - } - - chan->nrpn_select = 0; /* Reset to 0 */ - } - } - else if (chan->cc[RPN_MSB] == 0) /* RPN is active: MSB = 0? */ - { - switch (chan->cc[RPN_LSB]) - { - case RPN_PITCH_BEND_RANGE: - fluid_channel_pitch_wheel_sens (chan, value); /* Set bend range in semitones */ - /* FIXME - Handle LSB? (Fine bend range in cents) */ - break; - case RPN_CHANNEL_FINE_TUNE: /* Fine tune is 14 bit over +/-1 semitone (+/- 100 cents, 8192 = center) */ - fluid_synth_set_gen(chan->synth, chan->channum, GEN_FINETUNE, - (data - 8192) / 8192.0 * 100.0); - break; - case RPN_CHANNEL_COARSE_TUNE: /* Coarse tune is 7 bit and in semitones (64 is center) */ - fluid_synth_set_gen(chan->synth, chan->channum, GEN_COARSETUNE, - value - 64); - break; - case RPN_TUNING_PROGRAM_CHANGE: - break; - case RPN_TUNING_BANK_SELECT: - break; - case RPN_MODULATION_DEPTH_RANGE: - break; - } - } - - break; - } - - case NRPN_MSB: - chan->cc[NRPN_LSB] = 0; - chan->nrpn_select = 0; - chan->nrpn_active = 1; - break; - - case NRPN_LSB: - /* SontFont 2.01 NRPN Message (Sect. 9.6, p. 74) */ - if (chan->cc[NRPN_MSB] == 120) { - if (value == 100) { - chan->nrpn_select += 100; - } else if (value == 101) { - chan->nrpn_select += 1000; - } else if (value == 102) { - chan->nrpn_select += 10000; - } else if (value < 100) { - chan->nrpn_select += value; - } - } - - chan->nrpn_active = 1; - break; - - case RPN_MSB: - case RPN_LSB: - chan->nrpn_active = 0; - break; - - default: - fluid_synth_modulate_voices(chan->synth, chan->channum, 1, num); - } - - return FLUID_OK; -} - -/* - * fluid_channel_get_cc - */ -int -fluid_channel_get_cc(fluid_channel_t* chan, int num) -{ - return ((num >= 0) && (num < 128))? chan->cc[num] : 0; -} - -/* - * fluid_channel_pressure - */ -int -fluid_channel_pressure(fluid_channel_t* chan, int val) -{ - chan->channel_pressure = val; - fluid_synth_modulate_voices(chan->synth, chan->channum, 0, FLUID_MOD_CHANNELPRESSURE); - return FLUID_OK; -} - -/* - * fluid_channel_pitch_bend - */ -int -fluid_channel_pitch_bend(fluid_channel_t* chan, int val) -{ - chan->pitch_bend = val; - fluid_synth_modulate_voices(chan->synth, chan->channum, 0, FLUID_MOD_PITCHWHEEL); - return FLUID_OK; -} - -/* - * fluid_channel_pitch_wheel_sens - */ -int -fluid_channel_pitch_wheel_sens(fluid_channel_t* chan, int val) -{ - chan->pitch_wheel_sensitivity = val; - fluid_synth_modulate_voices(chan->synth, chan->channum, 0, FLUID_MOD_PITCHWHEELSENS); - return FLUID_OK; -} - -/* - * fluid_channel_get_num - */ -int -fluid_channel_get_num(fluid_channel_t* chan) -{ - return chan->channum; -} - -/* Purpose: - * Sets the index of the interpolation method used on this channel, - * as in fluid_interp in fluidsynth.h - */ -void fluid_channel_set_interp_method(fluid_channel_t* chan, int new_method) -{ - chan->interp_method = new_method; -} - -/* Purpose: - * Returns the index of the interpolation method used on this channel, - * as in fluid_interp in fluidsynth.h - */ -int fluid_channel_get_interp_method(fluid_channel_t* chan) -{ - return chan->interp_method; -} - -unsigned int fluid_channel_get_sfontnum(fluid_channel_t* chan) -{ - return chan->sfontnum; -} - -int fluid_channel_set_sfontnum(fluid_channel_t* chan, unsigned int sfontnum) -{ - chan->sfontnum = sfontnum; - return FLUID_OK; -} diff --git a/src/libs/fluidsynth/src/fluid_chan.h b/src/libs/fluidsynth/src/fluid_chan.h deleted file mode 100644 index 504aabb9a2..0000000000 --- a/src/libs/fluidsynth/src/fluid_chan.h +++ /dev/null @@ -1,107 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#ifndef _FLUID_CHAN_H -#define _FLUID_CHAN_H - -#include "fluidsynth_priv.h" -#include "fluid_midi.h" -#include "fluid_tuning.h" - -/* - * fluid_channel_t - */ -struct _fluid_channel_t -{ - int channum; - unsigned int sfontnum; - unsigned int banknum; - unsigned int prognum; - fluid_preset_t* preset; - fluid_synth_t* synth; - short key_pressure; - short channel_pressure; - short pitch_bend; - short pitch_wheel_sensitivity; - - /* controller values */ - short cc[128]; - - /* cached values of last MSB values of MSB/LSB controllers */ - unsigned char bank_msb; - int interp_method; - - /* the micro-tuning */ - fluid_tuning_t* tuning; - - /* NRPN system */ - short nrpn_select; - short nrpn_active; /* 1 if data entry CCs are for NRPN, 0 if RPN */ - - /* The values of the generators, set by NRPN messages, or by - * fluid_synth_set_gen(), are cached in the channel so they can be - * applied to future notes. They are copied to a voice's generators - * in fluid_voice_init(), wihich calls fluid_gen_init(). */ - fluid_real_t gen[GEN_LAST]; - - /* By default, the NRPN values are relative to the values of the - * generators set in the SoundFont. For example, if the NRPN - * specifies an attack of 100 msec then 100 msec will be added to the - * combined attack time of the sound font and the modulators. - * - * However, it is useful to be able to specify the generator value - * absolutely, completely ignoring the generators of the sound font - * and the values of modulators. The gen_abs field, is a boolean - * flag indicating whether the NRPN value is absolute or not. - */ - char gen_abs[GEN_LAST]; -}; - -fluid_channel_t* new_fluid_channel(fluid_synth_t* synth, int num); -int delete_fluid_channel(fluid_channel_t* chan); -void fluid_channel_init(fluid_channel_t* chan); -void fluid_channel_init_ctrl(fluid_channel_t* chan); -void fluid_channel_reset(fluid_channel_t* chan); -int fluid_channel_set_preset(fluid_channel_t* chan, fluid_preset_t* preset); -fluid_preset_t* fluid_channel_get_preset(fluid_channel_t* chan); -unsigned int fluid_channel_get_sfontnum(fluid_channel_t* chan); -int fluid_channel_set_sfontnum(fluid_channel_t* chan, unsigned int sfont); -unsigned int fluid_channel_get_banknum(fluid_channel_t* chan); -int fluid_channel_set_banknum(fluid_channel_t* chan, unsigned int bank); -int fluid_channel_set_prognum(fluid_channel_t* chan, int prognum); -int fluid_channel_get_prognum(fluid_channel_t* chan); -int fluid_channel_cc(fluid_channel_t* chan, int ctrl, int val); -int fluid_channel_pressure(fluid_channel_t* chan, int val); -int fluid_channel_pitch_bend(fluid_channel_t* chan, int val); -int fluid_channel_pitch_wheel_sens(fluid_channel_t* chan, int val); -int fluid_channel_get_cc(fluid_channel_t* chan, int num); -int fluid_channel_get_num(fluid_channel_t* chan); -void fluid_channel_set_interp_method(fluid_channel_t* chan, int new_method); -int fluid_channel_get_interp_method(fluid_channel_t* chan); - -#define fluid_channel_set_tuning(_c, _t) { (_c)->tuning = _t; } -#define fluid_channel_has_tuning(_c) ((_c)->tuning != NULL) -#define fluid_channel_get_tuning(_c) ((_c)->tuning) -#define fluid_channel_sustained(_c) ((_c)->cc[SUSTAIN_SWITCH] >= 64) -#define fluid_channel_set_gen(_c, _n, _v, _a) { (_c)->gen[_n] = _v; (_c)->gen_abs[_n] = _a; } -#define fluid_channel_get_gen(_c, _n) ((_c)->gen[_n]) -#define fluid_channel_get_gen_abs(_c, _n) ((_c)->gen_abs[_n]) - -#endif /* _FLUID_CHAN_H */ diff --git a/src/libs/fluidsynth/src/fluid_chorus.c b/src/libs/fluidsynth/src/fluid_chorus.c deleted file mode 100644 index 0f19995128..0000000000 --- a/src/libs/fluidsynth/src/fluid_chorus.c +++ /dev/null @@ -1,606 +0,0 @@ -/* - * August 24, 1998 - * Copyright (C) 1998 Juergen Mueller And Sundry Contributors - * This source code is freely redistributable and may be used for - * any purpose. This copyright notice must be maintained. - * Juergen Mueller And Sundry Contributors are not responsible for - * the consequences of using this software. - */ - -/* - - CHANGES - - - Adapted for fluidsynth, Peter Hanappe, March 2002 - - - Variable delay line implementation using bandlimited - interpolation, code reorganization: Markus Nentwig May 2002 - - */ - - -/* - * Chorus effect. - * - * Flow diagram scheme for n delays ( 1 <= n <= MAX_CHORUS ): - * - * * gain-in ___ - * ibuff -----+--------------------------------------------->| | - * | _________ | | - * | | | * level 1 | | - * +---->| delay 1 |----------------------------->| | - * | |_________| | | - * | /|\ | | - * : | | | - * : +-----------------+ +--------------+ | + | - * : | Delay control 1 |<--| mod. speed 1 | | | - * : +-----------------+ +--------------+ | | - * | _________ | | - * | | | * level n | | - * +---->| delay n |----------------------------->| | - * |_________| | | - * /|\ |___| - * | | - * +-----------------+ +--------------+ | * gain-out - * | Delay control n |<--| mod. speed n | | - * +-----------------+ +--------------+ +----->obuff - * - * - * The delay i is controlled by a sine or triangle modulation i ( 1 <= i <= n). - * - * The delay of each block is modulated between 0..depth ms - * - */ - - -/* Variable delay line implementation - * ================================== - * - * The modulated delay needs the value of the delayed signal between - * samples. A lowpass filter is used to obtain intermediate values - * between samples (bandlimited interpolation). The sample pulse - * train is convoluted with the impulse response of the low pass - * filter (sinc function). To make it work with a small number of - * samples, the sinc function is windowed (Hamming window). - * - */ - -#include "fluid_chorus.h" -#include "fluid_sys.h" - -#define MAX_CHORUS 99 -#define MAX_DELAY 100 -#define MAX_DEPTH 10 -#define MIN_SPEED_HZ 0.29 -#define MAX_SPEED_HZ 5 - -/* Length of one delay line in samples: - * Set through MAX_SAMPLES_LN2. - * For example: - * MAX_SAMPLES_LN2=12 - * => MAX_SAMPLES=pow(2,12)=4096 - * => MAX_SAMPLES_ANDMASK=4095 - */ -#define MAX_SAMPLES_LN2 12 - -#define MAX_SAMPLES (1 << (MAX_SAMPLES_LN2-1)) -#define MAX_SAMPLES_ANDMASK (MAX_SAMPLES-1) - - -/* Interpolate how many steps between samples? Must be power of two - For example: 8 => use a resolution of 256 steps between any two - samples -*/ -#define INTERPOLATION_SUBSAMPLES_LN2 8 -#define INTERPOLATION_SUBSAMPLES (1 << (INTERPOLATION_SUBSAMPLES_LN2-1)) -#define INTERPOLATION_SUBSAMPLES_ANDMASK (INTERPOLATION_SUBSAMPLES-1) - -/* Use how many samples for interpolation? Must be odd. '7' sounds - relatively clean, when listening to the modulated delay signal - alone. For a demo on aliasing try '1' With '3', the aliasing is - still quite pronounced for some input frequencies -*/ -#define INTERPOLATION_SAMPLES 5 - -/* Private data for SKEL file */ -struct _fluid_chorus_t { - /* Store the values between fluid_chorus_set_xxx and fluid_chorus_update - * Logic behind this: - * - both 'parameter' and 'new_parameter' hold the same value. - * - To change the chorus settings, 'new_parameter' is modified and - * fluid_chorus_update is called. - * - If the new value is valid, it is copied to 'parameter'. - * - If it is invalid, 'new_parameter' is restored to 'parameter'. - */ - int type; /* current value */ - int new_type; /* next value, if parameter check is OK */ - fluid_real_t depth_ms; /* current value */ - fluid_real_t new_depth_ms; /* next value, if parameter check is OK */ - fluid_real_t level; /* current value */ - fluid_real_t new_level; /* next value, if parameter check is OK */ - fluid_real_t speed_Hz; /* current value */ - fluid_real_t new_speed_Hz; /* next value, if parameter check is OK */ - int number_blocks; /* current value */ - int new_number_blocks; /* next value, if parameter check is OK */ - - fluid_real_t *chorusbuf; - int counter; - long phase[MAX_CHORUS]; - long modulation_period_samples; - int *lookup_tab; - fluid_real_t sample_rate; - - /* sinc lookup table */ - fluid_real_t sinc_table[INTERPOLATION_SAMPLES][INTERPOLATION_SUBSAMPLES]; -}; - -void fluid_chorus_triangle(int *buf, int len, int depth); -void fluid_chorus_sine(int *buf, int len, int depth); - -fluid_chorus_t* -new_fluid_chorus(fluid_real_t sample_rate) -{ - int i; int ii; - fluid_chorus_t* chorus; - - chorus = FLUID_NEW(fluid_chorus_t); - if (chorus == NULL) { - fluid_log(FLUID_PANIC, "chorus: Out of memory"); - return NULL; - } - - FLUID_MEMSET(chorus, 0, sizeof(fluid_chorus_t)); - - chorus->sample_rate = sample_rate; - - /* Lookup table for the SI function (impulse response of an ideal low pass) */ - - /* i: Offset in terms of whole samples */ - for (i = 0; i < INTERPOLATION_SAMPLES; i++){ - - /* ii: Offset in terms of fractional samples ('subsamples') */ - for (ii = 0; ii < INTERPOLATION_SUBSAMPLES; ii++){ - /* Move the origin into the center of the table */ - double i_shifted = ((double) i- ((double) INTERPOLATION_SAMPLES) / 2. - + (double) ii / (double) INTERPOLATION_SUBSAMPLES); - if (fabs(i_shifted) < 0.000001) { - /* sinc(0) cannot be calculated straightforward (limit needed - for 0/0) */ - chorus->sinc_table[i][ii] = (fluid_real_t)1.; - - } else { - chorus->sinc_table[i][ii] = (fluid_real_t)sin(i_shifted * M_PI) / (M_PI * i_shifted); - /* Hamming window */ - chorus->sinc_table[i][ii] *= (fluid_real_t)0.5 * (1.0 + cos(2.0 * M_PI * i_shifted / (fluid_real_t)INTERPOLATION_SAMPLES)); - }; - }; - }; - - /* allocate lookup tables */ - chorus->lookup_tab = FLUID_ARRAY(int, (int) (chorus->sample_rate / MIN_SPEED_HZ)); - if (chorus->lookup_tab == NULL) { - fluid_log(FLUID_PANIC, "chorus: Out of memory"); - goto error_recovery; - } - - /* allocate sample buffer */ - - chorus->chorusbuf = FLUID_ARRAY(fluid_real_t, MAX_SAMPLES); - if (chorus->chorusbuf == NULL) { - fluid_log(FLUID_PANIC, "chorus: Out of memory"); - goto error_recovery; - } - - if (fluid_chorus_init(chorus) != FLUID_OK){ - goto error_recovery; - }; - - return chorus; - - error_recovery: - delete_fluid_chorus(chorus); - return NULL; -} - - -int -fluid_chorus_init(fluid_chorus_t* chorus) -{ - int i; - - for (i = 0; i < MAX_SAMPLES; i++) { - chorus->chorusbuf[i] = 0.0; - } - - /* initialize the chorus with the default settings */ - fluid_chorus_set_nr(chorus, FLUID_CHORUS_DEFAULT_N); - fluid_chorus_set_level(chorus, FLUID_CHORUS_DEFAULT_LEVEL); - fluid_chorus_set_speed_Hz(chorus, FLUID_CHORUS_DEFAULT_SPEED); - fluid_chorus_set_depth_ms(chorus, FLUID_CHORUS_DEFAULT_DEPTH); - fluid_chorus_set_type(chorus, FLUID_CHORUS_MOD_SINE); - - return fluid_chorus_update(chorus); -} - -/* Purpose: - * Sets the number of stages. - * Requires call to fluid_chorus_update afterwards. - * Range checking is performed there.*/ -void fluid_chorus_set_nr(fluid_chorus_t* chorus, int nr) -{ - chorus->new_number_blocks = nr; -} - -/* Purpose: - * API function, read the current state of the chorus - */ -int fluid_chorus_get_nr(fluid_chorus_t* chorus) -{ - return chorus->number_blocks; -}; - -/* Purpose: - * Sets the mixing level of the signal from each delay line (linear). - * Requires calling fluid_chorus_update afterwards.*/ -void fluid_chorus_set_level(fluid_chorus_t* chorus, fluid_real_t level) -{ - chorus->new_level = level; -} - -/* Purpose: - * API function, read the current state of the chorus - */ -fluid_real_t fluid_chorus_get_level(fluid_chorus_t* chorus) -{ - return chorus->level; -}; - -/* Purpose: - * Sets the modulation frequency. - * Requires call to fluid_chorus_update afterwards. - * Range checking is performed there.*/ -void fluid_chorus_set_speed_Hz(fluid_chorus_t* chorus, fluid_real_t speed_Hz) -{ - chorus->new_speed_Hz = speed_Hz; -} - -/* Purpose: - * API function, read the current state of the chorus - */ -fluid_real_t fluid_chorus_get_speed_Hz(fluid_chorus_t* chorus) -{ - return chorus->speed_Hz; -}; - -/* Purpose: - * Sets the modulation depth in ms. - * Requires call to fluid_chorus_update afterwards. - * Range checking is performed there.*/ -void fluid_chorus_set_depth_ms(fluid_chorus_t* chorus, fluid_real_t depth_ms) -{ - chorus->new_depth_ms=depth_ms; -} - -/* Purpose: - * API function, read the current state of the chorus - */ -fluid_real_t fluid_chorus_get_depth_ms(fluid_chorus_t* chorus) -{ - return chorus->depth_ms; -}; - -/* Purpose: - * Sets the type of the modulation waveform. - * Requires call to fluid_chorus_update afterwards. - * Check for meaningful values is performed there.*/ -void fluid_chorus_set_type(fluid_chorus_t* chorus, int type) -{ - chorus->new_type=type; -} - -/* Purpose: - * API function, read the current state of the chorus - */ -int fluid_chorus_get_type(fluid_chorus_t* chorus) -{ - return chorus->type; -}; - -void -delete_fluid_chorus(fluid_chorus_t* chorus) -{ - if (chorus == NULL) { - return; - } - - if (chorus->chorusbuf != NULL) { - FLUID_FREE(chorus->chorusbuf); - } - - if (chorus->lookup_tab != NULL) { - FLUID_FREE(chorus->lookup_tab); - } - - FLUID_FREE(chorus); -} - - -/* Purpose: - * Calculates the internal chorus parameters using the settings from - * fluid_chorus_set_xxx. */ -int -fluid_chorus_update(fluid_chorus_t* chorus) -{ - int i; - int modulation_depth_samples; - - if (chorus->new_number_blocks < 0) { - fluid_log(FLUID_WARN, "chorus: number blocks must be >=0! Setting value to 0."); - chorus->new_number_blocks = 0; - } else if (chorus->new_number_blocks > MAX_CHORUS) { - fluid_log(FLUID_WARN, "chorus: number blocks larger than max. allowed! Setting value to %d.", - MAX_CHORUS); - chorus->new_number_blocks = MAX_CHORUS; - }; - - if (chorus->new_speed_Hz < MIN_SPEED_HZ) { - fluid_log(FLUID_WARN, "chorus: speed is too low (min %f)! Setting value to min.", - (double) MIN_SPEED_HZ); - chorus->new_speed_Hz = MIN_SPEED_HZ; - } else if (chorus->new_speed_Hz > MAX_SPEED_HZ) { - fluid_log(FLUID_WARN, "chorus: speed must be below %f Hz! Setting value to max.", - (double) MAX_SPEED_HZ); - chorus->new_speed_Hz = MAX_SPEED_HZ; - } - if (chorus->new_depth_ms < 0.0) { - fluid_log(FLUID_WARN, "chorus: depth must be positive! Setting value to 0."); - chorus->new_depth_ms = 0.0; - } - /* Depth: Check for too high value through modulation_depth_samples. */ - - if (chorus->new_level < 0.0) { - fluid_log(FLUID_WARN, "chorus: level must be positive! Setting value to 0."); - chorus->new_level = 0.0; - } else if (chorus->new_level > 10) { - fluid_log(FLUID_WARN, "chorus: level must be < 10. A reasonable level is << 1! " - "Setting it to 0.1."); - chorus->new_level = 0.1; - } - - /* The modulating LFO goes through a full period every x samples: */ - chorus->modulation_period_samples = chorus->sample_rate / chorus->new_speed_Hz; - - /* The variation in delay time is x: */ - modulation_depth_samples = (int) - (chorus->new_depth_ms / 1000.0 /* convert modulation depth in ms to s*/ - * chorus->sample_rate); - - if (modulation_depth_samples > MAX_SAMPLES) { - fluid_log(FLUID_WARN, "chorus: Too high depth. Setting it to max (%d).", MAX_SAMPLES); - modulation_depth_samples = MAX_SAMPLES; - } - - /* initialize LFO table */ - if (chorus->type == FLUID_CHORUS_MOD_SINE) { - fluid_chorus_sine(chorus->lookup_tab, chorus->modulation_period_samples, - modulation_depth_samples); - } else if (chorus->type == FLUID_CHORUS_MOD_TRIANGLE) { - fluid_chorus_triangle(chorus->lookup_tab, chorus->modulation_period_samples, - modulation_depth_samples); - } else { - fluid_log(FLUID_WARN, "chorus: Unknown modulation type. Using sinewave."); - chorus->type = FLUID_CHORUS_MOD_SINE; - fluid_chorus_sine(chorus->lookup_tab, chorus->modulation_period_samples, - modulation_depth_samples); - }; - - for (i = 0; i < chorus->number_blocks; i++) { - /* Set the phase of the chorus blocks equally spaced */ - chorus->phase[i] = (int) ((double) chorus->modulation_period_samples - * (double) i / (double) chorus->number_blocks); - } - - /* Start of the circular buffer */ - chorus->counter = 0; - - chorus->type = chorus->new_type; - chorus->depth_ms = chorus->new_depth_ms; - chorus->level = chorus->new_level; - chorus->speed_Hz = chorus->new_speed_Hz; - chorus->number_blocks = chorus->new_number_blocks; - return FLUID_OK; - -/* failure: */ - /* Note: This lives on the assumption, that the last chorus values were correct. - * If not, this will loop forever and a day. */ -/* fluid_log(FLUID_WARN, "chorus: Restoring last good settings"); */ -/* chorus->new_type = chorus->type; */ -/* chorus->new_depth_ms = chorus->depth_ms; */ -/* chorus->new_level = chorus->level; */ -/* chorus->new_speed_Hz = chorus->speed_Hz; */ -/* chorus->new_number_blocks = chorus->number_blocks; */ -/* return FLUID_FAILED; */ -} - - -void fluid_chorus_processmix(fluid_chorus_t* chorus, fluid_real_t *in, - fluid_real_t *left_out, fluid_real_t *right_out) -{ - int sample_index; - int i; - fluid_real_t d_in, d_out; - - for (sample_index = 0; sample_index < FLUID_BUFSIZE; sample_index++) { - - d_in = in[sample_index]; - d_out = 0.0f; - -# if 0 - /* Debug: Listen to the chorus signal only */ - left_out[sample_index]=0; - right_out[sample_index]=0; -#endif - - /* Write the current sample into the circular buffer */ - chorus->chorusbuf[chorus->counter] = d_in; - - for (i = 0; i < chorus->number_blocks; i++) { - int ii; - /* Calculate the delay in subsamples for the delay line of chorus block nr. */ - - /* The value in the lookup table is so, that this expression - * will always be positive. It will always include a number of - * full periods of MAX_SAMPLES*INTERPOLATION_SUBSAMPLES to - * remain positive at all times. */ - int pos_subsamples = (INTERPOLATION_SUBSAMPLES * chorus->counter - - chorus->lookup_tab[chorus->phase[i]]); - - int pos_samples = pos_subsamples/INTERPOLATION_SUBSAMPLES; - - /* modulo divide by INTERPOLATION_SUBSAMPLES */ - pos_subsamples &= INTERPOLATION_SUBSAMPLES_ANDMASK; - - for (ii = 0; ii < INTERPOLATION_SAMPLES; ii++){ - /* Add the delayed signal to the chorus sum d_out Note: The - * delay in the delay line moves backwards for increasing - * delay!*/ - - /* The & in chorusbuf[...] is equivalent to a division modulo - MAX_SAMPLES, only faster. */ - d_out += chorus->chorusbuf[pos_samples & MAX_SAMPLES_ANDMASK] - * chorus->sinc_table[ii][pos_subsamples]; - - pos_samples--; - }; - /* Cycle the phase of the modulating LFO */ - chorus->phase[i]++; - chorus->phase[i] %= (chorus->modulation_period_samples); - } /* foreach chorus block */ - - d_out *= chorus->level; - - /* Add the chorus sum d_out to output */ - left_out[sample_index] += d_out; - right_out[sample_index] += d_out; - - /* Move forward in circular buffer */ - chorus->counter++; - chorus->counter %= MAX_SAMPLES; - - } /* foreach sample */ -} - -/* Duplication of code ... (replaces sample data instead of mixing) */ -void fluid_chorus_processreplace(fluid_chorus_t* chorus, fluid_real_t *in, - fluid_real_t *left_out, fluid_real_t *right_out) -{ - int sample_index; - int i; - fluid_real_t d_in, d_out; - - for (sample_index = 0; sample_index < FLUID_BUFSIZE; sample_index++) { - - d_in = in[sample_index]; - d_out = 0.0f; - -# if 0 - /* Debug: Listen to the chorus signal only */ - left_out[sample_index]=0; - right_out[sample_index]=0; -#endif - - /* Write the current sample into the circular buffer */ - chorus->chorusbuf[chorus->counter] = d_in; - - for (i = 0; i < chorus->number_blocks; i++) { - int ii; - /* Calculate the delay in subsamples for the delay line of chorus block nr. */ - - /* The value in the lookup table is so, that this expression - * will always be positive. It will always include a number of - * full periods of MAX_SAMPLES*INTERPOLATION_SUBSAMPLES to - * remain positive at all times. */ - int pos_subsamples = (INTERPOLATION_SUBSAMPLES * chorus->counter - - chorus->lookup_tab[chorus->phase[i]]); - - int pos_samples = pos_subsamples / INTERPOLATION_SUBSAMPLES; - - /* modulo divide by INTERPOLATION_SUBSAMPLES */ - pos_subsamples &= INTERPOLATION_SUBSAMPLES_ANDMASK; - - for (ii = 0; ii < INTERPOLATION_SAMPLES; ii++){ - /* Add the delayed signal to the chorus sum d_out Note: The - * delay in the delay line moves backwards for increasing - * delay!*/ - - /* The & in chorusbuf[...] is equivalent to a division modulo - MAX_SAMPLES, only faster. */ - d_out += chorus->chorusbuf[pos_samples & MAX_SAMPLES_ANDMASK] - * chorus->sinc_table[ii][pos_subsamples]; - - pos_samples--; - }; - /* Cycle the phase of the modulating LFO */ - chorus->phase[i]++; - chorus->phase[i] %= (chorus->modulation_period_samples); - } /* foreach chorus block */ - - d_out *= chorus->level; - - /* Store the chorus sum d_out to output */ - left_out[sample_index] = d_out; - right_out[sample_index] = d_out; - - /* Move forward in circular buffer */ - chorus->counter++; - chorus->counter %= MAX_SAMPLES; - - } /* foreach sample */ -} - -/* Purpose: - * - * Calculates a modulation waveform (sine) Its value ( modulo - * MAXSAMPLES) varies between 0 and depth*INTERPOLATION_SUBSAMPLES. - * Its period length is len. The waveform data will be used modulo - * MAXSAMPLES only. Since MAXSAMPLES is substracted from the waveform - * a couple of times here, the resulting (current position in - * buffer)-(waveform sample) will always be positive. - */ -void fluid_chorus_sine(int *buf, int len, int depth) -{ - int i; - double val; - - for (i = 0; i < len; i++) { - val = sin((double) i / (double)len * 2.0 * M_PI); - buf[i] = (int) ((1.0 + val) * (double) depth / 2.0 * (double) INTERPOLATION_SUBSAMPLES); - buf[i] -= 3* MAX_SAMPLES * INTERPOLATION_SUBSAMPLES; - // printf("%i %i\n",i,buf[i]); - } -} - -/* Purpose: - * Calculates a modulation waveform (triangle) - * See fluid_chorus_sine for comments. - */ -void fluid_chorus_triangle(int *buf, int len, int depth) -{ - int i=0; - int ii=len-1; - double val; - double val2; - - while (i <= ii){ - val = i * 2.0 / len * (double)depth * (double) INTERPOLATION_SUBSAMPLES; - val2= (int) (val + 0.5) - 3 * MAX_SAMPLES * INTERPOLATION_SUBSAMPLES; - buf[i++] = (int) val2; - buf[ii--] = (int) val2; - } -} - -void -fluid_chorus_reset(fluid_chorus_t* chorus) -{ - fluid_chorus_init(chorus); -} diff --git a/src/libs/fluidsynth/src/fluid_chorus.h b/src/libs/fluidsynth/src/fluid_chorus.h deleted file mode 100644 index e82b2ff8c4..0000000000 --- a/src/libs/fluidsynth/src/fluid_chorus.h +++ /dev/null @@ -1,56 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - - -#ifndef _FLUID_CHORUS_H -#define _FLUID_CHORUS_H - -#include "fluidsynth_priv.h" - - -typedef struct _fluid_chorus_t fluid_chorus_t; - -/* - * chorus - */ -fluid_chorus_t* new_fluid_chorus(fluid_real_t sample_rate); -void delete_fluid_chorus(fluid_chorus_t* chorus); -void fluid_chorus_processmix(fluid_chorus_t* chorus, fluid_real_t *in, - fluid_real_t *left_out, fluid_real_t *right_out); -void fluid_chorus_processreplace(fluid_chorus_t* chorus, fluid_real_t *in, - fluid_real_t *left_out, fluid_real_t *right_out); - -int fluid_chorus_init(fluid_chorus_t* chorus); -void fluid_chorus_reset(fluid_chorus_t* chorus); - -void fluid_chorus_set_nr(fluid_chorus_t* chorus, int nr); -void fluid_chorus_set_level(fluid_chorus_t* chorus, fluid_real_t level); -void fluid_chorus_set_speed_Hz(fluid_chorus_t* chorus, fluid_real_t speed_Hz); -void fluid_chorus_set_depth_ms(fluid_chorus_t* chorus, fluid_real_t depth_ms); -void fluid_chorus_set_type(fluid_chorus_t* chorus, int type); -int fluid_chorus_update(fluid_chorus_t* chorus); -int fluid_chorus_get_nr(fluid_chorus_t* chorus); -fluid_real_t fluid_chorus_get_level(fluid_chorus_t* chorus); -fluid_real_t fluid_chorus_get_speed_Hz(fluid_chorus_t* chorus); -fluid_real_t fluid_chorus_get_depth_ms(fluid_chorus_t* chorus); -int fluid_chorus_get_type(fluid_chorus_t* chorus); - - -#endif /* _FLUID_CHORUS_H */ diff --git a/src/libs/fluidsynth/src/fluid_cmd.c b/src/libs/fluidsynth/src/fluid_cmd.c deleted file mode 100644 index 086a225fed..0000000000 --- a/src/libs/fluidsynth/src/fluid_cmd.c +++ /dev/null @@ -1,1850 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#include "fluidsynth_priv.h" -#include "fluid_cmd.h" -#include "fluid_synth.h" -#include "fluid_settings.h" -#include "fluid_io.h" -#include "fluid_hash.h" -#include "fluid_sys.h" -#include "fluid_io.h" -#include "fluid_midi_router.h" -#include "fluid_sfont.h" - -#if WITH_READLINE -#include -#include -#endif - -#define MAX_TOKENS 100 /* LADSPA plugins need lots of parameters */ -#define MAX_COMMAND_LEN 1024 /* max command length accepted by fluid_command() */ -#define FLUID_WORKLINELENGTH 1024 /* LADSPA plugins use long command lines */ - -void fluid_shell_settings(fluid_settings_t* settings) -{ - fluid_settings_register_str(settings, "shell.prompt", "", 0, NULL, NULL); - fluid_settings_register_int(settings, "shell.port", 9800, 1, 65535, 0, NULL, NULL); -} - - -/** the table of all handled commands */ - -fluid_cmd_t fluid_commands[] = { - { "help", "general", (fluid_cmd_func_t) fluid_handle_help, NULL, - "help Command summary. 'help help' for more help topics" }, - { "quit", "general", (fluid_cmd_func_t) fluid_handle_quit, NULL, - "quit Quit the synthesizer" }, - { "noteon", "event", (fluid_cmd_func_t) fluid_handle_noteon, NULL, - "noteon chan key vel Send noteon" }, - { "noteoff", "event", (fluid_cmd_func_t) fluid_handle_noteoff, NULL, - "noteoff chan key Send noteoff" }, - { "cc", "event", (fluid_cmd_func_t) fluid_handle_cc, NULL, - "cc chan ctrl value Send control-change message" }, - { "prog", "event", (fluid_cmd_func_t) fluid_handle_prog, NULL, - "prog chan num Send program-change message" }, - { "select", "event", (fluid_cmd_func_t) fluid_handle_select, NULL, - "select chan sfont bank prog Combination of bank-select and program-change" }, - { "load", "general", (fluid_cmd_func_t) fluid_handle_load, NULL, - "load file [reset] [bankofs] Load SoundFont (reset=0|1, def 1; bankofs=n, def 0)" }, - { "unload", "general", (fluid_cmd_func_t) fluid_handle_unload, NULL, - "unload id [reset] Unload SoundFont by ID (reset=0|1, default 1)"}, - { "reload", "general", (fluid_cmd_func_t) fluid_handle_reload, NULL, - "reload id Reload the SoundFont with the specified ID" }, - { "fonts", "general", (fluid_cmd_func_t) fluid_handle_fonts, NULL, - "fonts Display the list of loaded SoundFonts" }, - { "inst", "general", (fluid_cmd_func_t) fluid_handle_inst, NULL, - "inst font Print out the available instruments for the font" }, - { "channels", "general", (fluid_cmd_func_t) fluid_handle_channels, NULL, - "channels [-verbose] Print out preset of all channels" }, - { "interp", "general", (fluid_cmd_func_t) fluid_handle_interp, NULL, - "interp num Choose interpolation method for all channels" }, - { "interpc", "general", (fluid_cmd_func_t) fluid_handle_interpc, NULL, - "interpc chan num Choose interpolation method for one channel" }, - { "rev_preset", "reverb", (fluid_cmd_func_t) fluid_handle_reverbpreset, NULL, - "rev_preset num Load preset num into the reverb unit" }, - { "rev_setroomsize", "reverb", (fluid_cmd_func_t) fluid_handle_reverbsetroomsize, NULL, - "rev_setroomsize num Change reverb room size" }, - { "rev_setdamp", "reverb", (fluid_cmd_func_t) fluid_handle_reverbsetdamp, NULL, - "rev_setdamp num Change reverb damping" }, - { "rev_setwidth", "reverb", (fluid_cmd_func_t) fluid_handle_reverbsetwidth, NULL, - "rev_setwidth num Change reverb width" }, - { "rev_setlevel", "reverb", (fluid_cmd_func_t) fluid_handle_reverbsetlevel, NULL, - "rev_setlevel num Change reverb level" }, - { "reverb", "reverb", (fluid_cmd_func_t) fluid_handle_reverb, NULL, - "reverb [0|1|on|off] Turn the reverb on or off" }, - { "cho_set_nr", "chorus", (fluid_cmd_func_t) fluid_handle_chorusnr, NULL, - "cho_set_nr n Use n delay lines (default 3)" }, - { "cho_set_level", "chorus", (fluid_cmd_func_t) fluid_handle_choruslevel, NULL, - "cho_set_level num Set output level of each chorus line to num" }, - { "cho_set_speed", "chorus", (fluid_cmd_func_t) fluid_handle_chorusspeed, NULL, - "cho_set_speed num Set mod speed of chorus to num (Hz)" }, - { "cho_set_depth", "chorus", (fluid_cmd_func_t) fluid_handle_chorusdepth, NULL, - "cho_set_depth num Set chorus modulation depth to num (ms)" }, - { "chorus", "chorus", (fluid_cmd_func_t) fluid_handle_chorus, NULL, - "chorus [0|1|on|off] Turn the chorus on or off" }, - { "gain", "general", (fluid_cmd_func_t) fluid_handle_gain, NULL, - "gain value Set the master gain (0 < gain < 5)" }, - { "tuning", "tuning", (fluid_cmd_func_t) fluid_handle_tuning, NULL, - "tuning name bank prog Create a tuning with name, bank number, \n" - " and program number (0 <= bank,prog <= 127)" }, - { "tune", "tuning", (fluid_cmd_func_t) fluid_handle_tune, NULL, - "tune bank prog key pitch Tune a key" }, - { "settuning", "tuning", (fluid_cmd_func_t) fluid_handle_settuning, NULL, - "settuning chan bank prog Set the tuning for a MIDI channel" }, - { "resettuning", "tuning", (fluid_cmd_func_t) fluid_handle_resettuning, NULL, - "resettuning chan Restore the default tuning of a MIDI channel" }, - { "tunings", "tuning", (fluid_cmd_func_t) fluid_handle_tunings, NULL, - "tunings Print the list of available tunings" }, - { "dumptuning", "tuning", (fluid_cmd_func_t) fluid_handle_dumptuning, NULL, - "dumptuning bank prog Print the pitch details of the tuning" }, - { "reset", "general", (fluid_cmd_func_t) fluid_handle_reset, NULL, - "reset System reset (all notes off, reset controllers)" }, - { "set", "settings", (fluid_cmd_func_t) fluid_handle_set, NULL, - "set name value Set the value of a controller or settings" }, - { "get", "settings", (fluid_cmd_func_t) fluid_handle_get, NULL, - "get name Get the value of a controller or settings" }, - { "info", "settings", (fluid_cmd_func_t) fluid_handle_info, NULL, - "info name Get information about a controller or settings" }, - { "settings", "settings", (fluid_cmd_func_t) fluid_handle_settings, NULL, - "settings Print out all settings" }, - { "echo", "general", (fluid_cmd_func_t) fluid_handle_echo, NULL, - "echo arg Print arg" }, - /* LADSPA-related commands */ -#ifdef LADSPA - { "ladspa_clear", "ladspa", (fluid_cmd_func_t) fluid_LADSPA_handle_clear, NULL, - "ladspa_clear Resets LADSPA effect unit to bypass state"}, - { "ladspa_add", "ladspa", (fluid_cmd_func_t) fluid_LADSPA_handle_add, NULL, - "ladspa_add lib plugin n1 <- p1 n2 -> p2 ... Loads and connects LADSPA plugin"}, - { "ladspa_start", "ladspa", (fluid_cmd_func_t) fluid_LADSPA_handle_start, NULL, - "ladspa_start Starts LADSPA effect unit"}, - { "ladspa_declnode", "ladspa", (fluid_cmd_func_t) fluid_LADSPA_handle_declnode, NULL, - "ladspa_declnode node value Declares control node `node' with value `value'"}, - { "ladspa_setnode", "ladspa", (fluid_cmd_func_t) fluid_LADSPA_handle_setnode, NULL, - "ladspa_setnode node value Assigns `value' to `node'"}, -#endif - { "router_clear", "router", (fluid_cmd_func_t) fluid_midi_router_handle_clear, NULL, - "router_clear Clears all routing rules from the midi router"}, - { "router_default", "router", (fluid_cmd_func_t) fluid_midi_router_handle_default, NULL, - "router_default Resets the midi router to default state"}, - { "router_begin", "router", (fluid_cmd_func_t) fluid_midi_router_handle_begin, NULL, - "router_begin [note|cc|prog|pbend|cpress|kpress]: Starts a new routing rule"}, - { "router_chan", "router", (fluid_cmd_func_t) fluid_midi_router_handle_chan, NULL, - "router_chan min max mul add filters and maps midi channels on current rule"}, - { "router_par1", "router", (fluid_cmd_func_t) fluid_midi_router_handle_par1, NULL, - "router_par1 min max mul add filters and maps parameter 1 (key/ctrl nr)"}, - { "router_par2", "router", (fluid_cmd_func_t) fluid_midi_router_handle_par2, NULL, - "router_par2 min max mul add filters and maps parameter 2 (vel/cc val)"}, - { "router_end", "router", (fluid_cmd_func_t) fluid_midi_router_handle_end, NULL, - "router_end closes and commits the current routing rule"}, - { NULL, NULL, NULL, NULL, NULL } -}; - -/** - * Process a string command. - * NOTE: FluidSynth 1.0.8+ no longer modifies the 'cmd' string. - * @param handle FluidSynth command handler - * @param cmd Command string (NOTE: Gets modified by FluidSynth prior to 1.0.8) - * @param out Output stream to display command response to - * @return Integer value corresponding to: -1 on command error, 0 on success, - * 1 if 'cmd' is a comment or is empty and -2 if quit was issued - */ -int -fluid_command(fluid_cmd_handler_t* handler, char* cmd, fluid_ostream_t out) -{ - char* token[MAX_TOKENS]; - char buf[MAX_COMMAND_LEN+1]; - char *strtok, *tok; - int num_tokens = 0; - - if (cmd[0] == '#') { - return 1; - } - - if (strlen (cmd) > MAX_COMMAND_LEN) - { - fluid_ostream_printf(out, "Command exceeded max length of %d chars\n", - MAX_COMMAND_LEN); - return -1; - } - - FLUID_STRCPY(buf, cmd); /* copy - since fluid_strtok thrashes it */ - strtok = buf; - - /* tokenize the input line */ - while ((tok = fluid_strtok (&strtok, " \t\n\r"))) - token[num_tokens++] = tok; - - if (num_tokens == 0) return 1; - - /* handle the command */ - return fluid_cmd_handler_handle(handler, num_tokens, &token[0], out); -} - -struct _fluid_shell_t { - fluid_settings_t* settings; - fluid_cmd_handler_t* handler; - fluid_thread_t* thread; - fluid_istream_t in; - fluid_ostream_t out; -}; - -int fluid_shell_run(fluid_shell_t* shell); -void fluid_shell_init(fluid_shell_t* shell, - fluid_settings_t* settings, fluid_cmd_handler_t* handler, - fluid_istream_t in, fluid_ostream_t out); - - -fluid_shell_t* new_fluid_shell(fluid_settings_t* settings, fluid_cmd_handler_t* handler, - fluid_istream_t in, fluid_ostream_t out, int thread) -{ - fluid_shell_t* shell = FLUID_NEW(fluid_shell_t); - if (shell == NULL) { - FLUID_LOG (FLUID_PANIC, "Out of memory"); - return NULL; - } - - - fluid_shell_init(shell, settings, handler, in, out); - - if (thread) { - shell->thread = new_fluid_thread((fluid_thread_func_t) fluid_shell_run, shell, 1); - if (shell->thread == NULL) { - delete_fluid_shell(shell); - return NULL; - } - } else { - shell->thread = NULL; - fluid_shell_run(shell); - } - - return shell; - -} - -void fluid_shell_init(fluid_shell_t* shell, - fluid_settings_t* settings, fluid_cmd_handler_t* handler, - fluid_istream_t in, fluid_ostream_t out) -{ - shell->settings = settings; - shell->handler = handler; - shell->in = in; - shell->out = out; -} - -void delete_fluid_shell(fluid_shell_t* shell) -{ - if (shell->thread != NULL) { - delete_fluid_thread(shell->thread); - } - - FLUID_FREE(shell); -} - - -int fluid_shell_run(fluid_shell_t* shell) -{ - char workline[FLUID_WORKLINELENGTH]; - char* prompt = ""; - int cont = 1; - int errors = 0; - int n; - - if (shell->settings) { - fluid_settings_getstr(shell->settings, "shell.prompt", &prompt); - } - - /* handle user input */ - while (cont) { - - n = fluid_istream_readline(shell->in, prompt, workline, FLUID_WORKLINELENGTH); - - if (n < 0) { - break; - } - -#if WITH_READLINE - if (shell->in == fluid_get_stdin()) { - add_history(workline); - } -#endif - - /* handle the command */ - switch (fluid_command(shell->handler, workline, shell->out)) { - - case 1: /* empty line or comment */ - break; - - case -1: /* erronous command */ - errors++; - case 0: /* valid command */ - break; - - case -2: /* quit */ - cont = 0; - break; - } - - if (n == 0) { - break; - } - } - - return errors; -} - - -void -fluid_usershell(fluid_settings_t* settings, fluid_cmd_handler_t* handler) -{ - fluid_shell_t shell; - fluid_shell_init(&shell, settings, handler, fluid_get_stdin(), fluid_get_stdout()); - fluid_shell_run(&shell); -} - -int -fluid_source(fluid_cmd_handler_t* handler, char* filename) -{ - int file; - fluid_shell_t shell; - -#ifdef WIN32 - file = _open(filename, _O_RDONLY); -#else - file = open(filename, O_RDONLY); -#endif - if (file < 0) { - return file; - } - fluid_shell_init(&shell, NULL, handler, file, fluid_get_stdout()); - return fluid_shell_run(&shell); -} - - -char* -fluid_get_userconf(char* buf, int len) -{ -#if defined(WIN32) || defined(MACOS9) - return NULL; -#else - char* home = getenv("HOME"); - if (home == NULL) { - return NULL; - } else { - snprintf(buf, len, "%s/.fluidsynth", home); - return buf; - } -#endif -} - -char* -fluid_get_sysconf(char* buf, int len) -{ -#if defined(WIN32) || defined(MACOS9) - return NULL; -#else - snprintf(buf, len, "/etc/fluidsynth.conf"); - return buf; -#endif -} - - -/* - * handlers - */ -int -fluid_handle_noteon(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - if (ac < 3) { - fluid_ostream_printf(out, "noteon: too few arguments\n"); - return -1; - } - if (!fluid_is_number(av[0]) || !fluid_is_number(av[1]) || !fluid_is_number(av[2])) { - fluid_ostream_printf(out, "noteon: invalid argument\n"); - return -1; - } - return fluid_synth_noteon(synth, atoi(av[0]), atoi(av[1]), atoi(av[2])); -} - -int -fluid_handle_noteoff(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - if (ac < 2) { - fluid_ostream_printf(out, "noteoff: too few arguments\n"); - return -1; - } - if (!fluid_is_number(av[0]) || !fluid_is_number(av[1])) { - fluid_ostream_printf(out, "noteon: invalid argument\n"); - return -1; - } - return fluid_synth_noteoff(synth, atoi(av[0]), atoi(av[1])); -} - -int -fluid_handle_cc(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - if (ac < 3) { - fluid_ostream_printf(out, "cc: too few arguments\n"); - return -1; - } - if (!fluid_is_number(av[0]) || !fluid_is_number(av[1]) || !fluid_is_number(av[2])) { - fluid_ostream_printf(out, "cc: invalid argument\n"); - return -1; - } - return fluid_synth_cc(synth, atoi(av[0]), atoi(av[1]), atoi(av[2])); -} - -int -fluid_handle_prog(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - if (ac < 2) { - fluid_ostream_printf(out, "prog: too few arguments\n"); - return -1; - } - if (!fluid_is_number(av[0]) || !fluid_is_number(av[1])) { - fluid_ostream_printf(out, "prog: invalid argument\n"); - return -1; - } - return fluid_synth_program_change(synth, atoi(av[0]), atoi(av[1])); -} - -int -fluid_handle_select(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - int sfont_id; - int chan; - int bank; - int prog; - - if (ac < 4) { - fluid_ostream_printf(out, "preset: too few arguments\n"); - return -1; - } - if (!fluid_is_number(av[0]) || !fluid_is_number(av[1]) - || !fluid_is_number(av[2]) || !fluid_is_number(av[3])) { - fluid_ostream_printf(out, "preset: invalid argument\n"); - return -1; - } - - chan = atoi(av[0]); - sfont_id = atoi(av[1]); - bank = atoi(av[2]); - prog = atoi(av[3]); - - if (sfont_id != 0) { - return fluid_synth_program_select(synth, chan, sfont_id, bank, prog); - } else { - if (fluid_synth_bank_select(synth, chan, bank) == FLUID_OK) { - return fluid_synth_program_change(synth, chan, prog); - } - return FLUID_FAILED; - } -} - -int -fluid_handle_inst(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - int font; - fluid_sfont_t* sfont; - fluid_preset_t preset; - int offset; - - if (ac < 1) { - fluid_ostream_printf(out, "inst: too few arguments\n"); - return -1; - } - - if (!fluid_is_number(av[0])) { - fluid_ostream_printf(out, "inst: invalid argument\n"); - return -1; - } - - font = atoi(av[0]); - - sfont = fluid_synth_get_sfont_by_id(synth, font); - offset = fluid_synth_get_bank_offset(synth, font); - - if (sfont == NULL) { - fluid_ostream_printf(out, "inst: invalid font number\n"); - return -1; - } - - fluid_sfont_iteration_start(sfont); - - while (fluid_sfont_iteration_next(sfont, &preset)) { - fluid_ostream_printf(out, "%03d-%03d %s\n", - fluid_preset_get_banknum(&preset) + offset, - fluid_preset_get_num(&preset), - fluid_preset_get_name(&preset)); - } - - return 0; -} - - -int -fluid_handle_channels(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - int i; - fluid_preset_t* preset; - int verbose = 0; - - if (ac > 0 && strcmp( av[0], "-verbose") == 0) verbose = 1; - - for (i = 0; i < fluid_synth_count_midi_channels(synth); i++) { - preset = fluid_synth_get_channel_preset(synth, i); - if (preset == NULL) fluid_ostream_printf(out, "chan %d, no preset\n", i); - else if (!verbose) fluid_ostream_printf(out, "chan %d, %s\n", i, fluid_preset_get_name(preset)); - else fluid_ostream_printf(out, "chan %d, sfont %d, bank %d, preset %d, %s\n", i, - fluid_sfont_get_id( preset->sfont), - fluid_preset_get_banknum(preset), - fluid_preset_get_num(preset), - fluid_preset_get_name(preset)); - } - return 0; -} - -int -fluid_handle_load(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - char buf[1024]; - int id; - int reset = 1; - int offset = 0; - - if (ac < 1) { - fluid_ostream_printf(out, "load: too few arguments\n"); - return -1; - } - if (ac == 2) { - reset = atoi(av[1]); - } - if (ac == 3) { - offset = atoi(av[2]); - } - - /* Load the SoundFont without resetting the programs. The reset will - * be done later (if requested). */ - id = fluid_synth_sfload(synth, fluid_expand_path(av[0], buf, 1024), 0); - - if (id == -1) { - fluid_ostream_printf(out, "failed to load the SoundFont\n"); - return -1; - } else { - fluid_ostream_printf(out, "loaded SoundFont has ID %d\n", id); - } - - if (offset) { - fluid_synth_set_bank_offset(synth, id, offset); - } - - /* The reset should be done after the offset is set. */ - if (reset) { - fluid_synth_program_reset(synth); - } - - return 0; -} - -int -fluid_handle_unload(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - int reset = 1; - if (ac < 1) { - fluid_ostream_printf(out, "unload: too few arguments\n"); - return -1; - } - if (!fluid_is_number(av[0])) { - fluid_ostream_printf(out, "unload: expected a number as argument\n"); - return -1; - } - if (ac == 2) { - reset = atoi(av[1]); - } - if (fluid_synth_sfunload(synth, atoi(av[0]), reset) != 0) { - fluid_ostream_printf(out, "failed to unload the SoundFont\n"); - return -1; - } - return 0; -} - -int -fluid_handle_reload(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - if (ac < 1) { - fluid_ostream_printf(out, "reload: too few arguments\n"); - return -1; - } - if (!fluid_is_number(av[0])) { - fluid_ostream_printf(out, "reload: expected a number as argument\n"); - return -1; - } - if (fluid_synth_sfreload(synth, atoi(av[0])) == -1) { - fluid_ostream_printf(out, "failed to reload the SoundFont\n"); - return -1; - } - return 0; -} - - -int -fluid_handle_fonts(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - int i; - fluid_sfont_t* sfont; - int num; - - num = fluid_synth_sfcount(synth); - - if (num == 0) { - fluid_ostream_printf(out, "no SoundFont loaded (try load)\n"); - return 0; - } - - fluid_ostream_printf(out, "ID Name\n"); - - for (i = 0; i < num; i++) { - sfont = fluid_synth_get_sfont(synth, i); - fluid_ostream_printf(out, "%2d %s\n", - fluid_sfont_get_id(sfont), - fluid_sfont_get_name(sfont)); - } - - return 0; -} - -int -fluid_handle_mstat(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ -/* fluid_ostream_printf(out, "Dvr=%s, Dev=%s\n", */ -/* fluid_midi_handler_get_driver_name(midi), */ -/* fluid_midi_handler_get_device_name(midi)); */ -/* fluid_ostream_printf(out, "Stat=%s, On=%d, Off=%d, Prog=%d, Pbend=%d, Err=%d\n", */ -/* fluid_midi_handler_get_status(midi), */ -/* fluid_midi_handler_get_event_count(midi, 0x90), */ -/* fluid_midi_handler_get_event_count(midi, 0x80), */ -/* fluid_midi_handler_get_event_count(midi, 0xc0), */ -/* fluid_midi_handler_get_event_count(midi, 0xe0), */ -/* fluid_midi_handler_get_event_count(midi, 0)); */ - fluid_ostream_printf(out, "not yet implemented\n"); - return -1; -} - -/* Purpose: - * Response to 'rev_preset' command. - * Load the values from a reverb preset into the reverb unit. */ -int -fluid_handle_reverbpreset(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - int reverb_preset_number; - if (ac < 1) { - fluid_ostream_printf(out, "rev_preset: too few arguments\n"); - return -1; - } - reverb_preset_number = atoi(av[0]); - if (fluid_synth_set_reverb_preset(synth, reverb_preset_number)!=FLUID_OK){ - fluid_ostream_printf(out, "rev_preset: Failed. Parameter out of range?\n"); - return -1; - }; - return 0; -} - -/* Purpose: - * Response to 'rev_setroomsize' command. - * Load the new room size into the reverb unit. */ -int -fluid_handle_reverbsetroomsize(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - fluid_real_t room_size; - if (ac < 1) { - fluid_ostream_printf(out, "rev_setroomsize: too few arguments.\n"); - return -1; - } - room_size = atof(av[0]); - if (room_size < 0){ - fluid_ostream_printf(out, "rev_setroomsize: Room size must be positive!\n"); - return -1; - } - if (room_size > 1.2){ - fluid_ostream_printf(out, "rev_setroomsize: Room size too big!\n"); - return -1; - } - fluid_revmodel_setroomsize(synth->reverb, room_size); - return 0; -} - -/* Purpose: - * Response to 'rev_setdamp' command. - * Load the new damp factor into the reverb unit. */ -int -fluid_handle_reverbsetdamp(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - fluid_real_t damp; - if (ac < 1) { - fluid_ostream_printf(out, "rev_setdamp: too few arguments.\n"); - return -1; - } - damp = atof(av[0]); - if ((damp < 0.0f) || (damp > 1)){ - fluid_ostream_printf(out, "rev_setdamp: damp must be between 0 and 1!\n"); - return -1; - } - fluid_revmodel_setdamp(synth->reverb, damp); - return 0; -} - -/* Purpose: - * Response to 'rev_setwidth' command. - * Load the new width into the reverb unit. */ -int -fluid_handle_reverbsetwidth(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - fluid_real_t width; - if (ac < 1) { - fluid_ostream_printf(out, "rev_setwidth: too few arguments.\n"); - return -1; - } - width = atof(av[0]); - if ((width < 0) || (width > 100)){ - fluid_ostream_printf(out, "rev_setroomsize: Too wide! (0..100)\n"); - return 0; - } - fluid_revmodel_setwidth(synth->reverb, width); - return 0; -} - -/* Purpose: - * Response to 'rev_setlevel' command. - * Load the new level into the reverb unit. */ -int -fluid_handle_reverbsetlevel(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - fluid_real_t level; - if (ac < 1) { - fluid_ostream_printf(out, "rev_setlevel: too few arguments.\n"); - return -1; - } - level = atof(av[0]); - if (abs(level) > 30){ - fluid_ostream_printf(out, "rev_setlevel: Value too high! (Value of 10 =+20 dB)\n"); - return 0; - } - fluid_revmodel_setlevel(synth->reverb, level); - return 0; -} - -/* Purpose: - * Response to 'reverb' command. - * Change the FLUID_REVERB flag in the synth */ -int -fluid_handle_reverb(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - if (ac < 1) { - fluid_ostream_printf(out, "reverb: too few arguments.\n"); - return -1; - } - - if ((strcmp(av[0], "0") == 0) || (strcmp(av[0], "off") == 0)) { - fluid_synth_set_reverb_on(synth,0); - } else if ((strcmp(av[0], "1") == 0) || (strcmp(av[0], "on") == 0)) { - fluid_synth_set_reverb_on(synth,1); - } else { - fluid_ostream_printf(out, "reverb: invalid arguments %s [0|1|on|off]", av[0]); - return -1; - } - - return 0; -} - - -/* Purpose: - * Response to 'chorus_setnr' command */ -int -fluid_handle_chorusnr(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - int nr; - if (ac < 1) { - fluid_ostream_printf(out, "cho_set_nr: too few arguments.\n"); - return -1; - } - nr = atoi(av[0]); - fluid_chorus_set_nr(synth->chorus, nr); - return fluid_chorus_update(synth->chorus); -} - -/* Purpose: - * Response to 'chorus_setlevel' command */ -int -fluid_handle_choruslevel(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - fluid_real_t level; - if (ac < 1) { - fluid_ostream_printf(out, "cho_set_level: too few arguments.\n"); - return -1; - } - level = atof(av[0]); - fluid_chorus_set_level(synth->chorus, level); - return fluid_chorus_update(synth->chorus); - -} - -/* Purpose: - * Response to 'chorus_setspeed' command */ -int -fluid_handle_chorusspeed(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - fluid_real_t speed; - if (ac < 1) { - fluid_ostream_printf(out, "cho_set_speed: too few arguments.\n"); - return -1; - } - speed = atof(av[0]); - fluid_chorus_set_speed_Hz(synth->chorus, speed); - return fluid_chorus_update(synth->chorus); -} - -/* Purpose: - * Response to 'chorus_setdepth' command */ -int -fluid_handle_chorusdepth(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - fluid_real_t depth; - if (ac < 1) { - fluid_ostream_printf(out, "cho_set_depth: too few arguments.\n"); - return -1; - } - depth = atof(av[0]); - fluid_chorus_set_depth_ms(synth->chorus, depth); - return fluid_chorus_update(synth->chorus); -} - -int -fluid_handle_chorus(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - if (ac < 1) { - fluid_ostream_printf(out, "chorus: too few arguments\n"); - return -1; - } - - if ((strcmp(av[0], "0") == 0) || (strcmp(av[0], "off") == 0)) { - fluid_synth_set_chorus_on(synth,0); - } else if ((strcmp(av[0], "1") == 0) || (strcmp(av[0], "on") == 0)) { - fluid_synth_set_chorus_on(synth,1); - } else { - fluid_ostream_printf(out, "chorus: invalid arguments %s [0|1|on|off]", av[0]); - return -1; - } - - return 0; -} - -/* Purpose: - * Response to the 'echo' command. - * The command itself is useful, when the synth is used via TCP/IP. - * It can signal for example, that a list of commands has been processed. - */ -int -fluid_handle_echo(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out) -{ - if (ac < 1) { - fluid_ostream_printf(out, "echo: too few arguments.\n"); - return -1; - } - - fluid_ostream_printf(out, "%s\n",av[0]); - - return 0; -} - -int -fluid_handle_source(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out) -{ - if (ac < 1) { - fluid_ostream_printf(out, "source: too few arguments.\n"); - return -1; - } - - fluid_source(handler, av[0]); - - return 0; -} - -/* Purpose: - * Response to 'gain' command. */ -int -fluid_handle_gain(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - float gain; - - if (ac < 1) { - fluid_ostream_printf(out, "gain: too few arguments.\n"); - return -1; - } - - gain = atof(av[0]); - - if ((gain < 0.0f) || (gain > 5.0f)) { - fluid_ostream_printf(out, "gain: value should be between '0' and '5'.\n"); - return -1; - }; - - fluid_synth_set_gain(synth, gain); - - return 0; -} - -/* Purpose: - * Response to 'interp' command. */ -int -fluid_handle_interp(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - int interp; - int chan=-1; /* -1: Set all channels */ - - if (ac < 1) { - fluid_ostream_printf(out, "interp: too few arguments.\n"); - return -1; - } - - interp = atoi(av[0]); - - if ((interp < 0) || (interp > FLUID_INTERP_HIGHEST)) { - fluid_ostream_printf(out, "interp: Bad value\n"); - return -1; - }; - - fluid_synth_set_interp_method(synth, chan, interp); - - return 0; -} - -/* Purpose: - * Response to 'interp' command. */ -int -fluid_handle_interpc(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - int interp; - int chan; - - if (ac < 2) { - fluid_ostream_printf(out, "interpc: too few arguments.\n"); - return -1; - } - - chan = atoi(av[0]); - interp = atoi(av[1]); - - if ((chan < 0) || (chan >= fluid_synth_count_midi_channels(synth))){ - fluid_ostream_printf(out, "interp: Bad value for channel number.\n"); - return -1; - }; - if ((interp < 0) || (interp > FLUID_INTERP_HIGHEST)) { - fluid_ostream_printf(out, "interp: Bad value for interpolation method.\n"); - return -1; - }; - - fluid_synth_set_interp_method(synth, chan, interp); - - return 0; -} - -int -fluid_handle_tuning(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - char *name; - int bank, prog; - - if (ac < 3) { - fluid_ostream_printf(out, "tuning: too few arguments.\n"); - return -1; - } - - name = av[0]; - - if (!fluid_is_number(av[1])) { - fluid_ostream_printf(out, "tuning: 2nd argument should be a number.\n"); - return -1; - } - bank = atoi(av[1]); - if ((bank < 0) || (bank >= 128)){ - fluid_ostream_printf(out, "tuning: invalid bank number.\n"); - return -1; - }; - - if (!fluid_is_number(av[2])) { - fluid_ostream_printf(out, "tuning: 3rd argument should be a number.\n"); - return -1; - } - prog = atoi(av[2]); - if ((prog < 0) || (prog >= 128)){ - fluid_ostream_printf(out, "tuning: invalid program number.\n"); - return -1; - }; - - fluid_synth_create_key_tuning(synth, bank, prog, name, NULL); - - return 0; -} - -int -fluid_handle_tune(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - int bank, prog, key; - double pitch; - - if (ac < 4) { - fluid_ostream_printf(out, "tune: too few arguments.\n"); - return -1; - } - - if (!fluid_is_number(av[0])) { - fluid_ostream_printf(out, "tune: 1st argument should be a number.\n"); - return -1; - } - bank = atoi(av[0]); - if ((bank < 0) || (bank >= 128)){ - fluid_ostream_printf(out, "tune: invalid bank number.\n"); - return -1; - }; - - if (!fluid_is_number(av[1])) { - fluid_ostream_printf(out, "tune: 2nd argument should be a number.\n"); - return -1; - } - prog = atoi(av[1]); - if ((prog < 0) || (prog >= 128)){ - fluid_ostream_printf(out, "tune: invalid program number.\n"); - return -1; - }; - - if (!fluid_is_number(av[2])) { - fluid_ostream_printf(out, "tune: 3rd argument should be a number.\n"); - return -1; - } - key = atoi(av[2]); - if ((key < 0) || (key >= 128)){ - fluid_ostream_printf(out, "tune: invalid key number.\n"); - return -1; - }; - - pitch = atof(av[3]); - if (pitch < 0.0f) { - fluid_ostream_printf(out, "tune: invalid pitch.\n"); - return -1; - }; - - fluid_synth_tune_notes(synth, bank, prog, 1, &key, &pitch, 0); - - return 0; -} - -int -fluid_handle_settuning(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - int chan, bank, prog; - - if (ac < 3) { - fluid_ostream_printf(out, "settuning: too few arguments.\n"); - return -1; - } - - if (!fluid_is_number(av[0])) { - fluid_ostream_printf(out, "tune: 1st argument should be a number.\n"); - return -1; - } - chan = atoi(av[0]); - if ((chan < 0) || (chan >= fluid_synth_count_midi_channels(synth))){ - fluid_ostream_printf(out, "tune: invalid channel number.\n"); - return -1; - }; - - if (!fluid_is_number(av[1])) { - fluid_ostream_printf(out, "tuning: 2nd argument should be a number.\n"); - return -1; - } - bank = atoi(av[1]); - if ((bank < 0) || (bank >= 128)){ - fluid_ostream_printf(out, "tuning: invalid bank number.\n"); - return -1; - }; - - if (!fluid_is_number(av[2])) { - fluid_ostream_printf(out, "tuning: 3rd argument should be a number.\n"); - return -1; - } - prog = atoi(av[2]); - if ((prog < 0) || (prog >= 128)){ - fluid_ostream_printf(out, "tuning: invalid program number.\n"); - return -1; - }; - - fluid_synth_select_tuning(synth, chan, bank, prog); - - return 0; -} - -int -fluid_handle_resettuning(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - int chan; - - if (ac < 1) { - fluid_ostream_printf(out, "resettuning: too few arguments.\n"); - return -1; - } - - if (!fluid_is_number(av[0])) { - fluid_ostream_printf(out, "tune: 1st argument should be a number.\n"); - return -1; - } - chan = atoi(av[0]); - if ((chan < 0) || (chan >= fluid_synth_count_midi_channels(synth))){ - fluid_ostream_printf(out, "tune: invalid channel number.\n"); - return -1; - }; - - fluid_synth_reset_tuning(synth, chan); - - return 0; -} - -int -fluid_handle_tunings(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - int bank, prog; - char name[256]; - int count = 0; - - fluid_synth_tuning_iteration_start(synth); - - while (fluid_synth_tuning_iteration_next(synth, &bank, &prog)) { - fluid_synth_tuning_dump(synth, bank, prog, name, 256, NULL); - fluid_ostream_printf(out, "%03d-%03d %s\n", bank, prog, name); - count++; - } - - if (count == 0) { - fluid_ostream_printf(out, "No tunings available\n"); - } - - return 0; -} - -int -fluid_handle_dumptuning(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - int bank, prog, i; - double pitch[128]; - char name[256]; - - if (ac < 2) { - fluid_ostream_printf(out, "dumptuning: too few arguments.\n"); - return -1; - } - - if (!fluid_is_number(av[0])) { - fluid_ostream_printf(out, "dumptuning: 1st argument should be a number.\n"); - return -1; - } - bank = atoi(av[0]); - if ((bank < 0) || (bank >= 128)){ - fluid_ostream_printf(out, "dumptuning: invalid bank number.\n"); - return -1; - }; - - if (!fluid_is_number(av[1])) { - fluid_ostream_printf(out, "dumptuning: 2nd argument should be a number.\n"); - return -1; - } - prog = atoi(av[1]); - if ((prog < 0) || (prog >= 128)){ - fluid_ostream_printf(out, "dumptuning: invalid program number.\n"); - return -1; - }; - - fluid_synth_tuning_dump(synth, bank, prog, name, 256, pitch); - - fluid_ostream_printf(out, "%03d-%03d %s:\n", bank, prog, name); - - for (i = 0; i < 128; i++) { - fluid_ostream_printf(out, "key %03d, pitch %5.2f\n", i, pitch[i]); - } - - return 0; -} - -int -fluid_handle_set(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - if (ac < 2) { - fluid_ostream_printf(out, "set: too few arguments.\n"); - return -1; - } - - if (fluid_is_number(av[1])) { - if (FLUID_STRCHR(av[1], '.') != NULL) { - fluid_synth_setnum(synth, av[0], atof(av[1])); - } else { - fluid_synth_setint(synth, av[0], atoi(av[1])); - } - } else { - fluid_synth_setstr(synth, av[0], av[1]); - } - - return 0; -} - -int -fluid_handle_get(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - if (ac < 1) { - fluid_ostream_printf(out, "get: too few arguments.\n"); - return -1; - } - - switch (fluid_settings_get_type(fluid_synth_get_settings(synth), av[0])) { - case FLUID_NO_TYPE: - fluid_ostream_printf(out, "get: no such settings '%s'.", av[0]); - return -1; - - case FLUID_NUM_TYPE: { - double value; - fluid_synth_getnum(synth, av[0], &value); - fluid_ostream_printf(out, "%.3f", value); - break; - } - - case FLUID_INT_TYPE: { - int value; - fluid_synth_getint(synth, av[0], &value); - fluid_ostream_printf(out, "%d", value); - break; - } - - case FLUID_STR_TYPE: { - char* s; - fluid_synth_getstr(synth, av[0], &s); - fluid_ostream_printf(out, "%s", s); - break; - } - - case FLUID_SET_TYPE: - fluid_ostream_printf(out, "%s is a node", av[0]); - break; - } - - return 0; -} - -struct _fluid_handle_settings_data_t { - int len; - fluid_synth_t* synth; - fluid_ostream_t out; -}; - -static void fluid_handle_settings_iter1(void* data, char* name, int type) -{ - struct _fluid_handle_settings_data_t* d = (struct _fluid_handle_settings_data_t*) data; - - int len = FLUID_STRLEN(name); - if (len > d->len) { - d->len = len; - } -} - -static void fluid_handle_settings_iter2(void* data, char* name, int type) -{ - struct _fluid_handle_settings_data_t* d = (struct _fluid_handle_settings_data_t*) data; - - int len = FLUID_STRLEN(name); - fluid_ostream_printf(d->out, "%s", name); - while (len++ < d->len) { - fluid_ostream_printf(d->out, " "); - } - fluid_ostream_printf(d->out, " "); - - switch (fluid_settings_get_type(fluid_synth_get_settings(d->synth), name)) { - case FLUID_NUM_TYPE: { - double value; - fluid_synth_getnum(d->synth, name, &value); - fluid_ostream_printf(d->out, "%.3f\n", value); - break; - } - - case FLUID_INT_TYPE: { - int value; - fluid_synth_getint(d->synth, name, &value); - fluid_ostream_printf(d->out, "%d\n", value); - break; - } - - case FLUID_STR_TYPE: { - char* s; - fluid_synth_getstr(d->synth, name, &s); - fluid_ostream_printf(d->out, "%s\n", s); - break; - } - } -} - -int -fluid_handle_settings(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - struct _fluid_handle_settings_data_t data; - - data.len = 0; - data.synth = synth; - data.out = out; - - fluid_settings_foreach(fluid_synth_get_settings(synth), &data, fluid_handle_settings_iter1); - fluid_settings_foreach(fluid_synth_get_settings(synth), &data, fluid_handle_settings_iter2); - return 0; -} - - -struct _fluid_handle_option_data_t { - int first; - fluid_ostream_t out; -}; - -void fluid_handle_print_option(void* data, char* name, char* option) -{ - struct _fluid_handle_option_data_t* d = (struct _fluid_handle_option_data_t*) data; - - if (d->first) { - fluid_ostream_printf(d->out, "%s", option); - d->first = 0; - } else { - fluid_ostream_printf(d->out, ", %s", option); - } -} - -int -fluid_handle_info(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - fluid_settings_t* settings = fluid_synth_get_settings(synth); - struct _fluid_handle_option_data_t data; - - if (ac < 1) { - fluid_ostream_printf(out, "info: too few arguments.\n"); - return -1; - } - - switch (fluid_settings_get_type(settings, av[0])) { - case FLUID_NO_TYPE: - fluid_ostream_printf(out, "info: no such settings '%s'.", av[0]); - return -1; - - case FLUID_NUM_TYPE: { - double value, min, max; - fluid_settings_getnum_range(settings, av[0], &min, &max); - fluid_settings_getnum(settings, av[0], &value); - fluid_ostream_printf(out, "%s:\n", av[0]); - fluid_ostream_printf(out, "Type: number\n"); - fluid_ostream_printf(out, "Value: %.3f\n", value); - fluid_ostream_printf(out, "Minimum value: %.3f\n", min); - fluid_ostream_printf(out, "Maximum value: %.3f\n", max); - fluid_ostream_printf(out, "Default value: %.3f\n", - fluid_settings_getnum_default(settings, av[0])); - fluid_ostream_printf(out, "Real-time: %s\n", - fluid_settings_is_realtime(settings, av[0])? "yes" : "no"); - break; - } - - case FLUID_INT_TYPE: { - int value, min, max; - fluid_settings_getint_range(settings, av[0], &min, &max); - fluid_settings_getint(settings, av[0], &value); - fluid_ostream_printf(out, "%s:\n", av[0]); - fluid_ostream_printf(out, "Type: integer\n"); - fluid_ostream_printf(out, "Value: %d\n", value); - fluid_ostream_printf(out, "Minimum value: %d\n", min); - fluid_ostream_printf(out, "Maximum value: %d\n", max); - fluid_ostream_printf(out, "Default value: %d\n", - fluid_settings_getint_default(settings, av[0])); - fluid_ostream_printf(out, "Real-time: %s\n", - fluid_settings_is_realtime(settings, av[0])? "yes" : "no"); - break; - } - - case FLUID_STR_TYPE: { - char *s; - fluid_settings_getstr(settings, av[0], &s); - fluid_ostream_printf(out, "%s:\n", av[0]); - fluid_ostream_printf(out, "Type: string\n"); - fluid_ostream_printf(out, "Value: %s\n", s); - fluid_ostream_printf(out, "Default value: %s\n", - fluid_settings_getstr_default(settings, av[0])); - - data.out = out; - data.first = 1; - fluid_ostream_printf(out, "Options: "); - fluid_settings_foreach_option(settings, av[0], &data, fluid_handle_print_option); - fluid_ostream_printf(out, "\n"); - - fluid_ostream_printf(out, "Real-time: %s\n", - fluid_settings_is_realtime(settings, av[0])? "yes" : "no"); - break; - } - - case FLUID_SET_TYPE: - fluid_ostream_printf(out, "%s is a node", av[0]); - break; - } - - return 0; -} - -int -fluid_handle_reset(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - fluid_synth_system_reset(synth); - return 0; -} - -int -fluid_handle_quit(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - fluid_ostream_printf(out, "cheers!\n"); - return -2; -} - -int -fluid_handle_help(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - /* Purpose: - * Prints the help text for the command line commands. - * Can be used as follows: - * - help - * - help (topic), where (topic) is 'general', 'chorus', etc. - * - help all - * - help help - */ - - char* topic = "general"; /* default, if no topic is given */ - int count = 0; - int i; - - fluid_ostream_printf(out, "\n"); - /* 1st argument (optional): help topic */ - if (ac >= 1) { - topic = av[0]; - } - if (strcmp(topic,"help") == 0){ - /* "help help": Print a list of all topics */ - fluid_ostream_printf(out, - "*** Help topics:***\n" - "help help (prints this list)\n" - "help all (prints all topics)\n"); - for (i = 0; fluid_commands[i].name != NULL; i++) { - int listed_first_time = 1; - int ii; - for (ii = 0; ii < i; ii++){ - if (strcmp(fluid_commands[i].topic, fluid_commands[ii].topic) == 0){ - listed_first_time = 0; - }; /* if topic has already been listed */ - }; /* for all topics (inner loop) */ - if (listed_first_time){ - fluid_ostream_printf(out, "help %s\n",fluid_commands[i].topic); - }; - }; /* for all topics (outer loop) */ - } else { - /* help (arbitrary topic or "all") */ - for (i = 0; fluid_commands[i].name != NULL; i++) { - fluid_cmd_t cmd = fluid_commands[i]; - if (cmd.help != NULL) { - if (strcmp(topic,"all") == 0 || strcmp(topic,cmd.topic) == 0){ - fluid_ostream_printf(out, "%s\n", fluid_commands[i].help); - count++; - }; /* if it matches the topic */ - }; /* if help text exists */ - }; /* foreach command */ - if (count == 0){ - fluid_ostream_printf(out, "Unknown help topic. Try 'help help'.\n"); - }; - }; - return 0; -} - -int -fluid_is_number(char* a) -{ - while (*a != 0) { - if (((*a < '0') || (*a > '9')) && (*a != '-') && (*a != '+') && (*a != '.')) { - return 0; - } - a++; - } - return 1; -} - -int -fluid_is_empty(char* a) -{ - while (*a != 0) { - if ((*a != ' ') && (*a != '\t') && (*a != '\n') && (*a != '\r')) { - return 0; - } - a++; - } - return 1; -} - -char* -fluid_expand_path(char* path, char* new_path, int len) -{ -#if defined(WIN32) || defined(MACOS9) - snprintf(new_path, len - 1, "%s", path); -#else - if ((path[0] == '~') && (path[1] == '/')) { - char* home = getenv("HOME"); - if (home == NULL) { - snprintf(new_path, len - 1, "%s", path); - } else { - snprintf(new_path, len - 1, "%s%s", home, &path[1]); - } - } else { - snprintf(new_path, len - 1, "%s", path); - } -#endif - - new_path[len - 1] = 0; - return new_path; -} - - - -/* - * Command - */ - -fluid_cmd_t* fluid_cmd_copy(fluid_cmd_t* cmd) -{ - fluid_cmd_t* copy = FLUID_NEW(fluid_cmd_t); - if (copy == NULL) { - FLUID_LOG (FLUID_PANIC, "Out of memory"); - return NULL; - } - - copy->name = FLUID_STRDUP(cmd->name); - copy->topic = FLUID_STRDUP(cmd->topic); - copy->help = FLUID_STRDUP(cmd->help); - copy->handler = cmd->handler; - copy->data = cmd->data; - return copy; -} - -void delete_fluid_cmd(fluid_cmd_t* cmd) -{ - if (cmd->name) { - FLUID_FREE(cmd->name); - } - if (cmd->topic) { - FLUID_FREE(cmd->topic); - } - if (cmd->help) { - FLUID_FREE(cmd->help); - } - FLUID_FREE(cmd); -} - -/* - * Command handler - */ - -void fluid_cmd_handler_delete(void* value, int type) -{ - delete_fluid_cmd((fluid_cmd_t*) value); -} - -fluid_cmd_handler_t* new_fluid_cmd_handler(fluid_synth_t* synth) -{ - int i; - fluid_cmd_handler_t* handler; - - fluid_cmd_t source = { - "source", "general", (fluid_cmd_func_t) fluid_handle_source, NULL, - "source filename Load a file and parse every line as a command" - }; - - handler = new_fluid_hashtable(fluid_cmd_handler_delete); - if (handler == NULL) { - return NULL; - } - - if (synth != NULL) { - for (i = 0; fluid_commands[i].name != NULL; i++) { - fluid_commands[i].data = synth; - fluid_cmd_handler_register(handler, &fluid_commands[i]); - fluid_commands[i].data = NULL; - } - } - - source.data = handler; - fluid_cmd_handler_register(handler, &source); - - return handler; -} - -void delete_fluid_cmd_handler(fluid_cmd_handler_t* handler) -{ - delete_fluid_hashtable(handler); -} - -int fluid_cmd_handler_register(fluid_cmd_handler_t* handler, fluid_cmd_t* cmd) -{ - fluid_cmd_t* copy = fluid_cmd_copy(cmd); - fluid_hashtable_insert(handler, copy->name, copy, 0); - return 0; -} - -int fluid_cmd_handler_unregister(fluid_cmd_handler_t* handler, char* cmd) -{ - return fluid_hashtable_remove(handler, cmd); -} - -int fluid_cmd_handler_handle(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out) -{ - void *vp; /* use a void pointer to avoid GCC "type-punned pointer" warning */ - fluid_cmd_t* cmd; - - if (fluid_hashtable_lookup(handler, av[0], &vp, NULL) - && ((fluid_cmd_t *)vp)->handler) { - cmd = vp; - return (*cmd->handler)(cmd->data, ac - 1, av + 1, out); - } else { - fluid_ostream_printf(out, "unknown command: %s (try help)\n", av[0]); - return -1; - } -} - - -#if !defined(WITHOUT_SERVER) - - - -struct _fluid_server_t { - fluid_server_socket_t* socket; - fluid_settings_t* settings; - fluid_server_newclient_func_t newclient; - void* data; - fluid_list_t* clients; - fluid_mutex_t mutex; -}; - -static void fluid_server_handle_connection(fluid_server_t* server, - fluid_socket_t client_socket, - char* addr); -static void fluid_server_close(fluid_server_t* server); - -fluid_server_t* -new_fluid_server(fluid_settings_t* settings, - fluid_server_newclient_func_t newclient, - void* data) -{ - fluid_server_t* server; - int port; - - server = FLUID_NEW(fluid_server_t); - if (server == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - - server->settings = settings; - server->clients = NULL; - server->newclient = newclient; - server->data = data; - - fluid_mutex_init(server->mutex); - - fluid_settings_getint(settings, "shell.port", &port); - - server->socket = new_fluid_server_socket(port, - (fluid_server_func_t) fluid_server_handle_connection, - server); - if (server->socket == NULL) { - FLUID_FREE(server); - return NULL; - } - - return server; -} - -void delete_fluid_server(fluid_server_t* server) -{ - if (server == NULL) { - return; - } - - fluid_server_close(server); - - FLUID_FREE(server); -} - -static void fluid_server_close(fluid_server_t* server) -{ - fluid_list_t* list; - fluid_list_t* clients; - fluid_client_t* client; - - if (server == NULL) { - return; - } - - fluid_mutex_lock(server->mutex); - clients = server->clients; - server->clients = NULL; - fluid_mutex_unlock(server->mutex); - - list = clients; - - while (list) { - client = fluid_list_get(list); - fluid_client_quit(client); - list = fluid_list_next(list); - } - - delete_fluid_list(clients); - - if (server->socket) { - delete_fluid_server_socket(server->socket); - server->socket = NULL; - } -} - -static void -fluid_server_handle_connection(fluid_server_t* server, fluid_socket_t client_socket, char* addr) -{ - fluid_client_t* client; - fluid_cmd_handler_t* handler; - - handler = server->newclient(server->data, addr); - if (handler == NULL) { - return; - } - - client = new_fluid_client(server, server->settings, handler, client_socket); - if (client == NULL) { - return; - } - fluid_server_add_client(server, client); -} - -void fluid_server_add_client(fluid_server_t* server, fluid_client_t* client) -{ - fluid_mutex_lock(server->mutex); - server->clients = fluid_list_append(server->clients, client); - fluid_mutex_unlock(server->mutex); -} - -void fluid_server_remove_client(fluid_server_t* server, fluid_client_t* client) -{ - fluid_mutex_lock(server->mutex); - server->clients = fluid_list_remove(server->clients, client); - fluid_mutex_unlock(server->mutex); -} - -int fluid_server_join(fluid_server_t* server) -{ - return fluid_server_socket_join(server->socket); -} - - - - -struct _fluid_client_t { - fluid_server_t* server; - fluid_settings_t* settings; - fluid_cmd_handler_t* handler; - fluid_socket_t socket; - fluid_thread_t* thread; -}; - - - -static void fluid_client_run(fluid_client_t* client) -{ - fluid_shell_t shell; - fluid_shell_init(&shell, - client->settings, - client->handler, - fluid_socket_get_istream(client->socket), - fluid_socket_get_ostream(client->socket)); - fluid_shell_run(&shell); - fluid_server_remove_client(client->server, client); - delete_fluid_client(client); -} - - -fluid_client_t* -new_fluid_client(fluid_server_t* server, fluid_settings_t* settings, - fluid_cmd_handler_t* handler, fluid_socket_t sock) -{ - fluid_client_t* client; - - client = FLUID_NEW(fluid_client_t); - if (client == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - - client->server = server; - client->socket = sock; - client->settings = settings; - client->handler = handler; - - client->thread = new_fluid_thread((fluid_thread_func_t) fluid_client_run, client, 0); - - if (client->thread == NULL) { - fluid_socket_close(sock); - FLUID_FREE(client); - return NULL; - } - - return client; -} - -void fluid_client_quit(fluid_client_t* client) -{ - if (client->socket != INVALID_SOCKET) { - fluid_socket_close(client->socket); - client->socket = INVALID_SOCKET; - } - FLUID_LOG(FLUID_DBG, "fluid_client_quit: joining"); - fluid_thread_join(client->thread); - FLUID_LOG(FLUID_DBG, "fluid_client_quit: done"); -} - -void delete_fluid_client(fluid_client_t* client) -{ - if (client->socket != INVALID_SOCKET) { - fluid_socket_close(client->socket); - client->socket = INVALID_SOCKET; - } - if (client->thread != NULL) { - delete_fluid_thread(client->thread); - client->thread = NULL; - } - FLUID_FREE(client); -} - - -#endif /* WITHOUT_SERVER */ diff --git a/src/libs/fluidsynth/src/fluid_cmd.h b/src/libs/fluidsynth/src/fluid_cmd.h deleted file mode 100644 index 9c05589edd..0000000000 --- a/src/libs/fluidsynth/src/fluid_cmd.h +++ /dev/null @@ -1,102 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#ifndef _FLUID_CMD_H -#define _FLUID_CMD_H - -#include "fluidsynth_priv.h" -#include "fluid_io.h" - -void fluid_shell_settings(fluid_settings_t* settings); - - -/** some help functions */ -int fluid_is_number(char* a); -int fluid_is_empty(char* a); -char* fluid_expand_path(char* path, char* new_path, int len); - -/** the handlers for the command lines */ -int fluid_handle_help(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_quit(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_noteon(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_noteoff(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_cc(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_prog(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_select(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_inst(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_channels(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_load(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_unload(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_reload(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_fonts(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_mstat(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_reverbpreset(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_reverbsetroomsize(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_reverbsetdamp(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_reverbsetwidth(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_reverbsetlevel(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_chorusnr(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_choruslevel(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_chorusspeed(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_chorusdepth(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_chorus(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_reverb(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_gain(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_interp(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_interpc(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_tuning(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_tune(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_settuning(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_resettuning(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_tunings(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_dumptuning(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_reset(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_source(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out); -int fluid_handle_echo(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out); - -int fluid_handle_set(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_get(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_info(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_handle_settings(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); - - -fluid_cmd_t* fluid_cmd_copy(fluid_cmd_t* cmd); -void delete_fluid_cmd(fluid_cmd_t* cmd); - -int fluid_cmd_handler_handle(fluid_cmd_handler_t* handler, - int ac, char** av, - fluid_ostream_t out); - - - -void fluid_server_remove_client(fluid_server_t* server, fluid_client_t* client); -void fluid_server_add_client(fluid_server_t* server, fluid_client_t* client); - - -fluid_client_t* new_fluid_client(fluid_server_t* server, - fluid_settings_t* settings, - fluid_cmd_handler_t* handler, - fluid_socket_t sock); - -void delete_fluid_client(fluid_client_t* client); -void fluid_client_quit(fluid_client_t* client); - - -#endif /* _FLUID_CMD_H */ diff --git a/src/libs/fluidsynth/src/fluid_conv.c b/src/libs/fluidsynth/src/fluid_conv.c deleted file mode 100644 index cf83550d42..0000000000 --- a/src/libs/fluidsynth/src/fluid_conv.c +++ /dev/null @@ -1,320 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#include "fluid_conv.h" - - -/* conversion tables */ -fluid_real_t fluid_ct2hz_tab[FLUID_CENTS_HZ_SIZE]; -fluid_real_t fluid_cb2amp_tab[FLUID_CB_AMP_SIZE]; -fluid_real_t fluid_atten2amp_tab[FLUID_ATTEN_AMP_SIZE]; -fluid_real_t fluid_posbp_tab[128]; -fluid_real_t fluid_concave_tab[128]; -fluid_real_t fluid_convex_tab[128]; -fluid_real_t fluid_pan_tab[FLUID_PAN_SIZE]; - -/* - * void fluid_synth_init - * - * Does all the initialization for this module. - */ -void -fluid_conversion_config(void) -{ - int i; - double x; - - for (i = 0; i < FLUID_CENTS_HZ_SIZE; i++) { - fluid_ct2hz_tab[i] = (fluid_real_t) pow(2.0, (double) i / 1200.0); - } - - /* centibels to amplitude conversion - * Note: SF2.01 section 8.1.3: Initial attenuation range is - * between 0 and 144 dB. Therefore a negative attenuation is - * not allowed. - */ - for (i = 0; i < FLUID_CB_AMP_SIZE; i++) { - fluid_cb2amp_tab[i] = (fluid_real_t) pow(10.0, (double) i / -200.0); - } - - /* NOTE: EMU8k and EMU10k devices don't conform to the SoundFont - * specification in regards to volume attenuation. The below calculation - * is an approx. equation for generating a table equivelant to the - * cb_to_amp_table[] in tables.c of the TiMidity++ source, which I'm told - * was generated from device testing. By the spec this should be centibels. - */ - for (i = 0; i < FLUID_ATTEN_AMP_SIZE; i++) { - fluid_atten2amp_tab[i] = (fluid_real_t) pow(10.0, (double) i / FLUID_ATTEN_POWER_FACTOR); - } - - /* initialize the conversion tables (see fluid_mod.c - fluid_mod_get_value cases 4 and 8) */ - - /* concave unipolar positive transform curve */ - fluid_concave_tab[0] = 0.0; - fluid_concave_tab[127] = 1.0; - - /* convex unipolar positive transform curve */ - fluid_convex_tab[0] = 0; - fluid_convex_tab[127] = 1.0; - x = log10(128.0 / 127.0); - - /* There seems to be an error in the specs. The equations are - implemented according to the pictures on SF2.01 page 73. */ - - for (i = 1; i < 127; i++) { - x = -20.0 / 96.0 * log((i * i) / (127.0 * 127.0)) / log(10.0); - fluid_convex_tab[i] = (fluid_real_t) (1.0 - x); - fluid_concave_tab[127 - i] = (fluid_real_t) x; - } - - /* initialize the pan conversion table */ - x = PI / 2.0 / (FLUID_PAN_SIZE - 1.0); - for (i = 0; i < FLUID_PAN_SIZE; i++) { - fluid_pan_tab[i] = (fluid_real_t) sin(i * x); - } -} - -/* - * fluid_ct2hz - */ -fluid_real_t -fluid_ct2hz_real(fluid_real_t cents) -{ - if (cents < 0) - return (fluid_real_t) 1.0; - else if (cents < 900) { - return (fluid_real_t) 6.875 * fluid_ct2hz_tab[(int) (cents + 300)]; - } else if (cents < 2100) { - return (fluid_real_t) 13.75 * fluid_ct2hz_tab[(int) (cents - 900)]; - } else if (cents < 3300) { - return (fluid_real_t) 27.5 * fluid_ct2hz_tab[(int) (cents - 2100)]; - } else if (cents < 4500) { - return (fluid_real_t) 55.0 * fluid_ct2hz_tab[(int) (cents - 3300)]; - } else if (cents < 5700) { - return (fluid_real_t) 110.0 * fluid_ct2hz_tab[(int) (cents - 4500)]; - } else if (cents < 6900) { - return (fluid_real_t) 220.0 * fluid_ct2hz_tab[(int) (cents - 5700)]; - } else if (cents < 8100) { - return (fluid_real_t) 440.0 * fluid_ct2hz_tab[(int) (cents - 6900)]; - } else if (cents < 9300) { - return (fluid_real_t) 880.0 * fluid_ct2hz_tab[(int) (cents - 8100)]; - } else if (cents < 10500) { - return (fluid_real_t) 1760.0 * fluid_ct2hz_tab[(int) (cents - 9300)]; - } else if (cents < 11700) { - return (fluid_real_t) 3520.0 * fluid_ct2hz_tab[(int) (cents - 10500)]; - } else if (cents < 12900) { - return (fluid_real_t) 7040.0 * fluid_ct2hz_tab[(int) (cents - 11700)]; - } else if (cents < 14100) { - return (fluid_real_t) 14080.0 * fluid_ct2hz_tab[(int) (cents - 12900)]; - } else { - return (fluid_real_t) 1.0; /* some loony trying to make you deaf */ - } -} - -/* - * fluid_ct2hz - */ -fluid_real_t -fluid_ct2hz(fluid_real_t cents) -{ - /* Filter fc limit: SF2.01 page 48 # 8 */ - if (cents >= 13500){ - cents = 13500; /* 20 kHz */ - } else if (cents < 1500){ - cents = 1500; /* 20 Hz */ - } - return fluid_ct2hz_real(cents); -} - -/* - * fluid_cb2amp - * - * in: a value between 0 and 960, 0 is no attenuation - * out: a value between 1 and 0 - */ -fluid_real_t -fluid_cb2amp(fluid_real_t cb) -{ - /* - * cb: an attenuation in 'centibels' (1/10 dB) - * SF2.01 page 49 # 48 limits it to 144 dB. - * 96 dB is reasonable for 16 bit systems, 144 would make sense for 24 bit. - */ - - /* minimum attenuation: 0 dB */ - if (cb < 0) { - return 1.0; - } - if (cb >= FLUID_CB_AMP_SIZE) { - return 0.0; - } - return fluid_cb2amp_tab[(int) cb]; -} - -/* - * fluid_atten2amp - * - * in: a value between 0 and 1440, 0 is no attenuation - * out: a value between 1 and 0 - * - * Note: Volume attenuation is supposed to be centibels but EMU8k/10k don't - * follow this. Thats the reason for separate fluid_cb2amp and fluid_atten2amp. - */ -fluid_real_t -fluid_atten2amp(fluid_real_t atten) -{ - if (atten < 0) return 1.0; - else if (atten >= FLUID_ATTEN_AMP_SIZE) return 0.0; - else return fluid_atten2amp_tab[(int) atten]; -} - -/* - * fluid_tc2sec_delay - */ -fluid_real_t -fluid_tc2sec_delay(fluid_real_t tc) -{ - /* SF2.01 section 8.1.2 items 21, 23, 25, 33 - * SF2.01 section 8.1.3 items 21, 23, 25, 33 - * - * The most negative number indicates a delay of 0. Range is limited - * from -12000 to 5000 */ - if (tc <= -32768.0f) { - return (fluid_real_t) 0.0f; - }; - if (tc < -12000.) { - tc = (fluid_real_t) -12000.0f; - } - if (tc > 5000.0f) { - tc = (fluid_real_t) 5000.0f; - } - return (fluid_real_t) pow(2.0, (double) tc / 1200.0); -} - -/* - * fluid_tc2sec_attack - */ -fluid_real_t -fluid_tc2sec_attack(fluid_real_t tc) -{ - /* SF2.01 section 8.1.2 items 26, 34 - * SF2.01 section 8.1.3 items 26, 34 - * The most negative number indicates a delay of 0 - * Range is limited from -12000 to 8000 */ - if (tc<=-32768.){return (fluid_real_t) 0.0;}; - if (tc<-12000.){tc=(fluid_real_t) -12000.0;}; - if (tc>8000.){tc=(fluid_real_t) 8000.0;}; - return (fluid_real_t) pow(2.0, (double) tc / 1200.0); -} - -/* - * fluid_tc2sec - */ -fluid_real_t -fluid_tc2sec(fluid_real_t tc) -{ - /* No range checking here! */ - return (fluid_real_t) pow(2.0, (double) tc / 1200.0); -} - -/* - * fluid_tc2sec_release - */ -fluid_real_t -fluid_tc2sec_release(fluid_real_t tc) -{ - /* SF2.01 section 8.1.2 items 30, 38 - * SF2.01 section 8.1.3 items 30, 38 - * No 'most negative number' rule here! - * Range is limited from -12000 to 8000 */ - if (tc<=-32768.){return (fluid_real_t) 0.0;}; - if (tc<-12000.){tc=(fluid_real_t) -12000.0;}; - if (tc>8000.){tc=(fluid_real_t) 8000.0;}; - return (fluid_real_t) pow(2.0, (double) tc / 1200.0); -} - -/* - * fluid_act2hz - * - * Convert from absolute cents to Hertz - */ -fluid_real_t -fluid_act2hz(fluid_real_t c) -{ - return (fluid_real_t) (8.176 * pow(2.0, (double) c / 1200.0)); -} - -/* - * fluid_hz2ct - * - * Convert from Hertz to cents - */ -fluid_real_t -fluid_hz2ct(fluid_real_t f) -{ - return (fluid_real_t) (6900 + 1200 * log(f / 440.0) / log(2.0)); -} - -/* - * fluid_pan - */ -fluid_real_t -fluid_pan(fluid_real_t c, int left) -{ - if (left) { - c = -c; - } - if (c < -500) { - return (fluid_real_t) 0.0; - } else if (c > 500) { - return (fluid_real_t) 1.0; - } else { - return fluid_pan_tab[(int) (c + 500)]; - } -} - -/* - * fluid_concave - */ -fluid_real_t -fluid_concave(fluid_real_t val) -{ - if (val < 0) { - return 0; - } else if (val > 127) { - return 1; - } - return fluid_concave_tab[(int) val]; -} - -/* - * fluid_convex - */ -fluid_real_t -fluid_convex(fluid_real_t val) -{ - if (val < 0) { - return 0; - } else if (val > 127) { - return 1; - } - return fluid_convex_tab[(int) val]; -} diff --git a/src/libs/fluidsynth/src/fluid_conv.h b/src/libs/fluidsynth/src/fluid_conv.h deleted file mode 100644 index 83bb21e908..0000000000 --- a/src/libs/fluidsynth/src/fluid_conv.h +++ /dev/null @@ -1,63 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#ifndef _FLUID_CONV_H -#define _FLUID_CONV_H - -#include "fluidsynth_priv.h" - -#define FLUID_CENTS_HZ_SIZE 1200 -#define FLUID_VEL_CB_SIZE 128 -#define FLUID_CB_AMP_SIZE 961 -#define FLUID_ATTEN_AMP_SIZE 1441 -#define FLUID_PAN_SIZE 1002 - -/* EMU 8k/10k don't follow spec in regards to volume attenuation. - * This factor is used in the equation pow (10.0, cb / FLUID_ATTEN_POWER_FACTOR). - * By the standard this should be -200.0. */ -/* 07/11/2008 modified by S. Christian Collins for increased velocity sensitivity. Now it equals the response of EMU10K1 programming.*/ -#define FLUID_ATTEN_POWER_FACTOR (-200.0) /* was (-531.509)*/ - -void fluid_conversion_config(void); - -fluid_real_t fluid_ct2hz_real(fluid_real_t cents); -fluid_real_t fluid_ct2hz(fluid_real_t cents); -fluid_real_t fluid_cb2amp(fluid_real_t cb); -fluid_real_t fluid_atten2amp(fluid_real_t atten); -fluid_real_t fluid_tc2sec(fluid_real_t tc); -fluid_real_t fluid_tc2sec_delay(fluid_real_t tc); -fluid_real_t fluid_tc2sec_attack(fluid_real_t tc); -fluid_real_t fluid_tc2sec_release(fluid_real_t tc); -fluid_real_t fluid_act2hz(fluid_real_t c); -fluid_real_t fluid_hz2ct(fluid_real_t c); -fluid_real_t fluid_pan(fluid_real_t c, int left); -fluid_real_t fluid_concave(fluid_real_t val); -fluid_real_t fluid_convex(fluid_real_t val); - -extern fluid_real_t fluid_ct2hz_tab[FLUID_CENTS_HZ_SIZE]; -extern fluid_real_t fluid_vel2cb_tab[FLUID_VEL_CB_SIZE]; -extern fluid_real_t fluid_cb2amp_tab[FLUID_CB_AMP_SIZE]; -extern fluid_real_t fluid_posbp_tab[128]; -extern fluid_real_t fluid_concave_tab[128]; -extern fluid_real_t fluid_convex_tab[128]; -extern fluid_real_t fluid_pan_tab[FLUID_PAN_SIZE]; - - -#endif /* _FLUID_CONV_H */ diff --git a/src/libs/fluidsynth/src/fluid_defsfont.c b/src/libs/fluidsynth/src/fluid_defsfont.c deleted file mode 100644 index c6bd713bc0..0000000000 --- a/src/libs/fluidsynth/src/fluid_defsfont.c +++ /dev/null @@ -1,3214 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * SoundFont file loading code borrowed from Smurf SoundFont Editor - * Copyright (C) 1999-2001 Josh Green - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - - -#include "fluid_defsfont.h" -/* Todo: Get rid of that 'include' */ -#include "fluid_sys.h" - -/*************************************************************** - * - * SFONT LOADER - */ - -fluid_sfloader_t* new_fluid_defsfloader() -{ - fluid_sfloader_t* loader; - - loader = FLUID_NEW(fluid_sfloader_t); - if (loader == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - - loader->data = NULL; - loader->free = delete_fluid_defsfloader; - loader->load = fluid_defsfloader_load; - - return loader; -} - -int delete_fluid_defsfloader(fluid_sfloader_t* loader) -{ - if (loader) { - FLUID_FREE(loader); - } - return FLUID_OK; -} - -fluid_sfont_t* fluid_defsfloader_load(fluid_sfloader_t* loader, const char* filename) -{ - fluid_defsfont_t* defsfont; - fluid_sfont_t* sfont; - - defsfont = new_fluid_defsfont(); - - if (defsfont == NULL) { - return NULL; - } - - if (fluid_defsfont_load(defsfont, filename) == FLUID_FAILED) { - delete_fluid_defsfont(defsfont); - return NULL; - } - - sfont = FLUID_NEW(fluid_sfont_t); - if (sfont == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - - sfont->data = defsfont; - sfont->free = fluid_defsfont_sfont_delete; - sfont->get_name = fluid_defsfont_sfont_get_name; - sfont->get_preset = fluid_defsfont_sfont_get_preset; - sfont->iteration_start = fluid_defsfont_sfont_iteration_start; - sfont->iteration_next = fluid_defsfont_sfont_iteration_next; - - return sfont; -} - - - -/*************************************************************** - * - * PUBLIC INTERFACE - */ - -int fluid_defsfont_sfont_delete(fluid_sfont_t* sfont) -{ - if (delete_fluid_defsfont(sfont->data) != 0) { - return -1; - } - FLUID_FREE(sfont); - return 0; -} - -char* fluid_defsfont_sfont_get_name(fluid_sfont_t* sfont) -{ - return fluid_defsfont_get_name((fluid_defsfont_t*) sfont->data); -} - -fluid_preset_t* -fluid_defsfont_sfont_get_preset(fluid_sfont_t* sfont, unsigned int bank, unsigned int prenum) -{ - fluid_preset_t* preset; - fluid_defpreset_t* defpreset; - - defpreset = fluid_defsfont_get_preset((fluid_defsfont_t*) sfont->data, bank, prenum); - - if (defpreset == NULL) { - return NULL; - } - - preset = FLUID_NEW(fluid_preset_t); - if (preset == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - - preset->sfont = sfont; - preset->data = defpreset; - preset->free = fluid_defpreset_preset_delete; - preset->get_name = fluid_defpreset_preset_get_name; - preset->get_banknum = fluid_defpreset_preset_get_banknum; - preset->get_num = fluid_defpreset_preset_get_num; - preset->noteon = fluid_defpreset_preset_noteon; - preset->notify = NULL; - - return preset; -} - -void fluid_defsfont_sfont_iteration_start(fluid_sfont_t* sfont) -{ - fluid_defsfont_iteration_start((fluid_defsfont_t*) sfont->data); -} - -int fluid_defsfont_sfont_iteration_next(fluid_sfont_t* sfont, fluid_preset_t* preset) -{ - preset->free = fluid_defpreset_preset_delete; - preset->get_name = fluid_defpreset_preset_get_name; - preset->get_banknum = fluid_defpreset_preset_get_banknum; - preset->get_num = fluid_defpreset_preset_get_num; - preset->noteon = fluid_defpreset_preset_noteon; - preset->notify = NULL; - - return fluid_defsfont_iteration_next((fluid_defsfont_t*) sfont->data, preset); -} - -int fluid_defpreset_preset_delete(fluid_preset_t* preset) -{ - FLUID_FREE(preset); - - /* TODO: free modulators */ - - return 0; -} - -char* fluid_defpreset_preset_get_name(fluid_preset_t* preset) -{ - return fluid_defpreset_get_name((fluid_defpreset_t*) preset->data); -} - -int fluid_defpreset_preset_get_banknum(fluid_preset_t* preset) -{ - return fluid_defpreset_get_banknum((fluid_defpreset_t*) preset->data); -} - -int fluid_defpreset_preset_get_num(fluid_preset_t* preset) -{ - return fluid_defpreset_get_num((fluid_defpreset_t*) preset->data); -} - -int fluid_defpreset_preset_noteon(fluid_preset_t* preset, fluid_synth_t* synth, - int chan, int key, int vel) -{ - return fluid_defpreset_noteon((fluid_defpreset_t*) preset->data, synth, chan, key, vel); -} - - - - -/*************************************************************** - * - * SFONT - */ - -/* - * new_fluid_defsfont - */ -fluid_defsfont_t* new_fluid_defsfont() -{ - fluid_defsfont_t* sfont; - - sfont = FLUID_NEW(fluid_defsfont_t); - if (sfont == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - - sfont->filename = NULL; - sfont->samplepos = 0; - sfont->samplesize = 0; - sfont->sample = NULL; - sfont->sampledata = NULL; - sfont->preset = NULL; - - return sfont; -} - -/* - * delete_fluid_defsfont - */ -int delete_fluid_defsfont(fluid_defsfont_t* sfont) -{ - fluid_list_t *list; - fluid_defpreset_t* preset; - fluid_sample_t* sample; - - /* Check that no samples are currently used */ - for (list = sfont->sample; list; list = fluid_list_next(list)) { - sample = (fluid_sample_t*) fluid_list_get(list); - if (fluid_sample_refcount(sample) != 0) { - return -1; - } - } - - if (sfont->filename != NULL) { - FLUID_FREE(sfont->filename); - } - - for (list = sfont->sample; list; list = fluid_list_next(list)) { - delete_fluid_sample((fluid_sample_t*) fluid_list_get(list)); - } - - if (sfont->sample) { - delete_fluid_list(sfont->sample); - } - - if (sfont->sampledata != NULL) { - fluid_munlock(sfont->sampledata, sfont->samplesize); - FLUID_FREE(sfont->sampledata); - } - - preset = sfont->preset; - while (preset != NULL) { - sfont->preset = preset->next; - delete_fluid_defpreset(preset); - preset = sfont->preset; - } - - FLUID_FREE(sfont); - return FLUID_OK; -} - -/* - * fluid_defsfont_get_name - */ -char* fluid_defsfont_get_name(fluid_defsfont_t* sfont) -{ - return sfont->filename; -} - - -/* - * fluid_defsfont_load - */ -int fluid_defsfont_load(fluid_defsfont_t* sfont, const char* file) -{ - SFData* sfdata; - fluid_list_t *p; - SFPreset* sfpreset; - SFSample* sfsample; - fluid_sample_t* sample; - fluid_defpreset_t* preset; - - sfont->filename = FLUID_MALLOC(1 + FLUID_STRLEN(file)); - if (sfont->filename == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return FLUID_FAILED; - } - FLUID_STRCPY(sfont->filename, file); - - /* The actual loading is done in the sfont and sffile files */ - sfdata = sfload_file(file); - if (sfdata == NULL) { - FLUID_LOG(FLUID_ERR, "Couldn't load soundfont file"); - return FLUID_FAILED; - } - - /* Keep track of the position and size of the sample data because - it's loaded separately (and might be unoaded/reloaded in future) */ - sfont->samplepos = sfdata->samplepos; - sfont->samplesize = sfdata->samplesize; - - /* load sample data in one block */ - if (fluid_defsfont_load_sampledata(sfont) != FLUID_OK) - goto err_exit; - - /* Create all the sample headers */ - p = sfdata->sample; - while (p != NULL) { - sfsample = (SFSample *) p->data; - - sample = new_fluid_sample(); - if (sample == NULL) goto err_exit; - - if (fluid_sample_import_sfont(sample, sfsample, sfont) != FLUID_OK) - goto err_exit; - - fluid_defsfont_add_sample(sfont, sample); - fluid_voice_optimize_sample(sample); - p = fluid_list_next(p); - } - - /* Load all the presets */ - p = sfdata->preset; - while (p != NULL) { - sfpreset = (SFPreset *) p->data; - preset = new_fluid_defpreset(sfont); - if (preset == NULL) goto err_exit; - - if (fluid_defpreset_import_sfont(preset, sfpreset, sfont) != FLUID_OK) - goto err_exit; - - fluid_defsfont_add_preset(sfont, preset); - p = fluid_list_next(p); - } - sfont_close (sfdata); - - return FLUID_OK; - -err_exit: - sfont_close (sfdata); - return FLUID_FAILED; -} - -/* fluid_defsfont_add_sample - * - * Add a sample to the SoundFont - */ -int fluid_defsfont_add_sample(fluid_defsfont_t* sfont, fluid_sample_t* sample) -{ - sfont->sample = fluid_list_append(sfont->sample, sample); - return FLUID_OK; -} - -/* fluid_defsfont_add_preset - * - * Add a preset to the SoundFont - */ -int fluid_defsfont_add_preset(fluid_defsfont_t* sfont, fluid_defpreset_t* preset) -{ - fluid_defpreset_t *cur, *prev; - if (sfont->preset == NULL) { - preset->next = NULL; - sfont->preset = preset; - } else { - /* sort them as we go along. very basic sorting trick. */ - cur = sfont->preset; - prev = NULL; - while (cur != NULL) { - if ((preset->bank < cur->bank) - || ((preset->bank == cur->bank) && (preset->num < cur->num))) { - if (prev == NULL) { - preset->next = cur; - sfont->preset = preset; - } else { - preset->next = cur; - prev->next = preset; - } - return FLUID_OK; - } - prev = cur; - cur = cur->next; - } - preset->next = NULL; - prev->next = preset; - } - return FLUID_OK; -} - -/* - * fluid_defsfont_load_sampledata - */ -int -fluid_defsfont_load_sampledata(fluid_defsfont_t* sfont) -{ - fluid_file fd; - unsigned short endian; - fd = FLUID_FOPEN(sfont->filename, "rb"); - if (fd == NULL) { - FLUID_LOG(FLUID_ERR, "Can't open soundfont file"); - return FLUID_FAILED; - } - if (FLUID_FSEEK(fd, sfont->samplepos, SEEK_SET) == -1) { - perror("error"); - FLUID_LOG(FLUID_ERR, "Failed to seek position in data file"); - return FLUID_FAILED; - } - sfont->sampledata = (short*) FLUID_MALLOC(sfont->samplesize); - if (sfont->sampledata == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return FLUID_FAILED; - } - if (FLUID_FREAD(sfont->sampledata, 1, sfont->samplesize, fd) < sfont->samplesize) { - FLUID_LOG(FLUID_ERR, "Failed to read sample data"); - return FLUID_FAILED; - } - FLUID_FCLOSE(fd); - - /* Lock the memory to disable paging. It's okay if this fails. It - probably means that the user doesn't have to required permission. */ - if (fluid_mlock(sfont->sampledata, sfont->samplesize) != 0) { - FLUID_LOG(FLUID_WARN, "Failed to pin the sample data to RAM; swapping is possible."); - } - - - /* I'm not sure this endian test is waterproof... */ - endian = 0x0100; - - /* If this machine is big endian, the sample have to byte swapped */ - if (((char *) &endian)[0]) { - unsigned char* cbuf; - unsigned char hi, lo; - unsigned int i, j; - short s; - cbuf = (unsigned char*) sfont->sampledata; - for (i = 0, j = 0; j < sfont->samplesize; i++) { - lo = cbuf[j++]; - hi = cbuf[j++]; - s = (hi << 8) | lo; - sfont->sampledata[i] = s; - } - } - return FLUID_OK; -} - -/* - * fluid_defsfont_get_sample - */ -fluid_sample_t* fluid_defsfont_get_sample(fluid_defsfont_t* sfont, char *s) -{ - fluid_list_t* list; - fluid_sample_t* sample; - - for (list = sfont->sample; list; list = fluid_list_next(list)) { - - sample = (fluid_sample_t*) fluid_list_get(list); - - if (FLUID_STRCMP(sample->name, s) == 0) { - return sample; - } - } - - return NULL; -} - -/* - * fluid_defsfont_get_preset - */ -fluid_defpreset_t* fluid_defsfont_get_preset(fluid_defsfont_t* sfont, unsigned int bank, unsigned int num) -{ - fluid_defpreset_t* preset = sfont->preset; - while (preset != NULL) { - if ((preset->bank == bank) && ((preset->num == num))) { - return preset; - } - preset = preset->next; - } - return NULL; -} - -/* - * fluid_defsfont_iteration_start - */ -void fluid_defsfont_iteration_start(fluid_defsfont_t* sfont) -{ - sfont->iter_cur = sfont->preset; -} - -/* - * fluid_defsfont_iteration_next - */ -int fluid_defsfont_iteration_next(fluid_defsfont_t* sfont, fluid_preset_t* preset) -{ - if (sfont->iter_cur == NULL) { - return 0; - } - - preset->data = (void*) sfont->iter_cur; - sfont->iter_cur = fluid_defpreset_next(sfont->iter_cur); - return 1; -} - -/*************************************************************** - * - * PRESET - */ - -/* - * new_fluid_defpreset - */ -fluid_defpreset_t* -new_fluid_defpreset(fluid_defsfont_t* sfont) -{ - fluid_defpreset_t* preset = FLUID_NEW(fluid_defpreset_t); - if (preset == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - preset->next = NULL; - preset->sfont = sfont; - preset->name[0] = 0; - preset->bank = 0; - preset->num = 0; - preset->global_zone = NULL; - preset->zone = NULL; - return preset; -} - -/* - * delete_fluid_defpreset - */ -int -delete_fluid_defpreset(fluid_defpreset_t* preset) -{ - int err = FLUID_OK; - fluid_preset_zone_t* zone; - if (preset->global_zone != NULL) { - if (delete_fluid_preset_zone(preset->global_zone) != FLUID_OK) { - err = FLUID_FAILED; - } - preset->global_zone = NULL; - } - zone = preset->zone; - while (zone != NULL) { - preset->zone = zone->next; - if (delete_fluid_preset_zone(zone) != FLUID_OK) { - err = FLUID_FAILED; - } - zone = preset->zone; - } - FLUID_FREE(preset); - return err; -} - -int -fluid_defpreset_get_banknum(fluid_defpreset_t* preset) -{ - return preset->bank; -} - -int -fluid_defpreset_get_num(fluid_defpreset_t* preset) -{ - return preset->num; -} - -char* -fluid_defpreset_get_name(fluid_defpreset_t* preset) -{ - return preset->name; -} - -/* - * fluid_defpreset_next - */ -fluid_defpreset_t* -fluid_defpreset_next(fluid_defpreset_t* preset) -{ - return preset->next; -} - - -/* - * fluid_defpreset_noteon - */ -int -fluid_defpreset_noteon(fluid_defpreset_t* preset, fluid_synth_t* synth, int chan, int key, int vel) -{ - fluid_preset_zone_t *preset_zone, *global_preset_zone; - fluid_inst_t* inst; - fluid_inst_zone_t *inst_zone, *global_inst_zone, *z; - fluid_sample_t* sample; - fluid_voice_t* voice; - fluid_mod_t * mod; - fluid_mod_t * mod_list[FLUID_NUM_MOD]; /* list for 'sorting' preset modulators */ - int mod_list_count; - int i; - - global_preset_zone = fluid_defpreset_get_global_zone(preset); - - /* run thru all the zones of this preset */ - preset_zone = fluid_defpreset_get_zone(preset); - while (preset_zone != NULL) { - - /* check if the note falls into the key and velocity range of this - preset */ - if (fluid_preset_zone_inside_range(preset_zone, key, vel)) { - - inst = fluid_preset_zone_get_inst(preset_zone); - global_inst_zone = fluid_inst_get_global_zone(inst); - - /* run thru all the zones of this instrument */ - inst_zone = fluid_inst_get_zone(inst); - while (inst_zone != NULL) { - - /* make sure this instrument zone has a valid sample */ - sample = fluid_inst_zone_get_sample(inst_zone); - if (fluid_sample_in_rom(sample) || (sample == NULL)) { - inst_zone = fluid_inst_zone_next(inst_zone); - continue; - } - - /* check if the note falls into the key and velocity range of this - instrument */ - - if (fluid_inst_zone_inside_range(inst_zone, key, vel) && (sample != NULL)) { - - /* this is a good zone. allocate a new synthesis process and - initialize it */ - - voice = fluid_synth_alloc_voice(synth, sample, chan, key, vel); - if (voice == NULL) { - return FLUID_FAILED; - } - - - z = inst_zone; - - /* Instrument level, generators */ - - for (i = 0; i < GEN_LAST; i++) { - - /* SF 2.01 section 9.4 'bullet' 4: - * - * A generator in a local instrument zone supersedes a - * global instrument zone generator. Both cases supersede - * the default generator -> voice_gen_set */ - - if (inst_zone->gen[i].flags){ - fluid_voice_gen_set(voice, i, inst_zone->gen[i].val); - - } else if ((global_inst_zone != NULL) && (global_inst_zone->gen[i].flags)) { - fluid_voice_gen_set(voice, i, global_inst_zone->gen[i].val); - - } else { - /* The generator has not been defined in this instrument. - * Do nothing, leave it at the default. - */ - } - - } /* for all generators */ - - /* global instrument zone, modulators: Put them all into a - * list. */ - - mod_list_count = 0; - - if (global_inst_zone){ - mod = global_inst_zone->mod; - while (mod){ - mod_list[mod_list_count++] = mod; - mod = mod->next; - } - } - - /* local instrument zone, modulators. - * Replace modulators with the same definition in the list: - * SF 2.01 page 69, 'bullet' 8 - */ - mod = inst_zone->mod; - - while (mod){ - - /* 'Identical' modulators will be deleted by setting their - * list entry to NULL. The list length is known, NULL - * entries will be ignored later. SF2.01 section 9.5.1 - * page 69, 'bullet' 3 defines 'identical'. */ - - for (i = 0; i < mod_list_count; i++){ - if (mod_list[i] && fluid_mod_test_identity(mod,mod_list[i])){ - mod_list[i] = NULL; - } - } - - /* Finally add the new modulator to to the list. */ - mod_list[mod_list_count++] = mod; - mod = mod->next; - } - - /* Add instrument modulators (global / local) to the voice. */ - for (i = 0; i < mod_list_count; i++){ - - mod = mod_list[i]; - - if (mod != NULL){ /* disabled modulators CANNOT be skipped. */ - - /* Instrument modulators -supersede- existing (default) - * modulators. SF 2.01 page 69, 'bullet' 6 */ - fluid_voice_add_mod(voice, mod, FLUID_VOICE_OVERWRITE); - } - } - - /* Preset level, generators */ - - for (i = 0; i < GEN_LAST; i++) { - - /* SF 2.01 section 8.5 page 58: If some generators are - * encountered at preset level, they should be ignored */ - if ((i != GEN_STARTADDROFS) - && (i != GEN_ENDADDROFS) - && (i != GEN_STARTLOOPADDROFS) - && (i != GEN_ENDLOOPADDROFS) - && (i != GEN_STARTADDRCOARSEOFS) - && (i != GEN_ENDADDRCOARSEOFS) - && (i != GEN_STARTLOOPADDRCOARSEOFS) - && (i != GEN_KEYNUM) - && (i != GEN_VELOCITY) - && (i != GEN_ENDLOOPADDRCOARSEOFS) - && (i != GEN_SAMPLEMODE) - && (i != GEN_EXCLUSIVECLASS) - && (i != GEN_OVERRIDEROOTKEY)) { - - /* SF 2.01 section 9.4 'bullet' 9: A generator in a - * local preset zone supersedes a global preset zone - * generator. The effect is -added- to the destination - * summing node -> voice_gen_incr */ - - if (preset_zone->gen[i].flags) { - fluid_voice_gen_incr(voice, i, preset_zone->gen[i].val); - } else if ((global_preset_zone != NULL) && global_preset_zone->gen[i].flags) { - fluid_voice_gen_incr(voice, i, global_preset_zone->gen[i].val); - } else { - /* The generator has not been defined in this preset - * Do nothing, leave it unchanged. - */ - } - } /* if available at preset level */ - } /* for all generators */ - - - /* Global preset zone, modulators: put them all into a - * list. */ - mod_list_count = 0; - if (global_preset_zone){ - mod = global_preset_zone->mod; - while (mod){ - mod_list[mod_list_count++] = mod; - mod = mod->next; - } - } - - /* Process the modulators of the local preset zone. Kick - * out all identical modulators from the global preset zone - * (SF 2.01 page 69, second-last bullet) */ - - mod = preset_zone->mod; - while (mod){ - for (i = 0; i < mod_list_count; i++){ - if (mod_list[i] && fluid_mod_test_identity(mod,mod_list[i])){ - mod_list[i] = NULL; - } - } - - /* Finally add the new modulator to the list. */ - mod_list[mod_list_count++] = mod; - mod = mod->next; - } - - /* Add preset modulators (global / local) to the voice. */ - for (i = 0; i < mod_list_count; i++){ - mod = mod_list[i]; - if ((mod != NULL) && (mod->amount != 0)) { /* disabled modulators can be skipped. */ - - /* Preset modulators -add- to existing instrument / - * default modulators. SF2.01 page 70 first bullet on - * page */ - fluid_voice_add_mod(voice, mod, FLUID_VOICE_ADD); - } - } - - /* add the synthesis process to the synthesis loop. */ - fluid_synth_start_voice(synth, voice); - - /* Store the ID of the first voice that was created by this noteon event. - * Exclusive class may only terminate older voices. - * That avoids killing voices, which have just been created. - * (a noteon event can create several voice processes with the same exclusive - * class - for example when using stereo samples) - */ - } - - inst_zone = fluid_inst_zone_next(inst_zone); - } - } - preset_zone = fluid_preset_zone_next(preset_zone); - } - - return FLUID_OK; -} - -/* - * fluid_defpreset_set_global_zone - */ -int -fluid_defpreset_set_global_zone(fluid_defpreset_t* preset, fluid_preset_zone_t* zone) -{ - preset->global_zone = zone; - return FLUID_OK; -} - -/* - * fluid_defpreset_import_sfont - */ -int -fluid_defpreset_import_sfont(fluid_defpreset_t* preset, - SFPreset* sfpreset, - fluid_defsfont_t* sfont) -{ - fluid_list_t *p; - SFZone* sfzone; - fluid_preset_zone_t* zone; - int count; - char zone_name[256]; - if ((sfpreset->name != NULL) && (FLUID_STRLEN(sfpreset->name) > 0)) { - FLUID_STRCPY(preset->name, sfpreset->name); - } else { - FLUID_SPRINTF(preset->name, "Bank%d,Preset%d", sfpreset->bank, sfpreset->prenum); - } - preset->bank = sfpreset->bank; - preset->num = sfpreset->prenum; - p = sfpreset->zone; - count = 0; - while (p != NULL) { - sfzone = (SFZone *) p->data; - FLUID_SPRINTF(zone_name, "%s/%d", preset->name, count); - zone = new_fluid_preset_zone(zone_name); - if (zone == NULL) { - return FLUID_FAILED; - } - if (fluid_preset_zone_import_sfont(zone, sfzone, sfont) != FLUID_OK) { - return FLUID_FAILED; - } - if ((count == 0) && (fluid_preset_zone_get_inst(zone) == NULL)) { - fluid_defpreset_set_global_zone(preset, zone); - } else if (fluid_defpreset_add_zone(preset, zone) != FLUID_OK) { - return FLUID_FAILED; - } - p = fluid_list_next(p); - count++; - } - return FLUID_OK; -} - -/* - * fluid_defpreset_add_zone - */ -int -fluid_defpreset_add_zone(fluid_defpreset_t* preset, fluid_preset_zone_t* zone) -{ - if (preset->zone == NULL) { - zone->next = NULL; - preset->zone = zone; - } else { - zone->next = preset->zone; - preset->zone = zone; - } - return FLUID_OK; -} - -/* - * fluid_defpreset_get_zone - */ -fluid_preset_zone_t* -fluid_defpreset_get_zone(fluid_defpreset_t* preset) -{ - return preset->zone; -} - -/* - * fluid_defpreset_get_global_zone - */ -fluid_preset_zone_t* -fluid_defpreset_get_global_zone(fluid_defpreset_t* preset) -{ - return preset->global_zone; -} - -/* - * fluid_preset_zone_next - */ -fluid_preset_zone_t* -fluid_preset_zone_next(fluid_preset_zone_t* preset) -{ - return preset->next; -} - -/* - * new_fluid_preset_zone - */ -fluid_preset_zone_t* -new_fluid_preset_zone(char *name) -{ - int size; - fluid_preset_zone_t* zone = NULL; - zone = FLUID_NEW(fluid_preset_zone_t); - if (zone == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - zone->next = NULL; - size = 1 + FLUID_STRLEN(name); - zone->name = FLUID_MALLOC(size); - if (zone->name == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - FLUID_FREE(zone); - return NULL; - } - FLUID_STRCPY(zone->name, name); - zone->inst = NULL; - zone->keylo = 0; - zone->keyhi = 128; - zone->vello = 0; - zone->velhi = 128; - - /* Flag all generators as unused (default, they will be set when they are found - * in the sound font). - * This also sets the generator values to default, but that is of no concern here.*/ - fluid_gen_set_default_values(&zone->gen[0]); - zone->mod = NULL; /* list of modulators */ - return zone; -} - -/*************************************************************** - * - * PRESET_ZONE - */ - -/* - * delete_fluid_preset_zone - */ -int -delete_fluid_preset_zone(fluid_preset_zone_t* zone) -{ - fluid_mod_t *mod, *tmp; - - mod = zone->mod; - while (mod) /* delete the modulators */ - { - tmp = mod; - mod = mod->next; - fluid_mod_delete (tmp); - } - - if (zone->name) FLUID_FREE (zone->name); - if (zone->inst) delete_fluid_inst (zone->inst); - FLUID_FREE(zone); - return FLUID_OK; -} - -/* - * fluid_preset_zone_import_sfont - */ -int -fluid_preset_zone_import_sfont(fluid_preset_zone_t* zone, SFZone *sfzone, fluid_defsfont_t* sfont) -{ - fluid_list_t *r; - SFGen* sfgen; - int count; - for (count = 0, r = sfzone->gen; r != NULL; count++) { - sfgen = (SFGen *) r->data; - switch (sfgen->id) { - case GEN_KEYRANGE: - zone->keylo = (int) sfgen->amount.range.lo; - zone->keyhi = (int) sfgen->amount.range.hi; - break; - case GEN_VELRANGE: - zone->vello = (int) sfgen->amount.range.lo; - zone->velhi = (int) sfgen->amount.range.hi; - break; - default: - /* FIXME: some generators have an unsigne word amount value but i don't know which ones */ - zone->gen[sfgen->id].val = (fluid_real_t) sfgen->amount.sword; - zone->gen[sfgen->id].flags = GEN_SET; - break; - } - r = fluid_list_next(r); - } - if ((sfzone->instsamp != NULL) && (sfzone->instsamp->data != NULL)) { - zone->inst = (fluid_inst_t*) new_fluid_inst(); - if (zone->inst == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return FLUID_FAILED; - } - if (fluid_inst_import_sfont(zone->inst, (SFInst *) sfzone->instsamp->data, sfont) != FLUID_OK) { - return FLUID_FAILED; - } - } - - /* Import the modulators (only SF2.1 and higher) */ - for (count = 0, r = sfzone->mod; r != NULL; count++) { - - SFMod* mod_src = (SFMod *)r->data; - fluid_mod_t * mod_dest = fluid_mod_new(); - int type; - - if (mod_dest == NULL){ - return FLUID_FAILED; - } - mod_dest->next = NULL; /* pointer to next modulator, this is the end of the list now.*/ - - /* *** Amount *** */ - mod_dest->amount = mod_src->amount; - - /* *** Source *** */ - mod_dest->src1 = mod_src->src & 127; /* index of source 1, seven-bit value, SF2.01 section 8.2, page 50 */ - mod_dest->flags1 = 0; - - /* Bit 7: CC flag SF 2.01 section 8.2.1 page 50*/ - if (mod_src->src & (1<<7)){ - mod_dest->flags1 |= FLUID_MOD_CC; - } else { - mod_dest->flags1 |= FLUID_MOD_GC; - } - - /* Bit 8: D flag SF 2.01 section 8.2.2 page 51*/ - if (mod_src->src & (1<<8)){ - mod_dest->flags1 |= FLUID_MOD_NEGATIVE; - } else { - mod_dest->flags1 |= FLUID_MOD_POSITIVE; - } - - /* Bit 9: P flag SF 2.01 section 8.2.3 page 51*/ - if (mod_src->src & (1<<9)){ - mod_dest->flags1 |= FLUID_MOD_BIPOLAR; - } else { - mod_dest->flags1 |= FLUID_MOD_UNIPOLAR; - } - - /* modulator source types: SF2.01 section 8.2.1 page 52 */ - type=(mod_src->src) >> 10; - type &= 63; /* type is a 6-bit value */ - if (type == 0){ - mod_dest->flags1 |= FLUID_MOD_LINEAR; - } else if (type == 1){ - mod_dest->flags1 |= FLUID_MOD_CONCAVE; - } else if (type == 2){ - mod_dest->flags1 |= FLUID_MOD_CONVEX; - } else if (type == 3){ - mod_dest->flags1 |= FLUID_MOD_SWITCH; - } else { - /* This shouldn't happen - unknown type! - * Deactivate the modulator by setting the amount to 0. */ - mod_dest->amount=0; - } - - /* *** Dest *** */ - mod_dest->dest = mod_src->dest; /* index of controlled generator */ - - /* *** Amount source *** */ - mod_dest->src2 = mod_src->amtsrc & 127; /* index of source 2, seven-bit value, SF2.01 section 8.2, p.50 */ - mod_dest->flags2 = 0; - - /* Bit 7: CC flag SF 2.01 section 8.2.1 page 50*/ - if (mod_src->amtsrc & (1<<7)){ - mod_dest->flags2 |= FLUID_MOD_CC; - } else { - mod_dest->flags2 |= FLUID_MOD_GC; - } - - /* Bit 8: D flag SF 2.01 section 8.2.2 page 51*/ - if (mod_src->amtsrc & (1<<8)){ - mod_dest->flags2 |= FLUID_MOD_NEGATIVE; - } else { - mod_dest->flags2 |= FLUID_MOD_POSITIVE; - } - - /* Bit 9: P flag SF 2.01 section 8.2.3 page 51*/ - if (mod_src->amtsrc & (1<<9)){ - mod_dest->flags2 |= FLUID_MOD_BIPOLAR; - } else { - mod_dest->flags2 |= FLUID_MOD_UNIPOLAR; - } - - /* modulator source types: SF2.01 section 8.2.1 page 52 */ - type = (mod_src->amtsrc) >> 10; - type &= 63; /* type is a 6-bit value */ - if (type == 0){ - mod_dest->flags2 |= FLUID_MOD_LINEAR; - } else if (type == 1){ - mod_dest->flags2 |= FLUID_MOD_CONCAVE; - } else if (type == 2){ - mod_dest->flags2 |= FLUID_MOD_CONVEX; - } else if (type == 3){ - mod_dest->flags2 |= FLUID_MOD_SWITCH; - } else { - /* This shouldn't happen - unknown type! - * Deactivate the modulator by setting the amount to 0. */ - mod_dest->amount=0; - } - - /* *** Transform *** */ - /* SF2.01 only uses the 'linear' transform (0). - * Deactivate the modulator by setting the amount to 0 in any other case. - */ - if (mod_src->trans !=0){ - mod_dest->amount = 0; - } - - /* Store the new modulator in the zone The order of modulators - * will make a difference, at least in an instrument context: The - * second modulator overwrites the first one, if they only differ - * in amount. */ - if (count == 0){ - zone->mod = mod_dest; - } else { - fluid_mod_t * last_mod = zone->mod; - - /* Find the end of the list */ - while (last_mod->next != NULL){ - last_mod=last_mod->next; - } - - last_mod->next = mod_dest; - } - - r = fluid_list_next(r); - } /* foreach modulator */ - - return FLUID_OK; -} - -/* - * fluid_preset_zone_get_inst - */ -fluid_inst_t* -fluid_preset_zone_get_inst(fluid_preset_zone_t* zone) -{ - return zone->inst; -} - -/* - * fluid_preset_zone_inside_range - */ -int -fluid_preset_zone_inside_range(fluid_preset_zone_t* zone, int key, int vel) -{ - return ((zone->keylo <= key) && - (zone->keyhi >= key) && - (zone->vello <= vel) && - (zone->velhi >= vel)); -} - -/*************************************************************** - * - * INST - */ - -/* - * new_fluid_inst - */ -fluid_inst_t* -new_fluid_inst() -{ - fluid_inst_t* inst = FLUID_NEW(fluid_inst_t); - if (inst == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - inst->name[0] = 0; - inst->global_zone = NULL; - inst->zone = NULL; - return inst; -} - -/* - * delete_fluid_inst - */ -int -delete_fluid_inst(fluid_inst_t* inst) -{ - fluid_inst_zone_t* zone; - int err = FLUID_OK; - if (inst->global_zone != NULL) { - if (delete_fluid_inst_zone(inst->global_zone) != FLUID_OK) { - err = FLUID_FAILED; - } - inst->global_zone = NULL; - } - zone = inst->zone; - while (zone != NULL) { - inst->zone = zone->next; - if (delete_fluid_inst_zone(zone) != FLUID_OK) { - err = FLUID_FAILED; - } - zone = inst->zone; - } - FLUID_FREE(inst); - return err; -} - -/* - * fluid_inst_set_global_zone - */ -int -fluid_inst_set_global_zone(fluid_inst_t* inst, fluid_inst_zone_t* zone) -{ - inst->global_zone = zone; - return FLUID_OK; -} - -/* - * fluid_inst_import_sfont - */ -int -fluid_inst_import_sfont(fluid_inst_t* inst, SFInst *sfinst, fluid_defsfont_t* sfont) -{ - fluid_list_t *p; - SFZone* sfzone; - fluid_inst_zone_t* zone; - char zone_name[256]; - int count; - - p = sfinst->zone; - if ((sfinst->name != NULL) && (FLUID_STRLEN(sfinst->name) > 0)) { - FLUID_STRCPY(inst->name, sfinst->name); - } else { - FLUID_STRCPY(inst->name, ""); - } - - count = 0; - while (p != NULL) { - - sfzone = (SFZone *) p->data; - FLUID_SPRINTF(zone_name, "%s/%d", inst->name, count); - - zone = new_fluid_inst_zone(zone_name); - if (zone == NULL) { - return FLUID_FAILED; - } - - if (fluid_inst_zone_import_sfont(zone, sfzone, sfont) != FLUID_OK) { - return FLUID_FAILED; - } - - if ((count == 0) && (fluid_inst_zone_get_sample(zone) == NULL)) { - fluid_inst_set_global_zone(inst, zone); - - } else if (fluid_inst_add_zone(inst, zone) != FLUID_OK) { - return FLUID_FAILED; - } - - p = fluid_list_next(p); - count++; - } - return FLUID_OK; -} - -/* - * fluid_inst_add_zone - */ -int -fluid_inst_add_zone(fluid_inst_t* inst, fluid_inst_zone_t* zone) -{ - if (inst->zone == NULL) { - zone->next = NULL; - inst->zone = zone; - } else { - zone->next = inst->zone; - inst->zone = zone; - } - return FLUID_OK; -} - -/* - * fluid_inst_get_zone - */ -fluid_inst_zone_t* -fluid_inst_get_zone(fluid_inst_t* inst) -{ - return inst->zone; -} - -/* - * fluid_inst_get_global_zone - */ -fluid_inst_zone_t* -fluid_inst_get_global_zone(fluid_inst_t* inst) -{ - return inst->global_zone; -} - -/*************************************************************** - * - * INST_ZONE - */ - -/* - * new_fluid_inst_zone - */ -fluid_inst_zone_t* -new_fluid_inst_zone(char* name) -{ - int size; - fluid_inst_zone_t* zone = NULL; - zone = FLUID_NEW(fluid_inst_zone_t); - if (zone == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - zone->next = NULL; - size = 1 + FLUID_STRLEN(name); - zone->name = FLUID_MALLOC(size); - if (zone->name == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - FLUID_FREE(zone); - return NULL; - } - FLUID_STRCPY(zone->name, name); - zone->sample = NULL; - zone->keylo = 0; - zone->keyhi = 128; - zone->vello = 0; - zone->velhi = 128; - - /* Flag the generators as unused. - * This also sets the generator values to default, but they will be overwritten anyway, if used.*/ - fluid_gen_set_default_values(&zone->gen[0]); - zone->mod=NULL; /* list of modulators */ - return zone; -} - -/* - * delete_fluid_inst_zone - */ -int -delete_fluid_inst_zone(fluid_inst_zone_t* zone) -{ - fluid_mod_t *mod, *tmp; - - mod = zone->mod; - while (mod) /* delete the modulators */ - { - tmp = mod; - mod = mod->next; - fluid_mod_delete (tmp); - } - - if (zone->name) FLUID_FREE (zone->name); - FLUID_FREE(zone); - return FLUID_OK; -} - -/* - * fluid_inst_zone_next - */ -fluid_inst_zone_t* -fluid_inst_zone_next(fluid_inst_zone_t* zone) -{ - return zone->next; -} - -/* - * fluid_inst_zone_import_sfont - */ -int -fluid_inst_zone_import_sfont(fluid_inst_zone_t* zone, SFZone *sfzone, fluid_defsfont_t* sfont) -{ - fluid_list_t *r; - SFGen* sfgen; - int count; - - for (count = 0, r = sfzone->gen; r != NULL; count++) { - sfgen = (SFGen *) r->data; - switch (sfgen->id) { - case GEN_KEYRANGE: - zone->keylo = (int) sfgen->amount.range.lo; - zone->keyhi = (int) sfgen->amount.range.hi; - break; - case GEN_VELRANGE: - zone->vello = (int) sfgen->amount.range.lo; - zone->velhi = (int) sfgen->amount.range.hi; - break; - default: - /* FIXME: some generators have an unsigned word amount value but - i don't know which ones */ - zone->gen[sfgen->id].val = (fluid_real_t) sfgen->amount.sword; - zone->gen[sfgen->id].flags = GEN_SET; - break; - } - r = fluid_list_next(r); - } - - /* FIXME */ -/* if (zone->gen[GEN_EXCLUSIVECLASS].flags == GEN_SET) { */ -/* FLUID_LOG(FLUID_DBG, "ExclusiveClass=%d\n", (int) zone->gen[GEN_EXCLUSIVECLASS].val); */ -/* } */ - - if ((sfzone->instsamp != NULL) && (sfzone->instsamp->data != NULL)) { - zone->sample = fluid_defsfont_get_sample(sfont, ((SFSample *) sfzone->instsamp->data)->name); - if (zone->sample == NULL) { - FLUID_LOG(FLUID_ERR, "Couldn't find sample name"); - return FLUID_FAILED; - } - } - - /* Import the modulators (only SF2.1 and higher) */ - for (count = 0, r = sfzone->mod; r != NULL; count++) { - SFMod* mod_src = (SFMod *) r->data; - int type; - fluid_mod_t* mod_dest; - - mod_dest = fluid_mod_new(); - if (mod_dest == NULL){ - return FLUID_FAILED; - } - - mod_dest->next = NULL; /* pointer to next modulator, this is the end of the list now.*/ - - /* *** Amount *** */ - mod_dest->amount = mod_src->amount; - - /* *** Source *** */ - mod_dest->src1 = mod_src->src & 127; /* index of source 1, seven-bit value, SF2.01 section 8.2, page 50 */ - mod_dest->flags1 = 0; - - /* Bit 7: CC flag SF 2.01 section 8.2.1 page 50*/ - if (mod_src->src & (1<<7)){ - mod_dest->flags1 |= FLUID_MOD_CC; - } else { - mod_dest->flags1 |= FLUID_MOD_GC; - } - - /* Bit 8: D flag SF 2.01 section 8.2.2 page 51*/ - if (mod_src->src & (1<<8)){ - mod_dest->flags1 |= FLUID_MOD_NEGATIVE; - } else { - mod_dest->flags1 |= FLUID_MOD_POSITIVE; - } - - /* Bit 9: P flag SF 2.01 section 8.2.3 page 51*/ - if (mod_src->src & (1<<9)){ - mod_dest->flags1 |= FLUID_MOD_BIPOLAR; - } else { - mod_dest->flags1 |= FLUID_MOD_UNIPOLAR; - } - - /* modulator source types: SF2.01 section 8.2.1 page 52 */ - type = (mod_src->src) >> 10; - type &= 63; /* type is a 6-bit value */ - if (type == 0){ - mod_dest->flags1 |= FLUID_MOD_LINEAR; - } else if (type == 1){ - mod_dest->flags1 |= FLUID_MOD_CONCAVE; - } else if (type == 2){ - mod_dest->flags1 |= FLUID_MOD_CONVEX; - } else if (type == 3){ - mod_dest->flags1 |= FLUID_MOD_SWITCH; - } else { - /* This shouldn't happen - unknown type! - * Deactivate the modulator by setting the amount to 0. */ - mod_dest->amount = 0; - } - - /* *** Dest *** */ - mod_dest->dest=mod_src->dest; /* index of controlled generator */ - - /* *** Amount source *** */ - mod_dest->src2=mod_src->amtsrc & 127; /* index of source 2, seven-bit value, SF2.01 section 8.2, page 50 */ - mod_dest->flags2 = 0; - - /* Bit 7: CC flag SF 2.01 section 8.2.1 page 50*/ - if (mod_src->amtsrc & (1<<7)){ - mod_dest->flags2 |= FLUID_MOD_CC; - } else { - mod_dest->flags2 |= FLUID_MOD_GC; - } - - /* Bit 8: D flag SF 2.01 section 8.2.2 page 51*/ - if (mod_src->amtsrc & (1<<8)){ - mod_dest->flags2 |= FLUID_MOD_NEGATIVE; - } else { - mod_dest->flags2 |= FLUID_MOD_POSITIVE; - } - - /* Bit 9: P flag SF 2.01 section 8.2.3 page 51*/ - if (mod_src->amtsrc & (1<<9)){ - mod_dest->flags2 |= FLUID_MOD_BIPOLAR; - } else { - mod_dest->flags2 |= FLUID_MOD_UNIPOLAR; - } - - /* modulator source types: SF2.01 section 8.2.1 page 52 */ - type=(mod_src->amtsrc) >> 10; - type &= 63; /* type is a 6-bit value */ - if (type == 0){ - mod_dest->flags2 |= FLUID_MOD_LINEAR; - } else if (type == 1){ - mod_dest->flags2 |= FLUID_MOD_CONCAVE; - } else if (type == 2){ - mod_dest->flags2 |= FLUID_MOD_CONVEX; - } else if (type == 3){ - mod_dest->flags2 |= FLUID_MOD_SWITCH; - } else { - /* This shouldn't happen - unknown type! - * Deactivate the modulator by setting the amount to 0. */ - mod_dest->amount = 0; - } - - /* *** Transform *** */ - /* SF2.01 only uses the 'linear' transform (0). - * Deactivate the modulator by setting the amount to 0 in any other case. - */ - if (mod_src->trans !=0){ - mod_dest->amount = 0; - } - - /* Store the new modulator in the zone - * The order of modulators will make a difference, at least in an instrument context: - * The second modulator overwrites the first one, if they only differ in amount. */ - if (count == 0){ - zone->mod=mod_dest; - } else { - fluid_mod_t * last_mod=zone->mod; - /* Find the end of the list */ - while (last_mod->next != NULL){ - last_mod=last_mod->next; - } - last_mod->next=mod_dest; - } - - r = fluid_list_next(r); - } /* foreach modulator */ - return FLUID_OK; -} - -/* - * fluid_inst_zone_get_sample - */ -fluid_sample_t* -fluid_inst_zone_get_sample(fluid_inst_zone_t* zone) -{ - return zone->sample; -} - -/* - * fluid_inst_zone_inside_range - */ -int -fluid_inst_zone_inside_range(fluid_inst_zone_t* zone, int key, int vel) -{ - return ((zone->keylo <= key) && - (zone->keyhi >= key) && - (zone->vello <= vel) && - (zone->velhi >= vel)); -} - -/*************************************************************** - * - * SAMPLE - */ - -/* - * new_fluid_sample - */ -fluid_sample_t* -new_fluid_sample() -{ - fluid_sample_t* sample = NULL; - - sample = FLUID_NEW(fluid_sample_t); - if (sample == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - - memset(sample, 0, sizeof(fluid_sample_t)); - sample->valid = 1; - - return sample; -} - -/* - * delete_fluid_sample - */ -int -delete_fluid_sample(fluid_sample_t* sample) -{ - FLUID_FREE(sample); - return FLUID_OK; -} - -/* - * fluid_sample_in_rom - */ -int -fluid_sample_in_rom(fluid_sample_t* sample) -{ - return (sample->sampletype & FLUID_SAMPLETYPE_ROM); -} - -/* - * fluid_sample_import_sfont - */ -int -fluid_sample_import_sfont(fluid_sample_t* sample, SFSample* sfsample, fluid_defsfont_t* sfont) -{ - FLUID_STRCPY(sample->name, sfsample->name); - sample->data = sfont->sampledata; - sample->start = sfsample->start; - sample->end = sfsample->start + sfsample->end; - sample->loopstart = sfsample->start + sfsample->loopstart; - sample->loopend = sfsample->start + sfsample->loopend; - sample->samplerate = sfsample->samplerate; - sample->origpitch = sfsample->origpitch; - sample->pitchadj = sfsample->pitchadj; - sample->sampletype = sfsample->sampletype; - - if (sample->sampletype & FLUID_SAMPLETYPE_ROM) { - sample->valid = 0; - FLUID_LOG(FLUID_WARN, "Ignoring sample %s: can't use ROM samples", sample->name); - } - if (sample->end - sample->start < 8) { - sample->valid = 0; - FLUID_LOG(FLUID_WARN, "Ignoring sample %s: too few sample data points", sample->name); - } else { -/* if (sample->loopstart < sample->start + 8) { */ -/* FLUID_LOG(FLUID_WARN, "Fixing sample %s: at least 8 data points required before loop start", sample->name); */ -/* sample->loopstart = sample->start + 8; */ -/* } */ -/* if (sample->loopend > sample->end - 8) { */ -/* FLUID_LOG(FLUID_WARN, "Fixing sample %s: at least 8 data points required after loop end", sample->name); */ -/* sample->loopend = sample->end - 8; */ -/* } */ - } - return FLUID_OK; -} - - - -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ - - - -/*=================================sfload.c======================== - Borrowed from Smurf SoundFont Editor by Josh Green - =================================================================*/ - -/* - functions for loading data from sfont files, with appropriate byte swapping - on big endian machines. Sfont IDs are not swapped because the ID read is - equivalent to the matching ID list in memory regardless of LE/BE machine -*/ - -#ifdef WORDS_BIGENDIAN -#define READCHUNK(var,fd) G_STMT_START { \ - if (!safe_fread(var, 8, fd)) \ - return(FAIL); \ - ((SFChunk *)(var))->size = GUINT32_FROM_BE(((SFChunk *)(var))->size); \ -} G_STMT_END -#else -#define READCHUNK(var,fd) G_STMT_START { \ - if (!safe_fread(var, 8, fd)) \ - return(FAIL); \ - ((SFChunk *)(var))->size = GUINT32_FROM_LE(((SFChunk *)(var))->size); \ -} G_STMT_END -#endif -#define READID(var,fd) G_STMT_START { \ - if (!safe_fread(var, 4, fd)) \ - return(FAIL); \ -} G_STMT_END -#define READSTR(var,fd) G_STMT_START { \ - if (!safe_fread(var, 20, fd)) \ - return(FAIL); \ - (*var)[20] = '\0'; \ -} G_STMT_END -#ifdef WORDS_BIGENDIAN -#define READD(var,fd) G_STMT_START { \ - unsigned int _temp; \ - if (!safe_fread(&_temp, 4, fd)) \ - return(FAIL); \ - var = GINT32_FROM_BE(_temp); \ -} G_STMT_END -#else -#define READD(var,fd) G_STMT_START { \ - unsigned int _temp; \ - if (!safe_fread(&_temp, 4, fd)) \ - return(FAIL); \ - var = GINT32_FROM_LE(_temp); \ -} G_STMT_END -#endif -#ifdef WORDS_BIGENDIAN - #define READW(var,fd) G_STMT_START { \ - unsigned short _temp; \ - if (!safe_fread(&_temp, 2, fd)) \ - return(FAIL); \ -var = GINT16_FROM_BE(_temp); \ -} G_STMT_END -#else -#define READW(var,fd) G_STMT_START { \ - unsigned short _temp; \ - if (!safe_fread(&_temp, 2, fd)) \ - return(FAIL); \ - var = GINT16_FROM_LE(_temp); \ -} G_STMT_END -#endif -#define READB(var,fd) G_STMT_START { \ - if (!safe_fread(&var, 1, fd)) \ - return(FAIL); \ -} G_STMT_END -#define FSKIP(size,fd) G_STMT_START { \ - if (!safe_fseek(fd, size, SEEK_CUR)) \ - return(FAIL); \ -} G_STMT_END -#define FSKIPW(fd) G_STMT_START { \ - if (!safe_fseek(fd, 2, SEEK_CUR)) \ - return(FAIL); \ -} G_STMT_END - -/* removes and advances a fluid_list_t pointer */ -#define SLADVREM(list, item) G_STMT_START { \ - fluid_list_t *_temp = item; \ - item = fluid_list_next(item); \ - list = fluid_list_remove_link(list, _temp); \ - delete1_fluid_list(_temp); \ -} G_STMT_END - -static int chunkid (unsigned int id); -static int load_body (unsigned int size, SFData * sf, FILE * fd); -static int read_listchunk (SFChunk * chunk, FILE * fd); -static int process_info (int size, SFData * sf, FILE * fd); -static int process_sdta (int size, SFData * sf, FILE * fd); -static int pdtahelper (unsigned int expid, unsigned int reclen, SFChunk * chunk, - int * size, FILE * fd); -static int process_pdta (int size, SFData * sf, FILE * fd); -static int load_phdr (int size, SFData * sf, FILE * fd); -static int load_pbag (int size, SFData * sf, FILE * fd); -static int load_pmod (int size, SFData * sf, FILE * fd); -static int load_pgen (int size, SFData * sf, FILE * fd); -static int load_ihdr (int size, SFData * sf, FILE * fd); -static int load_ibag (int size, SFData * sf, FILE * fd); -static int load_imod (int size, SFData * sf, FILE * fd); -static int load_igen (int size, SFData * sf, FILE * fd); -static int load_shdr (unsigned int size, SFData * sf, FILE * fd); -static int fixup_pgen (SFData * sf); -static int fixup_igen (SFData * sf); -static int fixup_sample (SFData * sf); - -char idlist[] = { - "RIFFLISTsfbkINFOsdtapdtaifilisngINAMiromiverICRDIENGIPRD" - "ICOPICMTISFTsnamsmplphdrpbagpmodpgeninstibagimodigenshdr" -}; - -static unsigned int sdtachunk_size; - -/* sound font file load functions */ -static int -chunkid (unsigned int id) -{ - unsigned int i; - unsigned int *p; - - p = (unsigned int *) & idlist; - for (i = 0; i < sizeof (idlist) / sizeof (int); i++, p += 1) - if (*p == id) - return (i + 1); - - return (UNKN_ID); -} - -SFData * -sfload_file (const char * fname) -{ - SFData *sf = NULL; - FILE *fd; - int fsize = 0; - int err = FALSE; - - if (!(fd = fopen (fname, "rb"))) - { - FLUID_LOG (FLUID_ERR, _("Unable to open file \"%s\""), fname); - return (NULL); - } - - if (!(sf = FLUID_NEW (SFData))) - { - FLUID_LOG(FLUID_ERR, "Out of memory"); - err = TRUE; - } - - if (!err) - { - memset (sf, 0, sizeof (SFData)); /* zero sfdata */ - sf->fname = FLUID_STRDUP (fname); /* copy file name */ - sf->sffd = fd; - } - - /* get size of file */ - if (!err && fseek (fd, 0L, SEEK_END) == -1) - { /* seek to end of file */ - err = TRUE; - FLUID_LOG (FLUID_ERR, _("Seek to end of file failed")); - } - if (!err && (fsize = ftell (fd)) == -1) - { /* position = size */ - err = TRUE; - FLUID_LOG (FLUID_ERR, _("Get end of file position failed")); - } - if (!err) - rewind (fd); - - if (!err && !load_body (fsize, sf, fd)) - err = TRUE; /* load the sfont */ - - if (err) - { - if (sf) - sfont_close (sf); - return (NULL); - } - - return (sf); -} - -static int -load_body (unsigned int size, SFData * sf, FILE * fd) -{ - SFChunk chunk; - - READCHUNK (&chunk, fd); /* load RIFF chunk */ - if (chunkid (chunk.id) != RIFF_ID) { /* error if not RIFF */ - FLUID_LOG (FLUID_ERR, _("Not a RIFF file")); - return (FAIL); - } - - READID (&chunk.id, fd); /* load file ID */ - if (chunkid (chunk.id) != SFBK_ID) { /* error if not SFBK_ID */ - FLUID_LOG (FLUID_ERR, _("Not a sound font file")); - return (FAIL); - } - - if (chunk.size != size - 8) { - gerr (ErrCorr, _("Sound font file size mismatch")); - return (FAIL); - } - - /* Process INFO block */ - if (!read_listchunk (&chunk, fd)) - return (FAIL); - if (chunkid (chunk.id) != INFO_ID) - return (gerr (ErrCorr, _("Invalid ID found when expecting INFO chunk"))); - if (!process_info (chunk.size, sf, fd)) - return (FAIL); - - /* Process sample chunk */ - if (!read_listchunk (&chunk, fd)) - return (FAIL); - if (chunkid (chunk.id) != SDTA_ID) - return (gerr (ErrCorr, - _("Invalid ID found when expecting SAMPLE chunk"))); - if (!process_sdta (chunk.size, sf, fd)) - return (FAIL); - - /* process HYDRA chunk */ - if (!read_listchunk (&chunk, fd)) - return (FAIL); - if (chunkid (chunk.id) != PDTA_ID) - return (gerr (ErrCorr, _("Invalid ID found when expecting HYDRA chunk"))); - if (!process_pdta (chunk.size, sf, fd)) - return (FAIL); - - if (!fixup_pgen (sf)) - return (FAIL); - if (!fixup_igen (sf)) - return (FAIL); - if (!fixup_sample (sf)) - return (FAIL); - - /* sort preset list by bank, preset # */ - sf->preset = fluid_list_sort (sf->preset, - (fluid_compare_func_t) sfont_preset_compare_func); - - return (OK); -} - -static int -read_listchunk (SFChunk * chunk, FILE * fd) -{ - READCHUNK (chunk, fd); /* read list chunk */ - if (chunkid (chunk->id) != LIST_ID) /* error if ! list chunk */ - return (gerr (ErrCorr, _("Invalid chunk id in level 0 parse"))); - READID (&chunk->id, fd); /* read id string */ - chunk->size -= 4; - return (OK); -} - -static int -process_info (int size, SFData * sf, FILE * fd) -{ - SFChunk chunk; - unsigned char id; - char *item; - unsigned short ver; - - while (size > 0) - { - READCHUNK (&chunk, fd); - size -= 8; - - id = chunkid (chunk.id); - - if (id == IFIL_ID) - { /* sound font version chunk? */ - if (chunk.size != 4) - return (gerr (ErrCorr, - _("Sound font version info chunk has invalid size"))); - - READW (ver, fd); - sf->version.major = ver; - READW (ver, fd); - sf->version.minor = ver; - - if (sf->version.major < 2) { - FLUID_LOG (FLUID_ERR, - _("Sound font version is %d.%d which is not" - " supported, convert to version 2.0x"), - sf->version.major, - sf->version.minor); - return (FAIL); - } - - if (sf->version.major > 2) { - FLUID_LOG (FLUID_WARN, - _("Sound font version is %d.%d which is newer than" - " what this version of FLUID Synth was designed for (v2.0x)"), - sf->version.major, - sf->version.minor); - return (FAIL); - } - } - else if (id == IVER_ID) - { /* ROM version chunk? */ - if (chunk.size != 4) - return (gerr (ErrCorr, - _("ROM version info chunk has invalid size"))); - - READW (ver, fd); - sf->romver.major = ver; - READW (ver, fd); - sf->romver.minor = ver; - } - else if (id != UNKN_ID) - { - if ((id != ICMT_ID && chunk.size > 256) || (chunk.size > 65536) - || (chunk.size % 2)) - return (gerr (ErrCorr, - _("INFO sub chunk %.4s has invalid chunk size" - " of %d bytes"), &chunk.id, chunk.size)); - - /* alloc for chunk id and da chunk */ - if (!(item = FLUID_MALLOC (chunk.size + 1))) - { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return (FAIL); - } - - /* attach to INFO list, sfont_close will cleanup if FAIL occurs */ - sf->info = fluid_list_append (sf->info, item); - - *(unsigned char *) item = id; - if (!safe_fread (&item[1], chunk.size, fd)) - return (FAIL); - - /* force terminate info item (don't forget uint8 info ID) */ - *(item + chunk.size) = '\0'; - } - else - return (gerr (ErrCorr, _("Invalid chunk id in INFO chunk"))); - size -= chunk.size; - } - - if (size < 0) - return (gerr (ErrCorr, _("INFO chunk size mismatch"))); - - return (OK); -} - -static int -process_sdta (int size, SFData * sf, FILE * fd) -{ - SFChunk chunk; - - if (size == 0) - return (OK); /* no sample data? */ - - /* read sub chunk */ - READCHUNK (&chunk, fd); - size -= 8; - - if (chunkid (chunk.id) != SMPL_ID) - return (gerr (ErrCorr, - _("Expected SMPL chunk found invalid id instead"))); - - if ((size - chunk.size) != 0) - return (gerr (ErrCorr, _("SDTA chunk size mismatch"))); - - /* sample data follows */ - sf->samplepos = ftell (fd); - - /* used in fixup_sample() to check validity of sample headers */ - sdtachunk_size = chunk.size; - sf->samplesize = chunk.size; - - FSKIP (chunk.size, fd); - - return (OK); -} - -static int -pdtahelper (unsigned int expid, unsigned int reclen, SFChunk * chunk, - int * size, FILE * fd) -{ - unsigned int id; - char *expstr; - - expstr = CHNKIDSTR (expid); /* in case we need it */ - - READCHUNK (chunk, fd); - *size -= 8; - - if ((id = chunkid (chunk->id)) != expid) - return (gerr (ErrCorr, _("Expected" - " PDTA sub-chunk \"%.4s\" found invalid id instead"), expstr)); - - if (chunk->size % reclen) /* valid chunk size? */ - return (gerr (ErrCorr, - _("\"%.4s\" chunk size is not a multiple of %d bytes"), expstr, - reclen)); - if ((*size -= chunk->size) < 0) - return (gerr (ErrCorr, - _("\"%.4s\" chunk size exceeds remaining PDTA chunk size"), expstr)); - return (OK); -} - -static int -process_pdta (int size, SFData * sf, FILE * fd) -{ - SFChunk chunk; - - if (!pdtahelper (PHDR_ID, SFPHDRSIZE, &chunk, &size, fd)) - return (FAIL); - if (!load_phdr (chunk.size, sf, fd)) - return (FAIL); - - if (!pdtahelper (PBAG_ID, SFBAGSIZE, &chunk, &size, fd)) - return (FAIL); - if (!load_pbag (chunk.size, sf, fd)) - return (FAIL); - - if (!pdtahelper (PMOD_ID, SFMODSIZE, &chunk, &size, fd)) - return (FAIL); - if (!load_pmod (chunk.size, sf, fd)) - return (FAIL); - - if (!pdtahelper (PGEN_ID, SFGENSIZE, &chunk, &size, fd)) - return (FAIL); - if (!load_pgen (chunk.size, sf, fd)) - return (FAIL); - - if (!pdtahelper (IHDR_ID, SFIHDRSIZE, &chunk, &size, fd)) - return (FAIL); - if (!load_ihdr (chunk.size, sf, fd)) - return (FAIL); - - if (!pdtahelper (IBAG_ID, SFBAGSIZE, &chunk, &size, fd)) - return (FAIL); - if (!load_ibag (chunk.size, sf, fd)) - return (FAIL); - - if (!pdtahelper (IMOD_ID, SFMODSIZE, &chunk, &size, fd)) - return (FAIL); - if (!load_imod (chunk.size, sf, fd)) - return (FAIL); - - if (!pdtahelper (IGEN_ID, SFGENSIZE, &chunk, &size, fd)) - return (FAIL); - if (!load_igen (chunk.size, sf, fd)) - return (FAIL); - - if (!pdtahelper (SHDR_ID, SFSHDRSIZE, &chunk, &size, fd)) - return (FAIL); - if (!load_shdr (chunk.size, sf, fd)) - return (FAIL); - - return (OK); -} - -/* preset header loader */ -static int -load_phdr (int size, SFData * sf, FILE * fd) -{ - int i, i2; - SFPreset *p, *pr = NULL; /* ptr to current & previous preset */ - unsigned short zndx, pzndx = 0; - - if (size % SFPHDRSIZE || size == 0) - return (gerr (ErrCorr, _("Preset header chunk size is invalid"))); - - i = size / SFPHDRSIZE - 1; - if (i == 0) - { /* at least one preset + term record */ - FLUID_LOG (FLUID_WARN, _("File contains no presets")); - FSKIP (SFPHDRSIZE, fd); - return (OK); - } - - for (; i > 0; i--) - { /* load all preset headers */ - p = FLUID_NEW (SFPreset); - sf->preset = fluid_list_append (sf->preset, p); - p->zone = NULL; /* In case of failure, sfont_close can cleanup */ - READSTR (&p->name, fd); /* possible read failure ^ */ - READW (p->prenum, fd); - READW (p->bank, fd); - READW (zndx, fd); - READD (p->libr, fd); - READD (p->genre, fd); - READD (p->morph, fd); - - if (pr) - { /* not first preset? */ - if (zndx < pzndx) - return (gerr (ErrCorr, _("Preset header indices not monotonic"))); - i2 = zndx - pzndx; - while (i2--) - { - pr->zone = fluid_list_prepend (pr->zone, NULL); - } - } - else if (zndx > 0) /* 1st preset, warn if ofs >0 */ - FLUID_LOG (FLUID_WARN, _("%d preset zones not referenced, discarding"), zndx); - pr = p; /* update preset ptr */ - pzndx = zndx; - } - - FSKIP (24, fd); - READW (zndx, fd); /* Read terminal generator index */ - FSKIP (12, fd); - - if (zndx < pzndx) - return (gerr (ErrCorr, _("Preset header indices not monotonic"))); - i2 = zndx - pzndx; - while (i2--) - { - pr->zone = fluid_list_prepend (pr->zone, NULL); - } - - return (OK); -} - -/* preset bag loader */ -static int -load_pbag (int size, SFData * sf, FILE * fd) -{ - fluid_list_t *p, *p2; - SFZone *z, *pz = NULL; - unsigned short genndx, modndx; - unsigned short pgenndx = 0, pmodndx = 0; - unsigned short i; - - if (size % SFBAGSIZE || size == 0) /* size is multiple of SFBAGSIZE? */ - return (gerr (ErrCorr, _("Preset bag chunk size is invalid"))); - - p = sf->preset; - while (p) - { /* traverse through presets */ - p2 = ((SFPreset *) (p->data))->zone; - while (p2) - { /* traverse preset's zones */ - if ((size -= SFBAGSIZE) < 0) - return (gerr (ErrCorr, _("Preset bag chunk size mismatch"))); - z = FLUID_NEW (SFZone); - p2->data = z; - z->gen = NULL; /* Init gen and mod before possible failure, */ - z->mod = NULL; /* to ensure proper cleanup (sfont_close) */ - READW (genndx, fd); /* possible read failure ^ */ - READW (modndx, fd); - z->instsamp = NULL; - - if (pz) - { /* if not first zone */ - if (genndx < pgenndx) - return (gerr (ErrCorr, - _("Preset bag generator indices not monotonic"))); - if (modndx < pmodndx) - return (gerr (ErrCorr, - _("Preset bag modulator indices not monotonic"))); - i = genndx - pgenndx; - while (i--) - pz->gen = fluid_list_prepend (pz->gen, NULL); - i = modndx - pmodndx; - while (i--) - pz->mod = fluid_list_prepend (pz->mod, NULL); - } - pz = z; /* update previous zone ptr */ - pgenndx = genndx; /* update previous zone gen index */ - pmodndx = modndx; /* update previous zone mod index */ - p2 = fluid_list_next (p2); - } - p = fluid_list_next (p); - } - - size -= SFBAGSIZE; - if (size != 0) - return (gerr (ErrCorr, _("Preset bag chunk size mismatch"))); - - READW (genndx, fd); - READW (modndx, fd); - - if (!pz) - { - if (genndx > 0) - FLUID_LOG (FLUID_WARN, _("No preset generators and terminal index not 0")); - if (modndx > 0) - FLUID_LOG (FLUID_WARN, _("No preset modulators and terminal index not 0")); - return (OK); - } - - if (genndx < pgenndx) - return (gerr (ErrCorr, _("Preset bag generator indices not monotonic"))); - if (modndx < pmodndx) - return (gerr (ErrCorr, _("Preset bag modulator indices not monotonic"))); - i = genndx - pgenndx; - while (i--) - pz->gen = fluid_list_prepend (pz->gen, NULL); - i = modndx - pmodndx; - while (i--) - pz->mod = fluid_list_prepend (pz->mod, NULL); - - return (OK); -} - -/* preset modulator loader */ -static int -load_pmod (int size, SFData * sf, FILE * fd) -{ - fluid_list_t *p, *p2, *p3; - SFMod *m; - - p = sf->preset; - while (p) - { /* traverse through all presets */ - p2 = ((SFPreset *) (p->data))->zone; - while (p2) - { /* traverse this preset's zones */ - p3 = ((SFZone *) (p2->data))->mod; - while (p3) - { /* load zone's modulators */ - if ((size -= SFMODSIZE) < 0) - return (gerr (ErrCorr, - _("Preset modulator chunk size mismatch"))); - m = FLUID_NEW (SFMod); - p3->data = m; - READW (m->src, fd); - READW (m->dest, fd); - READW (m->amount, fd); - READW (m->amtsrc, fd); - READW (m->trans, fd); - p3 = fluid_list_next (p3); - } - p2 = fluid_list_next (p2); - } - p = fluid_list_next (p); - } - - /* - If there isn't even a terminal record - Hmmm, the specs say there should be one, but.. - */ - if (size == 0) - return (OK); - - size -= SFMODSIZE; - if (size != 0) - return (gerr (ErrCorr, _("Preset modulator chunk size mismatch"))); - FSKIP (SFMODSIZE, fd); /* terminal mod */ - - return (OK); -} - -/* ------------------------------------------------------------------- - * preset generator loader - * generator (per preset) loading rules: - * Zones with no generators or modulators shall be annihilated - * Global zone must be 1st zone, discard additional ones (instrumentless zones) - * - * generator (per zone) loading rules (in order of decreasing precedence): - * KeyRange is 1st in list (if exists), else discard - * if a VelRange exists only preceded by a KeyRange, else discard - * if a generator follows an instrument discard it - * if a duplicate generator exists replace previous one - * ------------------------------------------------------------------- */ -static int -load_pgen (int size, SFData * sf, FILE * fd) -{ - fluid_list_t *p, *p2, *p3, *dup, **hz = NULL; - SFZone *z; - SFGen *g; - SFGenAmount genval; - unsigned short genid; - int level, skip, drop, gzone, discarded; - - p = sf->preset; - while (p) - { /* traverse through all presets */ - gzone = FALSE; - discarded = FALSE; - p2 = ((SFPreset *) (p->data))->zone; - if (p2) - hz = &p2; - while (p2) - { /* traverse preset's zones */ - level = 0; - z = (SFZone *) (p2->data); - p3 = z->gen; - while (p3) - { /* load zone's generators */ - dup = NULL; - skip = FALSE; - drop = FALSE; - if ((size -= SFGENSIZE) < 0) - return (gerr (ErrCorr, - _("Preset generator chunk size mismatch"))); - - READW (genid, fd); - - if (genid == Gen_KeyRange) - { /* nothing precedes */ - if (level == 0) - { - level = 1; - READB (genval.range.lo, fd); - READB (genval.range.hi, fd); - } - else - skip = TRUE; - } - else if (genid == Gen_VelRange) - { /* only KeyRange precedes */ - if (level <= 1) - { - level = 2; - READB (genval.range.lo, fd); - READB (genval.range.hi, fd); - } - else - skip = TRUE; - } - else if (genid == Gen_Instrument) - { /* inst is last gen */ - level = 3; - READW (genval.uword, fd); - ((SFZone *) (p2->data))->instsamp = GINT_TO_POINTER (genval.uword + 1); - break; /* break out of generator loop */ - } - else - { - level = 2; - if (gen_validp (genid)) - { /* generator valid? */ - READW (genval.sword, fd); - dup = gen_inlist (genid, z->gen); - } - else - skip = TRUE; - } - - if (!skip) - { - if (!dup) - { /* if gen ! dup alloc new */ - g = FLUID_NEW (SFGen); - p3->data = g; - g->id = genid; - } - else - { - g = (SFGen *) (dup->data); /* ptr to orig gen */ - drop = TRUE; - } - g->amount = genval; - } - else - { /* Skip this generator */ - discarded = TRUE; - drop = TRUE; - FSKIPW (fd); - } - - if (!drop) - p3 = fluid_list_next (p3); /* next gen */ - else - SLADVREM (z->gen, p3); /* drop place holder */ - - } /* generator loop */ - - if (level == 3) - SLADVREM (z->gen, p3); /* zone has inst? */ - else - { /* congratulations its a global zone */ - if (!gzone) - { /* Prior global zones? */ - gzone = TRUE; - - /* if global zone is not 1st zone, relocate */ - if (*hz != p2) - { - void* save = p2->data; - FLUID_LOG (FLUID_WARN, - _("Preset \"%s\": Global zone is not first zone"), - ((SFPreset *) (p->data))->name); - SLADVREM (*hz, p2); - *hz = fluid_list_prepend (*hz, save); - continue; - } - } - else - { /* previous global zone exists, discard */ - FLUID_LOG (FLUID_WARN, - _("Preset \"%s\": Discarding invalid global zone"), - ((SFPreset *) (p->data))->name); - sfont_zone_delete (sf, hz, (SFZone *) (p2->data)); - } - } - - while (p3) - { /* Kill any zones following an instrument */ - discarded = TRUE; - if ((size -= SFGENSIZE) < 0) - return (gerr (ErrCorr, - _("Preset generator chunk size mismatch"))); - FSKIP (SFGENSIZE, fd); - SLADVREM (z->gen, p3); - } - - p2 = fluid_list_next (p2); /* next zone */ - } - if (discarded) - FLUID_LOG(FLUID_WARN, - _("Preset \"%s\": Some invalid generators were discarded"), - ((SFPreset *) (p->data))->name); - p = fluid_list_next (p); - } - - /* in case there isn't a terminal record */ - if (size == 0) - return (OK); - - size -= SFGENSIZE; - if (size != 0) - return (gerr (ErrCorr, _("Preset generator chunk size mismatch"))); - FSKIP (SFGENSIZE, fd); /* terminal gen */ - - return (OK); -} - -/* instrument header loader */ -static int -load_ihdr (int size, SFData * sf, FILE * fd) -{ - int i, i2; - SFInst *p, *pr = NULL; /* ptr to current & previous instrument */ - unsigned short zndx, pzndx = 0; - - if (size % SFIHDRSIZE || size == 0) /* chunk size is valid? */ - return (gerr (ErrCorr, _("Instrument header has invalid size"))); - - size = size / SFIHDRSIZE - 1; - if (size == 0) - { /* at least one preset + term record */ - FLUID_LOG (FLUID_WARN, _("File contains no instruments")); - FSKIP (SFIHDRSIZE, fd); - return (OK); - } - - for (i = 0; i < size; i++) - { /* load all instrument headers */ - p = FLUID_NEW (SFInst); - sf->inst = fluid_list_append (sf->inst, p); - p->zone = NULL; /* For proper cleanup if fail (sfont_close) */ - READSTR (&p->name, fd); /* Possible read failure ^ */ - READW (zndx, fd); - - if (pr) - { /* not first instrument? */ - if (zndx < pzndx) - return (gerr (ErrCorr, - _("Instrument header indices not monotonic"))); - i2 = zndx - pzndx; - while (i2--) - pr->zone = fluid_list_prepend (pr->zone, NULL); - } - else if (zndx > 0) /* 1st inst, warn if ofs >0 */ - FLUID_LOG (FLUID_WARN, _("%d instrument zones not referenced, discarding"), - zndx); - pzndx = zndx; - pr = p; /* update instrument ptr */ - } - - FSKIP (20, fd); - READW (zndx, fd); - - if (zndx < pzndx) - return (gerr (ErrCorr, _("Instrument header indices not monotonic"))); - i2 = zndx - pzndx; - while (i2--) - pr->zone = fluid_list_prepend (pr->zone, NULL); - - return (OK); -} - -/* instrument bag loader */ -static int -load_ibag (int size, SFData * sf, FILE * fd) -{ - fluid_list_t *p, *p2; - SFZone *z, *pz = NULL; - unsigned short genndx, modndx, pgenndx = 0, pmodndx = 0; - int i; - - if (size % SFBAGSIZE || size == 0) /* size is multiple of SFBAGSIZE? */ - return (gerr (ErrCorr, _("Instrument bag chunk size is invalid"))); - - p = sf->inst; - while (p) - { /* traverse through inst */ - p2 = ((SFInst *) (p->data))->zone; - while (p2) - { /* load this inst's zones */ - if ((size -= SFBAGSIZE) < 0) - return (gerr (ErrCorr, _("Instrument bag chunk size mismatch"))); - z = FLUID_NEW (SFZone); - p2->data = z; - z->gen = NULL; /* In case of failure, */ - z->mod = NULL; /* sfont_close can clean up */ - READW (genndx, fd); /* READW = possible read failure */ - READW (modndx, fd); - z->instsamp = NULL; - - if (pz) - { /* if not first zone */ - if (genndx < pgenndx) - return (gerr (ErrCorr, - _("Instrument generator indices not monotonic"))); - if (modndx < pmodndx) - return (gerr (ErrCorr, - _("Instrument modulator indices not monotonic"))); - i = genndx - pgenndx; - while (i--) - pz->gen = fluid_list_prepend (pz->gen, NULL); - i = modndx - pmodndx; - while (i--) - pz->mod = fluid_list_prepend (pz->mod, NULL); - } - pz = z; /* update previous zone ptr */ - pgenndx = genndx; - pmodndx = modndx; - p2 = fluid_list_next (p2); - } - p = fluid_list_next (p); - } - - size -= SFBAGSIZE; - if (size != 0) - return (gerr (ErrCorr, _("Instrument chunk size mismatch"))); - - READW (genndx, fd); - READW (modndx, fd); - - if (!pz) - { /* in case that all are no zoners */ - if (genndx > 0) - FLUID_LOG (FLUID_WARN, - _("No instrument generators and terminal index not 0")); - if (modndx > 0) - FLUID_LOG (FLUID_WARN, - _("No instrument modulators and terminal index not 0")); - return (OK); - } - - if (genndx < pgenndx) - return (gerr (ErrCorr, _("Instrument generator indices not monotonic"))); - if (modndx < pmodndx) - return (gerr (ErrCorr, _("Instrument modulator indices not monotonic"))); - i = genndx - pgenndx; - while (i--) - pz->gen = fluid_list_prepend (pz->gen, NULL); - i = modndx - pmodndx; - while (i--) - pz->mod = fluid_list_prepend (pz->mod, NULL); - - return (OK); -} - -/* instrument modulator loader */ -static int -load_imod (int size, SFData * sf, FILE * fd) -{ - fluid_list_t *p, *p2, *p3; - SFMod *m; - - p = sf->inst; - while (p) - { /* traverse through all inst */ - p2 = ((SFInst *) (p->data))->zone; - while (p2) - { /* traverse this inst's zones */ - p3 = ((SFZone *) (p2->data))->mod; - while (p3) - { /* load zone's modulators */ - if ((size -= SFMODSIZE) < 0) - return (gerr (ErrCorr, - _("Instrument modulator chunk size mismatch"))); - m = FLUID_NEW (SFMod); - p3->data = m; - READW (m->src, fd); - READW (m->dest, fd); - READW (m->amount, fd); - READW (m->amtsrc, fd); - READW (m->trans, fd); - p3 = fluid_list_next (p3); - } - p2 = fluid_list_next (p2); - } - p = fluid_list_next (p); - } - - /* - If there isn't even a terminal record - Hmmm, the specs say there should be one, but.. - */ - if (size == 0) - return (OK); - - size -= SFMODSIZE; - if (size != 0) - return (gerr (ErrCorr, _("Instrument modulator chunk size mismatch"))); - FSKIP (SFMODSIZE, fd); /* terminal mod */ - - return (OK); -} - -/* load instrument generators (see load_pgen for loading rules) */ -static int -load_igen (int size, SFData * sf, FILE * fd) -{ - fluid_list_t *p, *p2, *p3, *dup, **hz = NULL; - SFZone *z; - SFGen *g; - SFGenAmount genval; - unsigned short genid; - int level, skip, drop, gzone, discarded; - - p = sf->inst; - while (p) - { /* traverse through all instruments */ - gzone = FALSE; - discarded = FALSE; - p2 = ((SFInst *) (p->data))->zone; - if (p2) - hz = &p2; - while (p2) - { /* traverse this instrument's zones */ - level = 0; - z = (SFZone *) (p2->data); - p3 = z->gen; - while (p3) - { /* load zone's generators */ - dup = NULL; - skip = FALSE; - drop = FALSE; - if ((size -= SFGENSIZE) < 0) - return (gerr (ErrCorr, _("IGEN chunk size mismatch"))); - - READW (genid, fd); - - if (genid == Gen_KeyRange) - { /* nothing precedes */ - if (level == 0) - { - level = 1; - READB (genval.range.lo, fd); - READB (genval.range.hi, fd); - } - else - skip = TRUE; - } - else if (genid == Gen_VelRange) - { /* only KeyRange precedes */ - if (level <= 1) - { - level = 2; - READB (genval.range.lo, fd); - READB (genval.range.hi, fd); - } - else - skip = TRUE; - } - else if (genid == Gen_SampleId) - { /* sample is last gen */ - level = 3; - READW (genval.uword, fd); - ((SFZone *) (p2->data))->instsamp = GINT_TO_POINTER (genval.uword + 1); - break; /* break out of generator loop */ - } - else - { - level = 2; - if (gen_valid (genid)) - { /* gen valid? */ - READW (genval.sword, fd); - dup = gen_inlist (genid, z->gen); - } - else - skip = TRUE; - } - - if (!skip) - { - if (!dup) - { /* if gen ! dup alloc new */ - g = FLUID_NEW (SFGen); - p3->data = g; - g->id = genid; - } - else - { - g = (SFGen *) (dup->data); - drop = TRUE; - } - g->amount = genval; - } - else - { /* skip this generator */ - discarded = TRUE; - drop = TRUE; - FSKIPW (fd); - } - - if (!drop) - p3 = fluid_list_next (p3); /* next gen */ - else - SLADVREM (z->gen, p3); - - } /* generator loop */ - - if (level == 3) - SLADVREM (z->gen, p3); /* zone has sample? */ - else - { /* its a global zone */ - if (!gzone) - { - gzone = TRUE; - - /* if global zone is not 1st zone, relocate */ - if (*hz != p2) - { - void* save = p2->data; - FLUID_LOG (FLUID_WARN, - _("Instrument \"%s\": Global zone is not first zone"), - ((SFPreset *) (p->data))->name); - SLADVREM (*hz, p2); - *hz = fluid_list_prepend (*hz, save); - continue; - } - } - else - { /* previous global zone exists, discard */ - FLUID_LOG (FLUID_WARN, - _("Instrument \"%s\": Discarding invalid global zone"), - ((SFInst *) (p->data))->name); - sfont_zone_delete (sf, hz, (SFZone *) (p2->data)); - } - } - - while (p3) - { /* Kill any zones following a sample */ - discarded = TRUE; - if ((size -= SFGENSIZE) < 0) - return (gerr (ErrCorr, - _("Instrument generator chunk size mismatch"))); - FSKIP (SFGENSIZE, fd); - SLADVREM (z->gen, p3); - } - - p2 = fluid_list_next (p2); /* next zone */ - } - if (discarded) - FLUID_LOG(FLUID_WARN, - _("Instrument \"%s\": Some invalid generators were discarded"), - ((SFInst *) (p->data))->name); - p = fluid_list_next (p); - } - - /* for those non-terminal record cases, grr! */ - if (size == 0) - return (OK); - - size -= SFGENSIZE; - if (size != 0) - return (gerr (ErrCorr, _("IGEN chunk size mismatch"))); - FSKIP (SFGENSIZE, fd); /* terminal gen */ - - return (OK); -} - -/* sample header loader */ -static int -load_shdr (unsigned int size, SFData * sf, FILE * fd) -{ - unsigned int i; - SFSample *p; - - if (size % SFSHDRSIZE || size == 0) /* size is multiple of SHDR size? */ - return (gerr (ErrCorr, _("Sample header has invalid size"))); - - size = size / SFSHDRSIZE - 1; - if (size == 0) - { /* at least one sample + term record? */ - FLUID_LOG (FLUID_WARN, _("File contains no samples")); - FSKIP (SFSHDRSIZE, fd); - return (OK); - } - - /* load all sample headers */ - for (i = 0; i < size; i++) - { - p = FLUID_NEW (SFSample); - sf->sample = fluid_list_append (sf->sample, p); - READSTR (&p->name, fd); - READD (p->start, fd); - READD (p->end, fd); /* - end, loopstart and loopend */ - READD (p->loopstart, fd); /* - will be checked and turned into */ - READD (p->loopend, fd); /* - offsets in fixup_sample() */ - READD (p->samplerate, fd); - READB (p->origpitch, fd); - READB (p->pitchadj, fd); - FSKIPW (fd); /* skip sample link */ - READW (p->sampletype, fd); - p->samfile = 0; - } - - FSKIP (SFSHDRSIZE, fd); /* skip terminal shdr */ - - return (OK); -} - -/* "fixup" (inst # -> inst ptr) instrument references in preset list */ -static int -fixup_pgen (SFData * sf) -{ - fluid_list_t *p, *p2, *p3; - SFZone *z; - int i; - - p = sf->preset; - while (p) - { - p2 = ((SFPreset *) (p->data))->zone; - while (p2) - { /* traverse this preset's zones */ - z = (SFZone *) (p2->data); - if ((i = GPOINTER_TO_INT (z->instsamp))) - { /* load instrument # */ - p3 = fluid_list_nth (sf->inst, i - 1); - if (!p3) - return (gerr (ErrCorr, - _("Preset %03d %03d: Invalid instrument reference"), - ((SFPreset *) (p->data))->bank, - ((SFPreset *) (p->data))->prenum)); - z->instsamp = p3; - } - else - z->instsamp = NULL; - p2 = fluid_list_next (p2); - } - p = fluid_list_next (p); - } - - return (OK); -} - -/* "fixup" (sample # -> sample ptr) sample references in instrument list */ -static int -fixup_igen (SFData * sf) -{ - fluid_list_t *p, *p2, *p3; - SFZone *z; - int i; - - p = sf->inst; - while (p) - { - p2 = ((SFInst *) (p->data))->zone; - while (p2) - { /* traverse instrument's zones */ - z = (SFZone *) (p2->data); - if ((i = GPOINTER_TO_INT (z->instsamp))) - { /* load sample # */ - p3 = fluid_list_nth (sf->sample, i - 1); - if (!p3) - return (gerr (ErrCorr, - _("Instrument \"%s\": Invalid sample reference"), - ((SFInst *) (p->data))->name)); - z->instsamp = p3; - } - p2 = fluid_list_next (p2); - } - p = fluid_list_next (p); - } - - return (OK); -} - -/* convert sample end, loopstart and loopend to offsets and check if valid */ -static int -fixup_sample (SFData * sf) -{ - fluid_list_t *p; - SFSample *sam; - - p = sf->sample; - while (p) - { - sam = (SFSample *) (p->data); - - /* if sample is not a ROM sample and end is over the sample data chunk - or sam start is greater than 4 less than the end (at least 4 samples) */ - if ((!(sam->sampletype & FLUID_SAMPLETYPE_ROM) - && sam->end > sdtachunk_size) || sam->start > (sam->end - 4)) - { - FLUID_LOG (FLUID_WARN, _("Sample '%s' start/end file positions are invalid," - " disabling and will not be saved"), sam->name); - - /* disable sample by setting all sample markers to 0 */ - sam->start = sam->end = sam->loopstart = sam->loopend = 0; - - return (OK); - } - else if (sam->loopend > sam->end || sam->loopstart >= sam->loopend - || sam->loopstart <= sam->start) - { /* loop is fowled?? (cluck cluck :) */ - /* can pad loop by 8 samples and ensure at least 4 for loop (2*8+4) */ - if ((sam->end - sam->start) >= 20) - { - sam->loopstart = sam->start + 8; - sam->loopend = sam->end - 8; - } - else - { /* loop is fowled, sample is tiny (can't pad 8 samples) */ - sam->loopstart = sam->start + 1; - sam->loopend = sam->end - 1; - } - } - - /* convert sample end, loopstart, loopend to offsets from sam->start */ - sam->end -= sam->start + 1; /* marks last sample, contrary to SF spec. */ - sam->loopstart -= sam->start; - sam->loopend -= sam->start; - - p = fluid_list_next (p); - } - - return (OK); -} - -/*=================================sfont.c======================== - Smurf SoundFont Editor - ================================================================*/ - - -/* optimum chunk area sizes (could be more optimum) */ -#define PRESET_CHUNK_OPTIMUM_AREA 256 -#define INST_CHUNK_OPTIMUM_AREA 256 -#define SAMPLE_CHUNK_OPTIMUM_AREA 256 -#define ZONE_CHUNK_OPTIMUM_AREA 256 -#define MOD_CHUNK_OPTIMUM_AREA 256 -#define GEN_CHUNK_OPTIMUM_AREA 256 - -unsigned short badgen[] = { Gen_Unused1, Gen_Unused2, Gen_Unused3, Gen_Unused4, - Gen_Reserved1, Gen_Reserved2, Gen_Reserved3, 0 -}; - -unsigned short badpgen[] = { Gen_StartAddrOfs, Gen_EndAddrOfs, Gen_StartLoopAddrOfs, - Gen_EndLoopAddrOfs, Gen_StartAddrCoarseOfs, Gen_EndAddrCoarseOfs, - Gen_StartLoopAddrCoarseOfs, Gen_Keynum, Gen_Velocity, - Gen_EndLoopAddrCoarseOfs, Gen_SampleModes, Gen_ExclusiveClass, - Gen_OverrideRootKey, 0 -}; - -/* close SoundFont file and delete a SoundFont structure */ -void -sfont_close (SFData * sf) -{ - fluid_list_t *p, *p2; - - if (sf->sffd) - fclose (sf->sffd); - - if (sf->fname) - free (sf->fname); - - p = sf->info; - while (p) - { - free (p->data); - p = fluid_list_next (p); - } - delete_fluid_list(sf->info); - sf->info = NULL; - - p = sf->preset; - while (p) - { /* loop over presets */ - p2 = ((SFPreset *) (p->data))->zone; - while (p2) - { /* loop over preset's zones */ - sfont_free_zone (p2->data); - p2 = fluid_list_next (p2); - } /* free preset's zone list */ - delete_fluid_list (((SFPreset *) (p->data))->zone); - FLUID_FREE (p->data); /* free preset chunk */ - p = fluid_list_next (p); - } - delete_fluid_list (sf->preset); - sf->preset = NULL; - - p = sf->inst; - while (p) - { /* loop over instruments */ - p2 = ((SFInst *) (p->data))->zone; - while (p2) - { /* loop over inst's zones */ - sfont_free_zone (p2->data); - p2 = fluid_list_next (p2); - } /* free inst's zone list */ - delete_fluid_list (((SFInst *) (p->data))->zone); - FLUID_FREE (p->data); - p = fluid_list_next (p); - } - delete_fluid_list (sf->inst); - sf->inst = NULL; - - p = sf->sample; - while (p) - { - FLUID_FREE (p->data); - p = fluid_list_next (p); - } - delete_fluid_list (sf->sample); - sf->sample = NULL; - - FLUID_FREE (sf); -} - -/* free all elements of a zone (Preset or Instrument) */ -void -sfont_free_zone (SFZone * zone) -{ - fluid_list_t *p; - - if (!zone) - return; - - p = zone->gen; - while (p) - { /* Free gen chunks for this zone */ - if (p->data) - FLUID_FREE (p->data); - p = fluid_list_next (p); - } - delete_fluid_list (zone->gen); /* free genlist */ - - p = zone->mod; - while (p) - { /* Free mod chunks for this zone */ - if (p->data) - FLUID_FREE (p->data); - p = fluid_list_next (p); - } - delete_fluid_list (zone->mod); /* free modlist */ - - FLUID_FREE (zone); /* free zone chunk */ -} - -/* preset sort function, first by bank, then by preset # */ -int -sfont_preset_compare_func (void* a, void* b) -{ - int aval, bval; - - aval = (int) (((SFPreset *) a)->bank) << 16 | ((SFPreset *) a)->prenum; - bval = (int) (((SFPreset *) b)->bank) << 16 | ((SFPreset *) b)->prenum; - - return (aval - bval); -} - -/* delete zone from zone list */ -void -sfont_zone_delete (SFData * sf, fluid_list_t ** zlist, SFZone * zone) -{ - *zlist = fluid_list_remove (*zlist, (void*) zone); - sfont_free_zone (zone); -} - -/* Find generator in gen list */ -fluid_list_t * -gen_inlist (int gen, fluid_list_t * genlist) -{ /* is generator in gen list? */ - fluid_list_t *p; - - p = genlist; - while (p) - { - if (p->data == NULL) - return (NULL); - if (gen == ((SFGen *) p->data)->id) - break; - p = fluid_list_next (p); - } - return (p); -} - -/* check validity of instrument generator */ -int -gen_valid (int gen) -{ /* is generator id valid? */ - int i = 0; - - if (gen > Gen_MaxValid) - return (FALSE); - while (badgen[i] && badgen[i] != gen) - i++; - return (badgen[i] == 0); -} - -/* check validity of preset generator */ -int -gen_validp (int gen) -{ /* is preset generator valid? */ - int i = 0; - - if (!gen_valid (gen)) - return (FALSE); - while (badpgen[i] && badpgen[i] != (unsigned short) gen) - i++; - return (badpgen[i] == 0); -} - -/*================================util.c===========================*/ - -/* Logging function, returns FAIL to use as a return value in calling funcs */ -int -gerr (int ev, char * fmt, ...) -{ - va_list args; - - va_start (args, fmt); - vprintf(fmt, args); - va_end (args); - - printf("\n"); - - return (FAIL); -} - -int -safe_fread (void *buf, int count, FILE * fd) -{ - if (fread (buf, count, 1, fd) != 1) - { /* size_t = count, nmemb = 1 */ - if (feof (fd)) - gerr (ErrEof, _("EOF while attemping to read %d bytes"), count); - else - FLUID_LOG (FLUID_ERR, _("File read failed")); - return (FAIL); - } - return (OK); -} - -int -safe_fseek (FILE * fd, long ofs, int whence) -{ - if (fseek (fd, ofs, whence) == -1) { - FLUID_LOG (FLUID_ERR, _("File seek failed with offset = %ld and whence = %d"), ofs, whence); - return (FAIL); - } - return (OK); -} diff --git a/src/libs/fluidsynth/src/fluid_defsfont.h b/src/libs/fluidsynth/src/fluid_defsfont.h deleted file mode 100644 index 1fe463f23c..0000000000 --- a/src/libs/fluidsynth/src/fluid_defsfont.h +++ /dev/null @@ -1,606 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * SoundFont loading code borrowed from Smurf SoundFont Editor by Josh Green - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - - -#ifndef _FLUID_DEFSFONT_H -#define _FLUID_DEFSFONT_H - - -#include "fluidsynth.h" -#include "fluidsynth_priv.h" -#include "fluid_list.h" - - - -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ - -/*-----------------------------------sfont.h----------------------------*/ - -#define SF_SAMPMODES_LOOP 1 -#define SF_SAMPMODES_UNROLL 2 - -#define SF_MIN_SAMPLERATE 400 -#define SF_MAX_SAMPLERATE 50000 - -#define SF_MIN_SAMPLE_LENGTH 32 - -/* Sound Font structure defines */ - -typedef struct _SFVersion -{ /* version structure */ - unsigned short major; - unsigned short minor; -} -SFVersion; - -typedef struct _SFMod -{ /* Modulator structure */ - unsigned short src; /* source modulator */ - unsigned short dest; /* destination generator */ - signed short amount; /* signed, degree of modulation */ - unsigned short amtsrc; /* second source controls amnt of first */ - unsigned short trans; /* transform applied to source */ -} -SFMod; - -typedef union _SFGenAmount -{ /* Generator amount structure */ - signed short sword; /* signed 16 bit value */ - unsigned short uword; /* unsigned 16 bit value */ - struct - { - unsigned char lo; /* low value for ranges */ - unsigned char hi; /* high value for ranges */ - } - range; -} -SFGenAmount; - -typedef struct _SFGen -{ /* Generator structure */ - unsigned short id; /* generator ID */ - SFGenAmount amount; /* generator value */ -} -SFGen; - -typedef struct _SFZone -{ /* Sample/instrument zone structure */ - fluid_list_t *instsamp; /* instrument/sample pointer for zone */ - fluid_list_t *gen; /* list of generators */ - fluid_list_t *mod; /* list of modulators */ -} -SFZone; - -typedef struct _SFSample -{ /* Sample structure */ - char name[21]; /* Name of sample */ - unsigned char samfile; /* Loaded sfont/sample buffer = 0/1 */ - unsigned int start; /* Offset in sample area to start of sample */ - unsigned int end; /* Offset from start to end of sample, - this is the last point of the - sample, the SF spec has this as the - 1st point after, corrected on - load/save */ - unsigned int loopstart; /* Offset from start to start of loop */ - unsigned int loopend; /* Offset from start to end of loop, - marks the first point after loop, - whose sample value is ideally - equivalent to loopstart */ - unsigned int samplerate; /* Sample rate recorded at */ - unsigned char origpitch; /* root midi key number */ - signed char pitchadj; /* pitch correction in cents */ - unsigned short sampletype; /* 1 mono,2 right,4 left,linked 8,0x8000=ROM */ -} -SFSample; - -typedef struct _SFInst -{ /* Instrument structure */ - char name[21]; /* Name of instrument */ - fluid_list_t *zone; /* list of instrument zones */ -} -SFInst; - -typedef struct _SFPreset -{ /* Preset structure */ - char name[21]; /* preset name */ - unsigned short prenum; /* preset number */ - unsigned short bank; /* bank number */ - unsigned int libr; /* Not used (preserved) */ - unsigned int genre; /* Not used (preserved) */ - unsigned int morph; /* Not used (preserved) */ - fluid_list_t *zone; /* list of preset zones */ -} -SFPreset; - -/* NOTE: sffd is also used to determine if sound font is new (NULL) */ -typedef struct _SFData -{ /* Sound font data structure */ - SFVersion version; /* sound font version */ - SFVersion romver; /* ROM version */ - unsigned int samplepos; /* position within sffd of the sample chunk */ - unsigned int samplesize; /* length within sffd of the sample chunk */ - char *fname; /* file name */ - FILE *sffd; /* loaded sfont file descriptor */ - fluid_list_t *info; /* linked list of info strings (1st byte is ID) */ - fluid_list_t *preset; /* linked list of preset info */ - fluid_list_t *inst; /* linked list of instrument info */ - fluid_list_t *sample; /* linked list of sample info */ -} -SFData; - -/* sf file chunk IDs */ -enum -{ UNKN_ID, RIFF_ID, LIST_ID, SFBK_ID, - INFO_ID, SDTA_ID, PDTA_ID, /* info/sample/preset */ - - IFIL_ID, ISNG_ID, INAM_ID, IROM_ID, /* info ids (1st byte of info strings) */ - IVER_ID, ICRD_ID, IENG_ID, IPRD_ID, /* more info ids */ - ICOP_ID, ICMT_ID, ISFT_ID, /* and yet more info ids */ - - SNAM_ID, SMPL_ID, /* sample ids */ - PHDR_ID, PBAG_ID, PMOD_ID, PGEN_ID, /* preset ids */ - IHDR_ID, IBAG_ID, IMOD_ID, IGEN_ID, /* instrument ids */ - SHDR_ID /* sample info */ -}; - -/* generator types */ -typedef enum -{ Gen_StartAddrOfs, Gen_EndAddrOfs, Gen_StartLoopAddrOfs, - Gen_EndLoopAddrOfs, Gen_StartAddrCoarseOfs, Gen_ModLFO2Pitch, - Gen_VibLFO2Pitch, Gen_ModEnv2Pitch, Gen_FilterFc, Gen_FilterQ, - Gen_ModLFO2FilterFc, Gen_ModEnv2FilterFc, Gen_EndAddrCoarseOfs, - Gen_ModLFO2Vol, Gen_Unused1, Gen_ChorusSend, Gen_ReverbSend, Gen_Pan, - Gen_Unused2, Gen_Unused3, Gen_Unused4, - Gen_ModLFODelay, Gen_ModLFOFreq, Gen_VibLFODelay, Gen_VibLFOFreq, - Gen_ModEnvDelay, Gen_ModEnvAttack, Gen_ModEnvHold, Gen_ModEnvDecay, - Gen_ModEnvSustain, Gen_ModEnvRelease, Gen_Key2ModEnvHold, - Gen_Key2ModEnvDecay, Gen_VolEnvDelay, Gen_VolEnvAttack, - Gen_VolEnvHold, Gen_VolEnvDecay, Gen_VolEnvSustain, Gen_VolEnvRelease, - Gen_Key2VolEnvHold, Gen_Key2VolEnvDecay, Gen_Instrument, - Gen_Reserved1, Gen_KeyRange, Gen_VelRange, - Gen_StartLoopAddrCoarseOfs, Gen_Keynum, Gen_Velocity, - Gen_Attenuation, Gen_Reserved2, Gen_EndLoopAddrCoarseOfs, - Gen_CoarseTune, Gen_FineTune, Gen_SampleId, Gen_SampleModes, - Gen_Reserved3, Gen_ScaleTune, Gen_ExclusiveClass, Gen_OverrideRootKey, - Gen_Dummy -} -Gen_Type; - -#define Gen_MaxValid Gen_Dummy - 1 /* maximum valid generator */ -#define Gen_Count Gen_Dummy /* count of generators */ -#define GenArrSize sizeof(SFGenAmount)*Gen_Count /* gen array size */ - -/* generator unit type */ -typedef enum -{ - None, /* No unit type */ - Unit_Smpls, /* in samples */ - Unit_32kSmpls, /* in 32k samples */ - Unit_Cent, /* in cents (1/100th of a semitone) */ - Unit_HzCent, /* in Hz Cents */ - Unit_TCent, /* in Time Cents */ - Unit_cB, /* in centibels (1/100th of a decibel) */ - Unit_Percent, /* in percentage */ - Unit_Semitone, /* in semitones */ - Unit_Range /* a range of values */ -} -Gen_Unit; - -/* global data */ - -extern unsigned short badgen[]; /* list of bad generators */ -extern unsigned short badpgen[]; /* list of bad preset generators */ - -/* functions */ -void sfont_init_chunks (void); - -void sfont_close (SFData * sf); -void sfont_free_zone (SFZone * zone); -int sfont_preset_compare_func (void* a, void* b); - -void sfont_zone_delete (SFData * sf, fluid_list_t ** zlist, SFZone * zone); - -fluid_list_t *gen_inlist (int gen, fluid_list_t * genlist); -int gen_valid (int gen); -int gen_validp (int gen); - - -/*-----------------------------------sffile.h----------------------------*/ -/* - File structures and routines (used to be in sffile.h) -*/ - -#define CHNKIDSTR(id) &idlist[(id - 1) * 4] - -/* sfont file chunk sizes */ -#define SFPHDRSIZE 38 -#define SFBAGSIZE 4 -#define SFMODSIZE 10 -#define SFGENSIZE 4 -#define SFIHDRSIZE 22 -#define SFSHDRSIZE 46 - -/* sfont file data structures */ -typedef struct _SFChunk -{ /* RIFF file chunk structure */ - unsigned int id; /* chunk id */ - unsigned int size; /* size of the following chunk */ -} -SFChunk; - -typedef struct _SFPhdr -{ - unsigned char name[20]; /* preset name */ - unsigned short preset; /* preset number */ - unsigned short bank; /* bank number */ - unsigned short pbagndx; /* index into preset bag */ - unsigned int library; /* just for preserving them */ - unsigned int genre; /* Not used */ - unsigned int morphology; /* Not used */ -} -SFPhdr; - -typedef struct _SFBag -{ - unsigned short genndx; /* index into generator list */ - unsigned short modndx; /* index into modulator list */ -} -SFBag; - -typedef struct _SFIhdr -{ - char name[20]; /* Name of instrument */ - unsigned short ibagndx; /* Instrument bag index */ -} -SFIhdr; - -typedef struct _SFShdr -{ /* Sample header loading struct */ - char name[20]; /* Sample name */ - unsigned int start; /* Offset to start of sample */ - unsigned int end; /* Offset to end of sample */ - unsigned int loopstart; /* Offset to start of loop */ - unsigned int loopend; /* Offset to end of loop */ - unsigned int samplerate; /* Sample rate recorded at */ - unsigned char origpitch; /* root midi key number */ - signed char pitchadj; /* pitch correction in cents */ - unsigned short samplelink; /* Not used */ - unsigned short sampletype; /* 1 mono,2 right,4 left,linked 8,0x8000=ROM */ -} -SFShdr; - -/* data */ -extern char idlist[]; - -/* functions */ -SFData *sfload_file (const char * fname); - - - -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ - -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - - -/* Provide definitions for some commonly used macros. - * Some of them are only provided if they haven't already - * been defined. It is assumed that if they are already - * defined then the current definition is correct. - */ -#ifndef FALSE -#define FALSE (0) -#endif - -#ifndef TRUE -#define TRUE (!FALSE) -#endif - -#define GPOINTER_TO_INT(p) ((int) (p)) -#define GINT_TO_POINTER(i) ((void *) (i)) - -char* g_strdup (const char *str); - - - - - -/* Provide simple macro statement wrappers (adapted from Perl): - * G_STMT_START { statements; } G_STMT_END; - * can be used as a single statement, as in - * if (x) G_STMT_START { ... } G_STMT_END; else ... - * - * For gcc we will wrap the statements within `({' and `})' braces. - * For SunOS they will be wrapped within `if (1)' and `else (void) 0', - * and otherwise within `do' and `while (0)'. - */ -#if !(defined (G_STMT_START) && defined (G_STMT_END)) -# if defined (__GNUC__) && !defined (__STRICT_ANSI__) && !defined (__cplusplus) -# define G_STMT_START (void)( -# define G_STMT_END ) -# else -# if (defined (sun) || defined (__sun__)) -# define G_STMT_START if (1) -# define G_STMT_END else (void)0 -# else -# define G_STMT_START do -# define G_STMT_END while (0) -# endif -# endif -#endif - - -/* Basic bit swapping functions - */ -#define GUINT16_SWAP_LE_BE_CONSTANT(val) ((unsigned short) ( \ - (((unsigned short) (val) & (unsigned short) 0x00ffU) << 8) | \ - (((unsigned short) (val) & (unsigned short) 0xff00U) >> 8))) -#define GUINT32_SWAP_LE_BE_CONSTANT(val) ((unsigned int) ( \ - (((unsigned int) (val) & (unsigned int) 0x000000ffU) << 24) | \ - (((unsigned int) (val) & (unsigned int) 0x0000ff00U) << 8) | \ - (((unsigned int) (val) & (unsigned int) 0x00ff0000U) >> 8) | \ - (((unsigned int) (val) & (unsigned int) 0xff000000U) >> 24))) - -#define GUINT16_SWAP_LE_BE(val) (GUINT16_SWAP_LE_BE_CONSTANT (val)) -#define GUINT32_SWAP_LE_BE(val) (GUINT32_SWAP_LE_BE_CONSTANT (val)) - -#define GINT16_TO_LE(val) ((signed short) (val)) -#define GUINT16_TO_LE(val) ((unsigned short) (val)) -#define GINT16_TO_BE(val) ((signed short) GUINT16_SWAP_LE_BE (val)) -#define GUINT16_TO_BE(val) (GUINT16_SWAP_LE_BE (val)) -#define GINT32_TO_LE(val) ((signed int) (val)) -#define GUINT32_TO_LE(val) ((unsigned int) (val)) -#define GINT32_TO_BE(val) ((signed int) GUINT32_SWAP_LE_BE (val)) -#define GUINT32_TO_BE(val) (GUINT32_SWAP_LE_BE (val)) - -/* The G*_TO_?E() macros are defined in glibconfig.h. - * The transformation is symmetric, so the FROM just maps to the TO. - */ -#define GINT16_FROM_LE(val) (GINT16_TO_LE (val)) -#define GUINT16_FROM_LE(val) (GUINT16_TO_LE (val)) -#define GINT16_FROM_BE(val) (GINT16_TO_BE (val)) -#define GUINT16_FROM_BE(val) (GUINT16_TO_BE (val)) -#define GINT32_FROM_LE(val) (GINT32_TO_LE (val)) -#define GUINT32_FROM_LE(val) (GUINT32_TO_LE (val)) -#define GINT32_FROM_BE(val) (GINT32_TO_BE (val)) -#define GUINT32_FROM_BE(val) (GUINT32_TO_BE (val)) - - -/*-----------------------------------util.h----------------------------*/ -/* - Utility functions (formerly in util.h) - */ -#define FAIL 0 -#define OK 1 - -enum -{ ErrWarn, ErrFatal, ErrStatus, ErrCorr, ErrEof, ErrMem, Errno, - ErrRead, ErrWrite -}; - -#define ErrMax ErrWrite -#define ErrnoStart Errno -#define ErrnoEnd ErrWrite - -int gerr (int ev, char * fmt, ...); -int safe_fread (void *buf, int count, FILE * fd); -int safe_fwrite (void *buf, int count, FILE * fd); -int safe_fseek (FILE * fd, long ofs, int whence); - - -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ - - - -/*************************************************************** - * - * FORWARD DECLARATIONS - */ -typedef struct _fluid_defsfont_t fluid_defsfont_t; -typedef struct _fluid_defpreset_t fluid_defpreset_t; -typedef struct _fluid_preset_zone_t fluid_preset_zone_t; -typedef struct _fluid_inst_t fluid_inst_t; -typedef struct _fluid_inst_zone_t fluid_inst_zone_t; - -/* - - Public interface - - */ - -fluid_sfloader_t* new_fluid_defsfloader(void); -int delete_fluid_defsfloader(fluid_sfloader_t* loader); -fluid_sfont_t* fluid_defsfloader_load(fluid_sfloader_t* loader, const char* filename); - - -int fluid_defsfont_sfont_delete(fluid_sfont_t* sfont); -char* fluid_defsfont_sfont_get_name(fluid_sfont_t* sfont); -fluid_preset_t* fluid_defsfont_sfont_get_preset(fluid_sfont_t* sfont, unsigned int bank, unsigned int prenum); -void fluid_defsfont_sfont_iteration_start(fluid_sfont_t* sfont); -int fluid_defsfont_sfont_iteration_next(fluid_sfont_t* sfont, fluid_preset_t* preset); - - -int fluid_defpreset_preset_delete(fluid_preset_t* preset); -char* fluid_defpreset_preset_get_name(fluid_preset_t* preset); -int fluid_defpreset_preset_get_banknum(fluid_preset_t* preset); -int fluid_defpreset_preset_get_num(fluid_preset_t* preset); -int fluid_defpreset_preset_noteon(fluid_preset_t* preset, fluid_synth_t* synth, int chan, int key, int vel); - - -/* - * fluid_defsfont_t - */ -struct _fluid_defsfont_t -{ - char* filename; /* the filename of this soundfont */ - unsigned int samplepos; /* the position in the file at which the sample data starts */ - unsigned int samplesize; /* the size of the sample data */ - short* sampledata; /* the sample data, loaded in ram */ - fluid_list_t* sample; /* the samples in this soundfont */ - fluid_defpreset_t* preset; /* the presets of this soundfont */ - - fluid_preset_t iter_preset; /* preset interface used in the iteration */ - fluid_defpreset_t* iter_cur; /* the current preset in the iteration */ -}; - - -fluid_defsfont_t* new_fluid_defsfont(void); -int delete_fluid_defsfont(fluid_defsfont_t* sfont); -int fluid_defsfont_load(fluid_defsfont_t* sfont, const char* file); -char* fluid_defsfont_get_name(fluid_defsfont_t* sfont); -fluid_defpreset_t* fluid_defsfont_get_preset(fluid_defsfont_t* sfont, unsigned int bank, unsigned int prenum); -void fluid_defsfont_iteration_start(fluid_defsfont_t* sfont); -int fluid_defsfont_iteration_next(fluid_defsfont_t* sfont, fluid_preset_t* preset); -int fluid_defsfont_load_sampledata(fluid_defsfont_t* sfont); -int fluid_defsfont_add_sample(fluid_defsfont_t* sfont, fluid_sample_t* sample); -int fluid_defsfont_add_preset(fluid_defsfont_t* sfont, fluid_defpreset_t* preset); -fluid_sample_t* fluid_defsfont_get_sample(fluid_defsfont_t* sfont, char *s); - - -/* - * fluid_preset_t - */ -struct _fluid_defpreset_t -{ - fluid_defpreset_t* next; - fluid_defsfont_t* sfont; /* the soundfont this preset belongs to */ - char name[21]; /* the name of the preset */ - unsigned int bank; /* the bank number */ - unsigned int num; /* the preset number */ - fluid_preset_zone_t* global_zone; /* the global zone of the preset */ - fluid_preset_zone_t* zone; /* the chained list of preset zones */ -}; - -fluid_defpreset_t* new_fluid_defpreset(fluid_defsfont_t* sfont); -int delete_fluid_defpreset(fluid_defpreset_t* preset); -fluid_defpreset_t* fluid_defpreset_next(fluid_defpreset_t* preset); -int fluid_defpreset_import_sfont(fluid_defpreset_t* preset, SFPreset* sfpreset, fluid_defsfont_t* sfont); -int fluid_defpreset_set_global_zone(fluid_defpreset_t* preset, fluid_preset_zone_t* zone); -int fluid_defpreset_add_zone(fluid_defpreset_t* preset, fluid_preset_zone_t* zone); -fluid_preset_zone_t* fluid_defpreset_get_zone(fluid_defpreset_t* preset); -fluid_preset_zone_t* fluid_defpreset_get_global_zone(fluid_defpreset_t* preset); -int fluid_defpreset_get_banknum(fluid_defpreset_t* preset); -int fluid_defpreset_get_num(fluid_defpreset_t* preset); -char* fluid_defpreset_get_name(fluid_defpreset_t* preset); -int fluid_defpreset_noteon(fluid_defpreset_t* preset, fluid_synth_t* synth, int chan, int key, int vel); - -/* - * fluid_preset_zone - */ -struct _fluid_preset_zone_t -{ - fluid_preset_zone_t* next; - char* name; - fluid_inst_t* inst; - int keylo; - int keyhi; - int vello; - int velhi; - fluid_gen_t gen[GEN_LAST]; - fluid_mod_t * mod; /* List of modulators */ -}; - -fluid_preset_zone_t* new_fluid_preset_zone(char* name); -int delete_fluid_preset_zone(fluid_preset_zone_t* zone); -fluid_preset_zone_t* fluid_preset_zone_next(fluid_preset_zone_t* preset); -int fluid_preset_zone_import_sfont(fluid_preset_zone_t* zone, SFZone* sfzone, fluid_defsfont_t* sfont); -int fluid_preset_zone_inside_range(fluid_preset_zone_t* zone, int key, int vel); -fluid_inst_t* fluid_preset_zone_get_inst(fluid_preset_zone_t* zone); - -/* - * fluid_inst_t - */ -struct _fluid_inst_t -{ - char name[21]; - fluid_inst_zone_t* global_zone; - fluid_inst_zone_t* zone; -}; - -fluid_inst_t* new_fluid_inst(void); -int delete_fluid_inst(fluid_inst_t* inst); -int fluid_inst_import_sfont(fluid_inst_t* inst, SFInst *sfinst, fluid_defsfont_t* sfont); -int fluid_inst_set_global_zone(fluid_inst_t* inst, fluid_inst_zone_t* zone); -int fluid_inst_add_zone(fluid_inst_t* inst, fluid_inst_zone_t* zone); -fluid_inst_zone_t* fluid_inst_get_zone(fluid_inst_t* inst); -fluid_inst_zone_t* fluid_inst_get_global_zone(fluid_inst_t* inst); - -/* - * fluid_inst_zone_t - */ -struct _fluid_inst_zone_t -{ - fluid_inst_zone_t* next; - char* name; - fluid_sample_t* sample; - int keylo; - int keyhi; - int vello; - int velhi; - fluid_gen_t gen[GEN_LAST]; - fluid_mod_t * mod; /* List of modulators */ -}; - -fluid_inst_zone_t* new_fluid_inst_zone(char* name); -int delete_fluid_inst_zone(fluid_inst_zone_t* zone); -fluid_inst_zone_t* fluid_inst_zone_next(fluid_inst_zone_t* zone); -int fluid_inst_zone_import_sfont(fluid_inst_zone_t* zone, SFZone *sfzone, fluid_defsfont_t* sfont); -int fluid_inst_zone_inside_range(fluid_inst_zone_t* zone, int key, int vel); -fluid_sample_t* fluid_inst_zone_get_sample(fluid_inst_zone_t* zone); - - - -fluid_sample_t* new_fluid_sample(void); -int delete_fluid_sample(fluid_sample_t* sample); -int fluid_sample_import_sfont(fluid_sample_t* sample, SFSample* sfsample, fluid_defsfont_t* sfont); -int fluid_sample_in_rom(fluid_sample_t* sample); - - -#endif /* _FLUID_SFONT_H */ diff --git a/src/libs/fluidsynth/src/fluid_dsp_float.c b/src/libs/fluidsynth/src/fluid_dsp_float.c deleted file mode 100644 index cf64e2bfff..0000000000 --- a/src/libs/fluidsynth/src/fluid_dsp_float.c +++ /dev/null @@ -1,687 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#include "fluidsynth_priv.h" -#include "fluid_phase.h" - -/* Purpose: - * - * Interpolates audio data (obtains values between the samples of the original - * waveform data). - * - * Variables loaded from the voice structure (assigned in fluid_voice_write()): - * - dsp_data: Pointer to the original waveform data - * - dsp_phase: The position in the original waveform data. - * This has an integer and a fractional part (between samples). - * - dsp_phase_incr: For each output sample, the position in the original - * waveform advances by dsp_phase_incr. This also has an integer - * part and a fractional part. - * If a sample is played at root pitch (no pitch change), - * dsp_phase_incr is integer=1 and fractional=0. - * - dsp_amp: The current amplitude envelope value. - * - dsp_amp_incr: The changing rate of the amplitude envelope. - * - * A couple of variables are used internally, their results are discarded: - * - dsp_i: Index through the output buffer - * - dsp_buf: Output buffer of floating point values (FLUID_BUFSIZE in length) - */ - -#include "fluidsynth_priv.h" -#include "fluid_synth.h" -#include "fluid_voice.h" - - -/* Interpolation (find a value between two samples of the original waveform) */ - -/* Linear interpolation table (2 coefficients centered on 1st) */ -static fluid_real_t interp_coeff_linear[FLUID_INTERP_MAX][2]; - -/* 4th order (cubic) interpolation table (4 coefficients centered on 2nd) */ -static fluid_real_t interp_coeff[FLUID_INTERP_MAX][4]; - -/* 7th order interpolation (7 coefficients centered on 3rd) */ -static fluid_real_t sinc_table7[FLUID_INTERP_MAX][7]; - - -#define SINC_INTERP_ORDER 7 /* 7th order constant */ - - -/* Initializes interpolation tables */ -void fluid_dsp_float_config (void) -{ - int i, i2; - double x, v; - double i_shifted; - - /* Initialize the coefficients for the interpolation. The math comes - * from a mail, posted by Olli Niemitalo to the music-dsp mailing - * list (I found it in the music-dsp archives - * http://www.smartelectronix.com/musicdsp/). */ - - for (i = 0; i < FLUID_INTERP_MAX; i++) - { - x = (double) i / (double) FLUID_INTERP_MAX; - - interp_coeff[i][0] = (fluid_real_t)(x * (-0.5 + x * (1 - 0.5 * x))); - interp_coeff[i][1] = (fluid_real_t)(1.0 + x * x * (1.5 * x - 2.5)); - interp_coeff[i][2] = (fluid_real_t)(x * (0.5 + x * (2.0 - 1.5 * x))); - interp_coeff[i][3] = (fluid_real_t)(0.5 * x * x * (x - 1.0)); - - interp_coeff_linear[i][0] = (fluid_real_t)(1.0 - x); - interp_coeff_linear[i][1] = (fluid_real_t)x; - } - - /* i: Offset in terms of whole samples */ - for (i = 0; i < SINC_INTERP_ORDER; i++) - { /* i2: Offset in terms of fractional samples ('subsamples') */ - for (i2 = 0; i2 < FLUID_INTERP_MAX; i2++) - { - /* center on middle of table */ - i_shifted = (double)i - ((double)SINC_INTERP_ORDER / 2.0) - + (double)i2 / (double)FLUID_INTERP_MAX; - - /* sinc(0) cannot be calculated straightforward (limit needed for 0/0) */ - if (fabs (i_shifted) > 0.000001) - { - v = (fluid_real_t)sin (i_shifted * M_PI) / (M_PI * i_shifted); - /* Hamming window */ - v *= (fluid_real_t)0.5 * (1.0 + cos (2.0 * M_PI * i_shifted / (fluid_real_t)SINC_INTERP_ORDER)); - } - else v = 1.0; - - sinc_table7[FLUID_INTERP_MAX - i2 - 1][i] = v; - } - } - -#if 0 - for (i = 0; i < FLUID_INTERP_MAX; i++) - { - printf ("%d %0.3f %0.3f %0.3f %0.3f %0.3f %0.3f %0.3f\n", - i, sinc_table7[0][i], sinc_table7[1][i], sinc_table7[2][i], - sinc_table7[3][i], sinc_table7[4][i], sinc_table7[5][i], sinc_table7[6][i]); - } -#endif - - fluid_check_fpe("interpolation table calculation"); -} - - -/* No interpolation. Just take the sample, which is closest to - * the playback pointer. Questionable quality, but very - * efficient. */ -int -fluid_dsp_float_interpolate_none (fluid_voice_t *voice) -{ - fluid_phase_t dsp_phase = voice->phase; - fluid_phase_t dsp_phase_incr, end_phase; - short int *dsp_data = voice->sample->data; - fluid_real_t *dsp_buf = voice->dsp_buf; - fluid_real_t dsp_amp = voice->amp; - fluid_real_t dsp_amp_incr = voice->amp_incr; - unsigned int dsp_i = 0; - unsigned int dsp_phase_index; - unsigned int end_index; - int looping; - - /* Convert playback "speed" floating point value to phase index/fract */ - fluid_phase_set_float (dsp_phase_incr, voice->phase_incr); - - /* voice is currently looping? */ - looping = _SAMPLEMODE (voice) == FLUID_LOOP_DURING_RELEASE - || (_SAMPLEMODE (voice) == FLUID_LOOP_UNTIL_RELEASE - && voice->volenv_section < FLUID_VOICE_ENVRELEASE); - - end_index = looping ? voice->loopend - 1 : voice->end; - - while (1) - { - dsp_phase_index = fluid_phase_index_round (dsp_phase); /* round to nearest point */ - - /* interpolate sequence of sample points */ - for ( ; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++) - { - dsp_buf[dsp_i] = dsp_amp * dsp_data[dsp_phase_index]; - - /* increment phase and amplitude */ - fluid_phase_incr (dsp_phase, dsp_phase_incr); - dsp_phase_index = fluid_phase_index_round (dsp_phase); /* round to nearest point */ - dsp_amp += dsp_amp_incr; - } - - /* break out if not looping (buffer may not be full) */ - if (!looping) break; - - /* go back to loop start */ - if (dsp_phase_index > end_index) - { - fluid_phase_sub_int (dsp_phase, voice->loopend - voice->loopstart); - voice->has_looped = 1; - } - - /* break out if filled buffer */ - if (dsp_i >= FLUID_BUFSIZE) break; - } - - voice->phase = dsp_phase; - voice->amp = dsp_amp; - - return (dsp_i); -} - -/* Straight line interpolation. - * Returns number of samples processed (usually FLUID_BUFSIZE but could be - * smaller if end of sample occurs). - */ -int -fluid_dsp_float_interpolate_linear (fluid_voice_t *voice) -{ - fluid_phase_t dsp_phase = voice->phase; - fluid_phase_t dsp_phase_incr, end_phase; - short int *dsp_data = voice->sample->data; - fluid_real_t *dsp_buf = voice->dsp_buf; - fluid_real_t dsp_amp = voice->amp; - fluid_real_t dsp_amp_incr = voice->amp_incr; - unsigned int dsp_i = 0; - unsigned int dsp_phase_index; - unsigned int end_index; - short int point; - fluid_real_t *coeffs; - int looping; - - /* Convert playback "speed" floating point value to phase index/fract */ - fluid_phase_set_float (dsp_phase_incr, voice->phase_incr); - - /* voice is currently looping? */ - looping = _SAMPLEMODE (voice) == FLUID_LOOP_DURING_RELEASE - || (_SAMPLEMODE (voice) == FLUID_LOOP_UNTIL_RELEASE - && voice->volenv_section < FLUID_VOICE_ENVRELEASE); - - /* last index before 2nd interpolation point must be specially handled */ - end_index = (looping ? voice->loopend - 1 : voice->end) - 1; - - /* 2nd interpolation point to use at end of loop or sample */ - if (looping) point = dsp_data[voice->loopstart]; /* loop start */ - else point = dsp_data[voice->end]; /* duplicate end for samples no longer looping */ - - while (1) - { - dsp_phase_index = fluid_phase_index (dsp_phase); - - /* interpolate the sequence of sample points */ - for ( ; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++) - { - coeffs = interp_coeff_linear[fluid_phase_fract_to_tablerow (dsp_phase)]; - dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * dsp_data[dsp_phase_index] - + coeffs[1] * dsp_data[dsp_phase_index+1]); - - /* increment phase and amplitude */ - fluid_phase_incr (dsp_phase, dsp_phase_incr); - dsp_phase_index = fluid_phase_index (dsp_phase); - dsp_amp += dsp_amp_incr; - } - - /* break out if buffer filled */ - if (dsp_i >= FLUID_BUFSIZE) break; - - end_index++; /* we're now interpolating the last point */ - - /* interpolate within last point */ - for (; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++) - { - coeffs = interp_coeff_linear[fluid_phase_fract_to_tablerow (dsp_phase)]; - dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * dsp_data[dsp_phase_index] - + coeffs[1] * point); - - /* increment phase and amplitude */ - fluid_phase_incr (dsp_phase, dsp_phase_incr); - dsp_phase_index = fluid_phase_index (dsp_phase); - dsp_amp += dsp_amp_incr; /* increment amplitude */ - } - - if (!looping) break; /* break out if not looping (end of sample) */ - - /* go back to loop start (if past */ - if (dsp_phase_index > end_index) - { - fluid_phase_sub_int (dsp_phase, voice->loopend - voice->loopstart); - voice->has_looped = 1; - } - - /* break out if filled buffer */ - if (dsp_i >= FLUID_BUFSIZE) break; - - end_index--; /* set end back to second to last sample point */ - } - - voice->phase = dsp_phase; - voice->amp = dsp_amp; - - return (dsp_i); -} - -/* 4th order (cubic) interpolation. - * Returns number of samples processed (usually FLUID_BUFSIZE but could be - * smaller if end of sample occurs). - */ -int -fluid_dsp_float_interpolate_4th_order (fluid_voice_t *voice) -{ - fluid_phase_t dsp_phase = voice->phase; - fluid_phase_t dsp_phase_incr, end_phase; - short int *dsp_data = voice->sample->data; - fluid_real_t *dsp_buf = voice->dsp_buf; - fluid_real_t dsp_amp = voice->amp; - fluid_real_t dsp_amp_incr = voice->amp_incr; - unsigned int dsp_i = 0; - unsigned int dsp_phase_index; - unsigned int start_index, end_index; - short int start_point, end_point1, end_point2; - fluid_real_t *coeffs; - int looping; - - /* Convert playback "speed" floating point value to phase index/fract */ - fluid_phase_set_float (dsp_phase_incr, voice->phase_incr); - - /* voice is currently looping? */ - looping = _SAMPLEMODE (voice) == FLUID_LOOP_DURING_RELEASE - || (_SAMPLEMODE (voice) == FLUID_LOOP_UNTIL_RELEASE - && voice->volenv_section < FLUID_VOICE_ENVRELEASE); - - /* last index before 4th interpolation point must be specially handled */ - end_index = (looping ? voice->loopend - 1 : voice->end) - 2; - - if (voice->has_looped) /* set start_index and start point if looped or not */ - { - start_index = voice->loopstart; - start_point = dsp_data[voice->loopend - 1]; /* last point in loop (wrap around) */ - } - else - { - start_index = voice->start; - start_point = dsp_data[voice->start]; /* just duplicate the point */ - } - - /* get points off the end (loop start if looping, duplicate point if end) */ - if (looping) - { - end_point1 = dsp_data[voice->loopstart]; - end_point2 = dsp_data[voice->loopstart + 1]; - } - else - { - end_point1 = dsp_data[voice->end]; - end_point2 = end_point1; - } - - while (1) - { - dsp_phase_index = fluid_phase_index (dsp_phase); - - /* interpolate first sample point (start or loop start) if needed */ - for ( ; dsp_phase_index == start_index && dsp_i < FLUID_BUFSIZE; dsp_i++) - { - coeffs = interp_coeff[fluid_phase_fract_to_tablerow (dsp_phase)]; - dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * start_point - + coeffs[1] * dsp_data[dsp_phase_index] - + coeffs[2] * dsp_data[dsp_phase_index+1] - + coeffs[3] * dsp_data[dsp_phase_index+2]); - - /* increment phase and amplitude */ - fluid_phase_incr (dsp_phase, dsp_phase_incr); - dsp_phase_index = fluid_phase_index (dsp_phase); - dsp_amp += dsp_amp_incr; - } - - /* interpolate the sequence of sample points */ - for ( ; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++) - { - coeffs = interp_coeff[fluid_phase_fract_to_tablerow (dsp_phase)]; - dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * dsp_data[dsp_phase_index-1] - + coeffs[1] * dsp_data[dsp_phase_index] - + coeffs[2] * dsp_data[dsp_phase_index+1] - + coeffs[3] * dsp_data[dsp_phase_index+2]); - - /* increment phase and amplitude */ - fluid_phase_incr (dsp_phase, dsp_phase_incr); - dsp_phase_index = fluid_phase_index (dsp_phase); - dsp_amp += dsp_amp_incr; - } - - /* break out if buffer filled */ - if (dsp_i >= FLUID_BUFSIZE) break; - - end_index++; /* we're now interpolating the 2nd to last point */ - - /* interpolate within 2nd to last point */ - for (; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++) - { - coeffs = interp_coeff[fluid_phase_fract_to_tablerow (dsp_phase)]; - dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * dsp_data[dsp_phase_index-1] - + coeffs[1] * dsp_data[dsp_phase_index] - + coeffs[2] * dsp_data[dsp_phase_index+1] - + coeffs[3] * end_point1); - - /* increment phase and amplitude */ - fluid_phase_incr (dsp_phase, dsp_phase_incr); - dsp_phase_index = fluid_phase_index (dsp_phase); - dsp_amp += dsp_amp_incr; - } - - end_index++; /* we're now interpolating the last point */ - - /* interpolate within the last point */ - for (; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++) - { - coeffs = interp_coeff[fluid_phase_fract_to_tablerow (dsp_phase)]; - dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * dsp_data[dsp_phase_index-1] - + coeffs[1] * dsp_data[dsp_phase_index] - + coeffs[2] * end_point1 - + coeffs[3] * end_point2); - - /* increment phase and amplitude */ - fluid_phase_incr (dsp_phase, dsp_phase_incr); - dsp_phase_index = fluid_phase_index (dsp_phase); - dsp_amp += dsp_amp_incr; - } - - if (!looping) break; /* break out if not looping (end of sample) */ - - /* go back to loop start */ - if (dsp_phase_index > end_index) - { - fluid_phase_sub_int (dsp_phase, voice->loopend - voice->loopstart); - - if (!voice->has_looped) - { - voice->has_looped = 1; - start_index = voice->loopstart; - start_point = dsp_data[voice->loopend - 1]; - } - } - - /* break out if filled buffer */ - if (dsp_i >= FLUID_BUFSIZE) break; - - end_index -= 2; /* set end back to third to last sample point */ - } - - voice->phase = dsp_phase; - voice->amp = dsp_amp; - - return (dsp_i); -} - -/* 7th order interpolation. - * Returns number of samples processed (usually FLUID_BUFSIZE but could be - * smaller if end of sample occurs). - */ -int -fluid_dsp_float_interpolate_7th_order (fluid_voice_t *voice) -{ - fluid_phase_t dsp_phase = voice->phase; - fluid_phase_t dsp_phase_incr, end_phase; - short int *dsp_data = voice->sample->data; - fluid_real_t *dsp_buf = voice->dsp_buf; - fluid_real_t dsp_amp = voice->amp; - fluid_real_t dsp_amp_incr = voice->amp_incr; - unsigned int dsp_i = 0; - unsigned int dsp_phase_index; - unsigned int start_index, end_index; - short int start_points[3]; - short int end_points[3]; - fluid_real_t *coeffs; - int looping; - - /* Convert playback "speed" floating point value to phase index/fract */ - fluid_phase_set_float (dsp_phase_incr, voice->phase_incr); - - /* add 1/2 sample to dsp_phase since 7th order interpolation is centered on - * the 4th sample point */ - fluid_phase_incr (dsp_phase, (fluid_phase_t)0x80000000); - - /* voice is currently looping? */ - looping = _SAMPLEMODE (voice) == FLUID_LOOP_DURING_RELEASE - || (_SAMPLEMODE (voice) == FLUID_LOOP_UNTIL_RELEASE - && voice->volenv_section < FLUID_VOICE_ENVRELEASE); - - /* last index before 7th interpolation point must be specially handled */ - end_index = (looping ? voice->loopend - 1 : voice->end) - 3; - - if (voice->has_looped) /* set start_index and start point if looped or not */ - { - start_index = voice->loopstart; - start_points[0] = dsp_data[voice->loopend - 1]; - start_points[1] = dsp_data[voice->loopend - 2]; - start_points[2] = dsp_data[voice->loopend - 3]; - } - else - { - start_index = voice->start; - start_points[0] = dsp_data[voice->start]; /* just duplicate the start point */ - start_points[1] = start_points[0]; - start_points[2] = start_points[0]; - } - - /* get the 3 points off the end (loop start if looping, duplicate point if end) */ - if (looping) - { - end_points[0] = dsp_data[voice->loopstart]; - end_points[1] = dsp_data[voice->loopstart + 1]; - end_points[2] = dsp_data[voice->loopstart + 2]; - } - else - { - end_points[0] = dsp_data[voice->end]; - end_points[1] = end_points[0]; - end_points[2] = end_points[0]; - } - - while (1) - { - dsp_phase_index = fluid_phase_index (dsp_phase); - - /* interpolate first sample point (start or loop start) if needed */ - for ( ; dsp_phase_index == start_index && dsp_i < FLUID_BUFSIZE; dsp_i++) - { - coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)]; - - dsp_buf[dsp_i] = dsp_amp - * (coeffs[0] * (fluid_real_t)start_points[2] - + coeffs[1] * (fluid_real_t)start_points[1] - + coeffs[2] * (fluid_real_t)start_points[0] - + coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index] - + coeffs[4] * (fluid_real_t)dsp_data[dsp_phase_index+1] - + coeffs[5] * (fluid_real_t)dsp_data[dsp_phase_index+2] - + coeffs[6] * (fluid_real_t)dsp_data[dsp_phase_index+3]); - - /* increment phase and amplitude */ - fluid_phase_incr (dsp_phase, dsp_phase_incr); - dsp_phase_index = fluid_phase_index (dsp_phase); - dsp_amp += dsp_amp_incr; - } - - start_index++; - - /* interpolate 2nd to first sample point (start or loop start) if needed */ - for ( ; dsp_phase_index == start_index && dsp_i < FLUID_BUFSIZE; dsp_i++) - { - coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)]; - - dsp_buf[dsp_i] = dsp_amp - * (coeffs[0] * (fluid_real_t)start_points[1] - + coeffs[1] * (fluid_real_t)start_points[0] - + coeffs[2] * (fluid_real_t)dsp_data[dsp_phase_index-1] - + coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index] - + coeffs[4] * (fluid_real_t)dsp_data[dsp_phase_index+1] - + coeffs[5] * (fluid_real_t)dsp_data[dsp_phase_index+2] - + coeffs[6] * (fluid_real_t)dsp_data[dsp_phase_index+3]); - - /* increment phase and amplitude */ - fluid_phase_incr (dsp_phase, dsp_phase_incr); - dsp_phase_index = fluid_phase_index (dsp_phase); - dsp_amp += dsp_amp_incr; - } - - start_index++; - - /* interpolate 3rd to first sample point (start or loop start) if needed */ - for ( ; dsp_phase_index == start_index && dsp_i < FLUID_BUFSIZE; dsp_i++) - { - coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)]; - - dsp_buf[dsp_i] = dsp_amp - * (coeffs[0] * (fluid_real_t)start_points[0] - + coeffs[1] * (fluid_real_t)dsp_data[dsp_phase_index-2] - + coeffs[2] * (fluid_real_t)dsp_data[dsp_phase_index-1] - + coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index] - + coeffs[4] * (fluid_real_t)dsp_data[dsp_phase_index+1] - + coeffs[5] * (fluid_real_t)dsp_data[dsp_phase_index+2] - + coeffs[6] * (fluid_real_t)dsp_data[dsp_phase_index+3]); - - /* increment phase and amplitude */ - fluid_phase_incr (dsp_phase, dsp_phase_incr); - dsp_phase_index = fluid_phase_index (dsp_phase); - dsp_amp += dsp_amp_incr; - } - - start_index -= 2; /* set back to original start index */ - - - /* interpolate the sequence of sample points */ - for ( ; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++) - { - coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)]; - - dsp_buf[dsp_i] = dsp_amp - * (coeffs[0] * (fluid_real_t)dsp_data[dsp_phase_index-3] - + coeffs[1] * (fluid_real_t)dsp_data[dsp_phase_index-2] - + coeffs[2] * (fluid_real_t)dsp_data[dsp_phase_index-1] - + coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index] - + coeffs[4] * (fluid_real_t)dsp_data[dsp_phase_index+1] - + coeffs[5] * (fluid_real_t)dsp_data[dsp_phase_index+2] - + coeffs[6] * (fluid_real_t)dsp_data[dsp_phase_index+3]); - - /* increment phase and amplitude */ - fluid_phase_incr (dsp_phase, dsp_phase_incr); - dsp_phase_index = fluid_phase_index (dsp_phase); - dsp_amp += dsp_amp_incr; - } - - /* break out if buffer filled */ - if (dsp_i >= FLUID_BUFSIZE) break; - - end_index++; /* we're now interpolating the 3rd to last point */ - - /* interpolate within 3rd to last point */ - for (; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++) - { - coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)]; - - dsp_buf[dsp_i] = dsp_amp - * (coeffs[0] * (fluid_real_t)dsp_data[dsp_phase_index-3] - + coeffs[1] * (fluid_real_t)dsp_data[dsp_phase_index-2] - + coeffs[2] * (fluid_real_t)dsp_data[dsp_phase_index-1] - + coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index] - + coeffs[4] * (fluid_real_t)dsp_data[dsp_phase_index+1] - + coeffs[5] * (fluid_real_t)dsp_data[dsp_phase_index+2] - + coeffs[6] * (fluid_real_t)end_points[0]); - - /* increment phase and amplitude */ - fluid_phase_incr (dsp_phase, dsp_phase_incr); - dsp_phase_index = fluid_phase_index (dsp_phase); - dsp_amp += dsp_amp_incr; - } - - end_index++; /* we're now interpolating the 2nd to last point */ - - /* interpolate within 2nd to last point */ - for (; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++) - { - coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)]; - - dsp_buf[dsp_i] = dsp_amp - * (coeffs[0] * (fluid_real_t)dsp_data[dsp_phase_index-3] - + coeffs[1] * (fluid_real_t)dsp_data[dsp_phase_index-2] - + coeffs[2] * (fluid_real_t)dsp_data[dsp_phase_index-1] - + coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index] - + coeffs[4] * (fluid_real_t)dsp_data[dsp_phase_index+1] - + coeffs[5] * (fluid_real_t)end_points[0] - + coeffs[6] * (fluid_real_t)end_points[1]); - - /* increment phase and amplitude */ - fluid_phase_incr (dsp_phase, dsp_phase_incr); - dsp_phase_index = fluid_phase_index (dsp_phase); - dsp_amp += dsp_amp_incr; - } - - end_index++; /* we're now interpolating the last point */ - - /* interpolate within last point */ - for (; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++) - { - coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)]; - - dsp_buf[dsp_i] = dsp_amp - * (coeffs[0] * (fluid_real_t)dsp_data[dsp_phase_index-3] - + coeffs[1] * (fluid_real_t)dsp_data[dsp_phase_index-2] - + coeffs[2] * (fluid_real_t)dsp_data[dsp_phase_index-1] - + coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index] - + coeffs[4] * (fluid_real_t)end_points[0] - + coeffs[5] * (fluid_real_t)end_points[1] - + coeffs[6] * (fluid_real_t)end_points[2]); - - /* increment phase and amplitude */ - fluid_phase_incr (dsp_phase, dsp_phase_incr); - dsp_phase_index = fluid_phase_index (dsp_phase); - dsp_amp += dsp_amp_incr; - } - - if (!looping) break; /* break out if not looping (end of sample) */ - - /* go back to loop start */ - if (dsp_phase_index > end_index) - { - fluid_phase_sub_int (dsp_phase, voice->loopend - voice->loopstart); - - if (!voice->has_looped) - { - voice->has_looped = 1; - start_index = voice->loopstart; - start_points[0] = dsp_data[voice->loopend - 1]; - start_points[1] = dsp_data[voice->loopend - 2]; - start_points[2] = dsp_data[voice->loopend - 3]; - } - } - - /* break out if filled buffer */ - if (dsp_i >= FLUID_BUFSIZE) break; - - end_index -= 3; /* set end back to 4th to last sample point */ - } - - /* sub 1/2 sample from dsp_phase since 7th order interpolation is centered on - * the 4th sample point (correct back to real value) */ - fluid_phase_decr (dsp_phase, (fluid_phase_t)0x80000000); - - voice->phase = dsp_phase; - voice->amp = dsp_amp; - - return (dsp_i); -} diff --git a/src/libs/fluidsynth/src/fluid_dsp_simple.c b/src/libs/fluidsynth/src/fluid_dsp_simple.c deleted file mode 100644 index 663f5a67c0..0000000000 --- a/src/libs/fluidsynth/src/fluid_dsp_simple.c +++ /dev/null @@ -1,120 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - - -/* Purpose: - * Low-level voice processing: - * - * - interpolates (obtains values between the samples of the original waveform data) - * - filters (applies a lowpass filter with variable cutoff frequency and quality factor) - * - mixes the processed sample to left and right output using the pan setting - * - sends the processed sample to chorus and reverb - * - * - * This file does -not- generate an object file. - * Instead, it is #included in several places in fluid_voice.c. - * The motivation for this is - * - Calling it as a subroutine may be time consuming, especially with optimization off - * - The previous implementation as a macro was clumsy to handle - * - * - * Fluid_voice.c sets a couple of variables before #including this: - * - dsp_data: Pointer to the original waveform data - * - dsp_left_buf: The generated signal goes here, left channel - * - dsp_right_buf: right channel - * - dsp_reverb_buf: Send to reverb unit - * - dsp_chorus_buf: Send to chorus unit - * - dsp_start: Start processing at this output buffer index - * - dsp_end: End processing just before this output buffer index - * - dsp_a1: Coefficient for the filter - * - dsp_a2: same - * - dsp_b0: same - * - dsp_b1: same - * - dsp_b2: same - * - dsp_filter_flag: Set, the filter is needed (many sound fonts don't use - * the filter at all. If it is left at its default setting - * of roughly 20 kHz, there is no need to apply filterling.) - * - dsp_interp_method: Which interpolation method to use. - * - voice holds the voice structure - * - * Some variables are set and modified: - * - dsp_phase: The position in the original waveform data. - * This has an integer and a fractional part (between samples). - * - dsp_phase_incr: For each output sample, the position in the original - * waveform advances by dsp_phase_incr. This also has an integer - * part and a fractional part. - * If a sample is played at root pitch (no pitch change), - * dsp_phase_incr is integer=1 and fractional=0. - * - dsp_amp: The current amplitude envelope value. - * - dsp_amp_incr: The changing rate of the amplitude envelope. - * - * A couple of variables are used internally, their results are discarded: - * - dsp_i: Index through the output buffer - * - dsp_phase_fractional: The fractional part of dsp_phase - * - dsp_coeff: A table of four coefficients, depending on the fractional phase. - * Used to interpolate between samples. - * - dsp_process_buffer: Holds the processed signal between stages - * - dsp_centernode: delay line for the IIR filter - * - dsp_hist1: same - * - dsp_hist2: same - * - */ - - -/* Nonoptimized DSP loop */ -#warning "This code is meant for experiments only."; - -/* wave table interpolation */ -for (dsp_i = dsp_start; dsp_i < dsp_end; dsp_i++) { - - dsp_coeff = &interp_coeff[fluid_phase_fract_to_tablerow(dsp_phase)]; - dsp_phase_index = fluid_phase_index(dsp_phase); - dsp_sample = (dsp_amp * - (dsp_coeff->a0 * dsp_data[dsp_phase_index] - + dsp_coeff->a1 * dsp_data[dsp_phase_index+1] - + dsp_coeff->a2 * dsp_data[dsp_phase_index+2] - + dsp_coeff->a3 * dsp_data[dsp_phase_index+3])); - - /* increment phase and amplitude */ - fluid_phase_incr(dsp_phase, dsp_phase_incr); - dsp_amp += dsp_amp_incr; - - /* filter */ - /* The filter is implemented in Direct-II form. */ - dsp_centernode = dsp_sample - dsp_a1 * dsp_hist1 - dsp_a2 * dsp_hist2; - dsp_sample = dsp_b0 * dsp_centernode + dsp_b1 * dsp_hist1 + dsp_b2 * dsp_hist2; - dsp_hist2 = dsp_hist1; - dsp_hist1 = dsp_centernode; - - /* pan */ - dsp_left_buf[dsp_i] += voice->amp_left * dsp_sample; - dsp_right_buf[dsp_i] += voice->amp_right * dsp_sample; - - /* reverb */ - if (dsp_reverb_buf){ - dsp_reverb_buf[dsp_i] += voice->amp_reverb * dsp_sample; - } - - /* chorus */ - if (dsp_chorus_buf){ - dsp_chorus_buf[dsp_i] += voice->amp_chorus * dsp_sample; - } -} - diff --git a/src/libs/fluidsynth/src/fluid_event.c b/src/libs/fluidsynth/src/fluid_event.c deleted file mode 100644 index aaa7465e1a..0000000000 --- a/src/libs/fluidsynth/src/fluid_event.c +++ /dev/null @@ -1,735 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - - -/* - 2002 : API design by Peter Hanappe and Antoine Schmitt - August 2002 : Implementation by Antoine Schmitt as@gratin.org - as part of the infiniteCD author project - http://www.infiniteCD.org/ - Oct4.2002 : AS : corrected bug in heap allocation, that caused a crash during sequencer free. -*/ - - -#include "fluid_event_priv.h" -#include "fluidsynth_priv.h" - -/*************************************************************** - * - * SEQUENCER EVENTS - */ - -/* Event alloc/free */ - -/** - * Create a new sequencer event structure. - * @return New sequencer event structure or NULL if out of memory - */ -fluid_event_t* -new_fluid_event() -{ - fluid_event_t* evt; - - evt = FLUID_NEW(fluid_event_t); - if (evt == NULL) { - fluid_log(FLUID_PANIC, "event: Out of memory\n"); - return NULL; - } - - FLUID_MEMSET(evt, 0, sizeof(fluid_event_t)); - - // by default, no type - evt->dest = -1; - evt->src = -1; - evt->type = -1; - - return(evt); -} - -/** - * Delete a sequencer event structure. - * @param evt Sequencer event structure created by new_fluid_event(). - */ -void -delete_fluid_event(fluid_event_t* evt) -{ - - if (evt == NULL) { - return; - } - - FLUID_FREE(evt); -} - -/** - * Set the time field of a sequencer event. - * @internal - * @param evt Sequencer event structure - * @param time Time value to assign - */ -void -fluid_event_set_time(fluid_event_t* evt, unsigned int time) -{ - evt->time = time; -} - -/** - * Set source of a sequencer event (DOCME). - * @param evt Sequencer event structure - * @param src DOCME - */ -void -fluid_event_set_source(fluid_event_t* evt, short src) -{ - evt->src = src; -} - -/** - * Set destination of a sequencer event (DOCME). - * @param evt Sequencer event structure - * @param dest DOCME - */ -void -fluid_event_set_dest(fluid_event_t* evt, short dest) -{ - evt->dest = dest; -} - -/** - * Set a sequencer event to be a timer event. - * @param evt Sequencer event structure - * @param data DOCME - */ -void -fluid_event_timer(fluid_event_t* evt, void* data) -{ - evt->type = FLUID_SEQ_TIMER; - evt->data = data; -} - -/** - * Set a sequencer event to be a note on event. - * @param evt Sequencer event structure - * @param channel MIDI channel number - * @param key MIDI note number (0-127) - * @param vel MIDI velocity value (0-127) - */ -void -fluid_event_noteon(fluid_event_t* evt, int channel, short key, short vel) -{ - evt->type = FLUID_SEQ_NOTEON; - evt->channel = channel; - evt->key = key; - evt->vel = vel; -} - -/** - * Set a sequencer event to be a note off event. - * @param evt Sequencer event structure - * @param channel MIDI channel number - * @param key MIDI note number (0-127) - */ -void -fluid_event_noteoff(fluid_event_t* evt, int channel, short key) -{ - evt->type = FLUID_SEQ_NOTEOFF; - evt->channel = channel; - evt->key = key; -} - -/** - * Set a sequencer event to be a note duration event. - * @param evt Sequencer event structure - * @param channel MIDI channel number - * @param key MIDI note number (0-127) - * @param vel MIDI velocity value (0-127) - * @param duration Duration of note (DOCME units?) - */ -void -fluid_event_note(fluid_event_t* evt, int channel, short key, short vel, unsigned int duration) -{ - evt->type = FLUID_SEQ_NOTE; - evt->channel = channel; - evt->key = key; - evt->vel = vel; - evt->duration = duration; -} - -/** - * Set a sequencer event to be an all sounds off event. - * @param evt Sequencer event structure - * @param channel MIDI channel number - */ -void -fluid_event_all_sounds_off(fluid_event_t* evt, int channel) -{ - evt->type = FLUID_SEQ_ALLSOUNDSOFF; - evt->channel = channel; -} - -/** - * Set a sequencer event to be a all notes off event. - * @param evt Sequencer event structure - * @param channel MIDI channel number - */ -void -fluid_event_all_notes_off(fluid_event_t* evt, int channel) -{ - evt->type = FLUID_SEQ_ALLNOTESOFF; - evt->channel = channel; -} - -/** - * Set a sequencer event to be a bank select event. - * @param evt Sequencer event structure - * @param channel MIDI channel number - * @param bank_num MIDI bank number (0-16383) - */ -void -fluid_event_bank_select(fluid_event_t* evt, int channel, short bank_num) -{ - evt->type = FLUID_SEQ_BANKSELECT; - evt->channel = channel; - evt->control = bank_num; -} - -/** - * Set a sequencer event to be a program change event. - * @param evt Sequencer event structure - * @param channel MIDI channel number - * @param val MIDI program number (0-127) - */ -void -fluid_event_program_change(fluid_event_t* evt, int channel, short val) -{ - evt->type = FLUID_SEQ_PROGRAMCHANGE; - evt->channel = channel; - evt->value = val; -} - -/** - * Set a sequencer event to be a program select event. - * @param evt Sequencer event structure - * @param channel MIDI channel number - * @param sfont_id SoundFont ID number - * @param bank_num MIDI bank number (0-16383) - * @param preset_num MIDI preset number (0-127) - */ -void -fluid_event_program_select(fluid_event_t* evt, int channel, - unsigned int sfont_id, short bank_num, short preset_num) -{ - evt->type = FLUID_SEQ_PROGRAMSELECT; - evt->channel = channel; - evt->duration = sfont_id; - evt->value = preset_num; - evt->control = bank_num; -} - -/** - * Set a sequencer event to be an any control change event. - * @param evt Sequencer event structure - * @param channel MIDI channel number - * DOCME - */ -void -fluid_event_any_control_change(fluid_event_t* evt, int channel) -{ - evt->type = FLUID_SEQ_ANYCONTROLCHANGE; - evt->channel = channel; -} - -/** - * Set a sequencer event to be a pitch bend event. - * @param evt Sequencer event structure - * @param channel MIDI channel number - * @param pitch MIDI pitch bend value (0-16383, 8192 = no bend) - */ -void -fluid_event_pitch_bend(fluid_event_t* evt, int channel, int pitch) -{ - evt->type = FLUID_SEQ_PITCHBEND; - evt->channel = channel; - if (pitch < 0) pitch = 0; - if (pitch > 16383) pitch = 16383; - evt->pitch = pitch; -} - -/** - * Set a sequencer event to be a pitch wheel sensitivity event. - * @param evt Sequencer event structure - * @param channel MIDI channel number - * @param value MIDI pitch wheel sensitivity value (DOCME units?) - */ -void -fluid_event_pitch_wheelsens(fluid_event_t* evt, int channel, short value) -{ - evt->type = FLUID_SEQ_PITCHWHHELSENS; - evt->channel = channel; - evt->value = value; -} - -/** - * Set a sequencer event to be a modulation event. - * @param evt Sequencer event structure - * @param channel MIDI channel number - * @param val MIDI modulation value (0-127) - */ -void -fluid_event_modulation(fluid_event_t* evt, int channel, short val) -{ - evt->type = FLUID_SEQ_MODULATION; - evt->channel = channel; - if (val < 0) val = 0; - if (val > 127) val = 127; - evt->value = val; -} - -/** - * Set a sequencer event to be a MIDI sustain event. - * @param evt Sequencer event structure - * @param channel MIDI channel number - * @param val MIDI sustain value (0-127) - */ -void -fluid_event_sustain(fluid_event_t* evt, int channel, short val) -{ - evt->type = FLUID_SEQ_SUSTAIN; - evt->channel = channel; - if (val < 0) val = 0; - if (val > 127) val = 127; - evt->value = val; -} - -/** - * Set a sequencer event to be a MIDI control change event. - * @param evt Sequencer event structure - * @param channel MIDI channel number - * @param control MIDI control number (0-127) - * @param val MIDI control value (0-16383 DOCME is that true?) - */ -void -fluid_event_control_change(fluid_event_t* evt, int channel, short control, short val) -{ - evt->type = FLUID_SEQ_CONTROLCHANGE; - evt->channel = channel; - evt->control = control; - evt->value = val; -} - -/** - * Set a sequencer event to be a stereo pan event. - * @param evt Sequencer event structure - * @param channel MIDI channel number - * @param val MIDI panning value (0-127, 0=left, 64 = middle, 127 = right) - */ -void -fluid_event_pan(fluid_event_t* evt, int channel, short val) -{ - evt->type = FLUID_SEQ_PAN; - evt->channel = channel; - if (val < 0) val = 0; - if (val > 127) val = 127; - evt->value = val; -} - -/** - * Set a sequencer event to be a volume event. - * @param evt Sequencer event structure - * @param channel MIDI channel number - * @param val Volume value (0-127) - */ -void -fluid_event_volume(fluid_event_t* evt, int channel, short val) -{ - evt->type = FLUID_SEQ_VOLUME; - evt->channel = channel; - if (val < 0) val = 0; - if (val > 127) val = 127; - evt->value = val; -} - -/** - * Set a sequencer event to be a reverb send event. - * @param evt Sequencer event structure - * @param channel MIDI channel number - * @param val Reverb amount (0-127) - */ -void -fluid_event_reverb_send(fluid_event_t* evt, int channel, short val) -{ - evt->type = FLUID_SEQ_REVERBSEND; - evt->channel = channel; - if (val < 0) val = 0; - if (val > 127) val = 127; - evt->value = val; -} - -/** - * Set a sequencer event to be a chorus send event. - * @param evt Sequencer event structure - * @param channel MIDI channel number - * @param val Chorus amount (0-127) - */ -void -fluid_event_chorus_send(fluid_event_t* evt, int channel, short val) -{ - evt->type = FLUID_SEQ_CHORUSSEND; - evt->channel = channel; - if (val < 0) val = 0; - if (val > 127) val = 127; - evt->value = val; -} - - -/* - * Accessing event data - */ - -/** - * Get the event type (#fluid_seq_event_type) field from a sequencer event structure. - * @param evt Sequencer event structure - * @return Event type (#fluid_seq_event_type). - */ -int fluid_event_get_type(fluid_event_t* evt) -{ - return evt->type; -} - -/** - * Get the time field from a sequencer event structure. - * @param evt Sequencer event structure - * @return Time value (DOCME units?) - */ -unsigned int fluid_event_get_time(fluid_event_t* evt) -{ - return evt->time; -} - -/** - * Get the source field from a sequencer event structure. - * @param evt Sequencer event structure - * @return DOCME - */ -short fluid_event_get_source(fluid_event_t* evt) -{ - return evt->src; -} - -/** - * Get the dest field from a sequencer event structure. - * @param evt Sequencer event structure - * @return DOCME - */ -short fluid_event_get_dest(fluid_event_t* evt) -{ - return evt->dest; -} - -/** - * Get the MIDI channel field from a sequencer event structure. - * @param evt Sequencer event structure - * @return MIDI channel number (DOCME 0-15 or more?) - */ -int fluid_event_get_channel(fluid_event_t* evt) -{ - return evt->channel; -} - -/** - * Get the MIDI note field from a sequencer event structure. - * @param evt Sequencer event structure - * @return MIDI note number (0-127) - */ -short fluid_event_get_key(fluid_event_t* evt) -{ - return evt->key; -} - -/** - * Get the MIDI velocity field from a sequencer event structure. - * @param evt Sequencer event structure - * @return MIDI velocity value (0-127) - */ -short fluid_event_get_velocity(fluid_event_t* evt) - -{ - return evt->vel; -} - -/** - * Get the MIDI control number field from a sequencer event structure. - * @param evt Sequencer event structure - * @return MIDI control number (0-127) - */ -short fluid_event_get_control(fluid_event_t* evt) -{ - return evt->control; -} - -/** - * Get the value field from a sequencer event structure. - * @param evt Sequencer event structure - * @return Value field of event. - * - * The Value field is used by the following event types: - * #FLUID_SEQ_PROGRAMCHANGE, #FLUID_SEQ_PROGRAMSELECT (preset_num), - * #FLUID_SEQ_PITCHWHHELSENS, #FLUID_SEQ_MODULATION, #FLUID_SEQ_SUSTAIN, - * #FLUID_SEQ_CONTROLCHANGE, #FLUID_SEQ_PAN, #FLUID_SEQ_VOLUME, - * #FLUID_SEQ_REVERBSEND, #FLUID_SEQ_CHORUSSEND. - */ -short fluid_event_get_value(fluid_event_t* evt) -{ - return evt->value; -} - -/** - * Get the data field from a sequencer event structure. - * @param evt Sequencer event structure - * @return Data field of event. - * - * Used by the #FLUID_SEQ_TIMER event type. - */ -void* fluid_event_get_data(fluid_event_t* evt) -{ - return evt->data; -} - -/** - * Get the duration field from a sequencer event structure. - * @param evt Sequencer event structure - * @return Note duration value (DOCME units?) - * - * Used by the #FLUID_SEQ_NOTE event type. - */ -unsigned int fluid_event_get_duration(fluid_event_t* evt) -{ - return evt->duration; -} - -/** - * Get the MIDI bank field from a sequencer event structure. - * @param evt Sequencer event structure - * @return MIDI bank number (0-16383) - * - * Used by the #FLUID_SEQ_BANKSELECT and #FLUID_SEQ_PROGRAMSELECT - * event types. - */ -short fluid_event_get_bank(fluid_event_t* evt) -{ - return evt->control; -} - -/** - * Get the pitch field from a sequencer event structure. - * @param evt Sequencer event structure - * @return MIDI pitch bend pitch value (0-16383, 8192 = no bend) - * - * Used by the #FLUID_SEQ_PITCHBEND event type. - */ -int fluid_event_get_pitch(fluid_event_t* evt) -{ - return evt->pitch; -} - -/** - * Get the MIDI program field from a sequencer event structure. - * @param evt Sequencer event structure - * @return MIDI program number (0-127) - * - * Used by the #FLUID_SEQ_PROGRAMCHANGE and #FLUID_SEQ_PROGRAMSELECT - * event types. - */ -short -fluid_event_get_program(fluid_event_t* evt) -{ - return evt->value; -} - -/** - * Get the SoundFont ID field from a sequencer event structure. - * @param evt Sequencer event structure - * @return SoundFont identifier value. - * - * Used by the #FLUID_SEQ_PROGRAMSELECT event type. - */ -unsigned int -fluid_event_get_sfont_id(fluid_event_t* evt) -{ - return evt->duration; -} - - - -/********************/ -/* heap management */ -/********************/ - -fluid_evt_heap_t* -_fluid_evt_heap_init(int nbEvents) -{ -#ifdef HEAP_WITH_DYNALLOC - - int i; - fluid_evt_heap_t* heap; - fluid_evt_entry *tmp; - - heap = FLUID_NEW(fluid_evt_heap_t); - if (heap == NULL) { - fluid_log(FLUID_PANIC, "sequencer: Out of memory\n"); - return NULL; - } - - heap->freelist = NULL; - fluid_mutex_init(heap->mutex); - - /* LOCK */ - fluid_mutex_lock(heap->mutex); - - /* Allocate the event entries */ - for (i = 0; i < nbEvents; i++) { - tmp = FLUID_NEW(fluid_evt_entry); - tmp->next = heap->freelist; - heap->freelist = tmp; - } - - /* UNLOCK */ - fluid_mutex_unlock(heap->mutex); - - -#else - int i; - fluid_evt_heap_t* heap; - int siz = 2*sizeof(fluid_evt_entry *) + sizeof(fluid_evt_entry)*nbEvents; - - heap = (fluid_evt_heap_t *)FLUID_MALLOC(siz); - if (heap == NULL) { - fluid_log(FLUID_PANIC, "sequencer: Out of memory\n"); - return NULL; - } - FLUID_MEMSET(heap, 0, siz); - - /* link all heap events */ - { - fluid_evt_entry *tmp = &(heap->pool); - for (i = 0 ; i < nbEvents - 1 ; i++) - tmp[i].next = &(tmp[i+1]); - tmp[nbEvents-1].next = NULL; - - /* set head & tail */ - heap->tail = &(tmp[nbEvents-1]); - heap->head = &(heap->pool); - } -#endif - return (heap); -} - -void -_fluid_evt_heap_free(fluid_evt_heap_t* heap) -{ -#ifdef HEAP_WITH_DYNALLOC - fluid_evt_entry *tmp, *next; - - /* LOCK */ - fluid_mutex_lock(heap->mutex); - - tmp = heap->freelist; - while (tmp) { - next = tmp->next; - FLUID_FREE(tmp); - tmp = next; - } - - /* UNLOCK */ - fluid_mutex_unlock(heap->mutex); - fluid_mutex_destroy(heap->mutex); - - FLUID_FREE(heap); - -#else - FLUID_FREE(heap); -#endif -} - -fluid_evt_entry* -_fluid_seq_heap_get_free(fluid_evt_heap_t* heap) -{ -#ifdef HEAP_WITH_DYNALLOC - fluid_evt_entry* evt = NULL; - - /* LOCK */ - fluid_mutex_lock(heap->mutex); - -#if !defined(MACOS9) - if (heap->freelist == NULL) { - heap->freelist = FLUID_NEW(fluid_evt_entry); - if (heap->freelist != NULL) { - heap->freelist->next = NULL; - } - } -#endif - - evt = heap->freelist; - - if (evt != NULL) { - heap->freelist = heap->freelist->next; - evt->next = NULL; - } - - /* UNLOCK */ - fluid_mutex_unlock(heap->mutex); - - return evt; - -#else - fluid_evt_entry* evt; - if (heap->head == NULL) return NULL; - - /* take from head of the heap */ - /* critical - should threadlock ? */ - evt = heap->head; - heap->head = heap->head->next; - - return evt; -#endif -} - -void -_fluid_seq_heap_set_free(fluid_evt_heap_t* heap, fluid_evt_entry* evt) -{ -#ifdef HEAP_WITH_DYNALLOC - - /* LOCK */ - fluid_mutex_lock(heap->mutex); - - evt->next = heap->freelist; - heap->freelist = evt; - - /* UNLOCK */ - fluid_mutex_unlock(heap->mutex); - -#else - /* append to the end of the heap */ - /* critical - should threadlock ? */ - heap->tail->next = evt; - heap->tail = evt; - evt->next = NULL; -#endif -} diff --git a/src/libs/fluidsynth/src/fluid_event_priv.h b/src/libs/fluidsynth/src/fluid_event_priv.h deleted file mode 100644 index 619381c4e1..0000000000 --- a/src/libs/fluidsynth/src/fluid_event_priv.h +++ /dev/null @@ -1,81 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - - -#ifndef _FLUID_EVENT_PRIV_H -#define _FLUID_EVENT_PRIV_H - -#include "fluidsynth.h" -#include "fluid_sys.h" - -/* Private data for event */ -/* ?? should be optimized in size, using unions */ -struct _fluid_event_t { - unsigned int time; - int type; - short src; - short dest; - int channel; - short key; - short vel; - short control; - short value; - short id; //?? unused ? - int pitch; - unsigned int duration; - void* data; -}; - -unsigned int fluid_event_get_time(fluid_event_t* evt); -void fluid_event_set_time(fluid_event_t* evt, unsigned int time); - -/* private data for sorter + heap */ -enum fluid_evt_entry_type { - FLUID_EVT_ENTRY_INSERT = 0, - FLUID_EVT_ENTRY_REMOVE -}; - -typedef struct _fluid_evt_entry fluid_evt_entry; -struct _fluid_evt_entry { - fluid_evt_entry *next; - short entryType; - fluid_event_t evt; -}; - -#define HEAP_WITH_DYNALLOC 1 -/* #undef HEAP_WITH_DYNALLOC */ - -typedef struct _fluid_evt_heap_t { -#ifdef HEAP_WITH_DYNALLOC - fluid_evt_entry* freelist; - fluid_mutex_t mutex; -#else - fluid_evt_entry* head; - fluid_evt_entry* tail; - fluid_evt_entry pool; -#endif -} fluid_evt_heap_t; - -fluid_evt_heap_t* _fluid_evt_heap_init(int nbEvents); -void _fluid_evt_heap_free(fluid_evt_heap_t* heap); -fluid_evt_entry* _fluid_seq_heap_get_free(fluid_evt_heap_t* heap); -void _fluid_seq_heap_set_free(fluid_evt_heap_t* heap, fluid_evt_entry* evt); - -#endif /* _FLUID_EVENT_PRIV_H */ diff --git a/src/libs/fluidsynth/src/fluid_gen.c b/src/libs/fluidsynth/src/fluid_gen.c deleted file mode 100644 index 4f9bb02346..0000000000 --- a/src/libs/fluidsynth/src/fluid_gen.c +++ /dev/null @@ -1,149 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - - -#include "fluid_gen.h" -#include "fluid_chan.h" - - -/* See SFSpec21 $8.1.3 */ -fluid_gen_info_t fluid_gen_info[] = { - /* number/name init scale min max def */ - { GEN_STARTADDROFS, 1, 1, 0.0f, 1e10f, 0.0f }, - { GEN_ENDADDROFS, 1, 1, -1e10f, 0.0f, 0.0f }, - { GEN_STARTLOOPADDROFS, 1, 1, -1e10f, 1e10f, 0.0f }, - { GEN_ENDLOOPADDROFS, 1, 1, -1e10f, 1e10f, 0.0f }, - { GEN_STARTADDRCOARSEOFS, 0, 1, 0.0f, 1e10f, 0.0f }, - { GEN_MODLFOTOPITCH, 1, 2, -12000.0f, 12000.0f, 0.0f }, - { GEN_VIBLFOTOPITCH, 1, 2, -12000.0f, 12000.0f, 0.0f }, - { GEN_MODENVTOPITCH, 1, 2, -12000.0f, 12000.0f, 0.0f }, - { GEN_FILTERFC, 1, 2, 1500.0f, 13500.0f, 13500.0f }, - { GEN_FILTERQ, 1, 1, 0.0f, 960.0f, 0.0f }, - { GEN_MODLFOTOFILTERFC, 1, 2, -12000.0f, 12000.0f, 0.0f }, - { GEN_MODENVTOFILTERFC, 1, 2, -12000.0f, 12000.0f, 0.0f }, - { GEN_ENDADDRCOARSEOFS, 0, 1, -1e10f, 0.0f, 0.0f }, - { GEN_MODLFOTOVOL, 1, 1, -960.0f, 960.0f, 0.0f }, - { GEN_UNUSED1, 0, 0, 0.0f, 0.0f, 0.0f }, - { GEN_CHORUSSEND, 1, 1, 0.0f, 1000.0f, 0.0f }, - { GEN_REVERBSEND, 1, 1, 0.0f, 1000.0f, 0.0f }, - { GEN_PAN, 1, 1, -500.0f, 500.0f, 0.0f }, - { GEN_UNUSED2, 0, 0, 0.0f, 0.0f, 0.0f }, - { GEN_UNUSED3, 0, 0, 0.0f, 0.0f, 0.0f }, - { GEN_UNUSED4, 0, 0, 0.0f, 0.0f, 0.0f }, - { GEN_MODLFODELAY, 1, 2, -12000.0f, 5000.0f, -12000.0f }, - { GEN_MODLFOFREQ, 1, 4, -16000.0f, 4500.0f, 0.0f }, - { GEN_VIBLFODELAY, 1, 2, -12000.0f, 5000.0f, -12000.0f }, - { GEN_VIBLFOFREQ, 1, 4, -16000.0f, 4500.0f, 0.0f }, - { GEN_MODENVDELAY, 1, 2, -12000.0f, 5000.0f, -12000.0f }, - { GEN_MODENVATTACK, 1, 2, -12000.0f, 8000.0f, -12000.0f }, - { GEN_MODENVHOLD, 1, 2, -12000.0f, 5000.0f, -12000.0f }, - { GEN_MODENVDECAY, 1, 2, -12000.0f, 8000.0f, -12000.0f }, - { GEN_MODENVSUSTAIN, 0, 1, 0.0f, 1000.0f, 0.0f }, - { GEN_MODENVRELEASE, 1, 2, -12000.0f, 8000.0f, -12000.0f }, - { GEN_KEYTOMODENVHOLD, 0, 1, -1200.0f, 1200.0f, 0.0f }, - { GEN_KEYTOMODENVDECAY, 0, 1, -1200.0f, 1200.0f, 0.0f }, - { GEN_VOLENVDELAY, 1, 2, -12000.0f, 5000.0f, -12000.0f }, - { GEN_VOLENVATTACK, 1, 2, -12000.0f, 8000.0f, -12000.0f }, - { GEN_VOLENVHOLD, 1, 2, -12000.0f, 5000.0f, -12000.0f }, - { GEN_VOLENVDECAY, 1, 2, -12000.0f, 8000.0f, -12000.0f }, - { GEN_VOLENVSUSTAIN, 0, 1, 0.0f, 1440.0f, 0.0f }, - { GEN_VOLENVRELEASE, 1, 2, -12000.0f, 8000.0f, -12000.0f }, - { GEN_KEYTOVOLENVHOLD, 0, 1, -1200.0f, 1200.0f, 0.0f }, - { GEN_KEYTOVOLENVDECAY, 0, 1, -1200.0f, 1200.0f, 0.0f }, - { GEN_INSTRUMENT, 0, 0, 0.0f, 0.0f, 0.0f }, - { GEN_RESERVED1, 0, 0, 0.0f, 0.0f, 0.0f }, - { GEN_KEYRANGE, 0, 0, 0.0f, 127.0f, 0.0f }, - { GEN_VELRANGE, 0, 0, 0.0f, 127.0f, 0.0f }, - { GEN_STARTLOOPADDRCOARSEOFS, 0, 1, -1e10f, 1e10f, 0.0f }, - { GEN_KEYNUM, 1, 0, 0.0f, 127.0f, -1.0f }, - { GEN_VELOCITY, 1, 1, 0.0f, 127.0f, -1.0f }, - { GEN_ATTENUATION, 1, 1, 0.0f, 1440.0f, 0.0f }, - { GEN_RESERVED2, 0, 0, 0.0f, 0.0f, 0.0f }, - { GEN_ENDLOOPADDRCOARSEOFS, 0, 1, -1e10f, 1e10f, 0.0f }, - { GEN_COARSETUNE, 0, 1, -120.0f, 120.0f, 0.0f }, - { GEN_FINETUNE, 0, 1, -99.0f, 99.0f, 0.0f }, - { GEN_SAMPLEID, 0, 0, 0.0f, 0.0f, 0.0f }, - { GEN_SAMPLEMODE, 0, 0, 0.0f, 0.0f, 0.0f }, - { GEN_RESERVED3, 0, 0, 0.0f, 0.0f, 0.0f }, - { GEN_SCALETUNE, 0, 1, 0.0f, 1200.0f, 100.0f }, - { GEN_EXCLUSIVECLASS, 0, 0, 0.0f, 0.0f, 0.0f }, - { GEN_OVERRIDEROOTKEY, 1, 0, 0.0f, 127.0f, -1.0f }, - { GEN_PITCH, 1, 0, 0.0f, 127.0f, 0.0f } -}; - - -/** - * Set an array of generators to their default values. - * @param gen Array of generators (should be #GEN_LAST in size). - * @return Always returns 0 - */ -int -fluid_gen_set_default_values(fluid_gen_t* gen) -{ - int i; - - for (i = 0; i < GEN_LAST; i++) { - gen[i].flags = GEN_UNUSED; - gen[i].mod = 0.0; - gen[i].nrpn = 0.0; - gen[i].val = fluid_gen_info[i].def; - } - - return FLUID_OK; -} - - -/* fluid_gen_init - * - * Set an array of generators to their initial value - */ -int -fluid_gen_init(fluid_gen_t* gen, fluid_channel_t* channel) -{ - int i; - - fluid_gen_set_default_values(gen); - - for (i = 0; i < GEN_LAST; i++) { - gen[i].nrpn = fluid_channel_get_gen(channel, i); - - /* This is an extension to the SoundFont standard. More - * documentation is available at the fluid_synth_set_gen2() - * function. */ - if (fluid_channel_get_gen_abs(channel, i)) { - gen[i].flags = GEN_ABS_NRPN; - } - } - - return FLUID_OK; -} - -fluid_real_t fluid_gen_scale(int gen, float value) -{ - return (fluid_gen_info[gen].min - + value * (fluid_gen_info[gen].max - fluid_gen_info[gen].min)); -} - -fluid_real_t fluid_gen_scale_nrpn(int gen, int data) -{ - fluid_real_t value = (float) data - 8192.0f; - fluid_clip(value, -8192, 8192); - return value * (float) fluid_gen_info[gen].nrpn_scale; -} diff --git a/src/libs/fluidsynth/src/fluid_gen.h b/src/libs/fluidsynth/src/fluid_gen.h deleted file mode 100644 index c35193a52c..0000000000 --- a/src/libs/fluidsynth/src/fluid_gen.h +++ /dev/null @@ -1,44 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - - -#ifndef _FLUID_GEN_H -#define _FLUID_GEN_H - -#include "fluidsynth_priv.h" - -typedef struct _fluid_gen_info_t { - char num; /* Generator number */ - char init; /* Does the generator need to be initialized (cfr. fluid_voice_init()) */ - char nrpn_scale; /* The scale to convert from NRPN (cfr. fluid_gen_map_nrpn()) */ - float min; /* The minimum value */ - float max; /* The maximum value */ - float def; /* The default value (cfr. fluid_gen_set_default_values()) */ -} fluid_gen_info_t; - -#define fluid_gen_set_mod(_gen, _val) { (_gen)->mod = (double) (_val); } -#define fluid_gen_set_nrpn(_gen, _val) { (_gen)->nrpn = (double) (_val); } - -fluid_real_t fluid_gen_scale(int gen, float value); -fluid_real_t fluid_gen_scale_nrpn(int gen, int nrpn); -int fluid_gen_init(fluid_gen_t* gen, fluid_channel_t* channel); - - -#endif /* _FLUID_GEN_H */ diff --git a/src/libs/fluidsynth/src/fluid_hash.c b/src/libs/fluidsynth/src/fluid_hash.c deleted file mode 100644 index 9094908afe..0000000000 --- a/src/libs/fluidsynth/src/fluid_hash.c +++ /dev/null @@ -1,388 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -/* - * MT safe - */ - -#include "fluidsynth_priv.h" -#include "fluid_hash.h" - - -#define HASH_TABLE_MIN_SIZE 7 -#define HASH_TABLE_MAX_SIZE 13845163 - - -typedef struct _fluid_hashnode_t fluid_hashnode_t; - -struct _fluid_hashnode_t { - char* key; - void* value; - int type; - fluid_hashnode_t *next; -}; - -static fluid_hashnode_t* new_fluid_hashnode(char* key, void* value, int type); -static void delete_fluid_hashnode(fluid_hashnode_t *hash_node, fluid_hash_delete_t del); -static void delete_fluid_hashnodes(fluid_hashnode_t *hash_node, fluid_hash_delete_t del); - -struct _fluid_hashtable_t { - unsigned int size; - unsigned int nnodes; - fluid_hashnode_t **nodes; - fluid_hash_delete_t del; -}; - -#define FLUID_HASHTABLE_RESIZE(hash_table) \ - if ((3 * hash_table->size <= hash_table->nnodes) \ - && (hash_table->size < HASH_TABLE_MAX_SIZE)) { \ - fluid_hashtable_resize(hash_table); \ - } - -static void fluid_hashtable_resize(fluid_hashtable_t *hash_table); -static fluid_hashnode_t** fluid_hashtable_lookup_node(fluid_hashtable_t *hash_table, char* key); - -/** - * new_fluid_hashtable: - * - * Creates a new #fluid_hashtable_t. - * - * Return value: a new #fluid_hashtable_t. - **/ -fluid_hashtable_t* -new_fluid_hashtable(fluid_hash_delete_t del) -{ - fluid_hashtable_t *hash_table; - unsigned int i; - - hash_table = FLUID_NEW(fluid_hashtable_t); - hash_table->size = HASH_TABLE_MIN_SIZE; - hash_table->nnodes = 0; - hash_table->nodes = FLUID_ARRAY(fluid_hashnode_t*, hash_table->size); - hash_table->del = del; - - for (i = 0; i < hash_table->size; i++) { - hash_table->nodes[i] = NULL; - } - - return hash_table; -} - -/** - * delete_fluid_hashtable: - * @hash_table: a #fluid_hashtable_t. - * - * Destroys the #fluid_hashtable_t. If keys and/or values are dynamically - * allocated, you should either free them first or create the #fluid_hashtable_t - * using fluid_hashtable_new_full(). In the latter case the destroy functions - * you supplied will be called on all keys and values before destroying - * the #fluid_hashtable_t. - **/ -void -delete_fluid_hashtable(fluid_hashtable_t *hash_table) -{ - unsigned int i; - - if (hash_table == NULL) { - return; - } - - for (i = 0; i < hash_table->size; i++) { - delete_fluid_hashnodes(hash_table->nodes[i], hash_table->del); - } - - FLUID_FREE(hash_table->nodes); - FLUID_FREE(hash_table); -} - - -static /*inline*/ fluid_hashnode_t** -fluid_hashtable_lookup_node (fluid_hashtable_t* hash_table, char* key) -{ - fluid_hashnode_t **node; - - node = &hash_table->nodes[fluid_str_hash(key) % hash_table->size]; - - while (*node && (FLUID_STRCMP((*node)->key, key) != 0)) { - node = &(*node)->next; - } - - return node; -} - -/** - * fluid_hashtable_lookup: - * @hash_table: a #fluid_hashtable_t. - * @key: the key to look up. - * - * Looks up a key in a #fluid_hashtable_t. - * - * Return value: the associated value, or %NULL if the key is not found. - **/ -int -fluid_hashtable_lookup(fluid_hashtable_t *hash_table, char* key, void** value, int* type) -{ - fluid_hashnode_t *node; - - node = *fluid_hashtable_lookup_node(hash_table, key); - - if (node) { - if (value) { - *value = node->value; - } - if (type) { - *type = node->type; - } - return 1; - } else { - return 0; - } -} - -/** - * fluid_hashtable_insert: - * @hash_table: a #fluid_hashtable_t. - * @key: a key to insert. - * @value: the value to associate with the key. - * - * Inserts a new key and value into a #fluid_hashtable_t. - * - * If the key already exists in the #fluid_hashtable_t its current value is replaced - * with the new value. If you supplied a @value_destroy_func when creating the - * #fluid_hashtable_t, the old value is freed using that function. If you supplied - * a @key_destroy_func when creating the #fluid_hashtable_t, the passed key is freed - * using that function. - **/ -void -fluid_hashtable_insert(fluid_hashtable_t *hash_table, char* key, void* value, int type) -{ - fluid_hashnode_t **node; - - node = fluid_hashtable_lookup_node(hash_table, key); - - if (*node) { - (*node)->value = value; - (*node)->type = type; - } else { - *node = new_fluid_hashnode(key, value, type); - hash_table->nnodes++; - FLUID_HASHTABLE_RESIZE(hash_table); - } -} - - -/** - * fluid_hashtable_replace: - * @hash_table: a #GHashTable. - * @key: a key to insert. - * @value: the value to associate with the key. - * - * Inserts a new key and value into a #GHashTable similar to - * fluid_hashtable_insert(). The difference is that if the key already exists - * in the #GHashTable, it gets replaced by the new key. If you supplied a - * @value_destroy_func when creating the #GHashTable, the old value is freed - * using that function. If you supplied a @key_destroy_func when creating the - * #GHashTable, the old key is freed using that function. - **/ -void -fluid_hashtable_replace(fluid_hashtable_t *hash_table, char* key, void* value, int type) -{ - fluid_hashnode_t **node; - - node = fluid_hashtable_lookup_node(hash_table, key); - - if (*node) { - if (hash_table->del) { - hash_table->del((*node)->value, (*node)->type); - } - (*node)->value = value; - - } else { - *node = new_fluid_hashnode(key, value, type); - hash_table->nnodes++; - FLUID_HASHTABLE_RESIZE(hash_table); - } -} - -/** - * fluid_hashtable_remove: - * @hash_table: a #fluid_hashtable_t. - * @key: the key to remove. - * - * Removes a key and its associated value from a #fluid_hashtable_t. - * - * If the #fluid_hashtable_t was created using fluid_hashtable_new_full(), the - * key and value are freed using the supplied destroy functions, otherwise - * you have to make sure that any dynamically allocated values are freed - * yourself. - * - * Return value: %TRUE if the key was found and removed from the #fluid_hashtable_t. - **/ -int -fluid_hashtable_remove (fluid_hashtable_t *hash_table, char* key) -{ - fluid_hashnode_t **node, *dest; - - node = fluid_hashtable_lookup_node(hash_table, key); - if (*node) { - dest = *node; - (*node) = dest->next; - delete_fluid_hashnode(dest, hash_table->del); - hash_table->nnodes--; - - FLUID_HASHTABLE_RESIZE (hash_table); - - return 1; - } - - return 0; -} - -/** - * fluid_hashtable_foreach: - * @hash_table: a #fluid_hashtable_t. - * @func: the function to call for each key/value pair. - * @user_data: user data to pass to the function. - * - * Calls the given function for each of the key/value pairs in the - * #fluid_hashtable_t. The function is passed the key and value of each - * pair, and the given @user_data parameter. The hash table may not - * be modified while iterating over it (you can't add/remove - * items). To remove all items matching a predicate, use - * fluid_hashtable_remove(). - **/ -void -fluid_hashtable_foreach(fluid_hashtable_t *hash_table, fluid_hash_iter_t func, void* data) -{ - fluid_hashnode_t *node = NULL; - unsigned int i; - - for (i = 0; i < hash_table->size; i++) { - for (node = hash_table->nodes[i]; node != NULL; node = node->next) { - (*func)(node->key, node->value, node->type, data); - } - } -} - -/** - * fluid_hashtable_size: - * @hash_table: a #fluid_hashtable_t. - * - * Returns the number of elements contained in the #fluid_hashtable_t. - * - * Return value: the number of key/value pairs in the #fluid_hashtable_t. - **/ -unsigned int -fluid_hashtable_size(fluid_hashtable_t *hash_table) -{ - return hash_table->nnodes; -} - -static void -fluid_hashtable_resize(fluid_hashtable_t *hash_table) -{ - fluid_hashnode_t **new_nodes; - fluid_hashnode_t *node; - fluid_hashnode_t *next; - unsigned int hash_val; - int new_size; - unsigned int i; - - new_size = 3 * hash_table->size + 1; - new_size = (new_size > HASH_TABLE_MAX_SIZE)? HASH_TABLE_MAX_SIZE : new_size; - -/* printf("%s: %d: resizing, new size = %d\n", __FILE__, __LINE__, new_size); */ - - new_nodes = FLUID_ARRAY(fluid_hashnode_t*, new_size); - FLUID_MEMSET(new_nodes, 0, new_size * sizeof(fluid_hashnode_t*)); - - for (i = 0; i < hash_table->size; i++) { - for (node = hash_table->nodes[i]; node; node = next) { - next = node->next; - hash_val = fluid_str_hash(node->key) % new_size; - node->next = new_nodes[hash_val]; - new_nodes[hash_val] = node; - } - } - - FLUID_FREE(hash_table->nodes); - hash_table->nodes = new_nodes; - hash_table->size = new_size; -} - -static fluid_hashnode_t* -new_fluid_hashnode(char* key, void* value, int type) -{ - fluid_hashnode_t *hash_node; - - hash_node = FLUID_NEW(fluid_hashnode_t); - - hash_node->key = FLUID_STRDUP(key); - hash_node->value = value; - hash_node->type = type; - hash_node->next = NULL; - - return hash_node; -} - -static void -delete_fluid_hashnode(fluid_hashnode_t *hash_node, fluid_hash_delete_t del) -{ - if (del) { - (*del)(hash_node->value, hash_node->type); - } - if (hash_node->key) { - FLUID_FREE(hash_node->key); - } - FLUID_FREE(hash_node); -} - -static void -delete_fluid_hashnodes(fluid_hashnode_t *hash_node, fluid_hash_delete_t del) -{ - while (hash_node) { - fluid_hashnode_t *next = hash_node->next; - delete_fluid_hashnode(hash_node, del); - hash_node = next; - } -} - - -/* 31 bit hash function */ -unsigned int -fluid_str_hash(char* key) -{ - char *p = key; - unsigned int h = *p; - - if (h) { - for (p += 1; *p != '\0'; p++) { - h = (h << 5) - h + *p; - } - } - - return h; -} diff --git a/src/libs/fluidsynth/src/fluid_hash.h b/src/libs/fluidsynth/src/fluid_hash.h deleted file mode 100644 index d2e8577eb5..0000000000 --- a/src/libs/fluidsynth/src/fluid_hash.h +++ /dev/null @@ -1,64 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -/* - * Demolished by Peter Hanappe [December 2002] - * - * - only string as key - * - stores additional type info - * - removed use of GLib types (gpointer, gint, ...) - * - reduced the number of API functions - * - changed names to fluid_hashtable_... - */ - -#ifndef _FLUID_HASH_H -#define _FLUID_HASH_H - - -typedef int (*fluid_hash_iter_t)(char* key, void* value, int type, void* data); -typedef void (*fluid_hash_delete_t)(void* value, int type); - -fluid_hashtable_t* new_fluid_hashtable(fluid_hash_delete_t delete); -void delete_fluid_hashtable(fluid_hashtable_t *hash_table); - -void fluid_hashtable_insert(fluid_hashtable_t *hash_table, char* key, void* value, int type); - -void fluid_hashtable_replace(fluid_hashtable_t *hash_table, char* key, void* value, int type); - -/* Returns non-zero if found, 0 if not found */ -int fluid_hashtable_lookup(fluid_hashtable_t *hash_table, char* key, void** value, int* type); - -/* Returns non-zero if removed, 0 if not removed */ -int fluid_hashtable_remove(fluid_hashtable_t *hash_table, char* key); - -void fluid_hashtable_foreach(fluid_hashtable_t *hashtable, fluid_hash_iter_t fun, void* data); - -unsigned int fluid_hashtable_size(fluid_hashtable_t *hash_table); - -unsigned int fluid_str_hash(char* v); - -#endif /* _FLUID_HASH_H */ - diff --git a/src/libs/fluidsynth/src/fluid_io.c b/src/libs/fluidsynth/src/fluid_io.c deleted file mode 100644 index 1c46d9d378..0000000000 --- a/src/libs/fluidsynth/src/fluid_io.c +++ /dev/null @@ -1,121 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - - -#include "fluidsynth_priv.h" -#include "fluid_io.h" - -#if WITH_READLINE -#include -#include -#endif - -int fluid_istream_gets(fluid_istream_t in, char* buf, int len); - -fluid_istream_t fluid_get_stdin() -{ -#ifdef MACOS9 - return 0; /* to be tested - Antoine 8/3/3 */ -#else - return STDIN_FILENO; -#endif -} - -fluid_ostream_t fluid_get_stdout() -{ -#ifdef MACOS9 - return 1; /* to be tested - Antoine 8/3/3 */ -#else - return STDOUT_FILENO; -#endif -} - -int fluid_istream_readline(fluid_istream_t in, char* prompt, char* buf, int len) -{ -#if WITH_READLINE - if (in == fluid_get_stdin()) { - char* line; - - line = readline(prompt); - if (line == NULL) { - return -1; - } - - snprintf(buf, len, "%s", line); - buf[len - 1] = 0; - - free(line); - return 1; - } else { - return fluid_istream_gets(in, buf, len); - } -#else - return fluid_istream_gets(in, buf, len); -#endif -} - -/* FIXME */ -int fluid_istream_gets(fluid_istream_t in, char* buf, int len) -{ - char c; - int n; - - buf[len - 1] = 0; - - while (--len > 0) { - n = read(in, &c, 1); - if (n == 0) { - *buf++ = 0; - return 0; - } - if (n < 0) { - return n; - } - if ((c == '\n') || (c == '\r')) { - *buf++ = 0; - return 1; - } - *buf++ = c; - } - - return -1; -} - - -int fluid_ostream_printf(fluid_ostream_t out, char* format, ...) -{ - char buf[4096]; - va_list args; - int len; - - va_start(args, format); - len = vsnprintf(buf, 4095, format, args); - va_end(args); - - if (len <= 0) { - printf("fluid_ostream_printf: buffer overflow"); - return -1; - } - - buf[4095] = 0; - -/* return write(out, buf, len); */ - return write(out, buf, strlen(buf)); -} diff --git a/src/libs/fluidsynth/src/fluid_io.h b/src/libs/fluidsynth/src/fluid_io.h deleted file mode 100644 index 95e1aaff64..0000000000 --- a/src/libs/fluidsynth/src/fluid_io.h +++ /dev/null @@ -1,42 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - - -#ifndef _FLUID_IO_H -#define _FLUID_IO_H - - -/** Read a line from the input stream. - - \returns 0 if end-of-stream, -1 if error, non zero otherwise -*/ -int fluid_istream_readline(fluid_istream_t in, char* prompt, char* buf, int len); - - -/** Read a line from the input stream. - - \returns The number of bytes written. If an error occured, -1 is - returned. -*/ -int fluid_ostream_printf(fluid_ostream_t out, char* format, ...); - - - -#endif /* _FLUID_IO_H */ diff --git a/src/libs/fluidsynth/src/fluid_ladspa.c b/src/libs/fluidsynth/src/fluid_ladspa.c deleted file mode 100644 index 57efa9be7a..0000000000 --- a/src/libs/fluidsynth/src/fluid_ladspa.c +++ /dev/null @@ -1,1118 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -/* This module: 3/2002 - * Author: Markus Nentwig, nentwig@users.sourceforge.net - */ - -#define PrintErrorMessage -1 - -#include "fluidsynth_priv.h" - -#ifdef LADSPA -#include - -/* Dynamic library functions */ -#include - -#include "fluid_ladspa.h" -#include "fluid_synth.h" -#include "fluid_io.h" - -/* Logging to stdout. */ -//#define L(x) x;printf("\n"); -#define L(x); - -fluid_LADSPA_FxUnit_t* new_fluid_LADSPA_FxUnit(fluid_synth_t* synth){ - fluid_LADSPA_FxUnit_t* FxUnit=FLUID_NEW(fluid_LADSPA_FxUnit_t); - assert(FxUnit); - assert(synth); - /* The default state is 'bypassed'. The Fx unit has to be turned on explicitly by the user. */ - /* Those settings have to be done in order to allow fluid_LADSPA_clean. */ - FxUnit->Bypass=fluid_LADSPA_Bypassed; - FxUnit->NumberNodes=0; - FxUnit->NumberPlugins=0; - FxUnit->NumberLibs=0; - FxUnit->NumberCommands=0; - FxUnit->NumberUserControlNodes=0; - FxUnit->synth=synth; - pthread_cond_init(&FxUnit->cond,NULL); - return FxUnit; -}; - -/* Purpose: - * Creates the system nodes to get data into and out of the Fx unit. - */ -void fluid_LADSPA_CreateSystemNodes(fluid_LADSPA_FxUnit_t* FxUnit){ - char str[99]; - int nr_input_nodes; - int nr_fx_input_nodes; - int nr_output_nodes; - int temp; - int i; - - /* Retrieve the number of synth / audio out / Fx send nodes */ - assert(fluid_settings_getint(FxUnit->synth->settings, "synth.audio-groups", &temp)); - nr_input_nodes=(int) temp; - printf("%i audio groups\n", nr_input_nodes); - - assert(fluid_settings_getint(FxUnit->synth->settings, "synth.audio-channels", &temp)); - nr_output_nodes=temp; - - assert(fluid_settings_getint(FxUnit->synth->settings, "synth.effects-channels", &temp)); - nr_fx_input_nodes=temp; - - /* Create regular input nodes (associated with audio groups) */ - for (i=0; i < nr_input_nodes; i++){ - sprintf(str, "in%i_L",(i+1)); - fluid_LADSPA_CreateNode(FxUnit, str, fluid_LADSPA_node_is_audio | fluid_LADSPA_node_is_source); - sprintf(str, "in%i_R",(i+1)); - fluid_LADSPA_CreateNode(FxUnit, str, fluid_LADSPA_node_is_audio | fluid_LADSPA_node_is_source); - }; - - /* Create effects send nodes (for example reverb, chorus send) */ - for (i=0; i < nr_fx_input_nodes; i++){ - sprintf(str, "send%i_L",(i+1)); - fluid_LADSPA_CreateNode(FxUnit, str, fluid_LADSPA_node_is_audio | fluid_LADSPA_node_is_source); - sprintf(str, "send%i_R",(i+1)); - fluid_LADSPA_CreateNode(FxUnit, str, fluid_LADSPA_node_is_audio | fluid_LADSPA_node_is_source); - }; - - /* Create output nodes (usually towards the sound card) */ - for (i=0; i < nr_input_nodes; i++){ - sprintf(str, "out%i_L",(i+1)); - fluid_LADSPA_CreateNode(FxUnit, str, fluid_LADSPA_node_is_audio | fluid_LADSPA_node_is_sink); - sprintf(str, "out%i_R",(i+1)); - fluid_LADSPA_CreateNode(FxUnit, str, fluid_LADSPA_node_is_audio | fluid_LADSPA_node_is_sink); - }; -}; - -/* Purpose: - * Creates predeclared nodes for control of the Fx unit during operation. - */ -void fluid_LADSPA_CreateUserControlNodes(fluid_LADSPA_FxUnit_t* FxUnit){ - int i; - fluid_LADSPA_Node_t* CurrentNode; - - for (i=0; iNumberUserControlNodes; i++){ - CurrentNode=fluid_LADSPA_CreateNode(FxUnit,FxUnit->UserControlNodeNames[i],fluid_LADSPA_node_is_control); - assert(CurrentNode); - CurrentNode->buf[0]=FxUnit->UserControlNodeValues[i]; - CurrentNode->InCount++; /* The constant counts as input */ - CurrentNode->flags=fluid_LADSPA_node_is_source | fluid_LADSPA_node_is_user_ctrl; /* It is a user control node */ - }; -}; - -/* Purpose: - * Returns the pointer to the shared library loaded using 'LibraryFilename' (if it has been loaded). - * Return NULL otherwise. - * If not: Clear Fx and abort. - */ -void * fluid_LADSPA_RetrieveSharedLibrary(fluid_LADSPA_FxUnit_t* FxUnit, char * LibraryFilename){ - void * CurrentLib=NULL; - int LibCount; - for (LibCount=0; LibCountNumberLibs; LibCount++){ - assert(FxUnit->ppvPluginLibNames[LibCount]); - if (FLUID_STRCMP(FxUnit->ppvPluginLibNames[LibCount],LibraryFilename)==0){ - CurrentLib=FxUnit->ppvPluginLibs[LibCount]; - }; - }; - return CurrentLib; -}; - -/* Purpose: - * Loads a shared LADSPA library. - * Return NULL, if failed. - * TODO: use LADSPA_PATH - */ -void * fluid_LADSPA_LoadSharedLibrary(fluid_LADSPA_FxUnit_t* FxUnit, char * LibraryFilename){ - void * LoadedLib; - assert(LibraryFilename); - LoadedLib=dlopen(LibraryFilename,RTLD_NOW); - if (!LoadedLib){ - return NULL; - }; - FxUnit->ppvPluginLibs[FxUnit->NumberLibs]=LoadedLib; - FxUnit->ppvPluginLibNames[FxUnit->NumberLibs]=FLUID_STRDUP(LibraryFilename); - FxUnit->NumberLibs++; - return LoadedLib; -}; - -/* Purpose: - * Retrieves a descriptor to the plugin labeled 'PluginLabel' from the shared library. - */ -const LADSPA_Descriptor * fluid_LADSPA_Retrieve_Plugin_Descriptor(void * CurrentLib, char * PluginLabel){ - LADSPA_Descriptor_Function pfDescriptorFunction; - unsigned long lPluginIndex=0; - const LADSPA_Descriptor * psDescriptor; - pfDescriptorFunction = (LADSPA_Descriptor_Function)dlsym(CurrentLib,"ladspa_descriptor"); - while (pfDescriptorFunction(lPluginIndex)){ - psDescriptor = pfDescriptorFunction(lPluginIndex); - if (FLUID_STRCMP(psDescriptor->Label, PluginLabel) == 0){ - return psDescriptor; - }; - lPluginIndex++; - }; - return NULL; -}; - -/* Purpose: - * Finds out, if 'PortName' starts with 'PluginPort'. - * Spaces and underscore mean the same. - * The comparison is not case sensitive. - * The result distinguishes between a full match (strings are equal), and a partial match (PortName starts with Plugin_Port, but is longer). - */ - -fluid_LADSPA_Stringmatch_t fluid_LADSPA_Check_SubString_Match(const char * Plugin_Port, const char * PortName){ - unsigned int CharCount; - char a; - char b; - for(CharCount=0; CharCount='a' && a <='z'){a-=32;} - if (b>='a' && b <='z'){b-=32;} - if (a == ' '){a='_';}; - if (b == ' '){b='_';}; - if ( a != b){ - return fluid_LADSPA_NoMatch; - }; - }; - if (FLUID_STRLEN(Plugin_Port) == FLUID_STRLEN(PortName)){ - return fluid_LADSPA_FullMatch; - }; - return fluid_LADSPA_PartialMatch; - -}; - -/* Purpose: - * Load the plugins added with 'ladspa_add' and then start the Fx unit. - */ - -int -fluid_LADSPA_handle_start(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out){ - fluid_LADSPA_FxUnit_t* FxUnit; - int CommandLineCount; - char * LibraryFilename; - char * PluginLabel; - char ** TokenSequence; - void * CurrentLib; - int NodeCount; //x - int IngoingSignalCount; // Count signals going into LADSPA Fx section - int OutgoingSignalCount; // Count signals going out of LADSPA Fx section - int ReturnVal=FLUID_OK; /* If warnings occur, this is set to -1. */ - char * LADSPA_Path = getenv("LADSPA_PATH"); - - L(fluid_ostream_printf(out,"ladspa_start: starting...")); - assert(synth); - FxUnit=synth->LADSPA_FxUnit; assert(FxUnit); - - /* When calling fluid_ladspastart, the Fx unit must be 'cleared' (no plugins, no libs, no nodes). Verify this here. */ - if (FxUnit->NumberPlugins || FxUnit->NumberLibs){ - fluid_ostream_printf(out, "***Error006***\n" - "Fx unit is currently in use!\n" - "Please run the ladspa_clear command before attempting to use ladspa_add!\n"); - /* In this case do _not_ clear the Fx unit. */ - return(PrintErrorMessage); - }; - if (!FxUnit->NumberCommands){ - fluid_ostream_printf(out, "***Error007***\n" - "Refusing to start the Fx unit without any plugin.\n" - "Use ladspa_add first!\n"); - fluid_LADSPA_clear(FxUnit); - return(PrintErrorMessage); - }; - - /* Create predefined nodes */ - L(fluid_ostream_printf(out,"ladspa_start: creating predefined nodes...")); - fluid_LADSPA_CreateSystemNodes(FxUnit); - - /* Create predeclared nodes, that will allow to control the Fx unit during operation */ - L(fluid_ostream_printf(out,"ladspa_start: creating user control nodes...")); - fluid_LADSPA_CreateUserControlNodes(FxUnit); - - L(fluid_ostream_printf(out,"ladspa_start: Processing command lines...")); - for (CommandLineCount=0; CommandLineCountNumberCommands; CommandLineCount++){ - int CurrentPlugin_PortConnected[FLUID_LADSPA_MaxTokens/3]; /* For example: 100 tokens corresponds to roughly 30 ports. */ - char LibFullPath[FLUID_LADSPA_MaxPathLength]; - const LADSPA_Descriptor * CurrentPluginDescriptor; - LADSPA_Handle CurrentPlugin; - unsigned long PortCount; - int TokenCount=0; - char * Search; - int HasASlash=0; - - if (FxUnit->NumberPlugins>=FLUID_LADSPA_MaxPlugins){ - fluid_ostream_printf(out, "***Error003***\n" - "Too many plugins at the same time (%i).\n" - "Change FLUID_LADSPA_MaxPlugins!\n", - FxUnit->NumberPlugins); - fluid_LADSPA_clear(FxUnit); - return(PrintErrorMessage); - }; - - L(fluid_ostream_printf(out,"Processing plugin nr. %i",FxUnit->NumberPlugins)); - - TokenSequence=FxUnit->LADSPA_Command_Sequence[CommandLineCount]; - assert(TokenSequence); - - /* Check, if the library is already loaded. If not, load. */ - LibraryFilename=TokenSequence[TokenCount++]; assert(LibraryFilename); - - L(fluid_ostream_printf(out,"Library name from ladspa_add: %s",LibraryFilename)); - /* A slash-free filename refers to the LADSPA_PATH directory. Add that path, if needed. */ - - - - /* Determine, if the library filename contains a slash. - * If no, try to retrieve the environment variable LADSPA_PATH. - * If that fails, signal error. - * Otherwise leave the filename as it is. - */; - - /* Determine, if the library name is just the filename, or a path (including a slash) */ - Search=LibraryFilename; - while (*Search != '\0') { - if ((*Search)== '/'){ - HasASlash=1; - }; - Search++; - }; - - if (!HasASlash){ - if (!LADSPA_Path){ - fluid_ostream_printf(out, "***Error018***\n" - "The library file name %s does not include a path.\n" - "The environment variable LADSPA_PATH is not set.\n" - "- Use an absolute path (i.e. /home/myself/mylib.so)\n" - "- For the current directory use ./mylib.so\n" - "- set the environment variable LADSPA_PATH (export LADSPA_PATH=/usr/lib/ladspa)\n" - "- depending on your shell, try 'setenv' instead of 'export'\n", - LibraryFilename); - fluid_LADSPA_clear(FxUnit); - return(PrintErrorMessage); - }; /* if no LADSPA_PATH */ - snprintf(LibFullPath,FLUID_LADSPA_MaxPathLength,"%s/%s",LADSPA_Path,LibraryFilename); - /* If no slash in filename */ - } else { - snprintf(LibFullPath,FLUID_LADSPA_MaxPathLength,"%s",LibraryFilename); - }; - - L(fluid_ostream_printf(out,"Full Library path name: %s",LibFullPath)); - - CurrentLib=fluid_LADSPA_RetrieveSharedLibrary(FxUnit, LibFullPath); - if (!CurrentLib){ - LADSPA_Descriptor_Function pfDescriptorFunction; - - L(fluid_ostream_printf(out,"Library %s not yet loaded. Loading.",LibFullPath)); - - if (FxUnit->NumberLibs>=FLUID_LADSPA_MaxLibs){ - fluid_ostream_printf(out, "***Error004***\n" - "Too many libraries open (%i)\n" - "Change FLUID_LADSPA_MaxLibs",FxUnit->NumberPlugins); - fluid_LADSPA_clear(FxUnit); - return(PrintErrorMessage); - }; - - /* Load a LADSPA plugin library and store it for future use.*/ - CurrentLib=fluid_LADSPA_LoadSharedLibrary(FxUnit, LibFullPath); - - if (!CurrentLib){ - fluid_ostream_printf(out, "***Error008***\n" - "Failed to load plugin library %s.", - LibraryFilename); - fluid_LADSPA_clear(FxUnit); - return(PrintErrorMessage); - }; - - - dlerror(); - pfDescriptorFunction = (LADSPA_Descriptor_Function)dlsym(CurrentLib,"ladspa_descriptor"); - if (!pfDescriptorFunction) { - const char * pcError = dlerror(); - if (!pcError) {pcError="Huh?! No error from lib!";}; - fluid_ostream_printf(out, "***Error015***\n" - "Unable to find ladspa_descriptor() function in plugin library file \"%s\": %s.\n" - "Are you sure this is a LADSPA plugin file?\n", - LibraryFilename, - pcError); - fluid_LADSPA_clear(FxUnit); - return(PrintErrorMessage); - }; - - L(fluid_ostream_printf(out,"Library loaded.")); - }; - - PluginLabel=TokenSequence[TokenCount++]; assert(PluginLabel); - L(fluid_ostream_printf(out,"Plugin Label from ladspa_add: %s",PluginLabel)); - /* Retrieve a 'plugin descriptor' from the library. */ - L(fluid_ostream_printf(out,"Looking for the plugin labeled %s",PluginLabel)); - - CurrentPluginDescriptor=fluid_LADSPA_Retrieve_Plugin_Descriptor(CurrentLib, PluginLabel); - - - /* Check, that the plugin was actually found.*/ - if (CurrentPluginDescriptor==NULL){ - fluid_ostream_printf(out, "***Error016***\n" - "Unable to find the plugin labeled \"%s\" in plugin library file \"%s\".\n" - "Hint: run analyzeplugin %s from the command line to get a list of valid plugin labels.\n", - PluginLabel, - LibraryFilename, - LibraryFilename); - fluid_LADSPA_clear(FxUnit); - return(PrintErrorMessage); - }; - - /* Create an instance of the plugin type from the descriptor */ - L(fluid_ostream_printf(out,"instantiating plugin %s",PluginLabel)); - CurrentPlugin=CurrentPluginDescriptor - ->instantiate(CurrentPluginDescriptor,44100); /* Sample rate hardcoded */ - assert(CurrentPlugin); - - /* The descriptor ("type of plugin") and the instance are stored for each plugin instantiation. - If one plugin type is instantiated several times, they will have the same descriptor, only - different instances.*/ - FxUnit->PluginDescriptorTable[FxUnit->NumberPlugins]=CurrentPluginDescriptor; - FxUnit->PluginInstanceTable[FxUnit->NumberPlugins]=CurrentPlugin; - - /* - * - * Wire up the inputs and outputs - * - */ - - /* List for checking, that each plugin port is exactly connected once */ - for (PortCount=0; PortCountPortCount; PortCount++){ - CurrentPlugin_PortConnected[PortCount]=0; - }; - - /* Note: There are three NULL tokens at the end. The last condition may be evaluated even if the first one already detects the end. */ - while (TokenSequence[TokenCount] && TokenSequence[TokenCount+1] && TokenSequence[TokenCount+2]){ - int CurrentPort_StringMatchCount; - LADSPA_PortDescriptor CurrentPort_Descriptor; - char * Plugin_Port=TokenSequence[TokenCount++]; - char * Direction=TokenSequence[TokenCount++]; - char * FLUID_Node=TokenSequence[TokenCount++]; - fluid_LADSPA_Node_t* Current_Node; - const char * PortName=NULL; - int CurrentPort_Index=-1; - fluid_LADSPA_Stringmatch_t StringMatchType=fluid_LADSPA_NoMatch; - fluid_LADSPA_Stringmatch_t CurrentPort_StringMatchType=fluid_LADSPA_NoMatch; - CurrentPort_StringMatchCount=0; - - L(fluid_ostream_printf(out,"Wiring %s %s %s",Plugin_Port, Direction, FLUID_Node)); - - /* Find the port number on the plugin, that belongs to "Plugin_Port". - * Match the identifier specified by the user against the first characters - * of the port name. - * - * If the given identifier matches several port names only partly, then the input is ambiguous, an error - * message results. - * - * Example: cmt.so, limit_peak: This plugin uses the labels - * - Output Envelope Attack (s) - * - Output Envelope Decay (s) - * - Output - * - * The user input 'Output' matches the first two labels partly, the third fully. This will be accepted. - * The user input 'Out' matches all three only partly, this results in an error message. - */ - - for (PortCount=0; PortCountPortCount; PortCount++){ - PortName=CurrentPluginDescriptor->PortNames[PortCount]; - - StringMatchType=fluid_LADSPA_Check_SubString_Match(Plugin_Port, PortName); - /* If a full-string match has been found earlier, reject all partial matches. */ - if (StringMatchType==fluid_LADSPA_FullMatch || - (StringMatchType==fluid_LADSPA_PartialMatch && CurrentPort_StringMatchType != fluid_LADSPA_FullMatch)){ - - if(StringMatchType==fluid_LADSPA_FullMatch && CurrentPort_StringMatchType==fluid_LADSPA_FullMatch){ - fluid_ostream_printf(out, "***Error027***\n" - "While processing plugin %s: The port label %s appears more than once!\n" - "This is an error in the plugin itself. Please correct it or use another plugin.",PluginLabel, Plugin_Port); - fluid_LADSPA_clear(FxUnit); - return(PrintErrorMessage); - }; - - CurrentPort_Index=PortCount; - CurrentPort_StringMatchType=StringMatchType; - CurrentPort_StringMatchCount++; - - }; /* if suitable match */ - }; /* For port count */ - - /* Several partial matches? Then the identifier is not unique. */ - if (CurrentPort_StringMatchCount > 1 && CurrentPort_StringMatchType == fluid_LADSPA_PartialMatch){ - fluid_ostream_printf(out, "***Error019***\n" - "While processing plugin %s: The identifier %s matches more than one plugin port.\n" - "Please use more letters for the port name. If needed, replace spaces with underscores (_).\n" - "This error will not occur, if you use the full name of a port.\n",PluginLabel, Plugin_Port); - fluid_LADSPA_clear(FxUnit); - return(PrintErrorMessage); - }; - - if (CurrentPort_Index<0){ - fluid_ostream_printf(out, "***Error017***\n" - "Unable to find port '%s' on plugin %s\n" - "Port names are:\n",Plugin_Port,PluginLabel); - for (PortCount=0; PortCountPortCount; PortCount++){ - printf("- `%s'\n",CurrentPluginDescriptor->PortNames[PortCount]); - }; - - fluid_LADSPA_clear(FxUnit); - return(PrintErrorMessage); - }; - CurrentPort_Descriptor=CurrentPluginDescriptor->PortDescriptors[CurrentPort_Index]; - assert(CurrentPort_Descriptor); - - /* Retrieve the node with the right name. */ - Current_Node=fluid_LADSPA_RetrieveNode(FxUnit,FLUID_Node); -#define PortIsAudio LADSPA_IS_PORT_AUDIO(CurrentPort_Descriptor) && !(LADSPA_IS_PORT_CONTROL(CurrentPort_Descriptor)) -#define PortIsControl LADSPA_IS_PORT_CONTROL(CurrentPort_Descriptor) && !(LADSPA_IS_PORT_AUDIO(CurrentPort_Descriptor)) - if (!Current_Node){ - /* Doesn't exist? Then create it. */ - if (FxUnit->NumberNodes>=FLUID_LADSPA_MaxNodes){ - fluid_ostream_printf(out, "***Error005***\n" - "Too many nodes (%i)\n" - "Change FLUID_LADSPA_MaxNodes",FxUnit->NumberNodes); - fluid_LADSPA_clear(FxUnit); - return(PrintErrorMessage); - }; - if (PortIsAudio){ - Current_Node=fluid_LADSPA_CreateNode(FxUnit,FLUID_Node,fluid_LADSPA_node_is_audio); - } else if (PortIsControl){ - Current_Node=fluid_LADSPA_CreateNode(FxUnit,FLUID_Node,fluid_LADSPA_node_is_control); - } else { - fluid_ostream_printf(out, "***Error025***\n" - "Plugin port number %i is neither input nor output!\n" - "This is an error in the plugin.\n" - "Please check plugin sourcecode.\n", - CurrentPort_Index); - fluid_LADSPA_clear(FxUnit); - return(PrintErrorMessage); - }; - }; - assert(Current_Node); - - /* - * - * Check flowgraph for some possible errors. - * - */ - - if (FLUID_STRCMP(Direction,"->")==0){ - /* Data from plugin to FLUID, into node - * - * *** Rule: **** - * A node may not have more than one data source.*/ - if (Current_Node->InCount !=0){ - fluid_ostream_printf(out, "***Error009***\n" - "Plugin %s tries to feed data from output %s into node %s, which is already connected to a data source.\n",PluginLabel,Plugin_Port,FLUID_Node); - fluid_LADSPA_clear(FxUnit); - return(PrintErrorMessage); - }; - Current_Node->InCount++; - } else if (FLUID_STRCMP(Direction,"<-")==0){ - /* Data from FLUID to plugin, out of node - * - * This check verifies the integrity of the flow graph: - * *** Rule *** - * The execution order of the plugins is the order, in which they are programmed. - * The plugins must be ordered so, that the input of a plugin is already computed at the time of its execution. - * If the user tries to read data out of a node that has not yet an input, then something is wrong.*/ - assert(Current_Node->InCount<=1); - if (Current_Node->InCount !=1){ - fluid_ostream_printf(out, "***Error010***\n" - "Plugin %s tries to read data through input %s from node %s.\n" - "But at this point there is no valid data at that node.\n" - "Please check the flowgraph and especially the execution order!\n",PluginLabel,Plugin_Port,FLUID_Node); - fluid_LADSPA_clear(FxUnit); - return(PrintErrorMessage); - }; - Current_Node->OutCount++; - } else { - fluid_ostream_printf(out, "***Error024***\n" - "Syntax error: Illegal `arrow' `%s', expecting -> or <-\n", - Direction); - fluid_LADSPA_clear(FxUnit); - return(PrintErrorMessage); - }; - - /* In any case, there must be a valid data source for the port at this time. */ - assert(Current_Node->InCount==1); - - /* Keep track on the number of connections to each port. - * This error occurs only, if an attempt is made to connect one port twice (i.e. ladspa_add libname pluginname port <- nodex port <- nodey) */ - if (CurrentPlugin_PortConnected[CurrentPort_Index]){ - fluid_ostream_printf(out, "***Error011***\n" - "Refusing to connect twice to port %s on plugin %s.\n",CurrentPluginDescriptor->PortNames[CurrentPort_Index], PluginLabel); - fluid_LADSPA_clear(FxUnit); - return(PrintErrorMessage); - }; - - /* - * - * Connect the port - * - */ - - L(fluid_ostream_printf(out,"Connecting %i",CurrentPort_Index)); - CurrentPluginDescriptor->connect_port - (CurrentPlugin, - CurrentPort_Index, - Current_Node->buf - ); - CurrentPlugin_PortConnected[CurrentPort_Index]++; - - }; /* While Tokensequence (more connections) */ - - /* - * - * Check for left-over tokens - * - */ - - if (TokenSequence[TokenCount]){ - char * T1="";char * T2="";char * T3=""; - if (TokenSequence[TokenCount]){T1=TokenSequence[TokenCount];}; - if (TokenSequence[TokenCount+1]){T2=TokenSequence[TokenCount+1];}; - if (TokenSequence[TokenCount+2]){T3=TokenSequence[TokenCount+2];}; - fluid_ostream_printf(out, "***Error012***\n" - "Leftover tokens: %s %s %s...\n",T1,T2,T3); - fluid_LADSPA_clear(FxUnit); - return(PrintErrorMessage); - }; - - /* - * - * Check, that all plugin ports are connected - * - */ - L(fluid_ostream_printf(out,"Checking left-over ports")); - assert(CurrentPluginDescriptor); - for (PortCount=0; PortCountPortCount; PortCount++){ - assert(CurrentPlugin_PortConnected[PortCount] <=1); - if (CurrentPlugin_PortConnected[PortCount] !=1){ - fluid_ostream_printf(out, "***Error013***\nPlugin: %s. Port %s is unconnected!\n",PluginLabel, CurrentPluginDescriptor->PortNames[PortCount]); - fluid_LADSPA_clear(FxUnit); - return(PrintErrorMessage); - }; - }; - - /* - * - *Run activate function on plugin, where possible - * - */ - - if (CurrentPluginDescriptor->activate !=NULL){ - CurrentPluginDescriptor->activate(CurrentPlugin); - }; - - FxUnit->NumberPlugins++; - }; /* For CommandLineCount: once for each new command (i.e. plugin instantiation request from user */ - - /* - * - * Further flow graph checks - * - */ - - L(fluid_ostream_printf(out,"Checking flow graph")); - - IngoingSignalCount=0; - OutgoingSignalCount=0; - - for (NodeCount=0; NodeCountNumberNodes; NodeCount++){ - fluid_LADSPA_Node_t* Current_Node; - Current_Node=FxUnit->Nodelist[NodeCount]; - assert(Current_Node); - if (Current_Node->flags & fluid_LADSPA_node_is_source){ - IngoingSignalCount+=Current_Node->OutCount; - } else if (Current_Node->flags & fluid_LADSPA_node_is_sink){ - OutgoingSignalCount+=Current_Node->InCount; - } else { - - /* A node without any input doesn't make sense. - * The flow graph check aborts with an error. This case cannot happen. - */ - if (Current_Node->InCount==0 && !Current_Node->flags & fluid_LADSPA_node_is_dummy){ /* There can only be one warning at a time. */ - fluid_ostream_printf(out, "***Warning020***" - "No input into node %s.\n" - "Use '_' as first char in nodename to suppress this warning.\n" - "Hint: Check for typos in the node name.\n",Current_Node->Name); - /* A warning can also be printed as an error message (check fluid_cmd.c). The only difference between - the return values -1 and 0 is, that -1 prints the result. */ - }; - ReturnVal=PrintErrorMessage; - }; - - /* A node without any output doesn't make sense. */ - if (Current_Node->OutCount==0 && !Current_Node->flags & fluid_LADSPA_node_is_dummy){ - fluid_ostream_printf(out, "***Warning021***\n" - "No output from node %s.\n" - "Use '_' as first char in nodename to suppress this warning.\n" - "Hint: Check for typos in the node name.\n",Current_Node->Name); - ReturnVal=PrintErrorMessage; - }; - /* A free-flying node simply cannot happen. */ - assert(Current_Node->OutCount+Current_Node->InCount); - }; /* Foreach node */ - - /* Issue a warning, if no signal goes into the Fx section. */ - if (IngoingSignalCount==0){ - fluid_ostream_printf(out, "***Warning022***\n" - "You have not connected anything to the synthesizer section (in1_L, in1_R).\n"); - ReturnVal=PrintErrorMessage; - }; - - /* Issue a warning, if no signal leaves the Fx section. */ - if (OutgoingSignalCount==0){ - fluid_ostream_printf(out, "***Warning023***\n" - "You have not connected anything to the output (out1_L, out1_R).\n"); - }; - - /* Finally turn on the Fx unit. */ - FxUnit->Bypass=fluid_LADSPA_Active; - L(fluid_ostream_printf(out,"LADSPA Init OK")); - return(ReturnVal); -}; - -void -fluid_LADSPA_run(fluid_LADSPA_FxUnit_t* FxUnit, fluid_real_t* left_buf[], fluid_real_t* right_buf[], fluid_real_t* fx_left_buf[], fluid_real_t* fx_right_buf[]){ - int i; - int ii; - - - int nr_audio_channels; - int nr_fx_sends; - int nr_groups; - int byte_size = FLUID_BUFSIZE * sizeof(fluid_real_t); - char str[99]; - fluid_LADSPA_Node_t* n; - int temp; - - /* Retrieve the number of synth / audio out / Fx send nodes */ - assert(fluid_settings_getint(FxUnit->synth->settings, "synth.audio-groups", &temp)); - nr_groups=(int) temp; - - assert(fluid_settings_getint(FxUnit->synth->settings, "synth.audio-channels", &temp)); - nr_audio_channels=temp; - - assert(fluid_settings_getint(FxUnit->synth->settings, "synth.effects-channels", &temp)); - nr_fx_sends=temp; - - /* Fixme: Retrieving nodes via names is inefficient - * (but not that bad, because the interesting nodes are always at the start of the list). - */ - - /* Input and output are processed via the same buffers. Therefore the effect is bypassed by just skipping everything else. */ - if (FxUnit->Bypass==fluid_LADSPA_Bypassed){ - return; - }; - - if (FxUnit->Bypass==fluid_LADSPA_BypassRequest){ - FxUnit->Bypass=fluid_LADSPA_Bypassed; - pthread_mutex_lock(&FxUnit->mutex); - pthread_cond_broadcast(&FxUnit->cond); - pthread_mutex_unlock(&FxUnit->mutex); - L(printf("LADSPA_Run: Command line asked for bypass of Fx unit. Acknowledged.")); - return; - }; - - assert(FxUnit); - - /* Clear the output buffers, if they are not connected anywhere */ - for (ii=0; ii < nr_audio_channels; ii++){ - - sprintf(str, "out%i_L",(ii+1)); - n=fluid_LADSPA_RetrieveNode(FxUnit, str); assert(n); - if (n->InCount == 0){ -/* printf("Output node %s is not connected -> clear buffer\n", str); */ - FLUID_MEMSET(n->buf, 0, byte_size); - }; - - sprintf(str, "out%i_R",(ii+1)); - n=fluid_LADSPA_RetrieveNode(FxUnit, str); assert(n); - if (n->InCount == 0){ -/* printf("Output node %s is not connected -> clear buffer\n", str); */ - FLUID_MEMSET(n->buf, 0, byte_size); - }; - }; - - /* Prepare the incoming data: - * Convert fluid_real_t data type to LADSPA_Data type */ - for (ii=0; ii < nr_groups; ii++){ - fluid_real_t* src_buf=left_buf[ii]; - sprintf(str, "in%i_L",(ii+1)); - n=fluid_LADSPA_RetrieveNode(FxUnit, str); assert(n); - - assert(FLUID_BUFSIZE % 2 == 0); - - /* Add a very small high frequency signal. This avoids denormal number problems. */ - for (i=0; ibuf[i]=(LADSPA_Data)(src_buf[i]+1.e-15); - i++; - n->buf[i]=(LADSPA_Data)(src_buf[i]); - i++; - }; - - src_buf=right_buf[ii]; - sprintf(str, "in%i_R",(ii+1)); - n=fluid_LADSPA_RetrieveNode(FxUnit, str); assert(n); - - /* Add a very small high frequency signal. This avoids denormal number problems. */ - for (i=0; ibuf[i]=(LADSPA_Data)(src_buf[i]+1.e-15); - i++; - n->buf[i]=(LADSPA_Data)(src_buf[i]); - i++; - }; - }; - - /* Effect send paths */ - for (ii=0; ii < nr_fx_sends; ii++){ - sprintf(str, "send%i_L",(ii+1)); - n=fluid_LADSPA_RetrieveNode(FxUnit, str); assert(n); - for (i=0; ibuf[i]=(LADSPA_Data)(fx_left_buf[ii][i]); - }; - - sprintf(str, "send%i_R",(ii+1)); - n=fluid_LADSPA_RetrieveNode(FxUnit, str); assert(n); - for (i=0; ibuf[i]=(LADSPA_Data)(fx_right_buf[ii][i]); - }; - }; - - /* Run each plugin on a block of data. - * The execution order has been checked during setup.*/ - for (i=0; iNumberPlugins; i++){ - FxUnit->PluginDescriptorTable[i]->run(FxUnit->PluginInstanceTable[i],FLUID_BUFSIZE); - }; - - /* Copy the data from the output nodes back to the synth. */ - for (ii=0; ii < nr_audio_channels; ii++){ - fluid_real_t* dest_buf=left_buf[ii]; - sprintf(str, "out%i_L",(ii+1)); - n=fluid_LADSPA_RetrieveNode(FxUnit, str); assert(n); - for (i=0; ibuf[i]; - }; - - dest_buf=right_buf[ii]; - sprintf(str, "out%i_R",(ii+1)); - n=fluid_LADSPA_RetrieveNode(FxUnit, str); assert(n); - for (i=0; ibuf[i]; - }; - }; -}; - -fluid_LADSPA_Node_t* -fluid_LADSPA_RetrieveNode(fluid_LADSPA_FxUnit_t* FxUnit, char * Name){ - int i=0; - assert(FxUnit);assert(Name); - for (i=0; iNumberNodes; i++){ - assert(FxUnit->Nodelist[i]); - if (FLUID_STRCMP(FxUnit->Nodelist[i]->Name,Name)==0){ - return FxUnit->Nodelist[i]; - }; - }; - return NULL; -}; - - -/* Purpose: - * Creates a new node from the node name given by the user. - */ -fluid_LADSPA_Node_t* -fluid_LADSPA_CreateNode(fluid_LADSPA_FxUnit_t* FxUnit, char * Name, int flags){ - int Dummy=0; - fluid_LADSPA_Node_t* NewNode; - assert(FxUnit); - assert(Name); -// printf("Flags is %i\n",flags); - L(printf("Create node: %s",Name)); - if (FxUnit->NumberNodes>=FLUID_LADSPA_MaxNodes){ - printf( "***Error014***\n" - "Too many nodes (%i)\n" - "Change FLUID_LADSPA_MaxNodes.\n",FxUnit->NumberNodes); - fluid_LADSPA_clear(FxUnit); - return NULL; - }; - - /* Don't allow node names, which start with -, 0..9 */ - if (Name[0] == '-' || (Name[0]>='0' && Name[0]<='9')){ - printf( "***Error026***\n" - "The node name %s starts with a digit / minus sign!\n" - "Please use a letter to start a node name.\n" - "A constant node is created by using `#' as first character,\n" - "for example #-2.5.\n", - Name); - fluid_LADSPA_clear(FxUnit); - return NULL; - }; - - /* A nodename starting with "_" is a possible dummy node, which may (but need not) act as a data sink or source (dummy node). */ - if (Name[0] == ' '){ /* ??? Should be '_' ??? */ - Dummy=1; - }; - NewNode=FLUID_NEW(fluid_LADSPA_Node_t);assert(NewNode); - if (flags && fluid_LADSPA_node_is_audio){ - /* Audio node contains buffer. */ - NewNode->buf=FLUID_ARRAY(LADSPA_Data, (FLUID_BUFSIZE));assert(NewNode->buf); - /* It is permitted to use a dummy node without input. Therefore clear all node buffers at startup. */ - FLUID_MEMSET(NewNode->buf, 0, (FLUID_BUFSIZE*sizeof(LADSPA_Data))); - } else if (flags & fluid_LADSPA_node_is_control){ - /* Control node contains single value. */ - NewNode->buf=FLUID_ARRAY(LADSPA_Data, 1);assert(NewNode->buf); - } else { - assert(0); - }; - NewNode->Name=FLUID_STRDUP(Name);assert(NewNode->Name); - if (Dummy){ - flags |= fluid_LADSPA_node_is_dummy; - }; - NewNode->InCount=0; - NewNode->OutCount=0; - NewNode->flags=flags; - - /* A nodename starting with "#" means that the node holds a constant value. */ - if (NewNode->Name[0] == '#'){ - assert(flags & fluid_LADSPA_node_is_control); - /* Skip the first character => +1 */ - NewNode->buf[0]=(LADSPA_Data)atof(NewNode->Name+1); - NewNode->InCount++; - }; - if (flags & fluid_LADSPA_node_is_source){ - NewNode->InCount++; -// printf("****************************** Source!\n"); - } else if (flags & fluid_LADSPA_node_is_sink){ - NewNode->OutCount++; - }; - FxUnit->Nodelist[FxUnit->NumberNodes++]=NewNode; - - L(printf("Node %s created.",Name)); - return NewNode; -}; - -void fluid_LADSPA_clear(fluid_LADSPA_FxUnit_t* FxUnit){ - int i; - int ii; - L(printf("ladspa_clear")); - assert(FxUnit); - - if (FxUnit->Bypass==fluid_LADSPA_Active){ - L(printf("clear: Requesting bypass from synthesis thread")); - /* Bypass the Fx unit before anything else. - * Reason: Not a good idea to release plugins, while another thread runs them. - */ - FxUnit->Bypass=fluid_LADSPA_BypassRequest; - pthread_mutex_lock(&FxUnit->mutex); - pthread_cond_wait(&FxUnit->cond,&FxUnit->mutex); - pthread_mutex_unlock(&FxUnit->mutex); - L(printf("clear: Synthesis thread has switched to bypass.")); - } else { - L(printf("clear: Fx unit was already bypassed. No action needed.")); - }; - - L(printf("Clear all user control node declarations")); - for (i=0; iNumberUserControlNodes; i++){ - FLUID_FREE(FxUnit->UserControlNodeNames[i]); - }; - FxUnit->NumberUserControlNodes=0; - - L(printf("Clear all plugin instances")); - for (i=0; iNumberPlugins; i++){ - assert(FxUnit->PluginDescriptorTable[i]); - assert(FxUnit->PluginInstanceTable[i]); - - /* Run deactivate function on plugin, if possible */ - if (FxUnit->PluginDescriptorTable[i]->deactivate){ - FxUnit->PluginDescriptorTable[i]->deactivate(FxUnit->PluginInstanceTable[i]); - }; - FxUnit->PluginDescriptorTable[i]->cleanup(FxUnit->PluginInstanceTable[i]); - }; - FxUnit->NumberPlugins=0; - - L(printf("Clear all nodes")); /* Only after removing plugins! */ - for (i=0; iNumberNodes; i++){ - FLUID_FREE(FxUnit->Nodelist[i]->buf); - FLUID_FREE(FxUnit->Nodelist[i]); - }; - FxUnit->NumberNodes=0; - - - L(printf("Clear all plugin libraries")); - for (i=0; iNumberLibs; i++){ - - assert(FxUnit->ppvPluginLibs[i]); - dlclose(FxUnit->ppvPluginLibs[i]); - - assert(FxUnit->ppvPluginLibNames[i]); - FLUID_FREE(FxUnit->ppvPluginLibNames[i]); - }; - FxUnit->NumberLibs=0; - - L(printf("Clear all command lines")); - for (i=0; iNumberCommands;i++){ - ii=0; - assert(FxUnit->LADSPA_Command_Sequence[i]); - while (FxUnit->LADSPA_Command_Sequence[i][ii]){ - FLUID_FREE(FxUnit->LADSPA_Command_Sequence[i][ii]); - ii++; - }; - FLUID_FREE(FxUnit->LADSPA_Command_Sequence[i]); - }; - FxUnit->NumberCommands=0; -}; - -int fluid_LADSPA_handle_add(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out){ - int i; - char * Token; - char ** CommandLine; - fluid_LADSPA_FxUnit_t* FxUnit; - assert(synth); - FxUnit=synth->LADSPA_FxUnit; assert(FxUnit); - if (ac>=FLUID_LADSPA_MaxTokens){ - /* Can't be tested. fluidsynth limits the number of tokens. */ - printf("***Error001***\n" - "Too many ports.\nChange FLUID_LADSPA_MaxTokens!"); - fluid_LADSPA_clear(FxUnit); - return(PrintErrorMessage); - }; - if (ac<2){ - printf("***Error002***\n" - "ladspa_add needs at least two arguments - libname and plugin name!"); - fluid_LADSPA_clear(FxUnit); - return(PrintErrorMessage); - }; - - if (FxUnit->NumberCommands>=FLUID_LADSPA_MaxPlugins){ - printf("***Error032***\n" - "Too many plugins.\nChange FLUID_LADSPA_MaxPlugins!"); - fluid_LADSPA_clear(FxUnit); - return(PrintErrorMessage); - }; - - /* CommandLine (token sequence) is terminated with NULL. - * Add two more NULLs, so that a chunk of three tokens can be checked later without risk.*/ - - CommandLine=FLUID_ARRAY(char*, (ac+3));assert(CommandLine); - for (i=0; iLADSPA_Command_Sequence[FxUnit->NumberCommands]=CommandLine; - FxUnit->NumberCommands++; - return(FLUID_OK); -}; - -int fluid_LADSPA_handle_declnode(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out){ - int i; - char * Token; - char ** CommandLine; - char * NodeName; - fluid_real_t NodeValue; - fluid_LADSPA_FxUnit_t* FxUnit; - assert(synth); - FxUnit=synth->LADSPA_FxUnit; assert(FxUnit); - - if (ac<2){ - printf("***Error028***\n" - "ladspa_declnode needs two arguments - node name and value!\n"); - fluid_LADSPA_clear(FxUnit); - return(PrintErrorMessage); - }; - - if (FxUnit->NumberUserControlNodes>=FLUID_LADSPA_MaxNodes){ - printf("***Error033***\n" - "Too many user-control nodes.\nChange FLUID_LADSPA_MaxNodes!"); - fluid_LADSPA_clear(FxUnit); - return(PrintErrorMessage); - }; - - NodeName=FLUID_STRDUP(av[0]); assert(NodeName); - NodeValue=atof(av[1]); - FxUnit->UserControlNodeNames[FxUnit->NumberUserControlNodes]=NodeName; - FxUnit->UserControlNodeValues[FxUnit->NumberUserControlNodes]=NodeValue; - FxUnit->NumberUserControlNodes++; - return(FLUID_OK); -}; -int fluid_LADSPA_handle_setnode(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out){ - int i; - char * Token; - char * NodeName; - fluid_real_t NodeValue; - fluid_LADSPA_FxUnit_t* FxUnit; - fluid_LADSPA_Node_t* CurrentNode; - assert(synth); - FxUnit=synth->LADSPA_FxUnit; assert(FxUnit); - - if (ac!=2){ - printf("***Error029***\n" - "ladspa_setnode needs two arguments - node name and value!\n"); - /* Do not clear the Fx unit (no fluid_LADSPA_clear). */ - return(PrintErrorMessage); - }; - - NodeName=av[0]; assert(NodeName); - NodeValue=atof(av[1]); - - CurrentNode=fluid_LADSPA_RetrieveNode(FxUnit,NodeName); - if (!CurrentNode){ - printf("***Error030***\n" - "The node %s was not found. Please use the full name of a node, that was\n" - "previously declared with ladspa_declnode.\n",NodeName); - /* Do not clear the Fx unit (no fluid_LADSPA_clear). */ - return(PrintErrorMessage); - }; - if (!(CurrentNode->flags & fluid_LADSPA_node_is_user_ctrl)){ - printf("***Error031***\n" - "The node %s is an ordinary control node.\n" - "Only user control nodes can be modified with ladspa_setnode.\n",NodeName); - /* Do not clear the Fx unit (no fluid_LADSPA_clear). */ - return(PrintErrorMessage); - }; - L(printf("ladspa_setnode: Assigning value %f",NodeValue)); - CurrentNode->buf[0]=NodeValue; - return(FLUID_OK); -}; - -int fluid_LADSPA_handle_clear(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out){ - fluid_LADSPA_FxUnit_t* FxUnit; - assert(synth); - FxUnit=synth->LADSPA_FxUnit; assert(FxUnit); - fluid_LADSPA_clear(FxUnit); - return(FLUID_OK); -}; - -void fluid_LADSPA_shutdown(fluid_LADSPA_FxUnit_t* FxUnit){ - /* The synthesis thread is not running anymore. - * Set the bypass switch, so that fluid_LADSPA_clear can proceed.*/ - FxUnit->Bypass=fluid_LADSPA_Bypassed; - fluid_LADSPA_clear(FxUnit); - pthread_cond_destroy(&FxUnit->cond); /* pro forma */ -}; -#endif /*LADSPA*/ diff --git a/src/libs/fluidsynth/src/fluid_ladspa.h b/src/libs/fluidsynth/src/fluid_ladspa.h deleted file mode 100644 index 45706a228a..0000000000 --- a/src/libs/fluidsynth/src/fluid_ladspa.h +++ /dev/null @@ -1,240 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -/* Author: Markus Nentwig, nentwig@users.sourceforge.net - */ - - -#ifndef _FLUID_LADSPA_H -#define _FLUID_LADSPA_H - -/*************************************************************** - * - * INCLUDES - */ - -#include "fluidsynth_priv.h" - -#ifdef LADSPA -#include "fluid_list.h" -#include -#include - -/*************************************************************** - * - * DEFINES - */ - -/* How many different plugin libraries may be used at the same time? */ -#define FLUID_LADSPA_MaxLibs 100 -/* How many plugin instances may be used at the same time? */ -#define FLUID_LADSPA_MaxPlugins 100 -/* How many nodes are allowed? */ -#define FLUID_LADSPA_MaxNodes 100 -/* How many tokens are allowed in one command line? (for example 152 => max. 50 port plugin allowed) */ -#define FLUID_LADSPA_MaxTokens 152 -/* What is the maximum path length? */ -#define FLUID_LADSPA_MaxPathLength 512 -/*************************************************************** - * - * ENUM - */ - -typedef enum { - fluid_LADSPA_NoMatch, - fluid_LADSPA_PartialMatch, - fluid_LADSPA_FullMatch -} fluid_LADSPA_Stringmatch_t; - -/* Bypass state of the Fx unit */ -typedef enum { - fluid_LADSPA_Active, - fluid_LADSPA_Bypassed, - fluid_LADSPA_BypassRequest -} fluid_LADSPA_BypassState; - -typedef enum { - fluid_LADSPA_node_is_source=1, - fluid_LADSPA_node_is_sink=2, - fluid_LADSPA_node_is_audio=4, - fluid_LADSPA_node_is_control=8, - fluid_LADSPA_node_is_dummy=16, - fluid_LADSPA_node_is_user_ctrl=32 -} fluid_LADSPA_nodeflags; - -/* fluid_LADSPA_Node_t - * An internal node of the Fx unit. - * A 'node' is the 'glue' that connects several LADSPA plugins. - * Basically it's a real-valued variable (control node) or a real-valued buffer (audio node). - */ -typedef struct { - LADSPA_Data * buf; /*Either the buffer (Audio node) or a single control value (Control node)*/ - char * Name; /* Unique identifier*/ - int InCount; /* How many sources feed into this node? (0 or 1) */ - int OutCount; /* How many other elements take data out of this node? */ - int flags; -} fluid_LADSPA_Node_t; - -/* - * fluid_LADSPA_Fx_t - * Fx unit using LADSPA. - * This includes a number of LADSPA plugins, their libraries, nodes etc. - * The Fx unit connects its input to Fluidsynth and its output to the soundcard. - */ -typedef struct { - /* LADSPA-plugins are in shared libraries (for example aw.so). - * Pointers to them are stored here. A library is uniquely identified through - * its filename (full path).*/ - fluid_synth_t* synth; - - int NumberLibs; - void * ppvPluginLibs[FLUID_LADSPA_MaxLibs]; - char * ppvPluginLibNames[FLUID_LADSPA_MaxLibs]; - - /*List of plugins (descriptor and instance) - * A LADSPA plugin descriptor points to the code, which is executed, when a plugin is run. - * The plugin instance is given as a parameter, when calling. - */ - int NumberPlugins; - const LADSPA_Descriptor * PluginDescriptorTable[FLUID_LADSPA_MaxPlugins]; - LADSPA_Handle * PluginInstanceTable[FLUID_LADSPA_MaxPlugins]; - - /* List of nodes */ - int NumberNodes; - fluid_LADSPA_Node_t * Nodelist[FLUID_LADSPA_MaxNodes]; - - /* List of Command lines - * During the setup phase, each ladspa_add command creates one command sequence. For example: - * ./aw.so alienwah_stereo Input <- Master_L_Synth Output -> Master_R_Synth Parameter <- #42.0 - * Those lists are stored in LADSPA_Command_Sequence. - * One command line results in one plugin => size MaxPlugins. - */ - int NumberCommands; - char ** LADSPA_Command_Sequence[FLUID_LADSPA_MaxPlugins]; - - /* User control nodes - * A user control node is declared at any time before the ladspa_start command. - * It acts as a constant node, but it has a name and can be changed with the ladspa_nodeset command. */ - int NumberUserControlNodes; - char * UserControlNodeNames[FLUID_LADSPA_MaxNodes]; - fluid_real_t UserControlNodeValues[FLUID_LADSPA_MaxNodes]; - - /* Bypass switch - * If set, the LADSPA Fx unit does not touch the signal.*/ - fluid_LADSPA_BypassState Bypass; - - /* Communication between the 'command line' process and the synthesis process. - * A possible conflict situation arises, when fluid_clear is called, and starts to destroy - * the plugins. But the synthesis thread still processes plugins at the same time. The consequences are ugly. - * Therefore ladspa_clear waits for acknowledgement from the synthesis thread, that the Fx unit is bypassed. - * 'cond' is used for the communication, the mutex is required for changing the condition. - */ - pthread_cond_t cond; - pthread_mutex_t mutex; -} fluid_LADSPA_FxUnit_t; - -/* - * misc - */ - -/* Purpose: - * Creates a new Fx unit in bypass mode with default settings. - * It is ready for further calls (add, clear, start). - */ -fluid_LADSPA_FxUnit_t* new_fluid_LADSPA_FxUnit(fluid_synth_t* synth); - -/* Purpose: - * Applies the master gain (from command line option --gain or gain command). - * Processes one block of sound data (generated from the synthesizer) through - * the LADSPA Fx unit. - * Acknowledges a bypass request. - */ -void fluid_LADSPA_run(fluid_LADSPA_FxUnit_t* Fx_unit, fluid_real_t* left_buf[], fluid_real_t* right_buf[], fluid_real_t* fx_left_buf[], fluid_real_t* fx_right_buf[]); - -/* Purpose: - * Returns the node belonging to Name or NULL, if not found - */ -fluid_LADSPA_Node_t* fluid_LADSPA_RetrieveNode(fluid_LADSPA_FxUnit_t* FxUnit, char * Name); - -/* Purpose: - * Creates a new node with the given characteristics. - */ -fluid_LADSPA_Node_t* fluid_LADSPA_CreateNode(fluid_LADSPA_FxUnit_t* FxUnit, char * Name, int flags); - -/* Purpose: - * - Resets LADSPA Fx unit to bypass. - * - Removes all plugins from the reverb unit. - * - Releases all libraries. - * Note: It would be more efficient to keep the libraries. But then the user would have to restart fluidsynth each time - * a plugin is recompiled. - */ -void fluid_LADSPA_clear(fluid_LADSPA_FxUnit_t* FxUnit); - -/* Purpose: - * Frees all memory and shuts down the Fx block. - * The synthesis thread must be stopped, when calling. - */ -void fluid_LADSPA_shutdown(fluid_LADSPA_FxUnit_t* FxUnit); - - - -/* - * fluid_handle_LADSPA_XXX - * Those functions are called from fluid_cmd, when a command is entered on the command line. - */ - -/* Purpose: - * - Resets LADSPA Fx unit to bypass. - * - Removes all plugins from the reverb unit. - * - Releases all libraries. - * Note: It would be more efficient to keep the libraries. But then the user would have to restart fluidsynth each time - * a plugin is recompiled. - */ -int fluid_LADSPA_handle_clear(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); - -/* Purpose: - * Loads the plugins added with 'ladspa_add' and then start the Fx unit. - * Internal processes: - * - load the LADSPA plugin libraries - * - instantiate the plugins - * - connect the plugins - * - set the bypass switch to 'not bypassed' - */ -int fluid_LADSPA_handle_start(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); - -/* Purpose: - * Adds one plugin into the list of the LADSPA Fx unit. - * This is only allowed, while the Fx block is in 'bypass' state (after clear). - */ -int fluid_LADSPA_handle_add(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); - -/* Purpose: - * Declares a user control node and a value; for further processing in ladspa_start. - */ -int fluid_LADSPA_handle_declnode(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); - -/* Purpose: - * Assigns a value to the a user control node - */ -int fluid_LADSPA_handle_setnode(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); - -#endif /* LADSPA */ - -#endif /* _FLUID_LADSPA_H */ diff --git a/src/libs/fluidsynth/src/fluid_lash.c b/src/libs/fluidsynth/src/fluid_lash.c deleted file mode 100644 index 0f3c55f284..0000000000 --- a/src/libs/fluidsynth/src/fluid_lash.c +++ /dev/null @@ -1,300 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ -#include "fluid_lash.h" -#include "fluid_synth.h" - -#include /* for usleep() */ -#include -#include -#include -#include -#include - -static void fluid_lash_save (fluid_synth_t * synth); -static void fluid_lash_load (fluid_synth_t * synth, const char * filename); -static void *fluid_lash_run (void * data); - -/* - * lash client - this symbol needs to be in the library else - * all clients would need a fluid_lash_client symbol. - */ -#ifdef HAVE_LASH -lash_client_t * fluid_lash_client; -#else -cca_client_t * fluid_lash_client; -#endif - -static pthread_t fluid_lash_thread; - - -#ifdef HAVE_LASH - -fluid_lash_args_t * -fluid_lash_extract_args (int * pargc, char *** pargv) -{ - return lash_extract_args (pargc, pargv); -} - -int -fluid_lash_connect (fluid_lash_args_t * args) -{ - fluid_lash_client = lash_init (args, PACKAGE, LASH_Config_Data_Set | LASH_Terminal, LASH_PROTOCOL (2,0)); - return fluid_lash_client && lash_enabled (fluid_lash_client); -} - -void -fluid_lash_create_thread (fluid_synth_t * synth) -{ - pthread_create (&fluid_lash_thread, NULL, fluid_lash_run, synth); -} - -static void -fluid_lash_save (fluid_synth_t * synth) -{ - int i; - int sfcount; - fluid_sfont_t * sfont; - lash_config_t * config; - char num[32]; - - sfcount = fluid_synth_sfcount (synth); - - config = lash_config_new (); - lash_config_set_key (config, "soundfont count"); - lash_config_set_value_int (config, sfcount); - lash_send_config (fluid_lash_client, config); - - for (i = sfcount - 1; i >= 0; i--) - { - sfont = fluid_synth_get_sfont (synth, i); - config = lash_config_new (); - - sprintf (num, "%d", i); - - lash_config_set_key (config, num); - lash_config_set_value_string (config, sfont->get_name (sfont)); - - lash_send_config (fluid_lash_client, config); - } -} - -static void -fluid_lash_load (fluid_synth_t * synth, const char * filename) -{ - fluid_synth_sfload (synth, filename, 1); -} - -static void * -fluid_lash_run (void * data) -{ - lash_event_t * event; - lash_config_t * config; - fluid_synth_t * synth; - int done = 0; - int err; - int pending_restores = 0; - - synth = (fluid_synth_t *) data; - - while (!done) - { - while ( (event = lash_get_event (fluid_lash_client)) ) - { - switch (lash_event_get_type (event)) - { - case LASH_Save_Data_Set: - fluid_lash_save (synth); - lash_send_event (fluid_lash_client, event); - break; - case LASH_Restore_Data_Set: - lash_event_destroy (event); - break; - case LASH_Quit: - err = kill (getpid(), SIGQUIT); - if (err) - fprintf (stderr, "%s: error sending signal: %s", - __FUNCTION__, strerror (errno)); - lash_event_destroy (event); - done = 1; - break; - case LASH_Server_Lost: - lash_event_destroy (event); - done = 1; - break; - default: - fprintf (stderr, "Recieved unknown LASH event of type %d\n", lash_event_get_type (event)); - lash_event_destroy (event); - break; - } - } - - while ( (config = lash_get_config (fluid_lash_client)) ) - { - if (strcmp (lash_config_get_key (config), "soundfont count") == 0) - pending_restores = lash_config_get_value_int (config); - else - { - fluid_lash_load (synth, lash_config_get_value_string (config)); - pending_restores--; - } - lash_config_destroy (config); - - if (!pending_restores) - { - event = lash_event_new_with_type (LASH_Restore_Data_Set); - lash_send_event (fluid_lash_client, event); - } - } - - usleep (10000); - } - - return NULL; -} - - -#else /* depricated LADCCA support, will remove someday */ - - -fluid_lash_args_t * -fluid_lash_extract_args (int * pargc, char *** pargv) -{ - return cca_extract_args (pargc, pargv); -} - -int -fluid_lash_connect (fluid_lash_args_t * args) -{ - fluid_lash_client = cca_init (args, PACKAGE, CCA_Config_Data_Set | CCA_Terminal, CCA_PROTOCOL (2,0)); - return fluid_lash_client && cca_enabled (fluid_lash_client); -} - -void -fluid_lash_create_thread (fluid_synth_t * synth) -{ - pthread_create (&fluid_lash_thread, NULL, fluid_lash_run, synth); -} - -static void -fluid_lash_save (fluid_synth_t * synth) -{ - int i; - int sfcount; - fluid_sfont_t * sfont; - cca_config_t * config; - char num[32]; - - sfcount = fluid_synth_sfcount (synth); - - config = cca_config_new (); - cca_config_set_key (config, "soundfont count"); - cca_config_set_value_int (config, sfcount); - cca_send_config (fluid_lash_client, config); - - for (i = sfcount - 1; i >= 0; i--) - { - sfont = fluid_synth_get_sfont (synth, i); - config = cca_config_new (); - - sprintf (num, "%d", i); - - cca_config_set_key (config, num); - cca_config_set_value_string (config, sfont->get_name (sfont)); - - cca_send_config (fluid_lash_client, config); - } -} - -static void -fluid_lash_load (fluid_synth_t * synth, const char * filename) -{ - fluid_synth_sfload (synth, filename, 1); -} - -/* LADCCA thread */ -static void * -fluid_lash_run (void * data) -{ - cca_event_t * event; - cca_config_t * config; - fluid_synth_t * synth; - int done = 0; - int err; - int pending_restores = 0; - - synth = (fluid_synth_t *) data; - - while (!done) - { - while ( (event = cca_get_event (fluid_lash_client)) ) - { - switch (cca_event_get_type (event)) - { - case CCA_Save_Data_Set: - fluid_lash_save (synth); - cca_send_event (fluid_lash_client, event); - break; - case CCA_Restore_Data_Set: - cca_event_destroy (event); - break; - case CCA_Quit: - err = kill (getpid(), SIGQUIT); - if (err) - fprintf (stderr, "%s: error sending signal: %s", - __FUNCTION__, strerror (errno)); - cca_event_destroy (event); - done = 1; - break; - case CCA_Server_Lost: - cca_event_destroy (event); - done = 1; - break; - default: - fprintf (stderr, "Recieved unknown LADCCA event of type %d\n", cca_event_get_type (event)); - cca_event_destroy (event); - break; - } - } - - while ( (config = cca_get_config (fluid_lash_client)) ) - { - if (strcmp (cca_config_get_key (config), "soundfont count") == 0) - pending_restores = cca_config_get_value_int (config); - else - { - fluid_lash_load (synth, cca_config_get_value_string (config)); - pending_restores--; - } - cca_config_destroy (config); - - if (!pending_restores) - { - event = cca_event_new_with_type (CCA_Restore_Data_Set); - cca_send_event (fluid_lash_client, event); - } - } - - usleep (10000); - } - - return NULL; -} - -#endif /* #if HAVE_LASH #else */ diff --git a/src/libs/fluidsynth/src/fluid_lash.h b/src/libs/fluidsynth/src/fluid_lash.h deleted file mode 100644 index 125283c051..0000000000 --- a/src/libs/fluidsynth/src/fluid_lash.h +++ /dev/null @@ -1,53 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#if defined(HAVE_LASH) || defined(HAVE_LADCCA) - -#include "fluid_synth.h" - -#define LASH_ENABLED 1 - -#ifdef HAVE_LASH - -#include -extern lash_client_t * fluid_lash_client; -#define fluid_lash_args_t lash_args_t -#define fluid_lash_alsa_client_id lash_alsa_client_id -#define fluid_lash_jack_client_name lash_jack_client_name - -#else /* old depricated LADCCA support which will be removed someday */ - -#include -extern cca_client_t * fluid_lash_client; -#define fluid_lash_args_t cca_args_t -#define fluid_lash_alsa_client_id cca_alsa_client_id -#define fluid_lash_jack_client_name cca_jack_client_name - -#endif - - -fluid_lash_args_t *fluid_lash_extract_args (int * pargc, char *** pargv); -int fluid_lash_connect (fluid_lash_args_t * args); -void fluid_lash_create_thread (fluid_synth_t * synth); - -#endif /* defined(HAVE_LASH) || defined(HAVE_LADCCA) */ diff --git a/src/libs/fluidsynth/src/fluid_list.c b/src/libs/fluidsynth/src/fluid_list.c deleted file mode 100644 index 4d1e64fd5f..0000000000 --- a/src/libs/fluidsynth/src/fluid_list.c +++ /dev/null @@ -1,257 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* - * Modified by the GLib Team and others 1997-1999. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - - - -#include "fluid_list.h" - - -fluid_list_t* -new_fluid_list(void) -{ - fluid_list_t* list; - list = (fluid_list_t*) FLUID_MALLOC(sizeof(fluid_list_t)); - list->data = NULL; - list->next = NULL; - return list; -} - -void -delete_fluid_list(fluid_list_t *list) -{ - fluid_list_t *next; - while (list) { - next = list->next; - FLUID_FREE(list); - list = next; - } -} - -void -delete1_fluid_list(fluid_list_t *list) -{ - if (list) { - FLUID_FREE(list); - } -} - -fluid_list_t* -fluid_list_append(fluid_list_t *list, void* data) -{ - fluid_list_t *new_list; - fluid_list_t *last; - - new_list = new_fluid_list(); - new_list->data = data; - - if (list) - { - last = fluid_list_last(list); - /* g_assert (last != NULL); */ - last->next = new_list; - - return list; - } - else - return new_list; -} - -fluid_list_t* -fluid_list_prepend(fluid_list_t *list, void* data) -{ - fluid_list_t *new_list; - - new_list = new_fluid_list(); - new_list->data = data; - new_list->next = list; - - return new_list; -} - -fluid_list_t* -fluid_list_nth(fluid_list_t *list, int n) -{ - while ((n-- > 0) && list) { - list = list->next; - } - - return list; -} - -fluid_list_t* -fluid_list_remove(fluid_list_t *list, void* data) -{ - fluid_list_t *tmp; - fluid_list_t *prev; - - prev = NULL; - tmp = list; - - while (tmp) { - if (tmp->data == data) { - if (prev) { - prev->next = tmp->next; - } - if (list == tmp) { - list = list->next; - } - tmp->next = NULL; - delete_fluid_list(tmp); - - break; - } - - prev = tmp; - tmp = tmp->next; - } - - return list; -} - -fluid_list_t* -fluid_list_remove_link(fluid_list_t *list, fluid_list_t *link) -{ - fluid_list_t *tmp; - fluid_list_t *prev; - - prev = NULL; - tmp = list; - - while (tmp) { - if (tmp == link) { - if (prev) { - prev->next = tmp->next; - } - if (list == tmp) { - list = list->next; - } - tmp->next = NULL; - break; - } - - prev = tmp; - tmp = tmp->next; - } - - return list; -} - -static fluid_list_t* -fluid_list_sort_merge(fluid_list_t *l1, fluid_list_t *l2, fluid_compare_func_t compare_func) -{ - fluid_list_t list, *l; - - l = &list; - - while (l1 && l2) { - if (compare_func(l1->data,l2->data) < 0) { - l = l->next = l1; - l1 = l1->next; - } else { - l = l->next = l2; - l2 = l2->next; - } - } - l->next= l1 ? l1 : l2; - - return list.next; -} - -fluid_list_t* -fluid_list_sort(fluid_list_t *list, fluid_compare_func_t compare_func) -{ - fluid_list_t *l1, *l2; - - if (!list) { - return NULL; - } - if (!list->next) { - return list; - } - - l1 = list; - l2 = list->next; - - while ((l2 = l2->next) != NULL) { - if ((l2 = l2->next) == NULL) - break; - l1=l1->next; - } - l2 = l1->next; - l1->next = NULL; - - return fluid_list_sort_merge(fluid_list_sort(list, compare_func), - fluid_list_sort(l2, compare_func), - compare_func); -} - - -fluid_list_t* -fluid_list_last(fluid_list_t *list) -{ - if (list) { - while (list->next) - list = list->next; - } - - return list; -} - -int -fluid_list_size(fluid_list_t *list) -{ - int n = 0; - while (list) { - n++; - list = list->next; - } - return n; -} - -fluid_list_t* fluid_list_insert_at(fluid_list_t *list, int n, void* data) -{ - fluid_list_t *new_list; - fluid_list_t *cur; - fluid_list_t *prev = NULL; - - new_list = new_fluid_list(); - new_list->data = data; - - cur = list; - while ((n-- > 0) && cur) { - prev = cur; - cur = cur->next; - } - - new_list->next = cur; - - if (prev) { - prev->next = new_list; - return list; - } else { - return new_list; - } -} diff --git a/src/libs/fluidsynth/src/fluid_list.h b/src/libs/fluidsynth/src/fluid_list.h deleted file mode 100644 index 6d5779bf41..0000000000 --- a/src/libs/fluidsynth/src/fluid_list.h +++ /dev/null @@ -1,61 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef _FLUID_LIST_H -#define _FLUID_LIST_H - -#include "fluidsynth_priv.h" - -/* - * - * Lists - * - * A sound font loader has to pack the data from the .SF2 file into - * list structures of this type. - * - */ - -typedef struct _fluid_list_t fluid_list_t; - -typedef int (*fluid_compare_func_t)(void* a, void* b); - -struct _fluid_list_t -{ - void* data; - fluid_list_t *next; -}; - -fluid_list_t* new_fluid_list(void); -void delete_fluid_list(fluid_list_t *list); -void delete1_fluid_list(fluid_list_t *list); -fluid_list_t* fluid_list_sort(fluid_list_t *list, fluid_compare_func_t compare_func); -fluid_list_t* fluid_list_append(fluid_list_t *list, void* data); -fluid_list_t* fluid_list_prepend(fluid_list_t *list, void* data); -fluid_list_t* fluid_list_remove(fluid_list_t *list, void* data); -fluid_list_t* fluid_list_remove_link(fluid_list_t *list, fluid_list_t *llink); -fluid_list_t* fluid_list_nth(fluid_list_t *list, int n); -fluid_list_t* fluid_list_last(fluid_list_t *list); -fluid_list_t* fluid_list_insert_at(fluid_list_t *list, int n, void* data); -int fluid_list_size(fluid_list_t *list); - -#define fluid_list_next(slist) ((slist) ? (((fluid_list_t *)(slist))->next) : NULL) -#define fluid_list_get(slist) ((slist) ? ((slist)->data) : NULL) - - -#endif /* _FLUID_LIST_H */ diff --git a/src/libs/fluidsynth/src/fluid_mdriver.c b/src/libs/fluidsynth/src/fluid_mdriver.c deleted file mode 100644 index 7ce5c217e6..0000000000 --- a/src/libs/fluidsynth/src/fluid_mdriver.c +++ /dev/null @@ -1,235 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#include "fluid_mdriver.h" -#include "fluid_settings.h" - - -/* ALSA */ -#if ALSA_SUPPORT -fluid_midi_driver_t* new_fluid_alsa_rawmidi_driver(fluid_settings_t* settings, - handle_midi_event_func_t handler, - void* event_handler_data); -int delete_fluid_alsa_rawmidi_driver(fluid_midi_driver_t* p); -void fluid_alsa_rawmidi_driver_settings(fluid_settings_t* settings); - -fluid_midi_driver_t* new_fluid_alsa_seq_driver(fluid_settings_t* settings, - handle_midi_event_func_t handler, - void* event_handler_data); -int delete_fluid_alsa_seq_driver(fluid_midi_driver_t* p); -void fluid_alsa_seq_driver_settings(fluid_settings_t* settings); -#endif - -/* JACK */ -#if JACK_SUPPORT -void fluid_jack_midi_driver_settings (fluid_settings_t *settings); -fluid_midi_driver_t *new_fluid_jack_midi_driver (fluid_settings_t *settings, - handle_midi_event_func_t handler, - void *data); -int delete_fluid_jack_midi_driver(fluid_midi_driver_t *p); -#endif - -/* OSS */ -#if OSS_SUPPORT -fluid_midi_driver_t* new_fluid_oss_midi_driver(fluid_settings_t* settings, - handle_midi_event_func_t handler, - void* event_handler_data); -int delete_fluid_oss_midi_driver(fluid_midi_driver_t* p); -void fluid_oss_midi_driver_settings(fluid_settings_t* settings); -#endif - -/* Windows MIDI service */ -#if WINMIDI_SUPPORT -fluid_midi_driver_t* new_fluid_winmidi_driver(fluid_settings_t* settings, - handle_midi_event_func_t handler, - void* event_handler_data); -int delete_fluid_winmidi_driver(fluid_midi_driver_t* p); -void fluid_winmidi_midi_driver_settings(fluid_settings_t* settings); -#endif - -/* definitions for the MidiShare driver */ -#if MIDISHARE_SUPPORT -fluid_midi_driver_t* new_fluid_midishare_midi_driver(fluid_settings_t* settings, - void* event_handler_data, - handle_midi_event_func_t handler); -int delete_fluid_midishare_midi_driver(fluid_midi_driver_t* p); -#endif - -/* definitions for the CoreMidi driver */ -#if COREMIDI_SUPPORT -fluid_midi_driver_t* new_fluid_coremidi_driver(fluid_settings_t* settings, - void* event_handler_data, - handle_midi_event_func_t handler); -int delete_fluid_coremidi_driver(fluid_midi_driver_t* p); -void fluid_coremidi_driver_settings(fluid_settings_t* settings); -#endif - - -/* - * fluid_mdriver_definition - */ -struct fluid_mdriver_definition_t { - char* name; - fluid_midi_driver_t* (*new)(fluid_settings_t* settings, - handle_midi_event_func_t event_handler, - void* event_handler_data); - int (*free)(fluid_midi_driver_t* p); - void (*settings)(fluid_settings_t* settings); -}; - - -struct fluid_mdriver_definition_t fluid_midi_drivers[] = { -#if JACK_SUPPORT - { "jack", - new_fluid_jack_midi_driver, - delete_fluid_jack_midi_driver, - fluid_jack_midi_driver_settings }, -#endif -#if OSS_SUPPORT - { "oss", - new_fluid_oss_midi_driver, - delete_fluid_oss_midi_driver, - fluid_oss_midi_driver_settings }, -#endif -#if ALSA_SUPPORT - { "alsa_raw", - new_fluid_alsa_rawmidi_driver, - delete_fluid_alsa_rawmidi_driver, - fluid_alsa_rawmidi_driver_settings }, - { "alsa_seq", - new_fluid_alsa_seq_driver, - delete_fluid_alsa_seq_driver, - fluid_alsa_seq_driver_settings }, -#endif -#if WINMIDI_SUPPORT - { "winmidi", - new_fluid_winmidi_driver, - delete_fluid_winmidi_driver, - fluid_winmidi_midi_driver_settings }, -#endif -#if MIDISHARE_SUPPORT - { "midishare", - new_fluid_midishare_midi_driver, - delete_fluid_midishare_midi_driver, - NULL }, -#endif -#if COREMIDI_SUPPORT - { "coremidi", - new_fluid_coremidi_driver, - delete_fluid_coremidi_driver, - fluid_coremidi_driver_settings }, -#endif - { NULL, NULL, NULL, NULL } -}; - - - -void fluid_midi_driver_settings(fluid_settings_t* settings) -{ - int i; - - /* Set the default driver */ -#if ALSA_SUPPORT - fluid_settings_register_str(settings, "midi.driver", "alsa_seq", 0, NULL, NULL); -#elif JACK_SUPPORT - fluid_settings_register_str(settings, "midi.driver", "jack", 0, NULL, NULL); -#elif OSS_SUPPORT - fluid_settings_register_str(settings, "midi.driver", "oss", 0, NULL, NULL); -#elif WINMIDI_SUPPORT - fluid_settings_register_str(settings, "midi.driver", "winmidi", 0, NULL, NULL); -#elif MIDISHARE_SUPPORT - fluid_settings_register_str(settings, "midi.driver", "midishare", 0, NULL, NULL); -#elif COREMIDI_SUPPORT - fluid_settings_register_str(settings, "midi.driver", "coremidi", 0, NULL, NULL); -#else - fluid_settings_register_str(settings, "midi.driver", "", 0, NULL, NULL); -#endif - - /* Add all drivers to the list of options */ -#if ALSA_SUPPORT - fluid_settings_add_option(settings, "midi.driver", "alsa_seq"); - fluid_settings_add_option(settings, "midi.driver", "alsa_raw"); -#endif -#if JACK_SUPPORT - fluid_settings_add_option(settings, "midi.driver", "jack"); -#endif -#if OSS_SUPPORT - fluid_settings_add_option(settings, "midi.driver", "oss"); -#endif -#if WINMIDI_SUPPORT - fluid_settings_add_option(settings, "midi.driver", "winmidi"); -#endif -#if MIDISHARE_SUPPORT - fluid_settings_add_option(settings, "midi.driver", "midishare"); -#endif -#if COREMIDI_SUPPORT - fluid_settings_add_option(settings, "midi.driver", "coremidi"); -#endif - - for (i = 0; fluid_midi_drivers[i].name != NULL; i++) { - if (fluid_midi_drivers[i].settings != NULL) { - fluid_midi_drivers[i].settings(settings); - } - } -} - - -/** - * Create a new MIDI driver instance. - * @param settings Settings used to configure new MIDI driver. - * @param handler MIDI handler callback (for example: fluid_midi_router_handle_midi_event() - * for MIDI router) - * @param event_handler_data Caller defined data to pass to 'handler' - * @return New MIDI driver instance or NULL on error - */ -fluid_midi_driver_t* new_fluid_midi_driver(fluid_settings_t* settings, handle_midi_event_func_t handler, void* event_handler_data) -{ - int i; - fluid_midi_driver_t* driver = NULL; - for (i = 0; fluid_midi_drivers[i].name != NULL; i++) { - if (fluid_settings_str_equal(settings, "midi.driver", fluid_midi_drivers[i].name)) { - FLUID_LOG(FLUID_DBG, "Using '%s' midi driver", fluid_midi_drivers[i].name); - driver = fluid_midi_drivers[i].new(settings, handler, event_handler_data); - if (driver) { - driver->name = fluid_midi_drivers[i].name; - } - return driver; - } - } - - FLUID_LOG(FLUID_ERR, "Couldn't find the requested midi driver"); - return NULL; -} - -/** - * Delete a MIDI driver instance. - * @param driver MIDI driver to delete - */ -void delete_fluid_midi_driver(fluid_midi_driver_t* driver) -{ - int i; - - for (i = 0; fluid_midi_drivers[i].name != NULL; i++) { - if (fluid_midi_drivers[i].name == driver->name) { - fluid_midi_drivers[i].free(driver); - return; - } - } -} diff --git a/src/libs/fluidsynth/src/fluid_mdriver.h b/src/libs/fluidsynth/src/fluid_mdriver.h deleted file mode 100644 index f366efc453..0000000000 --- a/src/libs/fluidsynth/src/fluid_mdriver.h +++ /dev/null @@ -1,42 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#ifndef _FLUID_MDRIVER_H -#define _FLUID_MDRIVER_H - -#include "fluidsynth_priv.h" - -void fluid_midi_driver_settings(fluid_settings_t* settings); - - -/* - * fluid_midi_driver_t - */ - -struct _fluid_midi_driver_t -{ - char* name; - handle_midi_event_func_t handler; - void* data; -}; - - - -#endif /* _FLUID_AUDRIVER_H */ diff --git a/src/libs/fluidsynth/src/fluid_midi.c b/src/libs/fluidsynth/src/fluid_midi.c deleted file mode 100644 index 31105a5d29..0000000000 --- a/src/libs/fluidsynth/src/fluid_midi.c +++ /dev/null @@ -1,1616 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#include "fluid_midi.h" -#include "fluid_sys.h" -#include "fluid_synth.h" -#include "fluid_settings.h" - -/* all outgoing user messages are stored in a global text buffer */ -#define MIDI_MESSAGE_LENGTH 1024 -char midi_message_buffer[MIDI_MESSAGE_LENGTH]; - - -/* Taken from Nagano Daisuke's USB-MIDI driver */ - -static int remains_f0f6[] = { - 0, /** 0xF0 **/ - 2, /** 0XF1 **/ - 3, /** 0XF2 **/ - 2, /** 0XF3 **/ - 2, /** 0XF4 (Undefined by MIDI Spec, and subject to change) **/ - 2, /** 0XF5 (Undefined by MIDI Spec, and subject to change) **/ - 1 /** 0XF6 **/ -}; - -static int remains_80e0[] = { - 3, /** 0x8X Note Off **/ - 3, /** 0x9X Note On **/ - 3, /** 0xAX Poly-key pressure **/ - 3, /** 0xBX Control Change **/ - 2, /** 0xCX Program Change **/ - 2, /** 0xDX Channel pressure **/ - 3 /** 0xEX PitchBend Change **/ -}; - - -/*************************************************************** - * - * MIDIFILE - */ - -/** - * Open a MIDI file and return a new MIDI file handle. - * @internal - * @param filename Path of file to open. - * @return New MIDI file handle or NULL on error. - */ -fluid_midi_file* new_fluid_midi_file(char* filename) -{ - fluid_midi_file* mf; - - mf = FLUID_NEW(fluid_midi_file); - if (mf == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - FLUID_MEMSET(mf, 0, sizeof(fluid_midi_file)); - - mf->c = -1; - mf->running_status = -1; - mf->fp = FLUID_FOPEN(filename, "rb"); - - if (mf->fp == NULL) { - FLUID_LOG(FLUID_ERR, "Couldn't open the MIDI file"); - FLUID_FREE(mf); - return NULL; - } - - if (fluid_midi_file_read_mthd(mf) != FLUID_OK) { - FLUID_FREE(mf); - return NULL; - } - return mf; -} - -/** - * Delete a MIDI file handle. - * @internal - * @param mf MIDI file handle to close and free. - */ -void delete_fluid_midi_file(fluid_midi_file* mf) -{ - if (mf == NULL) { - return; - } - if (mf->fp != NULL) { - FLUID_FCLOSE(mf->fp); - } - FLUID_FREE(mf); - return; -} - -/* - * Get the next byte in a MIDI file. - */ -int fluid_midi_file_getc(fluid_midi_file* mf) -{ - unsigned char c; - int n; - if (mf->c >= 0) { - c = mf->c; - mf->c = -1; - } else { - n = FLUID_FREAD(&c, 1, 1, mf->fp); - mf->trackpos++; - } - return (int) c; -} - -/* - * fluid_midi_file_push - */ -int fluid_midi_file_push(fluid_midi_file* mf, int c) -{ - mf->c = c; - return FLUID_OK; -} - -/* - * fluid_midi_file_read - */ -int fluid_midi_file_read(fluid_midi_file* mf, void* buf, int len) -{ - int num = FLUID_FREAD(buf, 1, len, mf->fp); - mf->trackpos += num; -#if DEBUG - if (num != len) { - FLUID_LOG(FLUID_DBG, "Coulnd't read the requested number of bytes"); - } -#endif - return (num != len)? FLUID_FAILED : FLUID_OK; -} - -/* - * fluid_midi_file_skip - */ -int fluid_midi_file_skip(fluid_midi_file* mf, int skip) -{ - int err = FLUID_FSEEK(mf->fp, skip, SEEK_CUR); - if (err) { - FLUID_LOG(FLUID_ERR, "Failed to seek position in file"); - return FLUID_FAILED; - } - return FLUID_OK; -} - -/* - * fluid_midi_file_read_mthd - */ -int fluid_midi_file_read_mthd(fluid_midi_file* mf) -{ - char mthd[15]; - if (fluid_midi_file_read(mf, mthd, 14) != FLUID_OK) { - return FLUID_FAILED; - } - if ((FLUID_STRNCMP(mthd, "MThd", 4) != 0) || (mthd[7] != 6) || (mthd[9] > 2)) { - FLUID_LOG(FLUID_ERR, "Doesn't look like a MIDI file: invalid MThd header"); - return FLUID_FAILED; - } - mf->type = mthd[9]; - mf->ntracks = (unsigned) mthd[11]; - mf->ntracks += (unsigned int) (mthd[10]) << 16; - if((mthd[12]) < 0){ - mf->uses_smpte = 1; - mf->smpte_fps = -mthd[12]; - mf->smpte_res = (unsigned) mthd[13]; - FLUID_LOG(FLUID_ERR, "File uses SMPTE timing -- Not implemented yet"); - return FLUID_FAILED; - } else { - mf->uses_smpte = 0; - mf->division = (mthd[12] << 8) | (mthd[13] & 0xff); - FLUID_LOG(FLUID_DBG, "Division=%d", mf->division); - } - return FLUID_OK; -} - -/* - * fluid_midi_file_load_tracks - */ -int fluid_midi_file_load_tracks(fluid_midi_file* mf, fluid_player_t* player) -{ - int i; - for (i = 0; i < mf->ntracks; i++) { - if (fluid_midi_file_read_track(mf, player, i) != FLUID_OK) { - return FLUID_FAILED; - } - } - return FLUID_OK; -} - -/* - * fluid_isasciistring - */ -int fluid_isasciistring(char* s) -{ - int i; - int len = (int) FLUID_STRLEN(s); - for (i = 0; i < len; i++) { - if (!fluid_isascii(s[i])) { - return 0; - } - } - return 1; -} - -/* - * fluid_getlength - */ -long fluid_getlength(unsigned char *s) -{ - long i = 0; - i = s[3] | (s[2]<<8) | (s[1]<<16) | (s[0]<<24); - return i; -} - -/* - * fluid_midi_file_read_tracklen - */ -int fluid_midi_file_read_tracklen(fluid_midi_file* mf) -{ - unsigned char length[5]; - if (fluid_midi_file_read(mf, length, 4) != FLUID_OK) { - return FLUID_FAILED; - } - mf->tracklen = fluid_getlength(length); - mf->trackpos = 0; - mf->eot = 0; - return FLUID_OK; -} - -/* - * fluid_midi_file_eot - */ -int fluid_midi_file_eot(fluid_midi_file* mf) -{ -#if DEBUG - if (mf->trackpos > mf->tracklen) { - printf("track overrun: %d > %d\n", mf->trackpos, mf->tracklen); - } -#endif - return mf->eot || (mf->trackpos >= mf->tracklen); -} - -/* - * fluid_midi_file_read_track - */ -int fluid_midi_file_read_track(fluid_midi_file* mf, fluid_player_t* player, int num) -{ - fluid_track_t* track; - unsigned char id[5], length[5]; - int found_track = 0; - int skip; - - if (fluid_midi_file_read(mf, id, 4) != FLUID_OK) { - return FLUID_FAILED; - } - id[4]='\0'; - mf->dtime = 0; - - while (!found_track){ - - if (fluid_isasciistring((char*) id) == 0) { - FLUID_LOG(FLUID_ERR, "An non-ascii track header found, currupt file"); - return FLUID_FAILED; - - } else if (strcmp((char*) id, "MTrk") == 0) { - - found_track = 1; - - if (fluid_midi_file_read_tracklen(mf) != FLUID_OK) { - return FLUID_FAILED; - } - - track = new_fluid_track(num); - if (track == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return FLUID_FAILED; - } - - while (!fluid_midi_file_eot(mf)) { - if (fluid_midi_file_read_event(mf, track) != FLUID_OK) { - return FLUID_FAILED; - } - } - - fluid_player_add_track(player, track); - - } else { - found_track = 0; - if (fluid_midi_file_read(mf, length, 4) != FLUID_OK) { - return FLUID_FAILED; - } - skip = fluid_getlength(length); -/* fseek(mf->fp, skip, SEEK_CUR); */ - if (fluid_midi_file_skip(mf, skip) != FLUID_OK) { - return FLUID_FAILED; - } - } - } - if (feof(mf->fp)) { - FLUID_LOG(FLUID_ERR, "Unexpected end of file"); - return FLUID_FAILED; - } - return FLUID_OK; -} - -/* - * fluid_midi_file_read_varlen - */ -int fluid_midi_file_read_varlen(fluid_midi_file* mf) -{ - int i; - int c; - mf->varlen = 0; - for (i = 0;;i++) { - if (i == 4) { - FLUID_LOG(FLUID_ERR, "Invalid variable length number"); - return FLUID_FAILED; - } - c = fluid_midi_file_getc(mf); - if (c < 0) { - FLUID_LOG(FLUID_ERR, "Unexpected end of file"); - return FLUID_FAILED; - } - if (c & 0x80){ - mf->varlen |= (int) (c & 0x7F); - mf->varlen <<= 7; - } else { - mf->varlen += c; - break; - } - } - return FLUID_OK; -} - -/* - * fluid_midi_file_read_event - */ -int fluid_midi_file_read_event(fluid_midi_file* mf, fluid_track_t* track) -{ - int status; - int type; - int tempo; - unsigned char* metadata = NULL; - unsigned char* dyn_buf = NULL; - unsigned char static_buf[256]; - int nominator, denominator, clocks, notes, sf, mi; - fluid_midi_event_t* evt; - int channel = 0; - int param1 = 0; - int param2 = 0; - - /* read the delta-time of the event */ - if (fluid_midi_file_read_varlen(mf) != FLUID_OK) { - return FLUID_FAILED; - } - mf->dtime += mf->varlen; - - /* read the status byte */ - status = fluid_midi_file_getc(mf); - if (status < 0) { - FLUID_LOG(FLUID_ERR, "Unexpected end of file"); - return FLUID_FAILED; - } - - /* not a valid status byte: use the running status instead */ - if ((status & 0x80) == 0) { - if ((mf->running_status & 0x80) == 0) { - FLUID_LOG(FLUID_ERR, "Undefined status and invalid running status"); - return FLUID_FAILED; - } - fluid_midi_file_push(mf, status); - status = mf->running_status; - } - - /* check what message we have */ - if (status & 0x80) { - mf->running_status = status; - - if ((status == MIDI_SYSEX) || (status == MIDI_EOX)) { /* system exclusif */ - /* - * Sysex messages are not handled yet - */ - /* read the length of the message */ - if (fluid_midi_file_read_varlen(mf) != FLUID_OK) { - return FLUID_FAILED; - } - - if (mf->varlen) { - - if (mf->varlen < 255) { - metadata = &static_buf[0]; - } else { - FLUID_LOG(FLUID_DBG, "%s: %d: alloc metadata, len = %d", __FILE__, __LINE__, mf->varlen); - dyn_buf = FLUID_MALLOC(mf->varlen + 1); - if (dyn_buf == NULL) { - FLUID_LOG(FLUID_PANIC, "Out of memory"); - return FLUID_FAILED; - } - metadata = dyn_buf; - } - - /* read the data of the message */ - if (fluid_midi_file_read(mf, metadata, mf->varlen) != FLUID_OK) { - if (dyn_buf) { - FLUID_FREE(dyn_buf); - } - return FLUID_FAILED; - } - - if (dyn_buf) { - FLUID_LOG(FLUID_DBG, "%s: %d: free metadata", __FILE__, __LINE__); - FLUID_FREE(dyn_buf); - } - } - - return FLUID_OK; - - } else if (status == MIDI_META_EVENT) { /* meta events */ - - int result = FLUID_OK; - - /* get the type of the meta message */ - type = fluid_midi_file_getc(mf); - if (type < 0) { - FLUID_LOG(FLUID_ERR, "Unexpected end of file"); - return FLUID_FAILED; - } - - /* get the length of the data part */ - if (fluid_midi_file_read_varlen(mf) != FLUID_OK) { - return FLUID_FAILED; - } - - if (mf->varlen < 255) { - metadata = &static_buf[0]; - } else { - FLUID_LOG(FLUID_DBG, "%s: %d: alloc metadata, len = %d", __FILE__, __LINE__, mf->varlen); - dyn_buf = FLUID_MALLOC(mf->varlen + 1); - if (dyn_buf == NULL) { - FLUID_LOG(FLUID_PANIC, "Out of memory"); - return FLUID_FAILED; - } - metadata = dyn_buf; - } - - /* read the data */ - if (mf->varlen) - { - if (fluid_midi_file_read(mf, metadata, mf->varlen) != FLUID_OK) { - if (dyn_buf) { - FLUID_FREE(dyn_buf); - } - return FLUID_FAILED; - } - } - - /* handle meta data */ - switch (type) { - - case MIDI_COPYRIGHT: - metadata[mf->varlen] = 0; - break; - - case MIDI_TRACK_NAME: - metadata[mf->varlen] = 0; - fluid_track_set_name(track, (char*) metadata); - break; - - case MIDI_INST_NAME: - metadata[mf->varlen] = 0; - break; - - case MIDI_LYRIC: - break; - - case MIDI_MARKER: - break; - - case MIDI_CUE_POINT: - break; /* don't care much for text events */ - - case MIDI_EOT: - if (mf->varlen != 0) { - FLUID_LOG(FLUID_ERR, "Invalid length for EndOfTrack event"); - result = FLUID_FAILED; - break; - } - mf->eot = 1; - break; - - case MIDI_SET_TEMPO: - if (mf->varlen != 3) { - FLUID_LOG(FLUID_ERR, "Invalid length for SetTempo meta event"); - result = FLUID_FAILED; - break; - } - tempo = (metadata[0] << 16) + (metadata[1] << 8) + metadata[2]; - evt = new_fluid_midi_event(); - if (evt == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - result = FLUID_FAILED; - break; - } - evt->dtime = mf->dtime; - evt->type = MIDI_SET_TEMPO; - evt->channel = 0; - evt->param1 = tempo; - evt->param2 = 0; - fluid_track_add_event(track, evt); - mf->dtime = 0; - break; - - case MIDI_SMPTE_OFFSET: - if (mf->varlen != 5) { - FLUID_LOG(FLUID_ERR, "Invalid length for SMPTE Offset meta event"); - result = FLUID_FAILED; - break; - } - break; /* we don't use smtp */ - - case MIDI_TIME_SIGNATURE: - if (mf->varlen != 4) { - FLUID_LOG(FLUID_ERR, "Invalid length for TimeSignature meta event"); - result = FLUID_FAILED; - break; - } - nominator = metadata[0]; - denominator = pow(2.0, (double) metadata[1]); - clocks = metadata[2]; - notes = metadata[3]; - - FLUID_LOG(FLUID_DBG, "signature=%d/%d, metronome=%d, 32nd-notes=%d", - nominator, denominator, clocks, notes); - - break; - - case MIDI_KEY_SIGNATURE: - if (mf->varlen != 2) { - FLUID_LOG(FLUID_ERR, "Invalid length for KeySignature meta event"); - result = FLUID_FAILED; - break; - } - sf = metadata[0]; - mi = metadata[1]; - break; - - case MIDI_SEQUENCER_EVENT: - break; - - default: - break; - } - - if (dyn_buf) { - FLUID_LOG(FLUID_DBG, "%s: %d: free metadata", __FILE__, __LINE__); - FLUID_FREE(dyn_buf); - } - - return result; - - } else { /* channel messages */ - - type = status & 0xf0; - channel = status & 0x0f; - - /* all channel message have at least 1 byte of associated data */ - if ((param1 = fluid_midi_file_getc(mf)) < 0) { - FLUID_LOG(FLUID_ERR, "Unexpected end of file"); - return FLUID_FAILED; - } - - switch (type) { - - case NOTE_ON: - if ((param2 = fluid_midi_file_getc(mf)) < 0) { - FLUID_LOG(FLUID_ERR, "Unexpected end of file"); - return FLUID_FAILED; - } - break; - - case NOTE_OFF: - if ((param2 = fluid_midi_file_getc(mf)) < 0) { - FLUID_LOG(FLUID_ERR, "Unexpected end of file"); - return FLUID_FAILED; - } - break; - - case KEY_PRESSURE: - if ((param2 = fluid_midi_file_getc(mf)) < 0) { - FLUID_LOG(FLUID_ERR, "Unexpected end of file"); - return FLUID_FAILED; - } - break; - - case CONTROL_CHANGE: - if ((param2 = fluid_midi_file_getc(mf)) < 0) { - FLUID_LOG(FLUID_ERR, "Unexpected end of file"); - return FLUID_FAILED; - } - break; - - case PROGRAM_CHANGE: - break; - - case CHANNEL_PRESSURE: - break; - - case PITCH_BEND: - if ((param2 = fluid_midi_file_getc(mf)) < 0) { - FLUID_LOG(FLUID_ERR, "Unexpected end of file"); - return FLUID_FAILED; - } - - param1 = ((param2 & 0x7f) << 7) | (param1 & 0x7f); - param2 = 0; - break; - - default: - /* Can't possibly happen !? */ - FLUID_LOG(FLUID_ERR, "Unrecognized MIDI event"); - return FLUID_FAILED; - } - evt = new_fluid_midi_event(); - if (evt == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return FLUID_FAILED; - } - evt->dtime = mf->dtime; - evt->type = type; - evt->channel = channel; - evt->param1 = param1; - evt->param2 = param2; - fluid_track_add_event(track, evt); - mf->dtime = 0; - } - } - return FLUID_OK; -} - -/* - * fluid_midi_file_get_division - */ -int fluid_midi_file_get_division(fluid_midi_file* midifile) -{ - return midifile->division; -} - -/****************************************************** - * - * fluid_track_t - */ - -/** - * Create a MIDI event structure. - * @return New MIDI event structure or NULL when out of memory. - */ -fluid_midi_event_t* new_fluid_midi_event() -{ - fluid_midi_event_t* evt; - evt = FLUID_NEW(fluid_midi_event_t); - if (evt == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - evt->dtime = 0; - evt->type = 0; - evt->channel = 0; - evt->param1 = 0; - evt->param2 = 0; - evt->next = NULL; - return evt; -} - -/** - * Delete MIDI event structure. - * @param evt MIDI event structure - * @return Always returns 0 - */ -int delete_fluid_midi_event(fluid_midi_event_t* evt) -{ - fluid_midi_event_t *temp; - - while (evt) - { - temp = evt->next; - FLUID_FREE(evt); - evt = temp; - } - return FLUID_OK; -} - -/** - * Get the event type field of a MIDI event structure. - * DOCME - Event type enum appears to be internal (fluid_midi.h) - * @param evt MIDI event structure - * @return Event type field - */ -int fluid_midi_event_get_type(fluid_midi_event_t* evt) -{ - return evt->type; -} - -/** - * Set the event type field of a MIDI event structure. - * DOCME - Event type enum appears to be internal (fluid_midi.h) - * @param evt MIDI event structure - * @param type Event type field - * @return Always returns 0 - */ -int fluid_midi_event_set_type(fluid_midi_event_t* evt, int type) -{ - evt->type = type; - return FLUID_OK; -} - -/** - * Get the channel field of a MIDI event structure. - * @param evt MIDI event structure - * @return Channel field - */ -int fluid_midi_event_get_channel(fluid_midi_event_t* evt) -{ - return evt->channel; -} - -/** - * Set the channel field of a MIDI event structure. - * @param evt MIDI event structure - * @param chan MIDI channel field - * @return Always returns 0 - */ -int fluid_midi_event_set_channel(fluid_midi_event_t* evt, int chan) -{ - evt->channel = chan; - return FLUID_OK; -} - -/** - * Get the key field of a MIDI event structure. - * @param evt MIDI event structure - * @return MIDI note number (0-127) - */ -int fluid_midi_event_get_key(fluid_midi_event_t* evt) -{ - return evt->param1; -} - -/** - * Set the key field of a MIDI event structure. - * @param evt MIDI event structure - * @param v MIDI note number (0-127) - * @return Always returns 0 - */ -int fluid_midi_event_set_key(fluid_midi_event_t* evt, int v) -{ - evt->param1 = v; - return FLUID_OK; -} - -/** - * Get the velocity field of a MIDI event structure. - * @param evt MIDI event structure - * @return MIDI velocity number (0-127) - */ -int fluid_midi_event_get_velocity(fluid_midi_event_t* evt) -{ - return evt->param2; -} - -/** - * Set the velocity field of a MIDI event structure. - * @param evt MIDI event structure - * @param v MIDI velocity value - * @return Always returns 0 - */ -int fluid_midi_event_set_velocity(fluid_midi_event_t* evt, int v) -{ - evt->param2 = v; - return FLUID_OK; -} - -/** - * Get the control number of a MIDI event structure. - * @param evt MIDI event structure - * @return MIDI control number - */ -int fluid_midi_event_get_control(fluid_midi_event_t* evt) -{ - return evt->param1; -} - -/** - * Set the control field of a MIDI event structure. - * @param evt MIDI event structure - * @param v MIDI control number - * @return Always returns 0 - */ -int fluid_midi_event_set_control(fluid_midi_event_t* evt, int v) -{ - evt->param1 = v; - return FLUID_OK; -} - -/** - * Get the value field from a MIDI event structure. - * @param evt MIDI event structure - * @return Value field - */ -int fluid_midi_event_get_value(fluid_midi_event_t* evt) -{ - return evt->param2; -} - -/** - * Set the value field of a MIDI event structure. - * @param evt MIDI event structure - * @param v Value to assign - * @return Always returns 0 - */ -int fluid_midi_event_set_value(fluid_midi_event_t* evt, int v) -{ - evt->param2 = v; - return FLUID_OK; -} - -/** - * Get the program field of a MIDI event structure. - * @param evt MIDI event structure - * @return MIDI program number (0-127) - */ -int fluid_midi_event_get_program(fluid_midi_event_t* evt) -{ - return evt->param1; -} - -/** - * Set the program field of a MIDI event structure. - * @param evt MIDI event structure - * @param val MIDI program number (0-127) - * @return Always returns 0 - */ -int fluid_midi_event_set_program(fluid_midi_event_t* evt, int val) -{ - evt->param1 = val; - return FLUID_OK; -} - -/** - * Get the pitch field of a MIDI event structure. - * @param evt MIDI event structure - * @return Pitch value (DOCME units?) - */ -int fluid_midi_event_get_pitch(fluid_midi_event_t* evt) -{ - return evt->param1; -} - -/** - * Set the pitch field of a MIDI event structure. - * @param evt MIDI event structure - * @param val Pitch value (DOCME units?) - * @return Always returns 0 - */ -int fluid_midi_event_set_pitch(fluid_midi_event_t* evt, int val) -{ - evt->param1 = val; - return FLUID_OK; -} - -/* - * fluid_midi_event_get_param1 - */ -/* int fluid_midi_event_get_param1(fluid_midi_event_t* evt) */ -/* { */ -/* return evt->param1; */ -/* } */ - -/* - * fluid_midi_event_set_param1 - */ -/* int fluid_midi_event_set_param1(fluid_midi_event_t* evt, int v) */ -/* { */ -/* evt->param1 = v; */ -/* return FLUID_OK; */ -/* } */ - -/* - * fluid_midi_event_get_param2 - */ -/* int fluid_midi_event_get_param2(fluid_midi_event_t* evt) */ -/* { */ -/* return evt->param2; */ -/* } */ - -/* - * fluid_midi_event_set_param2 - */ -/* int fluid_midi_event_set_param2(fluid_midi_event_t* evt, int v) */ -/* { */ -/* evt->param2 = v; */ -/* return FLUID_OK; */ -/* } */ - -/****************************************************** - * - * fluid_track_t - */ - -/* - * new_fluid_track - */ -fluid_track_t* new_fluid_track(int num) -{ - fluid_track_t* track; - track = FLUID_NEW(fluid_track_t); - if (track == NULL) { - return NULL; - } - track->name = NULL; - track->num = num; - track->first = NULL; - track->cur = NULL; - track->last = NULL; - track->ticks = 0; - return track; -} - -/* - * delete_fluid_track - */ -int delete_fluid_track(fluid_track_t* track) -{ - if (track->name != NULL) { - FLUID_FREE(track->name); - } - if (track->first != NULL) { - delete_fluid_midi_event(track->first); - } - FLUID_FREE(track); - return FLUID_OK; -} - -/* - * fluid_track_set_name - */ -int fluid_track_set_name(fluid_track_t* track, char* name) -{ - int len; - if (track->name != NULL) { - FLUID_FREE(track->name); - } - if (name == NULL) { - track->name = NULL; - return FLUID_OK; - } - len = FLUID_STRLEN(name); - track->name = FLUID_MALLOC(len + 1); - if (track->name == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return FLUID_FAILED; - } - FLUID_STRCPY(track->name, name); - return FLUID_OK; -} - -/* - * fluid_track_get_name - */ -char* fluid_track_get_name(fluid_track_t* track) -{ - return track->name; -} - -/* - * fluid_track_get_duration - */ -int fluid_track_get_duration(fluid_track_t* track) -{ - int time = 0; - fluid_midi_event_t* evt = track->first; - while (evt != NULL) { - time += evt->dtime; - evt = evt->next; - } - return time; -} - -/* - * fluid_track_count_events - */ -int fluid_track_count_events(fluid_track_t* track, int* on, int* off) -{ - fluid_midi_event_t* evt = track->first; - while (evt != NULL) { - if (evt->type == NOTE_ON) { - (*on)++; - } else if (evt->type == NOTE_OFF) { - (*off)++; - } - evt = evt->next; - } - return FLUID_OK; -} - -/* - * fluid_track_add_event - */ -int fluid_track_add_event(fluid_track_t* track, fluid_midi_event_t* evt) -{ - evt->next = NULL; - if (track->first == NULL) { - track->first = evt; - track->cur = evt; - track->last = evt; - } else { - track->last->next = evt; - track->last = evt; - } - return FLUID_OK; -} - -/* - * fluid_track_first_event - */ -fluid_midi_event_t* fluid_track_first_event(fluid_track_t* track) -{ - track->cur = track->first; - return track->cur; -} - -/* - * fluid_track_next_event - */ -fluid_midi_event_t* fluid_track_next_event(fluid_track_t* track) -{ - if (track->cur != NULL) { - track->cur = track->cur->next; - } - return track->cur; -} - -/* - * fluid_track_reset - */ -int -fluid_track_reset(fluid_track_t* track) -{ - track->ticks = 0; - track->cur = track->first; - return FLUID_OK; -} - -/* - * fluid_track_send_events - */ -int -fluid_track_send_events(fluid_track_t* track, - fluid_synth_t* synth, - fluid_player_t* player, - unsigned int ticks) -{ - int status = FLUID_OK; - fluid_midi_event_t* event; - - while (1) { - - event = track->cur; - if (event == NULL) { - return status; - } - -/* printf("track=%02d\tticks=%05u\ttrack=%05u\tdtime=%05u\tnext=%05u\n", */ -/* track->num, */ -/* ticks, */ -/* track->ticks, */ -/* event->dtime, */ -/* track->ticks + event->dtime); */ - - if (track->ticks + event->dtime > ticks) { - return status; - } - - - track->ticks += event->dtime; - status = fluid_midi_send_event(synth, player, event); - fluid_track_next_event(track); - - } - return status; -} - -/****************************************************** - * - * fluid_player - */ - -/** - * Create a new MIDI player. - * @param synth Fluid synthesizer instance to create player for - * @return New MIDI player instance or NULL on error (out of memory) - */ -fluid_player_t* new_fluid_player(fluid_synth_t* synth) -{ - int i; - fluid_player_t* player; - player = FLUID_NEW(fluid_player_t); - if (player == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - player->status = FLUID_PLAYER_READY; - player->loop = 0; - player->ntracks = 0; - for (i = 0; i < MAX_NUMBER_OF_TRACKS; i++) { - player->track[i] = NULL; - } - player->synth = synth; - player->timer = NULL; - player->playlist = NULL; - player->current_file = NULL; - player->division = 0; - player->send_program_change = 1; - player->miditempo = 480000; - player->deltatime = 4.0; - return player; -} - -/** - * Delete a MIDI player instance. - * @param player MIDI player instance - * @return Always returns 0 - */ -int delete_fluid_player(fluid_player_t* player) -{ - if (player == NULL) { - return FLUID_OK; - } - fluid_player_stop(player); - fluid_player_reset(player); - FLUID_FREE(player); - return FLUID_OK; -} - -int fluid_player_reset(fluid_player_t* player) -{ - int i; - - for (i = 0; i < MAX_NUMBER_OF_TRACKS; i++) { - if (player->track[i] != NULL) { - delete_fluid_track(player->track[i]); - player->track[i] = NULL; - } - } - player->current_file = NULL; - player->status = FLUID_PLAYER_READY; - player->loop = 0; - player->ntracks = 0; - player->division = 0; - player->send_program_change = 1; - player->miditempo = 480000; - player->deltatime = 4.0; - return 0; -} - -/* - * fluid_player_add_track - */ -int fluid_player_add_track(fluid_player_t* player, fluid_track_t* track) -{ - if (player->ntracks < MAX_NUMBER_OF_TRACKS) { - player->track[player->ntracks++] = track; - return FLUID_OK; - } else { - return FLUID_FAILED; - } -} - -/* - * fluid_player_count_tracks - */ -int fluid_player_count_tracks(fluid_player_t* player) -{ - return player->ntracks; -} - -/* - * fluid_player_get_track - */ -fluid_track_t* fluid_player_get_track(fluid_player_t* player, int i) -{ - if ((i >= 0) && (i < MAX_NUMBER_OF_TRACKS)) { - return player->track[i]; - } else { - return NULL; - } -} - -int fluid_player_add(fluid_player_t* player, char* midifile) -{ - char *s = FLUID_STRDUP(midifile); - player->playlist = fluid_list_append(player->playlist, s); - return 0; -} - -/* - * fluid_player_load - */ -int fluid_player_load(fluid_player_t* player, char *filename) -{ - fluid_midi_file* midifile; - - midifile = new_fluid_midi_file(filename); - if (midifile == NULL) { - return FLUID_FAILED; - } - player->division = fluid_midi_file_get_division(midifile); - - /*FLUID_LOG(FLUID_DBG, "quarter note division=%d\n", player->division); */ - - if (fluid_midi_file_load_tracks(midifile, player) != FLUID_OK){ - return FLUID_FAILED; - } - delete_fluid_midi_file(midifile); - return FLUID_OK; -} - -/* - * fluid_player_callback - */ -int fluid_player_callback(void* data, unsigned int msec) -{ - int i; - int status = FLUID_PLAYER_DONE; - fluid_player_t* player; - fluid_synth_t* synth; - player = (fluid_player_t*) data; - synth = player->synth; - - /* Load the next file if necessary */ - while (player->current_file == NULL) { - - if (player->playlist == NULL) { - return 0; - } - - fluid_player_reset(player); - - player->current_file = fluid_list_get(player->playlist); - player->playlist = fluid_list_next(player->playlist); - - FLUID_LOG(FLUID_DBG, "%s: %d: Loading midifile %s", __FILE__, __LINE__, player->current_file); - - if (fluid_player_load(player, player->current_file) == FLUID_OK) { - - player->begin_msec = msec; - player->start_msec = msec; - player->start_ticks = 0; - player->cur_ticks = 0; - - for (i = 0; i < player->ntracks; i++) { - if (player->track[i] != NULL) { - fluid_track_reset(player->track[i]); - } - } - - } else { - player->current_file = NULL; - } - } - - player->cur_msec = msec; - player->cur_ticks = (player->start_ticks + - (int) ((double) (player->cur_msec - player->start_msec) / player->deltatime)); - - for (i = 0; i < player->ntracks; i++) { - if (!fluid_track_eot(player->track[i])) { - status = FLUID_PLAYER_PLAYING; - if (fluid_track_send_events(player->track[i], synth, player, player->cur_ticks) != FLUID_OK) { - /* */ - } - } - } - - player->status = status; - - if (player->status == FLUID_PLAYER_DONE) { - FLUID_LOG(FLUID_DBG, "%s: %d: Duration=%.3f sec", - __FILE__, __LINE__, (msec - player->begin_msec) / 1000.0); - player->current_file = NULL; - } - - return 1; -} - -/** - * Activates play mode for a MIDI player if not already playing. - * @param player MIDI player instance - * @return 0 on success, -1 on failure - */ -int fluid_player_play(fluid_player_t* player) -{ - if (player->status == FLUID_PLAYER_PLAYING) { - return FLUID_OK; - } - - if (player->playlist == NULL) { - return FLUID_OK; - } - - player->status = FLUID_PLAYER_PLAYING; - - player->timer = new_fluid_timer((int) player->deltatime, fluid_player_callback, - (void*) player, 1, 0); - if (player->timer == NULL) { - return FLUID_FAILED; - } - return FLUID_OK; -} - -/** - * Stops a MIDI player. - * @param player MIDI player instance - * @return Always returns 0 - */ -int fluid_player_stop(fluid_player_t* player) -{ - if (player->timer != NULL) { - delete_fluid_timer(player->timer); - } - player->status = FLUID_PLAYER_DONE; - player->timer = NULL; - return FLUID_OK; -} - -/* FIXME - Looping seems to not actually be implemented? */ - -/** - * Enable looping of a MIDI player (DOCME - Does this actually work?) - * @param player MIDI player instance - * @param loop Value for looping (DOCME - What would this value be, boolean/time index?) - * @return Always returns 0 - */ -int fluid_player_set_loop(fluid_player_t* player, int loop) -{ - player->loop = loop; - return FLUID_OK; -} - -/** - * Set the tempo of a MIDI player. - * @param player MIDI player instance - * @param tempo Tempo to set playback speed to (DOCME - Units?) - * @return Always returns 0 - * - */ -int fluid_player_set_midi_tempo(fluid_player_t* player, int tempo) -{ - player->miditempo = tempo; - player->deltatime = (double) tempo / player->division / 1000.0; /* in milliseconds */ - player->start_msec = player->cur_msec; - player->start_ticks = player->cur_ticks; - - FLUID_LOG(FLUID_DBG,"tempo=%d, tick time=%f msec, cur time=%d msec, cur tick=%d", - tempo, player->deltatime, player->cur_msec, player->cur_ticks); - - return FLUID_OK; -} - -/** - * Set the tempo of a MIDI player in beats per minute. - * @param player MIDI player instance - * @param bpm Tempo in beats per minute - * @return Always returns 0 - */ -int fluid_player_set_bpm(fluid_player_t* player, int bpm) -{ - return fluid_player_set_midi_tempo(player, (int)((double) 60 * 1e6 / bpm)); -} - -/** - * Wait for a MIDI player to terminate (when done playing). - * @param player MIDI player instance - * @return 0 on success, -1 otherwise - * - */ -int fluid_player_join(fluid_player_t* player) -{ - return player->timer? fluid_timer_join(player->timer) : FLUID_OK; -} - -/************************************************************************ - * MIDI PARSER - * - */ - -/* - * new_fluid_midi_parser - */ -fluid_midi_parser_t* new_fluid_midi_parser() -{ - fluid_midi_parser_t* parser; - parser = FLUID_NEW(fluid_midi_parser_t); - if (parser == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - parser->status = 0; /* As long as the status is 0, the parser won't do anything -> no need to initialize all the fields. */ - return parser; -} - -/* - * delete_fluid_midi_parser - */ -int delete_fluid_midi_parser(fluid_midi_parser_t* parser) -{ - FLUID_FREE(parser); - return FLUID_OK; -} - -/* - * fluid_midi_parser_parse - * - * Purpose: - * The MIDI byte stream is fed into the parser, one byte at a time. - * As soon as the parser has recognized an event, it will return it. - * Otherwise it returns NULL. - */ -fluid_midi_event_t* fluid_midi_parser_parse(fluid_midi_parser_t* parser, unsigned char c) -{ - /*********************************************************************/ - /* 'Process' system real-time messages */ - /*********************************************************************/ - /* There are not too many real-time messages that are of interest here. - * They can occur anywhere, even in the middle of a noteon message! - * Real-time range: 0xF8 .. 0xFF - * Note: Real-time does not affect (running) status. - */ - if (c >= 0xF8){ - if (c == MIDI_SYSTEM_RESET){ - parser->event.type = c; - parser->status = 0; /* clear the status */ - return &parser->event; - }; - return NULL; - }; - - /*********************************************************************/ - /* 'Process' system common messages (again, just skip them) */ - /*********************************************************************/ - /* There are no system common messages that are of interest here. - * System common range: 0xF0 .. 0xF7 - */ - - if (c > 0xF0){ - /* MIDI specs say: To ignore a non-real-time message, just discard all data up to - * the next status byte. - * And our parser will ignore data that is received without a valid status. - * Note: system common cancels running status. */ - parser->status = 0; - return NULL; - }; - - /*********************************************************************/ - /* Process voice category messages: */ - /*********************************************************************/ - /* Now that we have handled realtime and system common messages, only - * voice messages are left. - * Only a status byte has bit # 7 set. - * So no matter the status of the parser (in case we have lost sync), - * as soon as a byte >= 0x80 comes in, we are dealing with a status byte - * and start a new event. - */ - - if (c & 0x80){ - parser->channel = c & 0x0F; - parser->status = c & 0xF0; - /* The event consumes x bytes of data... (subtract 1 for the status byte) */ - parser->nr_bytes_total=fluid_midi_event_length(parser->status)-1; - /* of which we have read 0 at this time. */ - parser->nr_bytes = 0; - return NULL; - }; - - /*********************************************************************/ - /* Process data */ - /*********************************************************************/ - /* If we made it this far, then the received char belongs to the data - * of the last event. */ - if (parser->status == 0){ - /* We are not interested in the event currently received. - * Discard the data. */ - return NULL; - }; - - /* Store the first couple of bytes */ - if (parser->nr_bytes < FLUID_MIDI_PARSER_MAX_PAR){ - parser->p[parser->nr_bytes]=c; - }; - parser->nr_bytes++; - - /* Do we still need more data to get this event complete? */ - if (parser->nr_bytes < parser->nr_bytes_total){ - return NULL; - }; - - /*********************************************************************/ - /* Send the event */ - /*********************************************************************/ - /* The event is ready-to-go. - * About 'running status': - * The MIDI protocol has a built-in compression mechanism. If several similar events are sent - * in-a-row, for example note-ons, then the event type is only sent once. For this case, - * the last event type (status) is remembered. - * We simply keep the status as it is, just reset - * the parameter counter. If another status byte comes in, it will overwrite the status. */ - parser->event.type = parser->status; - parser->event.channel = parser->channel; - parser->nr_bytes = 0; /* Related to running status! */ - switch (parser->status){ - case NOTE_OFF: - case NOTE_ON: - case KEY_PRESSURE: - case CONTROL_CHANGE: - case PROGRAM_CHANGE: - case CHANNEL_PRESSURE: - parser->event.param1 = parser->p[0]; /* For example key number */ - parser->event.param2 = parser->p[1]; /* For example velocity */ - break; - case PITCH_BEND: - /* Pitch-bend is transmitted with 14-bit precision. */ - parser->event.param1 = ((parser->p[1] << 7) | parser->p[0]); /* Note: '|' does here the same as '+' (no common bits), but might be faster */ - break; - default: - /* Unlikely */ - return NULL; - }; - return &parser->event; -}; - -/* Purpose: - * Returns the length of the MIDI message starting with c. - * Taken from Nagano Daisuke's USB-MIDI driver */ -int fluid_midi_event_length(unsigned char event){ - if ( event < 0xf0 ) { - return remains_80e0[((event-0x80)>>4)&0x0f]; - } else if ( event < 0xf7 ) { - return remains_f0f6[event-0xf0]; - } else { - return 1; - } -} - -/************************************************************************ - * fluid_midi_send_event - * - * This is a utility function that doesn't really belong to any class - * or structure. It is called by fluid_midi_track and fluid_midi_device. - */ -int fluid_midi_send_event(fluid_synth_t* synth, fluid_player_t* player, fluid_midi_event_t* event) -{ - switch (event->type) { - case NOTE_ON: - if (fluid_synth_noteon(synth, event->channel, event->param1, event->param2) != FLUID_OK) { - return FLUID_FAILED; - } - break; - case NOTE_OFF: - if (fluid_synth_noteoff(synth, event->channel, event->param1) != FLUID_OK) { - return FLUID_FAILED; - } - break; - case CONTROL_CHANGE: - if (fluid_synth_cc(synth, event->channel, event->param1, event->param2) != FLUID_OK) { - return FLUID_FAILED; - } - break; - case MIDI_SET_TEMPO: - if (player != NULL) { - if (fluid_player_set_midi_tempo(player, event->param1) != FLUID_OK) { - return FLUID_FAILED; - } - } - break; - case PROGRAM_CHANGE: - if (fluid_synth_program_change(synth, event->channel, event->param1) != FLUID_OK) { - return FLUID_FAILED; - } - break; - case PITCH_BEND: - if (fluid_synth_pitch_bend(synth, event->channel, event->param1) != FLUID_OK) { - return FLUID_FAILED; - } - break; - default: - break; - } - return FLUID_OK; -} diff --git a/src/libs/fluidsynth/src/fluid_midi.h b/src/libs/fluidsynth/src/fluid_midi.h deleted file mode 100644 index 8f0dd248bb..0000000000 --- a/src/libs/fluidsynth/src/fluid_midi.h +++ /dev/null @@ -1,335 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#ifndef _FLUID_MIDI_H -#define _FLUID_MIDI_H - -#include "fluidsynth_priv.h" -#include "fluid_sys.h" -#include "fluid_list.h" - -typedef struct _fluid_midi_parser_t fluid_midi_parser_t; - -fluid_midi_parser_t* new_fluid_midi_parser(void); -int delete_fluid_midi_parser(fluid_midi_parser_t* parser); -fluid_midi_event_t* fluid_midi_parser_parse(fluid_midi_parser_t* parser, unsigned char c); - -int fluid_midi_send_event(fluid_synth_t* synth, fluid_player_t* player, fluid_midi_event_t* evt); - - -/*************************************************************** - * - * CONSTANTS & ENUM - */ - - -#define MAX_NUMBER_OF_TRACKS 128 - -enum fluid_midi_event_type { - /* channel messages */ - NOTE_OFF = 0x80, - NOTE_ON = 0x90, - KEY_PRESSURE = 0xa0, - CONTROL_CHANGE = 0xb0, - PROGRAM_CHANGE = 0xc0, - CHANNEL_PRESSURE = 0xd0, - PITCH_BEND = 0xe0, - /* system exclusive */ - MIDI_SYSEX = 0xf0, - /* system common - never in midi files */ - MIDI_TIME_CODE = 0xf1, - MIDI_SONG_POSITION = 0xf2, - MIDI_SONG_SELECT = 0xf3, - MIDI_TUNE_REQUEST = 0xf6, - MIDI_EOX = 0xf7, - /* system real-time - never in midi files */ - MIDI_SYNC = 0xf8, - MIDI_TICK = 0xf9, - MIDI_START = 0xfa, - MIDI_CONTINUE = 0xfb, - MIDI_STOP = 0xfc, - MIDI_ACTIVE_SENSING = 0xfe, - MIDI_SYSTEM_RESET = 0xff, - /* meta event - for midi files only */ - MIDI_META_EVENT = 0xff -}; - -enum fluid_midi_control_change { - BANK_SELECT_MSB = 0x00, - MODULATION_MSB = 0x01, - BREATH_MSB = 0x02, - FOOT_MSB = 0x04, - PORTAMENTO_TIME_MSB = 0x05, - DATA_ENTRY_MSB = 0x06, - VOLUME_MSB = 0x07, - BALANCE_MSB = 0x08, - PAN_MSB = 0x0A, - EXPRESSION_MSB = 0x0B, - EFFECTS1_MSB = 0x0C, - EFFECTS2_MSB = 0x0D, - GPC1_MSB = 0x10, /* general purpose controller */ - GPC2_MSB = 0x11, - GPC3_MSB = 0x12, - GPC4_MSB = 0x13, - BANK_SELECT_LSB = 0x20, - MODULATION_WHEEL_LSB = 0x21, - BREATH_LSB = 0x22, - FOOT_LSB = 0x24, - PORTAMENTO_TIME_LSB = 0x25, - DATA_ENTRY_LSB = 0x26, - VOLUME_LSB = 0x27, - BALANCE_LSB = 0x28, - PAN_LSB = 0x2A, - EXPRESSION_LSB = 0x2B, - EFFECTS1_LSB = 0x2C, - EFFECTS2_LSB = 0x2D, - GPC1_LSB = 0x30, - GPC2_LSB = 0x31, - GPC3_LSB = 0x32, - GPC4_LSB = 0x33, - SUSTAIN_SWITCH = 0x40, - PORTAMENTO_SWITCH = 0x41, - SOSTENUTO_SWITCH = 0x42, - SOFT_PEDAL_SWITCH = 0x43, - LEGATO_SWITCH = 0x45, - HOLD2_SWITCH = 0x45, - SOUND_CTRL1 = 0x46, - SOUND_CTRL2 = 0x47, - SOUND_CTRL3 = 0x48, - SOUND_CTRL4 = 0x49, - SOUND_CTRL5 = 0x4A, - SOUND_CTRL6 = 0x4B, - SOUND_CTRL7 = 0x4C, - SOUND_CTRL8 = 0x4D, - SOUND_CTRL9 = 0x4E, - SOUND_CTRL10 = 0x4F, - GPC5 = 0x50, - GPC6 = 0x51, - GPC7 = 0x52, - GPC8 = 0x53, - PORTAMENTO_CTRL = 0x54, - EFFECTS_DEPTH1 = 0x5B, - EFFECTS_DEPTH2 = 0x5C, - EFFECTS_DEPTH3 = 0x5D, - EFFECTS_DEPTH4 = 0x5E, - EFFECTS_DEPTH5 = 0x5F, - DATA_ENTRY_INCR = 0x60, - DATA_ENTRY_DECR = 0x61, - NRPN_LSB = 0x62, - NRPN_MSB = 0x63, - RPN_LSB = 0x64, - RPN_MSB = 0x65, - ALL_SOUND_OFF = 0x78, - ALL_CTRL_OFF = 0x79, - LOCAL_CONTROL = 0x7A, - ALL_NOTES_OFF = 0x7B, - OMNI_OFF = 0x7C, - OMNI_ON = 0x7D, - POLY_OFF = 0x7E, - POLY_ON = 0x7F -}; - -/* General MIDI RPN event numbers (LSB, MSB = 0) */ -enum midi_rpn_event { - RPN_PITCH_BEND_RANGE = 0x00, - RPN_CHANNEL_FINE_TUNE = 0x01, - RPN_CHANNEL_COARSE_TUNE = 0x02, - RPN_TUNING_PROGRAM_CHANGE = 0x03, - RPN_TUNING_BANK_SELECT = 0x04, - RPN_MODULATION_DEPTH_RANGE = 0x05 -}; - -enum midi_meta_event { - MIDI_COPYRIGHT = 0x02, - MIDI_TRACK_NAME = 0x03, - MIDI_INST_NAME = 0x04, - MIDI_LYRIC = 0x05, - MIDI_MARKER = 0x06, - MIDI_CUE_POINT = 0x07, - MIDI_EOT = 0x2f, - MIDI_SET_TEMPO = 0x51, - MIDI_SMPTE_OFFSET = 0x54, - MIDI_TIME_SIGNATURE = 0x58, - MIDI_KEY_SIGNATURE = 0x59, - MIDI_SEQUENCER_EVENT = 0x7f -}; - -enum fluid_player_status -{ - FLUID_PLAYER_READY, - FLUID_PLAYER_PLAYING, - FLUID_PLAYER_DONE -}; - -enum fluid_driver_status -{ - FLUID_MIDI_READY, - FLUID_MIDI_LISTENING, - FLUID_MIDI_DONE -}; - -/*************************************************************** - * - * TYPE DEFINITIONS & FUNCTION DECLARATIONS - */ - -/* From ctype.h */ -#define fluid_isascii(c) (((c) & ~0x7f) == 0) - - - -/* - * fluid_midi_event_t - */ -struct _fluid_midi_event_t { - fluid_midi_event_t* next; /* Don't use it, it will dissappear. Used in midi tracks. */ - unsigned int dtime; /* Delay (ticks) between this and previous event. midi tracks. */ - unsigned char type; /* MIDI event type */ - unsigned char channel; /* MIDI channel */ - unsigned int param1; /* First parameter */ - unsigned int param2; /* Second parameter */ -}; - - -/* - * fluid_track_t - */ -struct _fluid_track_t { - char* name; - int num; - fluid_midi_event_t *first; - fluid_midi_event_t *cur; - fluid_midi_event_t *last; - unsigned int ticks; -}; - -typedef struct _fluid_track_t fluid_track_t; - -fluid_track_t* new_fluid_track(int num); -int delete_fluid_track(fluid_track_t* track); -int fluid_track_set_name(fluid_track_t* track, char* name); -char* fluid_track_get_name(fluid_track_t* track); -int fluid_track_add_event(fluid_track_t* track, fluid_midi_event_t* evt); -fluid_midi_event_t* fluid_track_first_event(fluid_track_t* track); -fluid_midi_event_t* fluid_track_next_event(fluid_track_t* track); -int fluid_track_get_duration(fluid_track_t* track); -int fluid_track_reset(fluid_track_t* track); - -int fluid_track_send_events(fluid_track_t* track, - fluid_synth_t* synth, - fluid_player_t* player, - unsigned int ticks); - -#define fluid_track_eot(track) ((track)->cur == NULL) - - -/* - * fluid_player - */ -struct _fluid_player_t { - int status; - int loop; - int ntracks; - fluid_track_t *track[MAX_NUMBER_OF_TRACKS]; - fluid_synth_t* synth; - fluid_timer_t* timer; - fluid_list_t* playlist; - char* current_file; - char send_program_change; /* should we ignore the program changes? */ - int start_ticks; /* the number of tempo ticks passed at the last tempo change */ - int cur_ticks; /* the number of tempo ticks passed */ - int begin_msec; /* the time (msec) of the beginning of the file */ - int start_msec; /* the start time of the last tempo change */ - int cur_msec; /* the current time */ - int miditempo; /* as indicated by MIDI SetTempo: n 24th of a usec per midi-clock. bravo! */ - double deltatime; /* milliseconds per midi tick. depends on set-tempo */ - unsigned int division; -}; - -int fluid_player_add_track(fluid_player_t* player, fluid_track_t* track); -int fluid_player_callback(void* data, unsigned int msec); -int fluid_player_count_tracks(fluid_player_t* player); -fluid_track_t* fluid_player_get_track(fluid_player_t* player, int i); -int fluid_player_reset(fluid_player_t* player); -int fluid_player_load(fluid_player_t* player, char *filename); - - -/* - * fluid_midi_file - */ -typedef struct { - fluid_file fp; - int running_status; - int c; - int type; - int ntracks; - int uses_smpte; - unsigned int smpte_fps; - unsigned int smpte_res; - unsigned int division; /* If uses_SMPTE == 0 then division is - ticks per beat (quarter-note) */ - double tempo; /* Beats per second (SI rules =) */ - int tracklen; - int trackpos; - int eot; - int varlen; - int dtime; -} fluid_midi_file; - -fluid_midi_file* new_fluid_midi_file(char* filename); -void delete_fluid_midi_file(fluid_midi_file* mf); -int fluid_midi_file_read_mthd(fluid_midi_file* midifile); -int fluid_midi_file_load_tracks(fluid_midi_file* midifile, fluid_player_t* player); -int fluid_midi_file_read_track(fluid_midi_file* mf, fluid_player_t* player, int num); -int fluid_midi_file_read_event(fluid_midi_file* mf, fluid_track_t* track); -int fluid_midi_file_read_varlen(fluid_midi_file* mf); -int fluid_midi_file_getc(fluid_midi_file* mf); -int fluid_midi_file_push(fluid_midi_file* mf, int c); -int fluid_midi_file_read(fluid_midi_file* mf, void* buf, int len); -int fluid_midi_file_skip(fluid_midi_file* mf, int len); -int fluid_midi_file_read_tracklen(fluid_midi_file* mf); -int fluid_midi_file_eot(fluid_midi_file* mf); -int fluid_midi_file_get_division(fluid_midi_file* midifile); -int fluid_midi_event_length(unsigned char status); - -/* How many parameters may a MIDI event have? */ -#define FLUID_MIDI_PARSER_MAX_PAR 3 - -/* - * fluid_midi_parser_t - */ -struct _fluid_midi_parser_t { - unsigned char status; /* Identifies the type of event, that is currently received ('Noteon', 'Pitch Bend' etc). */ - unsigned char channel; /* The channel of the event that is received (in case of a channel event) */ - unsigned int nr_bytes; /* How many bytes have been read for the current event? */ - unsigned int nr_bytes_total; /* How many bytes does the current event type include? */ - unsigned short p[FLUID_MIDI_PARSER_MAX_PAR]; /* The parameters */ - fluid_midi_event_t event; /* The event, that is returned to the MIDI driver. */ -}; - -int fluid_isasciistring(char* s); -long fluid_getlength(unsigned char *s); - - - -int fluid_midi_router_send_event(fluid_midi_router_t* router, fluid_midi_event_t* event); - - -#endif /* _FLUID_MIDI_H */ diff --git a/src/libs/fluidsynth/src/fluid_midi_router.c b/src/libs/fluidsynth/src/fluid_midi_router.c deleted file mode 100644 index f907f7f7de..0000000000 --- a/src/libs/fluidsynth/src/fluid_midi_router.c +++ /dev/null @@ -1,889 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -/* Author: Markus Nentwig, nentwig@users.sourceforge.net - */ - -#include "fluid_midi_router.h" -#include "fluid_midi.h" -#include "fluid_synth.h" -#include "fluid_io.h" - -/** - * Create a new midi router. - * @param settings Settings used to configure MIDI router - * @param handler MIDI event callback - * @param event_handler_data Caller defined data pointer which gets passed to 'handler' - * @return New MIDI router instance or NULL on error - * - * A midi handler connects to a midi input - * device and forwards incoming midi events to the synthesizer. - */ -fluid_midi_router_t* -new_fluid_midi_router(fluid_settings_t* settings, handle_midi_event_func_t handler, void* event_handler_data) -{ - fluid_midi_router_t* router=NULL; - fluid_midi_router_rule_t* rule=NULL; - - /* create the router */ - router = FLUID_NEW(fluid_midi_router_t); if (router == NULL){ - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - }; - - /* Clear the router, so that error_recovery can safely free all the rules. - * Dump functions are also NULLed. - */ - FLUID_MEMSET(router, 0, sizeof(fluid_midi_router_t)); - /* Retrieve the number of MIDI channels for range limiting */ - fluid_settings_getint(settings, "synth.midi-channels", &router->nr_midi_channels); - - fluid_mutex_init(router->ruletables_mutex); - - router->synth = (fluid_synth_t*) event_handler_data; - router->event_handler=handler; - router->event_handler_data=event_handler_data; - - /* Create the default routing rules - * They accept events on any channel for any range of parameters, - * and route them unchanged ("result=par*1.0+0") */ - - if (fluid_midi_router_create_default_rules(router) != FLUID_OK) goto error_recovery; - - return router; - - error_recovery: - FLUID_LOG(FLUID_ERR, "new_fluid_midi_router failed"); - fluid_midi_router_destroy_all_rules(router); - FLUID_FREE(router); - return NULL; -} - -/** - * Delete a MIDI router instance. - * @param router MIDI router to delete - * @return Always returns 0 - */ -int -delete_fluid_midi_router(fluid_midi_router_t* router) -{ - if (router == NULL) { - return FLUID_OK; - } - fluid_midi_router_destroy_all_rules(router); - FLUID_FREE(router); - return FLUID_OK; -} - -/* - * fluid_midi_router_destroy_all_rules(fluid_midi_router_t* router) - * Purpose: - * Frees the used memory. This is used only for shutdown! - */ -void fluid_midi_router_destroy_all_rules(fluid_midi_router_t* router){ - fluid_midi_router_rule_t* rules[6]; - fluid_midi_router_rule_t* current_rule; - fluid_midi_router_rule_t* next_rule; - int i; - - rules[0]=router->note_rules; - rules[1]=router->cc_rules; - rules[2]=router->progchange_rules; - rules[3]=router->pitchbend_rules; - rules[4]=router->channel_pressure_rules; - rules[5]=router->key_pressure_rules; - for (i=0; i < 6; i++){ - current_rule=rules[i]; - while (current_rule){ - next_rule=current_rule->next; - FLUID_FREE(current_rule); - current_rule=next_rule; - }; - }; -} - -/* - * new_fluid_midi_router_rule - */ -fluid_midi_router_rule_t* new_fluid_midi_router_rule(void) -{ - fluid_midi_router_rule_t* rule=FLUID_NEW(fluid_midi_router_rule_t); - if (rule == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - - FLUID_MEMSET(rule, 0, sizeof(fluid_midi_router_rule_t)); - return rule; -}; - -/* - * delete_fluid_midi_router_rule - */ -int -delete_fluid_midi_router_rule(fluid_midi_router_rule_t* rule) -{ - FLUID_FREE(rule); - return FLUID_OK; -} - - -int fluid_midi_router_create_default_rules(fluid_midi_router_t* router) -{ - fluid_midi_router_rule_t** rules[6]; - int i; - - rules[0]=&router->note_rules; - rules[1]=&router->cc_rules; - rules[2]=&router->progchange_rules; - rules[3]=&router->pitchbend_rules; - rules[4]=&router->channel_pressure_rules; - rules[5]=&router->key_pressure_rules; - - for (i=0; i < 6; i++){ - /* Start a new rule. rules[i] is the destination. _end will insert - * a new rule there into the linked list. - */ - if (fluid_midi_router_begin(router, rules[i]) != FLUID_OK) goto error_recovery; - if (fluid_midi_router_end(router) != FLUID_OK) goto error_recovery; - }; - - return FLUID_OK; - error_recovery: - FLUID_LOG(FLUID_ERR, "fluid_midi_router_create_default_rules failed"); - return FLUID_FAILED; -}; - -/* Purpose: - * Resets the new-rule registers in 'router' to their default values. - * Stores the destination (the linked list into which the new rule is inserted by _end) - */ -int fluid_midi_router_begin(fluid_midi_router_t* router, fluid_midi_router_rule_t** dest) -{ - if (!dest) goto error_recovery; - router->dest=dest; - - /* In the days before the router, MIDI data went straight to the synth. - * So there is no need to check for reasonable values here. - */ - router->new_rule_chan_min=0; - router->new_rule_chan_max=999999; - router->new_rule_chan_mul=1.; - router->new_rule_chan_add=0; - router->new_rule_par1_min=0; - router->new_rule_par1_max=999999; - router->new_rule_par1_mul=1.; - router->new_rule_par1_add=0; - router->new_rule_par2_min=0; - router->new_rule_par2_max=999999; - router->new_rule_par2_mul=1.; - router->new_rule_par2_add=0; - - return FLUID_OK; - error_recovery: - FLUID_LOG(FLUID_ERR, "fluid_midi_router_begin failed"); - return FLUID_FAILED; -}; - -/* Purpose: - * Concludes a sequence of commands: - * - router_start type - * - router_chan - * - router_par1 - * - router_par2 - * - router_end (this call). - * Creates a new event from the given parameters and stores it in - * the correct list. - */ - -int fluid_midi_router_end(fluid_midi_router_t* router){ - fluid_midi_router_rule_t* rule=new_fluid_midi_router_rule(); if (rule == NULL) goto error_recovery; - - rule->chan_min=router->new_rule_chan_min; - rule->chan_max=router->new_rule_chan_max; - rule->chan_mul=router->new_rule_chan_mul; - rule->chan_add=router->new_rule_chan_add; - rule->par1_min=router->new_rule_par1_min; - rule->par1_max=router->new_rule_par1_max; - rule->par1_mul=router->new_rule_par1_mul; - rule->par1_add=router->new_rule_par1_add; - rule->par2_min=router->new_rule_par2_min; - rule->par2_max=router->new_rule_par2_max; - rule->par2_mul=router->new_rule_par2_mul; - rule->par2_add=router->new_rule_par2_add; - - /* Now we modify the rules table. Lock it to make sure, that the RT - * thread is not in the middle of an event. Also prevent, that some - * other thread modifies the table at the same time. - */ - - fluid_mutex_lock(router->ruletables_mutex); - - rule->next= *(router->dest); - *router->dest=rule; - - fluid_mutex_unlock(router->ruletables_mutex); - - return FLUID_OK; - - error_recovery: - FLUID_LOG(FLUID_ERR, "fluid_midi_router_end failed"); - delete_fluid_midi_router_rule(rule); - return FLUID_FAILED; -}; - -/** - * Handle a MIDI event through a MIDI router instance. - * @param data MIDI router instance #fluid_midi_router_t (DOCME why is it a void *?) - * @param event MIDI event to handle - * @return 0 on success, -1 otherwise - * - * Purpose: The midi router is called for each event, that is received - * via the 'physical' midi input. Each event can trigger an arbitrary number - * of generated events. - * - * In default mode, a noteon event is just forwarded to the synth's 'noteon' function, - * a 'CC' event to the synth's 'CC' function and so on. - * - * The router can be used to - * - filter messages (for example: Pass sustain pedal CCs only to selected channels), - * - split the keyboard (noteon with notenr < x: to ch 1, >x to ch 2), - * - layer sounds (for each noteon received on ch 1, create a noteon on ch1, ch2, ch3,...) - * - velocity scaling (for each noteon event, scale the velocity by 1.27 to give DX7 users - * a chance) - * - velocity switching ("v <=100: Angel Choir; V > 100: Hell's Bells") - * - get rid of aftertouch - * - ... - */ -int -fluid_midi_router_handle_midi_event(void* data, fluid_midi_event_t* event) -{ - fluid_midi_router_t* router=(fluid_midi_router_t*)data; - fluid_synth_t* synth = router->synth; - fluid_midi_router_rule_t* rule=NULL; - fluid_midi_router_rule_t* next_rule=NULL; - int event_has_par2=0; /* Flag, indicates that current event needs two parameters */ - int negative_event=0; /* Flag, indicates that current event releases a key / pedal */ - int par1_max=127; /* Range limit for par1 */ - int par2_max=127; /* Range limit for par2 */ - int ret_val=FLUID_OK; - - /* Some keyboards report noteoff through a noteon event with vel=0. - * Convert those to noteoff to ease processing.*/ - if (event->type == NOTE_ON && event->param2 == 0) { - /* Channel: Remains the same - * Param 1: Note number, remains the same - * Param 2: release velocity), set to max - */ - event->type = NOTE_OFF; - event->param2=127; - }; - - /* Lock the rules table, so that for example the shell thread doesn't - * clear the rules we are just working with */ - fluid_mutex_lock(router->ruletables_mutex); - - /* Depending on the event type, choose the correct table of rules. - * Also invoke the appropriate callback function for the event type - * to notify external applications. - * Note: An event type not listed here simply won't find any rules and - * will be ignored. - */ - switch (event->type) { - case NOTE_ON: - rule=router->note_rules; - event_has_par2=1; - break; - case NOTE_OFF: - rule=router->note_rules; - event_has_par2=1; - break; - case CONTROL_CHANGE: - rule=router->cc_rules; - event_has_par2=1; - break; - case PROGRAM_CHANGE: - rule=router->progchange_rules; - break; - case PITCH_BEND: - rule=router->pitchbend_rules; - par1_max=16383; - break; - case CHANNEL_PRESSURE: - rule=router->channel_pressure_rules; - break; - case KEY_PRESSURE: - rule=router->key_pressure_rules; - event_has_par2=1; - break; - case MIDI_SYSTEM_RESET: - return router->event_handler(router->event_handler_data,event); - default: - break; - } - - /* At this point 'rule' contains the first rule in a linked list. - * Check for all rules, whether channel and parameter ranges match. - */ - - while (rule){ - int chan; /* Channel of the generated event */ - int par1; /* par1 of the generated event */ - int par2=0; - int event_par1=(int)event->param1; - int event_par2=(int)event->param2; - fluid_midi_event_t new_event; - - /* Store the pointer to the next rule right now. If the rule is later flagged for destruction, - * it may not be accessed anymore. - */ - next_rule=rule->next; - - /* Check, whether the rule is still active. Expired rules cannot be removed immediately, - * because freeing memory in a realtime thread is no good idea. And the MIDI thread, - * which calls us here, has raised priority.*/ - if (rule->state == MIDIRULE_DONE){ - goto do_next_rule; - }; - - /* Channel window */ - if (rule->chan_min > rule->chan_max){ - /* Inverted rule: Exclude everything between max and min (but not min/max) */ - if (event->channel > rule->chan_max && event->channel < rule->chan_min){ - goto do_next_rule; - } - } else { - /* Normal rule: Exclude everything < max or > min (but not min/max) */ - if (event->channel > rule->chan_max || event->channel < rule->chan_min){ - goto do_next_rule; - } - }; - - /* Par 1 window */ - if (rule->par1_min > rule->par1_max){ - /* Inverted rule: Exclude everything between max and min (but not min/max) */ - if (event_par1 > rule->par1_max && event_par1 < rule->par1_min){ - goto do_next_rule; - } - } else { - /* Normal rule: Exclude everything < max or > min (but not min/max)*/ - if (event_par1 > rule->par1_max || event_par1 < rule->par1_min){ - goto do_next_rule; - } - }; - - /* Par 2 window (only applies to event types, which have 2 pars) - * For noteoff events, velocity switching doesn't make any sense. - * Velocity scaling might be useful, though. - */ - if (event_has_par2 && event->type != NOTE_OFF){ - if (rule->par2_min > rule->par2_max){ - /* Inverted rule: Exclude everything between max and min (but not min/max) */ - if (event_par2 > rule->par2_max && event_par2 < rule->par2_min){ - goto do_next_rule; - } - } else { - /* Normal rule: Exclude everything < max or > min (but not min/max)*/ - if (event_par2 > rule->par2_max || event_par2 < rule->par2_min){ - goto do_next_rule; - }; - }; - }; - - /* Channel scaling / offset - * Note: rule->chan_mul will probably be 0 or 1. If it's 0, input from all - * input channels is mapped to the same synth channel. - */ - chan=(int)((fluid_real_t)event->channel * (fluid_real_t)rule->chan_mul + (fluid_real_t)rule->chan_add + 0.5); - - /* Par 1 scaling / offset */ - par1=(int)((fluid_real_t)event_par1 * (fluid_real_t)rule->par1_mul + (fluid_real_t)rule->par1_add + 0.5); - - /* Par 2 scaling / offset, if applicable */ - if (event_has_par2){ - par2=(int)((fluid_real_t)event_par2 * (fluid_real_t)rule->par2_mul + (fluid_real_t)rule->par2_add + 0.5); - }; - - /* Channel range limiting */ - if (chan < 0){ - chan=0; - /* Upper limit is hard to implement, because the number of MIDI channels can be changed via settings any time. */ - }; - - /* Par1 range limiting */ - if (par1 < 0){ - par1=0; - } else if (par1 > par1_max){ - par1=par1_max; - }; - - /* Par2 range limiting */ - if (event_has_par2){ - if (par2 < 0){ - par2=0; - } else if (par2 > par2_max){ - par2=par2_max; - }; - }; - - /* At this point we have to create an event of event->type on 'chan' with par1 (maybe par2). - * We keep track on the state of noteon and sustain pedal events. If the application tries - * to delete a rule, it will only be fully removed, if pending noteoff / pedal off events have - * arrived. In the meantime (MIDIRULE_WAITING) state, it will only let through 'negative' events - * (noteoff or pedal up). - */ - - if ( - event->type == NOTE_ON - || (event->type == CONTROL_CHANGE && par1 == SUSTAIN_SWITCH && par2 >= 64) - ){ - /* Noteon or sustain pedal down event generated */ - if (rule->keys_cc[par1] == 0){ - rule->keys_cc[par1]=1; - rule->pending_events++; - }; - } else if ( - event->type == NOTE_OFF - || (event->type == CONTROL_CHANGE && par1 == SUSTAIN_SWITCH && par2 < 64) - ){ - /* Noteoff or sustain pedal up event generated */ - if (rule->keys_cc[par1] > 0){ - rule->keys_cc[par1]=0; - rule->pending_events--; - negative_event=1; - }; - }; - - if (rule->state == MIDIRULE_WAITING){ - if (negative_event){ - if (rule->pending_events == 0){ - /* There are no more pending events in the rule - all keys are up. - * Change its state to 'unused', it will be cleared up at the next - * opportunity to run 'free' safely. - * Note: After this, the rule may disappear at any time - */ - rule->state=MIDIRULE_DONE; - }; - } else { - - /* This rule only exists because of some unfinished business: - * There is still a note or sustain pedal waiting to be - * released. But the event that came in does not release any. - * So we just ignore the event and go on with the next rule. - */ - goto do_next_rule; - }; - }; - - /* At this point it is decided, what is sent to the synth. - * Create a new event and make the appropriate call - */ - - fluid_midi_event_set_type(&new_event, event->type); - fluid_midi_event_set_channel(&new_event, chan); -/* fluid_midi_event_set_param1(&new_event, par1); */ -/* fluid_midi_event_set_param2(&new_event, par2); */ - new_event.param1 = par1; - new_event.param2 = par2; - - /* Don't know what to do with return values: What is, if - * generating one event fails? Current solution: Make all calls, - * regardless of failures, but report failure to the caller, as - * soon as only one call fails. Strategy should be thought - * through. - */ - if (router->event_handler(router->event_handler_data, &new_event) != FLUID_OK) { - ret_val=FLUID_FAILED; - } - - do_next_rule: - rule=next_rule; - }; - - /* We are finished with the rule tables. Allow the other threads to do their job. */ - fluid_mutex_unlock(router->ruletables_mutex); - - return ret_val; -} - -int fluid_midi_router_handle_clear(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - fluid_midi_router_t* router=synth->midi_router; - - if (ac != 0) { - fluid_ostream_printf(out, "router_clear needs no arguments.\n"); - goto error_recovery; - } - - /* Disable rules and mark for destruction */ - fluid_midi_router_disable_all_rules(router); - - /* Free unused rules */ - fluid_midi_router_free_unused_rules(router); - - return 0; - error_recovery: - return -1; -}; - -int fluid_midi_router_handle_default(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - fluid_midi_router_t* router=synth->midi_router; - - if (ac != 0) { - fluid_ostream_printf(out, "router_default needs no arguments.\n"); - return -1; - } - - /* Disable rules and mark for destruction */ - fluid_midi_router_disable_all_rules(router); - - /* Create default rules */ - if (fluid_midi_router_create_default_rules(router) != FLUID_OK){ - FLUID_LOG(FLUID_ERR, "create_default_rules failed"); - goto error_recovery; - }; - - /* Free unused rules */ - fluid_midi_router_free_unused_rules(router); - - return 0; - error_recovery: - return -1; -}; - -int fluid_midi_router_handle_begin(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - fluid_midi_router_t* router=synth->midi_router; - fluid_midi_router_rule_t** dest=NULL; - - if (ac != 1) { - fluid_ostream_printf(out, "router_begin needs no arguments.\n"); - goto error_recovery; - } - - if (FLUID_STRCMP(av[0],"note") == 0){ - dest=& router->note_rules; - } else if (FLUID_STRCMP(av[0],"cc") == 0){ - dest=& router->cc_rules; - } else if (FLUID_STRCMP(av[0],"prog") == 0){ - dest=& router->progchange_rules; - } else if (FLUID_STRCMP(av[0],"pbend") == 0){ - dest=& router->pitchbend_rules; - } else if (FLUID_STRCMP(av[0],"cpress") == 0){ - dest=& router->channel_pressure_rules; - } else if (FLUID_STRCMP(av[0],"kpress") == 0){ - dest=& router->key_pressure_rules; - }; - - if (dest == NULL){ - fluid_ostream_printf(out, "router_begin args: note, cc, prog, pbend, cpress, kpress\n"); - goto error_recovery; - }; - - if (fluid_midi_router_begin(router, dest) != FLUID_OK){ - goto error_recovery; - }; - - /* Free unused rules (give it a try) */ - fluid_midi_router_free_unused_rules(router); - - return 0; - - error_recovery: - return -1; -}; - -int fluid_midi_router_handle_end(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - fluid_midi_router_t* router=synth->midi_router; - - if (ac != 0) { - fluid_ostream_printf(out, "router_end needs no arguments."); - goto error_recovery; - } - - if (fluid_midi_router_end(router) != FLUID_OK){ - FLUID_LOG(FLUID_ERR, "midi_router_end failed"); - goto error_recovery; - }; - - /* Free unused rules (give it a try) */ - fluid_midi_router_free_unused_rules(router); - - return 0; - - error_recovery: - return -1; -}; - -int fluid_midi_router_handle_chan(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - fluid_midi_router_t* router=synth->midi_router; - - if (ac != 4) { - fluid_ostream_printf(out, "router_chan needs four args: min, max, mul, add."); - goto error_recovery; - } - - router->new_rule_chan_min=atoi(av[0]); - router->new_rule_chan_max=atoi(av[1]); - router->new_rule_chan_mul=atoi(av[2]); - router->new_rule_chan_add=atoi(av[3]); - - /* Free unused rules (give it a try) */ - fluid_midi_router_free_unused_rules(router); - - return 0; - - error_recovery: - return -1; -}; - -int fluid_midi_router_handle_par1(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - fluid_midi_router_t* router=synth->midi_router; - - if (ac != 4) { - fluid_ostream_printf(out, "router_par1 needs four args: min, max, mul, add."); - goto error_recovery; - } - - router->new_rule_par1_min=atoi(av[0]); - router->new_rule_par1_max=atoi(av[1]); - router->new_rule_par1_mul=atoi(av[2]); - router->new_rule_par1_add=atoi(av[3]); - - /* Free unused rules (give it a try) */ - fluid_midi_router_free_unused_rules(router); - - return 0; - - error_recovery: - return -1; -}; - -int fluid_midi_router_handle_par2(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out) -{ - fluid_midi_router_t* router=synth->midi_router; - - if (ac != 4) { - fluid_ostream_printf(out, "router_par2 needs four args: min, max, mul, add."); - goto error_recovery; - } - - router->new_rule_par2_min=atoi(av[0]); - router->new_rule_par2_max=atoi(av[1]); - router->new_rule_par2_mul=atoi(av[2]); - router->new_rule_par2_add=atoi(av[3]); - - /* Free unused rules (give it a try) */ - fluid_midi_router_free_unused_rules(router); - return 0; - - error_recovery: - return -1; -}; - -void fluid_midi_router_disable_all_rules(fluid_midi_router_t* router) -{ - /* Go through all rules. If the rule has no outstanding events, then - * flag it for destruction. Otherwise change it to wait mode. Then - * it will handle the pending events, and flag itself for destruction - * as soon as all events have arrived. - */ - - fluid_midi_router_rule_t* rules[6]; - fluid_midi_router_rule_t* current_rule; - int i; - rules[0]=router->note_rules; - rules[1]=router->cc_rules; - rules[2]=router->progchange_rules; - rules[3]=router->pitchbend_rules; - rules[4]=router->channel_pressure_rules; - rules[5]=router->key_pressure_rules; - - /* Lock the rules table. We live on the assumption, that the rules - * table does not change while we are chewing at it. - * Changes between the processing of note / cc etc are permitted. - */ - for (i=0; i < 6; i++){ - fluid_mutex_lock(router->ruletables_mutex); - current_rule=rules[i]; - while (current_rule){ - if (current_rule->pending_events == 0){ - /* Flag for destruction */ - current_rule->state=MIDIRULE_DONE; - } else { - /* Wait mode */ - current_rule->state=MIDIRULE_WAITING; - }; - current_rule=current_rule->next; - }; - fluid_mutex_unlock(router->ruletables_mutex); - }; -}; - -void fluid_midi_router_free_unused_rules(fluid_midi_router_t* router) -{ - int i; - - for (i=0; i < 6; i++){ - fluid_midi_router_rule_t** p=NULL; - - /* We assume, that the table does not change while we are at it. - * Between different types (note, cc etc) we can allow changes. - */ - fluid_mutex_lock(router->ruletables_mutex); - switch(i){ - case 0: - p=&router->note_rules; - break; - case 1: - p=&router->cc_rules; - break; - case 2: - p=&router->progchange_rules; - break; - case 3: - p=&router->pitchbend_rules; - break; - case 4: - p=&router->channel_pressure_rules; - break; - case 5: - p=&router->key_pressure_rules; - break; - default: - break; - }; - - while (*p){ - fluid_midi_router_rule_t* current_rule=*p; - fluid_midi_router_rule_t* next_rule=current_rule->next; - - if (current_rule->state == MIDIRULE_DONE){ - /* p points to current_rule. - * current_rule->next points to next_rule. - * Unlink current_rule from the chain by setting the content - * of p to next_rule. - */ - - *p=next_rule; - - /* Now the rule is not in the chain anymore. Destroy it. */ - delete_fluid_midi_router_rule(current_rule); - - } else { - /* We have to keep the rule, there is still unfinished business. */ - p = ¤t_rule->next; - }; - }; - fluid_mutex_unlock(router->ruletables_mutex); - }; -}; - -/** - * MIDI event callback function to display event information to stdout - * @param data MIDI router instance - * @param event MIDI event data - * @return 0 on success, -1 otherwise - * - * An implementation of the #handle_midi_event_func_t function type, used for - * displaying MIDI event information between the MIDI driver and router to - * stdout. Useful for adding into a MIDI router chain for debugging MIDI events. - */ -int fluid_midi_dump_prerouter(void* data, fluid_midi_event_t* event) -{ - switch (event->type) { - case NOTE_ON: - fprintf(stdout, "event_pre_noteon %i %i %i\n", - event->channel, event->param1, event->param2); - break; - case NOTE_OFF: - fprintf(stdout, "event_pre_noteoff %i %i %i\n", - event->channel, event->param1, event->param2); - break; - case CONTROL_CHANGE: - fprintf(stdout, "event_pre_cc %i %i %i\n", - event->channel, event->param1, event->param2); - break; - case PROGRAM_CHANGE: - fprintf(stdout, "event_pre_prog %i %i\n", event->channel, event->param1); - break; - case PITCH_BEND: - fprintf(stdout, "event_pre_pitch %i %i\n", event->channel, event->param1); - break; - case CHANNEL_PRESSURE: - fprintf(stdout, "event_pre_cpress %i %i\n", event->channel, event->param1); - break; - case KEY_PRESSURE: - fprintf(stdout, "event_pre_kpress %i %i %i\n", - event->channel, event->param1, event->param2); - break; - default: - break; - }; - return fluid_midi_router_handle_midi_event((fluid_midi_router_t*) data, event); -}; - -/** - * MIDI event callback function to display event information to stdout - * @param data MIDI router instance - * @param event MIDI event data - * @return 0 on success, -1 otherwise - * - * An implementation of the #handle_midi_event_func_t function type, used for - * displaying MIDI event information between the MIDI driver and router to - * stdout. Useful for adding into a MIDI router chain for debugging MIDI events. - */ -int fluid_midi_dump_postrouter(void* data, fluid_midi_event_t* event) -{ - switch (event->type) { - case NOTE_ON: - fprintf(stdout, "event_post_noteon %i %i %i\n", - event->channel, event->param1, event->param2); - break; - case NOTE_OFF: - fprintf(stdout, "event_post_noteoff %i %i %i\n", - event->channel, event->param1, event->param2); - break; - case CONTROL_CHANGE: - fprintf(stdout, "event_post_cc %i %i %i\n", - event->channel, event->param1, event->param2); - break; - case PROGRAM_CHANGE: - fprintf(stdout, "event_post_prog %i %i\n", event->channel, event->param1); - break; - case PITCH_BEND: - fprintf(stdout, "event_post_pitch %i %i\n", event->channel, event->param1); - break; - case CHANNEL_PRESSURE: - fprintf(stdout, "event_post_cpress %i %i\n", event->channel, event->param1); - break; - case KEY_PRESSURE: - fprintf(stdout, "event_post_kpress %i %i %i\n", - event->channel, event->param1, event->param2); - break; - default: - break; - }; - return fluid_synth_handle_midi_event((fluid_synth_t*) data, event); -}; diff --git a/src/libs/fluidsynth/src/fluid_midi_router.h b/src/libs/fluidsynth/src/fluid_midi_router.h deleted file mode 100644 index 4a1fce4a8a..0000000000 --- a/src/libs/fluidsynth/src/fluid_midi_router.h +++ /dev/null @@ -1,112 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -/* Author: Markus Nentwig, nentwig@users.sourceforge.net - */ - -#ifndef _FLUID_MIDIROUTER_H -#define _FLUID_MIDIROUTER_H - -#include "fluidsynth_priv.h" -#include "fluid_midi.h" -#include "fluid_sys.h" - - - -void fluid_midi_router_destroy_all_rules(fluid_midi_router_t* router); -fluid_midi_router_rule_t* new_fluid_midi_router_rule(void); - -int fluid_midi_router_handle_clear(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_midi_router_handle_default(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_midi_router_handle_begin(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_midi_router_handle_chan(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_midi_router_handle_par1(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_midi_router_handle_par2(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); -int fluid_midi_router_handle_end(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out); - -int fluid_midi_router_begin(fluid_midi_router_t* router, fluid_midi_router_rule_t** dest); -int fluid_midi_router_end(fluid_midi_router_t* router); -int fluid_midi_router_create_default_rules(fluid_midi_router_t* router); -void fluid_midi_router_disable_all_rules(fluid_midi_router_t* router); -void fluid_midi_router_free_unused_rules(fluid_midi_router_t* router); - -/* - * fluid_midi_router - */ -struct _fluid_midi_router_t { - fluid_synth_t* synth; - - fluid_midi_router_rule_t* note_rules; - fluid_midi_router_rule_t* cc_rules; - fluid_midi_router_rule_t* progchange_rules; - fluid_midi_router_rule_t* pitchbend_rules; - fluid_midi_router_rule_t* channel_pressure_rules; - fluid_midi_router_rule_t* key_pressure_rules; - - int new_rule_chan_min; - int new_rule_chan_max; - double new_rule_chan_mul; - int new_rule_chan_add; - int new_rule_par1_min; - int new_rule_par1_max; - double new_rule_par1_mul; - int new_rule_par1_add; - int new_rule_par2_min; - int new_rule_par2_max; - double new_rule_par2_mul; - int new_rule_par2_add; - - fluid_midi_router_rule_t** dest; - - handle_midi_event_func_t event_handler; /* Callback function for generated events */ - void* event_handler_data; /* One arg for the callback */ - - int nr_midi_channels; /* For clipping the midi channel */ - fluid_mutex_t ruletables_mutex; -}; - -struct _fluid_midi_router_rule_t { - int chan_min; /* Channel window, for which this rule is valid */ - int chan_max; - fluid_real_t chan_mul; /* Channel multiplier (usually 0 or 1) */ - int chan_add; /* Channel offset */ - - int par1_min; /* Parameter 1 window, for which this rule is valid */ - int par1_max; - fluid_real_t par1_mul; - int par1_add; - - int par2_min; /* Parameter 2 window, for which this rule is valid */ - int par2_max; - fluid_real_t par2_mul; - int par2_add; - - int pending_events; /* In case of noteon: How many keys are still down? */ - char keys_cc[128]; /* Flags, whether a key is down / controller is set (sustain) */ - fluid_midi_router_rule_t* next; /* next entry */ - int state; /* Does this rule expire, as soon as (for example) all keys are up? */ -}; - -enum fluid_midirule_state { - MIDIRULE_ACTIVE = 0x00, - MIDIRULE_WAITING, - MIDIRULE_DONE -}; -#endif diff --git a/src/libs/fluidsynth/src/fluid_mod.c b/src/libs/fluidsynth/src/fluid_mod.c deleted file mode 100644 index a092e4259e..0000000000 --- a/src/libs/fluidsynth/src/fluid_mod.c +++ /dev/null @@ -1,434 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#include "fluid_mod.h" -#include "fluid_chan.h" -#include "fluid_voice.h" - -/* - * fluid_mod_clone - */ -void -fluid_mod_clone(fluid_mod_t* mod, fluid_mod_t* src) -{ - mod->dest = src->dest; - mod->src1 = src->src1; - mod->flags1 = src->flags1; - mod->src2 = src->src2; - mod->flags2 = src->flags2; - mod->amount = src->amount; -} - -/* - * fluid_mod_set_source1 - */ -void -fluid_mod_set_source1(fluid_mod_t* mod, int src, int flags) -{ - mod->src1 = src; - mod->flags1 = flags; -} - -/* - * fluid_mod_set_source2 - */ -void -fluid_mod_set_source2(fluid_mod_t* mod, int src, int flags) -{ - mod->src2 = src; - mod->flags2 = flags; -} - -/* - * fluid_mod_set_dest - */ -void -fluid_mod_set_dest(fluid_mod_t* mod, int dest) -{ - mod->dest = dest; -} - -/* - * fluid_mod_set_amount - */ -void -fluid_mod_set_amount(fluid_mod_t* mod, double amount) -{ - mod->amount = (double) amount; -} - -int fluid_mod_get_source1(fluid_mod_t* mod) -{ - return mod->src1; -} - -int fluid_mod_get_flags1(fluid_mod_t* mod) -{ - return mod->flags1; -} - -int fluid_mod_get_source2(fluid_mod_t* mod) -{ - return mod->src2; -} - -int fluid_mod_get_flags2(fluid_mod_t* mod) -{ - return mod->flags2; -} - -int fluid_mod_get_dest(fluid_mod_t* mod) -{ - return mod->dest; -} - -double fluid_mod_get_amount(fluid_mod_t* mod) -{ - return (fluid_real_t) mod->amount; -} - - -/* - * fluid_mod_get_value - */ -fluid_real_t -fluid_mod_get_value(fluid_mod_t* mod, fluid_channel_t* chan, fluid_voice_t* voice) -{ - fluid_real_t v1 = 0.0, v2 = 1.0; - fluid_real_t range1 = 127.0, range2 = 127.0; - - if (chan == NULL) { - return 0.0f; - } - - /* 'special treatment' for default controller - * - * Reference: SF2.01 section 8.4.2 - * - * The GM default controller 'vel-to-filter cut off' is not clearly - * defined: If implemented according to the specs, the filter - * frequency jumps between vel=63 and vel=64. To maintain - * compatibility with existing sound fonts, the implementation is - * 'hardcoded', it is impossible to implement using only one - * modulator otherwise. - * - * I assume here, that the 'intention' of the paragraph is one - * octave (1200 cents) filter frequency shift between vel=127 and - * vel=64. 'amount' is (-2400), at least as long as the controller - * is set to default. - * - * Further, the 'appearance' of the modulator (source enumerator, - * destination enumerator, flags etc) is different from that - * described in section 8.4.2, but it matches the definition used in - * several SF2.1 sound fonts (where it is used only to turn it off). - * */ - if ((mod->src2 == FLUID_MOD_VELOCITY) && - (mod->src1 == FLUID_MOD_VELOCITY) && - (mod->flags1 == (FLUID_MOD_GC | FLUID_MOD_UNIPOLAR - | FLUID_MOD_NEGATIVE | FLUID_MOD_LINEAR)) && - (mod->flags2 == (FLUID_MOD_GC | FLUID_MOD_UNIPOLAR - | FLUID_MOD_POSITIVE | FLUID_MOD_SWITCH)) && - (mod->dest == GEN_FILTERFC)) { -// S. Christian Collins' mod, to stop forcing velocity based filtering -/* - if (voice->vel < 64){ - return (fluid_real_t) mod->amount / 2.0; - } else { - return (fluid_real_t) mod->amount * (127 - voice->vel) / 127; - } -*/ - return 0; // (fluid_real_t) mod->amount / 2.0; - } -// end S. Christian Collins' mod - - /* get the initial value of the first source */ - if (mod->src1 > 0) { - if (mod->flags1 & FLUID_MOD_CC) { - v1 = fluid_channel_get_cc(chan, mod->src1); - } else { /* source 1 is one of the direct controllers */ - switch (mod->src1) { - case FLUID_MOD_NONE: /* SF 2.01 8.2.1 item 0: src enum=0 => value is 1 */ - v1 = range1; - break; - case FLUID_MOD_VELOCITY: - v1 = voice->vel; - break; - case FLUID_MOD_KEY: - v1 = voice->key; - break; - case FLUID_MOD_KEYPRESSURE: - v1 = chan->key_pressure; - break; - case FLUID_MOD_CHANNELPRESSURE: - v1 = chan->channel_pressure; - break; - case FLUID_MOD_PITCHWHEEL: - v1 = chan->pitch_bend; - range1 = 0x4000; - break; - case FLUID_MOD_PITCHWHEELSENS: - v1 = chan->pitch_wheel_sensitivity; - break; - default: - v1 = 0.0; - } - } - - /* transform the input value */ - switch (mod->flags1 & 0x0f) { - case 0: /* linear, unipolar, positive */ - v1 /= range1; - break; - case 1: /* linear, unipolar, negative */ - v1 = 1.0f - v1 / range1; - break; - case 2: /* linear, bipolar, positive */ - v1 = -1.0f + 2.0f * v1 / range1; - break; - case 3: /* linear, bipolar, negative */ - v1 = 1.0f - 2.0f * v1 / range1; - break; - case 4: /* concave, unipolar, positive */ - v1 = fluid_concave(v1); - break; - case 5: /* concave, unipolar, negative */ - v1 = fluid_concave(127 - v1); - break; - case 6: /* concave, bipolar, positive */ - v1 = (v1 > 64)? fluid_concave(2 * (v1 - 64)) : -fluid_concave(2 * (64 - v1)); - break; - case 7: /* concave, bipolar, negative */ - v1 = (v1 > 64)? -fluid_concave(2 * (v1 - 64)) : fluid_concave(2 * (64 - v1)); - break; - case 8: /* convex, unipolar, positive */ - v1 = fluid_convex(v1); - break; - case 9: /* convex, unipolar, negative */ - v1 = fluid_convex(127 - v1); - break; - case 10: /* convex, bipolar, positive */ - v1 = (v1 > 64)? fluid_convex(2 * (v1 - 64)) : -fluid_convex(2 * (64 - v1)); - break; - case 11: /* convex, bipolar, negative */ - v1 = (v1 > 64)? -fluid_convex(2 * (v1 - 64)) : fluid_convex(2 * (64 - v1)); - break; - case 12: /* switch, unipolar, positive */ - v1 = (v1 >= 64)? 1.0f : 0.0f; - break; - case 13: /* switch, unipolar, negative */ - v1 = (v1 >= 64)? 0.0f : 1.0f; - break; - case 14: /* switch, bipolar, positive */ - v1 = (v1 >= 64)? 1.0f : -1.0f; - break; - case 15: /* switch, bipolar, negative */ - v1 = (v1 >= 64)? -1.0f : 1.0f; - break; - } - } else { - return 0.0; - } - - /* no need to go further */ - if (v1 == 0.0f) { - return 0.0f; - } - - /* get the second input source */ - if (mod->src2 > 0) { - if (mod->flags2 & FLUID_MOD_CC) { - v2 = fluid_channel_get_cc(chan, mod->src2); - } else { - switch (mod->src2) { - case FLUID_MOD_NONE: /* SF 2.01 8.2.1 item 0: src enum=0 => value is 1 */ - v2 = range2; - break; - case FLUID_MOD_VELOCITY: - v2 = voice->vel; - break; - case FLUID_MOD_KEY: - v2 = voice->key; - break; - case FLUID_MOD_KEYPRESSURE: - v2 = chan->key_pressure; - break; - case FLUID_MOD_CHANNELPRESSURE: - v2 = chan->channel_pressure; - break; - case FLUID_MOD_PITCHWHEEL: - v2 = chan->pitch_bend; - break; - case FLUID_MOD_PITCHWHEELSENS: - v2 = chan->pitch_wheel_sensitivity; - break; - default: - v1 = 0.0f; - } - } - - /* transform the second input value */ - switch (mod->flags2 & 0x0f) { - case 0: /* linear, unipolar, positive */ - v2 /= range2; - break; - case 1: /* linear, unipolar, negative */ - v2 = 1.0f - v2 / range2; - break; - case 2: /* linear, bipolar, positive */ - v2 = -1.0f + 2.0f * v2 / range2; - break; - case 3: /* linear, bipolar, negative */ - v2 = -1.0f + 2.0f * v2 / range2; - break; - case 4: /* concave, unipolar, positive */ - v2 = fluid_concave(v2); - break; - case 5: /* concave, unipolar, negative */ - v2 = fluid_concave(127 - v2); - break; - case 6: /* concave, bipolar, positive */ - v2 = (v2 > 64)? fluid_concave(2 * (v2 - 64)) : -fluid_concave(2 * (64 - v2)); - break; - case 7: /* concave, bipolar, negative */ - v2 = (v2 > 64)? -fluid_concave(2 * (v2 - 64)) : fluid_concave(2 * (64 - v2)); - break; - case 8: /* convex, unipolar, positive */ - v2 = fluid_convex(v2); - break; - case 9: /* convex, unipolar, negative */ - v2 = 1.0f - fluid_convex(v2); - break; - case 10: /* convex, bipolar, positive */ - v2 = (v2 > 64)? -fluid_convex(2 * (v2 - 64)) : fluid_convex(2 * (64 - v2)); - break; - case 11: /* convex, bipolar, negative */ - v2 = (v2 > 64)? -fluid_convex(2 * (v2 - 64)) : fluid_convex(2 * (64 - v2)); - break; - case 12: /* switch, unipolar, positive */ - v2 = (v2 >= 64)? 1.0f : 0.0f; - break; - case 13: /* switch, unipolar, negative */ - v2 = (v2 >= 64)? 0.0f : 1.0f; - break; - case 14: /* switch, bipolar, positive */ - v2 = (v2 >= 64)? 1.0f : -1.0f; - break; - case 15: /* switch, bipolar, negative */ - v2 = (v2 >= 64)? -1.0f : 1.0f; - break; - } - } else { - v2 = 1.0f; - } - - /* it's as simple as that: */ - return (fluid_real_t) mod->amount * v1 * v2; -} - -/* - * fluid_mod_new - */ -fluid_mod_t* -fluid_mod_new() -{ - fluid_mod_t* mod = FLUID_NEW(fluid_mod_t); - if (mod == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - return mod; -}; - -/* - * fluid_mod_delete - */ -void -fluid_mod_delete(fluid_mod_t * mod) -{ - FLUID_FREE(mod); -}; - -/* - * fluid_mod_test_identity - */ -/* Purpose: - * Checks, if two modulators are identical. - * SF2.01 section 9.5.1 page 69, 'bullet' 3 defines 'identical'. - */ -int fluid_mod_test_identity(fluid_mod_t * mod1, fluid_mod_t * mod2){ - if (mod1->dest != mod2->dest){return 0;}; - if (mod1->src1 != mod2->src1){return 0;}; - if (mod1->src2 != mod2->src2){return 0;}; - if (mod1->flags1 != mod2->flags1){return 0;} - if (mod1->flags2 != mod2->flags2){return 0;} - return 1; -}; - -/* debug function: Prints the contents of a modulator */ -void fluid_dump_modulator(fluid_mod_t * mod){ - int src1=mod->src1; - int dest=mod->dest; - int src2=mod->src2; - int flags1=mod->flags1; - int flags2=mod->flags2; - fluid_real_t amount=(fluid_real_t)mod->amount; - - printf("Src: "); - if (flags1 & FLUID_MOD_CC){ - printf("MIDI CC=%i",src1); - } else { - switch(src1){ - case FLUID_MOD_NONE: - printf("None"); break; - case FLUID_MOD_VELOCITY: - printf("note-on velocity"); break; - case FLUID_MOD_KEY: - printf("Key nr"); break; - case FLUID_MOD_KEYPRESSURE: - printf("Poly pressure"); break; - case FLUID_MOD_CHANNELPRESSURE: - printf("Chan pressure"); break; - case FLUID_MOD_PITCHWHEEL: - printf("Pitch Wheel"); break; - case FLUID_MOD_PITCHWHEELSENS: - printf("Pitch Wheel sens"); break; - default: - printf("(unknown: %i)", src1); - }; /* switch src1 */ - }; /* if not CC */ - if (flags1 & FLUID_MOD_NEGATIVE){printf("- ");} else {printf("+ ");}; - if (flags1 & FLUID_MOD_BIPOLAR){printf("bip ");} else {printf("unip ");}; - printf("-> "); - switch(dest){ - case GEN_FILTERQ: printf("Q"); break; - case GEN_FILTERFC: printf("fc"); break; - case GEN_VIBLFOTOPITCH: printf("VibLFO-to-pitch"); break; - case GEN_MODENVTOPITCH: printf("ModEnv-to-pitch"); break; - case GEN_MODLFOTOPITCH: printf("ModLFO-to-pitch"); break; - case GEN_CHORUSSEND: printf("Chorus send"); break; - case GEN_REVERBSEND: printf("Reverb send"); break; - case GEN_PAN: printf("pan"); break; - case GEN_ATTENUATION: printf("att"); break; - default: printf("dest %i",dest); - }; /* switch dest */ - printf(", amount %f flags %i src2 %i flags2 %i\n",amount, flags1, src2, flags2); -}; - - diff --git a/src/libs/fluidsynth/src/fluid_mod.h b/src/libs/fluidsynth/src/fluid_mod.h deleted file mode 100644 index 31fb124618..0000000000 --- a/src/libs/fluidsynth/src/fluid_mod.h +++ /dev/null @@ -1,40 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#ifndef _FLUID_MOD_H -#define _FLUID_MOD_H - -#include "fluidsynth_priv.h" -#include "fluid_conv.h" - -void fluid_mod_clone(fluid_mod_t* mod, fluid_mod_t* src); -fluid_real_t fluid_mod_get_value(fluid_mod_t* mod, fluid_channel_t* chan, fluid_voice_t* voice); -void fluid_dump_modulator(fluid_mod_t * mod); - -#define fluid_mod_has_source(mod,cc,ctrl) \ -( ((((mod)->src1 == ctrl) && (((mod)->flags1 & FLUID_MOD_CC) != 0) && (cc != 0)) \ - || ((((mod)->src1 == ctrl) && (((mod)->flags1 & FLUID_MOD_CC) == 0) && (cc == 0)))) \ -|| ((((mod)->src2 == ctrl) && (((mod)->flags2 & FLUID_MOD_CC) != 0) && (cc != 0)) \ - || ((((mod)->src2 == ctrl) && (((mod)->flags2 & FLUID_MOD_CC) == 0) && (cc == 0))))) - -#define fluid_mod_has_dest(mod,gen) ((mod)->dest == gen) - - -#endif /* _FLUID_MOD_H */ diff --git a/src/libs/fluidsynth/src/fluid_phase.h b/src/libs/fluidsynth/src/fluid_phase.h deleted file mode 100644 index 59baa668ac..0000000000 --- a/src/libs/fluidsynth/src/fluid_phase.h +++ /dev/null @@ -1,117 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - - -#ifndef _FLUID_PHASE_H -#define _FLUID_PHASE_H - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -/* - * phase - */ - -#define FLUID_INTERP_BITS 8 -#define FLUID_INTERP_BITS_MASK 0xff000000 -#define FLUID_INTERP_BITS_SHIFT 24 -#define FLUID_INTERP_MAX 256 - -#define FLUID_FRACT_MAX ((double)4294967296.0) - -/* fluid_phase_t -* Purpose: -* Playing pointer for voice playback -* -* When a sample is played back at a different pitch, the playing pointer in the -* source sample will not advance exactly one sample per output sample. -* This playing pointer is implemented using fluid_phase_t. -* It is a 64 bit number. The higher 32 bits contain the 'index' (number of -* the current sample), the lower 32 bits the fractional part. -*/ -typedef unsigned long long fluid_phase_t; - -/* Purpose: - * Set a to b. - * a: fluid_phase_t - * b: fluid_phase_t - */ -#define fluid_phase_set(a,b) a=b; - -#define fluid_phase_set_int(a, b) ((a) = ((unsigned long long)(b)) << 32) - -/* Purpose: - * Sets the phase a to a phase increment given in b. - * For example, assume b is 0.9. After setting a to it, adding a to - * the playing pointer will advance it by 0.9 samples. */ -#define fluid_phase_set_float(a, b) \ - (a) = (((unsigned long long)(b)) << 32) \ - | (uint32) (((double)(b) - (int)(b)) * (double)FLUID_FRACT_MAX) - -/* create a fluid_phase_t from an index and a fraction value */ -#define fluid_phase_from_index_fract(index, fract) \ - ((((unsigned long long)(index)) << 32) + (fract)) - -/* Purpose: - * Return the index and the fractional part, respectively. */ -#define fluid_phase_index(_x) \ - ((unsigned int)((_x) >> 32)) -#define fluid_phase_fract(_x) \ - ((uint32)((_x) & 0xFFFFFFFF)) - -/* Get the phase index with fractional rounding */ -#define fluid_phase_index_round(_x) \ - ((unsigned int)(((_x) + 0x80000000) >> 32)) - - -/* Purpose: - * Takes the fractional part of the argument phase and - * calculates the corresponding position in the interpolation table. - * The fractional position of the playing pointer is calculated with a quite high - * resolution (32 bits). It would be unpractical to keep a set of interpolation - * coefficients for each possible fractional part... - */ -#define fluid_phase_fract_to_tablerow(_x) \ - ((unsigned int)(fluid_phase_fract(_x) & FLUID_INTERP_BITS_MASK) >> FLUID_INTERP_BITS_SHIFT) - -#define fluid_phase_double(_x) \ - ((double)(fluid_phase_index(_x)) + ((double)fluid_phase_fract(_x) / FLUID_FRACT_MAX)) - -/* Purpose: - * Advance a by a step of b (both are fluid_phase_t). - */ -#define fluid_phase_incr(a, b) a += b - -/* Purpose: - * Subtract b from a (both are fluid_phase_t). - */ -#define fluid_phase_decr(a, b) a -= b - -/* Purpose: - * Subtract b samples from a. - */ -#define fluid_phase_sub_int(a, b) ((a) -= (unsigned long long)(b) << 32) - -/* Purpose: - * Creates the expression a.index++. */ -#define fluid_phase_index_plusplus(a) (((a) += 0x100000000LL) - -#endif /* _FLUID_PHASE_H */ diff --git a/src/libs/fluidsynth/src/fluid_ramsfont.c b/src/libs/fluidsynth/src/fluid_ramsfont.c deleted file mode 100644 index 5df20eb59e..0000000000 --- a/src/libs/fluidsynth/src/fluid_ramsfont.c +++ /dev/null @@ -1,1117 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#include "fluid_ramsfont.h" -#include "fluid_sys.h" -#include "fluid_synth.h" - -/* thenumber of samples before the start and after the end */ -#define SAMPLE_LOOP_MARGIN 8 - -/* Prototypes */ -int fluid_rampreset_add_sample(fluid_rampreset_t* preset, fluid_sample_t* sample, int lokey, int hikey); -int fluid_rampreset_izone_set_gen(fluid_rampreset_t* preset, fluid_sample_t* sample, int gen_type, float value); -int fluid_rampreset_izone_set_loop(fluid_rampreset_t* preset, fluid_sample_t* sample, int on, float loopstart, float loopend); -int fluid_rampreset_remove_izone(fluid_rampreset_t* preset, fluid_sample_t* sample); -void fluid_rampreset_updatevoices(fluid_rampreset_t* preset, int gen_type, float val); - -/* - * fluid_ramsfont_create_sfont - */ -fluid_sfont_t* -fluid_ramsfont_create_sfont() -{ - fluid_sfont_t* sfont; - fluid_ramsfont_t* ramsfont; - - ramsfont = new_fluid_ramsfont(); - if (ramsfont == NULL) { - return NULL; - } - - sfont = FLUID_NEW(fluid_sfont_t); - if (sfont == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - - sfont->data = ramsfont; - sfont->free = fluid_ramsfont_sfont_delete; - sfont->get_name = fluid_ramsfont_sfont_get_name; - sfont->get_preset = fluid_ramsfont_sfont_get_preset; - sfont->iteration_start = fluid_ramsfont_sfont_iteration_start; - sfont->iteration_next = fluid_ramsfont_sfont_iteration_next; - - return sfont; - -} - -/*************************************************************** - * - * PUBLIC INTERFACE - */ - -int fluid_ramsfont_sfont_delete(fluid_sfont_t* sfont) -{ - if (delete_fluid_ramsfont(sfont->data) != 0) - return -1; - FLUID_FREE(sfont); - return 0; -} - -char* fluid_ramsfont_sfont_get_name(fluid_sfont_t* sfont) -{ - return fluid_ramsfont_get_name((fluid_ramsfont_t*) sfont->data); -} - -fluid_preset_t* fluid_ramsfont_sfont_get_preset(fluid_sfont_t* sfont, unsigned int bank, unsigned int prenum) -{ - fluid_preset_t* preset; - fluid_rampreset_t* rampreset; - - rampreset = fluid_ramsfont_get_preset((fluid_ramsfont_t*) sfont->data, bank, prenum); - - if (rampreset == NULL) { - return NULL; - } - - preset = FLUID_NEW(fluid_preset_t); - if (preset == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - - preset->sfont = sfont; - preset->data = rampreset; - preset->free = fluid_rampreset_preset_delete; - preset->get_name = fluid_rampreset_preset_get_name; - preset->get_banknum = fluid_rampreset_preset_get_banknum; - preset->get_num = fluid_rampreset_preset_get_num; - preset->noteon = fluid_rampreset_preset_noteon; - preset->notify = NULL; - - return preset; -} - -void fluid_ramsfont_sfont_iteration_start(fluid_sfont_t* sfont) -{ - fluid_ramsfont_iteration_start((fluid_ramsfont_t*) sfont->data); -} - -int fluid_ramsfont_sfont_iteration_next(fluid_sfont_t* sfont, fluid_preset_t* preset) -{ - preset->free = fluid_rampreset_preset_delete; - preset->get_name = fluid_rampreset_preset_get_name; - preset->get_banknum = fluid_rampreset_preset_get_banknum; - preset->get_num = fluid_rampreset_preset_get_num; - preset->noteon = fluid_rampreset_preset_noteon; - preset->notify = NULL; - - return fluid_ramsfont_iteration_next((fluid_ramsfont_t*) sfont->data, preset); -} - -int fluid_rampreset_preset_delete(fluid_preset_t* preset) -{ - FLUID_FREE(preset); - -/* TODO: free modulators */ - - return 0; -} - -char* fluid_rampreset_preset_get_name(fluid_preset_t* preset) -{ - return fluid_rampreset_get_name((fluid_rampreset_t*) preset->data); -} - -int fluid_rampreset_preset_get_banknum(fluid_preset_t* preset) -{ - return fluid_rampreset_get_banknum((fluid_rampreset_t*) preset->data); -} - -int fluid_rampreset_preset_get_num(fluid_preset_t* preset) -{ - return fluid_rampreset_get_num((fluid_rampreset_t*) preset->data); -} - -int fluid_rampreset_preset_noteon(fluid_preset_t* preset, fluid_synth_t* synth, int chan, int key, int vel) -{ - return fluid_rampreset_noteon((fluid_rampreset_t*) preset->data, synth, chan, key, vel); -} - - - - -/*************************************************************** - * - * SFONT - */ - -/* - * new_fluid_ramsfont - */ -fluid_ramsfont_t* new_fluid_ramsfont() -{ - fluid_ramsfont_t* sfont; - - sfont = FLUID_NEW(fluid_ramsfont_t); - if (sfont == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - - sfont->name[0] = 0; - sfont->sample = NULL; - sfont->preset = NULL; - - return sfont; -} - -/* - * delete_fluid_ramsfont - */ -int delete_fluid_ramsfont(fluid_ramsfont_t* sfont) -{ - fluid_list_t *list; - fluid_rampreset_t* preset; - - /* Check that no samples are currently used */ - for (list = sfont->sample; list; list = fluid_list_next(list)) { - fluid_sample_t* sam = (fluid_sample_t*) fluid_list_get(list); - if (fluid_sample_refcount(sam) != 0) { - return -1; - } - } - - for (list = sfont->sample; list; list = fluid_list_next(list)) { - /* in ram soundfonts, the samples hold their data : so we should free it ourselves */ - fluid_sample_t* sam = (fluid_sample_t*)fluid_list_get(list); - delete_fluid_ramsample(sam); - } - - if (sfont->sample) { - delete_fluid_list(sfont->sample); - } - - preset = sfont->preset; - while (preset != NULL) { - sfont->preset = preset->next; - delete_fluid_rampreset(preset); - preset = sfont->preset; - } - - FLUID_FREE(sfont); - return FLUID_OK; -} - -/* - * fluid_ramsfont_get_name - */ -char* fluid_ramsfont_get_name(fluid_ramsfont_t* sfont) -{ - return sfont->name; -} - -/* - * fluid_ramsfont_set_name - */ -int -fluid_ramsfont_set_name(fluid_ramsfont_t* sfont, char * name) -{ - FLUID_MEMCPY(sfont->name, name, 20); - return FLUID_OK; -} - - -/* fluid_ramsfont_add_preset - * - * Add a preset to the SoundFont - */ -int fluid_ramsfont_add_preset(fluid_ramsfont_t* sfont, fluid_rampreset_t* preset) -{ - fluid_rampreset_t *cur, *prev; - if (sfont->preset == NULL) { - preset->next = NULL; - sfont->preset = preset; - } else { - /* sort them as we go along. very basic sorting trick. */ - cur = sfont->preset; - prev = NULL; - while (cur != NULL) { - if ((preset->bank < cur->bank) - || ((preset->bank == cur->bank) && (preset->num < cur->num))) { - if (prev == NULL) { - preset->next = cur; - sfont->preset = preset; - } else { - preset->next = cur; - prev->next = preset; - } - return FLUID_OK; - } - prev = cur; - cur = cur->next; - } - preset->next = NULL; - prev->next = preset; - } - return FLUID_OK; -} - -/* - * fluid_ramsfont_add_ramsample - */ -int fluid_ramsfont_add_izone(fluid_ramsfont_t* sfont, - unsigned int bank, unsigned int num, fluid_sample_t* sample, - int lokey, int hikey) -{ - /*- find or create a preset - - add it the sample using the fluid_rampreset_add_sample fucntion - - add the sample to the list of samples - */ - int err; - - fluid_rampreset_t* preset = fluid_ramsfont_get_preset(sfont, bank, num); - if (preset == NULL) { - // Create it - preset = new_fluid_rampreset(sfont); - if (preset == NULL) { - return FLUID_FAILED; - } - - preset->bank = bank; - preset->num = num; - - err = fluid_rampreset_add_sample(preset, sample, lokey, hikey); - if (err != FLUID_OK) { - return FLUID_FAILED; - } - - // sort the preset - fluid_ramsfont_add_preset(sfont, preset); - - } else { - - // just add it - err = fluid_rampreset_add_sample(preset, sample, lokey, hikey); - if (err != FLUID_OK) { - return FLUID_FAILED; - } - } - - sfont->sample = fluid_list_append(sfont->sample, sample); - return FLUID_OK; -} - -int fluid_ramsfont_remove_izone(fluid_ramsfont_t* sfont, - unsigned int bank, unsigned int num, fluid_sample_t* sample) { - int err; - fluid_rampreset_t* preset = fluid_ramsfont_get_preset(sfont, bank, num); - if (preset == NULL) { - return FLUID_FAILED; - } - - // Fixed a crash bug : remove the sample from the sfont list after - // removing the izone (aschmitt august 2005) - err = fluid_rampreset_remove_izone(preset, sample); - if (err != FLUID_OK) - return err; - - // now we must remove the sample from sfont->sample - sfont->sample = fluid_list_remove(sfont->sample, sample); - - return FLUID_OK; -} - - -/* Note for version 2.0 : missing API fluid_ramsfont_izone_get_gen - Antoine Schmitt May 2003 */ -int fluid_ramsfont_izone_set_gen(fluid_ramsfont_t* sfont, - unsigned int bank, unsigned int num, fluid_sample_t* sample, - int gen_type, float value) { - - fluid_rampreset_t* preset = fluid_ramsfont_get_preset(sfont, bank, num); - if (preset == NULL) { - return FLUID_FAILED; - } - - return fluid_rampreset_izone_set_gen(preset, sample, gen_type, value); -} - -/* Note for version 2.0 : missing API fluid_ramsfont_izone_get_loop - Antoine Schmitt May 2003 */ -int fluid_ramsfont_izone_set_loop(fluid_ramsfont_t* sfont, - unsigned int bank, unsigned int num, fluid_sample_t* sample, - int on, float loopstart, float loopend) { - fluid_rampreset_t* preset = fluid_ramsfont_get_preset(sfont, bank, num); - if (preset == NULL) { - return FLUID_FAILED; - } - - return fluid_rampreset_izone_set_loop(preset, sample, on, loopstart, loopend); -} - -/* - * fluid_ramsfont_get_preset - */ -fluid_rampreset_t* fluid_ramsfont_get_preset(fluid_ramsfont_t* sfont, unsigned int bank, unsigned int num) -{ - fluid_rampreset_t* preset = sfont->preset; - while (preset != NULL) { - if ((preset->bank == bank) && ((preset->num == num))) { - return preset; - } - preset = preset->next; - } - return NULL; -} - -/* - * fluid_ramsfont_iteration_start - */ -void fluid_ramsfont_iteration_start(fluid_ramsfont_t* sfont) -{ - sfont->iter_cur = sfont->preset; -} - -/* - * fluid_ramsfont_iteration_next - */ -int fluid_ramsfont_iteration_next(fluid_ramsfont_t* sfont, fluid_preset_t* preset) -{ - if (sfont->iter_cur == NULL) { - return 0; - } - - preset->data = (void*) sfont->iter_cur; - sfont->iter_cur = fluid_rampreset_next(sfont->iter_cur); - return 1; -} - -/*************************************************************** - * - * PRESET - */ - -typedef struct _fluid_rampreset_voice_t fluid_rampreset_voice_t; -struct _fluid_rampreset_voice_t { - fluid_voice_t *voice; - unsigned int voiceID; -}; - -/* - * new_fluid_rampreset - */ -fluid_rampreset_t* -new_fluid_rampreset(fluid_ramsfont_t* sfont) -{ - fluid_rampreset_t* preset = FLUID_NEW(fluid_rampreset_t); - if (preset == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - preset->next = NULL; - preset->sfont = sfont; - preset->name[0] = 0; - preset->bank = 0; - preset->num = 0; - preset->global_zone = NULL; - preset->zone = NULL; - preset->presetvoices = NULL; - return preset; -} - -/* - * delete_fluid_rampreset - */ -int -delete_fluid_rampreset(fluid_rampreset_t* preset) -{ - int err = FLUID_OK; - fluid_preset_zone_t* zone; - fluid_rampreset_voice_t *data; - - if (preset->global_zone != NULL) { - if (delete_fluid_preset_zone(preset->global_zone) != FLUID_OK) { - err = FLUID_FAILED; - } - preset->global_zone = NULL; - } - zone = preset->zone; - while (zone != NULL) { - preset->zone = zone->next; - if (delete_fluid_preset_zone(zone) != FLUID_OK) { - err = FLUID_FAILED; - } - zone = preset->zone; - } - - if (preset->presetvoices != NULL) { - fluid_list_t *tmp = preset->presetvoices, *next; - while (tmp) { - data = (fluid_rampreset_voice_t *)(tmp->data); - FLUID_FREE(data); - - next = tmp->next; - FLUID_FREE(tmp); - tmp = next; - } - } - preset->presetvoices = NULL; - - FLUID_FREE(preset); - return err; -} - -int -fluid_rampreset_get_banknum(fluid_rampreset_t* preset) -{ - return preset->bank; -} - -int -fluid_rampreset_get_num(fluid_rampreset_t* preset) -{ - return preset->num; -} - -char* -fluid_rampreset_get_name(fluid_rampreset_t* preset) -{ - return preset->name; -} - -/* - * fluid_rampreset_next - */ -fluid_rampreset_t* -fluid_rampreset_next(fluid_rampreset_t* preset) -{ - return preset->next; -} - - -/* - * fluid_rampreset_add_zone - */ -int -fluid_rampreset_add_zone(fluid_rampreset_t* preset, fluid_preset_zone_t* zone) -{ - if (preset->zone == NULL) { - zone->next = NULL; - preset->zone = zone; - } else { - zone->next = preset->zone; - preset->zone = zone; - } - return FLUID_OK; -} - - -/* - * fluid_rampreset_add_sample - */ -int fluid_rampreset_add_sample(fluid_rampreset_t* preset, fluid_sample_t* sample, int lokey, int hikey) -{ - /* create a new instrument zone, with the given sample */ - - /* one preset zone */ - if (preset->zone == NULL) { - fluid_preset_zone_t* zone; - zone = new_fluid_preset_zone(""); - if (zone == NULL) { - return FLUID_FAILED; - } - - /* its instrument */ - zone->inst = (fluid_inst_t*) new_fluid_inst(); - if (zone->inst == NULL) { - delete_fluid_preset_zone(zone); - return FLUID_FAILED; - } - - fluid_rampreset_add_zone(preset, zone); - } - - /* add an instrument zone for each sample */ - { - fluid_inst_t* inst = fluid_preset_zone_get_inst(preset->zone); - fluid_inst_zone_t* izone = new_fluid_inst_zone(""); - if (izone == NULL) { - return FLUID_FAILED; - } - - if (fluid_inst_add_zone(inst, izone) != FLUID_OK) { - delete_fluid_inst_zone(izone); - return FLUID_FAILED; - } - - izone->sample = sample; - izone->keylo = lokey; - izone->keyhi = hikey; - - // give the preset the name of the sample - FLUID_MEMCPY(preset->name, sample->name, 20); - } - - return FLUID_OK; -} - -fluid_inst_zone_t* fluid_rampreset_izoneforsample(fluid_rampreset_t* preset, fluid_sample_t* sample) -{ - fluid_inst_t* inst; - fluid_inst_zone_t* izone; - - if (preset->zone == NULL) return NULL; - - inst = fluid_preset_zone_get_inst(preset->zone); - izone = inst->zone; - while (izone) { - if (izone->sample == sample) - return izone; - izone = izone->next; - } - return NULL; -} - -int fluid_rampreset_izone_set_loop(fluid_rampreset_t* preset, fluid_sample_t* sample, - int on, float loopstart, float loopend) { - fluid_inst_zone_t* izone = fluid_rampreset_izoneforsample(preset, sample); - short coarse, fine; - - if (izone == NULL) - return FLUID_FAILED; - - if (!on) { - izone->gen[GEN_SAMPLEMODE].flags = GEN_SET; - izone->gen[GEN_SAMPLEMODE].val = FLUID_UNLOOPED; - fluid_rampreset_updatevoices(preset, GEN_SAMPLEMODE, FLUID_UNLOOPED); - return FLUID_OK; -} - - /* NOTE : We should check that (sample->startloop + loopStart <= sample->endloop - loopend - 32) */ - - /* loopstart */ - if (loopstart > 32767. || loopstart < -32767.) { - coarse = (short)(loopstart/32768.); - fine = (short)(loopstart - (float)(coarse)*32768.); - } else { - coarse = 0; - fine = (short)loopstart; - } - izone->gen[GEN_STARTLOOPADDROFS].flags = GEN_SET; - izone->gen[GEN_STARTLOOPADDROFS].val = fine; - fluid_rampreset_updatevoices(preset, GEN_STARTLOOPADDROFS, fine); - if (coarse) { - izone->gen[GEN_STARTLOOPADDRCOARSEOFS].flags = GEN_SET; - izone->gen[GEN_STARTLOOPADDRCOARSEOFS].val = coarse; - } else { - izone->gen[GEN_STARTLOOPADDRCOARSEOFS].flags = GEN_UNUSED; - } - fluid_rampreset_updatevoices(preset, GEN_STARTLOOPADDRCOARSEOFS, coarse); - - /* loopend */ - if (loopend > 32767. || loopend < -32767.) { - coarse = (short)(loopend/32768.); - fine = (short)(loopend - (float)(coarse)*32768.); - } else { - coarse = 0; - fine = (short)loopend; - } - izone->gen[GEN_ENDLOOPADDROFS].flags = GEN_SET; - izone->gen[GEN_ENDLOOPADDROFS].val = fine; - fluid_rampreset_updatevoices(preset, GEN_ENDLOOPADDROFS, fine); - if (coarse) { - izone->gen[GEN_ENDLOOPADDRCOARSEOFS].flags = GEN_SET; - izone->gen[GEN_ENDLOOPADDRCOARSEOFS].val = coarse; - } else { - izone->gen[GEN_ENDLOOPADDRCOARSEOFS].flags = GEN_UNUSED; - } - fluid_rampreset_updatevoices(preset, GEN_ENDLOOPADDRCOARSEOFS, coarse); - - izone->gen[GEN_SAMPLEMODE].flags = GEN_SET; - izone->gen[GEN_SAMPLEMODE].val = FLUID_LOOP_DURING_RELEASE; - fluid_rampreset_updatevoices(preset, GEN_SAMPLEMODE, FLUID_LOOP_DURING_RELEASE); - - /* If the loop points are the whole samples, we are supposed to - copy the frames around in the margins (the start to the end margin and - the end to the start margin), but it works fine without this. Maybe some time - it will be needed (see SAMPLE_LOOP_MARGIN) -- Antoie Schmitt May 2003 */ - - return FLUID_OK; -} - -int fluid_rampreset_izone_set_gen(fluid_rampreset_t* preset, fluid_sample_t* sample, - int gen_type, float value) { - fluid_inst_zone_t* izone = fluid_rampreset_izoneforsample(preset, sample); - if (izone == NULL) - return FLUID_FAILED; - - izone->gen[gen_type].flags = GEN_SET; - izone->gen[gen_type].val = value; - - fluid_rampreset_updatevoices(preset, gen_type, value); - - return FLUID_OK; -} - -int fluid_rampreset_remove_izone(fluid_rampreset_t* preset, fluid_sample_t* sample) { - fluid_inst_t* inst; - fluid_inst_zone_t* izone, * prev; - int found = 0; - - if (preset->zone == NULL) return FLUID_FAILED; - inst = fluid_preset_zone_get_inst(preset->zone); - izone = inst->zone; - prev = NULL; - while (izone && !found) { - if (izone->sample == sample) { - if (prev == NULL) { - inst->zone = izone->next; - } else { - prev->next = izone->next; - } - izone->next = NULL; - delete_fluid_inst_zone(izone); - found = 1; - } else { - prev = izone; - izone = izone->next; - } - } - if (!found) - return FLUID_FAILED; - - // stop all the voices that use this sample, so that - // the sample can be cleared up - { - fluid_list_t *tmp = preset->presetvoices; - while (tmp) { - fluid_rampreset_voice_t *presetvoice = (fluid_rampreset_voice_t *)(tmp->data); - fluid_voice_t *voice = presetvoice->voice; - if (fluid_voice_is_playing(voice) && (fluid_voice_get_id(voice) == presetvoice->voiceID)) { - // still belongs to the preset - if (voice->sample == sample) { - // uses this sample : turn it off. - // our presetvoices struct will be cleaneup at the next update - fluid_voice_off(voice); - } - } - tmp = tmp->next; - } - } - return FLUID_OK; -} - -/* - * fluid_rampreset_remembervoice - */ -int -fluid_rampreset_remembervoice(fluid_rampreset_t* preset, fluid_voice_t* voice) { - /* stores the voice and the its ID in the preset for later update on gen_set */ - fluid_rampreset_voice_t *presetvoice = FLUID_NEW(fluid_rampreset_voice_t); - if (presetvoice == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return FLUID_FAILED; - } - - presetvoice->voice = voice; - presetvoice->voiceID = fluid_voice_get_id(voice); - - preset->presetvoices = fluid_list_append(preset->presetvoices, (void *)presetvoice); - if (preset->presetvoices == NULL) { - FLUID_FREE(presetvoice); - FLUID_LOG(FLUID_ERR, "Out of memory"); - return FLUID_FAILED; - } - return FLUID_OK; -} - -/* - * fluid_rampreset_updatevoice - */ -void -fluid_rampreset_updatevoices(fluid_rampreset_t* preset, int gen_type, float val) { - fluid_list_t *tmp = preset->presetvoices, *prev = NULL, *next; - - /* walk the presetvoice to update them if they are still active and ours. - If their ID has changed or their state is not playing, they are not ours, so we forget them - */ - while (tmp) { - fluid_rampreset_voice_t *presetvoice = (fluid_rampreset_voice_t *)(tmp->data); - fluid_voice_t *voice = presetvoice->voice; - if (!fluid_voice_is_playing(voice) || (fluid_voice_get_id(voice) != presetvoice->voiceID)) { - /* forget it */ - FLUID_FREE(presetvoice); - - /* unlink it */ - next = tmp->next; - FLUID_FREE(tmp); - if (prev) { - prev->next = next; - } else { - preset->presetvoices = next; - } - tmp = next; - - } else { - - /* update */ - fluid_voice_gen_set(voice, gen_type, val); - fluid_voice_update_param(voice, gen_type); - - /* next */ - prev = tmp; - tmp = tmp->next; - } - } -} - - -/* - * fluid_rampreset_noteon - */ -int -fluid_rampreset_noteon(fluid_rampreset_t* preset, fluid_synth_t* synth, int chan, int key, int vel) -{ - fluid_preset_zone_t *preset_zone; - fluid_inst_t* inst; - fluid_inst_zone_t *inst_zone, *global_inst_zone, *z; - fluid_sample_t* sample; - fluid_voice_t* voice; - fluid_mod_t * mod; - fluid_mod_t * mod_list[FLUID_NUM_MOD]; /* list for 'sorting' preset modulators */ - int mod_list_count; - int i; - - /* run thru all the zones of this preset */ - preset_zone = preset->zone; - while (preset_zone != NULL) { - - /* check if the note falls into the key and velocity range of this - preset */ - if (fluid_preset_zone_inside_range(preset_zone, key, vel)) { - - inst = fluid_preset_zone_get_inst(preset_zone); - global_inst_zone = fluid_inst_get_global_zone(inst); - - /* run thru all the zones of this instrument */ - inst_zone = fluid_inst_get_zone(inst); - while (inst_zone != NULL) { - - /* make sure this instrument zone has a valid sample */ - sample = fluid_inst_zone_get_sample(inst_zone); - if (fluid_sample_in_rom(sample) || (sample == NULL)) { - inst_zone = fluid_inst_zone_next(inst_zone); - continue; - } - - /* check if the note falls into the key and velocity range of this - instrument */ - - if (fluid_inst_zone_inside_range(inst_zone, key, vel) && (sample != NULL)) { - - /* this is a good zone. allocate a new synthesis process and - initialize it */ - - voice = fluid_synth_alloc_voice(synth, sample, chan, key, vel); - if (voice == NULL) { - return FLUID_FAILED; - } - - if (fluid_rampreset_remembervoice(preset, voice) != FLUID_OK) { - return FLUID_FAILED; - } - - z = inst_zone; - - /* Instrument level, generators */ - - for (i = 0; i < GEN_LAST; i++) { - - /* SF 2.01 section 9.4 'bullet' 4: - * - * A generator in a local instrument zone supersedes a - * global instrument zone generator. Both cases supersede - * the default generator -> voice_gen_set */ - - if (inst_zone->gen[i].flags){ - fluid_voice_gen_set(voice, i, inst_zone->gen[i].val); - - } else if (global_inst_zone != NULL && global_inst_zone->gen[i].flags){ - fluid_voice_gen_set(voice, i, global_inst_zone->gen[i].val); - - } else { - /* The generator has not been defined in this instrument. - * Do nothing, leave it at the default. - */ - }; - - }; /* for all generators */ - - /* global instrument zone, modulators: Put them all into a - * list. */ - - mod_list_count = 0; - - if (global_inst_zone){ - mod = global_inst_zone->mod; - while (mod){ - mod_list[mod_list_count++] = mod; - mod = mod->next; - }; - }; - - /* local instrument zone, modulators. - * Replace modulators with the same definition in the list: - * SF 2.01 page 69, 'bullet' 8 - */ - mod = inst_zone->mod; - - while (mod){ - - /* 'Identical' modulators will be deleted by setting their - * list entry to NULL. The list length is known, NULL - * entries will be ignored later. SF2.01 section 9.5.1 - * page 69, 'bullet' 3 defines 'identical'. */ - - for (i = 0; i < mod_list_count; i++){ - if (fluid_mod_test_identity(mod,mod_list[i])){ - mod_list[i] = NULL; - }; - }; - - /* Finally add the new modulator to to the list. */ - mod_list[mod_list_count++] = mod; - mod = mod->next; - }; - - /* Add instrument modulators (global / local) to the voice. */ - for (i = 0; i < mod_list_count; i++){ - - mod = mod_list[i]; - - if (mod != NULL){ /* disabled modulators CANNOT be skipped. */ - - /* Instrument modulators -supersede- existing (default) - * modulators. SF 2.01 page 69, 'bullet' 6 */ - fluid_voice_add_mod(voice, mod, FLUID_VOICE_OVERWRITE); - }; - }; - - /* Preset level, generators */ - - for (i = 0; i < GEN_LAST; i++) { - - /* SF 2.01 section 8.5 page 58: If some generators are - * encountered at preset level, they should be ignored */ - if ((i != GEN_STARTADDROFS) - && (i != GEN_ENDADDROFS) - && (i != GEN_STARTLOOPADDROFS) - && (i != GEN_ENDLOOPADDROFS) - && (i != GEN_STARTADDRCOARSEOFS) - && (i != GEN_ENDADDRCOARSEOFS) - && (i != GEN_STARTLOOPADDRCOARSEOFS) - && (i != GEN_KEYNUM) - && (i != GEN_VELOCITY) - && (i != GEN_ENDLOOPADDRCOARSEOFS) - && (i != GEN_SAMPLEMODE) - && (i != GEN_EXCLUSIVECLASS) - && (i != GEN_OVERRIDEROOTKEY)) { - - /* SF 2.01 section 9.4 'bullet' 9: A generator in a - * local preset zone supersedes a global preset zone - * generator. The effect is -added- to the destination - * summing node -> voice_gen_incr */ - - if (preset_zone->gen[i].flags){ - fluid_voice_gen_incr(voice, i, preset_zone->gen[i].val); - } else { - /* The generator has not been defined in this preset - * Do nothing, leave it unchanged. - */ - }; - }; /* if available at preset level */ - }; /* for all generators */ - - - /* Global preset zone, modulators: put them all into a - * list. */ - mod_list_count = 0; - - /* Process the modulators of the local preset zone. Kick - * out all identical modulators from the global preset zone - * (SF 2.01 page 69, second-last bullet) */ - - mod = preset_zone->mod; - while (mod){ - for (i = 0; i < mod_list_count; i++){ - if (fluid_mod_test_identity(mod,mod_list[i])){ - mod_list[i] = NULL; - }; - }; - - /* Finally add the new modulator to the list. */ - mod_list[mod_list_count++] = mod; - mod = mod->next; - }; - - /* Add preset modulators (global / local) to the voice. */ - for (i = 0; i < mod_list_count; i++){ - mod = mod_list[i]; - if ((mod != NULL) && (mod->amount != 0)) { /* disabled modulators can be skipped. */ - - /* Preset modulators -add- to existing instrument / - * default modulators. SF2.01 page 70 first bullet on - * page */ - fluid_voice_add_mod(voice, mod, FLUID_VOICE_ADD); - }; - }; - - /* add the synthesis process to the synthesis loop. */ - fluid_synth_start_voice(synth, voice); - - /* Store the ID of the first voice that was created by this noteon event. - * Exclusive class may only terminate older voices. - * That avoids killing voices, which have just been created. - * (a noteon event can create several voice processes with the same exclusive - * class - for example when using stereo samples) - */ - } - - inst_zone = fluid_inst_zone_next(inst_zone); - } - } - preset_zone = fluid_preset_zone_next(preset_zone); - } - - return FLUID_OK; -} - - - -/*************************************************************** - * - * SAMPLE - */ - - - -/* - * fluid_sample_set_name - */ -int -fluid_sample_set_name(fluid_sample_t* sample, char * name) -{ - FLUID_MEMCPY(sample->name, name, 20); - return FLUID_OK; -} - -/* - * fluid_sample_set_sound_data - */ -int -fluid_sample_set_sound_data(fluid_sample_t* sample, short *data, unsigned int nbframes, short copy_data, int rootkey) -{ - /* 16 bit mono 44.1KHz data in */ - /* in all cases, the sample has ownership of the data : it will release it in the end */ - unsigned int storedNbFrames; - - /* in case we already have some data */ - if (sample->data != NULL) { - FLUID_FREE(sample->data); - } - - if (copy_data) { - - /* nbframes should be >= 48 (SoundFont specs) */ - storedNbFrames = nbframes; - if (storedNbFrames < 48) storedNbFrames = 48; - - sample->data = FLUID_MALLOC(storedNbFrames*2 + 4*SAMPLE_LOOP_MARGIN); - if (sample->data == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return FLUID_FAILED; - } - FLUID_MEMSET(sample->data, 0, storedNbFrames*2 + 4*SAMPLE_LOOP_MARGIN); - FLUID_MEMCPY((char*)(sample->data) + 2*SAMPLE_LOOP_MARGIN, data, nbframes*2); - -#if 0 - /* this would do the fill of the margins */ - FLUID_MEMCPY((char*)(sample->data) + 2*SAMPLE_LOOP_MARGIN + storedNbFrames*2, (char*)data, 2*SAMPLE_LOOP_MARGIN); - FLUID_MEMCPY((char*)(sample->data), (char*)data + nbframes*2 - 2*SAMPLE_LOOP_MARGIN, 2*SAMPLE_LOOP_MARGIN); -#endif - - /* pointers */ - /* all from the start of data */ - sample->start = SAMPLE_LOOP_MARGIN; - sample->end = SAMPLE_LOOP_MARGIN + storedNbFrames; - } else { - /* we cannot assure the SAMPLE_LOOP_MARGIN */ - sample->data = data; - sample->start = 0; - sample->end = nbframes; - } - - /* only used as markers for the LOOP generators : set them on the first real frame */ - sample->loopstart = sample->start; - sample->loopend = sample->end; - - sample->samplerate = 44100; - sample->origpitch = rootkey; - sample->pitchadj = 0; - sample->sampletype = FLUID_SAMPLETYPE_MONO; - sample->valid = 1; - - return FLUID_OK; -} - -/* - * new_fluid_ramsample - */ -fluid_sample_t* -new_fluid_ramsample() -{ - /* same as new_fluid_sample. Only here so that it is exported */ - fluid_sample_t* sample = NULL; - - sample = FLUID_NEW(fluid_sample_t); - if (sample == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - - memset(sample, 0, sizeof(fluid_sample_t)); - - return sample; -} - -/* - * delete_fluid_ramsample - */ -int -delete_fluid_ramsample(fluid_sample_t* sample) -{ - /* same as delete_fluid_sample, plus frees the data */ - if (sample->data != NULL) { - FLUID_FREE(sample->data); - } - sample->data = NULL; - FLUID_FREE(sample); - return FLUID_OK; -} diff --git a/src/libs/fluidsynth/src/fluid_ramsfont.h b/src/libs/fluidsynth/src/fluid_ramsfont.h deleted file mode 100644 index 0e28dbf434..0000000000 --- a/src/libs/fluidsynth/src/fluid_ramsfont.h +++ /dev/null @@ -1,114 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - - -#ifndef _FLUID_RAMSFONT_H -#define _FLUID_RAMSFONT_H - - -#include "fluidsynth.h" -#include "fluidsynth_priv.h" - -#include "fluid_defsfont.h" - - -#ifdef __cplusplus -extern "C" { -#endif - - - -/* - - Public interface - - */ - -int fluid_ramsfont_sfont_delete(fluid_sfont_t* sfont); -char* fluid_ramsfont_sfont_get_name(fluid_sfont_t* sfont); -fluid_preset_t* fluid_ramsfont_sfont_get_preset(fluid_sfont_t* sfont, unsigned int bank, unsigned int prenum); -void fluid_ramsfont_sfont_iteration_start(fluid_sfont_t* sfont); -int fluid_ramsfont_sfont_iteration_next(fluid_sfont_t* sfont, fluid_preset_t* preset); - - -int fluid_rampreset_preset_delete(fluid_preset_t* preset); -char* fluid_rampreset_preset_get_name(fluid_preset_t* preset); -int fluid_rampreset_preset_get_banknum(fluid_preset_t* preset); -int fluid_rampreset_preset_get_num(fluid_preset_t* preset); -int fluid_rampreset_preset_noteon(fluid_preset_t* preset, fluid_synth_t* synth, int chan, int key, int vel); - - -/* - * fluid_ramsfont_t - */ -struct _fluid_ramsfont_t -{ - char name[21]; /* the name of the soundfont */ - fluid_list_t* sample; /* the samples in this soundfont */ - fluid_rampreset_t* preset; /* the presets of this soundfont */ - - fluid_preset_t iter_preset; /* preset interface used in the iteration */ - fluid_rampreset_t* iter_cur; /* the current preset in the iteration */ -}; - -/* interface */ -fluid_ramsfont_t* new_fluid_ramsfont(void); -int delete_fluid_ramsfont(fluid_ramsfont_t* sfont); -char* fluid_ramsfont_get_name(fluid_ramsfont_t* sfont); -fluid_rampreset_t* fluid_ramsfont_get_preset(fluid_ramsfont_t* sfont, unsigned int bank, unsigned int prenum); -void fluid_ramsfont_iteration_start(fluid_ramsfont_t* sfont); -int fluid_ramsfont_iteration_next(fluid_ramsfont_t* sfont, fluid_preset_t* preset); -/* specific */ - - - -/* - * fluid_preset_t - */ -struct _fluid_rampreset_t -{ - fluid_rampreset_t* next; - fluid_ramsfont_t* sfont; /* the soundfont this preset belongs to */ - char name[21]; /* the name of the preset */ - unsigned int bank; /* the bank number */ - unsigned int num; /* the preset number */ - fluid_preset_zone_t* global_zone; /* the global zone of the preset */ - fluid_preset_zone_t* zone; /* the chained list of preset zones */ - fluid_list_t *presetvoices; /* chained list of used voices */ -}; - -/* interface */ -fluid_rampreset_t* new_fluid_rampreset(fluid_ramsfont_t* sfont); -int delete_fluid_rampreset(fluid_rampreset_t* preset); -fluid_rampreset_t* fluid_rampreset_next(fluid_rampreset_t* preset); -char* fluid_rampreset_get_name(fluid_rampreset_t* preset); -int fluid_rampreset_get_banknum(fluid_rampreset_t* preset); -int fluid_rampreset_get_num(fluid_rampreset_t* preset); -int fluid_rampreset_noteon(fluid_rampreset_t* preset, fluid_synth_t* synth, int chan, int key, int vel); - - - - - -#ifdef __cplusplus -} -#endif - -#endif /* _FLUID_SFONT_H */ diff --git a/src/libs/fluidsynth/src/fluid_rev.c b/src/libs/fluidsynth/src/fluid_rev.c deleted file mode 100644 index 3f09b6d638..0000000000 --- a/src/libs/fluidsynth/src/fluid_rev.c +++ /dev/null @@ -1,561 +0,0 @@ -/* - - Freeverb - - Written by Jezar at Dreampoint, June 2000 - http://www.dreampoint.co.uk - This code is public domain - - Translated to C by Peter Hanappe, Mai 2001 -*/ - -#include "fluid_rev.h" - -/*************************************************************** - * - * REVERB - */ - -/* Denormalising: - * - * According to music-dsp thread 'Denormalise', Pentium processors - * have a hardware 'feature', that is of interest here, related to - * numeric underflow. We have a recursive filter. The output decays - * exponentially, if the input stops. So the numbers get smaller and - * smaller... At some point, they reach 'denormal' level. This will - * lead to drastic spikes in the CPU load. The effect was reproduced - * with the reverb - sometimes the average load over 10 s doubles!!. - * - * The 'undenormalise' macro fixes the problem: As soon as the number - * is close enough to denormal level, the macro forces the number to - * 0.0f. The original macro is: - * - * #define undenormalise(sample) if(((*(unsigned int*)&sample)&0x7f800000)==0) sample=0.0f - * - * This will zero out a number when it reaches the denormal level. - * Advantage: Maximum dynamic range Disadvantage: We'll have to check - * every sample, expensive. The alternative macro comes from a later - * mail from Jon Watte. It will zap a number before it reaches - * denormal level. Jon suggests to run it once per block instead of - * every sample. - */ - -# if defined(WITH_FLOATX) -# define zap_almost_zero(sample) (((*(unsigned int*)&(sample))&0x7f800000) < 0x08000000)?0.0f:(sample) -# else -/* 1e-20 was chosen as an arbitrary (small) threshold. */ -#define zap_almost_zero(sample) fabs(sample)<1e-10 ? 0 : sample; -#endif - -/* Denormalising part II: - * - * Another method fixes the problem cheaper: Use a small DC-offset in - * the filter calculations. Now the signals converge not against 0, - * but against the offset. The constant offset is invisible from the - * outside world (i.e. it does not appear at the output. There is a - * very small turn-on transient response, which should not cause - * problems. - */ - - -//#define DC_OFFSET 0 -#define DC_OFFSET 1e-8 -//#define DC_OFFSET 0.001f -typedef struct _fluid_allpass fluid_allpass; -typedef struct _fluid_comb fluid_comb; - -struct _fluid_allpass { - fluid_real_t feedback; - fluid_real_t *buffer; - int bufsize; - int bufidx; -}; - -void fluid_allpass_setbuffer(fluid_allpass* allpass, fluid_real_t *buf, int size); -void fluid_allpass_init(fluid_allpass* allpass); -void fluid_allpass_setfeedback(fluid_allpass* allpass, fluid_real_t val); -fluid_real_t fluid_allpass_getfeedback(fluid_allpass* allpass); - -void -fluid_allpass_setbuffer(fluid_allpass* allpass, fluid_real_t *buf, int size) -{ - allpass->bufidx = 0; - allpass->buffer = buf; - allpass->bufsize = size; -} - -void -fluid_allpass_init(fluid_allpass* allpass) -{ - int i; - int len = allpass->bufsize; - fluid_real_t* buf = allpass->buffer; - for (i = 0; i < len; i++) { - buf[i] = DC_OFFSET; /* this is not 100 % correct. */ - } -} - -void -fluid_allpass_setfeedback(fluid_allpass* allpass, fluid_real_t val) -{ - allpass->feedback = val; -} - -fluid_real_t -fluid_allpass_getfeedback(fluid_allpass* allpass) -{ - return allpass->feedback; -} - -#define fluid_allpass_process(_allpass, _input) \ -{ \ - fluid_real_t output; \ - fluid_real_t bufout; \ - bufout = _allpass.buffer[_allpass.bufidx]; \ - output = bufout-_input; \ - _allpass.buffer[_allpass.bufidx] = _input + (bufout * _allpass.feedback); \ - if (++_allpass.bufidx >= _allpass.bufsize) { \ - _allpass.bufidx = 0; \ - } \ - _input = output; \ -} - -/* fluid_real_t fluid_allpass_process(fluid_allpass* allpass, fluid_real_t input) */ -/* { */ -/* fluid_real_t output; */ -/* fluid_real_t bufout; */ -/* bufout = allpass->buffer[allpass->bufidx]; */ -/* undenormalise(bufout); */ -/* output = -input + bufout; */ -/* allpass->buffer[allpass->bufidx] = input + (bufout * allpass->feedback); */ -/* if (++allpass->bufidx >= allpass->bufsize) { */ -/* allpass->bufidx = 0; */ -/* } */ -/* return output; */ -/* } */ - -struct _fluid_comb { - fluid_real_t feedback; - fluid_real_t filterstore; - fluid_real_t damp1; - fluid_real_t damp2; - fluid_real_t *buffer; - int bufsize; - int bufidx; -}; - -void fluid_comb_setbuffer(fluid_comb* comb, fluid_real_t *buf, int size); -void fluid_comb_init(fluid_comb* comb); -void fluid_comb_setdamp(fluid_comb* comb, fluid_real_t val); -fluid_real_t fluid_comb_getdamp(fluid_comb* comb); -void fluid_comb_setfeedback(fluid_comb* comb, fluid_real_t val); -fluid_real_t fluid_comb_getfeedback(fluid_comb* comb); - -void -fluid_comb_setbuffer(fluid_comb* comb, fluid_real_t *buf, int size) -{ - comb->filterstore = 0; - comb->bufidx = 0; - comb->buffer = buf; - comb->bufsize = size; -} - -void -fluid_comb_init(fluid_comb* comb) -{ - int i; - fluid_real_t* buf = comb->buffer; - int len = comb->bufsize; - for (i = 0; i < len; i++) { - buf[i] = DC_OFFSET; /* This is not 100 % correct. */ - } -} - -void -fluid_comb_setdamp(fluid_comb* comb, fluid_real_t val) -{ - comb->damp1 = val; - comb->damp2 = 1 - val; -} - -fluid_real_t -fluid_comb_getdamp(fluid_comb* comb) -{ - return comb->damp1; -} - -void -fluid_comb_setfeedback(fluid_comb* comb, fluid_real_t val) -{ - comb->feedback = val; -} - -fluid_real_t -fluid_comb_getfeedback(fluid_comb* comb) -{ - return comb->feedback; -} - -#define fluid_comb_process(_comb, _input, _output) \ -{ \ - fluid_real_t _tmp = _comb.buffer[_comb.bufidx]; \ - _comb.filterstore = (_tmp * _comb.damp2) + (_comb.filterstore * _comb.damp1); \ - _comb.buffer[_comb.bufidx] = _input + (_comb.filterstore * _comb.feedback); \ - if (++_comb.bufidx >= _comb.bufsize) { \ - _comb.bufidx = 0; \ - } \ - _output += _tmp; \ -} - -/* fluid_real_t fluid_comb_process(fluid_comb* comb, fluid_real_t input) */ -/* { */ -/* fluid_real_t output; */ - -/* output = comb->buffer[comb->bufidx]; */ -/* undenormalise(output); */ -/* comb->filterstore = (output * comb->damp2) + (comb->filterstore * comb->damp1); */ -/* undenormalise(comb->filterstore); */ -/* comb->buffer[comb->bufidx] = input + (comb->filterstore * comb->feedback); */ -/* if (++comb->bufidx >= comb->bufsize) { */ -/* comb->bufidx = 0; */ -/* } */ - -/* return output; */ -/* } */ - -#define numcombs 8 -#define numallpasses 4 -#define fixedgain 0.015f -#define scalewet 3.0f -#define scaledamp 1.0f -#define scaleroom 0.28f -#define offsetroom 0.7f -#define initialroom 0.5f -#define initialdamp 0.2f -#define initialwet 1 -#define initialdry 0 -#define initialwidth 1 -#define stereospread 23 - -/* - These values assume 44.1KHz sample rate - they will probably be OK for 48KHz sample rate - but would need scaling for 96KHz (or other) sample rates. - The values were obtained by listening tests. -*/ -#define combtuningL1 1116 -#define combtuningR1 1116 + stereospread -#define combtuningL2 1188 -#define combtuningR2 1188 + stereospread -#define combtuningL3 1277 -#define combtuningR3 1277 + stereospread -#define combtuningL4 1356 -#define combtuningR4 1356 + stereospread -#define combtuningL5 1422 -#define combtuningR5 1422 + stereospread -#define combtuningL6 1491 -#define combtuningR6 1491 + stereospread -#define combtuningL7 1557 -#define combtuningR7 1557 + stereospread -#define combtuningL8 1617 -#define combtuningR8 1617 + stereospread -#define allpasstuningL1 556 -#define allpasstuningR1 556 + stereospread -#define allpasstuningL2 441 -#define allpasstuningR2 441 + stereospread -#define allpasstuningL3 341 -#define allpasstuningR3 341 + stereospread -#define allpasstuningL4 225 -#define allpasstuningR4 225 + stereospread - -struct _fluid_revmodel_t { - fluid_real_t roomsize; - fluid_real_t damp; - fluid_real_t wet, wet1, wet2; - fluid_real_t width; - fluid_real_t gain; - /* - The following are all declared inline - to remove the need for dynamic allocation - with its subsequent error-checking messiness - */ - /* Comb filters */ - fluid_comb combL[numcombs]; - fluid_comb combR[numcombs]; - /* Allpass filters */ - fluid_allpass allpassL[numallpasses]; - fluid_allpass allpassR[numallpasses]; - /* Buffers for the combs */ - fluid_real_t bufcombL1[combtuningL1]; - fluid_real_t bufcombR1[combtuningR1]; - fluid_real_t bufcombL2[combtuningL2]; - fluid_real_t bufcombR2[combtuningR2]; - fluid_real_t bufcombL3[combtuningL3]; - fluid_real_t bufcombR3[combtuningR3]; - fluid_real_t bufcombL4[combtuningL4]; - fluid_real_t bufcombR4[combtuningR4]; - fluid_real_t bufcombL5[combtuningL5]; - fluid_real_t bufcombR5[combtuningR5]; - fluid_real_t bufcombL6[combtuningL6]; - fluid_real_t bufcombR6[combtuningR6]; - fluid_real_t bufcombL7[combtuningL7]; - fluid_real_t bufcombR7[combtuningR7]; - fluid_real_t bufcombL8[combtuningL8]; - fluid_real_t bufcombR8[combtuningR8]; - /* Buffers for the allpasses */ - fluid_real_t bufallpassL1[allpasstuningL1]; - fluid_real_t bufallpassR1[allpasstuningR1]; - fluid_real_t bufallpassL2[allpasstuningL2]; - fluid_real_t bufallpassR2[allpasstuningR2]; - fluid_real_t bufallpassL3[allpasstuningL3]; - fluid_real_t bufallpassR3[allpasstuningR3]; - fluid_real_t bufallpassL4[allpasstuningL4]; - fluid_real_t bufallpassR4[allpasstuningR4]; -}; - -void fluid_revmodel_update(fluid_revmodel_t* rev); -void fluid_revmodel_init(fluid_revmodel_t* rev); - -fluid_revmodel_t* -new_fluid_revmodel() -{ - fluid_revmodel_t* rev; - rev = FLUID_NEW(fluid_revmodel_t); - if (rev == NULL) { - return NULL; - } - - /* Tie the components to their buffers */ - fluid_comb_setbuffer(&rev->combL[0], rev->bufcombL1, combtuningL1); - fluid_comb_setbuffer(&rev->combR[0], rev->bufcombR1, combtuningR1); - fluid_comb_setbuffer(&rev->combL[1], rev->bufcombL2, combtuningL2); - fluid_comb_setbuffer(&rev->combR[1], rev->bufcombR2, combtuningR2); - fluid_comb_setbuffer(&rev->combL[2], rev->bufcombL3, combtuningL3); - fluid_comb_setbuffer(&rev->combR[2], rev->bufcombR3, combtuningR3); - fluid_comb_setbuffer(&rev->combL[3], rev->bufcombL4, combtuningL4); - fluid_comb_setbuffer(&rev->combR[3], rev->bufcombR4, combtuningR4); - fluid_comb_setbuffer(&rev->combL[4], rev->bufcombL5, combtuningL5); - fluid_comb_setbuffer(&rev->combR[4], rev->bufcombR5, combtuningR5); - fluid_comb_setbuffer(&rev->combL[5], rev->bufcombL6, combtuningL6); - fluid_comb_setbuffer(&rev->combR[5], rev->bufcombR6, combtuningR6); - fluid_comb_setbuffer(&rev->combL[6], rev->bufcombL7, combtuningL7); - fluid_comb_setbuffer(&rev->combR[6], rev->bufcombR7, combtuningR7); - fluid_comb_setbuffer(&rev->combL[7], rev->bufcombL8, combtuningL8); - fluid_comb_setbuffer(&rev->combR[7], rev->bufcombR8, combtuningR8); - fluid_allpass_setbuffer(&rev->allpassL[0], rev->bufallpassL1, allpasstuningL1); - fluid_allpass_setbuffer(&rev->allpassR[0], rev->bufallpassR1, allpasstuningR1); - fluid_allpass_setbuffer(&rev->allpassL[1], rev->bufallpassL2, allpasstuningL2); - fluid_allpass_setbuffer(&rev->allpassR[1], rev->bufallpassR2, allpasstuningR2); - fluid_allpass_setbuffer(&rev->allpassL[2], rev->bufallpassL3, allpasstuningL3); - fluid_allpass_setbuffer(&rev->allpassR[2], rev->bufallpassR3, allpasstuningR3); - fluid_allpass_setbuffer(&rev->allpassL[3], rev->bufallpassL4, allpasstuningL4); - fluid_allpass_setbuffer(&rev->allpassR[3], rev->bufallpassR4, allpasstuningR4); - /* Set default values */ - fluid_allpass_setfeedback(&rev->allpassL[0], 0.5f); - fluid_allpass_setfeedback(&rev->allpassR[0], 0.5f); - fluid_allpass_setfeedback(&rev->allpassL[1], 0.5f); - fluid_allpass_setfeedback(&rev->allpassR[1], 0.5f); - fluid_allpass_setfeedback(&rev->allpassL[2], 0.5f); - fluid_allpass_setfeedback(&rev->allpassR[2], 0.5f); - fluid_allpass_setfeedback(&rev->allpassL[3], 0.5f); - fluid_allpass_setfeedback(&rev->allpassR[3], 0.5f); - - /* set values manually, since calling set functions causes update - and all values should be initialized for an update */ - rev->roomsize = initialroom * scaleroom + offsetroom; - rev->damp = initialdamp * scaledamp; - rev->wet = initialwet * scalewet; - rev->width = initialwidth; - rev->gain = fixedgain; - - /* now its okay to update reverb */ - fluid_revmodel_update(rev); - - /* Clear all buffers */ - fluid_revmodel_init(rev); - return rev; -} - -void -delete_fluid_revmodel(fluid_revmodel_t* rev) -{ - FLUID_FREE(rev); -} - -void -fluid_revmodel_init(fluid_revmodel_t* rev) -{ - int i; - for (i = 0; i < numcombs;i++) { - fluid_comb_init(&rev->combL[i]); - fluid_comb_init(&rev->combR[i]); - } - for (i = 0; i < numallpasses; i++) { - fluid_allpass_init(&rev->allpassL[i]); - fluid_allpass_init(&rev->allpassR[i]); - } -} - -void -fluid_revmodel_reset(fluid_revmodel_t* rev) -{ - fluid_revmodel_init(rev); -} - -void -fluid_revmodel_processreplace(fluid_revmodel_t* rev, fluid_real_t *in, - fluid_real_t *left_out, fluid_real_t *right_out) -{ - int i, k = 0; - fluid_real_t outL, outR, input; - - for (k = 0; k < FLUID_BUFSIZE; k++) { - - outL = outR = 0; - - /* The original Freeverb code expects a stereo signal and 'input' - * is set to the sum of the left and right input sample. Since - * this code works on a mono signal, 'input' is set to twice the - * input sample. */ - input = (2 * in[k] + DC_OFFSET) * rev->gain; - - /* Accumulate comb filters in parallel */ - for (i = 0; i < numcombs; i++) { - fluid_comb_process(rev->combL[i], input, outL); - fluid_comb_process(rev->combR[i], input, outR); - } - /* Feed through allpasses in series */ - for (i = 0; i < numallpasses; i++) { - fluid_allpass_process(rev->allpassL[i], outL); - fluid_allpass_process(rev->allpassR[i], outR); - } - - /* Remove the DC offset */ - outL -= DC_OFFSET; - outR -= DC_OFFSET; - - /* Calculate output REPLACING anything already there */ - left_out[k] = outL * rev->wet1 + outR * rev->wet2; - right_out[k] = outR * rev->wet1 + outL * rev->wet2; - } -} - -void -fluid_revmodel_processmix(fluid_revmodel_t* rev, fluid_real_t *in, - fluid_real_t *left_out, fluid_real_t *right_out) -{ - int i, k = 0; - fluid_real_t outL, outR, input; - - for (k = 0; k < FLUID_BUFSIZE; k++) { - - outL = outR = 0; - - /* The original Freeverb code expects a stereo signal and 'input' - * is set to the sum of the left and right input sample. Since - * this code works on a mono signal, 'input' is set to twice the - * input sample. */ - input = (2 * in[k] + DC_OFFSET) * rev->gain; - - /* Accumulate comb filters in parallel */ - for (i = 0; i < numcombs; i++) { - fluid_comb_process(rev->combL[i], input, outL); - fluid_comb_process(rev->combR[i], input, outR); - } - /* Feed through allpasses in series */ - for (i = 0; i < numallpasses; i++) { - fluid_allpass_process(rev->allpassL[i], outL); - fluid_allpass_process(rev->allpassR[i], outR); - } - - /* Remove the DC offset */ - outL -= DC_OFFSET; - outR -= DC_OFFSET; - - /* Calculate output MIXING with anything already there */ - left_out[k] += outL * rev->wet1 + outR * rev->wet2; - right_out[k] += outR * rev->wet1 + outL * rev->wet2; - } -} - -void -fluid_revmodel_update(fluid_revmodel_t* rev) -{ - /* Recalculate internal values after parameter change */ - int i; - - rev->wet1 = rev->wet * (rev->width / 2 + 0.5f); - rev->wet2 = rev->wet * ((1 - rev->width) / 2); - - for (i = 0; i < numcombs; i++) { - fluid_comb_setfeedback(&rev->combL[i], rev->roomsize); - fluid_comb_setfeedback(&rev->combR[i], rev->roomsize); - } - - for (i = 0; i < numcombs; i++) { - fluid_comb_setdamp(&rev->combL[i], rev->damp); - fluid_comb_setdamp(&rev->combR[i], rev->damp); - } -} - -/* - The following get/set functions are not inlined, because - speed is never an issue when calling them, and also - because as you develop the reverb model, you may - wish to take dynamic action when they are called. -*/ -void -fluid_revmodel_setroomsize(fluid_revmodel_t* rev, fluid_real_t value) -{ -/* fluid_clip(value, 0.0f, 1.0f); */ - rev->roomsize = (value * scaleroom) + offsetroom; - fluid_revmodel_update(rev); -} - -fluid_real_t -fluid_revmodel_getroomsize(fluid_revmodel_t* rev) -{ - return (rev->roomsize - offsetroom) / scaleroom; -} - -void -fluid_revmodel_setdamp(fluid_revmodel_t* rev, fluid_real_t value) -{ -/* fluid_clip(value, 0.0f, 1.0f); */ - rev->damp = value * scaledamp; - fluid_revmodel_update(rev); -} - -fluid_real_t -fluid_revmodel_getdamp(fluid_revmodel_t* rev) -{ - return rev->damp / scaledamp; -} - -void -fluid_revmodel_setlevel(fluid_revmodel_t* rev, fluid_real_t value) -{ - fluid_clip(value, 0.0f, 1.0f); - rev->wet = value * scalewet; - fluid_revmodel_update(rev); -} - -fluid_real_t -fluid_revmodel_getlevel(fluid_revmodel_t* rev) -{ - return rev->wet / scalewet; -} - -void -fluid_revmodel_setwidth(fluid_revmodel_t* rev, fluid_real_t value) -{ -/* fluid_clip(value, 0.0f, 1.0f); */ - rev->width = value; - fluid_revmodel_update(rev); -} - -fluid_real_t -fluid_revmodel_getwidth(fluid_revmodel_t* rev) -{ - return rev->width; -} diff --git a/src/libs/fluidsynth/src/fluid_rev.h b/src/libs/fluidsynth/src/fluid_rev.h deleted file mode 100644 index 1d0fd2ed40..0000000000 --- a/src/libs/fluidsynth/src/fluid_rev.h +++ /dev/null @@ -1,67 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - - -#ifndef _FLUID_REV_H -#define _FLUID_REV_H - -#include "fluidsynth_priv.h" - -typedef struct _fluid_revmodel_t fluid_revmodel_t; - - -/* - * reverb - */ -fluid_revmodel_t* new_fluid_revmodel(void); -void delete_fluid_revmodel(fluid_revmodel_t* rev); - -void fluid_revmodel_processmix(fluid_revmodel_t* rev, fluid_real_t *in, - fluid_real_t *left_out, fluid_real_t *right_out); - -void fluid_revmodel_processreplace(fluid_revmodel_t* rev, fluid_real_t *in, - fluid_real_t *left_out, fluid_real_t *right_out); - -void fluid_revmodel_reset(fluid_revmodel_t* rev); - -void fluid_revmodel_setroomsize(fluid_revmodel_t* rev, fluid_real_t value); -void fluid_revmodel_setdamp(fluid_revmodel_t* rev, fluid_real_t value); -void fluid_revmodel_setlevel(fluid_revmodel_t* rev, fluid_real_t value); -void fluid_revmodel_setwidth(fluid_revmodel_t* rev, fluid_real_t value); -void fluid_revmodel_setmode(fluid_revmodel_t* rev, fluid_real_t value); - -fluid_real_t fluid_revmodel_getroomsize(fluid_revmodel_t* rev); -fluid_real_t fluid_revmodel_getdamp(fluid_revmodel_t* rev); -fluid_real_t fluid_revmodel_getlevel(fluid_revmodel_t* rev); -fluid_real_t fluid_revmodel_getwidth(fluid_revmodel_t* rev); - -/* - * reverb preset - */ -typedef struct _fluid_revmodel_presets_t { - char* name; - fluid_real_t roomsize; - fluid_real_t damp; - fluid_real_t width; - fluid_real_t level; -} fluid_revmodel_presets_t; - - -#endif /* _FLUID_REV_H */ diff --git a/src/libs/fluidsynth/src/fluid_seq.c b/src/libs/fluidsynth/src/fluid_seq.c deleted file mode 100644 index 7a8dd85897..0000000000 --- a/src/libs/fluidsynth/src/fluid_seq.c +++ /dev/null @@ -1,1037 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - - - -/* - 2002 : API design by Peter Hanappe and Antoine Schmitt - August 2002 : Implementation by Antoine Schmitt as@gratin.org - as part of the infiniteCD author project - http://www.infiniteCD.org/ -*/ - -#include "fluid_event_priv.h" -#include "fluidsynth_priv.h" // FLUID_NEW, etc -#include "fluid_sys.h" // timer, threads, etc... -#include "fluid_list.h" - -/*************************************************************** - * - * SEQUENCER - */ - -#define FLUID_SEQUENCER_EVENTS_MAX 1000 - -/* Private data for SEQUENCER */ -struct _fluid_sequencer_t { - unsigned int startMs; - double scale; // ticks per second - fluid_list_t* clients; - short clientsID; - /* for queue + heap */ - fluid_evt_entry* preQueue; - fluid_evt_entry* preQueueLast; - fluid_timer_t* timer; - int queue0StartTime; - short prevCellNb; - fluid_evt_entry* queue0[256][2]; - fluid_evt_entry* queue1[255][2]; - fluid_evt_entry* queueLater; - fluid_evt_heap_t* heap; - fluid_mutex_t mutex; -#if FLUID_SEQ_WITH_TRACE - char *tracebuf; - char *traceptr; - int tracelen; -#endif -}; - -/* Private data for clients */ -typedef struct _fluid_sequencer_client_t { - short id; - char* name; - fluid_event_callback_t callback; - void* data; -} fluid_sequencer_client_t; - -/* prototypes */ -/* sorting API */ -short _fluid_seq_queue_init(fluid_sequencer_t* seq, int nbEvents); -void _fluid_seq_queue_end(fluid_sequencer_t* seq); -short _fluid_seq_queue_pre_insert(fluid_sequencer_t* seq, fluid_event_t * evt); -void _fluid_seq_queue_pre_remove(fluid_sequencer_t* seq, short src, short dest, int type); -int _fluid_seq_queue_process(void* data, unsigned int msec); // callback from timer - - -/* API implementation */ - -fluid_sequencer_t* -new_fluid_sequencer() -{ - fluid_sequencer_t* seq; - - seq = FLUID_NEW(fluid_sequencer_t); - if (seq == NULL) { - fluid_log(FLUID_PANIC, "sequencer: Out of memory\n"); - return NULL; - } - - FLUID_MEMSET(seq, 0, sizeof(fluid_sequencer_t)); - - seq->scale = 1000; // default value - seq->startMs = fluid_curtime(); - seq->clients = NULL; - seq->clientsID = 0; - - if (-1 == _fluid_seq_queue_init(seq, FLUID_SEQUENCER_EVENTS_MAX)) { - FLUID_FREE(seq); - fluid_log(FLUID_PANIC, "sequencer: Out of memory\n"); - return NULL; - } - -#if FLUID_SEQ_WITH_TRACE - seq->tracelen = 1024*100; - seq->tracebuf = (char *)FLUID_MALLOC(seq->tracelen); - if (seq->tracebuf == NULL) { - _fluid_seq_queue_end(seq); - FLUID_FREE(seq); - fluid_log(FLUID_PANIC, "sequencer: Out of memory\n"); - return NULL; - } - seq->traceptr = seq->tracebuf; -#endif - - return(seq); -} - -void -delete_fluid_sequencer(fluid_sequencer_t* seq) -{ - - if (seq == NULL) { - return; - } - - _fluid_seq_queue_end(seq); - - /* cleanup clients */ - if (seq->clients) { - fluid_list_t *tmp = seq->clients; - while (tmp != NULL) { - fluid_sequencer_client_t *client = (fluid_sequencer_client_t*)tmp->data; - if (client->name) FLUID_FREE(client->name); - tmp = tmp->next; - } - delete_fluid_list(seq->clients); - seq->clients = NULL; - } - -#if FLUID_SEQ_WITH_TRACE - if (seq->tracebuf != NULL) - FLUID_FREE(seq->tracebuf); - seq->tracebuf = NULL; -#endif - - FLUID_FREE(seq); -} - -#if FLUID_SEQ_WITH_TRACE - -/* trace */ -void -fluid_seq_dotrace(fluid_sequencer_t* seq, char *fmt, ...) -{ - va_list args; - int len, remain = seq->tracelen - (seq->traceptr - seq->tracebuf); - if (remain <= 0) return; - - va_start (args, fmt); - len = vsnprintf(seq->traceptr, remain, fmt, args); - va_end (args); - - if (len > 0) { - if (len <= remain) { - // all written, with 0 at end - seq->traceptr += len; - } else { - // not enough room, set to end - seq->traceptr = seq->tracebuf + seq->tracelen; - } - } - - return; -} - -void -fluid_seq_cleartrace(fluid_sequencer_t* seq) -{ - seq->traceptr = seq->tracebuf; -} - -char * -fluid_seq_gettrace(fluid_sequencer_t* seq) -{ - return seq->tracebuf; -} -#else - -void fluid_seq_dotrace(fluid_sequencer_t* seq, char *fmt, ...) {} - -#endif // FLUID_SEQ_WITH_TRACE - -/* clients */ - -short fluid_sequencer_register_client(fluid_sequencer_t* seq, char* name, - fluid_event_callback_t callback, void* data) { - - fluid_sequencer_client_t * client; - char * nameCopy; - - client = FLUID_NEW(fluid_sequencer_client_t); - if (client == NULL) { - fluid_log(FLUID_PANIC, "sequencer: Out of memory\n"); - return -1; - } - - nameCopy = FLUID_STRDUP(name); - if (nameCopy == NULL) { - fluid_log(FLUID_PANIC, "sequencer: Out of memory\n"); - return -1; - } - - seq->clientsID++; - - client->name = nameCopy; - client->id = seq->clientsID; - client->callback = callback; - client->data = data; - - seq->clients = fluid_list_append(seq->clients, (void *)client); - - return (client->id); -} - -/** Unregister a previously registered client. */ -void fluid_sequencer_unregister_client(fluid_sequencer_t* seq, short id) -{ - fluid_list_t *tmp; - - if (seq->clients == NULL) return; - - tmp = seq->clients; - while (tmp) { - fluid_sequencer_client_t *client = (fluid_sequencer_client_t*)tmp->data; - - if (client->id == id) { - if (client->name) - FLUID_FREE(client->name); - seq->clients = fluid_list_remove_link(seq->clients, tmp); - delete1_fluid_list(tmp); - return; - } - tmp = tmp->next; - } - return; -} - -int fluid_sequencer_count_clients(fluid_sequencer_t* seq) -{ - if (seq->clients == NULL) - return 0; - return fluid_list_size(seq->clients); -} - -/** Returns the id of a registered client. */ -short fluid_sequencer_get_client_id(fluid_sequencer_t* seq, int index) -{ - fluid_list_t *tmp = fluid_list_nth(seq->clients, index); - if (tmp == NULL) { - return -1; - } else { - fluid_sequencer_client_t *client = (fluid_sequencer_client_t*)tmp->data; - return client->id; - } -} - -/** Returns the name of a registered client. */ -char* fluid_sequencer_get_client_name(fluid_sequencer_t* seq, int id) -{ - fluid_list_t *tmp; - - if (seq->clients == NULL) - return NULL; - - tmp = seq->clients; - while (tmp) { - fluid_sequencer_client_t *client = (fluid_sequencer_client_t*)tmp->data; - - if (client->id == id) - return client->name; - - tmp = tmp->next; - } - return NULL; -} - -int fluid_sequencer_client_is_dest(fluid_sequencer_t* seq, int id) -{ - fluid_list_t *tmp; - - if (seq->clients == NULL) return 0; - - tmp = seq->clients; - while (tmp) { - fluid_sequencer_client_t *client = (fluid_sequencer_client_t*)tmp->data; - - if (client->id == id) - return (client->callback != NULL); - - tmp = tmp->next; - } - return 0; -} - -/* sending events */ -void fluid_sequencer_send_now(fluid_sequencer_t* seq, fluid_event_t* evt) -{ - short destID = fluid_event_get_dest(evt); - - /* find callback */ - fluid_list_t *tmp = seq->clients; - while (tmp) { - fluid_sequencer_client_t *dest = (fluid_sequencer_client_t*)tmp->data; - - if (dest->id == destID) { - if (dest->callback) - (dest->callback)(fluid_sequencer_get_tick(seq), - evt, seq, dest->data); - return; - } - tmp = tmp->next; - } -} - -int -fluid_sequencer_send_at(fluid_sequencer_t* seq, fluid_event_t* evt, unsigned int time, int absolute) -{ - unsigned int now = fluid_sequencer_get_tick(seq); - - /* set absolute */ - if (!absolute) - time = now + time; - - /* time stamp event */ - fluid_event_set_time(evt, time); - - /* process late */ - if (time < now) { - fluid_sequencer_send_now(seq, evt); - return 0; - } - - /* process now */ - if (time == now) { - fluid_sequencer_send_now(seq, evt); - return 0; - } - - /* queue for processing later */ - return _fluid_seq_queue_pre_insert(seq, evt); -} - -void -fluid_sequencer_remove_events(fluid_sequencer_t* seq, short source, short dest, int type) -{ - _fluid_seq_queue_pre_remove(seq, source, dest, type); -} - - -/************************************* - time -**************************************/ -unsigned int fluid_sequencer_get_tick(fluid_sequencer_t* seq) -{ - unsigned int absMs = fluid_curtime(); - double nowFloat; - unsigned int now; - nowFloat = ((double)(absMs - seq->startMs))*seq->scale/1000.0f; - now = nowFloat; - return now; -} - -void fluid_sequencer_set_time_scale(fluid_sequencer_t* seq, double scale) -{ - if (scale <= 0) { - fluid_log(FLUID_WARN, "sequencer: scale <= 0 : %f\n", scale); - return; - } - - if (scale > 1000.0) - // Otherwise : problems with the timer = 0ms... - scale = 1000.0; - - if (seq->scale != scale) { - double oldScale = seq->scale; - - // stop timer - if (seq->timer) { - delete_fluid_timer(seq->timer); - seq->timer = NULL; - } - - seq->scale = scale; - - // change start0 so that cellNb is preserved - seq->queue0StartTime = (seq->queue0StartTime + seq->prevCellNb)*(seq->scale/oldScale) - seq->prevCellNb; - - // change all preQueue events for new scale - { - fluid_evt_entry* tmp; - tmp = seq->preQueue; - while (tmp) { - if (tmp->entryType == FLUID_EVT_ENTRY_INSERT) - tmp->evt.time = tmp->evt.time*seq->scale/oldScale; - - tmp = tmp->next; - } - } - - /* re-start timer */ - seq->timer = new_fluid_timer((int)(1000/seq->scale), _fluid_seq_queue_process, (void *)seq, 1, 0); - } -} - -/** Set the conversion from tick to absolute time (ticks per - second). */ -double fluid_sequencer_get_time_scale(fluid_sequencer_t* seq) -{ - return seq->scale; -} - - -/********************** - - the queue - -**********************/ - -/* - The queue stores all future events to be processed. - - Data structures - - There is a heap, allocated at init time, for managing a pool - of event entries, that is description of an event, its time, - and whether it is a normal event or a removal command. - - The queue is separated in two arrays, and a list. The first - array 'queue0' corresponds to the events to be sent in the - next 256 ticks (0 to 255), the second array 'queue1' contains - the events to be send from now+256 to now+65535. The list - called 'queueLater' contains the events to be sent later than - that. In each array, one cell contains a list of events having - the same time (in the queue0 array), or the same time/256 (in - the queue1 array), and a pointer to the last event in the list - of the cell so as to be able to insert fast at the end of the - list (i.e. a cell = 2 pointers). The 'queueLater' list is - ordered by time and by post time. This way, inserting 'soon' - events is fast (below 65535 ticks, that is about 1 minute if 1 - tick=1ms). Inserting later events is more slow, but this is a - realtime engine, isn't it ? - - The queue0 starts at queue0StartTime. When 256 ticks have - elapsed, the queue0 array is emptied, and the first cell of - the queue1 array is expanded in the queue0 array, according to - the time of each event. The queue1 array is shifted to the - left, and the first events of the queueLater list are inserte - in the last cell of the queue1 array. - - We remember the previously managed cell in queue0 in the - prevCellNb variable. When processing the current cell, we - process the events in between (late events). - - Functions - - The main thread functions first get an event entry from the - heap, and copy the given event into it, then merely enqueue it - in a preQueue. This is in order to protect the data structure: - everything is managed in the callback (thread or interrupt, - depending on the architecture). - - All queue data structure management is done in a timer - callback: '_fluid_seq_queue_process'. The - _fluid_seq_queue_process function first process the preQueue, - inserting or removing event entrys from the queue, then - processes the queue, by sending events ready to be sent at the - current time. - - Critical sections between the main thread (or app) and the - sequencer thread (or interrupt) are: - - - the heap management (if two threads get a free event at the - same time) - - the preQueue access. - - These are really small and fast sections (merely a pointer or - two changing value). They are not protected by a mutex for now - (August 2002). Waiting for crossplatform mutex solutions. When - changing this code, beware that the - _fluid_seq_queue_pre_insert function may be called by the - callback of the queue thread (ex : a note event inserts a - noteoff event). - -*/ - - - -void _fluid_seq_queue_insert_entry(fluid_sequencer_t* seq, fluid_evt_entry * evtentry); -void _fluid_seq_queue_remove_entries_matching(fluid_sequencer_t* seq, fluid_evt_entry* temp); -void _fluid_seq_queue_send_queued_events(fluid_sequencer_t* seq); - - -/********************/ -/* API */ -/********************/ - -short -_fluid_seq_queue_init(fluid_sequencer_t* seq, int maxEvents) -{ - int i; - - seq->heap = _fluid_evt_heap_init(maxEvents); - if (seq->heap == NULL) { - fluid_log(FLUID_PANIC, "sequencer: Out of memory\n"); - return -1; - } - - seq->preQueue = NULL; - seq->preQueueLast = NULL; - - FLUID_MEMSET(seq->queue0, 0, 2*256*sizeof(fluid_evt_entry *)); - FLUID_MEMSET(seq->queue1, 0, 2*255*sizeof(fluid_evt_entry *)); - - seq->queueLater = NULL; - seq->queue0StartTime = fluid_sequencer_get_tick(seq); - seq->prevCellNb = -1; - - fluid_mutex_init(seq->mutex); - - /* start timer */ - seq->timer = new_fluid_timer((int)(1000/seq->scale), _fluid_seq_queue_process, - (void *)seq, 1, 0); - return (0); -} - -void -_fluid_seq_queue_end(fluid_sequencer_t* seq) -{ - if (seq->timer) { - delete_fluid_timer(seq->timer); - seq->timer = NULL; - } - - if (seq->heap) { - _fluid_evt_heap_free(seq->heap); - seq->heap = NULL; - } - fluid_mutex_destroy(seq->mutex); -} - - - -/********************/ -/* queue management */ -/********************/ - -/* create event_entry and append to the preQueue */ -/* may be called from the main thread (usually) but also recursively - from the queue thread, when a callback itself does an insert... */ -short -_fluid_seq_queue_pre_insert(fluid_sequencer_t* seq, fluid_event_t * evt) -{ - fluid_evt_entry * evtentry = _fluid_seq_heap_get_free(seq->heap); - if (evtentry == NULL) { - /* should not happen */ - fluid_log(FLUID_PANIC, "sequencer: no more free events\n"); - return -1; - } - - evtentry->next = NULL; - evtentry->entryType = FLUID_EVT_ENTRY_INSERT; - FLUID_MEMCPY(&(evtentry->evt), evt, sizeof(fluid_event_t)); - - fluid_mutex_lock(seq->mutex); - - /* append to preQueue */ - if (seq->preQueueLast) { - seq->preQueueLast->next = evtentry; - } else { - seq->preQueue = evtentry; - } - seq->preQueueLast = evtentry; - - fluid_mutex_unlock(seq->mutex); - - return (0); -} - -/* create event_entry and append to the preQueue */ -/* may be called from the main thread (usually) but also recursively - from the queue thread, when a callback itself does an insert... */ -void -_fluid_seq_queue_pre_remove(fluid_sequencer_t* seq, short src, short dest, int type) -{ - fluid_evt_entry * evtentry = _fluid_seq_heap_get_free(seq->heap); - if (evtentry == NULL) { - /* should not happen */ - fluid_log(FLUID_PANIC, "sequencer: no more free events\n"); - return; - } - - evtentry->next = NULL; - evtentry->entryType = FLUID_EVT_ENTRY_REMOVE; - { - fluid_event_t* evt = &(evtentry->evt); - fluid_event_set_source(evt, src); - fluid_event_set_source(evt, src); - fluid_event_set_dest(evt, dest); - evt->type = type; - } - - fluid_mutex_lock(seq->mutex); - - /* append to preQueue */ - if (seq->preQueueLast) { - seq->preQueueLast->next = evtentry; - } else { - seq->preQueue = evtentry; - } - seq->preQueueLast = evtentry; - - fluid_mutex_unlock(seq->mutex); - return; -} - -/*********************** - * callback from timer - * (may be in a different thread, or in an interrupt) - * - ***********************/ -int -_fluid_seq_queue_process(void* data, unsigned int msec) -{ - fluid_sequencer_t* seq = (fluid_sequencer_t *)data; - - /* process prequeue */ - fluid_evt_entry* tmp; - fluid_evt_entry* next; - - fluid_mutex_lock(seq->mutex); - - /* get the preQueue */ - tmp = seq->preQueue; - seq->preQueue = NULL; - seq->preQueueLast = NULL; - - fluid_mutex_unlock(seq->mutex); - - /* walk all the preQueue and process them in order : inserts and removes */ - while (tmp) { - next = tmp->next; - - if (tmp->entryType == FLUID_EVT_ENTRY_REMOVE) { - _fluid_seq_queue_remove_entries_matching(seq, tmp); - } else { - _fluid_seq_queue_insert_entry(seq, tmp); - } - - tmp = next; - } - - /* send queued events */ - _fluid_seq_queue_send_queued_events(seq); - - /* continue timer */ - return 1; -} - - -void -_fluid_seq_queue_print_later(fluid_sequencer_t* seq) -{ - int count = 0; - fluid_evt_entry* tmp = seq->queueLater; - - printf("queueLater:\n"); - - while (tmp) { - unsigned int delay = tmp->evt.time - seq->queue0StartTime; - printf("queueLater: Delay = %i\n", delay); - tmp = tmp->next; - count++; - } - printf("queueLater: Total of %i events\n", count); -} - - -void -_fluid_seq_queue_insert_queue0(fluid_sequencer_t* seq, fluid_evt_entry* tmp, int cell) -{ - if (seq->queue0[cell][1] == NULL) { - seq->queue0[cell][1] = seq->queue0[cell][0] = tmp; - } else { - seq->queue0[cell][1]->next = tmp; - seq->queue0[cell][1] = tmp; - } - tmp->next = NULL; -} - -void -_fluid_seq_queue_insert_queue1(fluid_sequencer_t* seq, fluid_evt_entry* tmp, int cell) -{ - if (seq->queue1[cell][1] == NULL) { - seq->queue1[cell][1] = seq->queue1[cell][0] = tmp; - } else { - seq->queue1[cell][1]->next = tmp; - seq->queue1[cell][1] = tmp; - } - tmp->next = NULL; -} - -void -_fluid_seq_queue_insert_queue_later(fluid_sequencer_t* seq, fluid_evt_entry* evtentry) -{ - fluid_evt_entry* prev; - fluid_evt_entry* tmp; - unsigned int time = evtentry->evt.time; - - /* insert in 'queueLater', after the ones that have the same - * time */ - - /* first? */ - if ((seq->queueLater == NULL) - || (seq->queueLater->evt.time > time)) { - evtentry->next = seq->queueLater; - seq->queueLater = evtentry; - return; - } - - /* walk queueLater */ - /* this is the only slow thing : if the event is more - than 65535 ticks after the current time */ - - prev = seq->queueLater; - tmp = prev->next; - while (tmp) { - if (tmp->evt.time > time) { - /* insert before tmp */ - evtentry->next = tmp; - prev->next = evtentry; - return; - } - prev = tmp; - tmp = prev->next; - } - - /* last */ - evtentry->next = NULL; - prev->next = evtentry; -} - -void -_fluid_seq_queue_insert_entry(fluid_sequencer_t* seq, fluid_evt_entry * evtentry) -{ - /* time is relative to seq origin, in ticks */ - fluid_event_t * evt = &(evtentry->evt); - unsigned int time = evt->time; - unsigned int delay; - - if (seq->queue0StartTime > 0) { - /* queue0StartTime could be < 0 if the scale changed a - lot early, breaking the following comparison - */ - if (time < (unsigned int)seq->queue0StartTime) { - /* we are late, send now */ - fluid_sequencer_send_now(seq, evt); - - _fluid_seq_heap_set_free(seq->heap, evtentry); - return; - } - } - - if (seq->prevCellNb >= 0) { - /* prevCellNb could be -1 is seq was just started - unlikely */ - /* prevCellNb can also be -1 if cellNb was reset to 0 in - _fluid_seq_queue_send_queued_events() */ - if (time <= (unsigned int)(seq->queue0StartTime + seq->prevCellNb)) { - /* we are late, send now */ - fluid_sequencer_send_now(seq, evt); - - _fluid_seq_heap_set_free(seq->heap, evtentry); - return; - } - } - - delay = time - seq->queue0StartTime; - - if (delay > 65535) { - _fluid_seq_queue_insert_queue_later(seq, evtentry); - - } else if (delay > 255) { - _fluid_seq_queue_insert_queue1(seq, evtentry, delay/256 - 1); - - } else { - _fluid_seq_queue_insert_queue0(seq, evtentry, delay); - } -} - -int -_fluid_seq_queue_matchevent(fluid_event_t* evt, int templType, short templSrc, short templDest) -{ - int eventType; - - if (templSrc != -1 && templSrc != fluid_event_get_source(evt)) - return 0; - - if (templDest != -1 && templDest != fluid_event_get_dest(evt)) - return 0; - - if (templType == -1) - return 1; - - eventType = fluid_event_get_type(evt); - - if (templType == eventType) - return 1; - - if (templType == FLUID_SEQ_ANYCONTROLCHANGE) - if (eventType == FLUID_SEQ_PITCHBEND || - eventType == FLUID_SEQ_MODULATION || - eventType == FLUID_SEQ_SUSTAIN || - eventType == FLUID_SEQ_PAN || - eventType == FLUID_SEQ_VOLUME || - eventType == FLUID_SEQ_REVERBSEND || - eventType == FLUID_SEQ_CONTROLCHANGE || - eventType == FLUID_SEQ_CHORUSSEND) - return 1; - - return 0; -} - -void -_fluid_seq_queue_remove_entries_matching(fluid_sequencer_t* seq, fluid_evt_entry* templ) -{ - /* we walk everything : this is slow, but that is life */ - int i, type; - short src, dest; - - src = templ->evt.src; - dest = templ->evt.dest; - type = templ->evt.type; - - /* we can set it free now */ - _fluid_seq_heap_set_free(seq->heap, templ); - - /* queue0 */ - for (i = 0 ; i < 256 ; i++) { - fluid_evt_entry* tmp = seq->queue0[i][0]; - fluid_evt_entry* prev = NULL; - while (tmp) { - /* remove and/or walk */ - if (_fluid_seq_queue_matchevent((&tmp->evt), type, src, dest)) { - /* remove */ - if (prev) { - prev->next = tmp->next; - if (tmp == seq->queue0[i][1]) // last one in list - seq->queue0[i][1] = prev; - - _fluid_seq_heap_set_free(seq->heap, tmp); - tmp = prev->next; - } else { - /* first one in list */ - seq->queue0[i][0] = tmp->next; - if (tmp == seq->queue0[i][1]) // last one in list - seq->queue0[i][1] = NULL; - - _fluid_seq_heap_set_free(seq->heap, tmp); - tmp = seq->queue0[i][0]; - } - } else { - prev = tmp; - tmp = prev->next; - } - } - } - - /* queue1 */ - for (i = 0 ; i < 255 ; i++) { - fluid_evt_entry* tmp = seq->queue1[i][0]; - fluid_evt_entry* prev = NULL; - while (tmp) { - if (_fluid_seq_queue_matchevent((&tmp->evt), type, src, dest)) { - /* remove */ - if (prev) { - prev->next = tmp->next; - if (tmp == seq->queue1[i][1]) // last one in list - seq->queue1[i][1] = prev; - - _fluid_seq_heap_set_free(seq->heap, tmp); - tmp = prev->next; - } else { - /* first one in list */ - seq->queue1[i][0] = tmp->next; - if (tmp == seq->queue1[i][1]) // last one in list - seq->queue1[i][1] = NULL; - - _fluid_seq_heap_set_free(seq->heap, tmp); - tmp = seq->queue1[i][0]; - } - } else { - prev = tmp; - tmp = prev->next; - } - } - } - - /* queueLater */ - { - fluid_evt_entry* tmp = seq->queueLater; - fluid_evt_entry* prev = NULL; - while (tmp) { - if (_fluid_seq_queue_matchevent((&tmp->evt), type, src, dest)) { - /* remove */ - if (prev) { - prev->next = tmp->next; - - _fluid_seq_heap_set_free(seq->heap, tmp); - tmp = prev->next; - } else { - seq->queueLater = tmp->next; - - _fluid_seq_heap_set_free(seq->heap, tmp); - tmp = seq->queueLater; - } - } else { - prev = tmp; - tmp = prev->next; - } - } - } -} - -void -_fluid_seq_queue_send_cell_events(fluid_sequencer_t* seq, int cellNb) -{ - fluid_evt_entry* next; - fluid_evt_entry* tmp; - - tmp = seq->queue0[cellNb][0]; - while (tmp) { - fluid_sequencer_send_now(seq, &(tmp->evt)); - - next = tmp->next; - - _fluid_seq_heap_set_free(seq->heap, tmp); - tmp = next; - } - seq->queue0[cellNb][0] = NULL; - seq->queue0[cellNb][1] = NULL; -} - -void -_fluid_seq_queue_slide(fluid_sequencer_t* seq) -{ - short i; - fluid_evt_entry* next; - fluid_evt_entry* tmp; - int count = 0; - - /* do the slide */ - seq->queue0StartTime += 256; - - /* sort all queue1[0] into queue0 according to new queue0StartTime */ - tmp = seq->queue1[0][0]; - while (tmp) { - unsigned int delay = tmp->evt.time - seq->queue0StartTime; - next = tmp->next; - if (delay > 255) { - /* should not happen !! */ - /* append it to queue1[1] */ - _fluid_seq_queue_insert_queue1(seq, tmp, 1); - } else { - _fluid_seq_queue_insert_queue0(seq, tmp, delay); - } - tmp = next; - count++; - } - - /* slide all queue1[i] into queue1[i-1] */ - for (i = 1 ; i < 255 ; i++) { - seq->queue1[i-1][0] = seq->queue1[i][0]; - seq->queue1[i-1][1] = seq->queue1[i][1]; - } - seq->queue1[254][0] = NULL; - seq->queue1[254][1] = NULL; - - - /* append queueLater to queue1[254] */ - count = 0; - tmp = seq->queueLater; - while (tmp) { - unsigned int delay = tmp->evt.time - seq->queue0StartTime; - - if (delay > 65535) { - break; - } - - next = tmp->next; - - /* append it */ - _fluid_seq_queue_insert_queue1(seq, tmp, 254); - tmp = next; - count++; - } - - seq->queueLater = tmp; -} - -void -_fluid_seq_queue_send_queued_events(fluid_sequencer_t* seq) -{ - unsigned int nowTicks = fluid_sequencer_get_tick(seq); - short cellNb; - - cellNb = seq->prevCellNb + 1; - while (cellNb <= (int)(nowTicks - seq->queue0StartTime)) { - if (cellNb == 256) { - cellNb = 0; - _fluid_seq_queue_slide(seq); - } /* slide */ - - - /* process queue0[cellNb] */ - _fluid_seq_queue_send_cell_events(seq, cellNb); - - /* next cell */ - cellNb++; - } - - seq->prevCellNb = cellNb - 1; -} diff --git a/src/libs/fluidsynth/src/fluid_seqbind.c b/src/libs/fluidsynth/src/fluid_seqbind.c deleted file mode 100644 index 3702d3f3d2..0000000000 --- a/src/libs/fluidsynth/src/fluid_seqbind.c +++ /dev/null @@ -1,159 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - - - -/* - 2002 : API design by Peter Hanappe and Antoine Schmitt - August 2002 : Implementation by Antoine Schmitt as@gratin.org - as part of the infiniteCD author project - http://www.infiniteCD.org/ -*/ - -#include "fluidsynth_priv.h" - - /*************************************************************** - * - * SEQUENCER BINDING - */ - -void fluid_seq_fluidsynth_callback(unsigned int time, fluid_event_t* event, fluid_sequencer_t* seq, void* data); - -/* registering the synth */ -short fluid_sequencer_register_fluidsynth(fluid_sequencer_t* seq, fluid_synth_t* synth) -{ - /* register fluidsynth itself */ - return fluid_sequencer_register_client(seq, "fluidsynth", fluid_seq_fluidsynth_callback, (void *)synth); -} - -/* the callback itself */ -void fluid_seq_fluidsynth_callback(unsigned int time, fluid_event_t* evt, fluid_sequencer_t* seq, void* data) -{ - fluid_synth_t* synth = (fluid_synth_t *)data; - - switch (fluid_event_get_type(evt)) { - - case FLUID_SEQ_NOTEON: - fluid_synth_noteon(synth, fluid_event_get_channel(evt), fluid_event_get_key(evt), fluid_event_get_velocity(evt)); - break; - - case FLUID_SEQ_NOTEOFF: - fluid_synth_noteoff(synth, fluid_event_get_channel(evt), fluid_event_get_key(evt)); - break; - - case FLUID_SEQ_NOTE: - { - unsigned int dur; - fluid_synth_noteon(synth, fluid_event_get_channel(evt), fluid_event_get_key(evt), fluid_event_get_velocity(evt)); - dur = fluid_event_get_duration(evt); - fluid_event_noteoff(evt, fluid_event_get_channel(evt), fluid_event_get_key(evt)); - fluid_sequencer_send_at(seq, evt, dur, 0); - } - break; - - case FLUID_SEQ_ALLSOUNDSOFF: - /* NYI */ - break; - - case FLUID_SEQ_ALLNOTESOFF: - fluid_synth_cc(synth, fluid_event_get_channel(evt), 0x7B, 0); - break; - - case FLUID_SEQ_BANKSELECT: - fluid_synth_bank_select(synth, fluid_event_get_channel(evt), fluid_event_get_bank(evt)); - break; - - case FLUID_SEQ_PROGRAMCHANGE: - fluid_synth_program_change(synth, fluid_event_get_channel(evt), fluid_event_get_program(evt)); - break; - - case FLUID_SEQ_PROGRAMSELECT: - fluid_synth_program_select(synth, fluid_event_get_channel(evt), fluid_event_get_sfont_id(evt), - fluid_event_get_bank(evt), fluid_event_get_program(evt)); - break; - - case FLUID_SEQ_ANYCONTROLCHANGE: - /* nothing = only used by remove_events */ - break; - - case FLUID_SEQ_PITCHBEND: - fluid_synth_pitch_bend(synth, fluid_event_get_channel(evt), fluid_event_get_pitch(evt)); - break; - - case FLUID_SEQ_PITCHWHHELSENS: - fluid_synth_pitch_wheel_sens(synth, fluid_event_get_channel(evt), fluid_event_get_value(evt)); - break; - - case FLUID_SEQ_CONTROLCHANGE: - fluid_synth_cc(synth, fluid_event_get_channel(evt), fluid_event_get_control(evt), fluid_event_get_value(evt)); - break; - - case FLUID_SEQ_MODULATION: - { - short ctrl = 0x01; // MODULATION_MSB - fluid_synth_cc(synth, fluid_event_get_channel(evt), ctrl, fluid_event_get_value(evt)); - } - break; - - case FLUID_SEQ_SUSTAIN: - { - short ctrl = 0x40; // SUSTAIN_SWITCH - fluid_synth_cc(synth, fluid_event_get_channel(evt), ctrl, fluid_event_get_value(evt)); - } - break; - - case FLUID_SEQ_PAN: - { - short ctrl = 0x0A; // PAN_MSB - fluid_synth_cc(synth, fluid_event_get_channel(evt), ctrl, fluid_event_get_value(evt)); - } - break; - - case FLUID_SEQ_VOLUME: - { - short ctrl = 0x07; // VOLUME_MSB - fluid_synth_cc(synth, fluid_event_get_channel(evt), ctrl, fluid_event_get_value(evt)); - } - break; - - case FLUID_SEQ_REVERBSEND: - { - short ctrl = 0x5B; // EFFECTS_DEPTH1 - fluid_synth_cc(synth, fluid_event_get_channel(evt), ctrl, fluid_event_get_value(evt)); - } - break; - - case FLUID_SEQ_CHORUSSEND: - { - short ctrl = 0x5D; // EFFECTS_DEPTH3 - fluid_synth_cc(synth, fluid_event_get_channel(evt), ctrl, fluid_event_get_value(evt)); - } - break; - - case FLUID_SEQ_TIMER: - /* nothing in fluidsynth */ - break; - - default: - break; - } -} - - diff --git a/src/libs/fluidsynth/src/fluid_settings.c b/src/libs/fluidsynth/src/fluid_settings.c deleted file mode 100644 index 46dda0951a..0000000000 --- a/src/libs/fluidsynth/src/fluid_settings.c +++ /dev/null @@ -1,896 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#include "fluidsynth_priv.h" -#include "fluid_sys.h" -#include "fluid_hash.h" -#include "fluid_synth.h" -#include "fluid_cmd.h" -#include "fluid_adriver.h" -#include "fluid_mdriver.h" -#include "fluid_settings.h" - -/* maximum allowed components of a settings variable (separated by '.') */ -#define MAX_SETTINGS_TOKENS 8 /* currently only a max of 3 are used */ -#define MAX_SETTINGS_LABEL 256 /* max length of a settings variable label */ - -static void fluid_settings_init(fluid_settings_t* settings); -static void fluid_settings_hash_delete(void* value, int type); -static int fluid_settings_tokenize(char* s, char *buf, char** ptr); - - -typedef struct { - char* value; - char* def; - int hints; - fluid_list_t* options; - fluid_str_update_t update; - void* data; -} fluid_str_setting_t; - -static fluid_str_setting_t* -new_fluid_str_setting(char* value, char* def, int hints, fluid_str_update_t fun, void* data) -{ - fluid_str_setting_t* str; - str = FLUID_NEW(fluid_str_setting_t); - str->value = value? FLUID_STRDUP(value) : NULL; - str->def = def? FLUID_STRDUP(def) : NULL; - str->hints = hints; - str->options = NULL; - str->update = fun; - str->data = data; - return str; -} - -static void delete_fluid_str_setting(fluid_str_setting_t* str) -{ - if (str) { - if (str->value) { - FLUID_FREE(str->value); - } - if (str->def) { - FLUID_FREE(str->def); - } - if (str->options) { - fluid_list_t* list = str->options; - - while (list) { - FLUID_FREE (list->data); - list = fluid_list_next(list); - } - - delete_fluid_list(str->options); - } - FLUID_FREE(str); - } -} - - - - -typedef struct { - double value; - double def; - double min; - double max; - int hints; - fluid_num_update_t update; - void* data; -} fluid_num_setting_t; - - -static fluid_num_setting_t* -new_fluid_num_setting(double min, double max, double def, - int hints, fluid_num_update_t fun, void* data) -{ - fluid_num_setting_t* setting; - setting = FLUID_NEW(fluid_num_setting_t); - setting->value = def; - setting->def = def; - setting->min = min; - setting->max = max; - setting->hints = hints; - setting->update = fun; - setting->data = data; - return setting; -} - -static void delete_fluid_num_setting(fluid_num_setting_t* setting) -{ - if (setting) { - FLUID_FREE(setting); - } -} - - - - -typedef struct { - int value; - int def; - int min; - int max; - int hints; - fluid_int_update_t update; - void* data; -} fluid_int_setting_t; - - -static fluid_int_setting_t* -new_fluid_int_setting(int min, int max, int def, - int hints, fluid_int_update_t fun, void* data) -{ - fluid_int_setting_t* setting; - setting = FLUID_NEW(fluid_int_setting_t); - setting->value = def; - setting->def = def; - setting->min = min; - setting->max = max; - setting->hints = hints; - setting->update = fun; - setting->data = data; - return setting; -} - -static void delete_fluid_int_setting(fluid_int_setting_t* setting) -{ - if (setting) { - FLUID_FREE(setting); - } -} - - - -fluid_settings_t* new_fluid_settings() -{ - fluid_settings_t* settings = new_fluid_hashtable(fluid_settings_hash_delete); - if (settings == NULL) { - return NULL; - } - fluid_settings_init(settings); - return settings; -} - -void delete_fluid_settings(fluid_settings_t* settings) -{ - delete_fluid_hashtable(settings); -} - -void fluid_settings_hash_delete(void* value, int type) -{ - switch (type) { - case FLUID_NUM_TYPE: - delete_fluid_num_setting((fluid_num_setting_t*) value); - break; - case FLUID_INT_TYPE: - delete_fluid_int_setting((fluid_int_setting_t*) value); - break; - case FLUID_STR_TYPE: - delete_fluid_str_setting((fluid_str_setting_t*) value); - break; - case FLUID_SET_TYPE: - delete_fluid_hashtable((fluid_hashtable_t*) value); - break; - } -} - -void fluid_settings_init(fluid_settings_t* settings) -{ - fluid_synth_settings(settings); - fluid_shell_settings(settings); - fluid_audio_driver_settings(settings); - fluid_midi_driver_settings(settings); -} - -static int fluid_settings_tokenize(char* s, char *buf, char** ptr) -{ - char *tokstr, *tok; - int n = 0; - - if (strlen (s) > MAX_SETTINGS_LABEL) - { - FLUID_LOG(FLUID_ERR, "Setting variable name exceeded max length of %d chars", - MAX_SETTINGS_LABEL); - return 0; - } - - FLUID_STRCPY(buf, s); /* copy string to buffer, since it gets modified */ - tokstr = buf; - - while ((tok = fluid_strtok (&tokstr, "."))) - { - if (n > MAX_SETTINGS_TOKENS) - { - FLUID_LOG(FLUID_ERR, "Setting variable name exceeded max token count of %d", - MAX_SETTINGS_TOKENS); - return 0; - } - - ptr[n++] = tok; - } - - return n; -} - -/** returns 1 if the value exists, 0 otherwise */ -static int fluid_settings_get(fluid_settings_t* settings, - char** name, int len, - void** value, int* type) -{ - fluid_hashtable_t* table = settings; - int t; - void* v; - int n; - - for (n = 0; n < len; n++) { - - if (table == NULL) { - return 0; - } - - if (!fluid_hashtable_lookup(table, name[n], &v, &t)) { - return 0; - } - - table = (t == FLUID_SET_TYPE)? (fluid_hashtable_t*) v : NULL; - } - - if (value) { - *value = v; - } - - if (type) { - *type = t; - } - - return 1; -} - -/** returns 1 if the value has been set, zero otherwise */ -static int fluid_settings_set(fluid_settings_t* settings, - char** name, int len, - void* value, int type) -{ - fluid_hashtable_t* table = settings; - int t; - void* v; - int n, num = len - 1; - - for (n = 0; n < num; n++) { - - if (fluid_hashtable_lookup(table, name[n], &v, &t)) { - - if (t == FLUID_SET_TYPE) { - table = (fluid_hashtable_t*) v; - } else { - /* path ends prematurely */ - FLUID_LOG(FLUID_WARN, "'%s' is not a node", name[n]); - return 0; - } - - } else { - /* create a new node */ - fluid_hashtable_t* tmp; - tmp = new_fluid_hashtable(fluid_settings_hash_delete); - fluid_hashtable_insert(table, name[n], tmp, FLUID_SET_TYPE); - table = tmp; - } - } - - fluid_hashtable_replace(table, name[num], value, type); - - return 1; -} - -/** returns 1 if the value has been registered correctly, 0 - otherwise */ -int fluid_settings_register_str(fluid_settings_t* settings, char* name, char* def, int hints, - fluid_str_update_t fun, void* data) -{ - int type; - void* value; - char* tokens[MAX_SETTINGS_TOKENS]; - char buf[MAX_SETTINGS_LABEL+1]; - int ntokens; - fluid_str_setting_t* setting; - - ntokens = fluid_settings_tokenize(name, buf, tokens); - - if (!fluid_settings_get(settings, tokens, ntokens, &value, &type)) { - setting = new_fluid_str_setting(def, def, hints, fun, data); - return fluid_settings_set(settings, tokens, ntokens, setting, FLUID_STR_TYPE); - - } else { - /* if variable already exists, don't change its value. */ - if (type == FLUID_STR_TYPE) { - setting = (fluid_str_setting_t*) value; - setting->update = fun; - setting->data = data; - setting->def = def? FLUID_STRDUP(def) : NULL; - setting->hints = hints; - return 1; - } else { - FLUID_LOG(FLUID_WARN, "Type mismatch on setting '%s'", name); - return 1; - } - } -} - -/** returns 1 if the value has been register correctly, zero - otherwise */ -int fluid_settings_register_num(fluid_settings_t* settings, char* name, double def, - double min, double max, int hints, - fluid_num_update_t fun, void* data) -{ - int type; - void* value; - char* tokens[MAX_SETTINGS_TOKENS]; - char buf[MAX_SETTINGS_LABEL+1]; - int ntokens; - - ntokens = fluid_settings_tokenize(name, buf, tokens); - - if (!fluid_settings_get(settings, tokens, ntokens, &value, &type)) { - /* insert a new setting */ - fluid_num_setting_t* setting; - setting = new_fluid_num_setting(min, max, def, hints, fun, data); - return fluid_settings_set(settings, tokens, ntokens, setting, FLUID_NUM_TYPE); - - } else { - if (type == FLUID_NUM_TYPE) { - /* update the existing setting but don't change its value */ - fluid_num_setting_t* setting = (fluid_num_setting_t*) value; - setting->update = fun; - setting->data = data; - setting->min = min; - setting->max = max; - setting->def = def; - setting->hints = hints; - return 1; - - } else { - /* type mismatch */ - FLUID_LOG(FLUID_WARN, "Type mismatch on setting '%s'", name); - return 0; - } - } -} - -/** returns 1 if the value has been register correctly, zero - otherwise */ -int fluid_settings_register_int(fluid_settings_t* settings, char* name, int def, - int min, int max, int hints, - fluid_int_update_t fun, void* data) -{ - int type; - void* value; - char* tokens[MAX_SETTINGS_TOKENS]; - char buf[MAX_SETTINGS_LABEL+1]; - int ntokens; - - ntokens = fluid_settings_tokenize(name, buf, tokens); - - if (!fluid_settings_get(settings, tokens, ntokens, &value, &type)) { - /* insert a new setting */ - fluid_int_setting_t* setting; - setting = new_fluid_int_setting(min, max, def, hints, fun, data); - return fluid_settings_set(settings, tokens, ntokens, setting, FLUID_INT_TYPE); - - } else { - if (type == FLUID_INT_TYPE) { - /* update the existing setting but don't change its value */ - fluid_int_setting_t* setting = (fluid_int_setting_t*) value; - setting->update = fun; - setting->data = data; - setting->min = min; - setting->max = max; - setting->def = def; - setting->hints = hints; - return 1; - - } else { - /* type mismatch */ - FLUID_LOG(FLUID_WARN, "Type mismatch on setting '%s'", name); - return 0; - } - } -} - -int fluid_settings_get_type(fluid_settings_t* settings, char* name) -{ - int type; - void* value; - char* tokens[MAX_SETTINGS_TOKENS]; - char buf[MAX_SETTINGS_LABEL+1]; - int ntokens; - - ntokens = fluid_settings_tokenize(name, buf, tokens); - - return (fluid_settings_get(settings, tokens, ntokens, &value, &type))? type : FLUID_NO_TYPE; -} - -int fluid_settings_get_hints(fluid_settings_t* settings, char* name) -{ - int type; - void* value; - char* tokens[MAX_SETTINGS_TOKENS]; - char buf[MAX_SETTINGS_LABEL+1]; - int ntokens; - - ntokens = fluid_settings_tokenize(name, buf, tokens); - - if (fluid_settings_get(settings, tokens, ntokens, &value, &type)) { - if (type == FLUID_NUM_TYPE) { - fluid_num_setting_t* setting = (fluid_num_setting_t*) value; - return setting->hints; - } else if (type == FLUID_STR_TYPE) { - fluid_str_setting_t* setting = (fluid_str_setting_t*) value; - return setting->hints; - } else { - return 0; - } - } else { - return 0; - } -} - -int fluid_settings_is_realtime(fluid_settings_t* settings, char* name) -{ - int type; - void* value; - char* tokens[MAX_SETTINGS_TOKENS]; - char buf[MAX_SETTINGS_LABEL+1]; - int ntokens; - - ntokens = fluid_settings_tokenize(name, buf, tokens); - - if (fluid_settings_get(settings, tokens, ntokens, &value, &type)) { - if (type == FLUID_NUM_TYPE) { - fluid_num_setting_t* setting = (fluid_num_setting_t*) value; - return setting->update != NULL; - - } else if (type == FLUID_STR_TYPE) { - fluid_str_setting_t* setting = (fluid_str_setting_t*) value; - return setting->update != NULL; - } else { - return 0; - } - } else { - return 0; - } -} - -int fluid_settings_setstr(fluid_settings_t* settings, char* name, char* str) -{ - char* tokens[MAX_SETTINGS_TOKENS]; - char buf[MAX_SETTINGS_LABEL+1]; - int ntokens; - int type; - void* value; - fluid_str_setting_t* setting; - - ntokens = fluid_settings_tokenize(name, buf, tokens); - - if (fluid_settings_get(settings, tokens, ntokens, &value, &type)) { - - if (type != FLUID_STR_TYPE) { - return 0; - } - - setting = (fluid_str_setting_t*) value; - - if (setting->value) { - FLUID_FREE(setting->value); - } - setting->value = str? FLUID_STRDUP(str) : NULL; - - if (setting->update) { - (*setting->update)(setting->data, name, setting->value); - } - - return 1; - - } else { - /* insert a new setting */ - fluid_str_setting_t* setting; - setting = new_fluid_str_setting(str, NULL, 0, NULL, NULL); - return fluid_settings_set(settings, tokens, ntokens, setting, FLUID_STR_TYPE); - } -} - -int fluid_settings_getstr(fluid_settings_t* settings, char* name, char** str) -{ - int type; - void* value; - char* tokens[MAX_SETTINGS_TOKENS]; - char buf[MAX_SETTINGS_LABEL+1]; - int ntokens; - - ntokens = fluid_settings_tokenize(name, buf, tokens); - - if (fluid_settings_get(settings, tokens, ntokens, &value, &type) - && (type == FLUID_STR_TYPE)) { - fluid_str_setting_t* setting = (fluid_str_setting_t*) value; - *str = setting->value; - return 1; - } - *str = NULL; - return 0; -} - -int fluid_settings_str_equal(fluid_settings_t* settings, char* name, char* s) -{ - int type; - void* value; - char* tokens[MAX_SETTINGS_TOKENS]; - char buf[MAX_SETTINGS_LABEL+1]; - int ntokens; - - ntokens = fluid_settings_tokenize(name, buf, tokens); - - if (fluid_settings_get(settings, tokens, ntokens, &value, &type) - && (type == FLUID_STR_TYPE)) { - fluid_str_setting_t* setting = (fluid_str_setting_t*) value; - return FLUID_STRCMP(setting->value, s) == 0; - } - return 0; -} - -char* -fluid_settings_getstr_default(fluid_settings_t* settings, char* name) -{ - int type; - void* value; - char* tokens[MAX_SETTINGS_TOKENS]; - char buf[MAX_SETTINGS_LABEL+1]; - int ntokens; - - ntokens = fluid_settings_tokenize(name, buf, tokens); - - if (fluid_settings_get(settings, tokens, ntokens, &value, &type) - && (type == FLUID_STR_TYPE)) { - fluid_str_setting_t* setting = (fluid_str_setting_t*) value; - return setting->def; - } else { - return NULL; - } -} - -int fluid_settings_add_option(fluid_settings_t* settings, char* name, char* s) -{ - int type; - void* value; - char* tokens[MAX_SETTINGS_TOKENS]; - char buf[MAX_SETTINGS_LABEL+1]; - int ntokens; - - ntokens = fluid_settings_tokenize(name, buf, tokens); - - if (fluid_settings_get(settings, tokens, ntokens, &value, &type) - && (type == FLUID_STR_TYPE)) { - fluid_str_setting_t* setting = (fluid_str_setting_t*) value; - char* copy = FLUID_STRDUP(s); - setting->options = fluid_list_append(setting->options, copy); - return 1; - } else { - return 0; - } -} - -int fluid_settings_remove_option(fluid_settings_t* settings, char* name, char* s) -{ - int type; - void* value; - char* tokens[MAX_SETTINGS_TOKENS]; - char buf[MAX_SETTINGS_LABEL+1]; - int ntokens; - - ntokens = fluid_settings_tokenize(name, buf, tokens); - - if (fluid_settings_get(settings, tokens, ntokens, &value, &type) - && (type == FLUID_STR_TYPE)) { - - fluid_str_setting_t* setting = (fluid_str_setting_t*) value; - fluid_list_t* list = setting->options; - - while (list) { - char* option = (char*) fluid_list_get(list); - if (FLUID_STRCMP(s, option) == 0) { - FLUID_FREE (option); - setting->options = fluid_list_remove_link(setting->options, list); - return 1; - } - list = fluid_list_next(list); - } - - return 0; - } else { - return 0; - } -} - -int fluid_settings_setnum(fluid_settings_t* settings, char* name, double val) -{ - int type; - void* value; - fluid_num_setting_t* setting; - char* tokens[MAX_SETTINGS_TOKENS]; - char buf[MAX_SETTINGS_LABEL+1]; - int ntokens; - - ntokens = fluid_settings_tokenize(name, buf, tokens); - - if (fluid_settings_get(settings, tokens, ntokens, &value, &type)) { - - if (type != FLUID_NUM_TYPE) { - return 0; - } - - setting = (fluid_num_setting_t*) value; - - if (val < setting->min) { - val = setting->min; - } else if (val > setting->max) { - val = setting->max; - } - - setting->value = val; - - if (setting->update) { - (*setting->update)(setting->data, name, val); - } - - return 1; - - } else { - /* insert a new setting */ - fluid_num_setting_t* setting; - setting = new_fluid_num_setting(-1e10, 1e10, 0.0f, 0, NULL, NULL); - setting->value = val; - return fluid_settings_set(settings, tokens, ntokens, setting, FLUID_NUM_TYPE); - } -} - -int fluid_settings_getnum(fluid_settings_t* settings, char* name, double* val) -{ - int type; - void* value; - char* tokens[MAX_SETTINGS_TOKENS]; - char buf[MAX_SETTINGS_LABEL+1]; - int ntokens; - - ntokens = fluid_settings_tokenize(name, buf, tokens); - - if (fluid_settings_get(settings, tokens, ntokens, &value, &type) - && (type == FLUID_NUM_TYPE)) { - fluid_num_setting_t* setting = (fluid_num_setting_t*) value; - *val = setting->value; - return 1; - } - return 0; -} - - -void fluid_settings_getnum_range(fluid_settings_t* settings, char* name, double* min, double* max) -{ - int type; - void* value; - char* tokens[MAX_SETTINGS_TOKENS]; - char buf[MAX_SETTINGS_LABEL+1]; - int ntokens; - - ntokens = fluid_settings_tokenize(name, buf, tokens); - - if (fluid_settings_get(settings, tokens, ntokens, &value, &type) - && (type == FLUID_NUM_TYPE)) { - fluid_num_setting_t* setting = (fluid_num_setting_t*) value; - *min = setting->min; - *max = setting->max; - } -} - -double -fluid_settings_getnum_default(fluid_settings_t* settings, char* name) -{ - int type; - void* value; - char* tokens[MAX_SETTINGS_TOKENS]; - char buf[MAX_SETTINGS_LABEL+1]; - int ntokens; - - ntokens = fluid_settings_tokenize(name, buf, tokens); - - if (fluid_settings_get(settings, tokens, ntokens, &value, &type) - && (type == FLUID_NUM_TYPE)) { - fluid_num_setting_t* setting = (fluid_num_setting_t*) value; - return setting->def; - } else { - return 0.0f; - } -} - - -int fluid_settings_setint(fluid_settings_t* settings, char* name, int val) -{ - int type; - void* value; - fluid_int_setting_t* setting; - char* tokens[MAX_SETTINGS_TOKENS]; - char buf[MAX_SETTINGS_LABEL+1]; - int ntokens; - - ntokens = fluid_settings_tokenize(name, buf, tokens); - - if (fluid_settings_get(settings, tokens, ntokens, &value, &type)) { - - if (type != FLUID_INT_TYPE) { - return 0; - } - - setting = (fluid_int_setting_t*) value; - - if (val < setting->min) { - val = setting->min; - } else if (val > setting->max) { - val = setting->max; - } - - setting->value = val; - - if (setting->update) { - (*setting->update)(setting->data, name, val); - } - - return 1; - - } else { - /* insert a new setting */ - fluid_int_setting_t* setting; - setting = new_fluid_int_setting(INT_MIN, INT_MAX, 0, 0, NULL, NULL); - setting->value = val; - return fluid_settings_set(settings, tokens, ntokens, setting, FLUID_INT_TYPE); - } -} - -int fluid_settings_getint(fluid_settings_t* settings, char* name, int* val) -{ - int type; - void* value; - char* tokens[MAX_SETTINGS_TOKENS]; - char buf[MAX_SETTINGS_LABEL+1]; - int ntokens; - - ntokens = fluid_settings_tokenize(name, buf, tokens); - - if (fluid_settings_get(settings, tokens, ntokens, &value, &type) - && (type == FLUID_INT_TYPE)) { - fluid_int_setting_t* setting = (fluid_int_setting_t*) value; - *val = setting->value; - return 1; - } - return 0; -} - - -void fluid_settings_getint_range(fluid_settings_t* settings, char* name, int* min, int* max) -{ - int type; - void* value; - char* tokens[MAX_SETTINGS_TOKENS]; - char buf[MAX_SETTINGS_LABEL+1]; - int ntokens; - - ntokens = fluid_settings_tokenize(name, buf, tokens); - - if (fluid_settings_get(settings, tokens, ntokens, &value, &type) - && (type == FLUID_INT_TYPE)) { - fluid_int_setting_t* setting = (fluid_int_setting_t*) value; - *min = setting->min; - *max = setting->max; - } -} - -int -fluid_settings_getint_default(fluid_settings_t* settings, char* name) -{ - int type; - void* value; - char* tokens[MAX_SETTINGS_TOKENS]; - char buf[MAX_SETTINGS_LABEL+1]; - int ntokens; - - ntokens = fluid_settings_tokenize(name, buf, tokens); - - if (fluid_settings_get(settings, tokens, ntokens, &value, &type) - && (type == FLUID_INT_TYPE)) { - fluid_int_setting_t* setting = (fluid_int_setting_t*) value; - return setting->def; - } else { - return 0.0f; - } -} - - - - -void fluid_settings_foreach_option(fluid_settings_t* settings, char* name, void* data, - fluid_settings_foreach_option_t func) -{ - int type; - void* value; - char* tokens[MAX_SETTINGS_TOKENS]; - char buf[MAX_SETTINGS_LABEL+1]; - int ntokens; - - if (!func) { - return; - } - - ntokens = fluid_settings_tokenize(name, buf, tokens); - - if (fluid_settings_get(settings, tokens, ntokens, &value, &type) - && (type == FLUID_STR_TYPE)) { - - fluid_str_setting_t* setting = (fluid_str_setting_t*) value; - fluid_list_t* list = setting->options; - - while (list) { - char* option = (char*) fluid_list_get(list); - (*func)(data, name, option); - list = fluid_list_next(list); - } - } -} - - -static fluid_settings_foreach_t fluid_settings_foreach_func; -static void* fluid_settings_foreach_data; - -int fluid_settings_foreach_iter(char* key, void* value, int type, void* data) -{ - char path[1024]; - - if (data == 0) { - snprintf(path, 1024, "%s", key); - } else { - snprintf(path, 1024, "%s.%s", (char*) data, key); - } - path[1023] = 0; - - switch (type) { - case FLUID_NUM_TYPE: - case FLUID_INT_TYPE: - case FLUID_STR_TYPE: - (*fluid_settings_foreach_func)(fluid_settings_foreach_data, path, type); - break; - case FLUID_SET_TYPE: - fluid_hashtable_foreach((fluid_hashtable_t*) value, fluid_settings_foreach_iter, &path[0]); - break; - } - - return 0; -} - -void fluid_settings_foreach(fluid_settings_t* settings, void* data, fluid_settings_foreach_t func) -{ - fluid_settings_foreach_func = func; - fluid_settings_foreach_data = data; - fluid_hashtable_foreach(settings, fluid_settings_foreach_iter, 0); -} diff --git a/src/libs/fluidsynth/src/fluid_settings.h b/src/libs/fluidsynth/src/fluid_settings.h deleted file mode 100644 index 198640d857..0000000000 --- a/src/libs/fluidsynth/src/fluid_settings.h +++ /dev/null @@ -1,55 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - - -#ifndef _FLUID_SETTINGS_H -#define _FLUID_SETTINGS_H - - - -/** returns 1 if the option was added, 0 otherwise */ -int fluid_settings_add_option(fluid_settings_t* settings, char* name, char* s); - -/** returns 1 if the option was added, 0 otherwise */ -int fluid_settings_remove_option(fluid_settings_t* settings, char* name, char* s); - - -typedef int (*fluid_num_update_t)(void* data, char* name, double value); -typedef int (*fluid_str_update_t)(void* data, char* name, char* value); -typedef int (*fluid_int_update_t)(void* data, char* name, int value); - -/** returns 0 if the value has been resgister correctly, non-zero - otherwise */ -int fluid_settings_register_str(fluid_settings_t* settings, char* name, char* def, int hints, - fluid_str_update_t fun, void* data); - -/** returns 0 if the value has been resgister correctly, non-zero - otherwise */ -int fluid_settings_register_num(fluid_settings_t* settings, char* name, double min, double max, - double def, int hints, fluid_num_update_t fun, void* data); - - -/** returns 0 if the value has been resgister correctly, non-zero - otherwise */ -int fluid_settings_register_int(fluid_settings_t* settings, char* name, int min, int max, - int def, int hints, fluid_int_update_t fun, void* data); - - -#endif /* _FLUID_SETTINGS_H */ diff --git a/src/libs/fluidsynth/src/fluid_sfont.h b/src/libs/fluidsynth/src/fluid_sfont.h deleted file mode 100644 index 57bddd9958..0000000000 --- a/src/libs/fluidsynth/src/fluid_sfont.h +++ /dev/null @@ -1,68 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - - -#ifndef _PRIV_FLUID_SFONT_H -#define _PRIV_FLUID_SFONT_H - - -/* - * Utility macros to access soundfonts, presets, and samples - */ - -#define fluid_sfloader_delete(_loader) { if ((_loader) && (_loader)->free) (*(_loader)->free)(_loader); } -#define fluid_sfloader_load(_loader, _filename) (*(_loader)->load)(_loader, _filename) - - -#define delete_fluid_sfont(_sf) ( ((_sf) && (_sf)->free)? (*(_sf)->free)(_sf) : 0) -#define fluid_sfont_get_name(_sf) (*(_sf)->get_name)(_sf) -#define fluid_sfont_get_preset(_sf,_bank,_prenum) (*(_sf)->get_preset)(_sf,_bank,_prenum) -#define fluid_sfont_iteration_start(_sf) (*(_sf)->iteration_start)(_sf) -#define fluid_sfont_iteration_next(_sf,_pr) (*(_sf)->iteration_next)(_sf,_pr) -#define fluid_sfont_get_data(_sf) (_sf)->data -#define fluid_sfont_set_data(_sf,_p) { (_sf)->data = (void*) (_p); } - - -#define delete_fluid_preset(_preset) \ - { if ((_preset) && (_preset)->free) { (*(_preset)->free)(_preset); }} - -#define fluid_preset_get_data(_preset) (_preset)->data -#define fluid_preset_set_data(_preset,_p) { (_preset)->data = (void*) (_p); } -#define fluid_preset_get_name(_preset) (*(_preset)->get_name)(_preset) -#define fluid_preset_get_banknum(_preset) (*(_preset)->get_banknum)(_preset) -#define fluid_preset_get_num(_preset) (*(_preset)->get_num)(_preset) - -#define fluid_preset_noteon(_preset,_synth,_ch,_key,_vel) \ - (*(_preset)->noteon)(_preset,_synth,_ch,_key,_vel) - -#define fluid_preset_notify(_preset,_reason,_chan) \ - { if ((_preset) && (_preset)->notify) { (*(_preset)->notify)(_preset,_reason,_chan); }} - - -#define fluid_sample_incr_ref(_sample) { (_sample)->refcount++; } - -#define fluid_sample_decr_ref(_sample) \ - (_sample)->refcount--; \ - if (((_sample)->refcount == 0) && ((_sample)->notify)) \ - (*(_sample)->notify)(_sample, FLUID_SAMPLE_DONE); - - - -#endif /* _PRIV_FLUID_SFONT_H */ diff --git a/src/libs/fluidsynth/src/fluid_synth.c b/src/libs/fluidsynth/src/fluid_synth.c deleted file mode 100644 index a81c3ba8f7..0000000000 --- a/src/libs/fluidsynth/src/fluid_synth.c +++ /dev/null @@ -1,3227 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#include - -#include "fluid_synth.h" -#include "fluid_sys.h" -#include "fluid_chan.h" -#include "fluid_tuning.h" -#include "fluid_settings.h" -#include "fluid_sfont.h" - -#ifdef TRAP_ON_FPE -#define _GNU_SOURCE -#include - -/* seems to not be declared in fenv.h */ -extern int feenableexcept (int excepts); -#endif - - -fluid_sfloader_t* new_fluid_defsfloader(void); - -/************************************************************************ - * - * These functions were added after the v1.0 API freeze. They are not - * in synth.h. They should be added as soon as a new development - * version is started. - * - ************************************************************************/ - -int fluid_synth_program_select2(fluid_synth_t* synth, - int chan, - char* sfont_name, - unsigned int bank_num, - unsigned int preset_num); - -fluid_sfont_t* fluid_synth_get_sfont_by_name(fluid_synth_t* synth, char *name); - -int fluid_synth_set_gen2(fluid_synth_t* synth, int chan, - int param, float value, - int absolute, int normalized); - - -/*************************************************************** - * - * GLOBAL - */ - -/* has the synth module been initialized? */ -static int fluid_synth_initialized = 0; -static void fluid_synth_init(void); -static void init_dither(void); - -/* default modulators - * SF2.01 page 52 ff: - * - * There is a set of predefined default modulators. They have to be - * explicitly overridden by the sound font in order to turn them off. - */ - -fluid_mod_t default_vel2att_mod; /* SF2.01 section 8.4.1 */ -fluid_mod_t default_vel2filter_mod; /* SF2.01 section 8.4.2 */ -fluid_mod_t default_at2viblfo_mod; /* SF2.01 section 8.4.3 */ -fluid_mod_t default_mod2viblfo_mod; /* SF2.01 section 8.4.4 */ -fluid_mod_t default_att_mod; /* SF2.01 section 8.4.5 */ -fluid_mod_t default_pan_mod; /* SF2.01 section 8.4.6 */ -fluid_mod_t default_expr_mod; /* SF2.01 section 8.4.7 */ -fluid_mod_t default_reverb_mod; /* SF2.01 section 8.4.8 */ -fluid_mod_t default_chorus_mod; /* SF2.01 section 8.4.9 */ -fluid_mod_t default_pitch_bend_mod; /* SF2.01 section 8.4.10 */ - -/* reverb presets */ -static fluid_revmodel_presets_t revmodel_preset[] = { - /* name */ /* roomsize */ /* damp */ /* width */ /* level */ - { "Test 1", 0.2f, 0.0f, 0.5f, 0.9f }, - { "Test 2", 0.4f, 0.2f, 0.5f, 0.8f }, - { "Test 3", 0.6f, 0.4f, 0.5f, 0.7f }, - { "Test 4", 0.8f, 0.7f, 0.5f, 0.6f }, - { "Test 5", 0.8f, 1.0f, 0.5f, 0.5f }, - { NULL, 0.0f, 0.0f, 0.0f, 0.0f } -}; - - -/*************************************************************** - * - * INITIALIZATION & UTILITIES - */ - - -void fluid_synth_settings(fluid_settings_t* settings) -{ - fluid_settings_register_str(settings, "synth.verbose", "no", 0, NULL, NULL); - fluid_settings_register_str(settings, "synth.dump", "no", 0, NULL, NULL); - fluid_settings_register_str(settings, "synth.reverb.active", "yes", 0, NULL, NULL); - fluid_settings_register_str(settings, "synth.chorus.active", "yes", 0, NULL, NULL); - fluid_settings_register_str(settings, "synth.ladspa.active", "no", 0, NULL, NULL); - fluid_settings_register_str(settings, "midi.portname", "", 0, NULL, NULL); - - fluid_settings_register_int(settings, "synth.polyphony", - 256, 16, 4096, 0, NULL, NULL); - fluid_settings_register_int(settings, "synth.midi-channels", - 16, 16, 256, 0, NULL, NULL); - fluid_settings_register_num(settings, "synth.gain", - 0.2f, 0.0f, 10.0f, - 0, NULL, NULL); - fluid_settings_register_int(settings, "synth.audio-channels", - 1, 1, 256, 0, NULL, NULL); - fluid_settings_register_int(settings, "synth.audio-groups", - 1, 1, 256, 0, NULL, NULL); - fluid_settings_register_int(settings, "synth.effects-channels", - 2, 2, 2, 0, NULL, NULL); - fluid_settings_register_num(settings, "synth.sample-rate", - 44100.0f, 22050.0f, 96000.0f, - 0, NULL, NULL); -} - -/* - * fluid_version - */ -void fluid_version(int *major, int *minor, int *micro) -{ - *major = FLUIDSYNTH_VERSION_MAJOR; - *minor = FLUIDSYNTH_VERSION_MINOR; - *micro = FLUIDSYNTH_VERSION_MICRO; -} - -/* - * fluid_version_str - */ -char* fluid_version_str(void) -{ - return FLUIDSYNTH_VERSION; -} - - -/* - * void fluid_synth_init - * - * Does all the initialization for this module. - */ -static void -fluid_synth_init() -{ - fluid_synth_initialized++; - -#ifdef TRAP_ON_FPE - /* Turn on floating point exception traps */ - feenableexcept (FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID); -#endif - - fluid_conversion_config(); - - fluid_dsp_float_config(); - - fluid_sys_config(); - - init_dither(); - - - /* SF2.01 page 53 section 8.4.1: MIDI Note-On Velocity to Initial Attenuation */ - fluid_mod_set_source1(&default_vel2att_mod, /* The modulator we are programming here */ - FLUID_MOD_VELOCITY, /* Source. VELOCITY corresponds to 'index=2'. */ - FLUID_MOD_GC /* Not a MIDI continuous controller */ - | FLUID_MOD_CONCAVE /* Curve shape. Corresponds to 'type=1' */ - | FLUID_MOD_UNIPOLAR /* Polarity. Corresponds to 'P=0' */ - | FLUID_MOD_NEGATIVE /* Direction. Corresponds to 'D=1' */ - ); - fluid_mod_set_source2(&default_vel2att_mod, 0, 0); /* No 2nd source */ - fluid_mod_set_dest(&default_vel2att_mod, GEN_ATTENUATION); /* Target: Initial attenuation */ - fluid_mod_set_amount(&default_vel2att_mod, 960.0); /* Modulation amount: 960 */ - - - - /* SF2.01 page 53 section 8.4.2: MIDI Note-On Velocity to Filter Cutoff - * Have to make a design decision here. The specs don't make any sense this way or another. - * One sound font, 'Kingston Piano', which has been praised for its quality, tries to - * override this modulator with an amount of 0 and positive polarity (instead of what - * the specs say, D=1) for the secondary source. - * So if we change the polarity to 'positive', one of the best free sound fonts works... - */ - fluid_mod_set_source1(&default_vel2filter_mod, FLUID_MOD_VELOCITY, /* Index=2 */ - FLUID_MOD_GC /* CC=0 */ - | FLUID_MOD_LINEAR /* type=0 */ - | FLUID_MOD_UNIPOLAR /* P=0 */ - | FLUID_MOD_NEGATIVE /* D=1 */ - ); - fluid_mod_set_source2(&default_vel2filter_mod, FLUID_MOD_VELOCITY, /* Index=2 */ - FLUID_MOD_GC /* CC=0 */ - | FLUID_MOD_SWITCH /* type=3 */ - | FLUID_MOD_UNIPOLAR /* P=0 */ - // do not remove | FLUID_MOD_NEGATIVE /* D=1 */ - | FLUID_MOD_POSITIVE /* D=0 */ - ); - fluid_mod_set_dest(&default_vel2filter_mod, GEN_FILTERFC); /* Target: Initial filter cutoff */ - fluid_mod_set_amount(&default_vel2filter_mod, -2400); - - - - /* SF2.01 page 53 section 8.4.3: MIDI Channel pressure to Vibrato LFO pitch depth */ - fluid_mod_set_source1(&default_at2viblfo_mod, FLUID_MOD_CHANNELPRESSURE, /* Index=13 */ - FLUID_MOD_GC /* CC=0 */ - | FLUID_MOD_LINEAR /* type=0 */ - | FLUID_MOD_UNIPOLAR /* P=0 */ - | FLUID_MOD_POSITIVE /* D=0 */ - ); - fluid_mod_set_source2(&default_at2viblfo_mod, 0,0); /* no second source */ - fluid_mod_set_dest(&default_at2viblfo_mod, GEN_VIBLFOTOPITCH); /* Target: Vib. LFO => pitch */ - fluid_mod_set_amount(&default_at2viblfo_mod, 50); - - - - /* SF2.01 page 53 section 8.4.4: Mod wheel (Controller 1) to Vibrato LFO pitch depth */ - fluid_mod_set_source1(&default_mod2viblfo_mod, 1, /* Index=1 */ - FLUID_MOD_CC /* CC=1 */ - | FLUID_MOD_LINEAR /* type=0 */ - | FLUID_MOD_UNIPOLAR /* P=0 */ - | FLUID_MOD_POSITIVE /* D=0 */ - ); - fluid_mod_set_source2(&default_mod2viblfo_mod, 0,0); /* no second source */ - fluid_mod_set_dest(&default_mod2viblfo_mod, GEN_VIBLFOTOPITCH); /* Target: Vib. LFO => pitch */ - fluid_mod_set_amount(&default_mod2viblfo_mod, 50); - - - - /* SF2.01 page 55 section 8.4.5: MIDI continuous controller 7 to initial attenuation*/ - fluid_mod_set_source1(&default_att_mod, 7, /* index=7 */ - FLUID_MOD_CC /* CC=1 */ - | FLUID_MOD_CONCAVE /* type=1 */ - | FLUID_MOD_UNIPOLAR /* P=0 */ - | FLUID_MOD_NEGATIVE /* D=1 */ - ); - fluid_mod_set_source2(&default_att_mod, 0, 0); /* No second source */ - fluid_mod_set_dest(&default_att_mod, GEN_ATTENUATION); /* Target: Initial attenuation */ - fluid_mod_set_amount(&default_att_mod, 960.0); /* Amount: 960 */ - - - - /* SF2.01 page 55 section 8.4.6 MIDI continuous controller 10 to Pan Position */ - fluid_mod_set_source1(&default_pan_mod, 10, /* index=10 */ - FLUID_MOD_CC /* CC=1 */ - | FLUID_MOD_LINEAR /* type=0 */ - | FLUID_MOD_BIPOLAR /* P=1 */ - | FLUID_MOD_POSITIVE /* D=0 */ - ); - fluid_mod_set_source2(&default_pan_mod, 0, 0); /* No second source */ - fluid_mod_set_dest(&default_pan_mod, GEN_PAN); /* Target: pan */ - /* Amount: 500. The SF specs $8.4.6, p. 55 syas: "Amount = 1000 - tenths of a percent". The center value (64) corresponds to 50%, - so it follows that amount = 50% x 1000/% = 500. */ - fluid_mod_set_amount(&default_pan_mod, 500.0); - - - /* SF2.01 page 55 section 8.4.7: MIDI continuous controller 11 to initial attenuation*/ - fluid_mod_set_source1(&default_expr_mod, 11, /* index=11 */ - FLUID_MOD_CC /* CC=1 */ - | FLUID_MOD_CONCAVE /* type=1 */ - | FLUID_MOD_UNIPOLAR /* P=0 */ - | FLUID_MOD_NEGATIVE /* D=1 */ - ); - fluid_mod_set_source2(&default_expr_mod, 0, 0); /* No second source */ - fluid_mod_set_dest(&default_expr_mod, GEN_ATTENUATION); /* Target: Initial attenuation */ - fluid_mod_set_amount(&default_expr_mod, 960.0); /* Amount: 960 */ - - - - /* SF2.01 page 55 section 8.4.8: MIDI continuous controller 91 to Reverb send */ - fluid_mod_set_source1(&default_reverb_mod, 91, /* index=91 */ - FLUID_MOD_CC /* CC=1 */ - | FLUID_MOD_LINEAR /* type=0 */ - | FLUID_MOD_UNIPOLAR /* P=0 */ - | FLUID_MOD_POSITIVE /* D=0 */ - ); - fluid_mod_set_source2(&default_reverb_mod, 0, 0); /* No second source */ - fluid_mod_set_dest(&default_reverb_mod, GEN_REVERBSEND); /* Target: Reverb send */ - fluid_mod_set_amount(&default_reverb_mod, 200); /* Amount: 200 ('tenths of a percent') */ - - - - /* SF2.01 page 55 section 8.4.9: MIDI continuous controller 93 to Reverb send */ - fluid_mod_set_source1(&default_chorus_mod, 93, /* index=93 */ - FLUID_MOD_CC /* CC=1 */ - | FLUID_MOD_LINEAR /* type=0 */ - | FLUID_MOD_UNIPOLAR /* P=0 */ - | FLUID_MOD_POSITIVE /* D=0 */ - ); - fluid_mod_set_source2(&default_chorus_mod, 0, 0); /* No second source */ - fluid_mod_set_dest(&default_chorus_mod, GEN_CHORUSSEND); /* Target: Chorus */ - fluid_mod_set_amount(&default_chorus_mod, 200); /* Amount: 200 ('tenths of a percent') */ - - - - /* SF2.01 page 57 section 8.4.10 MIDI Pitch Wheel to Initial Pitch ... */ - fluid_mod_set_source1(&default_pitch_bend_mod, FLUID_MOD_PITCHWHEEL, /* Index=14 */ - FLUID_MOD_GC /* CC =0 */ - | FLUID_MOD_LINEAR /* type=0 */ - | FLUID_MOD_BIPOLAR /* P=1 */ - | FLUID_MOD_POSITIVE /* D=0 */ - ); - fluid_mod_set_source2(&default_pitch_bend_mod, FLUID_MOD_PITCHWHEELSENS, /* Index = 16 */ - FLUID_MOD_GC /* CC=0 */ - | FLUID_MOD_LINEAR /* type=0 */ - | FLUID_MOD_UNIPOLAR /* P=0 */ - | FLUID_MOD_POSITIVE /* D=0 */ - ); - fluid_mod_set_dest(&default_pitch_bend_mod, GEN_PITCH); /* Destination: Initial pitch */ - fluid_mod_set_amount(&default_pitch_bend_mod, 12700.0); /* Amount: 12700 cents */ -} - - -int fluid_synth_verify_settings(fluid_settings_t *settings) -{ - return 0; -} - -/*************************************************************** - * - * FLUID SYNTH - */ - -/* - * new_fluid_synth - */ -fluid_synth_t* -new_fluid_synth(fluid_settings_t *settings) -{ - int i; - fluid_synth_t* synth; - fluid_sfloader_t* loader; - - /* initialize all the conversion tables and other stuff */ - if (fluid_synth_initialized == 0) { - fluid_synth_init(); - } - - fluid_synth_verify_settings(settings); - - /* allocate a new synthesizer object */ - synth = FLUID_NEW(fluid_synth_t); - if (synth == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - FLUID_MEMSET(synth, 0, sizeof(fluid_synth_t)); - - fluid_mutex_init(synth->busy); - - synth->settings = settings; - - synth->with_reverb = fluid_settings_str_equal(settings, "synth.reverb.active", "yes"); - synth->with_chorus = fluid_settings_str_equal(settings, "synth.chorus.active", "yes"); - synth->verbose = fluid_settings_str_equal(settings, "synth.verbose", "yes"); - synth->dump = fluid_settings_str_equal(settings, "synth.dump", "yes"); - - fluid_settings_getint(settings, "synth.polyphony", &synth->polyphony); - fluid_settings_getnum(settings, "synth.sample-rate", &synth->sample_rate); - fluid_settings_getint(settings, "synth.midi-channels", &synth->midi_channels); - fluid_settings_getint(settings, "synth.audio-channels", &synth->audio_channels); - fluid_settings_getint(settings, "synth.audio-groups", &synth->audio_groups); - fluid_settings_getint(settings, "synth.effects-channels", &synth->effects_channels); - fluid_settings_getnum(settings, "synth.gain", &synth->gain); - - /* register the callbacks */ - fluid_settings_register_num(settings, "synth.gain", - 0.2f, 0.0f, 10.0f, 0, - (fluid_num_update_t) fluid_synth_update_gain, synth); - fluid_settings_register_int(settings, "synth.polyphony", - synth->polyphony, 16, 4096, 0, - (fluid_int_update_t) fluid_synth_update_polyphony, - synth); - - /* do some basic sanity checking on the settings */ - - if (synth->midi_channels % 16 != 0) { - int n = synth->midi_channels / 16; - synth->midi_channels = (n + 1) * 16; - fluid_settings_setint(settings, "synth.midi-channels", synth->midi_channels); - FLUID_LOG(FLUID_WARN, "Requested number of MIDI channels is not a multiple of 16. " - "I'll increase the number of channels to the next multiple."); - } - - if (synth->audio_channels < 1) { - FLUID_LOG(FLUID_WARN, "Requested number of audio channels is smaller than 1. " - "Changing this setting to 1."); - synth->audio_channels = 1; - } else if (synth->audio_channels > 128) { - FLUID_LOG(FLUID_WARN, "Requested number of audio channels is too big (%d). " - "Limiting this setting to 128.", synth->audio_channels); - synth->audio_channels = 128; - } - - if (synth->audio_groups < 1) { - FLUID_LOG(FLUID_WARN, "Requested number of audio groups is smaller than 1. " - "Changing this setting to 1."); - synth->audio_groups = 1; - } else if (synth->audio_groups > 128) { - FLUID_LOG(FLUID_WARN, "Requested number of audio groups is too big (%d). " - "Limiting this setting to 128.", synth->audio_groups); - synth->audio_groups = 128; - } - - if (synth->effects_channels != 2) { - FLUID_LOG(FLUID_WARN, "Invalid number of effects channels (%d)." - "Setting effects channels to 2.", synth->effects_channels); - synth->effects_channels = 2; - } - - - /* The number of buffers is determined by the higher number of nr - * groups / nr audio channels. If LADSPA is unused, they should be - * the same. */ - synth->nbuf = synth->audio_channels; - if (synth->audio_groups > synth->nbuf) { - synth->nbuf = synth->audio_groups; - } - -#ifdef LADSPA - /* Create and initialize the Fx unit.*/ - synth->LADSPA_FxUnit = new_fluid_LADSPA_FxUnit(synth); -#endif - - /* as soon as the synth is created it starts playing. */ - synth->state = FLUID_SYNTH_PLAYING; - synth->sfont = NULL; - synth->noteid = 0; - synth->ticks = 0; - synth->tuning = NULL; - - /* allocate and add the default sfont loader */ - loader = new_fluid_defsfloader(); - - if (loader == NULL) { - FLUID_LOG(FLUID_WARN, "Failed to create the default SoundFont loader"); - } else { - fluid_synth_add_sfloader(synth, loader); - } - - /* allocate all channel objects */ - synth->channel = FLUID_ARRAY(fluid_channel_t*, synth->midi_channels); - if (synth->channel == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - goto error_recovery; - } - for (i = 0; i < synth->midi_channels; i++) { - synth->channel[i] = new_fluid_channel(synth, i); - if (synth->channel[i] == NULL) { - goto error_recovery; - } - } - - /* allocate all synthesis processes */ - synth->nvoice = synth->polyphony; - synth->voice = FLUID_ARRAY(fluid_voice_t*, synth->nvoice); - if (synth->voice == NULL) { - goto error_recovery; - } - for (i = 0; i < synth->nvoice; i++) { - synth->voice[i] = new_fluid_voice(synth->sample_rate); - if (synth->voice[i] == NULL) { - goto error_recovery; - } - } - - /* Allocate the sample buffers */ - synth->left_buf = NULL; - synth->right_buf = NULL; - synth->fx_left_buf = NULL; - synth->fx_right_buf = NULL; - - /* Left and right audio buffers */ - - synth->left_buf = FLUID_ARRAY(fluid_real_t*, synth->nbuf); - synth->right_buf = FLUID_ARRAY(fluid_real_t*, synth->nbuf); - - if ((synth->left_buf == NULL) || (synth->right_buf == NULL)) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - goto error_recovery; - } - - FLUID_MEMSET(synth->left_buf, 0, synth->nbuf * sizeof(fluid_real_t*)); - FLUID_MEMSET(synth->right_buf, 0, synth->nbuf * sizeof(fluid_real_t*)); - - for (i = 0; i < synth->nbuf; i++) { - - synth->left_buf[i] = FLUID_ARRAY(fluid_real_t, FLUID_BUFSIZE); - synth->right_buf[i] = FLUID_ARRAY(fluid_real_t, FLUID_BUFSIZE); - - if ((synth->left_buf[i] == NULL) || (synth->right_buf[i] == NULL)) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - goto error_recovery; - } - } - - /* Effects audio buffers */ - - synth->fx_left_buf = FLUID_ARRAY(fluid_real_t*, synth->effects_channels); - synth->fx_right_buf = FLUID_ARRAY(fluid_real_t*, synth->effects_channels); - - if ((synth->fx_left_buf == NULL) || (synth->fx_right_buf == NULL)) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - goto error_recovery; - } - - FLUID_MEMSET(synth->fx_left_buf, 0, 2 * sizeof(fluid_real_t*)); - FLUID_MEMSET(synth->fx_right_buf, 0, 2 * sizeof(fluid_real_t*)); - - for (i = 0; i < synth->effects_channels; i++) { - synth->fx_left_buf[i] = FLUID_ARRAY(fluid_real_t, FLUID_BUFSIZE); - synth->fx_right_buf[i] = FLUID_ARRAY(fluid_real_t, FLUID_BUFSIZE); - - if ((synth->fx_left_buf[i] == NULL) || (synth->fx_right_buf[i] == NULL)) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - goto error_recovery; - } - } - - - synth->cur = FLUID_BUFSIZE; - synth->dither_index = 0; - - /* allocate the reverb module */ - synth->reverb = new_fluid_revmodel(); - if (synth->reverb == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - goto error_recovery; - } - - fluid_synth_set_reverb(synth, - FLUID_REVERB_DEFAULT_ROOMSIZE, - FLUID_REVERB_DEFAULT_DAMP, - FLUID_REVERB_DEFAULT_WIDTH, - FLUID_REVERB_DEFAULT_LEVEL); - - /* allocate the chorus module */ - synth->chorus = new_fluid_chorus(synth->sample_rate); - if (synth->chorus == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - goto error_recovery; - } - - /* FIXME */ - synth->start = fluid_curtime(); - - return synth; - - error_recovery: - delete_fluid_synth(synth); - return NULL; -} - -/* - * delete_fluid_synth - */ -int -delete_fluid_synth(fluid_synth_t* synth) -{ - int i, k; - fluid_list_t *list; - fluid_sfont_t* sfont; - fluid_bank_offset_t* bank_offset; - fluid_sfloader_t* loader; - - if (synth == NULL) { - return FLUID_OK; - } - - fluid_profiling_print(); - - synth->state = FLUID_SYNTH_STOPPED; - - /* turn off all voices, needed to unload SoundFont data */ - if (synth->voice != NULL) { - for (i = 0; i < synth->nvoice; i++) { - if (synth->voice[i] && fluid_voice_is_playing (synth->voice[i])) - fluid_voice_off (synth->voice[i]); - } - } - - /* delete all the SoundFonts */ - for (list = synth->sfont; list; list = fluid_list_next(list)) { - sfont = (fluid_sfont_t*) fluid_list_get(list); - delete_fluid_sfont(sfont); - } - - delete_fluid_list(synth->sfont); - - /* and the SoundFont offsets */ - for (list = synth->bank_offsets; list; list = fluid_list_next(list)) { - bank_offset = (fluid_bank_offset_t*) fluid_list_get(list); - FLUID_FREE(bank_offset); - } - - delete_fluid_list(synth->bank_offsets); - - - /* delete all the SoundFont loaders */ - - for (list = synth->loaders; list; list = fluid_list_next(list)) { - loader = (fluid_sfloader_t*) fluid_list_get(list); - fluid_sfloader_delete(loader); - } - - delete_fluid_list(synth->loaders); - - - if (synth->channel != NULL) { - for (i = 0; i < synth->midi_channels; i++) { - if (synth->channel[i] != NULL) { - delete_fluid_channel(synth->channel[i]); - } - } - FLUID_FREE(synth->channel); - } - - if (synth->voice != NULL) { - for (i = 0; i < synth->nvoice; i++) { - if (synth->voice[i] != NULL) { - delete_fluid_voice(synth->voice[i]); - } - } - FLUID_FREE(synth->voice); - } - - /* free all the sample buffers */ - if (synth->left_buf != NULL) { - for (i = 0; i < synth->nbuf; i++) { - if (synth->left_buf[i] != NULL) { - FLUID_FREE(synth->left_buf[i]); - } - } - FLUID_FREE(synth->left_buf); - } - - if (synth->right_buf != NULL) { - for (i = 0; i < synth->nbuf; i++) { - if (synth->right_buf[i] != NULL) { - FLUID_FREE(synth->right_buf[i]); - } - } - FLUID_FREE(synth->right_buf); - } - - if (synth->fx_left_buf != NULL) { - for (i = 0; i < 2; i++) { - if (synth->fx_left_buf[i] != NULL) { - FLUID_FREE(synth->fx_left_buf[i]); - } - } - FLUID_FREE(synth->fx_left_buf); - } - - if (synth->fx_right_buf != NULL) { - for (i = 0; i < 2; i++) { - if (synth->fx_right_buf[i] != NULL) { - FLUID_FREE(synth->fx_right_buf[i]); - } - } - FLUID_FREE(synth->fx_right_buf); - } - - /* release the reverb module */ - if (synth->reverb != NULL) { - delete_fluid_revmodel(synth->reverb); - } - - /* release the chorus module */ - if (synth->chorus != NULL) { - delete_fluid_chorus(synth->chorus); - } - - /* free the tunings, if any */ - if (synth->tuning != NULL) { - for (i = 0; i < 128; i++) { - if (synth->tuning[i] != NULL) { - for (k = 0; k < 128; k++) { - if (synth->tuning[i][k] != NULL) { - FLUID_FREE(synth->tuning[i][k]); - } - } - FLUID_FREE(synth->tuning[i]); - } - } - FLUID_FREE(synth->tuning); - } - -#ifdef LADSPA - /* Release the LADSPA Fx unit */ - fluid_LADSPA_shutdown(synth->LADSPA_FxUnit); - FLUID_FREE(synth->LADSPA_FxUnit); -#endif - - fluid_mutex_destroy(synth->busy); - - FLUID_FREE(synth); - - return FLUID_OK; -} - -/* - * fluid_synth_error - * - * The error messages are not thread-save, yet. They are still stored - * in a global message buffer (see fluid_sys.c). - * */ -char* -fluid_synth_error(fluid_synth_t* synth) -{ - return fluid_error(); -} - -/* - * fluid_synth_noteon - */ -int -fluid_synth_noteon(fluid_synth_t* synth, int chan, int key, int vel) -{ - fluid_channel_t* channel; - int r = FLUID_FAILED; - - /* check the ranges of the arguments */ - if ((chan < 0) || (chan >= synth->midi_channels)) { - FLUID_LOG(FLUID_WARN, "Channel out of range"); - return FLUID_FAILED; - } - - /* notes with velocity zero go to noteoff */ - if (vel == 0) { - return fluid_synth_noteoff(synth, chan, key); - } - - channel = synth->channel[chan]; - - /* make sure this channel has a preset */ - if (channel->preset == NULL) { - if (synth->verbose) { - FLUID_LOG(FLUID_INFO, "noteon\t%d\t%d\t%d\t%05d\t%.3f\t%.3f\t%.3f\t%d\t%s", - chan, key, vel, 0, - (float) synth->ticks / 44100.0f, - (fluid_curtime() - synth->start) / 1000.0f, - 0.0f, 0, "channel has no preset"); - } - return FLUID_FAILED; - } - - /* If there is another voice process on the same channel and key, - advance it to the release phase. */ - fluid_synth_release_voice_on_same_note(synth, chan, key); - - return fluid_synth_start(synth, synth->noteid++, channel->preset, 0, chan, key, vel); -} - -/* - * fluid_synth_noteoff - */ -int -fluid_synth_noteoff(fluid_synth_t* synth, int chan, int key) -{ - int i; - fluid_voice_t* voice; - int status = FLUID_FAILED; -/* fluid_mutex_lock(synth->busy); /\* Don't interfere with the audio thread *\/ */ -/* fluid_mutex_unlock(synth->busy); */ - - for (i = 0; i < synth->polyphony; i++) { - voice = synth->voice[i]; - if (_ON(voice) && (voice->chan == chan) && (voice->key == key)) { - if (synth->verbose) { - int used_voices = 0; - int k; - for (k = 0; k < synth->polyphony; k++) { - if (!_AVAILABLE(synth->voice[k])) { - used_voices++; - } - } - FLUID_LOG(FLUID_INFO, "noteoff\t%d\t%d\t%d\t%05d\t%.3f\t%.3f\t%.3f\t%d", - voice->chan, voice->key, 0, voice->id, - (float) (voice->start_time + voice->ticks) / 44100.0f, - (fluid_curtime() - synth->start) / 1000.0f, - (float) voice->ticks / 44100.0f, - used_voices); - } /* if verbose */ - fluid_voice_noteoff(voice); - status = FLUID_OK; - } /* if voice on */ - } /* for all voices */ - return status; -} - -/* - * fluid_synth_damp_voices - */ -int -fluid_synth_damp_voices(fluid_synth_t* synth, int chan) -{ - int i; - fluid_voice_t* voice; - -/* fluid_mutex_lock(synth->busy); /\* Don't interfere with the audio thread *\/ */ -/* fluid_mutex_unlock(synth->busy); */ - - for (i = 0; i < synth->polyphony; i++) { - voice = synth->voice[i]; - if ((voice->chan == chan) && _SUSTAINED(voice)) { -/* printf("turned off sustained note: chan=%d, key=%d, vel=%d\n", voice->chan, voice->key, voice->vel); */ - fluid_voice_noteoff(voice); - } - } - - return FLUID_OK; -} - -/* - * fluid_synth_cc - */ -int -fluid_synth_cc(fluid_synth_t* synth, int chan, int num, int val) -{ -/* fluid_mutex_lock(synth->busy); /\* Don't interfere with the audio thread *\/ */ -/* fluid_mutex_unlock(synth->busy); */ - - /* check the ranges of the arguments */ - if ((chan < 0) || (chan >= synth->midi_channels)) { - FLUID_LOG(FLUID_WARN, "Channel out of range"); - return FLUID_FAILED; - } - if ((num < 0) || (num >= 128)) { - FLUID_LOG(FLUID_WARN, "Ctrl out of range"); - return FLUID_FAILED; - } - if ((val < 0) || (val >= 128)) { - FLUID_LOG(FLUID_WARN, "Value out of range"); - return FLUID_FAILED; - } - - if (synth->verbose) { - FLUID_LOG(FLUID_INFO, "cc\t%d\t%d\t%d", chan, num, val); - } - - /* set the controller value in the channel */ - fluid_channel_cc(synth->channel[chan], num, val); - - return FLUID_OK; -} - -/* - * fluid_synth_cc - */ -int -fluid_synth_get_cc(fluid_synth_t* synth, int chan, int num, int* pval) -{ - /* check the ranges of the arguments */ - if ((chan < 0) || (chan >= synth->midi_channels)) { - FLUID_LOG(FLUID_WARN, "Channel out of range"); - return FLUID_FAILED; - } - if ((num < 0) || (num >= 128)) { - FLUID_LOG(FLUID_WARN, "Ctrl out of range"); - return FLUID_FAILED; - } - - *pval = synth->channel[chan]->cc[num]; - return FLUID_OK; -} - -/* - * fluid_synth_all_notes_off - * - * put all notes on this channel into released state. - */ -int -fluid_synth_all_notes_off(fluid_synth_t* synth, int chan) -{ - int i; - fluid_voice_t* voice; - - for (i = 0; i < synth->polyphony; i++) { - voice = synth->voice[i]; - if (_PLAYING(voice) && (voice->chan == chan)) { - fluid_voice_noteoff(voice); - } - } - return FLUID_OK; -} - -/* - * fluid_synth_all_sounds_off - * - * immediately stop all notes on this channel. - */ -int -fluid_synth_all_sounds_off(fluid_synth_t* synth, int chan) -{ - int i; - fluid_voice_t* voice; - - for (i = 0; i < synth->polyphony; i++) { - voice = synth->voice[i]; - if (_PLAYING(voice) && (voice->chan == chan)) { - fluid_voice_off(voice); - } - } - return FLUID_OK; -} - -/* - * fluid_synth_system_reset - * - * Purpose: - * Respond to the MIDI command 'system reset' (0xFF, big red 'panic' button) - */ -int -fluid_synth_system_reset(fluid_synth_t* synth) -{ - int i; - fluid_voice_t* voice; - - for (i = 0; i < synth->polyphony; i++) { - voice = synth->voice[i]; - if (_PLAYING(voice)) { - fluid_voice_off(voice); - } - } - - for (i = 0; i < synth->midi_channels; i++) { - fluid_channel_reset(synth->channel[i]); - } - - fluid_chorus_reset(synth->chorus); - fluid_revmodel_reset(synth->reverb); - - return FLUID_OK; -} - -/* - * fluid_synth_modulate_voices - * - * tell all synthesis processes on this channel to update their - * synthesis parameters after a control change. - */ -int -fluid_synth_modulate_voices(fluid_synth_t* synth, int chan, int is_cc, int ctrl) -{ - int i; - fluid_voice_t* voice; - -/* fluid_mutex_lock(synth->busy); /\* Don't interfere with the audio thread *\/ */ -/* fluid_mutex_unlock(synth->busy); */ - - for (i = 0; i < synth->polyphony; i++) { - voice = synth->voice[i]; - if (voice->chan == chan) { - fluid_voice_modulate(voice, is_cc, ctrl); - } - } - return FLUID_OK; -} - -/* - * fluid_synth_modulate_voices_all - * - * Tell all synthesis processes on this channel to update their - * synthesis parameters after an all control off message (i.e. all - * controller have been reset to their default value). - */ -int -fluid_synth_modulate_voices_all(fluid_synth_t* synth, int chan) -{ - int i; - fluid_voice_t* voice; - -/* fluid_mutex_lock(synth->busy); /\* Don't interfere with the audio thread *\/ */ -/* fluid_mutex_unlock(synth->busy); */ - - for (i = 0; i < synth->polyphony; i++) { - voice = synth->voice[i]; - if (voice->chan == chan) { - fluid_voice_modulate_all(voice); - } - } - return FLUID_OK; -} - -/** - * Set the MIDI channel pressure controller value. - * @param synth FluidSynth instance - * @param chan MIDI channel number - * @param val MIDI channel pressure value (7 bit, 0-127) - * @return FLUID_OK on success - * - * Assign to the MIDI channel pressure controller value on a specific MIDI channel - * in real time. - */ -int -fluid_synth_channel_pressure(fluid_synth_t* synth, int chan, int val) -{ - -/* fluid_mutex_lock(synth->busy); /\* Don't interfere with the audio thread *\/ */ -/* fluid_mutex_unlock(synth->busy); */ - - /* check the ranges of the arguments */ - if ((chan < 0) || (chan >= synth->midi_channels)) { - FLUID_LOG(FLUID_WARN, "Channel out of range"); - return FLUID_FAILED; - } - - if (synth->verbose) { - FLUID_LOG(FLUID_INFO, "channelpressure\t%d\t%d", chan, val); - } - - /* set the channel pressure value in the channel */ - fluid_channel_pressure(synth->channel[chan], val); - - return FLUID_OK; -} - -/** - * Set the MIDI pitch bend controller value. - * @param synth FluidSynth instance - * @param chan MIDI channel number - * @param val MIDI pitch bend value (14 bit, 0-16383 with 8192 being center) - * @return FLUID_OK on success - * - * Assign to the MIDI pitch bend controller value on a specific MIDI channel - * in real time. - */ -int -fluid_synth_pitch_bend(fluid_synth_t* synth, int chan, int val) -{ - -/* fluid_mutex_lock(synth->busy); /\* Don't interfere with the audio thread *\/ */ -/* fluid_mutex_unlock(synth->busy); */ - - /* check the ranges of the arguments */ - if ((chan < 0) || (chan >= synth->midi_channels)) { - FLUID_LOG(FLUID_WARN, "Channel out of range"); - return FLUID_FAILED; - } - - if (synth->verbose) { - FLUID_LOG(FLUID_INFO, "pitchb\t%d\t%d", chan, val); - } - - /* set the pitch-bend value in the channel */ - fluid_channel_pitch_bend(synth->channel[chan], val); - - return FLUID_OK; -} - -/* - * fluid_synth_pitch_bend - */ -int -fluid_synth_get_pitch_bend(fluid_synth_t* synth, int chan, int* ppitch_bend) -{ - /* check the ranges of the arguments */ - if ((chan < 0) || (chan >= synth->midi_channels)) { - FLUID_LOG(FLUID_WARN, "Channel out of range"); - return FLUID_FAILED; - } - - *ppitch_bend = synth->channel[chan]->pitch_bend; - return FLUID_OK; -} - -/* - * Fluid_synth_pitch_wheel_sens - */ -int -fluid_synth_pitch_wheel_sens(fluid_synth_t* synth, int chan, int val) -{ - - /* check the ranges of the arguments */ - if ((chan < 0) || (chan >= synth->midi_channels)) { - FLUID_LOG(FLUID_WARN, "Channel out of range"); - return FLUID_FAILED; - } - - if (synth->verbose) { - FLUID_LOG(FLUID_INFO, "pitchsens\t%d\t%d", chan, val); - } - - /* set the pitch-bend value in the channel */ - fluid_channel_pitch_wheel_sens(synth->channel[chan], val); - - return FLUID_OK; -} - -/* - * fluid_synth_get_pitch_wheel_sens - * - * Note : this function was added after version 1.0 API freeze. - * So its API is not in the synth.h file. It should be added in some later - * version of fluidsynth. Maybe v2.0 ? -- Antoine Schmitt May 2003 - */ - -int -fluid_synth_get_pitch_wheel_sens(fluid_synth_t* synth, int chan, int* pval) -{ - - // check the ranges of the arguments - if ((chan < 0) || (chan >= synth->midi_channels)) { - FLUID_LOG(FLUID_WARN, "Channel out of range"); - return FLUID_FAILED; - } - - // get the pitch-bend value in the channel - *pval = synth->channel[chan]->pitch_wheel_sensitivity; - - return FLUID_OK; -} - -/* - * fluid_synth_get_preset - */ -fluid_preset_t* -fluid_synth_get_preset(fluid_synth_t* synth, unsigned int sfontnum, - unsigned int banknum, unsigned int prognum) -{ - fluid_preset_t* preset = NULL; - fluid_sfont_t* sfont = NULL; - fluid_list_t* list = synth->sfont; - int offset; - - sfont = fluid_synth_get_sfont_by_id(synth, sfontnum); - - if (sfont != NULL) { - offset = fluid_synth_get_bank_offset(synth, sfontnum); - preset = fluid_sfont_get_preset(sfont, banknum - offset, prognum); - if (preset != NULL) { - return preset; - } - } - return NULL; -} - -/* - * fluid_synth_get_preset2 - */ -fluid_preset_t* -fluid_synth_get_preset2(fluid_synth_t* synth, char* sfont_name, - unsigned int banknum, unsigned int prognum) -{ - fluid_preset_t* preset = NULL; - fluid_sfont_t* sfont = NULL; - int offset; - - sfont = fluid_synth_get_sfont_by_name(synth, sfont_name); - - if (sfont != NULL) { - offset = fluid_synth_get_bank_offset(synth, fluid_sfont_get_id(sfont)); - preset = fluid_sfont_get_preset(sfont, banknum - offset, prognum); - if (preset != NULL) { - return preset; - } - } - return NULL; -} - -fluid_preset_t* fluid_synth_find_preset(fluid_synth_t* synth, - unsigned int banknum, - unsigned int prognum) -{ - fluid_preset_t* preset = NULL; - fluid_sfont_t* sfont = NULL; - fluid_list_t* list = synth->sfont; - int offset; - - while (list) { - - sfont = (fluid_sfont_t*) fluid_list_get(list); - offset = fluid_synth_get_bank_offset(synth, fluid_sfont_get_id(sfont)); - preset = fluid_sfont_get_preset(sfont, banknum - offset, prognum); - - if (preset != NULL) { - preset->sfont = sfont; /* FIXME */ - return preset; - } - - list = fluid_list_next(list); - - } - return NULL; -} - - -/* - * fluid_synth_program_change - */ -int -fluid_synth_program_change(fluid_synth_t* synth, int chan, int prognum) -{ - fluid_preset_t* preset = NULL; - fluid_channel_t* channel; - unsigned int banknum; - unsigned int sfont_id; - int subst_bank, subst_prog; - - if ((prognum < 0) || (prognum >= FLUID_NUM_PROGRAMS) || - (chan < 0) || (chan >= synth->midi_channels)) - { - FLUID_LOG(FLUID_ERR, "Index out of range (chan=%d, prog=%d)", chan, prognum); - return FLUID_FAILED; - } - - channel = synth->channel[chan]; - banknum = fluid_channel_get_banknum(channel); - - /* inform the channel of the new program number */ - fluid_channel_set_prognum(channel, prognum); - - if (synth->verbose) - FLUID_LOG(FLUID_INFO, "prog\t%d\t%d\t%d", chan, banknum, prognum); - - /* Special handling of channel 10 (or 9 counting from 0). channel - * 10 is the percussion channel. - * - * FIXME - Shouldn't hard code bank selection for channel 10. I think this - * is a hack for MIDI files that do bank changes in GM mode. Proper way to - * handle this would probably be to ignore bank changes when in GM mode. - */ - if (channel->channum == 9) - preset = fluid_synth_find_preset(synth, DRUM_INST_BANK, prognum); - else preset = fluid_synth_find_preset(synth, banknum, prognum); - - /* Fallback to another preset if not found */ - if (!preset) - { - subst_bank = banknum; - subst_prog = prognum; - - /* Melodic instrument? */ - if (channel->channum != 9 && banknum != DRUM_INST_BANK) - { - subst_bank = 0; - - /* Fallback first to bank 0:prognum */ - preset = fluid_synth_find_preset(synth, 0, prognum); - - /* Fallback to first preset in bank 0 */ - if (!preset && prognum != 0) - { - preset = fluid_synth_find_preset(synth, 0, 0); - subst_prog = 0; - } - } - else /* Percussion: Fallback to preset 0 in percussion bank */ - { - preset = fluid_synth_find_preset(synth, DRUM_INST_BANK, 0); - subst_prog = 0; - } - - if (preset) - FLUID_LOG(FLUID_WARN, "Instrument not found on channel %d [bank=%d prog=%d], substituted [bank=%d prog=%d]", - chan, banknum, prognum, subst_bank, subst_prog); - } - - sfont_id = preset? fluid_sfont_get_id(preset->sfont) : 0; - fluid_channel_set_sfontnum(channel, sfont_id); - fluid_channel_set_preset(channel, preset); - - return FLUID_OK; -} - -/* - * fluid_synth_bank_select - */ -int fluid_synth_bank_select(fluid_synth_t* synth, int chan, unsigned int bank) -{ - if ((chan >= 0) && (chan < synth->midi_channels)) { - fluid_channel_set_banknum(synth->channel[chan], bank); - return FLUID_OK; - } - return FLUID_FAILED; -} - - -/* - * fluid_synth_sfont_select - */ -int fluid_synth_sfont_select(fluid_synth_t* synth, int chan, unsigned int sfont_id) -{ - if ((chan >= 0) && (chan < synth->midi_channels)) { - fluid_channel_set_sfontnum(synth->channel[chan], sfont_id); - return FLUID_OK; - } - return FLUID_FAILED; -} - -/* - * fluid_synth_get_program - */ -int -fluid_synth_get_program(fluid_synth_t* synth, int chan, - unsigned int* sfont_id, unsigned int* bank_num, unsigned int* preset_num) -{ - fluid_channel_t* channel; - if ((chan >= 0) && (chan < synth->midi_channels)) { - channel = synth->channel[chan]; - *sfont_id = fluid_channel_get_sfontnum(channel); - *bank_num = fluid_channel_get_banknum(channel); - *preset_num = fluid_channel_get_prognum(channel); - return FLUID_OK; - } - return FLUID_FAILED; -} - -/* - * fluid_synth_program_select - */ -int fluid_synth_program_select(fluid_synth_t* synth, - int chan, - unsigned int sfont_id, - unsigned int bank_num, - unsigned int preset_num) -{ - fluid_preset_t* preset = NULL; - fluid_channel_t* channel; - - if ((chan < 0) || (chan >= synth->midi_channels)) { - FLUID_LOG(FLUID_ERR, "Channel number out of range (chan=%d)", chan); - return FLUID_FAILED; - } - channel = synth->channel[chan]; - - preset = fluid_synth_get_preset(synth, sfont_id, bank_num, preset_num); - if (preset == NULL) { - FLUID_LOG(FLUID_ERR, - "There is no preset with bank number %d and preset number %d in SoundFont %d", - bank_num, preset_num, sfont_id); - return FLUID_FAILED; - } - - /* inform the channel of the new bank and program number */ - fluid_channel_set_sfontnum(channel, sfont_id); - fluid_channel_set_banknum(channel, bank_num); - fluid_channel_set_prognum(channel, preset_num); - - fluid_channel_set_preset(channel, preset); - - return FLUID_OK; -} - -/* - * fluid_synth_program_select2 - */ -int fluid_synth_program_select2(fluid_synth_t* synth, - int chan, - char* sfont_name, - unsigned int bank_num, - unsigned int preset_num) -{ - fluid_preset_t* preset = NULL; - fluid_channel_t* channel; - fluid_sfont_t* sfont = NULL; - int offset; - - if ((chan < 0) || (chan >= synth->midi_channels)) { - FLUID_LOG(FLUID_ERR, "Channel number out of range (chan=%d)", chan); - return FLUID_FAILED; - } - channel = synth->channel[chan]; - - sfont = fluid_synth_get_sfont_by_name(synth, sfont_name); - if (sfont == NULL) { - FLUID_LOG(FLUID_ERR, "Could not find SoundFont %s", sfont_name); - return FLUID_FAILED; - } - - offset = fluid_synth_get_bank_offset(synth, fluid_sfont_get_id(sfont)); - preset = fluid_sfont_get_preset(sfont, bank_num - offset, preset_num); - if (preset == NULL) { - FLUID_LOG(FLUID_ERR, - "There is no preset with bank number %d and preset number %d in SoundFont %s", - bank_num, preset_num, sfont_name); - return FLUID_FAILED; - } - - /* inform the channel of the new bank and program number */ - fluid_channel_set_sfontnum(channel, fluid_sfont_get_id(sfont)); - fluid_channel_set_banknum(channel, bank_num); - fluid_channel_set_prognum(channel, preset_num); - - fluid_channel_set_preset(channel, preset); - - return FLUID_OK; -} - -/* - * fluid_synth_update_presets - */ -void fluid_synth_update_presets(fluid_synth_t* synth) -{ - int chan; - fluid_channel_t* channel; - - for (chan = 0; chan < synth->midi_channels; chan++) { - channel = synth->channel[chan]; - fluid_channel_set_preset(channel, - fluid_synth_get_preset(synth, - fluid_channel_get_sfontnum(channel), - fluid_channel_get_banknum(channel), - fluid_channel_get_prognum(channel))); - } -} - - -/* - * fluid_synth_update_gain - */ -int fluid_synth_update_gain(fluid_synth_t* synth, char* name, double value) -{ - fluid_synth_set_gain(synth, (float) value); - return 0; -} - -/* - * fluid_synth_set_gain - */ -void fluid_synth_set_gain(fluid_synth_t* synth, float gain) -{ - int i; - - fluid_clip(gain, 0.0f, 10.0f); - synth->gain = gain; - - for (i = 0; i < synth->polyphony; i++) { - fluid_voice_t* voice = synth->voice[i]; - if (_PLAYING(voice)) { - fluid_voice_set_gain(voice, gain); - } - } -} - -/* - * fluid_synth_get_gain - */ -float fluid_synth_get_gain(fluid_synth_t* synth) -{ - return synth->gain; -} - -/* - * fluid_synth_update_polyphony - */ -int fluid_synth_update_polyphony(fluid_synth_t* synth, char* name, int value) -{ - fluid_synth_set_polyphony(synth, value); - return 0; -} - -/* - * fluid_synth_set_polyphony - */ -int fluid_synth_set_polyphony(fluid_synth_t* synth, int polyphony) -{ - int i; - - if (polyphony < 1 || polyphony > synth->nvoice) { - return FLUID_FAILED; - } - - /* turn off any voices above the new limit */ - for (i = polyphony; i < synth->nvoice; i++) { - fluid_voice_t* voice = synth->voice[i]; - if (_PLAYING(voice)) { - fluid_voice_off(voice); - } - } - - synth->polyphony = polyphony; - - return FLUID_OK; -} - -/* - * fluid_synth_get_polyphony - */ -int fluid_synth_get_polyphony(fluid_synth_t* synth) -{ - return synth->polyphony; -} - -/* - * fluid_synth_get_internal_buffer_size - */ -int fluid_synth_get_internal_bufsize(fluid_synth_t* synth) -{ - return FLUID_BUFSIZE; -} - -/* - * fluid_synth_program_reset - * - * Resend a bank select and a program change for every channel. This - * function is called mainly after a SoundFont has been loaded, - * unloaded or reloaded. */ -int -fluid_synth_program_reset(fluid_synth_t* synth) -{ - int i; - /* try to set the correct presets */ - for (i = 0; i < synth->midi_channels; i++){ - fluid_synth_program_change(synth, i, fluid_channel_get_prognum(synth->channel[i])); - } - return FLUID_OK; -} - -/* - * fluid_synth_set_reverb_preset - */ -int fluid_synth_set_reverb_preset(fluid_synth_t* synth, int num) -{ - int i = 0; - while (revmodel_preset[i].name != NULL) { - if (i == num) { - fluid_revmodel_setroomsize(synth->reverb, revmodel_preset[i].roomsize); - fluid_revmodel_setdamp(synth->reverb, revmodel_preset[i].damp); - fluid_revmodel_setwidth(synth->reverb, revmodel_preset[i].width); - fluid_revmodel_setlevel(synth->reverb, revmodel_preset[i].level); - return FLUID_OK; - } - i++; - } - return FLUID_FAILED; -} - -/* - * fluid_synth_set_reverb - */ -void fluid_synth_set_reverb(fluid_synth_t* synth, double roomsize, double damping, - double width, double level) -{ -/* fluid_mutex_lock(synth->busy); /\* Don't interfere with the audio thread *\/ */ -/* fluid_mutex_unlock(synth->busy); */ - - fluid_revmodel_setroomsize(synth->reverb, roomsize); - fluid_revmodel_setdamp(synth->reverb, damping); - fluid_revmodel_setwidth(synth->reverb, width); - fluid_revmodel_setlevel(synth->reverb, level); -} - -/* - * fluid_synth_set_chorus - */ -void fluid_synth_set_chorus(fluid_synth_t* synth, int nr, double level, - double speed, double depth_ms, int type) -{ -/* fluid_mutex_lock(synth->busy); /\* Don't interfere with the audio thread *\/ */ -/* fluid_mutex_unlock(synth->busy); */ - - fluid_chorus_set_nr(synth->chorus, nr); - fluid_chorus_set_level(synth->chorus, (fluid_real_t)level); - fluid_chorus_set_speed_Hz(synth->chorus, (fluid_real_t)speed); - fluid_chorus_set_depth_ms(synth->chorus, (fluid_real_t)depth_ms); - fluid_chorus_set_type(synth->chorus, type); - fluid_chorus_update(synth->chorus); -} - -/****************************************************** - -#define COMPRESS 1 -#define COMPRESS_X1 4.0 -#define COMPRESS_Y1 0.6 -#define COMPRESS_X2 10.0 -#define COMPRESS_Y2 1.0 - - len2 = 2 * len; - alpha1 = COMPRESS_Y1 / COMPRESS_X1; - alpha2 = (COMPRESS_Y2 - COMPRESS_Y1) / (COMPRESS_X2 - COMPRESS_X1); - if (COMPRESS_X1 == COMPRESS_Y1) { - for (j = 0; j < len2; j++) { - if (buf[j] > COMPRESS_X1) { - if (buf[j] > COMPRESS_X2) { - buf[j] = COMPRESS_Y2; - } else { - buf[j] = COMPRESS_Y1 + alpha2 * (buf[j] - COMPRESS_X1); - } - } else if (buf[j] < -COMPRESS_X1) { - if (buf[j] < -COMPRESS_X2) { - buf[j] = -COMPRESS_Y2; - } else { - buf[j] = -COMPRESS_Y1 + alpha2 * (buf[j] + COMPRESS_X1); - } - } - } - } else { - for (j = 0; j < len2; j++) { - if ((buf[j] >= -COMPRESS_X1) && (buf[j] <= COMPRESS_X1)) { - buf[j] *= alpha1; - } else if (buf[j] > COMPRESS_X1) { - if (buf[j] > COMPRESS_X2) { - buf[j] = COMPRESS_Y2; - } else { - buf[j] = COMPRESS_Y1 + alpha2 * (buf[j] - COMPRESS_X1); - } - } else { - if (buf[j] < -COMPRESS_X2) { - buf[j] = -COMPRESS_Y2; - } else { - buf[j] = -COMPRESS_Y1 + alpha2 * (buf[j] + COMPRESS_X1); - } - } - } - } - -***************************************************/ - -/* - * fluid_synth_nwrite_float - */ -int -fluid_synth_nwrite_float(fluid_synth_t* synth, int len, - float** left, float** right, - float** fx_left, float** fx_right) -{ - fluid_real_t** left_in = synth->left_buf; - fluid_real_t** right_in = synth->right_buf; - double time = fluid_utime(); - int i, num, available, count, bytes; - - /* make sure we're playing */ - if (synth->state != FLUID_SYNTH_PLAYING) { - return 0; - } - - /* First, take what's still available in the buffer */ - count = 0; - num = synth->cur; - if (synth->cur < FLUID_BUFSIZE) { - available = FLUID_BUFSIZE - synth->cur; - - num = (available > len)? len : available; - bytes = num * sizeof(float); - - for (i = 0; i < synth->audio_channels; i++) { - FLUID_MEMCPY(left[i], left_in[i] + synth->cur, bytes); - FLUID_MEMCPY(right[i], right_in[i] + synth->cur, bytes); - } - count += num; - num += synth->cur; /* if we're now done, num becomes the new synth->cur below */ - } - - /* Then, run one_block() and copy till we have 'len' samples */ - while (count < len) { - fluid_synth_one_block(synth, 1); - - num = (FLUID_BUFSIZE > len - count)? len - count : FLUID_BUFSIZE; - bytes = num * sizeof(float); - - for (i = 0; i < synth->audio_channels; i++) { - FLUID_MEMCPY(left[i] + count, left_in[i], bytes); - FLUID_MEMCPY(right[i] + count, right_in[i], bytes); - } - - count += num; - } - - synth->cur = num; - - time = fluid_utime() - time; - synth->cpu_load = 0.5 * (synth->cpu_load + - time * synth->sample_rate / len / 10000.0); - -/* printf("CPU: %.2f\n", synth->cpu_load); */ - - return 0; -} - - -int fluid_synth_process(fluid_synth_t* synth, int len, - int nin, float** in, - int nout, float** out) -{ - if (nout==2) { - return fluid_synth_write_float(synth, len, out[0], 0, 1, out[1], 0, 1); - } - else { - float **left, **right; - int i; - left = FLUID_ARRAY(float*, nout/2); - right = FLUID_ARRAY(float*, nout/2); - for(i=0; ileft_buf[0]; - fluid_real_t* right_in = synth->right_buf[0]; - double time = fluid_utime(); - - /* make sure we're playing */ - if (synth->state != FLUID_SYNTH_PLAYING) { - return 0; - } - - l = synth->cur; - - for (i = 0, j = loff, k = roff; i < len; i++, l++, j += lincr, k += rincr) { - /* fill up the buffers as needed */ - if (l == FLUID_BUFSIZE) { - fluid_synth_one_block(synth, 0); - l = 0; - } - - left_out[j] = (float) left_in[l]; - right_out[k] = (float) right_in[l]; - } - - synth->cur = l; - - time = fluid_utime() - time; - synth->cpu_load = 0.5 * (synth->cpu_load + - time * synth->sample_rate / len / 10000.0); - -/* printf("CPU: %.2f\n", synth->cpu_load); */ - - return 0; -} - -#define DITHER_SIZE 48000 -#define DITHER_CHANNELS 2 - -static float rand_table[DITHER_CHANNELS][DITHER_SIZE]; - -static void init_dither(void) -{ - float d, dp; - int c, i; - - for (c = 0; c < DITHER_CHANNELS; c++) { - dp = 0; - for (i = 0; i < DITHER_SIZE-1; i++) { - d = rand() / (float)RAND_MAX - 0.5f; - rand_table[c][i] = d - dp; - dp = d; - } - rand_table[c][DITHER_SIZE-1] = 0 - dp; - } -} - -/* A portable replacement for roundf(), seems it may actually be faster too! */ -static inline int -roundi (float x) -{ - if (x >= 0.0f) - return (int)(x+0.5f); - else - return (int)(x-0.5f); -} - -/* - * fluid_synth_write_s16 - */ -int -fluid_synth_write_s16(fluid_synth_t* synth, int len, - void* lout, int loff, int lincr, - void* rout, int roff, int rincr) -{ - int i, j, k, cur; - signed short* left_out = (signed short*) lout; - signed short* right_out = (signed short*) rout; - fluid_real_t* left_in = synth->left_buf[0]; - fluid_real_t* right_in = synth->right_buf[0]; - double prof_ref = fluid_profile_ref(); - fluid_real_t left_sample; - fluid_real_t right_sample; - double time = fluid_utime(); - int di = synth->dither_index; - double prof_ref_on_block; - - /* make sure we're playing */ - if (synth->state != FLUID_SYNTH_PLAYING) { - return 0; - } - - cur = synth->cur; - - for (i = 0, j = loff, k = roff; i < len; i++, cur++, j += lincr, k += rincr) { - - /* fill up the buffers as needed */ - if (cur == FLUID_BUFSIZE) { - prof_ref_on_block = fluid_profile_ref(); - - fluid_synth_one_block(synth, 0); - cur = 0; - - fluid_profile(FLUID_PROF_ONE_BLOCK, prof_ref_on_block); - } - - left_sample = roundi (left_in[cur] * 32766.0f + rand_table[0][di]); - right_sample = roundi (right_in[cur] * 32766.0f + rand_table[1][di]); - - di++; - if (di >= DITHER_SIZE) di = 0; - - /* digital clipping */ - if (left_sample > 32767.0f) left_sample = 32767.0f; - if (left_sample < -32768.0f) left_sample = -32768.0f; - if (right_sample > 32767.0f) right_sample = 32767.0f; - if (right_sample < -32768.0f) right_sample = -32768.0f; - - left_out[j] = (signed short) left_sample; - right_out[k] = (signed short) right_sample; - } - - synth->cur = cur; - synth->dither_index = di; /* keep dither buffer continous */ - - fluid_profile(FLUID_PROF_WRITE_S16, prof_ref); - - - time = fluid_utime() - time; - synth->cpu_load = 0.5 * (synth->cpu_load + - time * synth->sample_rate / len / 10000.0); - -/* printf("CPU: %.2f\n", synth->cpu_load); */ - - return 0; -} - -/* - * fluid_synth_dither_s16 - * Converts stereo floating point sample data to signed 16 bit data with - * dithering. 'dither_index' parameter is a caller supplied pointer to an - * integer which should be initialized to 0 before the first call and passed - * unmodified to additional calls which are part of the same synthesis output. - * Only used internally currently. - */ -void -fluid_synth_dither_s16(int *dither_index, int len, float* lin, float* rin, - void* lout, int loff, int lincr, - void* rout, int roff, int rincr) -{ - int i, j, k; - signed short* left_out = (signed short*) lout; - signed short* right_out = (signed short*) rout; - double prof_ref = fluid_profile_ref(); - fluid_real_t left_sample; - fluid_real_t right_sample; - int di = *dither_index; - - for (i = 0, j = loff, k = roff; i < len; i++, j += lincr, k += rincr) { - - left_sample = roundi (lin[i] * 32766.0f + rand_table[0][di]); - right_sample = roundi (rin[i] * 32766.0f + rand_table[1][di]); - - di++; - if (di >= DITHER_SIZE) di = 0; - - /* digital clipping */ - if (left_sample > 32767.0f) left_sample = 32767.0f; - if (left_sample < -32768.0f) left_sample = -32768.0f; - if (right_sample > 32767.0f) right_sample = 32767.0f; - if (right_sample < -32768.0f) right_sample = -32768.0f; - - left_out[j] = (signed short) left_sample; - right_out[k] = (signed short) right_sample; - } - - *dither_index = di; /* keep dither buffer continous */ - - fluid_profile(FLUID_PROF_WRITE_S16, prof_ref); -} - -/* - * fluid_synth_one_block - */ -int -fluid_synth_one_block(fluid_synth_t* synth, int do_not_mix_fx_to_out) -{ - int i, auchan; - fluid_voice_t* voice; - fluid_real_t* left_buf; - fluid_real_t* right_buf; - fluid_real_t* reverb_buf; - fluid_real_t* chorus_buf; - int byte_size = FLUID_BUFSIZE * sizeof(fluid_real_t); - double prof_ref = fluid_profile_ref(); - -/* fluid_mutex_lock(synth->busy); /\* Here comes the audio thread. Lock the synth. *\/ */ - - fluid_check_fpe("??? Just starting up ???"); - - /* clean the audio buffers */ - for (i = 0; i < synth->nbuf; i++) { - FLUID_MEMSET(synth->left_buf[i], 0, byte_size); - FLUID_MEMSET(synth->right_buf[i], 0, byte_size); - } - - for (i = 0; i < synth->effects_channels; i++) { - FLUID_MEMSET(synth->fx_left_buf[i], 0, byte_size); - FLUID_MEMSET(synth->fx_right_buf[i], 0, byte_size); - } - - /* Set up the reverb / chorus buffers only, when the effect is - * enabled on synth level. Nonexisting buffers are detected in the - * DSP loop. Not sending the reverb / chorus signal saves some time - * in that case. */ - reverb_buf = synth->with_reverb ? synth->fx_left_buf[0] : NULL; - chorus_buf = synth->with_chorus ? synth->fx_left_buf[1] : NULL; - - fluid_profile(FLUID_PROF_ONE_BLOCK_CLEAR, prof_ref); - - /* call all playing synthesis processes */ - for (i = 0; i < synth->polyphony; i++) { - voice = synth->voice[i]; - - if (_PLAYING(voice)) { - double prof_ref_voice = fluid_profile_ref(); - - /* The output associated with a MIDI channel is wrapped around - * using the number of audio groups as modulo divider. This is - * typically the number of output channels on the 'sound card', - * as long as the LADSPA Fx unit is not used. In case of LADSPA - * unit, think of it as subgroups on a mixer. - * - * For example: Assume that the number of groups is set to 2. - * Then MIDI channel 1, 3, 5, 7 etc. go to output 1, channels 2, - * 4, 6, 8 etc to output 2. Or assume 3 groups: Then MIDI - * channels 1, 4, 7, 10 etc go to output 1; 2, 5, 8, 11 etc to - * output 2, 3, 6, 9, 12 etc to output 3. - */ - auchan = fluid_channel_get_num(fluid_voice_get_channel(voice)); - auchan %= synth->audio_groups; - left_buf = synth->left_buf[auchan]; - right_buf = synth->right_buf[auchan]; - - fluid_voice_write(voice, left_buf, right_buf, reverb_buf, chorus_buf); - - fluid_profile(FLUID_PROF_ONE_BLOCK_VOICE, prof_ref_voice); - } - } - - fluid_check_fpe("Synthesis processes"); - - fluid_profile(FLUID_PROF_ONE_BLOCK_VOICES, prof_ref); - - /* if multi channel output, don't mix the output of the chorus and - reverb in the final output. The effects outputs are send - separately. */ - - if (do_not_mix_fx_to_out) { - - /* send to reverb */ - if (reverb_buf) { - fluid_revmodel_processreplace(synth->reverb, reverb_buf, - synth->fx_left_buf[0], synth->fx_right_buf[0]); - fluid_check_fpe("Reverb"); - } - - fluid_profile(FLUID_PROF_ONE_BLOCK_REVERB, prof_ref); - - /* send to chorus */ - if (chorus_buf) { - fluid_chorus_processreplace(synth->chorus, chorus_buf, - synth->fx_left_buf[1], synth->fx_right_buf[1]); - fluid_check_fpe("Chorus"); - } - - } else { - - /* send to reverb */ - if (reverb_buf) { - fluid_revmodel_processmix(synth->reverb, reverb_buf, - synth->left_buf[0], synth->right_buf[0]); - fluid_check_fpe("Reverb"); - } - - fluid_profile(FLUID_PROF_ONE_BLOCK_REVERB, prof_ref); - - /* send to chorus */ - if (chorus_buf) { - fluid_chorus_processmix(synth->chorus, chorus_buf, - synth->left_buf[0], synth->right_buf[0]); - fluid_check_fpe("Chorus"); - } - } - - fluid_profile(FLUID_PROF_ONE_BLOCK_CHORUS, prof_ref); - -#ifdef LADSPA - /* Run the signal through the LADSPA Fx unit */ - fluid_LADSPA_run(synth->LADSPA_FxUnit, synth->left_buf, synth->right_buf, synth->fx_left_buf, synth->fx_right_buf); - fluid_check_fpe("LADSPA"); -#endif - - synth->ticks += FLUID_BUFSIZE; - - /* Testcase, that provokes a denormal floating point error */ -#if 0 - {float num=1;while (num != 0){num*=0.5;};}; -#endif - fluid_check_fpe("??? Remainder of synth_one_block ???"); - -/* fluid_mutex_unlock(synth->busy); /\* Allow other threads to touch the synth *\/ */ - - return 0; -} - - -/* - * fluid_synth_free_voice_by_kill - * - * selects a voice for killing. the selection algorithm is a refinement - * of the algorithm previously in fluid_synth_alloc_voice. - */ -fluid_voice_t* -fluid_synth_free_voice_by_kill(fluid_synth_t* synth) -{ - int i; - fluid_real_t best_prio = 999999.; - fluid_real_t this_voice_prio; - fluid_voice_t* voice; - int best_voice_index=-1; - -/* fluid_mutex_lock(synth->busy); /\* Don't interfere with the audio thread *\/ */ -/* fluid_mutex_unlock(synth->busy); */ - - for (i = 0; i < synth->polyphony; i++) { - - voice = synth->voice[i]; - - /* safeguard against an available voice. */ - if (_AVAILABLE(voice)) { - return voice; - } - - /* Determine, how 'important' a voice is. - * Start with an arbitrary number */ - this_voice_prio = 10000.; - - /* Is this voice on the drum channel? - * Then it is very important. - * Also, forget about the released-note condition: - * Typically, drum notes are triggered only very briefly, they run most - * of the time in release phase. - */ - if (voice->chan == 9){ - this_voice_prio += 4000; - - } else if (_RELEASED(voice)){ - /* The key for this voice has been released. Consider it much less important - * than a voice, which is still held. - */ - this_voice_prio -= 2000.; - } - - if (_SUSTAINED(voice)){ - /* The sustain pedal is held down on this channel. - * Consider it less important than non-sustained channels. - * This decision is somehow subjective. But usually the sustain pedal - * is used to play 'more-voices-than-fingers', so it shouldn't hurt - * if we kill one voice. - */ - this_voice_prio -= 1000; - } - - /* We are not enthusiastic about releasing voices, which have just been started. - * Otherwise hitting a chord may result in killing notes belonging to that very same - * chord. - * So subtract the age of the voice from the priority - an older voice is just a little - * bit less important than a younger voice. - * This is a number between roughly 0 and 100.*/ - this_voice_prio -= (synth->noteid - fluid_voice_get_id(voice)); - - /* take a rough estimate of loudness into account. Louder voices are more important. */ - if (voice->volenv_section != FLUID_VOICE_ENVATTACK){ - this_voice_prio += voice->volenv_val * 1000.; - } - - /* check if this voice has less priority than the previous candidate. */ - if (this_voice_prio < best_prio) - best_voice_index = i, - best_prio = this_voice_prio; - } - - if (best_voice_index < 0) { - return NULL; - } - - voice = synth->voice[best_voice_index]; - fluid_voice_off(voice); - - return voice; -} - -/* - * fluid_synth_alloc_voice - */ -fluid_voice_t* -fluid_synth_alloc_voice(fluid_synth_t* synth, fluid_sample_t* sample, int chan, int key, int vel) -{ - int i, k; - fluid_voice_t* voice = NULL; - fluid_channel_t* channel = NULL; - -/* fluid_mutex_lock(synth->busy); /\* Don't interfere with the audio thread *\/ */ -/* fluid_mutex_unlock(synth->busy); */ - - /* check if there's an available synthesis process */ - for (i = 0; i < synth->polyphony; i++) { - if (_AVAILABLE(synth->voice[i])) { - voice = synth->voice[i]; - break; - } - } - - /* No success yet? Then stop a running voice. */ - if (voice == NULL) { - voice = fluid_synth_free_voice_by_kill(synth); - } - - if (voice == NULL) { - FLUID_LOG(FLUID_WARN, "Failed to allocate a synthesis process. (chan=%d,key=%d)", chan, key); - return NULL; - } - - if (synth->verbose) { - k = 0; - for (i = 0; i < synth->polyphony; i++) { - if (!_AVAILABLE(synth->voice[i])) { - k++; - } - } - - FLUID_LOG(FLUID_INFO, "noteon\t%d\t%d\t%d\t%05d\t%.3f\t%.3f\t%.3f\t%d", - chan, key, vel, synth->storeid, - (float) synth->ticks / 44100.0f, - (fluid_curtime() - synth->start) / 1000.0f, - 0.0f, - k); - } - - if (chan >= 0) { - channel = synth->channel[chan]; - } - - if (fluid_voice_init(voice, sample, channel, key, vel, - synth->storeid, synth->ticks, synth->gain) != FLUID_OK) { - FLUID_LOG(FLUID_WARN, "Failed to initialize voice"); - return NULL; - } - - /* add the default modulators to the synthesis process. */ - fluid_voice_add_mod(voice, &default_vel2att_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.1 */ - fluid_voice_add_mod(voice, &default_vel2filter_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.2 */ - fluid_voice_add_mod(voice, &default_at2viblfo_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.3 */ - fluid_voice_add_mod(voice, &default_mod2viblfo_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.4 */ - fluid_voice_add_mod(voice, &default_att_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.5 */ - fluid_voice_add_mod(voice, &default_pan_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.6 */ - fluid_voice_add_mod(voice, &default_expr_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.7 */ - fluid_voice_add_mod(voice, &default_reverb_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.8 */ - fluid_voice_add_mod(voice, &default_chorus_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.9 */ - fluid_voice_add_mod(voice, &default_pitch_bend_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.10 */ - - return voice; -} - -/* - * fluid_synth_kill_by_exclusive_class - */ -void fluid_synth_kill_by_exclusive_class(fluid_synth_t* synth, fluid_voice_t* new_voice) -{ - /** Kill all voices on a given channel, which belong into - excl_class. This function is called by a SoundFont's preset in - response to a noteon event. If one noteon event results in - several voice processes (stereo samples), ignore_ID must name - the voice ID of the first generated voice (so that it is not - stopped). The first voice uses ignore_ID=-1, which will - terminate all voices on a channel belonging into the exclusive - class excl_class. - */ - - int i; - int excl_class = _GEN(new_voice,GEN_EXCLUSIVECLASS); - - /* Check if the voice belongs to an exclusive class. In that case, - previous notes from the same class are released. */ - - /* Excl. class 0: No exclusive class */ - if (excl_class == 0) { - return; - } - - // FLUID_LOG(FLUID_INFO, "Voice belongs to exclusive class (class=%d, ignore_id=%d)", excl_class, ignore_ID); - - /* Kill all notes on the same channel with the same exclusive class */ - - for (i = 0; i < synth->polyphony; i++) { - fluid_voice_t* existing_voice = synth->voice[i]; - - /* Existing voice does not play? Leave it alone. */ - if (!_PLAYING(existing_voice)) { - continue; - } - - /* An exclusive class is valid for a whole channel (or preset). - * Is the voice on a different channel? Leave it alone. */ - if (existing_voice->chan != new_voice->chan) { - continue; - } - - /* Existing voice has a different (or no) exclusive class? Leave it alone. */ - if ((int)_GEN(existing_voice, GEN_EXCLUSIVECLASS) != excl_class) { - continue; - } - - /* Existing voice is a voice process belonging to this noteon - * event (for example: stereo sample)? Leave it alone. */ - if (fluid_voice_get_id(existing_voice) == fluid_voice_get_id(new_voice)) { - continue; - } - - // FLUID_LOG(FLUID_INFO, "Releasing previous voice of exclusive class (class=%d, id=%d)", - // (int)_GEN(existing_voice, GEN_EXCLUSIVECLASS), (int)fluid_voice_get_id(existing_voice)); - - fluid_voice_kill_excl(existing_voice); - }; -}; - -/* - * fluid_synth_start_voice - */ -void fluid_synth_start_voice(fluid_synth_t* synth, fluid_voice_t* voice) -{ -/* fluid_mutex_lock(synth->busy); /\* Don't interfere with the audio thread *\/ */ -/* fluid_mutex_unlock(synth->busy); */ - - /* Find the exclusive class of this voice. If set, kill all voices - * that match the exclusive class and are younger than the first - * voice process created by this noteon event. */ - fluid_synth_kill_by_exclusive_class(synth, voice); - - /* Start the new voice */ - - fluid_voice_start(voice); -} - -/* - * fluid_synth_add_sfloader - */ -void fluid_synth_add_sfloader(fluid_synth_t* synth, fluid_sfloader_t* loader) -{ - synth->loaders = fluid_list_prepend(synth->loaders, loader); -} - - -/* - * fluid_synth_sfload - */ -int -fluid_synth_sfload(fluid_synth_t* synth, const char* filename, int reset_presets) -{ - fluid_sfont_t* sfont; - fluid_list_t* list; - fluid_sfloader_t* loader; - -#if defined(MACOS9) - fluid_synth_sfunload_macos9(synth); -#endif - - if (filename == NULL) { - FLUID_LOG(FLUID_ERR, "Invalid filename"); - return FLUID_FAILED; - } - - for (list = synth->loaders; list; list = fluid_list_next(list)) { - loader = (fluid_sfloader_t*) fluid_list_get(list); - - sfont = fluid_sfloader_load(loader, filename); - - if (sfont != NULL) { - - sfont->id = ++synth->sfont_id; - - /* insert the sfont as the first one on the list */ - synth->sfont = fluid_list_prepend(synth->sfont, sfont); - - /* reset the presets for all channels */ - if (reset_presets) { - fluid_synth_program_reset(synth); - } - - return (int) sfont->id; - } - } - - FLUID_LOG(FLUID_ERR, "Failed to load SoundFont \"%s\"", filename); - return -1; -} - -/* - * fluid_synth_sfunload_callback - */ -static int fluid_synth_sfunload_callback(void* data, unsigned int msec) -{ - fluid_sfont_t* sfont = (fluid_sfont_t*) data; - int r = delete_fluid_sfont(sfont); - if (r == 0) { - FLUID_LOG(FLUID_DBG,"Unloaded SoundFont"); - } - return r != 0; -} - -/* - * fluid_synth_sfunload_macos9 - */ -void fluid_synth_sfunload_macos9(fluid_synth_t* synth) -{ -#if defined(MACOS9) - fluid_list_t *list, *next; - fluid_sfont_t* sfont; - - list = synth->unloading; - while (list) { - next = fluid_list_next(list); - sfont = (fluid_sfont_t*) fluid_list_get(list); - if (delete_fluid_sfont(sfont) == 0) { - synth->unloading = fluid_list_remove(synth->unloading, sfont); - } - list = next; - } -#endif -} - -/* - * fluid_synth_sfunload - */ -int -fluid_synth_sfunload(fluid_synth_t* synth, unsigned int id, int reset_presets) -{ - fluid_sfont_t* sfont = fluid_synth_get_sfont_by_id(synth, id); - -#if defined(MACOS9) - fluid_synth_sfunload_macos9(synth); -#endif - - if (!sfont) { - FLUID_LOG(FLUID_ERR, "No SoundFont with id = %d", id); - return FLUID_FAILED; - } - - /* remove the SoundFont from the list */ - synth->sfont = fluid_list_remove(synth->sfont, sfont); - - /* reset the presets for all channels */ - if (reset_presets) { - fluid_synth_program_reset(synth); - } else { - fluid_synth_update_presets(synth); - } - - if (delete_fluid_sfont(sfont) != 0) { -#if defined(MACOS9) - synth->unloading = fluid_list_prepend(synth->unloading, sfont); -#else - /* spin off a timer thread to unload the sfont later */ - new_fluid_timer(100, fluid_synth_sfunload_callback, sfont, 1, 1); -#endif - } - - return FLUID_OK; -} - -/* fluid_synth_sfreload - * - */ -int fluid_synth_sfreload(fluid_synth_t* synth, unsigned int id) -{ - char filename[1024]; - fluid_sfont_t* sfont; - int index = 0; - fluid_list_t *list; - fluid_sfloader_t* loader; - - - sfont = fluid_synth_get_sfont_by_id(synth, id); - if (!sfont) { - FLUID_LOG(FLUID_ERR, "No SoundFont with id = %d", id); - return FLUID_FAILED; - } - - /* find the index of the SoundFont */ - list = synth->sfont; - while (list) { - if (sfont == (fluid_sfont_t*) fluid_list_get(list)) { - break; - } - list = fluid_list_next(list); - index++; - } - - /* keep a copy of the SoundFont's filename */ - FLUID_STRCPY(filename, fluid_sfont_get_name(sfont)); - - if (fluid_synth_sfunload(synth, id, 0) != FLUID_OK) { - return FLUID_FAILED; - } - - for (list = synth->loaders; list; list = fluid_list_next(list)) { - loader = (fluid_sfloader_t*) fluid_list_get(list); - - sfont = fluid_sfloader_load(loader, filename); - - if (sfont != NULL) { - - sfont->id = id; - - /* insert the sfont at the same index */ - synth->sfont = fluid_list_insert_at(synth->sfont, index, sfont); - - /* reset the presets for all channels */ - fluid_synth_update_presets(synth); - - return sfont->id; - } - } - - FLUID_LOG(FLUID_ERR, "Failed to load SoundFont \"%s\"", filename); - return -1; -} - - -/* - * fluid_synth_add_sfont - */ -int fluid_synth_add_sfont(fluid_synth_t* synth, fluid_sfont_t* sfont) -{ - sfont->id = ++synth->sfont_id; - - /* insert the sfont as the first one on the list */ - synth->sfont = fluid_list_prepend(synth->sfont, sfont); - - /* reset the presets for all channels */ - fluid_synth_program_reset(synth); - - return sfont->id; -} - - -/* - * fluid_synth_remove_sfont - */ -void fluid_synth_remove_sfont(fluid_synth_t* synth, fluid_sfont_t* sfont) -{ - int sfont_id = fluid_sfont_get_id(sfont); - - synth->sfont = fluid_list_remove(synth->sfont, sfont); - - /* remove a possible bank offset */ - fluid_synth_remove_bank_offset(synth, sfont_id); - - /* reset the presets for all channels */ - fluid_synth_program_reset(synth); -} - - -/* fluid_synth_sfcount - * - * Returns the number of loaded SoundFonts - */ -int -fluid_synth_sfcount(fluid_synth_t* synth) -{ - return fluid_list_size(synth->sfont); -} - -/* fluid_synth_get_sfont - * - * Returns SoundFont num - */ -fluid_sfont_t* -fluid_synth_get_sfont(fluid_synth_t* synth, unsigned int num) -{ - return (fluid_sfont_t*) fluid_list_get(fluid_list_nth(synth->sfont, num)); -} - -/* fluid_synth_get_sfont_by_id - * - */ -fluid_sfont_t* fluid_synth_get_sfont_by_id(fluid_synth_t* synth, unsigned int id) -{ - fluid_list_t* list = synth->sfont; - fluid_sfont_t* sfont; - - while (list) { - sfont = (fluid_sfont_t*) fluid_list_get(list); - if (fluid_sfont_get_id(sfont) == id) { - return sfont; - } - list = fluid_list_next(list); - } - return NULL; -} - -/* fluid_synth_get_sfont_by_name - * - */ -fluid_sfont_t* fluid_synth_get_sfont_by_name(fluid_synth_t* synth, char *name) -{ - fluid_list_t* list = synth->sfont; - fluid_sfont_t* sfont; - - while (list) { - sfont = (fluid_sfont_t*) fluid_list_get(list); - if (FLUID_STRCMP(fluid_sfont_get_name(sfont), name) == 0) { - return sfont; - } - list = fluid_list_next(list); - } - return NULL; -} - -/* - * fluid_synth_get_channel_preset - */ -fluid_preset_t* -fluid_synth_get_channel_preset(fluid_synth_t* synth, int chan) -{ - if ((chan >= 0) && (chan < synth->midi_channels)) { - return fluid_channel_get_preset(synth->channel[chan]); - } - - return NULL; -} - -/* - * fluid_synth_get_voicelist - */ -void -fluid_synth_get_voicelist(fluid_synth_t* synth, fluid_voice_t* buf[], int bufsize, int ID) -{ - int i; - int count = 0; - for (i = 0; i < synth->polyphony; i++) { - fluid_voice_t* voice = synth->voice[i]; - if (count >= bufsize) { - return; - } - - if (_PLAYING(voice) && ((int)voice->id == ID || ID < 0)) { - buf[count++] = voice; - } - } - if (count >= bufsize) { - return; - } - buf[count++] = NULL; -} - -/* Purpose: - * Turns on / off the reverb unit in the synth */ -void fluid_synth_set_reverb_on(fluid_synth_t* synth, int on) -{ - synth->with_reverb = on; -} - -/* Purpose: - * Turns on / off the chorus unit in the synth */ -void fluid_synth_set_chorus_on(fluid_synth_t* synth, int on) -{ - synth->with_chorus = on; -} - -/* Purpose: - * Reports the current setting of the chorus unit. */ -int fluid_synth_get_chorus_nr(fluid_synth_t* synth) -{ - return fluid_chorus_get_nr(synth->chorus); -} - -double fluid_synth_get_chorus_level(fluid_synth_t* synth) -{ - return (double)fluid_chorus_get_level(synth->chorus); -} - -double fluid_synth_get_chorus_speed_Hz(fluid_synth_t* synth) -{ - return (double)fluid_chorus_get_speed_Hz(synth->chorus); -} - -double fluid_synth_get_chorus_depth_ms(fluid_synth_t* synth) -{ - return (double)fluid_chorus_get_depth_ms(synth->chorus); -} - -int fluid_synth_get_chorus_type(fluid_synth_t* synth) -{ - return fluid_chorus_get_type(synth->chorus); -} - -/* Purpose: - * Returns the current settings_old of the reverb unit */ -double fluid_synth_get_reverb_roomsize(fluid_synth_t* synth) -{ - return (double)fluid_revmodel_getroomsize(synth->reverb); -} - -double fluid_synth_get_reverb_damp(fluid_synth_t* synth) -{ - return (double) fluid_revmodel_getdamp(synth->reverb); -} - -double fluid_synth_get_reverb_level(fluid_synth_t* synth) -{ - return (double) fluid_revmodel_getlevel(synth->reverb); -} - -double fluid_synth_get_reverb_width(fluid_synth_t* synth) -{ - return (double) fluid_revmodel_getwidth(synth->reverb); -} - -/* Purpose: - * - * If the same note is hit twice on the same channel, then the older - * voice process is advanced to the release stage. Using a mechanical - * MIDI controller, the only way this can happen is when the sustain - * pedal is held. In this case the behaviour implemented here is - * natural for many instruments. Note: One noteon event can trigger - * several voice processes, for example a stereo sample. Don't - * release those... - */ -void fluid_synth_release_voice_on_same_note(fluid_synth_t* synth, int chan, int key){ - int i; - fluid_voice_t* voice; - -/* fluid_mutex_lock(synth->busy); /\* Don't interfere with the audio thread *\/ */ -/* fluid_mutex_unlock(synth->busy); */ - - for (i = 0; i < synth->polyphony; i++) { - voice = synth->voice[i]; - if (_PLAYING(voice) - && (voice->chan == chan) - && (voice->key == key) - && (fluid_voice_get_id(voice) != synth->noteid)) { - fluid_voice_noteoff(voice); - } - } -} - -/* Purpose: - * Sets the interpolation method to use on channel chan. - * If chan is < 0, then set the interpolation method on all channels. - */ -int fluid_synth_set_interp_method(fluid_synth_t* synth, int chan, int interp_method){ - int i; - for (i = 0; i < synth->midi_channels; i++) { - if (synth->channel[i] == NULL){ - FLUID_LOG(FLUID_ERR, "Channels don't exist (yet)!"); - return FLUID_FAILED; - }; - if (chan < 0 || fluid_channel_get_num(synth->channel[i]) == chan){ - fluid_channel_set_interp_method(synth->channel[i], interp_method); - }; - }; - return FLUID_OK; -}; - -/* Purpose: - * Returns the number of allocated midi channels - */ -int -fluid_synth_count_midi_channels(fluid_synth_t* synth) -{ - return synth->midi_channels; -} - -/* Purpose: - * Returns the number of allocated audio channels - */ -int -fluid_synth_count_audio_channels(fluid_synth_t* synth) -{ - return synth->audio_channels; -} - -/* Purpose: - * Returns the number of allocated audio channels - */ -int -fluid_synth_count_audio_groups(fluid_synth_t* synth) -{ - return synth->audio_groups; -} - -/* Purpose: - * Returns the number of allocated effects channels - */ -int -fluid_synth_count_effects_channels(fluid_synth_t* synth) -{ - return synth->effects_channels; -} - -double fluid_synth_get_cpu_load(fluid_synth_t* synth) -{ - return synth->cpu_load; -} - -static fluid_tuning_t* -fluid_synth_get_tuning(fluid_synth_t* synth, int bank, int prog) -{ - if ((bank < 0) || (bank >= 128)) { - FLUID_LOG(FLUID_WARN, "Bank number out of range"); - return NULL; - } - if ((prog < 0) || (prog >= 128)) { - FLUID_LOG(FLUID_WARN, "Program number out of range"); - return NULL; - } - if ((synth->tuning == NULL) || - (synth->tuning[bank] == NULL) || - (synth->tuning[bank][prog] == NULL)) { - FLUID_LOG(FLUID_WARN, "No tuning at bank %d, prog %d", bank, prog); - return NULL; - } - return synth->tuning[bank][prog]; -} - -static fluid_tuning_t* -fluid_synth_create_tuning(fluid_synth_t* synth, int bank, int prog, char* name) -{ - if ((bank < 0) || (bank >= 128)) { - FLUID_LOG(FLUID_WARN, "Bank number out of range"); - return NULL; - } - if ((prog < 0) || (prog >= 128)) { - FLUID_LOG(FLUID_WARN, "Program number out of range"); - return NULL; - } - if (synth->tuning == NULL) { - synth->tuning = FLUID_ARRAY(fluid_tuning_t**, 128); - if (synth->tuning == NULL) { - FLUID_LOG(FLUID_PANIC, "Out of memory"); - return NULL; - } - FLUID_MEMSET(synth->tuning, 0, 128 * sizeof(fluid_tuning_t**)); - } - - if (synth->tuning[bank] == NULL) { - synth->tuning[bank] = FLUID_ARRAY(fluid_tuning_t*, 128); - if (synth->tuning[bank] == NULL) { - FLUID_LOG(FLUID_PANIC, "Out of memory"); - return NULL; - } - FLUID_MEMSET(synth->tuning[bank], 0, 128 * sizeof(fluid_tuning_t*)); - } - - if (synth->tuning[bank][prog] == NULL) { - synth->tuning[bank][prog] = new_fluid_tuning(name, bank, prog); - if (synth->tuning[bank][prog] == NULL) { - return NULL; - } - } - - if ((fluid_tuning_get_name(synth->tuning[bank][prog]) == NULL) - || (FLUID_STRCMP(fluid_tuning_get_name(synth->tuning[bank][prog]), name) != 0)) { - fluid_tuning_set_name(synth->tuning[bank][prog], name); - } - - return synth->tuning[bank][prog]; -} - -int fluid_synth_create_key_tuning(fluid_synth_t* synth, - int bank, int prog, - char* name, double* pitch) -{ - fluid_tuning_t* tuning = fluid_synth_create_tuning(synth, bank, prog, name); - if (tuning == NULL) { - return FLUID_FAILED; - } - if (pitch) { - fluid_tuning_set_all(tuning, pitch); - } - return FLUID_OK; -} - - -int fluid_synth_create_octave_tuning(fluid_synth_t* synth, - int bank, int prog, - char* name, double* pitch) -{ - fluid_tuning_t* tuning = fluid_synth_create_tuning(synth, bank, prog, name); - if (tuning == NULL) { - return FLUID_FAILED; - } - fluid_tuning_set_octave(tuning, pitch); - return FLUID_OK; -} - -int fluid_synth_tune_notes(fluid_synth_t* synth, int bank, int prog, - int len, int *key, double* pitch, int apply) -{ - fluid_tuning_t* tuning = fluid_synth_get_tuning(synth, bank, prog); - int i; - - if (tuning == NULL) { - return FLUID_FAILED; - } - - for (i = 0; i < len; i++) { - fluid_tuning_set_pitch(tuning, key[i], pitch[i]); - } - - return FLUID_OK; -} - -int fluid_synth_select_tuning(fluid_synth_t* synth, int chan, - int bank, int prog) -{ - fluid_tuning_t* tuning = fluid_synth_get_tuning(synth, bank, prog); - - if (tuning == NULL) { - return FLUID_FAILED; - } - if ((chan < 0) || (chan >= synth->midi_channels)) { - FLUID_LOG(FLUID_WARN, "Channel out of range"); - return FLUID_FAILED; - } - - fluid_channel_set_tuning(synth->channel[chan], synth->tuning[bank][prog]); - - return FLUID_OK; -} - -int fluid_synth_reset_tuning(fluid_synth_t* synth, int chan) -{ - if ((chan < 0) || (chan >= synth->midi_channels)) { - FLUID_LOG(FLUID_WARN, "Channel out of range"); - return FLUID_FAILED; - } - - fluid_channel_set_tuning(synth->channel[chan], NULL); - - return FLUID_OK; -} - -void fluid_synth_tuning_iteration_start(fluid_synth_t* synth) -{ - synth->cur_tuning = NULL; -} - -int fluid_synth_tuning_iteration_next(fluid_synth_t* synth, int* bank, int* prog) -{ - int b = 0, p = 0; - - if (synth->tuning == NULL) { - return 0; - } - - if (synth->cur_tuning != NULL) { - /* get the next program number */ - b = fluid_tuning_get_bank(synth->cur_tuning); - p = 1 + fluid_tuning_get_prog(synth->cur_tuning); - if (p >= 128) { - p = 0; - b++; - } - } - - while (b < 128) { - if (synth->tuning[b] != NULL) { - while (p < 128) { - if (synth->tuning[b][p] != NULL) { - synth->cur_tuning = synth->tuning[b][p]; - *bank = b; - *prog = p; - return 1; - } - p++; - } - } - p = 0; - b++; - } - - return 0; -} - -int fluid_synth_tuning_dump(fluid_synth_t* synth, int bank, int prog, - char* name, int len, double* pitch) -{ - fluid_tuning_t* tuning = fluid_synth_get_tuning(synth, bank, prog); - - if (tuning == NULL) { - return FLUID_FAILED; - } - - if (name) { - snprintf(name, len - 1, "%s", fluid_tuning_get_name(tuning)); - name[len - 1] = 0; /* make sure the string is null terminated */ - } - if (pitch) { - FLUID_MEMCPY(pitch, fluid_tuning_get_all(tuning), 128 * sizeof(double)); - } - - return FLUID_OK; -} - -fluid_settings_t* fluid_synth_get_settings(fluid_synth_t* synth) -{ - return synth->settings; -} - -int fluid_synth_setstr(fluid_synth_t* synth, char* name, char* str) -{ - return fluid_settings_setstr(synth->settings, name, str); -} - -int fluid_synth_getstr(fluid_synth_t* synth, char* name, char** str) -{ - return fluid_settings_getstr(synth->settings, name, str); -} - -int fluid_synth_setnum(fluid_synth_t* synth, char* name, double val) -{ - return fluid_settings_setnum(synth->settings, name, val); -} - -int fluid_synth_getnum(fluid_synth_t* synth, char* name, double* val) -{ - return fluid_settings_getnum(synth->settings, name, val); -} - -int fluid_synth_setint(fluid_synth_t* synth, char* name, int val) -{ - return fluid_settings_setint(synth->settings, name, val); -} - -int fluid_synth_getint(fluid_synth_t* synth, char* name, int* val) -{ - return fluid_settings_getint(synth->settings, name, val); -} - -int -fluid_synth_set_gen(fluid_synth_t* synth, int chan, int param, float value) -{ - int i; - fluid_voice_t* voice; - - if ((chan < 0) || (chan >= synth->midi_channels)) { - FLUID_LOG(FLUID_WARN, "Channel out of range"); - return FLUID_FAILED; - } - - if ((param < 0) || (param >= GEN_LAST)) { - FLUID_LOG(FLUID_WARN, "Parameter number out of range"); - return FLUID_FAILED; - } - - fluid_channel_set_gen(synth->channel[chan], param, value, 0); - - for (i = 0; i < synth->polyphony; i++) { - voice = synth->voice[i]; - if (voice->chan == chan) { - fluid_voice_set_param(voice, param, value, 0); - } - } - - return FLUID_OK; -} - -/** Change the value of a generator. This function allows to control - all synthesis parameters in real-time. The changes are additive, - i.e. they add up to the existing parameter value. This function is - similar to sending an NRPN message to the synthesizer. The - function accepts a float as the value of the parameter. The - parameter numbers and ranges are described in the SoundFont 2.01 - specification, paragraph 8.1.3, page 48. See also - 'fluid_gen_type'. - - Using the fluid_synth_set_gen2() function, it is possible to set - the absolute value of a generator. This is an extension to the - SoundFont standard. If 'absolute' is non-zero, the value of the - generator specified in the SoundFont is completely ignored and the - generator is fixed to the value passed as argument. To undo this - behavior, you must call fluid_synth_set_gen2 again, with - 'absolute' set to 0 (and possibly 'value' set to zero). - - If 'normalized' is non-zero, the value is supposed to be - normalized between 0 and 1. Before applying the value, it will be - scaled and shifted to the range defined in the SoundFont - specifications. - - */ -int -fluid_synth_set_gen2(fluid_synth_t* synth, int chan, int param, - float value, int absolute, int normalized) -{ - int i; - fluid_voice_t* voice; - float v; - - if ((chan < 0) || (chan >= synth->midi_channels)) { - FLUID_LOG(FLUID_WARN, "Channel out of range"); - return FLUID_FAILED; - } - - if ((param < 0) || (param >= GEN_LAST)) { - FLUID_LOG(FLUID_WARN, "Parameter number out of range"); - return FLUID_FAILED; - } - - v = (normalized)? fluid_gen_scale(param, value) : value; - - fluid_channel_set_gen(synth->channel[chan], param, v, absolute); - - for (i = 0; i < synth->polyphony; i++) { - voice = synth->voice[i]; - if (voice->chan == chan) { - fluid_voice_set_param(voice, param, v, absolute); - } - } - - return FLUID_OK; -} - -float fluid_synth_get_gen(fluid_synth_t* synth, int chan, int param) -{ - if ((chan < 0) || (chan >= synth->midi_channels)) { - FLUID_LOG(FLUID_WARN, "Channel out of range"); - return 0.0; - } - - if ((param < 0) || (param >= GEN_LAST)) { - FLUID_LOG(FLUID_WARN, "Parameter number out of range"); - return 0.0; - } - - return fluid_channel_get_gen(synth->channel[chan], param); -} - -/* The synth needs to know the router for the command line handlers (they only - * supply the synth as argument) - */ -void fluid_synth_set_midi_router(fluid_synth_t* synth, fluid_midi_router_t* router){ - synth->midi_router=router; -}; - -/* Purpose: - * Any MIDI event from the MIDI router arrives here and is handed - * to the appropriate function. - */ -int fluid_synth_handle_midi_event(void* data, fluid_midi_event_t* event) -{ - fluid_synth_t* synth = (fluid_synth_t*) data; - int type = fluid_midi_event_get_type(event); - int chan = fluid_midi_event_get_channel(event); - - switch(type) { - case NOTE_ON: - return fluid_synth_noteon(synth, chan, - fluid_midi_event_get_key(event), - fluid_midi_event_get_velocity(event)); - - case NOTE_OFF: - return fluid_synth_noteoff(synth, chan, fluid_midi_event_get_key(event)); - - case CONTROL_CHANGE: - return fluid_synth_cc(synth, chan, - fluid_midi_event_get_control(event), - fluid_midi_event_get_value(event)); - - case PROGRAM_CHANGE: - return fluid_synth_program_change(synth, chan, fluid_midi_event_get_program(event)); - - case CHANNEL_PRESSURE: - return fluid_synth_channel_pressure(synth, chan, fluid_midi_event_get_program(event)); - - case PITCH_BEND: - return fluid_synth_pitch_bend(synth, chan, fluid_midi_event_get_pitch(event)); - - case MIDI_SYSTEM_RESET: - return fluid_synth_system_reset(synth); - } - return FLUID_FAILED; -} - - -int fluid_synth_start(fluid_synth_t* synth, unsigned int id, fluid_preset_t* preset, - int audio_chan, int midi_chan, int key, int vel) -{ - int r; - - /* check the ranges of the arguments */ - if ((midi_chan < 0) || (midi_chan >= synth->midi_channels)) { - FLUID_LOG(FLUID_WARN, "Channel out of range"); - return FLUID_FAILED; - } - - if ((key < 0) || (key >= 128)) { - FLUID_LOG(FLUID_WARN, "Key out of range"); - return FLUID_FAILED; - } - - if ((vel <= 0) || (vel >= 128)) { - FLUID_LOG(FLUID_WARN, "Velocity out of range"); - return FLUID_FAILED; - } - - fluid_mutex_lock(synth->busy); /* One at a time, please */ - - synth->storeid = id; - r = fluid_preset_noteon(preset, synth, midi_chan, key, vel); - - fluid_mutex_unlock(synth->busy); - - return r; -} - -int fluid_synth_stop(fluid_synth_t* synth, unsigned int id) -{ - int i; - fluid_voice_t* voice; - int status = FLUID_FAILED; - int count = 0; - - for (i = 0; i < synth->polyphony; i++) { - - voice = synth->voice[i]; - - if (_ON(voice) && (fluid_voice_get_id(voice) == id)) { - count++; - fluid_voice_noteoff(voice); - status = FLUID_OK; - } - } - - return status; -} - -fluid_bank_offset_t* -fluid_synth_get_bank_offset0(fluid_synth_t* synth, int sfont_id) -{ - fluid_list_t* list = synth->bank_offsets; - fluid_bank_offset_t* offset; - - while (list) { - - offset = (fluid_bank_offset_t*) fluid_list_get(list); - if (offset->sfont_id == sfont_id) { - return offset; - } - - list = fluid_list_next(list); - } - - return NULL; -} - -int -fluid_synth_set_bank_offset(fluid_synth_t* synth, int sfont_id, int offset) -{ - fluid_bank_offset_t* bank_offset; - - bank_offset = fluid_synth_get_bank_offset0(synth, sfont_id); - - if (bank_offset == NULL) { - bank_offset = FLUID_NEW(fluid_bank_offset_t); - if (bank_offset == NULL) { - return -1; - } - bank_offset->sfont_id = sfont_id; - bank_offset->offset = offset; - synth->bank_offsets = fluid_list_prepend(synth->bank_offsets, bank_offset); - } else { - bank_offset->offset = offset; - } - - return 0; -} - -int -fluid_synth_get_bank_offset(fluid_synth_t* synth, int sfont_id) -{ - fluid_bank_offset_t* bank_offset; - - bank_offset = fluid_synth_get_bank_offset0(synth, sfont_id); - return (bank_offset == NULL)? 0 : bank_offset->offset; -} - -void -fluid_synth_remove_bank_offset(fluid_synth_t* synth, int sfont_id) -{ - fluid_bank_offset_t* bank_offset; - - bank_offset = fluid_synth_get_bank_offset0(synth, sfont_id); - if (bank_offset != NULL) { - synth->bank_offsets = fluid_list_remove(synth->bank_offsets, bank_offset); - } -} diff --git a/src/libs/fluidsynth/src/fluid_synth.h b/src/libs/fluidsynth/src/fluid_synth.h deleted file mode 100644 index cd1527b0c8..0000000000 --- a/src/libs/fluidsynth/src/fluid_synth.h +++ /dev/null @@ -1,217 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - - -#ifndef _FLUID_SYNTH_H -#define _FLUID_SYNTH_H - - -/*************************************************************** - * - * INCLUDES - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif -#include "fluidsynth_priv.h" -#include "fluid_list.h" -#include "fluid_rev.h" -#include "fluid_voice.h" -#include "fluid_chorus.h" -#include "fluid_ladspa.h" -#include "fluid_midi_router.h" -#include "fluid_sys.h" - -/*************************************************************** - * - * DEFINES - */ -#define FLUID_NUM_PROGRAMS 128 -#define DRUM_INST_BANK 128 - -#if defined(WITH_FLOAT) -#define FLUID_SAMPLE_FORMAT FLUID_SAMPLE_FLOAT -#else -#define FLUID_SAMPLE_FORMAT FLUID_SAMPLE_DOUBLE -#endif - - -/*************************************************************** - * - * ENUM - */ -enum fluid_loop { - FLUID_UNLOOPED = 0, - FLUID_LOOP_DURING_RELEASE = 1, - FLUID_NOTUSED = 2, - FLUID_LOOP_UNTIL_RELEASE = 3 -}; - -enum fluid_synth_status -{ - FLUID_SYNTH_CLEAN, - FLUID_SYNTH_PLAYING, - FLUID_SYNTH_QUIET, - FLUID_SYNTH_STOPPED -}; - - -typedef struct _fluid_bank_offset_t fluid_bank_offset_t; - -struct _fluid_bank_offset_t { - int sfont_id; - int offset; -}; - - -/* - * fluid_synth_t - */ - -struct _fluid_synth_t -{ - /* fluid_settings_old_t settings_old; the old synthesizer settings */ - fluid_settings_t* settings; /** the synthesizer settings */ - int polyphony; /** maximum polyphony */ - char with_reverb; /** Should the synth use the built-in reverb unit? */ - char with_chorus; /** Should the synth use the built-in chorus unit? */ - char verbose; /** Turn verbose mode on? */ - char dump; /** Dump events to stdout to hook up a user interface? */ - double sample_rate; /** The sample rate */ - int midi_channels; /** the number of MIDI channels (>= 16) */ - int audio_channels; /** the number of audio channels (1 channel=left+right) */ - int audio_groups; /** the number of (stereo) 'sub'groups from the synth. - Typically equal to audio_channels. */ - int effects_channels; /** the number of effects channels (= 2) */ - unsigned int state; /** the synthesizer state */ - unsigned int ticks; /** the number of audio samples since the start */ - unsigned int start; /** the start in msec, as returned by system clock */ - - fluid_list_t *loaders; /** the soundfont loaders */ - fluid_list_t* sfont; /** the loaded soundfont */ - unsigned int sfont_id; - fluid_list_t* bank_offsets; /** the offsets of the soundfont banks */ - -#if defined(MACOS9) - fluid_list_t* unloading; /** the soundfonts that need to be unloaded */ -#endif - - double gain; /** master gain */ - fluid_channel_t** channel; /** the channels */ - int num_channels; /** the number of channels */ - int nvoice; /** the length of the synthesis process array */ - fluid_voice_t** voice; /** the synthesis processes */ - unsigned int noteid; /** the id is incremented for every new note. it's used for noteoff's */ - unsigned int storeid; - int nbuf; /** How many audio buffers are used? (depends on nr of audio channels / groups)*/ - - fluid_real_t** left_buf; - fluid_real_t** right_buf; - fluid_real_t** fx_left_buf; - fluid_real_t** fx_right_buf; - - fluid_revmodel_t* reverb; - fluid_chorus_t* chorus; - int cur; /** the current sample in the audio buffers to be output */ - int dither_index; /* current index in random dither value buffer: fluid_synth_(write_s16|dither_s16) */ - - char outbuf[256]; /** buffer for message output */ - double cpu_load; - - fluid_tuning_t*** tuning; /** 128 banks of 128 programs for the tunings */ - fluid_tuning_t* cur_tuning; /** current tuning in the iteration */ - - fluid_midi_router_t* midi_router; /* The midi router. Could be done nicer. */ - fluid_mutex_t busy; /* Indicates, whether the audio thread is currently running. - * Note: This simple scheme does -not- provide 100 % protection against - * thread problems, for example from MIDI thread and shell thread - */ -#ifdef LADSPA - fluid_LADSPA_FxUnit_t* LADSPA_FxUnit; /** Effects unit for LADSPA support */ -#endif -}; - -/** returns 1 if the value has been set, 0 otherwise */ -int fluid_synth_setstr(fluid_synth_t* synth, char* name, char* str); - -/** returns 1 if the value exists, 0 otherwise */ -int fluid_synth_getstr(fluid_synth_t* synth, char* name, char** str); - -/** returns 1 if the value has been set, 0 otherwise */ -int fluid_synth_setnum(fluid_synth_t* synth, char* name, double val); - -/** returns 1 if the value exists, 0 otherwise */ -int fluid_synth_getnum(fluid_synth_t* synth, char* name, double* val); - -/** returns 1 if the value has been set, 0 otherwise */ -int fluid_synth_setint(fluid_synth_t* synth, char* name, int val); - -/** returns 1 if the value exists, 0 otherwise */ -int fluid_synth_getint(fluid_synth_t* synth, char* name, int* val); - - -int fluid_synth_set_reverb_preset(fluid_synth_t* synth, int num); - -int fluid_synth_one_block(fluid_synth_t* synth, int do_not_mix_fx_to_out); - -fluid_preset_t* fluid_synth_get_preset(fluid_synth_t* synth, - unsigned int sfontnum, - unsigned int banknum, - unsigned int prognum); - -fluid_preset_t* fluid_synth_find_preset(fluid_synth_t* synth, - unsigned int banknum, - unsigned int prognum); - -int fluid_synth_all_notes_off(fluid_synth_t* synth, int chan); -int fluid_synth_all_sounds_off(fluid_synth_t* synth, int chan); -int fluid_synth_modulate_voices(fluid_synth_t* synth, int chan, int is_cc, int ctrl); -int fluid_synth_modulate_voices_all(fluid_synth_t* synth, int chan); -int fluid_synth_damp_voices(fluid_synth_t* synth, int chan); -int fluid_synth_kill_voice(fluid_synth_t* synth, fluid_voice_t * voice); -void fluid_synth_kill_by_exclusive_class(fluid_synth_t* synth, fluid_voice_t* voice); -void fluid_synth_release_voice_on_same_note(fluid_synth_t* synth, int chan, int key); -void fluid_synth_sfunload_macos9(fluid_synth_t* synth); - -void fluid_synth_print_voice(fluid_synth_t* synth); - -/** This function assures that every MIDI channels has a valid preset - * (NULL is okay). This function is called after a SoundFont is - * unloaded or reloaded. */ -void fluid_synth_update_presets(fluid_synth_t* synth); - - -int fluid_synth_update_gain(fluid_synth_t* synth, char* name, double value); -int fluid_synth_update_polyphony(fluid_synth_t* synth, char* name, int value); - -fluid_bank_offset_t* fluid_synth_get_bank_offset0(fluid_synth_t* synth, int sfont_id); -void fluid_synth_remove_bank_offset(fluid_synth_t* synth, int sfont_id); - -void fluid_synth_dither_s16(int *dither_index, int len, float* lin, float* rin, - void* lout, int loff, int lincr, - void* rout, int roff, int rincr); -/* - * misc - */ - -void fluid_synth_settings(fluid_settings_t* settings); - -#endif /* _FLUID_SYNTH_H */ diff --git a/src/libs/fluidsynth/src/fluid_sys.c b/src/libs/fluidsynth/src/fluid_sys.c deleted file mode 100644 index 34c0cbba89..0000000000 --- a/src/libs/fluidsynth/src/fluid_sys.c +++ /dev/null @@ -1,1671 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - - -#include "fluid_sys.h" - -static char fluid_errbuf[512]; /* buffer for error message */ - -static fluid_log_function_t fluid_log_function[LAST_LOG_LEVEL]; -static void* fluid_log_user_data[LAST_LOG_LEVEL]; -static int fluid_log_initialized = 0; - -static char* fluid_libname = "fluidsynth"; - - -void fluid_sys_config() -{ - fluid_log_config(); - fluid_time_config(); -} - - -unsigned int fluid_debug_flags = 0; - -#if DEBUG -/* - * fluid_debug - */ -int fluid_debug(int level, char * fmt, ...) -{ - if (fluid_debug_flags & level) { - fluid_log_function_t fun; - va_list args; - - va_start (args, fmt); - vsnprintf(fluid_errbuf, sizeof (fluid_errbuf), fmt, args); - va_end (args); - - fun = fluid_log_function[FLUID_DBG]; - if (fun != NULL) { - (*fun)(level, fluid_errbuf, fluid_log_user_data[FLUID_DBG]); - } - } - return 0; -} -#endif - -/** - * Installs a new log function for a specified log level. - * @param level Log level to install handler for. - * @param fun Callback function handler to call for logged messages - * @param data User supplied data pointer to pass to log function - * @return The previously installed function. - */ -fluid_log_function_t -fluid_set_log_function(int level, fluid_log_function_t fun, void* data) -{ - fluid_log_function_t old = NULL; - - if ((level >= 0) && (level < LAST_LOG_LEVEL)) { - old = fluid_log_function[level]; - fluid_log_function[level] = fun; - fluid_log_user_data[level] = data; - } - return old; -} - -/** - * Default log function which prints to the stderr. - * @param level Log level - * @param message Log message - * @param data User supplied data (not used) - */ -void -fluid_default_log_function(int level, char* message, void* data) -{ - FILE* out; - -#if defined(WIN32) - out = stdout; -#else - out = stderr; -#endif - - if (fluid_log_initialized == 0) { - fluid_log_config(); - } - - switch (level) { - case FLUID_PANIC: - FLUID_FPRINTF(out, "%s: panic: %s\n", fluid_libname, message); - break; - case FLUID_ERR: - FLUID_FPRINTF(out, "%s: error: %s\n", fluid_libname, message); - break; - case FLUID_WARN: - FLUID_FPRINTF(out, "%s: warning: %s\n", fluid_libname, message); - break; - case FLUID_INFO: - FLUID_FPRINTF(out, "%s: %s\n", fluid_libname, message); - break; - case FLUID_DBG: -#if DEBUG - FLUID_FPRINTF(out, "%s: debug: %s\n", fluid_libname, message); -#endif - break; - default: - FLUID_FPRINTF(out, "%s: %s\n", fluid_libname, message); - break; - } - fflush(out); -} - -/* - * fluid_init_log - */ -void -fluid_log_config(void) -{ - if (fluid_log_initialized == 0) { - - fluid_log_initialized = 1; - - if (fluid_log_function[FLUID_PANIC] == NULL) { - fluid_set_log_function(FLUID_PANIC, fluid_default_log_function, NULL); - } - - if (fluid_log_function[FLUID_ERR] == NULL) { - fluid_set_log_function(FLUID_ERR, fluid_default_log_function, NULL); - } - - if (fluid_log_function[FLUID_WARN] == NULL) { - fluid_set_log_function(FLUID_WARN, fluid_default_log_function, NULL); - } - - if (fluid_log_function[FLUID_INFO] == NULL) { - fluid_set_log_function(FLUID_INFO, fluid_default_log_function, NULL); - } - - if (fluid_log_function[FLUID_DBG] == NULL) { - fluid_set_log_function(FLUID_DBG, fluid_default_log_function, NULL); - } - } -} - -/** - * Print a message to the log. - * @param level Log level (#fluid_log_level). - * @param fmt Printf style format string for log message - * @param ... Arguments for printf 'fmt' message string - * @return Always returns -1 - */ -int -fluid_log(int level, char* fmt, ...) -{ - fluid_log_function_t fun = NULL; - - va_list args; - va_start (args, fmt); - vsnprintf(fluid_errbuf, sizeof (fluid_errbuf), fmt, args); - va_end (args); - - if ((level >= 0) && (level < LAST_LOG_LEVEL)) { - fun = fluid_log_function[level]; - if (fun != NULL) { - (*fun)(level, fluid_errbuf, fluid_log_user_data[level]); - } - } - return FLUID_FAILED; -} - -/** - * An improved strtok, still trashes the input string, but is portable and - * thread safe. Also skips token chars at beginning of token string and never - * returns an empty token (will return NULL if source ends in token chars though). - * NOTE: NOT part of public API - * @internal - * @param str Pointer to a string pointer of source to tokenize. Pointer gets - * updated on each invocation to point to beginning of next token. Note that - * token char get's overwritten with a 0 byte. String pointer is set to NULL - * when final token is returned. - * @param delim String of delimiter chars. - * @return Pointer to the next token or NULL if no more tokens. - */ -char *fluid_strtok (char **str, char *delim) -{ - char *s, *d, *token; - char c; - - if (str == NULL || delim == NULL || !*delim) - { - FLUID_LOG(FLUID_ERR, "Null pointer"); - return NULL; - } - - s = *str; - if (!s) return NULL; /* str points to a NULL pointer? (tokenize already ended) */ - - /* skip delimiter chars at beginning of token */ - do - { - c = *s; - if (!c) /* end of source string? */ - { - *str = NULL; - return NULL; - } - - for (d = delim; *d; d++) /* is source char a token char? */ - { - if (c == *d) /* token char match? */ - { - s++; /* advance to next source char */ - break; - } - } - } while (*d); /* while token char match */ - - token = s; /* start of token found */ - - /* search for next token char or end of source string */ - for (s = s+1; *s; s++) - { - c = *s; - - for (d = delim; *d; d++) /* is source char a token char? */ - { - if (c == *d) /* token char match? */ - { - *s = '\0'; /* overwrite token char with zero byte to terminate token */ - *str = s+1; /* update str to point to beginning of next token */ - return token; - } - } - } - - /* we get here only if source string ended */ - *str = NULL; - return token; -} - -/* - * fluid_error - */ -char* -fluid_error() -{ - return fluid_errbuf; -} - - -/* - * - * fluid_is_midifile - */ -int -fluid_is_midifile(char* filename) -{ - FILE* fp = fopen(filename, "rb"); - char id[4]; - - if (fp == NULL) { - return 0; - } - if (fread((void*) id, 1, 4, fp) != 4) { - fclose(fp); - return 0; - } - fclose(fp); - - return strncmp(id, "MThd", 4) == 0; -} - -/* - * fluid_is_soundfont - * - */ -int -fluid_is_soundfont(char* filename) -{ - FILE* fp = fopen(filename, "rb"); - char id[4]; - - if (fp == NULL) { - return 0; - } - if (fread((void*) id, 1, 4, fp) != 4) { - fclose(fp); - return 0; - } - fclose(fp); - - return strncmp(id, "RIFF", 4) == 0; -} - -#if defined(WIN32) - -/*=============================================================*/ -/* */ -/* Win32 */ -/* */ -/*=============================================================*/ - -/*************************************************************** - * - * Timer - * - */ - -struct _fluid_timer_t -{ - long msec; - fluid_timer_callback_t callback; - void* data; - HANDLE thread; - DWORD thread_id; - int cont; - int auto_destroy; -}; - -static int fluid_timer_count = 0; -DWORD WINAPI fluid_timer_run(LPVOID data); - -fluid_timer_t* -new_fluid_timer(int msec, fluid_timer_callback_t callback, void* data, - int new_thread, int auto_destroy) -{ - fluid_timer_t* timer = FLUID_NEW(fluid_timer_t); - if (timer == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - - timer->cont = 1; - timer->msec = msec; - timer->callback = callback; - timer->data = data; - timer->thread = 0; - timer->auto_destroy = auto_destroy; - - if (new_thread) { - timer->thread = CreateThread(NULL, 0, fluid_timer_run, (LPVOID) timer, 0, &timer->thread_id); - if (timer->thread == NULL) { - FLUID_LOG(FLUID_ERR, "Couldn't create timer thread"); - FLUID_FREE(timer); - return NULL; - } - SetThreadPriority(timer->thread, THREAD_PRIORITY_TIME_CRITICAL); - } else { - fluid_timer_run((LPVOID) timer); - } - return timer; -} - -DWORD WINAPI -fluid_timer_run(LPVOID data) -{ - int count = 0; - int cont = 1; - long start; - long delay; - fluid_timer_t* timer; - timer = (fluid_timer_t*) data; - - if ((timer == NULL) || (timer->callback == NULL)) { - return 0; - } - - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST); - - /* keep track of the start time for absolute positioning */ - start = fluid_curtime(); - - while (cont) { - - /* do whatever we have to do */ - cont = (*timer->callback)(timer->data, fluid_curtime() - start); - - count++; - - /* to avoid incremental time errors, I calculate the delay between - two callbacks bringing in the "absolute" time (count * - timer->msec) */ - delay = (count * timer->msec) - (fluid_curtime() - start); - if (delay > 0) { - Sleep(delay); - } - - cont &= timer->cont; - } - - FLUID_LOG(FLUID_DBG, "Timer thread finished"); - - if (timer->auto_destroy) { - FLUID_FREE(timer); - } - - ExitThread(0); - return 0; -} - -int -delete_fluid_timer(fluid_timer_t* timer) -{ - timer->cont = 0; - fluid_timer_join(timer); - FLUID_FREE(timer); - return FLUID_OK; -} - -int -fluid_timer_join(fluid_timer_t* timer) -{ - DWORD wait_result; - if (timer->thread == 0) { - return FLUID_OK; - } - wait_result = WaitForSingleObject(timer->thread, INFINITE); - return (wait_result == WAIT_OBJECT_0)? FLUID_OK : FLUID_FAILED; -} - - -/*************************************************************** - * - * Time - */ - -double rdtsc(void); -double fluid_estimate_cpu_frequency(void); - -static double fluid_cpu_frequency = -1.0; - -void fluid_time_config(void) -{ - if (fluid_cpu_frequency < 0.0) { - fluid_cpu_frequency = fluid_estimate_cpu_frequency() / 1000000.0; - } -} - -double fluid_utime(void) -{ - return (rdtsc() / fluid_cpu_frequency); -} - -double rdtsc(void) -{ - LARGE_INTEGER t; - QueryPerformanceCounter(&t); - return (double) t.QuadPart; -} - -double fluid_estimate_cpu_frequency(void) -{ -#if 0 - LONGLONG start, stop, ticks; - unsigned int before, after, delta; - double freq; - - start = rdtsc(); - stop = start; - before = fluid_curtime(); - after = before; - - while (1) { - if (after - before > 1000) { - break; - } - after = fluid_curtime(); - stop = rdtsc(); - } - - delta = after - before; - ticks = stop - start; - - freq = 1000 * ticks / delta; - - return freq; - -#else - unsigned int before, after; - LARGE_INTEGER start, stop; - - before = fluid_curtime(); - QueryPerformanceCounter(&start); - - Sleep(1000); - - after = fluid_curtime(); - QueryPerformanceCounter(&stop); - - return (double) 1000 * (stop.QuadPart - start.QuadPart) / (after - before); -#endif -} - - - -#elif defined(MACOS9) -/*=============================================================*/ -/* */ -/* MacOS 9 */ -/* */ -/*=============================================================*/ - - -/*************************************************************** - * - * Timer - */ - -struct _fluid_timer_t -{ - TMTask myTmTask; - long msec; - unsigned int start; - unsigned int count; - int isInstalled; - fluid_timer_callback_t callback; - void* data; - int auto_destroy; -}; - -static TimerUPP myTimerUPP; - -void -_timerCallback(fluid_timer_t *timer) -{ - int cont; - cont = (*timer->callback)(timer->data, fluid_curtime() - timer->start); - if (cont) { - PrimeTime((QElemPtr)timer, timer->msec); - } else { - timer->isInstalled = 0; - } - timer->count++; -} - -fluid_timer_t* -new_fluid_timer(int msec, fluid_timer_callback_t callback, void* data, - int new_thread, int auto_destroy) -{ - fluid_timer_t* timer = FLUID_NEW(fluid_timer_t); - if (timer == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - - if (!myTimerUPP) - myTimerUPP = NewTimerProc(_timerCallback); - - /* setup tmtask */ - timer->myTmTask.tmAddr = myTimerUPP; - timer->myTmTask.qLink = NULL; - timer->myTmTask.qType = 0; - timer->myTmTask.tmCount = 0L; - timer->myTmTask.tmWakeUp = 0L; - timer->myTmTask.tmReserved = 0L; - - timer->callback = callback; - - timer->msec = msec; - timer->data = data; - timer->start = fluid_curtime(); - timer->isInstalled = 1; - timer->count = 0; - timer->auto_destroy = auto_destroy; - - InsXTime((QElemPtr)timer); - PrimeTime((QElemPtr)timer, msec); - - return timer; -} - -int -delete_fluid_timer(fluid_timer_t* timer) -{ - if (timer->isInstalled) { - RmvTime((QElemPtr)timer); - } - FLUID_FREE(timer); - return FLUID_OK; -} - -int -fluid_timer_join(fluid_timer_t* timer) -{ - if (timer->isInstalled) { - int count = timer->count; - /* wait until count has incremented */ - while (count == timer->count) {} - } - return FLUID_OK; -} - -/*************************************************************** - * - * Time - */ -#define kTwoPower32 (4294967296.0) /* 2^32 */ - -void fluid_time_config(void) -{ -} - -unsigned int fluid_curtime() -{ - /* could be optimized by not going though a double */ - UnsignedWide uS; - double mSf; - unsigned int ms; - - Microseconds(&uS); - - mSf = ((((double) uS.hi) * kTwoPower32) + uS.lo)/1000.0f; - - ms = mSf; - - return (ms); -} - - - -#elif defined(__OS2__) -/*=============================================================*/ -/* */ -/* OS2 */ -/* */ -/*=============================================================*/ - -/*************************************************************** - * - * Timer - * - */ - -struct _fluid_timer_t -{ - long msec; - fluid_timer_callback_t callback; - void* data; - int thread_id; - int cont; - int auto_destroy; -}; - -static int fluid_timer_count = 0; -void fluid_timer_run(void *data); - -fluid_timer_t* -new_fluid_timer(int msec, fluid_timer_callback_t callback, void* data, - int new_thread, int auto_destroy) -{ - fluid_timer_t* timer = FLUID_NEW(fluid_timer_t); - if (timer == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - - timer->cont = 1; - timer->msec = msec; - timer->callback = callback; - timer->data = data; - timer->thread_id =-1; - timer->auto_destroy = auto_destroy; - - if (new_thread) { - timer->thread_id = _beginthread( fluid_timer_run, NULL, 256 * 1024, ( void * )timer ); - if (timer->thread_id == -1) { - FLUID_LOG(FLUID_ERR, "Couldn't create timer thread"); - FLUID_FREE(timer); - return NULL; - } - DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, PRTYD_MAXIMUM, timer->thread_id); - } else { - fluid_timer_run(( void * )timer); - } - return timer; -} - -void -fluid_timer_run(void *data) -{ - int count = 0; - int cont = 1; - long start; - long delay; - fluid_timer_t* timer; - timer = (fluid_timer_t*) data; - - if ((timer == NULL) || (timer->callback == NULL)) { - return; - } - - DosSetPriority( PRTYS_THREAD, PRTYC_REGULAR, PRTYD_MAXIMUM, 0 ); - - /* keep track of the start time for absolute positioning */ - start = fluid_curtime(); - - while (cont) { - - /* do whatever we have to do */ - cont = (*timer->callback)(timer->data, fluid_curtime() - start); - - count++; - - /* to avoid incremental time errors, I calculate the delay between - two callbacks bringing in the "absolute" time (count * - timer->msec) */ - delay = (count * timer->msec) - (fluid_curtime() - start); - if (delay > 0) { - DosSleep(delay); - } - - cont &= timer->cont; - } - - FLUID_LOG(FLUID_DBG, "Timer thread finished"); - - if (timer->auto_destroy) { - FLUID_FREE(timer); - } - - return; -} - -int -delete_fluid_timer(fluid_timer_t* timer) -{ - timer->cont = 0; - fluid_timer_join(timer); - FLUID_FREE(timer); - return FLUID_OK; -} - -int -fluid_timer_join(fluid_timer_t* timer) -{ - ULONG wait_result; - if (timer->thread_id == -1) { - return FLUID_OK; - } - wait_result = DosWaitThread(&timer->thread_id, DCWW_WAIT); - return (wait_result == 0)? FLUID_OK : FLUID_FAILED; -} - - -/*************************************************************** - * - * Time - */ - -double rdtsc(void); -double fluid_estimate_cpu_frequency(void); - -static double fluid_cpu_frequency = -1.0; - -void fluid_time_config(void) -{ - if (fluid_cpu_frequency < 0.0) { - fluid_cpu_frequency = fluid_estimate_cpu_frequency() / 1000000.0; - } -} - -unsigned int fluid_curtime(void) -{ - ULONG ulMS; - DosQuerySysInfo( QSV_MS_COUNT, QSV_MS_COUNT, &ulMS, sizeof( ULONG )); - return ulMS; -} - -double fluid_utime(void) -{ - return (rdtsc() / fluid_cpu_frequency); -} - -#define Q2ULL( q ) (*(unsigned long long *)&q) - -double rdtsc(void) -{ - QWORD t; - DosTmrQueryTime(&t); - return (double)Q2ULL(t); -} - -double fluid_estimate_cpu_frequency(void) -{ - unsigned int before, after; - QWORD start, stop; - - before = fluid_curtime(); - DosTmrQueryTime(&start); - - DosSleep(1000); - - after = fluid_curtime(); - DosTmrQueryTime(&stop); - - return (double) 1000 * (Q2ULL(stop) - Q2ULL(start)) / (after - before); -} - -#elif defined(__BEOS__) || defined(__HAIKU__) - -struct _fluid_timer_t -{ - long msec; - fluid_timer_callback_t callback; - void* data; - thread_id thread; - sem_id sem; -}; - -static int32 -fluid_thread_start(void *data) -{ - fluid_timer_t *timer = (fluid_timer_t *)data; - bigtime_t timestamp = system_time(); - while (true) { - if ((*timer->callback)(timer->data, timer->msec) == 0) { - delete_sem(timer->sem); - } - timestamp += timer->msec * 1000LL; - if (acquire_sem_etc(timer->sem, 1, B_ABSOLUTE_TIMEOUT, timestamp) != B_TIMED_OUT) { - break; - } - } - return B_OK; -} - -fluid_timer_t* -new_fluid_timer(int msec, fluid_timer_callback_t callback, void* data, - int new_thread, int auto_destroy) -{ - fluid_timer_t* timer = FLUID_NEW(fluid_timer_t); - if (timer == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - - timer->msec = msec; - timer->callback = callback; - timer->data = data; - timer->sem = create_sem(0, "synth_sem"); - if (timer->sem < B_OK) { - FLUID_LOG(FLUID_ERR, "Failed to create the timer sem"); - FLUID_FREE(timer); - return NULL; - } - timer->thread = spawn_thread(fluid_thread_start, "synth_thread", B_REAL_TIME_DISPLAY_PRIORITY, timer); - if (timer->thread < B_OK) { - FLUID_LOG(FLUID_ERR, "Failed to create the timer thread"); - delete_sem(timer->sem); - FLUID_FREE(timer); - return NULL; - } - return timer; -} - -int -delete_fluid_timer(fluid_timer_t* timer) -{ - fluid_timer_join(timer); - FLUID_FREE(timer); - return FLUID_OK; -} - -int -fluid_timer_join(fluid_timer_t* timer) -{ - status_t status; - if (timer->thread < 0) - return FLUID_OK; - - delete_sem(timer->sem); - wait_for_thread(timer->thread, &status); - return FLUID_OK; -} - -void fluid_time_config(void) -{ -} - -unsigned int fluid_curtime() -{ - return system_time() / 1000; -} - -double fluid_utime(void) -{ - return system_time(); -} - - -#else - -/*=============================================================*/ -/* */ -/* POSIX */ -/* */ -/*=============================================================*/ - - -/*************************************************************** - * - * Timer - */ - -struct _fluid_timer_t -{ - long msec; - fluid_timer_callback_t callback; - void* data; - pthread_t thread; - int cont; - int auto_destroy; -}; - -void* -fluid_timer_start(void *data) -{ - int count = 0; - int cont = 1; - long start; - long delay; - fluid_timer_t* timer; - timer = (fluid_timer_t*) data; - - /* keep track of the start time for absolute positioning */ - start = fluid_curtime(); - - while (cont) { - - /* do whatever we have to do */ - cont = (*timer->callback)(timer->data, fluid_curtime() - start); - - count++; - - /* to avoid incremental time errors, calculate the delay between - two callbacks bringing in the "absolute" time (count * - timer->msec) */ - delay = (count * timer->msec) - (fluid_curtime() - start); - if (delay > 0) { - usleep(delay * 1000); - } - - cont &= timer->cont; - } - - FLUID_LOG(FLUID_DBG, "Timer thread finished"); - if (timer->thread != 0) { - pthread_exit(NULL); - } - - if (timer->auto_destroy) { - FLUID_FREE(timer); - } - - return NULL; -} - -fluid_timer_t* -new_fluid_timer(int msec, fluid_timer_callback_t callback, void* data, - int new_thread, int auto_destroy) -{ - pthread_attr_t *attr = NULL; - pthread_attr_t rt_attr; - int sched = SCHED_FIFO; - struct sched_param priority; - int err; - - fluid_timer_t* timer = FLUID_NEW(fluid_timer_t); - if (timer == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - timer->msec = msec; - timer->callback = callback; - timer->data = data; - timer->cont = 1; - timer->thread = 0; - timer->auto_destroy = auto_destroy; - - err = pthread_attr_init(&rt_attr); - if (err == 0) { - err = pthread_attr_setschedpolicy(&rt_attr, SCHED_FIFO); - if (err == 0) { - priority.sched_priority = 10; - err = pthread_attr_setschedparam(&rt_attr, &priority); - if (err == 0) { - attr = &rt_attr; - } - } - } - - if (new_thread) { - err = pthread_create(&timer->thread, attr, fluid_timer_start, (void*) timer); - if (err == 0) { - FLUID_LOG(FLUID_DBG, "The timer thread was created with real-time priority"); - } else { - /* Create the thread with default attributes */ - err = pthread_create(&timer->thread, NULL, fluid_timer_start, (void*) timer); - if (err != 0) { - FLUID_LOG(FLUID_ERR, "Failed to create the timer thread"); - FLUID_FREE(timer); - return NULL; - } else { - FLUID_LOG(FLUID_DBG, "The timer thread does not have real-time priority"); - } - } - } else { - fluid_timer_start((void*) timer); - } - return timer; -} - -int -delete_fluid_timer(fluid_timer_t* timer) -{ - timer->cont = 0; - fluid_timer_join(timer); - FLUID_LOG(FLUID_DBG, "Joined player thread"); - FLUID_FREE(timer); - return FLUID_OK; -} - -int -fluid_timer_join(fluid_timer_t* timer) -{ - int err = 0; - - if (timer->thread != 0) { - err = pthread_join(timer->thread, NULL); - } - FLUID_LOG(FLUID_DBG, "Joined player thread"); - return (err == 0)? FLUID_OK : FLUID_FAILED; -} - - -/*************************************************************** - * - * Time - */ - -static double fluid_cpu_frequency = -1.0; - -double rdtsc(void); -double fluid_estimate_cpu_frequency(void); - -void fluid_time_config(void) -{ - if (fluid_cpu_frequency < 0.0) { - fluid_cpu_frequency = fluid_estimate_cpu_frequency() / 1000000.0; - if (fluid_cpu_frequency == 0.0) fluid_cpu_frequency = 1.0; - } -} - -unsigned int fluid_curtime() -{ - struct timeval now; - gettimeofday(&now, NULL); - return now.tv_sec * 1000 + now.tv_usec / 1000; -} - -double fluid_utime(void) -{ - return (rdtsc() / fluid_cpu_frequency); -} - -#if !defined(__i386__) - -double rdtsc(void) -{ - return 0.0; -} - -double fluid_estimate_cpu_frequency(void) -{ - return 1.0; -} - -#else - -double rdtsc(void) -{ - unsigned int a, b; - - __asm__ ("rdtsc" : "=a" (a), "=d" (b)); - return (double)b * (double)0x10000 * (double)0x10000 + a; -} - -double fluid_estimate_cpu_frequency(void) -{ - double start, stop; - unsigned int a0, b0, a1, b1; - unsigned int before, after; - - before = fluid_curtime(); - __asm__ ("rdtsc" : "=a" (a0), "=d" (b0)); - - sleep(1); - - after = fluid_curtime(); - __asm__ ("rdtsc" : "=a" (a1), "=d" (b1)); - - - start = (double)b0 * (double)0x10000 * (double)0x10000 + a0; - stop = (double)b1 * (double)0x10000 * (double)0x10000 + a1; - - return 1000 * (stop - start) / (after - before); -} -#endif - - -#ifdef FPE_CHECK - -/*************************************************************** - * - * Floating point exceptions - * - * The floating point exception functions were taken from Ircam's - * jMax source code. http://www.ircam.fr/jmax - * - * FIXME: check in config for i386 machine - * - * Currently not used. I leave the code here in case we want to pick - * this up again some time later. - */ - -/* Exception flags */ -#define _FPU_STATUS_IE 0x001 /* Invalid Operation */ -#define _FPU_STATUS_DE 0x002 /* Denormalized Operand */ -#define _FPU_STATUS_ZE 0x004 /* Zero Divide */ -#define _FPU_STATUS_OE 0x008 /* Overflow */ -#define _FPU_STATUS_UE 0x010 /* Underflow */ -#define _FPU_STATUS_PE 0x020 /* Precision */ -#define _FPU_STATUS_SF 0x040 /* Stack Fault */ -#define _FPU_STATUS_ES 0x080 /* Error Summary Status */ - -/* Macros for accessing the FPU status word. */ - -/* get the FPU status */ -#define _FPU_GET_SW(sw) __asm__ ("fnstsw %0" : "=m" (*&sw)) - -/* clear the FPU status */ -#define _FPU_CLR_SW() __asm__ ("fnclex" : : ) - -/* Purpose: - * Checks, if the floating point unit has produced an exception, print a message - * if so and clear the exception. - */ -unsigned int fluid_check_fpe_i386(char* explanation) -{ - unsigned int s; - - _FPU_GET_SW(s); - _FPU_CLR_SW(); - - s &= _FPU_STATUS_IE | _FPU_STATUS_DE | _FPU_STATUS_ZE | _FPU_STATUS_OE | _FPU_STATUS_UE; - - if (s) - { - FLUID_LOG(FLUID_WARN, "FPE exception (before or in %s): %s%s%s%s%s", explanation, - (s & _FPU_STATUS_IE) ? "Invalid operation " : "", - (s & _FPU_STATUS_DE) ? "Denormal number " : "", - (s & _FPU_STATUS_ZE) ? "Zero divide " : "", - (s & _FPU_STATUS_OE) ? "Overflow " : "", - (s & _FPU_STATUS_UE) ? "Underflow " : ""); - } - - return s; -} - -/* Purpose: - * Clear floating point exception. - */ -void fluid_clear_fpe_i386 (void) -{ - _FPU_CLR_SW(); -} - -#endif // ifdef FPE_CHECK - - -#endif // #else (its POSIX) - - -/*************************************************************** - * - * Profiling (Linux, i586 only) - * - */ - -#if WITH_PROFILING - -fluid_profile_data_t fluid_profile_data[] = -{ - { FLUID_PROF_WRITE_S16, "fluid_synth_write_s16 ", 1e10, 0.0, 0.0, 0}, - { FLUID_PROF_ONE_BLOCK, "fluid_synth_one_block ", 1e10, 0.0, 0.0, 0}, - { FLUID_PROF_ONE_BLOCK_CLEAR, "fluid_synth_one_block:clear ", 1e10, 0.0, 0.0, 0}, - { FLUID_PROF_ONE_BLOCK_VOICE, "fluid_synth_one_block:one voice ", 1e10, 0.0, 0.0, 0}, - { FLUID_PROF_ONE_BLOCK_VOICES, "fluid_synth_one_block:all voices", 1e10, 0.0, 0.0, 0}, - { FLUID_PROF_ONE_BLOCK_REVERB, "fluid_synth_one_block:reverb ", 1e10, 0.0, 0.0, 0}, - { FLUID_PROF_ONE_BLOCK_CHORUS, "fluid_synth_one_block:chorus ", 1e10, 0.0, 0.0, 0}, - { FLUID_PROF_VOICE_NOTE, "fluid_voice:note ", 1e10, 0.0, 0.0, 0}, - { FLUID_PROF_VOICE_RELEASE, "fluid_voice:release ", 1e10, 0.0, 0.0, 0}, - { FLUID_PROF_LAST, "last", 1e100, 0.0, 0.0, 0} -}; - - -void fluid_profiling_print(void) -{ - int i; - - printf("fluid_profiling_print\n"); - - FLUID_LOG(FLUID_INFO, "Estimated CPU frequency: %.0f MHz", fluid_cpu_frequency); - FLUID_LOG(FLUID_INFO, "Estimated times: min/avg/max (micro seconds)"); - - for (i = 0; i < FLUID_PROF_LAST; i++) { - if (fluid_profile_data[i].count > 0) { - FLUID_LOG(FLUID_INFO, "%s: %.3f/%.3f/%.3f", - fluid_profile_data[i].description, - fluid_profile_data[i].min, - fluid_profile_data[i].total / fluid_profile_data[i].count, - fluid_profile_data[i].max); - } else { - FLUID_LOG(FLUID_DBG, "%s: no profiling available", fluid_profile_data[i].description); - } - } -} - - -#endif /* WITH_PROFILING */ - - - -/*************************************************************** - * - * Threads - * - */ - -#if defined(MACOS9) -/* Not implemented */ -fluid_thread_t* new_fluid_thread(fluid_thread_func_t func, void* data, int detach) { return NULL; } -int delete_fluid_thread(fluid_thread_t* thread) { return 0; } -int fluid_thread_join(fluid_thread_t* thread) { return 0; } - -#elif defined(WIN32) - -struct _fluid_thread_t { - HANDLE thread; - DWORD thread_id; - fluid_thread_func_t func; - void* data; - int detached; -}; - -static DWORD WINAPI fluid_thread_start(LPVOID data) -{ - fluid_thread_t* thread = (fluid_thread_t*) data; - - thread->func(thread->data); - - if (thread->detached) { - FLUID_FREE(thread); - } - - return 0; -} - - -fluid_thread_t* new_fluid_thread(fluid_thread_func_t func, void* data, int detach) -{ - fluid_thread_t* thread; - - if (func == NULL) { - FLUID_LOG(FLUID_ERR, "Invalid thread function"); - return NULL; - } - - thread = FLUID_NEW(fluid_thread_t); - if (thread == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - - thread->data = data; - thread->func = func; - thread->detached = detach; - - thread->thread = CreateThread(NULL, 0, fluid_thread_start, (LPVOID) thread, - 0, &thread->thread_id); - if (thread->thread == NULL) { - FLUID_LOG(FLUID_ERR, "Couldn't create the thread"); - FLUID_FREE(thread); - return NULL; - } - - return thread; -} - -int delete_fluid_thread(fluid_thread_t* thread) -{ - FLUID_FREE(thread); - return FLUID_OK; -} - - -int fluid_thread_join(fluid_thread_t* thread) -{ - DWORD wait_result; - if (thread->thread == 0) { - return FLUID_OK; - } - wait_result = WaitForSingleObject(thread->thread, INFINITE); - return (wait_result == WAIT_OBJECT_0)? FLUID_OK : FLUID_FAILED; -} - -#elif defined(__OS2__) - -struct _fluid_thread_t { - int thread_id; - fluid_thread_func_t func; - void* data; - int detached; -}; - -static void fluid_thread_start(void *data) -{ - fluid_thread_t* thread = (fluid_thread_t*) data; - - thread->func(thread->data); - - if (thread->detached) { - FLUID_FREE(thread); - } - - return 0; -} - - -fluid_thread_t* new_fluid_thread(fluid_thread_func_t func, void* data, int detach) -{ - fluid_thread_t* thread; - - if (func == NULL) { - FLUID_LOG(FLUID_ERR, "Invalid thread function"); - return NULL; - } - - thread = FLUID_NEW(fluid_thread_t); - if (thread == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - - thread->data = data; - thread->func = func; - thread->detached = detach; - - thread->thread_id = _beginthread(fluid_thread_start, NULL, 256 * 1024, (void *) thread); - if (thread->thread_id == -1) { - FLUID_LOG(FLUID_ERR, "Couldn't create the thread"); - FLUID_FREE(thread); - return NULL; - } - - return thread; -} - -int delete_fluid_thread(fluid_thread_t* thread) -{ - FLUID_FREE(thread); - return FLUID_OK; -} - - -int fluid_thread_join(fluid_thread_t* thread) -{ - ULONG wait_result; - if (thread->thread_id == -1) { - return FLUID_OK; - } - wait_result = DosWaitThread(&thread->thread_id, DCWW_WAIT); - return (wait_result == 0)? FLUID_OK : FLUID_FAILED; -} - -#elif defined(__BEOS__) || defined(__HAIKU__) -/* Not implemented */ -fluid_thread_t* new_fluid_thread(fluid_thread_func_t func, void* data, int detach) { return NULL; } -int delete_fluid_thread(fluid_thread_t* thread) { return 0; } -int fluid_thread_join(fluid_thread_t* thread) { return 0; } - -#else - - -struct _fluid_thread_t { - pthread_t pthread; - fluid_thread_func_t func; - void* data; - int detached; -}; - -static void* fluid_thread_start(void *data) -{ - fluid_thread_t* thread = (fluid_thread_t*) data; - - thread->func(thread->data); - - if (thread->detached) { - FLUID_FREE(thread); - } - - return NULL; -} - -fluid_thread_t* new_fluid_thread(fluid_thread_func_t func, void* data, int detach) -{ - fluid_thread_t* thread; - pthread_attr_t attr; - - if (func == NULL) { - FLUID_LOG(FLUID_ERR, "Invalid thread function"); - return NULL; - } - - thread = FLUID_NEW(fluid_thread_t); - if (thread == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - - thread->data = data; - thread->func = func; - thread->detached = detach; - - pthread_attr_init(&attr); - - if (detach) { - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - } - - if (pthread_create(&thread->pthread, &attr, fluid_thread_start, thread)) { - FLUID_LOG(FLUID_ERR, "Failed to create the thread"); - FLUID_FREE(thread); - return NULL; - } - - return thread; -} - -int delete_fluid_thread(fluid_thread_t* thread) -{ - FLUID_FREE(thread); - return FLUID_OK; -} - -int fluid_thread_join(fluid_thread_t* thread) -{ - int err = 0; - - if (thread->pthread != 0) { - err = pthread_join(thread->pthread, NULL); - } - return (err == 0)? FLUID_OK : FLUID_FAILED; -} - -#endif - - - -/*************************************************************** - * - * Sockets - * - */ - - -#if defined(MACINTOSH) -/* Not implemented */ - - -#elif defined(WIN32) - -#if 0 -typedef unsigned int socklen_t; - -#define fluid_socket_read(_S,_B,_L) recv(_S,_B,_L,0) -#define fluid_socket_write(_S,_B,_L) send(_S,_B,_L,0) - -void fluid_socket_close(fluid_socket_t sock) -{ - int r; - char buf[1024]; - if (sock != INVALID_SOCKET) { - shutdown(sock, 0x02); - while (1) { - r = recv(sock, buf, 1024, 0); - if ((r == 0) || (r == SOCKET_ERROR)) { - break; - } - } - closesocket(sock); - } -} -#endif - - -#else -#define fluid_socket_read(_S,_B,_L) read(_S,_B,_L) -#define fluid_socket_write(_S,_B,_L) write(_S,_B,_L) -#define SOCKET_ERROR -1 - -void fluid_socket_close(fluid_socket_t sock) -{ - if (sock != INVALID_SOCKET) { - close(sock); - } -} - -#endif - -#if !defined(MACINTOSH) && !defined(WIN32) && !defined(__BEOS__) && !defined(__HAIKU__) - - -fluid_istream_t fluid_socket_get_istream(fluid_socket_t sock) -{ - return sock; -} - -fluid_ostream_t fluid_socket_get_ostream(fluid_socket_t sock) -{ - return sock; -} - - - -struct _fluid_server_socket_t { - fluid_socket_t socket; - fluid_thread_t* thread; - int cont; - fluid_server_func_t func; - void* data; -}; - - -static void fluid_server_socket_run(void* data) -{ - fluid_server_socket_t* server_socket = (fluid_server_socket_t*) data; - fluid_socket_t client_socket; - struct sockaddr_in addr; - socklen_t addrlen = sizeof(addr); - - FLUID_LOG(FLUID_DBG, "Server listening for connections"); - - while (server_socket->cont) { - - client_socket = accept(server_socket->socket, (struct sockaddr*) &addr, &addrlen); - - FLUID_LOG(FLUID_DBG, "New client connection"); - - if (client_socket == INVALID_SOCKET) { - if (server_socket->cont) { - FLUID_LOG(FLUID_ERR, "Failed to accept connection"); - } - server_socket->cont = 0; - return; - } else { - int r; - r = (*server_socket->func)(server_socket->data, client_socket, inet_ntoa(addr.sin_addr)); - if (r != 0) { - fluid_socket_close(client_socket); - } - } - } - - FLUID_LOG(FLUID_DBG, "Server closing"); -} - -fluid_server_socket_t* -new_fluid_server_socket(int port, fluid_server_func_t func, void* data) -{ - fluid_server_socket_t* server_socket; - struct sockaddr_in addr; - fluid_socket_t sock; - - if (func == NULL) { - FLUID_LOG(FLUID_ERR, "Invalid callback function"); - return NULL; - } - - sock = socket(AF_INET, SOCK_STREAM, 0); - if (sock == INVALID_SOCKET) { - FLUID_LOG(FLUID_ERR, "Failed to create server socket"); - return NULL; - } - - FLUID_MEMSET((char *)&addr, 0, sizeof(struct sockaddr_in)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = htonl(INADDR_ANY); - addr.sin_port = htons(port); - - if (bind(sock, (const struct sockaddr *) &addr, sizeof(struct sockaddr_in)) == SOCKET_ERROR) { - FLUID_LOG(FLUID_ERR, "Failed to bind server socket"); - fluid_socket_close(sock); - return NULL; - } - - if (listen(sock, 10) == SOCKET_ERROR) { - FLUID_LOG(FLUID_ERR, "Failed listen on server socket"); - fluid_socket_close(sock); - return NULL; - } - - server_socket = FLUID_NEW(fluid_server_socket_t); - if (server_socket == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - fluid_socket_close(sock); - return NULL; - } - - server_socket->socket = sock; - server_socket->func = func; - server_socket->data = data; - server_socket->cont = 1; - - server_socket->thread = new_fluid_thread(fluid_server_socket_run, server_socket, 0); - if (server_socket->thread == NULL) { - FLUID_FREE(server_socket); - fluid_socket_close(sock); - return NULL; - } - - return server_socket; -} - -int delete_fluid_server_socket(fluid_server_socket_t* server_socket) -{ - server_socket->cont = 0; - if (server_socket->socket != INVALID_SOCKET) { - fluid_socket_close(server_socket->socket); - } - if (server_socket->thread) { - delete_fluid_thread(server_socket->thread); - } - FLUID_FREE(server_socket); - return FLUID_OK; -} - -int fluid_server_socket_join(fluid_server_socket_t* server_socket) -{ - return fluid_thread_join(server_socket->thread); -} - -#endif diff --git a/src/libs/fluidsynth/src/fluid_sys.h b/src/libs/fluidsynth/src/fluid_sys.h deleted file mode 100644 index 38b9b3b1bd..0000000000 --- a/src/libs/fluidsynth/src/fluid_sys.h +++ /dev/null @@ -1,320 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - - -/** - - This header contains a bunch of (mostly) system and machine - dependent functions: - - - timers - - current time in milliseconds and microseconds - - debug logging - - profiling - - memory locking - - checking for floating point exceptions - - */ - -#ifndef _FLUID_SYS_H -#define _FLUID_SYS_H - -#include "fluidsynth_priv.h" - - -void fluid_sys_config(void); -void fluid_log_config(void); -void fluid_time_config(void); - - -/* - * Utility functions - */ -char *fluid_strtok (char **str, char *delim); - - -/** - - Additional debugging system, separate from the log system. This - allows to print selected debug messages of a specific subsystem. - - */ - -extern unsigned int fluid_debug_flags; - -#if DEBUG - -enum fluid_debug_level { - FLUID_DBG_DRIVER = 1 -}; - -int fluid_debug(int level, char * fmt, ...); - -#else -#define fluid_debug -#endif - - -/** fluid_curtime() returns the current time in milliseconds. This time - should only be used in relative time measurements. */ - -/** fluid_utime() returns the time in micro seconds. this time should - only be used to measure duration (relative times). */ - -#if defined(WIN32) -#define fluid_curtime() GetTickCount() - -double fluid_utime(void); - -#elif defined(MACOS9) -#include -#include - -unsigned int fluid_curtime(); -#define fluid_utime() 0.0 - -#elif defined(__OS2__) -#define INCL_DOS -#include - -typedef int socklen_t; - -unsigned int fluid_curtime(void); -double fluid_utime(void); - -#elif (defined(__BEOS__) || defined(__HAIKU__)) - -#include -unsigned int fluid_curtime(void); -double fluid_utime(void); - -#else - -unsigned int fluid_curtime(void); -double fluid_utime(void); - -#endif - - - -/** - Timers - - */ - -/* if the callback function returns 1 the timer will continue; if it - returns 0 it will stop */ -typedef int (*fluid_timer_callback_t)(void* data, unsigned int msec); - -typedef struct _fluid_timer_t fluid_timer_t; - -fluid_timer_t* new_fluid_timer(int msec, fluid_timer_callback_t callback, - void* data, int new_thread, int auto_destroy); - -int delete_fluid_timer(fluid_timer_t* timer); -int fluid_timer_join(fluid_timer_t* timer); -int fluid_timer_stop(fluid_timer_t* timer); - -/** - - Muteces - -*/ - -#if defined(MACOS9) -typedef int fluid_mutex_t; -#define fluid_mutex_init(_m) { (_m) = 0; } -#define fluid_mutex_destroy(_m) -#define fluid_mutex_lock(_m) -#define fluid_mutex_unlock(_m) - -#elif defined(WIN32) -typedef HANDLE fluid_mutex_t; -#define fluid_mutex_init(_m) { (_m) = CreateMutex(NULL, 0, NULL); } -#define fluid_mutex_destroy(_m) if (_m) { CloseHandle(_m); } -#define fluid_mutex_lock(_m) WaitForSingleObject(_m, INFINITE) -#define fluid_mutex_unlock(_m) ReleaseMutex(_m) - -#elif defined(__OS2__) -typedef HMTX fluid_mutex_t; -#define fluid_mutex_init(_m) { (_m) = 0; DosCreateMutexSem( NULL, &(_m), 0, FALSE ); } -#define fluid_mutex_destroy(_m) if (_m) { DosCloseMutexSem(_m); } -#define fluid_mutex_lock(_m) DosRequestMutexSem(_m, -1L) -#define fluid_mutex_unlock(_m) DosReleaseMutexSem(_m) - -#else -typedef pthread_mutex_t fluid_mutex_t; -#define fluid_mutex_init(_m) pthread_mutex_init(&(_m), NULL) -#define fluid_mutex_destroy(_m) pthread_mutex_destroy(&(_m)) -#define fluid_mutex_lock(_m) pthread_mutex_lock(&(_m)) -#define fluid_mutex_unlock(_m) pthread_mutex_unlock(&(_m)) -#endif - - -/** - Threads - -*/ - -typedef struct _fluid_thread_t fluid_thread_t; -typedef void (*fluid_thread_func_t)(void* data); - -/** When detached, 'join' does not work and the thread destroys itself - when finished. */ -fluid_thread_t* new_fluid_thread(fluid_thread_func_t func, void* data, int detach); -int delete_fluid_thread(fluid_thread_t* thread); -int fluid_thread_join(fluid_thread_t* thread); - - -/** - Sockets - -*/ - - -/** The function should return 0 if no error occured, non-zero - otherwise. If the function return non-zero, the socket will be - closed by the server. */ -typedef int (*fluid_server_func_t)(void* data, fluid_socket_t client_socket, char* addr); - - -fluid_server_socket_t* new_fluid_server_socket(int port, fluid_server_func_t func, void* data); -int delete_fluid_server_socket(fluid_server_socket_t* sock); -int fluid_server_socket_join(fluid_server_socket_t* sock); - - -/** Create a new client socket. */ -fluid_socket_t new_fluid_client_socket(char* host, int port); - -/** Delete the client socket. This function should only be called on - sockets create with 'new_fluid_client_socket'. */ -void delete_fluid_client_socket(fluid_socket_t sock); - - -void fluid_socket_close(fluid_socket_t sock); -fluid_istream_t fluid_socket_get_istream(fluid_socket_t sock); -fluid_ostream_t fluid_socket_get_ostream(fluid_socket_t sock); - - - -/** - - Profiling - */ - - -/** - Profile numbers. List all the pieces of code you want to profile - here. Be sure to add an entry in the fluid_profile_data table in - fluid_sys.c -*/ -enum { - FLUID_PROF_WRITE_S16, - FLUID_PROF_ONE_BLOCK, - FLUID_PROF_ONE_BLOCK_CLEAR, - FLUID_PROF_ONE_BLOCK_VOICE, - FLUID_PROF_ONE_BLOCK_VOICES, - FLUID_PROF_ONE_BLOCK_REVERB, - FLUID_PROF_ONE_BLOCK_CHORUS, - FLUID_PROF_VOICE_NOTE, - FLUID_PROF_VOICE_RELEASE, - FLUID_PROF_LAST -}; - - -#if WITH_PROFILING - -void fluid_profiling_print(void); - - -/** Profiling data. Keep track of min/avg/max values to execute a - piece of code. */ -typedef struct _fluid_profile_data_t { - int num; - char* description; - double min, max, total; - unsigned int count; -} fluid_profile_data_t; - -extern fluid_profile_data_t fluid_profile_data[]; - -/** Macro to obtain a time refence used for the profiling */ -#define fluid_profile_ref() fluid_utime() - -/** Macro to calculate the min/avg/max. Needs a time refence and a - profile number. */ -#define fluid_profile(_num,_ref) { \ - double _now = fluid_utime(); \ - double _delta = _now - _ref; \ - fluid_profile_data[_num].min = _delta < fluid_profile_data[_num].min ? _delta : fluid_profile_data[_num].min; \ - fluid_profile_data[_num].max = _delta > fluid_profile_data[_num].max ? _delta : fluid_profile_data[_num].max; \ - fluid_profile_data[_num].total += _delta; \ - fluid_profile_data[_num].count++; \ - _ref = _now; \ -} - - -#else - -/* No profiling */ -#define fluid_profiling_print() -#define fluid_profile_ref() 0 -#define fluid_profile(_num,_ref) - -#endif - - - -/** - - Memory locking - - Memory locking is used to avoid swapping of the large block of - sample data. - */ - -#if defined(HAVE_SYS_MMAN_H) && !defined(__OS2__) -#define fluid_mlock(_p,_n) mlock(_p, _n) -#define fluid_munlock(_p,_n) munlock(_p,_n) -#else -#define fluid_mlock(_p,_n) 0 -#define fluid_munlock(_p,_n) -#endif - - -/** - - Floating point exceptions - - fluid_check_fpe() checks for "unnormalized numbers" and other - exceptions of the floating point processsor. -*/ -#ifdef FPE_CHECK -#define fluid_check_fpe(expl) fluid_check_fpe_i386(expl) -#define fluid_clear_fpe() fluid_clear_fpe_i386() -#else -#define fluid_check_fpe(expl) -#define fluid_clear_fpe() -#endif - -unsigned int fluid_check_fpe_i386(char * explanation_in_case_of_fpe); -void fluid_clear_fpe_i386(void); - -#endif /* _FLUID_SYS_H */ diff --git a/src/libs/fluidsynth/src/fluid_tuning.c b/src/libs/fluidsynth/src/fluid_tuning.c deleted file mode 100644 index 7a12e22832..0000000000 --- a/src/libs/fluidsynth/src/fluid_tuning.c +++ /dev/null @@ -1,108 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - - -#include "fluid_tuning.h" -#include "fluidsynth_priv.h" - - -fluid_tuning_t* new_fluid_tuning(char* name, int bank, int prog) -{ - fluid_tuning_t* tuning; - int i; - - tuning = FLUID_NEW(fluid_tuning_t); - if (tuning == NULL) { - FLUID_LOG(FLUID_PANIC, "Out of memory"); - return NULL; - } - - tuning->name = NULL; - - if (name != NULL) { - tuning->name = FLUID_STRDUP(name); - } - - tuning->bank = bank; - tuning->prog = prog; - - for (i = 0; i < 128; i++) { - tuning->pitch[i] = i * 100.0; - } - - return tuning; -} - -void delete_fluid_tuning(fluid_tuning_t* tuning) -{ - if (tuning == NULL) { - return; - } - if (tuning->name != NULL) { - FLUID_FREE(tuning->name); - } - FLUID_FREE(tuning); -} - -void fluid_tuning_set_name(fluid_tuning_t* tuning, char* name) -{ - if (tuning->name != NULL) { - FLUID_FREE(tuning->name); - tuning->name = NULL; - } - if (name != NULL) { - tuning->name = FLUID_STRDUP(name); - } -} - -char* fluid_tuning_get_name(fluid_tuning_t* tuning) -{ - return tuning->name; -} - -void fluid_tuning_set_key(fluid_tuning_t* tuning, int key, double pitch) -{ - tuning->pitch[key] = pitch; -} - -void fluid_tuning_set_octave(fluid_tuning_t* tuning, double* pitch_deriv) -{ - int i; - - for (i = 0; i < 128; i++) { - tuning->pitch[i] = i * 100.0 + pitch_deriv[i % 12]; - } -} - -void fluid_tuning_set_all(fluid_tuning_t* tuning, double* pitch) -{ - int i; - - for (i = 0; i < 128; i++) { - tuning->pitch[i] = pitch[i]; - } -} - -void fluid_tuning_set_pitch(fluid_tuning_t* tuning, int key, double pitch) -{ - if ((key >= 0) && (key < 128)) { - tuning->pitch[key] = pitch; - } -} diff --git a/src/libs/fluidsynth/src/fluid_tuning.h b/src/libs/fluidsynth/src/fluid_tuning.h deleted file mode 100644 index 4693f4ec34..0000000000 --- a/src/libs/fluidsynth/src/fluid_tuning.h +++ /dev/null @@ -1,64 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - - -/* - - More information about micro tuning can be found at: - - http://www.midi.org/about-midi/tuning.htm - http://www.midi.org/about-midi/tuning-scale.htm - http://www.midi.org/about-midi/tuning_extens.htm - -*/ - -#ifndef _FLUID_TUNING_H -#define _FLUID_TUNING_H - -#include "fluidsynth_priv.h" - -struct _fluid_tuning_t { - char* name; - int bank; - int prog; - double pitch[128]; /* the pitch of every key, in cents */ -}; - -fluid_tuning_t* new_fluid_tuning(char* name, int bank, int prog); -void delete_fluid_tuning(fluid_tuning_t* tuning); - -void fluid_tuning_set_name(fluid_tuning_t* tuning, char* name); -char* fluid_tuning_get_name(fluid_tuning_t* tuning); - -#define fluid_tuning_get_bank(_t) ((_t)->bank) -#define fluid_tuning_get_prog(_t) ((_t)->prog) - -void fluid_tuning_set_pitch(fluid_tuning_t* tuning, int key, double pitch); -#define fluid_tuning_get_pitch(_t, _key) ((_t)->pitch[_key]) - -void fluid_tuning_set_octave(fluid_tuning_t* tuning, double* pitch_deriv); - -void fluid_tuning_set_all(fluid_tuning_t* tuning, double* pitch); -#define fluid_tuning_get_all(_t) (&(_t)->pitch[0]) - - - - -#endif /* _FLUID_TUNING_H */ diff --git a/src/libs/fluidsynth/src/fluid_voice.c b/src/libs/fluidsynth/src/fluid_voice.c deleted file mode 100644 index 843aeacb74..0000000000 --- a/src/libs/fluidsynth/src/fluid_voice.c +++ /dev/null @@ -1,2017 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#include "fluidsynth_priv.h" -#include "fluid_voice.h" -#include "fluid_mod.h" -#include "fluid_chan.h" -#include "fluid_conv.h" -#include "fluid_synth.h" -#include "fluid_sys.h" -#include "fluid_sfont.h" - -/* used for filter turn off optimization - if filter cutoff is above the - specified value and filter q is below the other value, turn filter off */ -#define FLUID_MAX_AUDIBLE_FILTER_FC 19000.0f -#define FLUID_MIN_AUDIBLE_FILTER_Q 1.2f - -/* Smallest amplitude that can be perceived (full scale is +/- 0.5) - * 16 bits => 96+4=100 dB dynamic range => 0.00001 - * 0.00001 * 2 is approximately 0.00003 :) - */ -#define FLUID_NOISE_FLOOR 0.00003 - -/* these should be the absolute minimum that FluidSynth can deal with */ -#define FLUID_MIN_LOOP_SIZE 2 -#define FLUID_MIN_LOOP_PAD 0 - -/* min vol envelope release (to stop clicks) in SoundFont timecents */ -#define FLUID_MIN_VOLENVRELEASE -7200.0f /* ~16ms */ - - -static inline void fluid_voice_effects (fluid_voice_t *voice, int count, - fluid_real_t* dsp_left_buf, - fluid_real_t* dsp_right_buf, - fluid_real_t* dsp_reverb_buf, - fluid_real_t* dsp_chorus_buf); -/* - * new_fluid_voice - */ -fluid_voice_t* -new_fluid_voice(fluid_real_t output_rate) -{ - fluid_voice_t* voice; - voice = FLUID_NEW(fluid_voice_t); - if (voice == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - voice->status = FLUID_VOICE_CLEAN; - voice->chan = NO_CHANNEL; - voice->key = 0; - voice->vel = 0; - voice->channel = NULL; - voice->sample = NULL; - voice->output_rate = output_rate; - - /* The 'sustain' and 'finished' segments of the volume / modulation - * envelope are constant. They are never affected by any modulator - * or generator. Therefore it is enough to initialize them once - * during the lifetime of the synth. - */ - voice->volenv_data[FLUID_VOICE_ENVSUSTAIN].count = 0xffffffff; - voice->volenv_data[FLUID_VOICE_ENVSUSTAIN].coeff = 1.0f; - voice->volenv_data[FLUID_VOICE_ENVSUSTAIN].incr = 0.0f; - voice->volenv_data[FLUID_VOICE_ENVSUSTAIN].min = -1.0f; - voice->volenv_data[FLUID_VOICE_ENVSUSTAIN].max = 2.0f; - - voice->volenv_data[FLUID_VOICE_ENVFINISHED].count = 0xffffffff; - voice->volenv_data[FLUID_VOICE_ENVFINISHED].coeff = 0.0f; - voice->volenv_data[FLUID_VOICE_ENVFINISHED].incr = 0.0f; - voice->volenv_data[FLUID_VOICE_ENVFINISHED].min = -1.0f; - voice->volenv_data[FLUID_VOICE_ENVFINISHED].max = 1.0f; - - voice->modenv_data[FLUID_VOICE_ENVSUSTAIN].count = 0xffffffff; - voice->modenv_data[FLUID_VOICE_ENVSUSTAIN].coeff = 1.0f; - voice->modenv_data[FLUID_VOICE_ENVSUSTAIN].incr = 0.0f; - voice->modenv_data[FLUID_VOICE_ENVSUSTAIN].min = -1.0f; - voice->modenv_data[FLUID_VOICE_ENVSUSTAIN].max = 2.0f; - - voice->modenv_data[FLUID_VOICE_ENVFINISHED].count = 0xffffffff; - voice->modenv_data[FLUID_VOICE_ENVFINISHED].coeff = 0.0f; - voice->modenv_data[FLUID_VOICE_ENVFINISHED].incr = 0.0f; - voice->modenv_data[FLUID_VOICE_ENVFINISHED].min = -1.0f; - voice->modenv_data[FLUID_VOICE_ENVFINISHED].max = 1.0f; - - return voice; -} - -/* - * delete_fluid_voice - */ -int -delete_fluid_voice(fluid_voice_t* voice) -{ - if (voice == NULL) { - return FLUID_OK; - } - FLUID_FREE(voice); - return FLUID_OK; -} - -/* fluid_voice_init - * - * Initialize the synthesis process - */ -int -fluid_voice_init(fluid_voice_t* voice, fluid_sample_t* sample, - fluid_channel_t* channel, int key, int vel, unsigned int id, - unsigned int start_time, fluid_real_t gain) -{ - /* Note: The voice parameters will be initialized later, when the - * generators have been retrieved from the sound font. Here, only - * the 'working memory' of the voice (position in envelopes, history - * of IIR filters, position in sample etc) is initialized. */ - - - voice->id = id; - voice->chan = fluid_channel_get_num(channel); - voice->key = (unsigned char) key; - voice->vel = (unsigned char) vel; - voice->channel = channel; - voice->mod_count = 0; - voice->sample = sample; - voice->start_time = start_time; - voice->ticks = 0; - voice->debug = 0; - voice->has_looped = 0; /* Will be set during voice_write when the 2nd loop point is reached */ - voice->last_fres = -1; /* The filter coefficients have to be calculated later in the DSP loop. */ - voice->filter_startup = 1; /* Set the filter immediately, don't fade between old and new settings */ - voice->interp_method = fluid_channel_get_interp_method(voice->channel); - - /* vol env initialization */ - voice->volenv_count = 0; - voice->volenv_section = 0; - voice->volenv_val = 0.0f; - voice->amp = 0.0f; /* The last value of the volume envelope, used to - calculate the volume increment during - processing */ - - /* mod env initialization*/ - voice->modenv_count = 0; - voice->modenv_section = 0; - voice->modenv_val = 0.0f; - - /* mod lfo */ - voice->modlfo_val = 0.0;/* Fixme: Retrieve from any other existing - voice on this channel to keep LFOs in - unison? */ - - /* vib lfo */ - voice->viblfo_val = 0.0f; /* Fixme: See mod lfo */ - - /* Clear sample history in filter */ - voice->hist1 = 0; - voice->hist2 = 0; - - /* Set all the generators to their default value, according to SF - * 2.01 section 8.1.3 (page 48). The value of NRPN messages are - * copied from the channel to the voice's generators. The sound font - * loader overwrites them. The generator values are later converted - * into voice parameters in - * fluid_voice_calculate_runtime_synthesis_parameters. */ - fluid_gen_init(&voice->gen[0], channel); - - voice->synth_gain = gain; - /* avoid division by zero later*/ - if (voice->synth_gain < 0.0000001){ - voice->synth_gain = 0.0000001; - } - - /* For a looped sample, this value will be overwritten as soon as the - * loop parameters are initialized (they may depend on modulators). - * This value can be kept, it is a worst-case estimate. - */ - - voice->amplitude_that_reaches_noise_floor_nonloop = FLUID_NOISE_FLOOR / voice->synth_gain; - voice->amplitude_that_reaches_noise_floor_loop = FLUID_NOISE_FLOOR / voice->synth_gain; - - /* Increment the reference count of the sample to prevent the - unloading of the soundfont while this voice is playing. */ - fluid_sample_incr_ref(voice->sample); - - return FLUID_OK; -} - -void fluid_voice_gen_set(fluid_voice_t* voice, int i, float val) -{ - voice->gen[i].val = val; - voice->gen[i].flags = GEN_SET; -} - -void fluid_voice_gen_incr(fluid_voice_t* voice, int i, float val) -{ - voice->gen[i].val += val; - voice->gen[i].flags = GEN_SET; -} - -float fluid_voice_gen_get(fluid_voice_t* voice, int gen) -{ - return voice->gen[gen].val; -} - -fluid_real_t fluid_voice_gen_value(fluid_voice_t* voice, int num) -{ - /* This is an extension to the SoundFont standard. More - * documentation is available at the fluid_synth_set_gen2() - * function. */ - if (voice->gen[num].flags == GEN_ABS_NRPN) { - return (fluid_real_t) voice->gen[num].nrpn; - } else { - return (fluid_real_t) (voice->gen[num].val + voice->gen[num].mod + voice->gen[num].nrpn); - } -} - - -/* - * fluid_voice_write - * - * This is where it all happens. This function is called by the - * synthesizer to generate the sound samples. The synthesizer passes - * four audio buffers: left, right, reverb out, and chorus out. - * - * The biggest part of this function sets the correct values for all - * the dsp parameters (all the control data boil down to only a few - * dsp parameters). The dsp routine is #included in several places (fluid_dsp_core.c). - */ -int -fluid_voice_write(fluid_voice_t* voice, - fluid_real_t* dsp_left_buf, fluid_real_t* dsp_right_buf, - fluid_real_t* dsp_reverb_buf, fluid_real_t* dsp_chorus_buf) -{ - unsigned int i; - fluid_real_t incr; - fluid_real_t fres; - fluid_real_t target_amp; /* target amplitude */ - int count; - - int dsp_interp_method = voice->interp_method; - - fluid_real_t dsp_buf[FLUID_BUFSIZE]; - fluid_env_data_t* env_data; - fluid_real_t x; - - - /* make sure we're playing and that we have sample data */ - if (!_PLAYING(voice)) return FLUID_OK; - - /******************* sample **********************/ - - if (voice->sample == NULL) - { - fluid_voice_off(voice); - return FLUID_OK; - } - - fluid_check_fpe ("voice_write startup"); - - /* Range checking for sample- and loop-related parameters - * Initial phase is calculated here*/ - fluid_voice_check_sample_sanity (voice); - - /******************* vol env **********************/ - - env_data = &voice->volenv_data[voice->volenv_section]; - - /* skip to the next section of the envelope if necessary */ - while (voice->volenv_count >= env_data->count) - { - // If we're switching envelope stages from decay to sustain, force the value to be the end value of the previous stage - if (env_data && voice->volenv_section == FLUID_VOICE_ENVDECAY) - voice->volenv_val = env_data->min * env_data->coeff; - - env_data = &voice->volenv_data[++voice->volenv_section]; - voice->volenv_count = 0; - } - - /* calculate the envelope value and check for valid range */ - x = env_data->coeff * voice->volenv_val + env_data->incr; - if (x < env_data->min) - { - x = env_data->min; - voice->volenv_section++; - voice->volenv_count = 0; - } - else if (x > env_data->max) - { - x = env_data->max; - voice->volenv_section++; - voice->volenv_count = 0; - } - - voice->volenv_val = x; - voice->volenv_count++; - - if (voice->volenv_section == FLUID_VOICE_ENVFINISHED) - { - fluid_profile (FLUID_PROF_VOICE_RELEASE, voice->ref); - fluid_voice_off (voice); - return FLUID_OK; - } - - fluid_check_fpe ("voice_write vol env"); - - /******************* mod env **********************/ - - env_data = &voice->modenv_data[voice->modenv_section]; - - /* skip to the next section of the envelope if necessary */ - while (voice->modenv_count >= env_data->count) - { - env_data = &voice->modenv_data[++voice->modenv_section]; - voice->modenv_count = 0; - } - - /* calculate the envelope value and check for valid range */ - x = env_data->coeff * voice->modenv_val + env_data->incr; - - if (x < env_data->min) - { - x = env_data->min; - voice->modenv_section++; - voice->modenv_count = 0; - } - else if (x > env_data->max) - { - x = env_data->max; - voice->modenv_section++; - voice->modenv_count = 0; - } - - voice->modenv_val = x; - voice->modenv_count++; - fluid_check_fpe ("voice_write mod env"); - - /******************* mod lfo **********************/ - - if (voice->ticks >= voice->modlfo_delay) - { - voice->modlfo_val += voice->modlfo_incr; - - if (voice->modlfo_val > 1.0) - { - voice->modlfo_incr = -voice->modlfo_incr; - voice->modlfo_val = (fluid_real_t) 2.0 - voice->modlfo_val; - } - else if (voice->modlfo_val < -1.0) - { - voice->modlfo_incr = -voice->modlfo_incr; - voice->modlfo_val = (fluid_real_t) -2.0 - voice->modlfo_val; - } - } - - fluid_check_fpe ("voice_write mod LFO"); - - /******************* vib lfo **********************/ - - if (voice->ticks >= voice->viblfo_delay) - { - voice->viblfo_val += voice->viblfo_incr; - - if (voice->viblfo_val > (fluid_real_t) 1.0) - { - voice->viblfo_incr = -voice->viblfo_incr; - voice->viblfo_val = (fluid_real_t) 2.0 - voice->viblfo_val; - } - else if (voice->viblfo_val < -1.0) - { - voice->viblfo_incr = -voice->viblfo_incr; - voice->viblfo_val = (fluid_real_t) -2.0 - voice->viblfo_val; - } - } - - fluid_check_fpe ("voice_write Vib LFO"); - - /******************* amplitude **********************/ - - /* calculate final amplitude - * - initial gain - * - amplitude envelope - */ - - if (voice->volenv_section == FLUID_VOICE_ENVDELAY) - goto post_process; /* The volume amplitude is in hold phase. No sound is produced. */ - - if (voice->volenv_section == FLUID_VOICE_ENVATTACK) - { - /* the envelope is in the attack section: ramp linearly to max value. - * A positive modlfo_to_vol should increase volume (negative attenuation). - */ - target_amp = fluid_atten2amp (voice->attenuation) - * fluid_cb2amp (voice->modlfo_val * -voice->modlfo_to_vol) - * voice->volenv_val; - } - else - { - fluid_real_t amplitude_that_reaches_noise_floor; - fluid_real_t amp_max; - - target_amp = fluid_atten2amp (voice->attenuation) - * fluid_cb2amp (960.0f * (1.0f - voice->volenv_val) - + voice->modlfo_val * -voice->modlfo_to_vol); - - /* We turn off a voice, if the volume has dropped low enough. */ - - /* A voice can be turned off, when an estimate for the volume - * (upper bound) falls below that volume, that will drop the - * sample below the noise floor. - */ - - /* If the loop amplitude is known, we can use it if the voice loop is within - * the sample loop - */ - - /* Is the playing pointer already in the loop? */ - if (voice->has_looped) - amplitude_that_reaches_noise_floor = voice->amplitude_that_reaches_noise_floor_loop; - else - amplitude_that_reaches_noise_floor = voice->amplitude_that_reaches_noise_floor_nonloop; - - /* voice->attenuation_min is a lower boundary for the attenuation - * now and in the future (possibly 0 in the worst case). Now the - * amplitude of sample and volenv cannot exceed amp_max (since - * volenv_val can only drop): - */ - - amp_max = fluid_atten2amp (voice->min_attenuation_cB) * voice->volenv_val; - - /* And if amp_max is already smaller than the known amplitude, - * which will attenuate the sample below the noise floor, then we - * can safely turn off the voice. Duh. */ - if (amp_max < amplitude_that_reaches_noise_floor) - { - fluid_profile (FLUID_PROF_VOICE_RELEASE, voice->ref); - fluid_voice_off (voice); - goto post_process; - } - } - - /* Volume increment to go from voice->amp to target_amp in FLUID_BUFSIZE steps */ - voice->amp_incr = (target_amp - voice->amp) / FLUID_BUFSIZE; - - fluid_check_fpe ("voice_write amplitude calculation"); - - /* no volume and not changing? - No need to process */ - if ((voice->amp == 0.0f) && (voice->amp_incr == 0.0f)) - goto post_process; - - /* Calculate the number of samples, that the DSP loop advances - * through the original waveform with each step in the output - * buffer. It is the ratio between the frequencies of original - * waveform and output waveform.*/ - voice->phase_incr = fluid_ct2hz_real - (voice->pitch + voice->modlfo_val * voice->modlfo_to_pitch - + voice->viblfo_val * voice->viblfo_to_pitch - + voice->modenv_val * voice->modenv_to_pitch) / voice->root_pitch; - - fluid_check_fpe ("voice_write phase calculation"); - - /* if phase_incr is not advancing, set it to the minimum fraction value (prevent stuckage) */ - if (voice->phase_incr == 0) voice->phase_incr = 1; - - /*************** resonant filter ******************/ - - /* calculate the frequency of the resonant filter in Hz */ - fres = fluid_ct2hz(voice->fres - + voice->modlfo_val * voice->modlfo_to_fc - + voice->modenv_val * voice->modenv_to_fc); - - /* FIXME - Still potential for a click during turn on, can we interpolate - between 20khz cutoff and 0 Q? */ - - /* I removed the optimization of turning the filter off when the - * resonance frequence is above the maximum frequency. Instead, the - * filter frequency is set to a maximum of 0.45 times the sampling - * rate. For a 44100 kHz sampling rate, this amounts to 19845 - * Hz. The reason is that there were problems with anti-aliasing when the - * synthesizer was run at lower sampling rates. Thanks to Stephan - * Tassart for pointing me to this bug. By turning the filter on and - * clipping the maximum filter frequency at 0.45*srate, the filter - * is used as an anti-aliasing filter. */ - - if (fres > 0.45f * voice->output_rate) - fres = 0.45f * voice->output_rate; - else if (fres < 5) - fres = 5; - - /* if filter enabled and there is a significant frequency change.. */ - if ((abs (fres - voice->last_fres) > 0.01)) - { - /* The filter coefficients have to be recalculated (filter - * parameters have changed). Recalculation for various reasons is - * forced by setting last_fres to -1. The flag filter_startup - * indicates, that the DSP loop runs for the first time, in this - * case, the filter is set directly, instead of smoothly fading - * between old and new settings. - * - * Those equations from Robert Bristow-Johnson's `Cookbook - * formulae for audio EQ biquad filter coefficients', obtained - * from Harmony-central.com / Computer / Programming. They are - * the result of the bilinear transform on an analogue filter - * prototype. To quote, `BLT frequency warping has been taken - * into account for both significant frequency relocation and for - * bandwidth readjustment'. */ - - fluid_real_t omega = (fluid_real_t) (2.0 * M_PI * (fres / ((float) voice->output_rate))); - fluid_real_t sin_coeff = (fluid_real_t) sin(omega); - fluid_real_t cos_coeff = (fluid_real_t) cos(omega); - fluid_real_t alpha_coeff = sin_coeff / (2.0f * voice->q_lin); - fluid_real_t a0_inv = 1.0f / (1.0f + alpha_coeff); - - /* Calculate the filter coefficients. All coefficients are - * normalized by a0. Think of `a1' as `a1/a0'. - * - * Here a couple of multiplications are saved by reusing common expressions. - * The original equations should be: - * voice->b0=(1.-cos_coeff)*a0_inv*0.5*voice->filter_gain; - * voice->b1=(1.-cos_coeff)*a0_inv*voice->filter_gain; - * voice->b2=(1.-cos_coeff)*a0_inv*0.5*voice->filter_gain; */ - - fluid_real_t a1_temp = -2.0f * cos_coeff * a0_inv; - fluid_real_t a2_temp = (1.0f - alpha_coeff) * a0_inv; - fluid_real_t b1_temp = (1.0f - cos_coeff) * a0_inv * voice->filter_gain; - /* both b0 -and- b2 */ - fluid_real_t b02_temp = b1_temp * 0.5f; - - if (voice->filter_startup) - { - /* The filter is calculated, because the voice was started up. - * In this case set the filter coefficients without delay. - */ - voice->a1 = a1_temp; - voice->a2 = a2_temp; - voice->b02 = b02_temp; - voice->b1 = b1_temp; - voice->filter_coeff_incr_count = 0; - voice->filter_startup = 0; -// printf("Setting initial filter coefficients.\n"); - } - else - { - - /* The filter frequency is changed. Calculate an increment - * factor, so that the new setting is reached after one buffer - * length. x_incr is added to the current value FLUID_BUFSIZE - * times. The length is arbitrarily chosen. Longer than one - * buffer will sacrifice some performance, though. Note: If - * the filter is still too 'grainy', then increase this number - * at will. - */ - -#define FILTER_TRANSITION_SAMPLES (FLUID_BUFSIZE) - - voice->a1_incr = (a1_temp - voice->a1) / FILTER_TRANSITION_SAMPLES; - voice->a2_incr = (a2_temp - voice->a2) / FILTER_TRANSITION_SAMPLES; - voice->b02_incr = (b02_temp - voice->b02) / FILTER_TRANSITION_SAMPLES; - voice->b1_incr = (b1_temp - voice->b1) / FILTER_TRANSITION_SAMPLES; - /* Have to add the increments filter_coeff_incr_count times. */ - voice->filter_coeff_incr_count = FILTER_TRANSITION_SAMPLES; - } - voice->last_fres = fres; - fluid_check_fpe ("voice_write filter calculation"); - } - - - fluid_check_fpe ("voice_write DSP coefficients"); - - /*********************** run the dsp chain ************************ - * The sample is mixed with the output buffer. - * The buffer has to be filled from 0 to FLUID_BUFSIZE-1. - * Depending on the position in the loop and the loop size, this - * may require several runs. */ - - voice->dsp_buf = dsp_buf; - - switch (voice->interp_method) - { - case FLUID_INTERP_NONE: - count = fluid_dsp_float_interpolate_none (voice); - break; - case FLUID_INTERP_LINEAR: - count = fluid_dsp_float_interpolate_linear (voice); - break; - case FLUID_INTERP_4THORDER: - default: - count = fluid_dsp_float_interpolate_4th_order (voice); - break; - case FLUID_INTERP_7THORDER: - count = fluid_dsp_float_interpolate_7th_order (voice); - break; - } - - fluid_check_fpe ("voice_write interpolation"); - - if (count > 0) - fluid_voice_effects (voice, count, dsp_left_buf, dsp_right_buf, - dsp_reverb_buf, dsp_chorus_buf); - - /* turn off voice if short count (sample ended and not looping) */ - if (count < FLUID_BUFSIZE) - { - fluid_profile(FLUID_PROF_VOICE_RELEASE, voice->ref); - fluid_voice_off(voice); - } - - post_process: - voice->ticks += FLUID_BUFSIZE; - fluid_check_fpe ("voice_write postprocess"); - return FLUID_OK; -} - - -/* Purpose: - * - * - filters (applies a lowpass filter with variable cutoff frequency and quality factor) - * - mixes the processed sample to left and right output using the pan setting - * - sends the processed sample to chorus and reverb - * - * Variable description: - * - dsp_data: Pointer to the original waveform data - * - dsp_left_buf: The generated signal goes here, left channel - * - dsp_right_buf: right channel - * - dsp_reverb_buf: Send to reverb unit - * - dsp_chorus_buf: Send to chorus unit - * - dsp_a1: Coefficient for the filter - * - dsp_a2: same - * - dsp_b0: same - * - dsp_b1: same - * - dsp_b2: same - * - voice holds the voice structure - * - * A couple of variables are used internally, their results are discarded: - * - dsp_i: Index through the output buffer - * - dsp_phase_fractional: The fractional part of dsp_phase - * - dsp_coeff: A table of four coefficients, depending on the fractional phase. - * Used to interpolate between samples. - * - dsp_process_buffer: Holds the processed signal between stages - * - dsp_centernode: delay line for the IIR filter - * - dsp_hist1: same - * - dsp_hist2: same - * - */ -static inline void -fluid_voice_effects (fluid_voice_t *voice, int count, - fluid_real_t* dsp_left_buf, fluid_real_t* dsp_right_buf, - fluid_real_t* dsp_reverb_buf, fluid_real_t* dsp_chorus_buf) -{ - /* IIR filter sample history */ - fluid_real_t dsp_hist1 = voice->hist1; - fluid_real_t dsp_hist2 = voice->hist2; - - /* IIR filter coefficients */ - fluid_real_t dsp_a1 = voice->a1; - fluid_real_t dsp_a2 = voice->a2; - fluid_real_t dsp_b02 = voice->b02; - fluid_real_t dsp_b1 = voice->b1; - fluid_real_t dsp_a1_incr = voice->a1_incr; - fluid_real_t dsp_a2_incr = voice->a2_incr; - fluid_real_t dsp_b02_incr = voice->b02_incr; - fluid_real_t dsp_b1_incr = voice->b1_incr; - int dsp_filter_coeff_incr_count = voice->filter_coeff_incr_count; - - fluid_real_t *dsp_buf = voice->dsp_buf; - - fluid_real_t dsp_centernode; - int dsp_i; - float v; - - /* filter (implement the voice filter according to SoundFont standard) */ - - /* Check for denormal number (too close to zero). */ - if (fabs (dsp_hist1) < 1e-20) dsp_hist1 = 0.0f; /* FIXME JMG - Is this even needed? */ - - /* Two versions of the filter loop. One, while the filter is - * changing towards its new setting. The other, if the filter - * doesn't change. - */ - - if (dsp_filter_coeff_incr_count > 0) - { - /* Increment is added to each filter coefficient filter_coeff_incr_count times. */ - for (dsp_i = 0; dsp_i < count; dsp_i++) - { - /* The filter is implemented in Direct-II form. */ - dsp_centernode = dsp_buf[dsp_i] - dsp_a1 * dsp_hist1 - dsp_a2 * dsp_hist2; - dsp_buf[dsp_i] = dsp_b02 * (dsp_centernode + dsp_hist2) + dsp_b1 * dsp_hist1; - dsp_hist2 = dsp_hist1; - dsp_hist1 = dsp_centernode; - - if (dsp_filter_coeff_incr_count-- > 0) - { - dsp_a1 += dsp_a1_incr; - dsp_a2 += dsp_a2_incr; - dsp_b02 += dsp_b02_incr; - dsp_b1 += dsp_b1_incr; - } - } /* for dsp_i */ - } - else /* The filter parameters are constant. This is duplicated to save time. */ - { - for (dsp_i = 0; dsp_i < count; dsp_i++) - { /* The filter is implemented in Direct-II form. */ - dsp_centernode = dsp_buf[dsp_i] - dsp_a1 * dsp_hist1 - dsp_a2 * dsp_hist2; - dsp_buf[dsp_i] = dsp_b02 * (dsp_centernode + dsp_hist2) + dsp_b1 * dsp_hist1; - dsp_hist2 = dsp_hist1; - dsp_hist1 = dsp_centernode; - } - } - - /* pan (Copy the signal to the left and right output buffer) The voice - * panning generator has a range of -500 .. 500. If it is centered, - * it's close to 0. voice->amp_left and voice->amp_right are then the - * same, and we can save one multiplication per voice and sample. - */ - if ((-0.5 < voice->pan) && (voice->pan < 0.5)) - { - /* The voice is centered. Use voice->amp_left twice. */ - for (dsp_i = 0; dsp_i < count; dsp_i++) - { - v = voice->amp_left * dsp_buf[dsp_i]; - dsp_left_buf[dsp_i] += v; - dsp_right_buf[dsp_i] += v; - } - } - else /* The voice is not centered. Stereo samples have one side zero. */ - { - if (voice->amp_left != 0.0) - { - for (dsp_i = 0; dsp_i < count; dsp_i++) - dsp_left_buf[dsp_i] += voice->amp_left * dsp_buf[dsp_i]; - } - - if (voice->amp_right != 0.0) - { - for (dsp_i = 0; dsp_i < count; dsp_i++) - dsp_right_buf[dsp_i] += voice->amp_right * dsp_buf[dsp_i]; - } - } - - /* reverb send. Buffer may be NULL. */ - if ((dsp_reverb_buf != NULL) && (voice->amp_reverb != 0.0)) - { - for (dsp_i = 0; dsp_i < count; dsp_i++) - dsp_reverb_buf[dsp_i] += voice->amp_reverb * dsp_buf[dsp_i]; - } - - /* chorus send. Buffer may be NULL. */ - if ((dsp_chorus_buf != NULL) && (voice->amp_chorus != 0)) - { - for (dsp_i = 0; dsp_i < count; dsp_i++) - dsp_chorus_buf[dsp_i] += voice->amp_chorus * dsp_buf[dsp_i]; - } - - voice->hist1 = dsp_hist1; - voice->hist2 = dsp_hist2; - voice->a1 = dsp_a1; - voice->a2 = dsp_a2; - voice->b02 = dsp_b02; - voice->b1 = dsp_b1; - voice->filter_coeff_incr_count = dsp_filter_coeff_incr_count; - - fluid_check_fpe ("voice_effects"); -} - -/* - * fluid_voice_get_channel - */ -fluid_channel_t* -fluid_voice_get_channel(fluid_voice_t* voice) -{ - return voice->channel; -} - -/* - * fluid_voice_start - */ -void fluid_voice_start(fluid_voice_t* voice) -{ - /* The maximum volume of the loop is calculated and cached once for each - * sample with its nominal loop settings. This happens, when the sample is used - * for the first time.*/ - - fluid_voice_calculate_runtime_synthesis_parameters(voice); - - /* Force setting of the phase at the first DSP loop run - * This cannot be done earlier, because it depends on modulators.*/ - voice->check_sample_sanity_flag=FLUID_SAMPLESANITY_STARTUP; - - voice->ref = fluid_profile_ref(); - - voice->status = FLUID_VOICE_ON; -} - -/* - * fluid_voice_calculate_runtime_synthesis_parameters - * - * in this function we calculate the values of all the parameters. the - * parameters are converted to their most useful unit for the DSP - * algorithm, for example, number of samples instead of - * timecents. Some parameters keep their "perceptual" unit and - * conversion will be done in the DSP function. This is the case, for - * example, for the pitch since it is modulated by the controllers in - * cents. */ -int -fluid_voice_calculate_runtime_synthesis_parameters(fluid_voice_t* voice) -{ - fluid_real_t x; - fluid_real_t q_db; - int i; - - int list_of_generators_to_initialize[35] = { - GEN_STARTADDROFS, /* SF2.01 page 48 #0 */ - GEN_ENDADDROFS, /* #1 */ - GEN_STARTLOOPADDROFS, /* #2 */ - GEN_ENDLOOPADDROFS, /* #3 */ - /* GEN_STARTADDRCOARSEOFS see comment below [1] #4 */ - GEN_MODLFOTOPITCH, /* #5 */ - GEN_VIBLFOTOPITCH, /* #6 */ - GEN_MODENVTOPITCH, /* #7 */ - GEN_FILTERFC, /* #8 */ - GEN_FILTERQ, /* #9 */ - GEN_MODLFOTOFILTERFC, /* #10 */ - GEN_MODENVTOFILTERFC, /* #11 */ - /* GEN_ENDADDRCOARSEOFS [1] #12 */ - GEN_MODLFOTOVOL, /* #13 */ - /* not defined #14 */ - GEN_CHORUSSEND, /* #15 */ - GEN_REVERBSEND, /* #16 */ - GEN_PAN, /* #17 */ - /* not defined #18 */ - /* not defined #19 */ - /* not defined #20 */ - GEN_MODLFODELAY, /* #21 */ - GEN_MODLFOFREQ, /* #22 */ - GEN_VIBLFODELAY, /* #23 */ - GEN_VIBLFOFREQ, /* #24 */ - GEN_MODENVDELAY, /* #25 */ - GEN_MODENVATTACK, /* #26 */ - GEN_MODENVHOLD, /* #27 */ - GEN_MODENVDECAY, /* #28 */ - /* GEN_MODENVSUSTAIN [1] #29 */ - GEN_MODENVRELEASE, /* #30 */ - /* GEN_KEYTOMODENVHOLD [1] #31 */ - /* GEN_KEYTOMODENVDECAY [1] #32 */ - GEN_VOLENVDELAY, /* #33 */ - GEN_VOLENVATTACK, /* #34 */ - GEN_VOLENVHOLD, /* #35 */ - GEN_VOLENVDECAY, /* #36 */ - /* GEN_VOLENVSUSTAIN [1] #37 */ - GEN_VOLENVRELEASE, /* #38 */ - /* GEN_KEYTOVOLENVHOLD [1] #39 */ - /* GEN_KEYTOVOLENVDECAY [1] #40 */ - /* GEN_STARTLOOPADDRCOARSEOFS [1] #45 */ - GEN_KEYNUM, /* #46 */ - GEN_VELOCITY, /* #47 */ - GEN_ATTENUATION, /* #48 */ - /* GEN_ENDLOOPADDRCOARSEOFS [1] #50 */ - /* GEN_COARSETUNE [1] #51 */ - /* GEN_FINETUNE [1] #52 */ - GEN_OVERRIDEROOTKEY, /* #58 */ - GEN_PITCH, /* --- */ - -1}; /* end-of-list marker */ - - /* When the voice is made ready for the synthesis process, a lot of - * voice-internal parameters have to be calculated. - * - * At this point, the sound font has already set the -nominal- value - * for all generators (excluding GEN_PITCH). Most generators can be - * modulated - they include a nominal value and an offset (which - * changes with velocity, note number, channel parameters like - * aftertouch, mod wheel...) Now this offset will be calculated as - * follows: - * - * - Process each modulator once. - * - Calculate its output value. - * - Find the target generator. - * - Add the output value to the modulation value of the generator. - * - * Note: The generators have been initialized with - * fluid_gen_set_default_values. - */ - - for (i = 0; i < voice->mod_count; i++) { - fluid_mod_t* mod = &voice->mod[i]; - fluid_real_t modval = fluid_mod_get_value(mod, voice->channel, voice); - int dest_gen_index = mod->dest; - fluid_gen_t* dest_gen = &voice->gen[dest_gen_index]; - dest_gen->mod += modval; - /* fluid_dump_modulator(mod); */ - } - - /* The GEN_PITCH is a hack to fit the pitch bend controller into the - * modulator paradigm. Now the nominal pitch of the key is set. - * Note about SCALETUNE: SF2.01 8.1.3 says, that this generator is a - * non-realtime parameter. So we don't allow modulation (as opposed - * to _GEN(voice, GEN_SCALETUNE) When the scale tuning is varied, - * one key remains fixed. Here C3 (MIDI number 60) is used. - */ - if (fluid_channel_has_tuning(voice->channel)) { - /* pitch(60) + scale * (pitch(key) - pitch(60)) */ - #define __pitch(_k) fluid_tuning_get_pitch(tuning, _k) - fluid_tuning_t* tuning = fluid_channel_get_tuning(voice->channel); - voice->gen[GEN_PITCH].val = (__pitch(60) + (voice->gen[GEN_SCALETUNE].val / 100.0f * - (__pitch(voice->key) - __pitch(60)))); - } else { - voice->gen[GEN_PITCH].val = (voice->gen[GEN_SCALETUNE].val * (voice->key - 60.0f) - + 100.0f * 60.0f); - } - - /* Now the generators are initialized, nominal and modulation value. - * The voice parameters (which depend on generators) are calculated - * with fluid_voice_update_param. Processing the list of generator - * changes will calculate each voice parameter once. - * - * Note [1]: Some voice parameters depend on several generators. For - * example, the pitch depends on GEN_COARSETUNE, GEN_FINETUNE and - * GEN_PITCH. voice->pitch. Unnecessary recalculation is avoided - * by removing all but one generator from the list of voice - * parameters. Same with GEN_XXX and GEN_XXXCOARSE: the - * initialisation list contains only GEN_XXX. - */ - - /* Calculate the voice parameter(s) dependent on each generator. */ - for (i = 0; list_of_generators_to_initialize[i] != -1; i++) { - fluid_voice_update_param(voice, list_of_generators_to_initialize[i]); - } - - /* Make an estimate on how loud this voice can get at any time (attenuation). */ - voice->min_attenuation_cB = fluid_voice_get_lower_boundary_for_attenuation(voice); - - return FLUID_OK; -} - -/* - * calculate_hold_decay_buffers - */ -int calculate_hold_decay_buffers(fluid_voice_t* voice, int gen_base, - int gen_key2base, int is_decay) -{ - /* Purpose: - * - * Returns the number of DSP loops, that correspond to the hold - * (is_decay=0) or decay (is_decay=1) time. - * gen_base=GEN_VOLENVHOLD, GEN_VOLENVDECAY, GEN_MODENVHOLD, - * GEN_MODENVDECAY gen_key2base=GEN_KEYTOVOLENVHOLD, - * GEN_KEYTOVOLENVDECAY, GEN_KEYTOMODENVHOLD, GEN_KEYTOMODENVDECAY - */ - - fluid_real_t timecents; - fluid_real_t seconds; - int buffers; - - /* SF2.01 section 8.4.3 # 31, 32, 39, 40 - * GEN_KEYTOxxxENVxxx uses key 60 as 'origin'. - * The unit of the generator is timecents per key number. - * If KEYTOxxxENVxxx is 100, a key one octave over key 60 (72) - * will cause (60-72)*100=-1200 timecents of time variation. - * The time is cut in half. - */ - timecents = (_GEN(voice, gen_base) + _GEN(voice, gen_key2base) * (60.0 - voice->key)); - - /* Range checking */ - if (is_decay){ - /* SF 2.01 section 8.1.3 # 28, 36 */ - if (timecents > 8000.0) { - timecents = 8000.0; - } - } else { - /* SF 2.01 section 8.1.3 # 27, 35 */ - if (timecents > 5000) { - timecents = 5000.0; - } - /* SF 2.01 section 8.1.2 # 27, 35: - * The most negative number indicates no hold time - */ - if (timecents <= -32768.) { - return 0; - } - } - /* SF 2.01 section 8.1.3 # 27, 28, 35, 36 */ - if (timecents < -12000.0) { - timecents = -12000.0; - } - - seconds = fluid_tc2sec(timecents); - /* Each DSP loop processes FLUID_BUFSIZE samples. */ - - /* round to next full number of buffers */ - buffers = (int)(((fluid_real_t)voice->output_rate * seconds) - / (fluid_real_t)FLUID_BUFSIZE - +0.5); - - return buffers; -} - -/* - * fluid_voice_update_param - * - * Purpose: - * - * The value of a generator (gen) has changed. (The different - * generators are listed in fluidsynth.h, or in SF2.01 page 48-49) - * Now the dependent 'voice' parameters are calculated. - * - * fluid_voice_update_param can be called during the setup of the - * voice (to calculate the initial value for a voice parameter), or - * during its operation (a generator has been changed due to - * real-time parameter modifications like pitch-bend). - * - * Note: The generator holds three values: The base value .val, an - * offset caused by modulators .mod, and an offset caused by the - * NRPN system. _GEN(voice, generator_enumerator) returns the sum - * of all three. - */ -void -fluid_voice_update_param(fluid_voice_t* voice, int gen) -{ - double q_dB; - fluid_real_t x; - fluid_real_t y; - unsigned int count; - // Alternate attenuation scale used by EMU10K1 cards when setting the attenuation at the preset or instrument level within the SoundFont bank. - static const float ALT_ATTENUATION_SCALE = 0.4; - - switch (gen) { - - case GEN_PAN: - /* range checking is done in the fluid_pan function */ - voice->pan = _GEN(voice, GEN_PAN); - voice->amp_left = fluid_pan(voice->pan, 1) * voice->synth_gain / 32768.0f; - voice->amp_right = fluid_pan(voice->pan, 0) * voice->synth_gain / 32768.0f; - break; - - case GEN_ATTENUATION: - voice->attenuation = ((fluid_real_t)(voice)->gen[GEN_ATTENUATION].val*ALT_ATTENUATION_SCALE) + - (fluid_real_t)(voice)->gen[GEN_ATTENUATION].mod + (fluid_real_t)(voice)->gen[GEN_ATTENUATION].nrpn; - - /* Range: SF2.01 section 8.1.3 # 48 - * Motivation for range checking: - * OHPiano.SF2 sets initial attenuation to a whooping -96 dB */ - fluid_clip(voice->attenuation, 0.0, 1440.0); - break; - - /* The pitch is calculated from three different generators. - * Read comment in fluidsynth.h about GEN_PITCH. - */ - case GEN_PITCH: - case GEN_COARSETUNE: - case GEN_FINETUNE: - /* The testing for allowed range is done in 'fluid_ct2hz' */ - voice->pitch = (_GEN(voice, GEN_PITCH) - + 100.0f * _GEN(voice, GEN_COARSETUNE) - + _GEN(voice, GEN_FINETUNE)); - break; - - case GEN_REVERBSEND: - /* The generator unit is 'tenths of a percent'. */ - voice->reverb_send = _GEN(voice, GEN_REVERBSEND) / 1000.0f; - fluid_clip(voice->reverb_send, 0.0, 1.0); - voice->amp_reverb = voice->reverb_send * voice->synth_gain / 32768.0f; - break; - - case GEN_CHORUSSEND: - /* The generator unit is 'tenths of a percent'. */ - voice->chorus_send = _GEN(voice, GEN_CHORUSSEND) / 1000.0f; - fluid_clip(voice->chorus_send, 0.0, 1.0); - voice->amp_chorus = voice->chorus_send * voice->synth_gain / 32768.0f; - break; - - case GEN_OVERRIDEROOTKEY: - /* This is a non-realtime parameter. Therefore the .mod part of the generator - * can be neglected. - * NOTE: origpitch sets MIDI root note while pitchadj is a fine tuning amount - * which offsets the original rate. This means that the fine tuning is - * inverted with respect to the root note (so subtract it, not add). - */ - if (voice->gen[GEN_OVERRIDEROOTKEY].val > -1) { //FIXME: use flag instead of -1 - voice->root_pitch = voice->gen[GEN_OVERRIDEROOTKEY].val * 100.0f - - voice->sample->pitchadj; - } else { - voice->root_pitch = voice->sample->origpitch * 100.0f - voice->sample->pitchadj; - } - voice->root_pitch = fluid_ct2hz(voice->root_pitch); - if (voice->sample != NULL) { - voice->root_pitch *= (fluid_real_t) voice->output_rate / voice->sample->samplerate; - } - break; - - case GEN_FILTERFC: - /* The resonance frequency is converted from absolute cents to - * midicents .val and .mod are both used, this permits real-time - * modulation. The allowed range is tested in the 'fluid_ct2hz' - * function [PH,20021214] - */ - voice->fres = _GEN(voice, GEN_FILTERFC); - - /* The synthesis loop will have to recalculate the filter - * coefficients. */ - voice->last_fres = -1.0f; - break; - - case GEN_FILTERQ: - /* The generator contains 'centibels' (1/10 dB) => divide by 10 to - * obtain dB */ - q_dB = _GEN(voice, GEN_FILTERQ) / 10.0f; - - /* Range: SF2.01 section 8.1.3 # 8 (convert from cB to dB => /10) */ - fluid_clip(q_dB, 0.0f, 96.0f); - - /* Short version: Modify the Q definition in a way, that a Q of 0 - * dB leads to no resonance hump in the freq. response. - * - * Long version: From SF2.01, page 39, item 9 (initialFilterQ): - * "The gain at the cutoff frequency may be less than zero when - * zero is specified". Assume q_dB=0 / q_lin=1: If we would leave - * q as it is, then this results in a 3 dB hump slightly below - * fc. At fc, the gain is exactly the DC gain (0 dB). What is - * (probably) meant here is that the filter does not show a - * resonance hump for q_dB=0. In this case, the corresponding - * q_lin is 1/sqrt(2)=0.707. The filter should have 3 dB of - * attenuation at fc now. In this case Q_dB is the height of the - * resonance peak not over the DC gain, but over the frequency - * response of a non-resonant filter. This idea is implemented as - * follows: */ - q_dB -= 3.01f; - - /* The 'sound font' Q is defined in dB. The filter needs a linear - q. Convert. */ - voice->q_lin = (fluid_real_t) (pow(10.0f, q_dB / 20.0f)); - - /* SF 2.01 page 59: - * - * The SoundFont specs ask for a gain reduction equal to half the - * height of the resonance peak (Q). For example, for a 10 dB - * resonance peak, the gain is reduced by 5 dB. This is done by - * multiplying the total gain with sqrt(1/Q). `Sqrt' divides dB - * by 2 (100 lin = 40 dB, 10 lin = 20 dB, 3.16 lin = 10 dB etc) - * The gain is later factored into the 'b' coefficients - * (numerator of the filter equation). This gain factor depends - * only on Q, so this is the right place to calculate it. - */ - voice->filter_gain = (fluid_real_t) (1.0 / sqrt(voice->q_lin)); - - /* The synthesis loop will have to recalculate the filter coefficients. */ - voice->last_fres = -1.; - break; - - case GEN_MODLFOTOPITCH: - voice->modlfo_to_pitch = _GEN(voice, GEN_MODLFOTOPITCH); - fluid_clip(voice->modlfo_to_pitch, -12000.0, 12000.0); - break; - - case GEN_MODLFOTOVOL: - voice->modlfo_to_vol = _GEN(voice, GEN_MODLFOTOVOL); - fluid_clip(voice->modlfo_to_vol, -960.0, 960.0); - break; - - case GEN_MODLFOTOFILTERFC: - voice->modlfo_to_fc = _GEN(voice, GEN_MODLFOTOFILTERFC); - fluid_clip(voice->modlfo_to_fc, -12000, 12000); - break; - - case GEN_MODLFODELAY: - x = _GEN(voice, GEN_MODLFODELAY); - fluid_clip(x, -12000.0f, 5000.0f); - voice->modlfo_delay = (unsigned int) (voice->output_rate * fluid_tc2sec_delay(x)); - break; - - case GEN_MODLFOFREQ: - /* - the frequency is converted into a delta value, per buffer of FLUID_BUFSIZE samples - * - the delay into a sample delay - */ - x = _GEN(voice, GEN_MODLFOFREQ); - fluid_clip(x, -16000.0f, 4500.0f); - voice->modlfo_incr = (4.0f * FLUID_BUFSIZE * fluid_act2hz(x) / voice->output_rate); - break; - - case GEN_VIBLFOFREQ: - /* vib lfo - * - * - the frequency is converted into a delta value, per buffer of FLUID_BUFSIZE samples - * - the delay into a sample delay - */ - x = _GEN(voice, GEN_VIBLFOFREQ); - fluid_clip(x, -16000.0f, 4500.0f); - voice->viblfo_incr = (4.0f * FLUID_BUFSIZE * fluid_act2hz(x) / voice->output_rate); - break; - - case GEN_VIBLFODELAY: - x = _GEN(voice,GEN_VIBLFODELAY); - fluid_clip(x, -12000.0f, 5000.0f); - voice->viblfo_delay = (unsigned int) (voice->output_rate * fluid_tc2sec_delay(x)); - break; - - case GEN_VIBLFOTOPITCH: - voice->viblfo_to_pitch = _GEN(voice, GEN_VIBLFOTOPITCH); - fluid_clip(voice->viblfo_to_pitch, -12000.0, 12000.0); - break; - - case GEN_KEYNUM: - /* GEN_KEYNUM: SF2.01 page 46, item 46 - * - * If this generator is active, it forces the key number to its - * value. Non-realtime controller. - * - * There is a flag, which should indicate, whether a generator is - * enabled or not. But here we rely on the default value of -1. - * */ - x = _GEN(voice, GEN_KEYNUM); - if (x >= 0){ - voice->key = x; - } - break; - - case GEN_VELOCITY: - /* GEN_VELOCITY: SF2.01 page 46, item 47 - * - * If this generator is active, it forces the velocity to its - * value. Non-realtime controller. - * - * There is a flag, which should indicate, whether a generator is - * enabled or not. But here we rely on the default value of -1. */ - x = _GEN(voice, GEN_VELOCITY); - if (x > 0) { - voice->vel = x; - } - break; - - case GEN_MODENVTOPITCH: - voice->modenv_to_pitch = _GEN(voice, GEN_MODENVTOPITCH); - fluid_clip(voice->modenv_to_pitch, -12000.0, 12000.0); - break; - - case GEN_MODENVTOFILTERFC: - voice->modenv_to_fc = _GEN(voice,GEN_MODENVTOFILTERFC); - - /* Range: SF2.01 section 8.1.3 # 1 - * Motivation for range checking: - * Filter is reported to make funny noises now and then - */ - fluid_clip(voice->modenv_to_fc, -12000.0, 12000.0); - break; - - - /* sample start and ends points - * - * Range checking is initiated via the - * voice->check_sample_sanity flag, - * because it is impossible to check here: - * During the voice setup, all modulators are processed, while - * the voice is inactive. Therefore, illegal settings may - * occur during the setup (for example: First move the loop - * end point ahead of the loop start point => invalid, then - * move the loop start point forward => valid again. - */ - case GEN_STARTADDROFS: /* SF2.01 section 8.1.3 # 0 */ - case GEN_STARTADDRCOARSEOFS: /* SF2.01 section 8.1.3 # 4 */ - if (voice->sample != NULL) { - voice->start = (voice->sample->start - + (int) _GEN(voice, GEN_STARTADDROFS) - + 32768 * (int) _GEN(voice, GEN_STARTADDRCOARSEOFS)); - voice->check_sample_sanity_flag = FLUID_SAMPLESANITY_CHECK; - } - break; - case GEN_ENDADDROFS: /* SF2.01 section 8.1.3 # 1 */ - case GEN_ENDADDRCOARSEOFS: /* SF2.01 section 8.1.3 # 12 */ - if (voice->sample != NULL) { - voice->end = (voice->sample->end - + (int) _GEN(voice, GEN_ENDADDROFS) - + 32768 * (int) _GEN(voice, GEN_ENDADDRCOARSEOFS)); - voice->check_sample_sanity_flag = FLUID_SAMPLESANITY_CHECK; - } - break; - case GEN_STARTLOOPADDROFS: /* SF2.01 section 8.1.3 # 2 */ - case GEN_STARTLOOPADDRCOARSEOFS: /* SF2.01 section 8.1.3 # 45 */ - if (voice->sample != NULL) { - voice->loopstart = (voice->sample->loopstart - + (int) _GEN(voice, GEN_STARTLOOPADDROFS) - + 32768 * (int) _GEN(voice, GEN_STARTLOOPADDRCOARSEOFS)); - voice->check_sample_sanity_flag = FLUID_SAMPLESANITY_CHECK; - } - break; - - case GEN_ENDLOOPADDROFS: /* SF2.01 section 8.1.3 # 3 */ - case GEN_ENDLOOPADDRCOARSEOFS: /* SF2.01 section 8.1.3 # 50 */ - if (voice->sample != NULL) { - voice->loopend = (voice->sample->loopend - + (int) _GEN(voice, GEN_ENDLOOPADDROFS) - + 32768 * (int) _GEN(voice, GEN_ENDLOOPADDRCOARSEOFS)); - voice->check_sample_sanity_flag = FLUID_SAMPLESANITY_CHECK; - } - break; - - /* Conversion functions differ in range limit */ -#define NUM_BUFFERS_DELAY(_v) (unsigned int) (voice->output_rate * fluid_tc2sec_delay(_v) / FLUID_BUFSIZE) -#define NUM_BUFFERS_ATTACK(_v) (unsigned int) (voice->output_rate * fluid_tc2sec_attack(_v) / FLUID_BUFSIZE) -#define NUM_BUFFERS_RELEASE(_v) (unsigned int) (voice->output_rate * fluid_tc2sec_release(_v) / FLUID_BUFSIZE) - - /* volume envelope - * - * - delay and hold times are converted to absolute number of samples - * - sustain is converted to its absolute value - * - attack, decay and release are converted to their increment per sample - */ - case GEN_VOLENVDELAY: /* SF2.01 section 8.1.3 # 33 */ - x = _GEN(voice, GEN_VOLENVDELAY); - fluid_clip(x, -12000.0f, 5000.0f); - count = NUM_BUFFERS_DELAY(x); - voice->volenv_data[FLUID_VOICE_ENVDELAY].count = count; - voice->volenv_data[FLUID_VOICE_ENVDELAY].coeff = 0.0f; - voice->volenv_data[FLUID_VOICE_ENVDELAY].incr = 0.0f; - voice->volenv_data[FLUID_VOICE_ENVDELAY].min = -1.0f; - voice->volenv_data[FLUID_VOICE_ENVDELAY].max = 1.0f; - break; - - case GEN_VOLENVATTACK: /* SF2.01 section 8.1.3 # 34 */ - x = _GEN(voice, GEN_VOLENVATTACK); - fluid_clip(x, -12000.0f, 8000.0f); - count = 1 + NUM_BUFFERS_ATTACK(x); - voice->volenv_data[FLUID_VOICE_ENVATTACK].count = count; - voice->volenv_data[FLUID_VOICE_ENVATTACK].coeff = 1.0f; - voice->volenv_data[FLUID_VOICE_ENVATTACK].incr = count ? 1.0f / count : 0.0f; - voice->volenv_data[FLUID_VOICE_ENVATTACK].min = -1.0f; - voice->volenv_data[FLUID_VOICE_ENVATTACK].max = 1.0f; - break; - - case GEN_VOLENVHOLD: /* SF2.01 section 8.1.3 # 35 */ - case GEN_KEYTOVOLENVHOLD: /* SF2.01 section 8.1.3 # 39 */ - count = calculate_hold_decay_buffers(voice, GEN_VOLENVHOLD, GEN_KEYTOVOLENVHOLD, 0); /* 0 means: hold */ - voice->volenv_data[FLUID_VOICE_ENVHOLD].count = count; - voice->volenv_data[FLUID_VOICE_ENVHOLD].coeff = 1.0f; - voice->volenv_data[FLUID_VOICE_ENVHOLD].incr = 0.0f; - voice->volenv_data[FLUID_VOICE_ENVHOLD].min = -1.0f; - voice->volenv_data[FLUID_VOICE_ENVHOLD].max = 2.0f; - break; - - case GEN_VOLENVDECAY: /* SF2.01 section 8.1.3 # 36 */ - case GEN_VOLENVSUSTAIN: /* SF2.01 section 8.1.3 # 37 */ - case GEN_KEYTOVOLENVDECAY: /* SF2.01 section 8.1.3 # 40 */ - y = 1.0f - 0.001f * _GEN(voice, GEN_VOLENVSUSTAIN); - fluid_clip(y, 0.0f, 1.0f); - count = calculate_hold_decay_buffers(voice, GEN_VOLENVDECAY, GEN_KEYTOVOLENVDECAY, 1); /* 1 for decay */ - voice->volenv_data[FLUID_VOICE_ENVDECAY].count = count; - voice->volenv_data[FLUID_VOICE_ENVDECAY].coeff = 1.0f; - voice->volenv_data[FLUID_VOICE_ENVDECAY].incr = count ? -1.0f / count : 0.0f; - voice->volenv_data[FLUID_VOICE_ENVDECAY].min = y; - voice->volenv_data[FLUID_VOICE_ENVDECAY].max = 2.0f; - break; - - case GEN_VOLENVRELEASE: /* SF2.01 section 8.1.3 # 38 */ - x = _GEN(voice, GEN_VOLENVRELEASE); - fluid_clip(x, FLUID_MIN_VOLENVRELEASE, 8000.0f); - count = 1 + NUM_BUFFERS_RELEASE(x); - voice->volenv_data[FLUID_VOICE_ENVRELEASE].count = count; - voice->volenv_data[FLUID_VOICE_ENVRELEASE].coeff = 1.0f; - voice->volenv_data[FLUID_VOICE_ENVRELEASE].incr = count ? -1.0f / count : 0.0f; - voice->volenv_data[FLUID_VOICE_ENVRELEASE].min = 0.0f; - voice->volenv_data[FLUID_VOICE_ENVRELEASE].max = 1.0f; - break; - - /* Modulation envelope */ - case GEN_MODENVDELAY: /* SF2.01 section 8.1.3 # 25 */ - x = _GEN(voice, GEN_MODENVDELAY); - fluid_clip(x, -12000.0f, 5000.0f); - voice->modenv_data[FLUID_VOICE_ENVDELAY].count = NUM_BUFFERS_DELAY(x); - voice->modenv_data[FLUID_VOICE_ENVDELAY].coeff = 0.0f; - voice->modenv_data[FLUID_VOICE_ENVDELAY].incr = 0.0f; - voice->modenv_data[FLUID_VOICE_ENVDELAY].min = -1.0f; - voice->modenv_data[FLUID_VOICE_ENVDELAY].max = 1.0f; - break; - - case GEN_MODENVATTACK: /* SF2.01 section 8.1.3 # 26 */ - x = _GEN(voice, GEN_MODENVATTACK); - fluid_clip(x, -12000.0f, 8000.0f); - count = 1 + NUM_BUFFERS_ATTACK(x); - voice->modenv_data[FLUID_VOICE_ENVATTACK].count = count; - voice->modenv_data[FLUID_VOICE_ENVATTACK].coeff = 1.0f; - voice->modenv_data[FLUID_VOICE_ENVATTACK].incr = count ? 1.0f / count : 0.0f; - voice->modenv_data[FLUID_VOICE_ENVATTACK].min = -1.0f; - voice->modenv_data[FLUID_VOICE_ENVATTACK].max = 1.0f; - break; - - case GEN_MODENVHOLD: /* SF2.01 section 8.1.3 # 27 */ - case GEN_KEYTOMODENVHOLD: /* SF2.01 section 8.1.3 # 31 */ - count = calculate_hold_decay_buffers(voice, GEN_MODENVHOLD, GEN_KEYTOMODENVHOLD, 0); /* 1 means: hold */ - voice->modenv_data[FLUID_VOICE_ENVHOLD].count = count; - voice->modenv_data[FLUID_VOICE_ENVHOLD].coeff = 1.0f; - voice->modenv_data[FLUID_VOICE_ENVHOLD].incr = 0.0f; - voice->modenv_data[FLUID_VOICE_ENVHOLD].min = -1.0f; - voice->modenv_data[FLUID_VOICE_ENVHOLD].max = 2.0f; - break; - - case GEN_MODENVDECAY: /* SF 2.01 section 8.1.3 # 28 */ - case GEN_MODENVSUSTAIN: /* SF 2.01 section 8.1.3 # 29 */ - case GEN_KEYTOMODENVDECAY: /* SF 2.01 section 8.1.3 # 32 */ - count = calculate_hold_decay_buffers(voice, GEN_MODENVDECAY, GEN_KEYTOMODENVDECAY, 1); /* 1 for decay */ - y = 1.0f - 0.001f * _GEN(voice, GEN_MODENVSUSTAIN); - fluid_clip(y, 0.0f, 1.0f); - voice->modenv_data[FLUID_VOICE_ENVDECAY].count = count; - voice->modenv_data[FLUID_VOICE_ENVDECAY].coeff = 1.0f; - voice->modenv_data[FLUID_VOICE_ENVDECAY].incr = count ? -1.0f / count : 0.0f; - voice->modenv_data[FLUID_VOICE_ENVDECAY].min = y; - voice->modenv_data[FLUID_VOICE_ENVDECAY].max = 2.0f; - break; - - case GEN_MODENVRELEASE: /* SF 2.01 section 8.1.3 # 30 */ - x = _GEN(voice, GEN_MODENVRELEASE); - fluid_clip(x, -12000.0f, 8000.0f); - count = 1 + NUM_BUFFERS_RELEASE(x); - voice->modenv_data[FLUID_VOICE_ENVRELEASE].count = count; - voice->modenv_data[FLUID_VOICE_ENVRELEASE].coeff = 1.0f; - voice->modenv_data[FLUID_VOICE_ENVRELEASE].incr = count ? -1.0f / count : 0.0; - voice->modenv_data[FLUID_VOICE_ENVRELEASE].min = 0.0f; - voice->modenv_data[FLUID_VOICE_ENVRELEASE].max = 2.0f; - break; - - } /* switch gen */ -} - -/** - * fluid_voice_modulate - * - * In this implementation, I want to make sure that all controllers - * are event based: the parameter values of the DSP algorithm should - * only be updates when a controller event arrived and not at every - * iteration of the audio cycle (which would probably be feasible if - * the synth was made in silicon). - * - * The update is done in three steps: - * - * - first, we look for all the modulators that have the changed - * controller as a source. This will yield a list of generators that - * will be changed because of the controller event. - * - * - For every changed generator, calculate its new value. This is the - * sum of its original value plus the values of al the attached - * modulators. - * - * - For every changed generator, convert its value to the correct - * unit of the corresponding DSP parameter - * - * @fn int fluid_voice_modulate(fluid_voice_t* voice, int cc, int ctrl, int val) - * @param voice the synthesis voice - * @param cc flag to distinguish between a continous control and a channel control (pitch bend, ...) - * @param ctrl the control number - * */ -int fluid_voice_modulate(fluid_voice_t* voice, int cc, int ctrl) -{ - int i, k; - fluid_mod_t* mod; - int gen; - fluid_real_t modval; - -/* printf("Chan=%d, CC=%d, Src=%d, Val=%d\n", voice->channel->channum, cc, ctrl, val); */ - - for (i = 0; i < voice->mod_count; i++) { - - mod = &voice->mod[i]; - - /* step 1: find all the modulators that have the changed controller - * as input source. */ - if (fluid_mod_has_source(mod, cc, ctrl)) { - - gen = fluid_mod_get_dest(mod); - modval = 0.0; - - /* step 2: for every changed modulator, calculate the modulation - * value of its associated generator */ - for (k = 0; k < voice->mod_count; k++) { - if (fluid_mod_has_dest(&voice->mod[k], gen)) { - modval += fluid_mod_get_value(&voice->mod[k], voice->channel, voice); - } - } - - fluid_gen_set_mod(&voice->gen[gen], modval); - - /* step 3: now that we have the new value of the generator, - * recalculate the parameter values that are derived from the - * generator */ - fluid_voice_update_param(voice, gen); - } - } - return FLUID_OK; -} - -/** - * fluid_voice_modulate_all - * - * Update all the modulators. This function is called after a - * ALL_CTRL_OFF MIDI message has been received (CC 121). - * - */ -int fluid_voice_modulate_all(fluid_voice_t* voice) -{ - fluid_mod_t* mod; - int i, k, gen; - fluid_real_t modval; - - /* Loop through all the modulators. - - FIXME: we should loop through the set of generators instead of - the set of modulators. We risk to call 'fluid_voice_update_param' - several times for the same generator if several modulators have - that generator as destination. It's not an error, just a wast of - energy (think polution, global warming, unhappy musicians, - ...) */ - - for (i = 0; i < voice->mod_count; i++) { - - mod = &voice->mod[i]; - gen = fluid_mod_get_dest(mod); - modval = 0.0; - - /* Accumulate the modulation values of all the modulators with - * destination generator 'gen' */ - for (k = 0; k < voice->mod_count; k++) { - if (fluid_mod_has_dest(&voice->mod[k], gen)) { - modval += fluid_mod_get_value(&voice->mod[k], voice->channel, voice); - } - } - - fluid_gen_set_mod(&voice->gen[gen], modval); - - /* Update the parameter values that are depend on the generator - * 'gen' */ - fluid_voice_update_param(voice, gen); - } - - return FLUID_OK; -} - -/* - * fluid_voice_noteoff - */ -int -fluid_voice_noteoff(fluid_voice_t* voice) -{ - fluid_profile(FLUID_PROF_VOICE_NOTE, voice->ref); - - if (voice->channel && fluid_channel_sustained(voice->channel)) { - voice->status = FLUID_VOICE_SUSTAINED; - } else { - if (voice->volenv_section == FLUID_VOICE_ENVATTACK) { - /* A voice is turned off during the attack section of the volume - * envelope. The attack section ramps up linearly with - * amplitude. The other sections use logarithmic scaling. Calculate new - * volenv_val to achieve equievalent amplitude during the release phase - * for seamless volume transition. - */ - if (voice->volenv_val > 0){ - fluid_real_t lfo = voice->modlfo_val * -voice->modlfo_to_vol; - fluid_real_t amp = voice->volenv_val * pow (10.0, lfo / -200); - fluid_real_t env_value = - ((-200 * log (amp) / log (10.0) - lfo) / 960.0 - 1); - fluid_clip (env_value, 0.0, 1.0); - voice->volenv_val = env_value; - } - } - voice->volenv_section = FLUID_VOICE_ENVRELEASE; - voice->volenv_count = 0; - voice->modenv_section = FLUID_VOICE_ENVRELEASE; - voice->modenv_count = 0; - } - - return FLUID_OK; -} - -/* - * fluid_voice_kill_excl - * - * Percussion sounds can be mutually exclusive: for example, a 'closed - * hihat' sound will terminate an 'open hihat' sound ringing at the - * same time. This behaviour is modeled using 'exclusive classes', - * turning on a voice with an exclusive class other than 0 will kill - * all other voices having that exclusive class within the same preset - * or channel. fluid_voice_kill_excl gets called, when 'voice' is to - * be killed for that reason. - */ -int -fluid_voice_kill_excl(fluid_voice_t* voice){ - - if (!_PLAYING(voice)) { - return FLUID_OK; - } - - /* Turn off the exclusive class information for this voice, - so that it doesn't get killed twice - */ - fluid_voice_gen_set(voice, GEN_EXCLUSIVECLASS, 0); - - /* If the voice is not yet in release state, put it into release state */ - if (voice->volenv_section != FLUID_VOICE_ENVRELEASE){ - voice->volenv_section = FLUID_VOICE_ENVRELEASE; - voice->volenv_count = 0; - voice->modenv_section = FLUID_VOICE_ENVRELEASE; - voice->modenv_count = 0; - } - - /* Speed up the volume envelope */ - /* The value was found through listening tests with hi-hat samples. */ - fluid_voice_gen_set(voice, GEN_VOLENVRELEASE, -200); - fluid_voice_update_param(voice, GEN_VOLENVRELEASE); - - /* Speed up the modulation envelope */ - fluid_voice_gen_set(voice, GEN_MODENVRELEASE, -200); - fluid_voice_update_param(voice, GEN_MODENVRELEASE); - - return FLUID_OK; -} - -/* - * fluid_voice_off - * - * Purpose: - * Turns off a voice, meaning that it is not processed - * anymore by the DSP loop. - */ -int -fluid_voice_off(fluid_voice_t* voice) -{ - fluid_profile(FLUID_PROF_VOICE_RELEASE, voice->ref); - - voice->chan = NO_CHANNEL; - voice->volenv_section = FLUID_VOICE_ENVFINISHED; - voice->volenv_count = 0; - voice->modenv_section = FLUID_VOICE_ENVFINISHED; - voice->modenv_count = 0; - voice->status = FLUID_VOICE_OFF; - - /* Decrement the reference count of the sample. */ - if (voice->sample) { - fluid_sample_decr_ref(voice->sample); - voice->sample = NULL; - } - - return FLUID_OK; -} - -/* - * fluid_voice_add_mod - * - * Adds a modulator to the voice. "mode" indicates, what to do, if - * an identical modulator exists already. - * - * mode == FLUID_VOICE_ADD: Identical modulators on preset level are added - * mode == FLUID_VOICE_OVERWRITE: Identical modulators on instrument level are overwritten - * mode == FLUID_VOICE_DEFAULT: This is a default modulator, there can be no identical modulator. - * Don't check. - */ -void -fluid_voice_add_mod(fluid_voice_t* voice, fluid_mod_t* mod, int mode) -{ - int i; - - /* - * Some soundfonts come with a huge number of non-standard - * controllers, because they have been designed for one particular - * sound card. Discard them, maybe print a warning. - */ - - if (((mod->flags1 & FLUID_MOD_CC) == 0) - && ((mod->src1 != 0) /* SF2.01 section 8.2.1: Constant value */ - && (mod->src1 != 2) /* Note-on velocity */ - && (mod->src1 != 3) /* Note-on key number */ - && (mod->src1 != 10) /* Poly pressure */ - && (mod->src1 != 13) /* Channel pressure */ - && (mod->src1 != 14) /* Pitch wheel */ - && (mod->src1 != 16))) { /* Pitch wheel sensitivity */ - FLUID_LOG(FLUID_WARN, "Ignoring invalid controller, using non-CC source %i.", mod->src1); - return; - } - - if (mode == FLUID_VOICE_ADD) { - - /* if identical modulator exists, add them */ - for (i = 0; i < voice->mod_count; i++) { - if (fluid_mod_test_identity(&voice->mod[i], mod)) { - // printf("Adding modulator...\n"); - voice->mod[i].amount += mod->amount; - return; - } - } - - } else if (mode == FLUID_VOICE_OVERWRITE) { - - /* if identical modulator exists, replace it (only the amount has to be changed) */ - for (i = 0; i < voice->mod_count; i++) { - if (fluid_mod_test_identity(&voice->mod[i], mod)) { - // printf("Replacing modulator...amount is %f\n",mod->amount); - voice->mod[i].amount = mod->amount; - return; - } - } - } - - /* Add a new modulator (No existing modulator to add / overwrite). - Also, default modulators (FLUID_VOICE_DEFAULT) are added without - checking, if the same modulator already exists. */ - if (voice->mod_count < FLUID_NUM_MOD) { - fluid_mod_clone(&voice->mod[voice->mod_count++], mod); - } -} - -unsigned int fluid_voice_get_id(fluid_voice_t* voice) -{ - return voice->id; -} - -int fluid_voice_is_playing(fluid_voice_t* voice) -{ - return _PLAYING(voice); -} - -/* - * fluid_voice_get_lower_boundary_for_attenuation - * - * Purpose: - * - * A lower boundary for the attenuation (as in 'the minimum - * attenuation of this voice, with volume pedals, modulators - * etc. resulting in minimum attenuation, cannot fall below x cB) is - * calculated. This has to be called during fluid_voice_init, after - * all modulators have been run on the voice once. Also, - * voice->attenuation has to be initialized. - */ -fluid_real_t fluid_voice_get_lower_boundary_for_attenuation(fluid_voice_t* voice) -{ - int i; - fluid_mod_t* mod; - fluid_real_t possible_att_reduction_cB=0; - fluid_real_t lower_bound; - - for (i = 0; i < voice->mod_count; i++) { - mod = &voice->mod[i]; - - /* Modulator has attenuation as target and can change over time? */ - if ((mod->dest == GEN_ATTENUATION) - && ((mod->flags1 & FLUID_MOD_CC) || (mod->flags2 & FLUID_MOD_CC))) { - - fluid_real_t current_val = fluid_mod_get_value(mod, voice->channel, voice); - fluid_real_t v = fabs(mod->amount); - - if ((mod->src1 == FLUID_MOD_PITCHWHEEL) - || (mod->flags1 & FLUID_MOD_BIPOLAR) - || (mod->flags2 & FLUID_MOD_BIPOLAR) - || (mod->amount < 0)) { - /* Can this modulator produce a negative contribution? */ - v *= -1.0; - } else { - /* No negative value possible. But still, the minimum contribution is 0. */ - v = 0; - } - - /* For example: - * - current_val=100 - * - min_val=-4000 - * - possible_att_reduction_cB += 4100 - */ - if (current_val > v){ - possible_att_reduction_cB += (current_val - v); - } - } - } - - lower_bound = voice->attenuation-possible_att_reduction_cB; - - /* SF2.01 specs do not allow negative attenuation */ - if (lower_bound < 0) { - lower_bound = 0; - } - return lower_bound; -} - - -/* Purpose: - * - * Make sure, that sample start / end point and loop points are in - * proper order. When starting up, calculate the initial phase. - */ -void fluid_voice_check_sample_sanity(fluid_voice_t* voice) -{ - int min_index_nonloop=(int) voice->sample->start; - int max_index_nonloop=(int) voice->sample->end; - - /* make sure we have enough samples surrounding the loop */ - int min_index_loop=(int) voice->sample->start + FLUID_MIN_LOOP_PAD; - int max_index_loop=(int) voice->sample->end - FLUID_MIN_LOOP_PAD + 1; /* 'end' is last valid sample, loopend can be + 1 */ - fluid_check_fpe("voice_check_sample_sanity start"); - - if (!voice->check_sample_sanity_flag){ - return; - } - -#if 0 - printf("Sample from %i to %i\n",voice->sample->start, voice->sample->end); - printf("Sample loop from %i %i\n",voice->sample->loopstart, voice->sample->loopend); - printf("Playback from %i to %i\n", voice->start, voice->end); - printf("Playback loop from %i to %i\n",voice->loopstart, voice->loopend); -#endif - - /* Keep the start point within the sample data */ - if (voice->start < min_index_nonloop){ - voice->start = min_index_nonloop; - } else if (voice->start > max_index_nonloop){ - voice->start = max_index_nonloop; - } - - /* Keep the end point within the sample data */ - if (voice->end < min_index_nonloop){ - voice->end = min_index_nonloop; - } else if (voice->end > max_index_nonloop){ - voice->end = max_index_nonloop; - } - - /* Keep start and end point in the right order */ - if (voice->start > voice->end){ - int temp = voice->start; - voice->start = voice->end; - voice->end = temp; - /*FLUID_LOG(FLUID_DBG, "Loop / sample sanity check: Changing order of start / end points!"); */ - } - - /* Zero length? */ - if (voice->start == voice->end){ - fluid_voice_off(voice); - return; - } - - if ((_SAMPLEMODE(voice) == FLUID_LOOP_UNTIL_RELEASE) - || (_SAMPLEMODE(voice) == FLUID_LOOP_DURING_RELEASE)) { - /* Keep the loop start point within the sample data */ - if (voice->loopstart < min_index_loop){ - voice->loopstart = min_index_loop; - } else if (voice->loopstart > max_index_loop){ - voice->loopstart = max_index_loop; - } - - /* Keep the loop end point within the sample data */ - if (voice->loopend < min_index_loop){ - voice->loopend = min_index_loop; - } else if (voice->loopend > max_index_loop){ - voice->loopend = max_index_loop; - } - - /* Keep loop start and end point in the right order */ - if (voice->loopstart > voice->loopend){ - int temp = voice->loopstart; - voice->loopstart = voice->loopend; - voice->loopend = temp; - /*FLUID_LOG(FLUID_DBG, "Loop / sample sanity check: Changing order of loop points!"); */ - } - - /* Loop too short? Then don't loop. */ - if (voice->loopend < voice->loopstart + FLUID_MIN_LOOP_SIZE){ - voice->gen[GEN_SAMPLEMODE].val = FLUID_UNLOOPED; - } - - /* The loop points may have changed. Obtain a new estimate for the loop volume. */ - /* Is the voice loop within the sample loop? */ - if ((int)voice->loopstart >= (int)voice->sample->loopstart - && (int)voice->loopend <= (int)voice->sample->loopend){ - /* Is there a valid peak amplitude available for the loop? */ - if (voice->sample->amplitude_that_reaches_noise_floor_is_valid){ - voice->amplitude_that_reaches_noise_floor_loop=voice->sample->amplitude_that_reaches_noise_floor / voice->synth_gain; - } else { - /* Worst case */ - voice->amplitude_that_reaches_noise_floor_loop=voice->amplitude_that_reaches_noise_floor_nonloop; - }; - }; - - } /* if sample mode is looped */ - - /* Run startup specific code (only once, when the voice is started) */ - if (voice->check_sample_sanity_flag & FLUID_SAMPLESANITY_STARTUP){ - if (max_index_loop - min_index_loop < FLUID_MIN_LOOP_SIZE){ - if ((_SAMPLEMODE(voice) == FLUID_LOOP_UNTIL_RELEASE) - || (_SAMPLEMODE(voice) == FLUID_LOOP_DURING_RELEASE)){ - voice->gen[GEN_SAMPLEMODE].val = FLUID_UNLOOPED; - } - } - - /* Set the initial phase of the voice (using the result from the - start offset modulators). */ - fluid_phase_set_int(voice->phase, voice->start); - } /* if startup */ - - /* Is this voice run in loop mode, or does it run straight to the - end of the waveform data? */ - if (((_SAMPLEMODE(voice) == FLUID_LOOP_UNTIL_RELEASE) && (voice->volenv_section < FLUID_VOICE_ENVRELEASE)) - || (_SAMPLEMODE(voice) == FLUID_LOOP_DURING_RELEASE)) { - /* Yes, it will loop as soon as it reaches the loop point. In - * this case we must prevent, that the playback pointer (phase) - * happens to end up beyond the 2nd loop point, because the - * point has moved. The DSP algorithm is unable to cope with - * that situation. So if the phase is beyond the 2nd loop - * point, set it to the start of the loop. No way to avoid some - * noise here. Note: If the sample pointer ends up -before the - * first loop point- instead, then the DSP loop will just play - * the sample, enter the loop and proceed as expected => no - * actions required. - */ - int index_in_sample = fluid_phase_index(voice->phase); - if (index_in_sample >= voice->loopend){ - /* FLUID_LOG(FLUID_DBG, "Loop / sample sanity check: Phase after 2nd loop point!"); */ - fluid_phase_set_int(voice->phase, voice->loopstart); - } - } -/* FLUID_LOG(FLUID_DBG, "Loop / sample sanity check: Sample from %i to %i, loop from %i to %i", voice->start, voice->end, voice->loopstart, voice->loopend); */ - - /* Sample sanity has been assured. Don't check again, until some - sample parameter is changed by modulation. */ - voice->check_sample_sanity_flag=0; -#if 0 - printf("Sane? playback loop from %i to %i\n", voice->loopstart, voice->loopend); -#endif - fluid_check_fpe("voice_check_sample_sanity"); -} - - -int fluid_voice_set_param(fluid_voice_t* voice, int gen, fluid_real_t nrpn_value, int abs) -{ - voice->gen[gen].nrpn = nrpn_value; - voice->gen[gen].flags = (abs)? GEN_ABS_NRPN : GEN_SET; - fluid_voice_update_param(voice, gen); - return FLUID_OK; -} - -int fluid_voice_set_gain(fluid_voice_t* voice, fluid_real_t gain) -{ - /* avoid division by zero*/ - if (gain < 0.0000001){ - gain = 0.0000001; - } - - voice->synth_gain = gain; - voice->amp_left = fluid_pan(voice->pan, 1) * gain / 32768.0f; - voice->amp_right = fluid_pan(voice->pan, 0) * gain / 32768.0f; - voice->amp_reverb = voice->reverb_send * gain / 32768.0f; - voice->amp_chorus = voice->chorus_send * gain / 32768.0f; - - return FLUID_OK; -} - -/* - Scan the loop - * - determine the peak level - * - Calculate, what factor will make the loop inaudible - * - Store in sample - */ -int fluid_voice_optimize_sample(fluid_sample_t* s) -{ - signed short peak_max = 0; - signed short peak_min = 0; - signed short peak; - fluid_real_t normalized_amplitude_during_loop; - double result; - int i; - - /* ignore ROM and other(?) invalid samples */ - if (!s->valid) return (FLUID_OK); - - if (!s->amplitude_that_reaches_noise_floor_is_valid){ /* Only once */ - /* Scan the loop */ - for (i = (int)s->loopstart; i < (int) s->loopend; i ++){ - signed short val = s->data[i]; - if (val > peak_max) { - peak_max = val; - } else if (val < peak_min) { - peak_min = val; - } - } - - /* Determine the peak level */ - if (peak_max >- peak_min){ - peak = peak_max; - } else { - peak =- peak_min; - }; - if (peak == 0){ - /* Avoid division by zero */ - peak = 1; - }; - - /* Calculate what factor will make the loop inaudible - * For example: Take a peak of 3277 (10 % of 32768). The - * normalized amplitude is 0.1 (10 % of 32768). An amplitude - * factor of 0.0001 (as opposed to the default 0.00001) will - * drop this sample to the noise floor. - */ - - /* 16 bits => 96+4=100 dB dynamic range => 0.00001 */ - normalized_amplitude_during_loop = ((fluid_real_t)peak)/32768.; - result = FLUID_NOISE_FLOOR / normalized_amplitude_during_loop; - - /* Store in sample */ - s->amplitude_that_reaches_noise_floor = (double)result; - s->amplitude_that_reaches_noise_floor_is_valid = 1; -#if 0 - printf("Sample peak detection: factor %f\n", (double)result); -#endif - }; - return FLUID_OK; -} diff --git a/src/libs/fluidsynth/src/fluid_voice.h b/src/libs/fluidsynth/src/fluid_voice.h deleted file mode 100644 index fa8d56623d..0000000000 --- a/src/libs/fluidsynth/src/fluid_voice.h +++ /dev/null @@ -1,291 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - - -#ifndef _FLUID_VOICE_H -#define _FLUID_VOICE_H - -#include "fluid_phase.h" -#include "fluid_gen.h" -#include "fluid_mod.h" - -#define NO_CHANNEL 0xff - -enum fluid_voice_status -{ - FLUID_VOICE_CLEAN, - FLUID_VOICE_ON, - FLUID_VOICE_SUSTAINED, - FLUID_VOICE_OFF -}; - - -/* - * envelope data - */ -struct _fluid_env_data_t { - unsigned int count; - fluid_real_t coeff; - fluid_real_t incr; - fluid_real_t min; - fluid_real_t max; -}; - -/* Indices for envelope tables */ -enum fluid_voice_envelope_index_t{ - FLUID_VOICE_ENVDELAY, - FLUID_VOICE_ENVATTACK, - FLUID_VOICE_ENVHOLD, - FLUID_VOICE_ENVDECAY, - FLUID_VOICE_ENVSUSTAIN, - FLUID_VOICE_ENVRELEASE, - FLUID_VOICE_ENVFINISHED, - FLUID_VOICE_ENVLAST -}; - -/* - * fluid_voice_t - */ -struct _fluid_voice_t -{ - unsigned int id; /* the id is incremented for every new noteon. - it's used for noteoff's */ - unsigned char status; - unsigned char chan; /* the channel number, quick access for channel messages */ - unsigned char key; /* the key, quick acces for noteoff */ - unsigned char vel; /* the velocity */ - fluid_channel_t* channel; - fluid_gen_t gen[GEN_LAST]; - fluid_mod_t mod[FLUID_NUM_MOD]; - int mod_count; - int has_looped; /* Flag that is set as soon as the first loop is completed. */ - fluid_sample_t* sample; - int check_sample_sanity_flag; /* Flag that initiates, that sample-related parameters - have to be checked. */ -#if 0 - /* Instead of keeping a pointer to a fluid_sample_t structure, - * I think it would be better to copy the sample data in the - * voice structure. SoundFont loader then do not have to - * allocate and maintain the fluid_sample_t structure. [PH] - * - * The notify callback may be used also for streaming samples. - */ - short* sample_data; /* pointer to the sample data */ - int sample_data_offset; /* the offset of data[0] in the whole sample */ - int sample_data_length; /* the length of the data array */ - unsigned int sample_start; - unsigned int sample_end; - unsigned int sample_loopstart; - unsigned int sample_loopend; - unsigned int sample_rate; - int sample_origpitch; - int sample_pitchadj; - int sample_type; - int (*sample_notify)(fluid_voice_t* voice, int reason); - void* sample_userdata; -#endif - - /* basic parameters */ - fluid_real_t output_rate; /* the sample rate of the synthesizer */ - - unsigned int start_time; - unsigned int ticks; - - fluid_real_t amp; /* current linear amplitude */ - fluid_phase_t phase; /* the phase of the sample wave */ - - /* Temporary variables used in fluid_voice_write() */ - - fluid_real_t phase_incr; /* the phase increment for the next 64 samples */ - fluid_real_t amp_incr; /* amplitude increment value */ - fluid_real_t *dsp_buf; /* buffer to store interpolated sample data to */ - - /* End temporary variables */ - - /* basic parameters */ - fluid_real_t pitch; /* the pitch in midicents */ - fluid_real_t attenuation; /* the attenuation in centibels */ - fluid_real_t min_attenuation_cB; /* Estimate on the smallest possible attenuation - * during the lifetime of the voice */ - fluid_real_t root_pitch; - - /* sample and loop start and end points (offset in sample memory). */ - int start; - int end; - int loopstart; - int loopend; /* Note: first point following the loop (superimposed on loopstart) */ - - /* master gain */ - fluid_real_t synth_gain; - - /* vol env */ - fluid_env_data_t volenv_data[FLUID_VOICE_ENVLAST]; - unsigned int volenv_count; - int volenv_section; - fluid_real_t volenv_val; - fluid_real_t amplitude_that_reaches_noise_floor_nonloop; - fluid_real_t amplitude_that_reaches_noise_floor_loop; - - /* mod env */ - fluid_env_data_t modenv_data[FLUID_VOICE_ENVLAST]; - unsigned int modenv_count; - int modenv_section; - fluid_real_t modenv_val; /* the value of the modulation envelope */ - fluid_real_t modenv_to_fc; - fluid_real_t modenv_to_pitch; - - /* mod lfo */ - fluid_real_t modlfo_val; /* the value of the modulation LFO */ - unsigned int modlfo_delay; /* the delay of the lfo in samples */ - fluid_real_t modlfo_incr; /* the lfo frequency is converted to a per-buffer increment */ - fluid_real_t modlfo_to_fc; - fluid_real_t modlfo_to_pitch; - fluid_real_t modlfo_to_vol; - - /* vib lfo */ - fluid_real_t viblfo_val; /* the value of the vibrato LFO */ - unsigned int viblfo_delay; /* the delay of the lfo in samples */ - fluid_real_t viblfo_incr; /* the lfo frequency is converted to a per-buffer increment */ - fluid_real_t viblfo_to_pitch; - - /* resonant filter */ - fluid_real_t fres; /* the resonance frequency, in cents (not absolute cents) */ - fluid_real_t last_fres; /* Current resonance frequency of the IIR filter */ - /* Serves as a flag: A deviation between fres and last_fres */ - /* indicates, that the filter has to be recalculated. */ - fluid_real_t q_lin; /* the q-factor on a linear scale */ - fluid_real_t filter_gain; /* Gain correction factor, depends on q */ - fluid_real_t hist1, hist2; /* Sample history for the IIR filter */ - int filter_startup; /* Flag: If set, the filter will be set directly. - Else it changes smoothly. */ - - /* filter coefficients */ - /* The coefficients are normalized to a0. */ - /* b0 and b2 are identical => b02 */ - fluid_real_t b02; /* b0 / a0 */ - fluid_real_t b1; /* b1 / a0 */ - fluid_real_t a1; /* a0 / a0 */ - fluid_real_t a2; /* a1 / a0 */ - - fluid_real_t b02_incr; - fluid_real_t b1_incr; - fluid_real_t a1_incr; - fluid_real_t a2_incr; - int filter_coeff_incr_count; - - /* pan */ - fluid_real_t pan; - fluid_real_t amp_left; - fluid_real_t amp_right; - - /* reverb */ - fluid_real_t reverb_send; - fluid_real_t amp_reverb; - - /* chorus */ - fluid_real_t chorus_send; - fluid_real_t amp_chorus; - - /* interpolation method, as in fluid_interp in fluidsynth.h */ - int interp_method; - - /* for debugging */ - int debug; - double ref; -}; - - -fluid_voice_t* new_fluid_voice(fluid_real_t output_rate); -int delete_fluid_voice(fluid_voice_t* voice); - -void fluid_voice_start(fluid_voice_t* voice); - -int fluid_voice_write(fluid_voice_t* voice, - fluid_real_t* left, fluid_real_t* right, - fluid_real_t* reverb_buf, fluid_real_t* chorus_buf); - -int fluid_voice_init(fluid_voice_t* voice, fluid_sample_t* sample, - fluid_channel_t* channel, int key, int vel, - unsigned int id, unsigned int time, fluid_real_t gain); - -int fluid_voice_modulate(fluid_voice_t* voice, int cc, int ctrl); -int fluid_voice_modulate_all(fluid_voice_t* voice); - -/** Set the NRPN value of a generator. */ -int fluid_voice_set_param(fluid_voice_t* voice, int gen, fluid_real_t value, int abs); - - -/** Set the gain. */ -int fluid_voice_set_gain(fluid_voice_t* voice, fluid_real_t gain); - - -/** Update all the synthesis parameters, which depend on generator - 'gen'. This is only necessary after changing a generator of an - already operating voice. Most applications will not need this - function.*/ -void fluid_voice_update_param(fluid_voice_t* voice, int gen); - -int fluid_voice_noteoff(fluid_voice_t* voice); -int fluid_voice_off(fluid_voice_t* voice); -int fluid_voice_calculate_runtime_synthesis_parameters(fluid_voice_t* voice); -fluid_channel_t* fluid_voice_get_channel(fluid_voice_t* voice); -int calculate_hold_decay_buffers(fluid_voice_t* voice, int gen_base, - int gen_key2base, int is_decay); -int fluid_voice_kill_excl(fluid_voice_t* voice); -fluid_real_t fluid_voice_get_lower_boundary_for_attenuation(fluid_voice_t* voice); -fluid_real_t fluid_voice_determine_amplitude_that_reaches_noise_floor_for_sample(fluid_voice_t* voice); -void fluid_voice_check_sample_sanity(fluid_voice_t* voice); - -#define fluid_voice_set_id(_voice, _id) { (_voice)->id = (_id); } -#define fluid_voice_get_chan(_voice) (_voice)->chan - - -#define _PLAYING(voice) (((voice)->status == FLUID_VOICE_ON) || ((voice)->status == FLUID_VOICE_SUSTAINED)) - -/* A voice is 'ON', if it has not yet received a noteoff - * event. Sending a noteoff event will advance the envelopes to - * section 5 (release). */ -#define _ON(voice) ((voice)->status == FLUID_VOICE_ON && (voice)->volenv_section < FLUID_VOICE_ENVRELEASE) -#define _SUSTAINED(voice) ((voice)->status == FLUID_VOICE_SUSTAINED) -#define _AVAILABLE(voice) (((voice)->status == FLUID_VOICE_CLEAN) || ((voice)->status == FLUID_VOICE_OFF)) -#define _RELEASED(voice) ((voice)->chan == NO_CHANNEL) -#define _SAMPLEMODE(voice) ((int)(voice)->gen[GEN_SAMPLEMODE].val) - - -fluid_real_t fluid_voice_gen_value(fluid_voice_t* voice, int num); - -#define _GEN(_voice, _n) \ - ((fluid_real_t)(_voice)->gen[_n].val \ - + (fluid_real_t)(_voice)->gen[_n].mod \ - + (fluid_real_t)(_voice)->gen[_n].nrpn) - -#define FLUID_SAMPLESANITY_CHECK (1 << 0) -#define FLUID_SAMPLESANITY_STARTUP (1 << 1) - - -/* defined in fluid_dsp_float.c */ - -void fluid_dsp_float_config (void); -int fluid_dsp_float_interpolate_none (fluid_voice_t *voice); -int fluid_dsp_float_interpolate_linear (fluid_voice_t *voice); -int fluid_dsp_float_interpolate_4th_order (fluid_voice_t *voice); -int fluid_dsp_float_interpolate_7th_order (fluid_voice_t *voice); - -#endif /* _FLUID_VOICE_H */ diff --git a/src/libs/fluidsynth/src/fluidsynth.c b/src/libs/fluidsynth/src/fluidsynth.c deleted file mode 100644 index 23d5843353..0000000000 --- a/src/libs/fluidsynth/src/fluidsynth.c +++ /dev/null @@ -1,712 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include - -#include "fluidsynth_priv.h" - -#if !defined(WIN32) && !defined(MACINTOSH) -#define _GNU_SOURCE -#include -#endif - -#if defined(WIN32) -#include -#endif - -#include "fluidsynth.h" - -#if defined(WIN32) && !defined(MINGW32) -#include "config_win32.h" -#endif - -#ifdef HAVE_SIGNAL_H -#include "signal.h" -#endif - -#include "fluid_lash.h" - -#ifndef WITH_MIDI -#define WITH_MIDI 1 -#endif - -/* default audio fragment count (if none specified) */ -#ifdef WIN32 -#define DEFAULT_FRAG_COUNT 32 -#else -#define DEFAULT_FRAG_COUNT 16 -#endif - -void print_usage(void); -void print_help(void); -void print_welcome(void); - -static fluid_cmd_handler_t* newclient(void* data, char* addr); - -/* - * the globals - */ -fluid_cmd_handler_t* cmd_handler = NULL; -int option_help = 0; /* set to 1 if "-o help" is specified */ - -/* - * support for the getopt function - */ -#if !defined(WIN32) && !defined(MACINTOSH) -#define GETOPT_SUPPORT 1 -int getopt(int argc, char * const argv[], const char *optstring); -extern char *optarg; -extern int optind, opterr, optopt; -#endif - - -/* process_o_cmd_line_option - * - * Purpose: - * Process a command line option -o setting=value, - * for example: -o synth.polyhony=16 - */ -void process_o_cmd_line_option(fluid_settings_t* settings, char* optarg){ - char* val; - for (val = optarg; *val != '\0'; val++) { - if (*val == '=') { - *val++ = 0; - break; - } - } - - /* did user request list of settings */ - if (strcmp (optarg, "help") == 0) - { - option_help = 1; - return; - } - - /* At this point: - * optarg => "synth.polyphony" - * val => "16" - */ - switch(fluid_settings_get_type(settings, optarg)){ - case FLUID_NUM_TYPE: - if (fluid_settings_setnum(settings, optarg, atof(val))){ - break; - }; - case FLUID_INT_TYPE: - if (fluid_settings_setint(settings, optarg, atoi(val))){ - break; - }; - case FLUID_STR_TYPE: - if (fluid_settings_setstr(settings, optarg, val)){ - break; - }; - default: - fprintf (stderr, "Settings argument on command line: Failed to set \"%s\" to \"%s\".\n" - "Most likely the parameter \"%s\" does not exist.\n", optarg, val, optarg); - } -} - -static void -print_pretty_int (int i) -{ - if (i == INT_MAX) printf ("MAXINT"); - else if (i == INT_MIN) printf ("MININT"); - else printf ("%d", i); -} - -/* fluid_settings_foreach function for displaying option help "-o help" */ -static void -settings_foreach_func (void *data, char *name, int type) -{ - fluid_settings_t *settings = (fluid_settings_t *)data; - double dmin, dmax, ddef; - int imin, imax, idef; - char *defstr; - - switch (type) - { - case FLUID_NUM_TYPE: - fluid_settings_getnum_range (settings, name, &dmin, &dmax); - ddef = fluid_settings_getnum_default (settings, name); - printf ("%-24s FLOAT [min=%0.3f, max=%0.3f, def=%0.3f]\n", - name, dmin, dmax, ddef); - break; - case FLUID_INT_TYPE: - fluid_settings_getint_range (settings, name, &imin, &imax); - idef = fluid_settings_getint_default (settings, name); - printf ("%-24s INT [min=", name); - print_pretty_int (imin); - printf (", max="); - print_pretty_int (imax); - printf (", def="); - print_pretty_int (idef); - printf ("]\n"); - break; - case FLUID_STR_TYPE: - defstr = fluid_settings_getstr_default (settings, name); - printf ("%-24s STR", name); - if (defstr) printf (" [def='%s']\n", defstr); - else printf ("\n"); - break; - case FLUID_SET_TYPE: - printf ("%-24s SET\n", name); - break; - } -} - - -#ifdef HAVE_SIGNAL_H -/* - * handle_signal - */ -void handle_signal(int sig_num) -{ -} -#endif - - -/* - * main - */ -int main(int argc, char** argv) -{ - fluid_settings_t* settings; - int arg1 = 1; - char buf[512]; - int c, i, fragcount = DEFAULT_FRAG_COUNT; - int interactive = 1; - int midi_in = 1; - fluid_player_t* player = NULL; - fluid_midi_router_t* router = NULL; - fluid_midi_driver_t* mdriver = NULL; - fluid_audio_driver_t* adriver = NULL; - fluid_synth_t* synth = NULL; - fluid_server_t* server = NULL; - char* midi_id = NULL; - char* midi_driver = NULL; - char* midi_device = NULL; - char* config_file = NULL; - int audio_groups = 0; - int audio_channels = 0; - int with_server = 0; - int dump = 0; - int connect_lash = 1; - char *optchars = "a:C:c:df:G:g:hijK:L:lm:no:p:R:r:sVvz:"; -#ifdef LASH_ENABLED - int enabled_lash = 0; /* set to TRUE if lash gets enabled */ - fluid_lash_args_t *lash_args; - - lash_args = fluid_lash_extract_args (&argc, &argv); -#endif - - settings = new_fluid_settings(); - -#ifdef GETOPT_SUPPORT /* pre section of GETOPT supported argument handling */ - opterr = 0; - - while (1) { - int option_index = 0; - - static struct option long_options[] = { - {"audio-bufcount", 1, 0, 'c'}, - {"audio-bufsize", 1, 0, 'z'}, - {"audio-channels", 1, 0, 'L'}, - {"audio-driver", 1, 0, 'a'}, - {"audio-groups", 1, 0, 'G'}, - {"chorus", 1, 0, 'C'}, - {"connect-jack-outputs", 0, 0, 'j'}, - {"disable-lash", 0, 0, 'l'}, - {"dump", 0, 0, 'd'}, - {"gain", 1, 0, 'g'}, - {"help", 0, 0, 'h'}, - {"load-config", 1, 0, 'f'}, - {"midi-channels", 1, 0, 'K'}, - {"midi-driver", 1, 0, 'm'}, - {"no-midi-in", 0, 0, 'n'}, - {"no-shell", 0, 0, 'i'}, - {"option", 1, 0, 'o'}, - {"portname", 1, 0, 'p'}, - {"reverb", 1, 0, 'R'}, - {"sample-rate", 1, 0, 'r'}, - {"server", 0, 0, 's'}, - {"verbose", 0, 0, 'v'}, - {"version", 0, 0, 'V'}, - {0, 0, 0, 0} - }; - - c = getopt_long(argc, argv, optchars, long_options, &option_index); - if (c == -1) { - break; - } -#else /* "pre" section to non getopt argument handling */ - for (i = 1; i < argc; i++) { - char *optarg; - - /* Skip non switch arguments (assume they are file names) */ - if ((argv[i][0] != '-') || (argv[i][1] == '\0')) break; - - c = argv[i][1]; - - optarg = strchr (optchars, c); /* find the option character in optchars */ - if (optarg && optarg[1] == ':') /* colon follows if switch argument expected */ - { - if (++i >= argc) - { - printf ("Option -%c requires an argument\n", c); - print_usage(); - exit(0); - } - else - { - optarg = argv[i]; - if (optarg[0] == '-') - { - printf ("Expected argument to option -%c found switch instead\n", c); - print_usage(); - exit(0); - } - } - } - else optarg = ""; -#endif - - switch (c) { -#ifdef GETOPT_SUPPORT - case 0: /* shouldn't normally happen, a long option's flag is set to NULL */ - printf ("option %s", long_options[option_index].name); - if (optarg) { - printf (" with arg %s", optarg); - } - printf ("\n"); - break; -#endif - case 'a': - fluid_settings_setstr(settings, "audio.driver", optarg); - break; - case 'C': - if ((optarg != NULL) && ((strcmp(optarg, "0") == 0) || (strcmp(optarg, "no") == 0))) { - fluid_settings_setstr(settings, "synth.chorus.active", "no"); - } else { - fluid_settings_setstr(settings, "synth.chorus.active", "yes"); - } - break; - case 'c': - fluid_settings_setint(settings, "audio.periods", atoi(optarg)); - break; - case 'd': - fluid_settings_setstr(settings, "synth.dump", "yes"); - dump = 1; - break; - case 'f': - config_file = optarg; - break; - case 'G': - audio_groups = atoi(optarg); - break; - case 'g': - fluid_settings_setnum(settings, "synth.gain", atof(optarg)); - break; - case 'h': - print_help(); - break; - case 'i': - interactive = 0; - break; - case 'j': - fluid_settings_setint(settings, "audio.jack.autoconnect", 1); - break; - case 'K': - fluid_settings_setint(settings, "synth.midi-channels", atoi(optarg)); - break; - case 'L': - audio_channels = atoi(optarg); - fluid_settings_setint(settings, "synth.audio-channels", audio_channels); - break; - case 'l': /* disable LASH */ - connect_lash = 0; - break; - case 'm': - fluid_settings_setstr(settings, "midi.driver", optarg); - break; - case 'n': - midi_in = 0; - break; - case 'o': - process_o_cmd_line_option(settings, optarg); - break; - case 'p' : - fluid_settings_setstr(settings, "midi.portname", optarg); - break; - case 'R': - if ((optarg != NULL) && ((strcmp(optarg, "0") == 0) || (strcmp(optarg, "no") == 0))) { - fluid_settings_setstr(settings, "synth.reverb.active", "no"); - } else { - fluid_settings_setstr(settings, "synth.reverb.active", "yes"); - } - break; - case 'r': - fluid_settings_setnum(settings, "synth.sample-rate", atof(optarg)); - break; - case 's': - with_server = 1; - break; - case 'V': - printf("FluidSynth %s\n", VERSION); - exit (0); - break; - case 'v': - fluid_settings_setstr(settings, "synth.verbose", "yes"); - break; - case 'z': - fluid_settings_setint(settings, "audio.period-size", atoi(optarg)); - break; -#ifdef GETOPT_SUPPORT - case '?': - printf ("Unknown option %c\n", optopt); - print_usage(); - exit(0); - break; - default: - printf ("?? getopt returned character code 0%o ??\n", c); - break; -#else /* Non getopt default case */ - default: - printf ("Unknown switch '%c'\n", c); - print_usage(); - exit(0); - break; -#endif - } /* end of switch statement */ - } /* end of loop */ - -#ifdef GETOPT_SUPPORT - arg1 = optind; -#else - arg1 = i; -#endif - - /* option help requested? "-o help" */ - if (option_help) - { - print_welcome (); - printf ("FluidSynth settings:\n"); - fluid_settings_foreach (settings, settings, settings_foreach_func); - exit (0); - } - -#ifdef WIN32 - SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); -#endif - -#ifdef LASH_ENABLED - /* connect to the lash server */ - if (connect_lash) - { - enabled_lash = fluid_lash_connect (lash_args); - fluid_settings_setint (settings, "lash.enable", enabled_lash ? 1 : 0); - } -#endif - - /* The 'groups' setting is only relevant for LADSPA operation - * If not given, set number groups to number of audio channels, because - * they are the same (there is nothing between synth output and 'sound card') - */ - if ((audio_groups == 0) && (audio_channels != 0)) { - audio_groups = audio_channels; - } - fluid_settings_setint(settings, "synth.audio-groups", audio_groups); - - /* create the synthesizer */ - synth = new_fluid_synth(settings); - if (synth == NULL) { - fprintf(stderr, "Failed to create the synthesizer\n"); - exit(-1); - } - - cmd_handler = new_fluid_cmd_handler(synth); - if (cmd_handler == NULL) { - fprintf(stderr, "Failed to create the command handler\n"); - goto cleanup; - } - - /* try to load the user or system configuration */ - if (config_file != NULL) { - fluid_source(cmd_handler, config_file); - } else if (fluid_get_userconf(buf, 512) != NULL) { - fluid_source(cmd_handler, buf); - } else if (fluid_get_sysconf(buf, 512) != NULL) { - fluid_source(cmd_handler, buf); - } - - /* load the soundfonts (check that all non options are SoundFont or MIDI files) */ - for (i = arg1; i < argc; i++) { - if (fluid_is_soundfont(argv[i])) - { - if (fluid_synth_sfload(synth, argv[i], 1) == -1) - fprintf(stderr, "Failed to load the SoundFont %s\n", argv[i]); - } - else if (!fluid_is_midifile(argv[i])) - fprintf (stderr, "Parameter '%s' not a SoundFont or MIDI file or error occurred identifying it.\n", - argv[i]); - } - -#ifdef HAVE_SIGNAL_H -/* signal(SIGINT, handle_signal); */ -#endif - - /* start the synthesis thread */ - adriver = new_fluid_audio_driver(settings, synth); - if (adriver == NULL) { - fprintf(stderr, "Failed to create the audio driver\n"); - goto cleanup; - } - - - /* start the midi router and link it to the synth */ -#if WITH_MIDI - if (midi_in) { - /* In dump mode, text output is generated for events going into and out of the router. - * The example dump functions are put into the chain before and after the router.. - */ - - router = new_fluid_midi_router( - settings, - dump ? fluid_midi_dump_postrouter : fluid_synth_handle_midi_event, - (void*)synth); - - if (router == NULL) { - fprintf(stderr, "Failed to create the MIDI input router; no MIDI input\n" - "will be available. You can access the synthesizer \n" - "through the console.\n"); - } else { - fluid_synth_set_midi_router(synth, router); /* Fixme, needed for command handler */ - mdriver = new_fluid_midi_driver( - settings, - dump ? fluid_midi_dump_prerouter : fluid_midi_router_handle_midi_event, - (void*) router); - if (mdriver == NULL) { - fprintf(stderr, "Failed to create the MIDI thread; no MIDI input\n" - "will be available. You can access the synthesizer \n" - "through the console.\n"); - } - } - } -#endif - - /* play the midi files, if any */ - for (i = arg1; i < argc; i++) { - if ((argv[i][0] != '-') && fluid_is_midifile(argv[i])) { - - if (player == NULL) { - player = new_fluid_player(synth); - if (player == NULL) { - fprintf(stderr, "Failed to create the midifile player.\n" - "Continuing without a player.\n"); - break; - } - } - - fluid_player_add(player, argv[i]); - } - } - - if (player != NULL) { - fluid_player_play(player); - } - - /* run the server, if requested */ -#if !defined(MACINTOSH) && !defined(WIN32) && !(defined(__BEOS__) || defined(__HAIKU__)) - if (with_server) { - server = new_fluid_server(settings, newclient, synth); - if (server == NULL) { - fprintf(stderr, "Failed to create the server.\n" - "Continuing without it.\n"); - } - } -#endif - - -#ifdef LASH_ENABLED - if (enabled_lash) - fluid_lash_create_thread (synth); -#endif - - /* run the shell */ - if (interactive) { - print_welcome(); - - printf ("Type 'help' for information on commands and 'help help' for help topics.\n\n"); - - /* In dump mode we set the prompt to "". The UI cannot easily - * handle lines, which don't end with CR. Changing the prompt - * cannot be done through a command, because the current shell - * does not handle empty arguments. The ordinary case is dump == - * 0. - */ - fluid_settings_setstr(settings, "shell.prompt", dump ? "" : "> "); - fluid_usershell(settings, cmd_handler); - } - - cleanup: - -#if !defined(MACINTOSH) && !defined(WIN32) && !(defined(__BEOS__) || defined(__HAIKU__)) - if (server != NULL) { - /* if the user typed 'quit' in the shell, kill the server */ - if (!interactive) { - fluid_server_join(server); - } - delete_fluid_server(server); - } -#endif - - if (cmd_handler != NULL) { - delete_fluid_cmd_handler(cmd_handler); - } - - if (player != NULL) { - /* if the user typed 'quit' in the shell, stop the player */ - if (interactive) { - fluid_player_stop(player); - } - fluid_player_join(player); - delete_fluid_player(player); - } - - if (router) { -#if WITH_MIDI - if (mdriver) { - delete_fluid_midi_driver(mdriver); - } - delete_fluid_midi_router(router); -#endif - } - - if (adriver) { - delete_fluid_audio_driver(adriver); - } - - if (synth) { - delete_fluid_synth(synth); - } - - if (settings) { - delete_fluid_settings(settings); - } - - return 0; -} - -static fluid_cmd_handler_t* newclient(void* data, char* addr) -{ - fluid_synth_t* synth = (fluid_synth_t*) data; - return new_fluid_cmd_handler(synth); -} - - -/* - * print_usage - */ -void -print_usage() -{ - print_welcome (); - fprintf(stderr, "Usage: fluidsynth [options] [soundfonts]\n"); - fprintf(stderr, "Try -h for help.\n"); - exit(0); -} - -/* - * print_welcome - */ -void -print_welcome() -{ - printf("FluidSynth version %s\n" - "Copyright (C) 2000-2006 Peter Hanappe and others.\n" - "Distributed under the LGPL license.\n" - "SoundFont(R) is a registered trademark of E-mu Systems, Inc.\n\n", - FLUIDSYNTH_VERSION); -} - -/* - * print_help - */ -void -print_help() -{ - print_welcome (); - printf("Usage: \n"); - printf(" fluidsynth [options] [soundfonts] [midifiles]\n"); - printf("Possible options:\n"); - printf(" -a, --audio-driver=[label]\n" - " The audio driver [alsa,jack,oss,dsound,...]\n"); - printf(" -C, --chorus\n" - " Turn the chorus on or off [0|1|yes|no, default = on]\n"); - printf(" -c, --audio-bufcount=[count]\n" - " Number of audio buffers\n"); - printf(" -d, --dump\n" - " Dump incoming and outgoing MIDI events to stdout\n"); - printf(" -f, --load-config\n" - " Load command configuration file (shell commands)\n"); - printf(" -G, --audio-groups\n" - " Defines the number of LADSPA audio nodes\n"); - printf(" -g, --gain\n" - " Set the master gain [0 < gain < 10, default = 0.2]\n"); - printf(" -h, --help\n" - " Print out this help summary\n"); - printf(" -i, --no-shell\n" - " Don't read commands from the shell [default = yes]\n"); - printf(" -j, --connect-jack-outputs\n" - " Attempt to connect the jack outputs to the physical ports\n"); - printf(" -K, --midi-channels=[num]\n" - " The number of midi channels [default = 16]\n"); - printf(" -L, --audio-channels=[num]\n" - " The number of stereo audio channels [default = 1]\n"); -#ifdef LASH_ENABLED - printf(" -l, --disable-lash\n" - " Don't connect to LASH server\n"); -#endif - printf(" -m, --midi-driver=[label]\n" - " The name of the midi driver to use [oss,alsa,alsa_seq,...]\n"); - printf(" -n, --no-midi-in\n" - " Don't create a midi driver to read MIDI input events [default = yes]\n"); - printf(" -p, --portname=[label]\n" - " Set MIDI port name (alsa_seq, coremidi drivers)\n"); - printf(" -o\n" - " Define a setting, -o name=value (\"-o help\" to dump current values)\n"); - printf(" -R, --reverb\n" - " Turn the reverb on or off [0|1|yes|no, default = on]\n"); - printf(" -r, --sample-rate\n" - " Set the sample rate\n"); - printf(" -s, --server\n" - " Start FluidSynth as a server process\n"); - printf(" -V, --version\n" - " Show version of program\n"); - printf(" -v, --verbose\n" - " Print out verbose messages about midi events\n"); - printf(" -z, --audio-bufsize=[size]\n" - " Size of each audio buffer\n"); - exit(0); -} diff --git a/src/libs/fluidsynth/src/fluidsynth_priv.h b/src/libs/fluidsynth/src/fluidsynth_priv.h deleted file mode 100644 index 4a12dcd096..0000000000 --- a/src/libs/fluidsynth/src/fluidsynth_priv.h +++ /dev/null @@ -1,311 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - - -#ifndef _FLUIDSYNTH_PRIV_H -#define _FLUIDSYNTH_PRIV_H - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#if defined(__POWERPC__) && !(defined(__APPLE__) && defined(__MACH__)) && !defined(__HAIKU__) -#include "config_maxmsp43.h" -#endif - -#if defined(WIN32) && !defined(MINGW32) -#include "config_win32.h" -#endif - -#if HAVE_STRING_H -#include -#endif - -#if HAVE_STDLIB_H -#include -#endif - -#if HAVE_STDIO_H -#include -#endif - -#if HAVE_MATH_H -#include -#endif - -#if HAVE_ERRNO_H -#include -#endif - -#if HAVE_STDARG_H -#include -#endif - -#if HAVE_UNISTD_H -#include -#endif - -#if HAVE_FCNTL_H -#include -#endif - -#if HAVE_SYS_MMAN_H -#include -#endif - -#if HAVE_SYS_TYPES_H -#include -#endif - -#if HAVE_SYS_STAT_H -#include -#endif - -#if HAVE_SYS_TIME_H -#include -#endif - -#if HAVE_SYS_SOCKET_H -#include -#endif - -#if HAVE_NETINET_IN_H -#include -#endif - -#if HAVE_NETINET_TCP_H -#include -#endif - -#if HAVE_ARPA_INET_H -#include -#endif - -#if HAVE_LIMITS_H -#include -#endif - -#if HAVE_PTHREAD_H -#include -#endif - -#if HAVE_IO_H -#include -#endif - -#if HAVE_WINDOWS_H -#include -#endif - -/* MinGW32 special defines */ -#ifdef MINGW32 - -#include -#define snprintf _snprintf -#define vsnprintf _vsnprintf - -#define DSOUND_SUPPORT 1 -#define WINMIDI_SUPPORT 1 -#define STDIN_FILENO 0 -#define STDOUT_FILENO 1 -#define STDERR_FILENO 2 -#define WITHOUT_SERVER 1 - -#endif - -/* Darwin special defines (taken from config_macosx.h) */ -#ifdef DARWIN -#define MACINTOSH -#define __Types__ -#define WITHOUT_SERVER 1 -#endif - - -#include "fluidsynth.h" - - -/*************************************************************** - * - * BASIC TYPES - */ - -#if defined(WITH_FLOAT) -typedef float fluid_real_t; -#else -typedef double fluid_real_t; -#endif - - -typedef enum { - FLUID_OK = 0, - FLUID_FAILED = -1 -} fluid_status; - - -#if defined(WIN32) -typedef SOCKET fluid_socket_t; -#else -typedef int fluid_socket_t; -#define INVALID_SOCKET -1 -#endif - - -/** Integer types */ - -#if defined(MINGW32) - -/* Windows using MinGW32 */ -typedef int8_t sint8; -typedef uint8_t uint8; -typedef int16_t sint16; -typedef uint16_t uint16; -typedef int32_t sint32; -typedef uint32_t uint32; -typedef int64_t sint64; -typedef uint64_t uint64; - -#elif defined(_WIN32) - -/* Windows */ -typedef signed __int8 sint8; -typedef unsigned __int8 uint8; -typedef signed __int16 sint16; -typedef unsigned __int16 uint16; -typedef signed __int32 sint32; -typedef unsigned __int32 uint32; -typedef signed __int64 sint64; -typedef unsigned __int64 uint64; - -#elif defined(MACOS9) - -/* Macintosh */ -typedef signed char sint8; -typedef unsigned char uint8; -typedef signed short sint16; -typedef unsigned short uint16; -typedef signed int sint32; -typedef unsigned int uint32; -/* FIXME: needs to be verified */ -typedef long long sint64; -typedef unsigned long long uint64; - -#elif (defined(__BEOS__) || defined(__HAIKU__)) -typedef signed char sint8; -typedef signed short sint16; -typedef signed int sint32; -typedef long long sint64; - -#else - -/* Linux & Darwin */ -typedef int8_t sint8; -typedef u_int8_t uint8; -typedef int16_t sint16; -typedef u_int16_t uint16; -typedef int32_t sint32; -typedef u_int32_t uint32; -typedef int64_t sint64; -typedef u_int64_t uint64; - -#endif - - -/*************************************************************** - * - * FORWARD DECLARATIONS - */ -typedef struct _fluid_env_data_t fluid_env_data_t; -typedef struct _fluid_adriver_definition_t fluid_adriver_definition_t; -typedef struct _fluid_channel_t fluid_channel_t; -typedef struct _fluid_tuning_t fluid_tuning_t; -typedef struct _fluid_hashtable_t fluid_hashtable_t; -typedef struct _fluid_client_t fluid_client_t; -typedef struct _fluid_server_socket_t fluid_server_socket_t; - -/*************************************************************** - * - * CONSTANTS - */ - -#define FLUID_BUFSIZE 64 - -#ifndef PI -#define PI 3.141592654 -#endif - -/*************************************************************** - * - * SYSTEM INTERFACE - */ -typedef FILE* fluid_file; - -#define FLUID_MALLOC(_n) malloc(_n) -#define FLUID_REALLOC(_p,_n) realloc(_p,_n) -#define FLUID_NEW(_t) (_t*)malloc(sizeof(_t)) -#define FLUID_ARRAY(_t,_n) (_t*)malloc((_n)*sizeof(_t)) -#define FLUID_FREE(_p) free(_p) -#define FLUID_FOPEN(_f,_m) fopen(_f,_m) -#define FLUID_FCLOSE(_f) fclose(_f) -#define FLUID_FREAD(_p,_s,_n,_f) fread(_p,_s,_n,_f) -#define FLUID_FSEEK(_f,_n,_set) fseek(_f,_n,_set) -#define FLUID_MEMCPY(_dst,_src,_n) memcpy(_dst,_src,_n) -#define FLUID_MEMSET(_s,_c,_n) memset(_s,_c,_n) -#define FLUID_STRLEN(_s) strlen(_s) -#define FLUID_STRCMP(_s,_t) strcmp(_s,_t) -#define FLUID_STRNCMP(_s,_t,_n) strncmp(_s,_t,_n) -#define FLUID_STRCPY(_dst,_src) strcpy(_dst,_src) -#define FLUID_STRCHR(_s,_c) strchr(_s,_c) -#ifdef strdup -#define FLUID_STRDUP(s) strdup(s) -#else -#define FLUID_STRDUP(s) FLUID_STRCPY(FLUID_MALLOC(FLUID_STRLEN(s) + 1), s) -#endif -#define FLUID_SPRINTF sprintf -#define FLUID_FPRINTF fprintf - -#define fluid_clip(_val, _min, _max) \ -{ (_val) = ((_val) < (_min))? (_min) : (((_val) > (_max))? (_max) : (_val)); } - -#if WITH_FTS -#define FLUID_PRINTF post -#define FLUID_FLUSH() -#else -#define FLUID_PRINTF printf -#define FLUID_FLUSH() fflush(stdout) -#endif - -#define FLUID_LOG fluid_log - -#ifndef M_PI -#define M_PI 3.1415926535897932384626433832795 -#endif - - -#define FLUID_ASSERT(a,b) -#define FLUID_ASSERT_P(a,b) - -char* fluid_error(void); - - -/* Internationalization */ -#define _(s) s - - -#endif /* _FLUIDSYNTH_PRIV_H */