mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2025-04-22 23:50:53 +00:00
Merge branch 'master' into sm24
This commit is contained in:
commit
7de0e02a82
51 changed files with 976 additions and 844 deletions
|
@ -28,9 +28,9 @@ set ( CMAKE_EXPORT_COMPILE_COMMANDS 1 )
|
|||
set ( PACKAGE "fluidsynth" )
|
||||
|
||||
# FluidSynth package version
|
||||
set ( FLUIDSYNTH_VERSION_MAJOR 1 )
|
||||
set ( FLUIDSYNTH_VERSION_MINOR 1 )
|
||||
set ( FLUIDSYNTH_VERSION_MICRO 8 )
|
||||
set ( FLUIDSYNTH_VERSION_MAJOR 2 )
|
||||
set ( FLUIDSYNTH_VERSION_MINOR 0 )
|
||||
set ( FLUIDSYNTH_VERSION_MICRO 0 )
|
||||
set ( VERSION "${FLUIDSYNTH_VERSION_MAJOR}.${FLUIDSYNTH_VERSION_MINOR}.${FLUIDSYNTH_VERSION_MICRO}" )
|
||||
set ( FLUIDSYNTH_VERSION "\"${VERSION}\"" )
|
||||
|
||||
|
@ -43,9 +43,9 @@ set ( FLUIDSYNTH_VERSION "\"${VERSION}\"" )
|
|||
# if any interfaces have been added: AGE++
|
||||
# if any interfaces have been removed/changed (compatibility broken): AGE=0
|
||||
# This is not exactly the same algorithm as the libtool one, but the results are the same.
|
||||
set ( LIB_VERSION_CURRENT 1 )
|
||||
set ( LIB_VERSION_AGE 6 )
|
||||
set ( LIB_VERSION_REVISION 1 )
|
||||
set ( LIB_VERSION_CURRENT 2 )
|
||||
set ( LIB_VERSION_AGE 0 )
|
||||
set ( LIB_VERSION_REVISION 0 )
|
||||
set ( LIB_VERSION_INFO
|
||||
"${LIB_VERSION_CURRENT}.${LIB_VERSION_AGE}.${LIB_VERSION_REVISION}" )
|
||||
|
||||
|
@ -158,9 +158,9 @@ if ( CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang" )
|
|||
endif ( OS2 )
|
||||
|
||||
set ( GNUCC_WARNING_FLAGS "-Wall -W -Wpointer-arith -Wbad-function-cast -Wno-cast-qual -Wcast-align -Wstrict-prototypes -Wno-unused-parameter -Wdeclaration-after-statement" )
|
||||
set ( CMAKE_C_FLAGS_DEBUG "-std=gnu89 -g ${GNUCC_VISIBILITY_FLAG} -DDEBUG ${GNUCC_WARNING_FLAGS} -fsanitize=undefined" )
|
||||
set ( CMAKE_C_FLAGS_RELEASE "-std=gnu89 -O2 -fomit-frame-pointer -finline-functions ${GNUCC_VISIBILITY_FLAG} -DNDEBUG ${GNUCC_WARNING_FLAGS}" )
|
||||
set ( CMAKE_C_FLAGS_RELWITHDEBINFO "-std=gnu89 -O2 -g -fomit-frame-pointer -finline-functions ${GNUCC_VISIBILITY_FLAG} -DNDEBUG ${GNUCC_WARNING_FLAGS}" )
|
||||
set ( CMAKE_C_FLAGS_DEBUG "-std=gnu89 -g ${GNUCC_VISIBILITY_FLAG} -DDEBUG ${GNUCC_WARNING_FLAGS} -fsanitize=undefined ${CMAKE_C_FLAGS_DEBUG}" )
|
||||
set ( CMAKE_C_FLAGS_RELEASE "-std=gnu89 -O2 -fomit-frame-pointer -finline-functions ${GNUCC_VISIBILITY_FLAG} -DNDEBUG ${GNUCC_WARNING_FLAGS} ${CMAKE_C_FLAGS_RELEASE}" )
|
||||
set ( CMAKE_C_FLAGS_RELWITHDEBINFO "-std=gnu89 -O2 -g -fomit-frame-pointer -finline-functions ${GNUCC_VISIBILITY_FLAG} -DNDEBUG ${GNUCC_WARNING_FLAGS} ${CMAKE_C_FLAGS_RELWITHDEBINFO}" )
|
||||
endif ( CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang" )
|
||||
|
||||
# Windows
|
||||
|
|
|
@ -88,7 +88,7 @@ FILE_PATTERNS = *.c *.h
|
|||
RECURSIVE = YES
|
||||
EXCLUDE =
|
||||
EXCLUDE_SYMLINKS = NO
|
||||
EXCLUDE_PATTERNS =
|
||||
EXCLUDE_PATTERNS = fluid_*.h
|
||||
EXCLUDE_SYMBOLS =
|
||||
EXAMPLE_PATH = ../doc
|
||||
EXAMPLE_PATTERNS = *.c
|
||||
|
@ -200,7 +200,7 @@ EXPAND_ONLY_PREDEF = NO
|
|||
SEARCH_INCLUDES = YES
|
||||
INCLUDE_PATH =
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED =
|
||||
PREDEFINED = __DOXYGEN__
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
|
|
|
@ -88,7 +88,7 @@ FILE_PATTERNS = *.c *.h
|
|||
RECURSIVE = YES
|
||||
EXCLUDE =
|
||||
EXCLUDE_SYMLINKS = NO
|
||||
EXCLUDE_PATTERNS =
|
||||
EXCLUDE_PATTERNS = fluid_*.h
|
||||
EXCLUDE_SYMBOLS =
|
||||
EXAMPLE_PATH = @CMAKE_SOURCE_DIR@/doc
|
||||
EXAMPLE_PATTERNS = *.c
|
||||
|
@ -200,7 +200,7 @@ EXPAND_ONLY_PREDEF = NO
|
|||
SEARCH_INCLUDES = YES
|
||||
INCLUDE_PATH =
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED =
|
||||
PREDEFINED = __DOXYGEN__
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
|
|
|
@ -114,6 +114,96 @@ https://stackoverflow.com/a/6251757
|
|||
<desc>
|
||||
Sets the minimum note duration in milliseconds. This ensures that really short duration note events, such as percussion notes, have a better chance of sounding as intended. Set to 0 to disable this feature.</desc>
|
||||
</setting>
|
||||
<setting>
|
||||
<name>overflow.age</name>
|
||||
<type>num</type>
|
||||
<def>1000</def>
|
||||
<min>-10000</min>
|
||||
<max>10000</max>
|
||||
<desc>
|
||||
This score is divided by the number of seconds this voice has been
|
||||
active and is added to the overflow priority. It is usually a positive
|
||||
value and gives voices which have just been started a higher priority,
|
||||
making them less likely to be killed in an overflow situation.
|
||||
</desc>
|
||||
</setting>
|
||||
<setting>
|
||||
<name>overflow.important</name>
|
||||
<type>num</type>
|
||||
<def>5000</def>
|
||||
<min>-50000</min>
|
||||
<max>50000</max>
|
||||
<desc>
|
||||
This score is added to voices on channels marked with the
|
||||
synth.overflow.important-channels setting.
|
||||
</desc>
|
||||
</setting>
|
||||
<setting>
|
||||
<name>overflow.important-channels</name>
|
||||
<type>str</type>
|
||||
<def>""</def>
|
||||
<desc>
|
||||
This setting is a comma-separated list of MIDI channel numbers that should
|
||||
be treated as "important" by the overflow calculation, adding the score
|
||||
set by synth.overflow.important to each voice on those channels. It can
|
||||
be used to make voices on particular MIDI channels
|
||||
less likely (synth.overflow.important > 0) or more likely
|
||||
(synth.overflow.important < 0) to be killed in an overflow situation. Channel
|
||||
numbers are 1-based, so the first MIDI channel is number 1.
|
||||
</desc>
|
||||
</setting>
|
||||
<setting>
|
||||
<name>overflow.percussion</name>
|
||||
<type>num</type>
|
||||
<def>4000</def>
|
||||
<min>-10000</min>
|
||||
<max>10000</max>
|
||||
<desc>
|
||||
Sets the overflow priority score added to voices on a percussion
|
||||
channel. This is usually a positive score, to give percussion voices
|
||||
a higher priority and less chance of being killed in an overflow
|
||||
situation.
|
||||
</desc>
|
||||
</setting>
|
||||
<setting>
|
||||
<name>overflow.released</name>
|
||||
<type>num</type>
|
||||
<def>-2000</def>
|
||||
<min>-10000</min>
|
||||
<max>10000</max>
|
||||
<desc>
|
||||
Sets the overflow priority score added to voices that have already
|
||||
received a note-off event. This is usually a negative score, to give released
|
||||
voices a lower priority so that they are killed first in an overflow
|
||||
situation.
|
||||
</desc>
|
||||
</setting>
|
||||
<setting>
|
||||
<name>overflow.sustained</name>
|
||||
<type>num</type>
|
||||
<def>-1000</def>
|
||||
<min>-10000</min>
|
||||
<max>10000</max>
|
||||
<desc>
|
||||
Sets the overflow priority score added to voices that are currently
|
||||
sustained. With the default value, sustained voices are considered less
|
||||
important and are more likely to be killed in an overflow situation.
|
||||
</desc>
|
||||
</setting>
|
||||
<setting>
|
||||
<name>overflow.volume</name>
|
||||
<type>num</type>
|
||||
<def>500</def>
|
||||
<min>-10000</min>
|
||||
<max>10000</max>
|
||||
<desc>
|
||||
Sets the overflow priority score added to voices based on their current
|
||||
volume. The voice volume is normalized to a value between 0 and 1 and
|
||||
multiplied with this setting. So voices with maximum volume get added
|
||||
the full score, voices with only half that volume get added half of this
|
||||
score.
|
||||
</desc>
|
||||
</setting>
|
||||
<setting>
|
||||
<name>parallel-render</name>
|
||||
<type>bool</type>
|
||||
|
|
|
@ -74,33 +74,45 @@ FluidSynths SOVERSION was bumped. The API was reworked, deprecated functions wer
|
|||
|
||||
Changes in FluidSynth 2.0.0 concerning developers:
|
||||
|
||||
- remove deprecated fluid_synth_get_program() and fluid_synth_get_channel_preset(), use fluid_synth_get_channel_info() instead
|
||||
- remove deprecated fluid_synth_get_channel_info() in favour of fluid_synth_get_program() and fluid_synth_get_channel_preset()
|
||||
- remove deprecated fluid_settings_getstr()
|
||||
- remove deprecated fluid_synth_set_midi_router()
|
||||
- remove deprecated fluid_get_hinstance() and fluid_set_hinstance() (dsound driver now uses the desktop window)
|
||||
- remove deprecated fluid_synth_create_key_tuning(), use fluid_synth_activate_key_tuning(synth, bank, prog, name, pitch, FALSE) instead
|
||||
- remove deprecated fluid_synth_create_octave_tuning(), use fluid_synth_activate_octave_tuning(synth, bank, prog, name, pitch, FALSE) instead
|
||||
- remove deprecated fluid_synth_select_tuning(), use fluid_synth_activate_tuning(synth, chan, bank, prog, FALSE) instead
|
||||
- remove deprecated fluid_synth_reset_tuning(), use fluid_synth_deactivate_tuning(synth, chan, FALSE) instead
|
||||
- remove deprecated FLUID_HINT_INTEGER
|
||||
- remove misspelled FLUID_SEQ_PITCHWHHELSENS macro
|
||||
- remove obsolete "audio.[out|in]put-channels" settings
|
||||
- remove unimplemented "synth.dump" setting
|
||||
- remove fluid_synth_set_gen2(), fluid_synth_set_gen() now behaves as fluid_synth_set_gen2()
|
||||
- remove struct fluid_mod_t from public API, use the getters and setters of mod.h instead
|
||||
- remove struct _fluid_mod_t from public API, use the getters and setters of mod.h instead
|
||||
- remove struct _fluid_gen_t, fluid_gen_set_default_values() and enum fluid_gen_flags from public API
|
||||
- remove macros fluid_sfont_get_id() and fluid_sample_refcount() from public API
|
||||
- remove FLUID_NUM_MOD macro from public API
|
||||
- remove the following deprecated enum values:
|
||||
- GEN_LAST
|
||||
- LAST_LOG_LEVEL
|
||||
- FLUID_SEQ_LASTEVENT
|
||||
- FLUID_MIDI_ROUTER_RULE_COUNT
|
||||
<br /><br />
|
||||
- all public \c fluid_settings_* functions that return an integer which is not meant to be interpreted as bool consistently return either FLUID_OK or FLUID_FAILED
|
||||
- all public delete_* functions return void and are safe when called with NULL
|
||||
- the shell command handler was decoupled internally, as a consequence the param list of new_fluid_server() and new_fluid_cmd_handler() was adapted
|
||||
- reverb: roomsize is now limited to an upper threshold of 1.0
|
||||
- use unique device names for the "audio.portaudio.device" setting
|
||||
- rename fluid_mod_new() and fluid_mod_delete() to match naming conventions: new_fluid_mod() and delete_fluid_mod()
|
||||
<br /><br />
|
||||
- add "synth.volenv" a setting for volume envelope processing
|
||||
- add "midi.autoconnect" a setting for automatically connecting fluidsynth to available MIDI input ports
|
||||
- add support for polyonic key pressure events, see fluid_event_key_pressure()
|
||||
- add support for polyphonic key pressure events, see fluid_event_key_pressure() and fluid_synth_key_pressure()
|
||||
- add fluid_synth_add_default_mod() and fluid_synth_remove_default_mod() for manipulating default modulators
|
||||
- add individual reverb setters: fluid_synth_set_reverb_roomsize(), fluid_synth_set_reverb_damp(), fluid_synth_set_reverb_width(), fluid_synth_set_reverb_level()
|
||||
- add individual chorus setters: fluid_synth_set_chorus_nr(), fluid_synth_set_chorus_level(), fluid_synth_set_chorus_speed(), fluid_synth_set_chorus_depth(), fluid_synth_set_chorus_type()
|
||||
- introduce a separate data type for sequencer client IDs: #fluid_seq_id_t
|
||||
- add file callback struct to _fluid_sfloader_t and expose new_fluid_defsfloader() to enable soundfont loading from memory ( see fluid_sfload_mem.c )
|
||||
|
||||
- add seek support to midi-player, see fluid_player_seek()
|
||||
- expose functions to manipulate the ladspa effects unit (see ladspa.h)
|
||||
|
||||
\section NewIn1_1_9 Whats new in 1.1.9?
|
||||
|
||||
|
|
|
@ -59,7 +59,9 @@ enum fluid_seq_event_type {
|
|||
FLUID_SEQ_KEYPRESSURE, /**< Polyphonic aftertouch event @since 2.0.0 */
|
||||
FLUID_SEQ_SYSTEMRESET, /**< System reset event @since 1.1.0 */
|
||||
FLUID_SEQ_UNREGISTERING, /**< Called when a sequencer client is being unregistered. @since 1.1.0 */
|
||||
FLUID_SEQ_LASTEVENT /**< Defines the count of event enums @deprecated As of 1.1.7 this enum value is deprecated and will be removed in a future release, because it prevents adding new enum values without breaking ABI compatibility. */
|
||||
#ifndef __DOXYGEN__
|
||||
FLUID_SEQ_LASTEVENT /**< @internal Defines the count of events enums @warning This symbol is not part of the public API and ABI stability guarantee and may change at any time! */
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Event alloc/free */
|
||||
|
|
|
@ -99,7 +99,9 @@ enum fluid_gen_type {
|
|||
* 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) @deprecated As of 1.1.7 this enum value is deprecated and will be removed in a future release, because it prevents adding new enum values without breaking ABI compatibility. */
|
||||
#ifndef __DOXYGEN__
|
||||
GEN_LAST /**< @internal Value defines the count of generators (#fluid_gen_type) @warning This symbol is not part of the public API and ABI stability guarantee and may change at any time! */
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -25,6 +25,17 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file ladspa.h
|
||||
* @brief Functions for manipulating the ladspa effects unit
|
||||
*
|
||||
* This header defines useful functions for programatically manipulating the ladspa
|
||||
* effects unit of the synth that can be retrieved via fluid_synth_get_ladspa_fx().
|
||||
*
|
||||
* Using any of those functions requires fluidsynth to be compiled with ladspa support.
|
||||
* Else all of those functions are useless dummies.
|
||||
*/
|
||||
|
||||
FLUIDSYNTH_API int fluid_ladspa_is_active(fluid_ladspa_fx_t *fx);
|
||||
FLUIDSYNTH_API int fluid_ladspa_activate(fluid_ladspa_fx_t *fx);
|
||||
FLUIDSYNTH_API int fluid_ladspa_deactivate(fluid_ladspa_fx_t *fx);
|
||||
|
|
|
@ -58,7 +58,9 @@ enum fluid_log_level {
|
|||
FLUID_WARN, /**< Warning */
|
||||
FLUID_INFO, /**< Verbose informational messages */
|
||||
FLUID_DBG, /**< Debugging messages */
|
||||
LAST_LOG_LEVEL /**< @deprecated As of 1.1.7 this enum value is deprecated and will be removed in a future release, because it prevents adding new enum values without breaking ABI compatibility. */
|
||||
#ifndef __DOXYGEN__
|
||||
LAST_LOG_LEVEL /**< @warning This symbol is not part of the public API and ABI stability guarantee and may change at any time! */
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -64,7 +64,9 @@ typedef enum
|
|||
FLUID_MIDI_ROUTER_RULE_PITCH_BEND, /**< MIDI pitch bend rule */
|
||||
FLUID_MIDI_ROUTER_RULE_CHANNEL_PRESSURE, /**< MIDI channel pressure rule */
|
||||
FLUID_MIDI_ROUTER_RULE_KEY_PRESSURE, /**< MIDI key pressure rule */
|
||||
FLUID_MIDI_ROUTER_RULE_COUNT /**< Total count of rule types */
|
||||
#ifndef __DOXYGEN__
|
||||
FLUID_MIDI_ROUTER_RULE_COUNT /**< @internal Total count of rule types @warning This symbol is not part of the public API and ABI stability guarantee and may change at any time!*/
|
||||
#endif
|
||||
} fluid_midi_router_rule_type;
|
||||
|
||||
/**
|
||||
|
|
|
@ -30,7 +30,6 @@ extern "C" {
|
|||
* @brief SoundFont modulator functions and constants.
|
||||
*/
|
||||
|
||||
#define FLUID_NUM_MOD 64 /**< Maximum number of modulators in a voice */
|
||||
|
||||
/**
|
||||
* Flags defining the polarity, mapping function and type of a modulator source.
|
||||
|
@ -68,8 +67,8 @@ enum fluid_mod_src
|
|||
FLUID_MOD_PITCHWHEELSENS = 16 /**< Pitch wheel sensitivity */
|
||||
};
|
||||
|
||||
FLUIDSYNTH_API fluid_mod_t* fluid_mod_new(void);
|
||||
FLUIDSYNTH_API void fluid_mod_delete(fluid_mod_t * mod);
|
||||
FLUIDSYNTH_API fluid_mod_t* new_fluid_mod(void);
|
||||
FLUIDSYNTH_API void delete_fluid_mod(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);
|
||||
|
|
|
@ -70,6 +70,18 @@ enum {
|
|||
FLUID_SAMPLE_DONE /**< Sample no longer needed notify */
|
||||
};
|
||||
|
||||
/**
|
||||
* Indicates the type of a sample used by the _fluid_sample_t::sampletype field.
|
||||
*/
|
||||
enum fluid_sample_type
|
||||
{
|
||||
FLUID_SAMPLETYPE_MONO = 0x1, /**< Used for mono samples */
|
||||
FLUID_SAMPLETYPE_RIGHT = 0x2, /**< Used for right samples of a stereo pair */
|
||||
FLUID_SAMPLETYPE_LEFT = 0x4, /**< Used for left samples of a stereo pair */
|
||||
FLUID_SAMPLETYPE_LINKED = 0x8, /**< Currently not used */
|
||||
FLUID_SAMPLETYPE_OGG_VORBIS = 0x10, /**< Used for Ogg Vorbis compressed samples @since 1.1.7 */
|
||||
FLUID_SAMPLETYPE_ROM = 0x8000 /**< Indicates ROM samples, causes sample to be ignored */
|
||||
};
|
||||
|
||||
/**
|
||||
* SoundFont loader structure.
|
||||
|
@ -191,7 +203,6 @@ struct _fluid_sfont_t {
|
|||
int (*iteration_next)(fluid_sfont_t* sfont, fluid_preset_t* preset);
|
||||
};
|
||||
|
||||
#define fluid_sfont_get_id(_sf) ((_sf)->id)
|
||||
|
||||
/**
|
||||
* Virtual SoundFont preset.
|
||||
|
@ -284,7 +295,7 @@ struct _fluid_sample_t
|
|||
unsigned int samplerate; /**< Sample rate */
|
||||
int origpitch; /**< Original pitch (MIDI note number, 0-127) */
|
||||
int pitchadj; /**< Fine pitch adjustment (+/- 99 cents) */
|
||||
int sampletype; /**< Values: #FLUID_SAMPLETYPE_MONO, FLUID_SAMPLETYPE_RIGHT, FLUID_SAMPLETYPE_LEFT, FLUID_SAMPLETYPE_ROM */
|
||||
int sampletype; /**< Specifies the type of this sample as indicated by the #fluid_sample_type enum */
|
||||
int valid; /**< Should be TRUE if sample data is valid, FALSE otherwise (in which case it will not be synthesized) */
|
||||
short* data; /**< Pointer to the sample's 16 bit PCM data */
|
||||
char* data24; /**< If not NULL, pointer to the sample's contains the least significant byte counterparts to each sample data point */
|
||||
|
@ -292,7 +303,7 @@ struct _fluid_sample_t
|
|||
int amplitude_that_reaches_noise_floor_is_valid; /**< Indicates if \a amplitude_that_reaches_noise_floor is valid (TRUE), set to FALSE initially to calculate. */
|
||||
double amplitude_that_reaches_noise_floor; /**< The amplitude at which the sample's loop will be below the noise floor. For voice off optimization, calculated automatically. */
|
||||
|
||||
unsigned int refcount; /**< Count of voices using this sample (use #fluid_sample_refcount to access this field) */
|
||||
unsigned int refcount; /**< Count of voices using this sample */
|
||||
|
||||
/**
|
||||
* Implement this function to receive notification when sample is no longer used.
|
||||
|
@ -306,18 +317,6 @@ struct _fluid_sample_t
|
|||
};
|
||||
|
||||
|
||||
#define fluid_sample_refcount(_sample) ((_sample)->refcount) /**< Get the reference count of a sample. Should only be called from within synthesis context (noteon method for example) */
|
||||
|
||||
|
||||
#define FLUID_SAMPLETYPE_MONO 1 /**< Flag for #fluid_sample_t \a sampletype field for mono samples */
|
||||
#define FLUID_SAMPLETYPE_RIGHT 2 /**< Flag for #fluid_sample_t \a sampletype field for right samples of a stereo pair */
|
||||
#define FLUID_SAMPLETYPE_LEFT 4 /**< Flag for #fluid_sample_t \a sampletype field for left samples of a stereo pair */
|
||||
#define FLUID_SAMPLETYPE_LINKED 8 /**< Flag for #fluid_sample_t \a sampletype field, not used currently */
|
||||
#define FLUID_SAMPLETYPE_OGG_VORBIS 0x10 /**< Flag for #fluid_sample_t \a sampletype field for Ogg Vorbis compressed samples @since 1.1.7 */
|
||||
#define FLUID_SAMPLETYPE_ROM 0x8000 /**< Flag for #fluid_sample_t \a sampletype field, ROM sample, causes sample to be ignored */
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -45,22 +45,6 @@ extern "C" {
|
|||
* fluid_synth_noteon(), fluid_synth_noteoff(), ...
|
||||
*/
|
||||
|
||||
#define FLUID_SYNTH_CHANNEL_INFO_NAME_SIZE 32 /**< Length of channel info name field (including zero terminator) */
|
||||
|
||||
/**
|
||||
* Channel information structure for fluid_synth_get_channel_info().
|
||||
* @since 2.0.0
|
||||
*/
|
||||
struct _fluid_synth_channel_info_t
|
||||
{
|
||||
int assigned : 1; /**< TRUE if a preset is assigned, FALSE otherwise */
|
||||
/* Reserved flag bits (at the least 31) */
|
||||
int sfont_id; /**< ID of parent SoundFont */
|
||||
int bank; /**< MIDI bank number (0-16383) */
|
||||
int program; /**< MIDI program number (0-127) */
|
||||
char name[FLUID_SYNTH_CHANNEL_INFO_NAME_SIZE]; /**< Channel preset name */
|
||||
char reserved[32]; /**< Reserved data for future expansion */
|
||||
};
|
||||
|
||||
FLUIDSYNTH_API fluid_synth_t* new_fluid_synth(fluid_settings_t* settings);
|
||||
FLUIDSYNTH_API void delete_fluid_synth(fluid_synth_t* synth);
|
||||
|
@ -95,9 +79,6 @@ 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);
|
||||
FLUIDSYNTH_API int fluid_synth_unset_program (fluid_synth_t *synth, int chan);
|
||||
FLUIDSYNTH_API
|
||||
FLUID_DEPRECATED
|
||||
int fluid_synth_get_channel_info (fluid_synth_t *synth, int chan, fluid_synth_channel_info_t *info);
|
||||
FLUIDSYNTH_API int fluid_synth_program_reset(fluid_synth_t* synth);
|
||||
FLUIDSYNTH_API int fluid_synth_system_reset(fluid_synth_t* synth);
|
||||
|
||||
|
@ -237,6 +218,8 @@ enum fluid_interp {
|
|||
/* Generator interface */
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_set_gen (fluid_synth_t* synth, int chan,
|
||||
int param, float value);
|
||||
FLUIDSYNTH_API int fluid_synth_set_gen2 (fluid_synth_t* synth, int chan,
|
||||
int param, float value,
|
||||
int absolute, int normalized);
|
||||
FLUIDSYNTH_API float fluid_synth_get_gen(fluid_synth_t* synth, int chan, int param);
|
||||
|
@ -244,33 +227,19 @@ FLUIDSYNTH_API float fluid_synth_get_gen(fluid_synth_t* synth, int chan, int par
|
|||
|
||||
/* Tuning */
|
||||
|
||||
FLUIDSYNTH_API
|
||||
FLUID_DEPRECATED
|
||||
int fluid_synth_create_key_tuning(fluid_synth_t* synth, int bank, int prog,
|
||||
const char* name, const double* pitch);
|
||||
FLUIDSYNTH_API
|
||||
int fluid_synth_activate_key_tuning(fluid_synth_t* synth, int bank, int prog,
|
||||
const char* name, const double* pitch, int apply);
|
||||
FLUIDSYNTH_API
|
||||
FLUID_DEPRECATED
|
||||
int fluid_synth_create_octave_tuning(fluid_synth_t* synth, int bank, int prog,
|
||||
const char* name, const double* pitch);
|
||||
FLUIDSYNTH_API
|
||||
int fluid_synth_activate_octave_tuning(fluid_synth_t* synth, int bank, int prog,
|
||||
const char* name, const double* pitch, int apply);
|
||||
FLUIDSYNTH_API
|
||||
int fluid_synth_tune_notes(fluid_synth_t* synth, int bank, int prog,
|
||||
int len, const int *keys, const double* pitch, int apply);
|
||||
FLUIDSYNTH_API
|
||||
FLUID_DEPRECATED
|
||||
int fluid_synth_select_tuning(fluid_synth_t* synth, int chan, int bank, int prog);
|
||||
FLUIDSYNTH_API
|
||||
int fluid_synth_activate_tuning(fluid_synth_t* synth, int chan, int bank, int prog,
|
||||
int apply);
|
||||
FLUIDSYNTH_API
|
||||
FLUID_DEPRECATED
|
||||
int fluid_synth_reset_tuning(fluid_synth_t* synth, int chan);
|
||||
FLUIDSYNTH_API
|
||||
int fluid_synth_deactivate_tuning(fluid_synth_t* synth, int chan, int apply);
|
||||
FLUIDSYNTH_API void fluid_synth_tuning_iteration_start(fluid_synth_t* synth);
|
||||
FLUIDSYNTH_API
|
||||
|
@ -343,9 +312,6 @@ FLUIDSYNTH_API void fluid_synth_start_voice(fluid_synth_t* synth, fluid_voice_t*
|
|||
FLUIDSYNTH_API void fluid_synth_get_voicelist(fluid_synth_t* synth,
|
||||
fluid_voice_t* buf[], int bufsize, int ID);
|
||||
FLUIDSYNTH_API int fluid_synth_handle_midi_event(void* data, fluid_midi_event_t* event);
|
||||
FLUIDSYNTH_API
|
||||
FLUID_DEPRECATED
|
||||
void fluid_synth_set_midi_router(fluid_synth_t* synth, fluid_midi_router_t* router);
|
||||
|
||||
/* LADSPA */
|
||||
|
||||
|
|
|
@ -35,7 +35,6 @@ extern "C" {
|
|||
|
||||
typedef struct _fluid_hashtable_t fluid_settings_t; /**< Configuration settings instance */
|
||||
typedef struct _fluid_synth_t fluid_synth_t; /**< Synthesizer instance */
|
||||
typedef struct _fluid_synth_channel_info_t fluid_synth_channel_info_t; /**< SoundFont channel info */
|
||||
typedef struct _fluid_voice_t fluid_voice_t; /**< Synthesis voice instance */
|
||||
typedef struct _fluid_sfloader_t fluid_sfloader_t; /**< SoundFont loader plugin */
|
||||
typedef struct _fluid_sfont_t fluid_sfont_t; /**< SoundFont */
|
||||
|
|
|
@ -36,8 +36,6 @@ extern "C" {
|
|||
*/
|
||||
|
||||
|
||||
FLUIDSYNTH_API void fluid_voice_update_param(fluid_voice_t* voice, int gen);
|
||||
|
||||
/**
|
||||
* Enum used with fluid_voice_add_mod() to specify how to handle duplicate modulators.
|
||||
*/
|
||||
|
@ -48,21 +46,22 @@ enum fluid_voice_add_mod {
|
|||
};
|
||||
|
||||
FLUIDSYNTH_API void fluid_voice_add_mod(fluid_voice_t* voice, fluid_mod_t* mod, int mode);
|
||||
FLUIDSYNTH_API void fluid_voice_gen_set(fluid_voice_t* voice, int gen, float val);
|
||||
FLUIDSYNTH_API float fluid_voice_gen_get(fluid_voice_t* voice, int gen);
|
||||
FLUIDSYNTH_API void fluid_voice_gen_set(fluid_voice_t* voice, int gen, float val);
|
||||
FLUIDSYNTH_API void fluid_voice_gen_incr(fluid_voice_t* voice, int gen, float val);
|
||||
|
||||
FLUIDSYNTH_API unsigned int fluid_voice_get_id(const fluid_voice_t* voice);
|
||||
FLUIDSYNTH_API int fluid_voice_get_channel(const fluid_voice_t* voice);
|
||||
FLUIDSYNTH_API int fluid_voice_get_key(const fluid_voice_t* voice);
|
||||
FLUIDSYNTH_API int fluid_voice_get_actual_key(const fluid_voice_t* voice);
|
||||
FLUIDSYNTH_API int fluid_voice_get_velocity(const fluid_voice_t* voice);
|
||||
FLUIDSYNTH_API int fluid_voice_get_actual_velocity(const fluid_voice_t* voice);
|
||||
FLUIDSYNTH_API int fluid_voice_is_playing(const fluid_voice_t* voice);
|
||||
FLUIDSYNTH_API int fluid_voice_is_on(const fluid_voice_t* voice);
|
||||
FLUIDSYNTH_API int fluid_voice_is_sustained(const fluid_voice_t* voice);
|
||||
FLUIDSYNTH_API int fluid_voice_is_sostenuto(const fluid_voice_t* voice);
|
||||
FLUIDSYNTH_API int fluid_voice_get_channel(const fluid_voice_t* voice);
|
||||
FLUIDSYNTH_API int fluid_voice_get_actual_key(const fluid_voice_t* voice);
|
||||
FLUIDSYNTH_API int fluid_voice_get_key(const fluid_voice_t* voice);
|
||||
FLUIDSYNTH_API int fluid_voice_get_actual_velocity(const fluid_voice_t* voice);
|
||||
FLUIDSYNTH_API int fluid_voice_get_velocity(const fluid_voice_t* voice);
|
||||
FLUIDSYNTH_API int fluid_voice_optimize_sample(fluid_sample_t* s);
|
||||
FLUIDSYNTH_API int fluid_voice_optimize_sample(fluid_sample_t* s);
|
||||
FLUIDSYNTH_API void fluid_voice_update_param(fluid_voice_t* voice, int gen);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -80,8 +80,8 @@ static int fluid_handle_voice_count (void* data, int ac, char **av,
|
|||
|
||||
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);
|
||||
fluid_settings_register_str(settings, "shell.prompt", "", 0);
|
||||
fluid_settings_register_int(settings, "shell.port", 9800, 1, 65535, 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1363,9 +1363,9 @@ fluid_handle_set(void* data, int ac, char** av, fluid_ostream_t out)
|
|||
if (fluid_settings_get_hints (handler->synth->settings, av[0], &hints) == FLUID_OK
|
||||
&& hints & FLUID_HINT_TOGGLED)
|
||||
{
|
||||
if (FLUID_STRCMP (av[1], "yes") == 0 || FLUID_STRCMP (av[1], "True") == 0
|
||||
|| FLUID_STRCMP (av[1], "TRUE") == 0 || FLUID_STRCMP (av[1], "true") == 0
|
||||
|| FLUID_STRCMP (av[1], "T") == 0)
|
||||
if (FLUID_STRCASECMP (av[1], "yes") == 0
|
||||
|| FLUID_STRCASECMP (av[1], "true") == 0
|
||||
|| FLUID_STRCASECMP (av[1], "t") == 0)
|
||||
ival = 1;
|
||||
else ival = atoi (av[1]);
|
||||
}
|
||||
|
|
|
@ -22,10 +22,8 @@
|
|||
* Low-level routines for file output.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "fluidsynth_priv.h"
|
||||
#include "fluid_synth.h"
|
||||
#include "fluid_sys.h"
|
||||
#include "fluid_synth.h"
|
||||
#include "fluid_settings.h"
|
||||
|
||||
#if LIBSNDFILE_SUPPORT
|
||||
|
@ -113,10 +111,10 @@ fluid_file_renderer_settings (fluid_settings_t* settings)
|
|||
unsigned int n;
|
||||
|
||||
fluid_settings_register_str(settings, "audio.file.name", "fluidsynth.wav",
|
||||
FLUID_HINT_FILENAME, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "audio.file.type", "auto", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "audio.file.format", "s16", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "audio.file.endian", "auto", 0, NULL, NULL);
|
||||
FLUID_HINT_FILENAME);
|
||||
fluid_settings_register_str(settings, "audio.file.type", "auto", 0);
|
||||
fluid_settings_register_str(settings, "audio.file.format", "s16", 0);
|
||||
fluid_settings_register_str(settings, "audio.file.endian", "auto", 0);
|
||||
|
||||
fluid_settings_add_option (settings, "audio.file.type", "auto");
|
||||
|
||||
|
@ -149,12 +147,12 @@ fluid_file_renderer_settings (fluid_settings_t* settings)
|
|||
|
||||
#else
|
||||
|
||||
fluid_settings_register_str(settings, "audio.file.name", "fluidsynth.raw", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "audio.file.type", "raw", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "audio.file.name", "fluidsynth.raw", 0);
|
||||
fluid_settings_register_str(settings, "audio.file.type", "raw", 0);
|
||||
fluid_settings_add_option (settings, "audio.file.type", "raw");
|
||||
fluid_settings_register_str(settings, "audio.file.format", "s16", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "audio.file.format", "s16", 0);
|
||||
fluid_settings_add_option (settings, "audio.file.format", "s16");
|
||||
fluid_settings_register_str(settings, "audio.file.endian", "cpu", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "audio.file.endian", "cpu", 0);
|
||||
fluid_settings_add_option (settings, "audio.file.endian", "cpu");
|
||||
#endif
|
||||
}
|
||||
|
@ -290,10 +288,10 @@ new_fluid_file_renderer(fluid_synth_t* synth)
|
|||
* @since 1.1.7
|
||||
*/
|
||||
int
|
||||
fluid_file_set_encoding_quality(fluid_file_renderer_t* r, double q)
|
||||
fluid_file_set_encoding_quality(fluid_file_renderer_t* dev, double q)
|
||||
{
|
||||
#if LIBSNDFILE_SUPPORT
|
||||
if (sf_command (r->sndfile, SFC_SET_VBR_ENCODING_QUALITY, &q, sizeof (double)) == SF_TRUE)
|
||||
if (sf_command (dev->sndfile, SFC_SET_VBR_ENCODING_QUALITY, &q, sizeof (double)) == SF_TRUE)
|
||||
return FLUID_OK;
|
||||
else
|
||||
#endif
|
||||
|
@ -455,7 +453,6 @@ fluid_file_renderer_parse_options (char *filetype, char *format, char *endian,
|
|||
/**
|
||||
* Searches for a supported libsndfile file type by extension.
|
||||
* @param extension The extension string
|
||||
* @param ext_len Length of the extension string
|
||||
* @param type Location to store the type (unmodified if not found)
|
||||
* @return TRUE if found, FALSE otherwise
|
||||
*/
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
#include "fluid_ladspa.h"
|
||||
|
||||
#ifdef LADSPA
|
||||
#if defined(LADSPA) || defined(__DOXYGEN__)
|
||||
|
||||
#include <math.h>
|
||||
#include <ladspa.h>
|
||||
|
|
|
@ -268,47 +268,47 @@ void fluid_audio_driver_settings(fluid_settings_t* settings)
|
|||
{
|
||||
unsigned int i;
|
||||
|
||||
fluid_settings_register_str(settings, "audio.sample-format", "16bits", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "audio.sample-format", "16bits", 0);
|
||||
fluid_settings_add_option(settings, "audio.sample-format", "16bits");
|
||||
fluid_settings_add_option(settings, "audio.sample-format", "float");
|
||||
|
||||
#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);
|
||||
fluid_settings_register_int(settings, "audio.period-size", 512, 64, 8192, 0);
|
||||
fluid_settings_register_int(settings, "audio.periods", 8, 2, 64, 0);
|
||||
#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);
|
||||
fluid_settings_register_int(settings, "audio.period-size", 64, 64, 8192, 0);
|
||||
fluid_settings_register_int(settings, "audio.periods", 8, 2, 64, 0);
|
||||
#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);
|
||||
fluid_settings_register_int(settings, "audio.period-size", 64, 64, 8192, 0);
|
||||
fluid_settings_register_int(settings, "audio.periods", 16, 2, 64, 0);
|
||||
#endif
|
||||
|
||||
fluid_settings_register_int (settings, "audio.realtime-prio",
|
||||
FLUID_DEFAULT_AUDIO_RT_PRIO, 0, 99, 0, NULL, NULL);
|
||||
FLUID_DEFAULT_AUDIO_RT_PRIO, 0, 99, 0);
|
||||
|
||||
/* Set the default driver */
|
||||
#if JACK_SUPPORT
|
||||
fluid_settings_register_str(settings, "audio.driver", "jack", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "audio.driver", "jack", 0);
|
||||
#elif ALSA_SUPPORT
|
||||
fluid_settings_register_str(settings, "audio.driver", "alsa", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "audio.driver", "alsa", 0);
|
||||
#elif PULSE_SUPPORT
|
||||
fluid_settings_register_str(settings, "audio.driver", "pulseaudio", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "audio.driver", "pulseaudio", 0);
|
||||
#elif OSS_SUPPORT
|
||||
fluid_settings_register_str(settings, "audio.driver", "oss", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "audio.driver", "oss", 0);
|
||||
#elif COREAUDIO_SUPPORT
|
||||
fluid_settings_register_str(settings, "audio.driver", "coreaudio", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "audio.driver", "coreaudio", 0);
|
||||
#elif DSOUND_SUPPORT
|
||||
fluid_settings_register_str(settings, "audio.driver", "dsound", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "audio.driver", "dsound", 0);
|
||||
#elif SNDMAN_SUPPORT
|
||||
fluid_settings_register_str(settings, "audio.driver", "sndman", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "audio.driver", "sndman", 0);
|
||||
#elif PORTAUDIO_SUPPORT
|
||||
fluid_settings_register_str(settings, "audio.driver", "portaudio", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "audio.driver", "portaudio", 0);
|
||||
#elif DART_SUPPORT
|
||||
fluid_settings_register_str(settings, "audio.driver", "dart", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "audio.driver", "dart", 0);
|
||||
#elif AUFILE_SUPPORT
|
||||
fluid_settings_register_str(settings, "audio.driver", "file", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "audio.driver", "file", 0);
|
||||
#else
|
||||
fluid_settings_register_str(settings, "audio.driver", "", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "audio.driver", "", 0);
|
||||
#endif
|
||||
|
||||
/* Add all drivers to the list of options */
|
||||
|
|
|
@ -34,13 +34,7 @@
|
|||
|
||||
#define ALSA_PCM_NEW_HW_PARAMS_API
|
||||
#include <alsa/asoundlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/poll.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "fluid_lash.h"
|
||||
|
||||
|
@ -151,7 +145,7 @@ static fluid_thread_return_t fluid_alsa_seq_run(void* d);
|
|||
|
||||
void fluid_alsa_audio_driver_settings(fluid_settings_t* settings)
|
||||
{
|
||||
fluid_settings_register_str(settings, "audio.alsa.device", "default", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "audio.alsa.device", "default", 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -548,7 +542,7 @@ static fluid_thread_return_t fluid_alsa_audio_run_s16 (void *d)
|
|||
|
||||
void fluid_alsa_rawmidi_driver_settings(fluid_settings_t* settings)
|
||||
{
|
||||
fluid_settings_register_str(settings, "midi.alsa.device", "default", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "midi.alsa.device", "default", 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -715,8 +709,8 @@ fluid_alsa_midi_run(void* d)
|
|||
|
||||
void fluid_alsa_seq_driver_settings(fluid_settings_t* settings)
|
||||
{
|
||||
fluid_settings_register_str(settings, "midi.alsa_seq.device", "default", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "midi.alsa_seq.id", "pid", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "midi.alsa_seq.device", "default", 0);
|
||||
fluid_settings_register_str(settings, "midi.alsa_seq.id", "pid", 0);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -24,11 +24,9 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include "fluid_sys.h"
|
||||
#include "fluid_adriver.h"
|
||||
#include "fluid_settings.h"
|
||||
#include "fluid_sys.h"
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
/** fluid_file_audio_driver_t
|
||||
|
|
|
@ -30,8 +30,6 @@
|
|||
#include "fluid_mdriver.h"
|
||||
#include "fluid_settings.h"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#if COREAUDIO_SUPPORT
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
|
@ -111,7 +109,7 @@ fluid_core_audio_driver_settings(fluid_settings_t* settings)
|
|||
pa.mScope = kAudioObjectPropertyScopeWildcard;
|
||||
pa.mElement = kAudioObjectPropertyElementMaster;
|
||||
|
||||
fluid_settings_register_str (settings, "audio.coreaudio.device", "default", 0, NULL, NULL);
|
||||
fluid_settings_register_str (settings, "audio.coreaudio.device", "default", 0);
|
||||
fluid_settings_add_option (settings, "audio.coreaudio.device", "default");
|
||||
if (OK (AudioObjectGetPropertyDataSize (kAudioObjectSystemObject, &pa, 0, 0, &size))) {
|
||||
int num = size / (int) sizeof (AudioDeviceID);
|
||||
|
|
|
@ -66,7 +66,7 @@ void fluid_coremidi_callback(const MIDIPacketList *list, void *p, void *src);
|
|||
|
||||
void fluid_coremidi_driver_settings(fluid_settings_t* settings)
|
||||
{
|
||||
fluid_settings_register_str(settings, "midi.coremidi.id", "pid", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "midi.coremidi.id", "pid", 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -75,7 +75,7 @@ static LONG APIENTRY fluid_dart_audio_run( ULONG ulStatus, PMCI_MIX_BUFFER pBuff
|
|||
|
||||
void fluid_dart_audio_driver_settings(fluid_settings_t* settings)
|
||||
{
|
||||
fluid_settings_register_str(settings, "audio.dart.device", "default", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "audio.dart.device", "default", 0);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ fluid_dsound_enum_callback2(LPGUID guid, LPCTSTR description, LPCTSTR module, LP
|
|||
|
||||
void fluid_dsound_audio_driver_settings(fluid_settings_t* settings)
|
||||
{
|
||||
fluid_settings_register_str(settings, "audio.dsound.device", "default", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "audio.dsound.device", "default", 0);
|
||||
fluid_settings_add_option(settings, "audio.dsound.device", "default");
|
||||
DirectSoundEnumerate((LPDSENUMCALLBACK) fluid_dsound_enum_callback, settings);
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include "fluidsynth_priv.h"
|
||||
#include "fluid_sys.h"
|
||||
#include "fluid_synth.h"
|
||||
#include "fluid_adriver.h"
|
||||
|
@ -38,7 +37,6 @@
|
|||
#include <jack/jack.h>
|
||||
#include <jack/midiport.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "fluid_lash.h"
|
||||
|
||||
|
||||
|
@ -106,10 +104,10 @@ static fluid_jack_client_t *last_client = NULL; /* Last unpaired client. F
|
|||
void
|
||||
fluid_jack_audio_driver_settings(fluid_settings_t* settings)
|
||||
{
|
||||
fluid_settings_register_str(settings, "audio.jack.id", "fluidsynth", 0, NULL, NULL);
|
||||
fluid_settings_register_int(settings, "audio.jack.multi", 0, 0, 1, FLUID_HINT_TOGGLED, NULL, NULL);
|
||||
fluid_settings_register_int(settings, "audio.jack.autoconnect", 0, 0, 1, FLUID_HINT_TOGGLED, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "audio.jack.server", "", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "audio.jack.id", "fluidsynth", 0);
|
||||
fluid_settings_register_int(settings, "audio.jack.multi", 0, 0, 1, FLUID_HINT_TOGGLED);
|
||||
fluid_settings_register_int(settings, "audio.jack.autoconnect", 0, 0, 1, FLUID_HINT_TOGGLED);
|
||||
fluid_settings_register_str(settings, "audio.jack.server", "", 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -614,8 +612,8 @@ fluid_jack_driver_shutdown(void *arg)
|
|||
|
||||
void fluid_jack_midi_driver_settings (fluid_settings_t *settings)
|
||||
{
|
||||
fluid_settings_register_str (settings, "midi.jack.id", "fluidsynth-midi", 0, NULL, NULL);
|
||||
fluid_settings_register_str (settings, "midi.jack.server", "", 0, NULL, NULL);
|
||||
fluid_settings_register_str (settings, "midi.jack.id", "fluidsynth-midi", 0);
|
||||
fluid_settings_register_str (settings, "midi.jack.server", "", 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -144,26 +144,26 @@ void fluid_midi_driver_settings(fluid_settings_t* settings)
|
|||
{
|
||||
unsigned int i;
|
||||
|
||||
fluid_settings_register_int (settings, "midi.autoconnect", 0, 0, 1, FLUID_HINT_TOGGLED, NULL, NULL);
|
||||
fluid_settings_register_int (settings, "midi.autoconnect", 0, 0, 1, FLUID_HINT_TOGGLED);
|
||||
|
||||
fluid_settings_register_int (settings, "midi.realtime-prio",
|
||||
FLUID_DEFAULT_MIDI_RT_PRIO, 0, 99, 0, NULL, NULL);
|
||||
FLUID_DEFAULT_MIDI_RT_PRIO, 0, 99, 0);
|
||||
|
||||
/* Set the default driver */
|
||||
#if ALSA_SUPPORT
|
||||
fluid_settings_register_str(settings, "midi.driver", "alsa_seq", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "midi.driver", "alsa_seq", 0);
|
||||
#elif JACK_SUPPORT
|
||||
fluid_settings_register_str(settings, "midi.driver", "jack", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "midi.driver", "jack", 0);
|
||||
#elif OSS_SUPPORT
|
||||
fluid_settings_register_str(settings, "midi.driver", "oss", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "midi.driver", "oss", 0);
|
||||
#elif WINMIDI_SUPPORT
|
||||
fluid_settings_register_str(settings, "midi.driver", "winmidi", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "midi.driver", "winmidi", 0);
|
||||
#elif MIDISHARE_SUPPORT
|
||||
fluid_settings_register_str(settings, "midi.driver", "midishare", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "midi.driver", "midishare", 0);
|
||||
#elif COREMIDI_SUPPORT
|
||||
fluid_settings_register_str(settings, "midi.driver", "coremidi", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "midi.driver", "coremidi", 0);
|
||||
#else
|
||||
fluid_settings_register_str(settings, "midi.driver", "", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "midi.driver", "", 0);
|
||||
#endif
|
||||
|
||||
/* Add all drivers to the list of options */
|
||||
|
|
|
@ -101,7 +101,7 @@ static fluid_thread_return_t fluid_oss_midi_run(void* d);
|
|||
void
|
||||
fluid_oss_audio_driver_settings(fluid_settings_t* settings)
|
||||
{
|
||||
fluid_settings_register_str(settings, "audio.oss.device", "/dev/dsp", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "audio.oss.device", "/dev/dsp", 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -502,7 +502,7 @@ fluid_oss_audio_run2(void* d)
|
|||
|
||||
void fluid_oss_midi_driver_settings(fluid_settings_t* settings)
|
||||
{
|
||||
fluid_settings_register_str(settings, "midi.oss.device", "/dev/midi", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "midi.oss.device", "/dev/midi", 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -122,7 +122,7 @@ fluid_portaudio_driver_settings (fluid_settings_t *settings)
|
|||
PaError err;
|
||||
int i;
|
||||
|
||||
fluid_settings_register_str (settings, "audio.portaudio.device", PORTAUDIO_DEFAULT_DEVICE, 0, NULL, NULL);
|
||||
fluid_settings_register_str (settings, "audio.portaudio.device", PORTAUDIO_DEFAULT_DEVICE, 0);
|
||||
fluid_settings_add_option (settings, "audio.portaudio.device", PORTAUDIO_DEFAULT_DEVICE);
|
||||
|
||||
err = Pa_Initialize();
|
||||
|
|
|
@ -28,8 +28,6 @@
|
|||
#include "fluid_adriver.h"
|
||||
#include "fluid_settings.h"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#if PULSE_SUPPORT
|
||||
|
||||
#include <pulse/simple.h>
|
||||
|
@ -63,11 +61,11 @@ static fluid_thread_return_t fluid_pulse_audio_run2(void* d);
|
|||
|
||||
void fluid_pulse_audio_driver_settings(fluid_settings_t* settings)
|
||||
{
|
||||
fluid_settings_register_str(settings, "audio.pulseaudio.server", "default", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "audio.pulseaudio.device", "default", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "audio.pulseaudio.media-role", "music", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "audio.pulseaudio.server", "default", 0);
|
||||
fluid_settings_register_str(settings, "audio.pulseaudio.device", "default", 0);
|
||||
fluid_settings_register_str(settings, "audio.pulseaudio.media-role", "music", 0);
|
||||
fluid_settings_register_int(settings, "audio.pulseaudio.adjust-latency", 1, 0, 1,
|
||||
FLUID_HINT_TOGGLED, NULL, NULL);
|
||||
FLUID_HINT_TOGGLED);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -26,8 +26,7 @@
|
|||
* NOTE: Unfortunately midiInAddBuffer(), for SYSEX data, should not be called
|
||||
* from within the MIDI input callback, despite many examples contrary to that
|
||||
* on the Internet. Some MIDI devices will deadlock. Therefore we add MIDIHDR
|
||||
* pointers to a queue and re-add them in a separate thread, using a mutex and
|
||||
* conditional to wake up the thread. Lame-o API! :(
|
||||
* pointers to a queue and re-add them in a separate thread. Lame-o API! :(
|
||||
*/
|
||||
|
||||
#include "fluidsynth_priv.h"
|
||||
|
@ -44,22 +43,17 @@
|
|||
typedef struct {
|
||||
fluid_midi_driver_t driver;
|
||||
HMIDIIN hmidiin;
|
||||
fluid_atomic_int_t closing; /* Set to TRUE when closing driver, to prevent endless SYSEX lockup loop */
|
||||
|
||||
fluid_thread_t *sysExAddThread; /* Thread for SYSEX re-add thread */
|
||||
fluid_cond_mutex_t *mutex; /* Lock for condition */
|
||||
fluid_cond_t *cond; /* Condition to signal MIDI event thread of available events */
|
||||
|
||||
/* MIDI HDR for SYSEX buffer */
|
||||
MIDIHDR sysExHdrs[MIDI_SYSEX_BUF_COUNT];
|
||||
|
||||
/* TRUE for each MIDIHDR buffer which should be re-added to MIDI device */
|
||||
fluid_atomic_int_t sysExHdrAdd[MIDI_SYSEX_BUF_COUNT];
|
||||
/* Thread for SYSEX re-add thread */
|
||||
HANDLE hThread;
|
||||
DWORD dwThread;
|
||||
|
||||
/* Sysex data buffer */
|
||||
unsigned char sysExBuf[MIDI_SYSEX_BUF_COUNT * MIDI_SYSEX_MAX_SIZE];
|
||||
|
||||
int sysExOffset; /* Current offset in sysex buffer (for message continuation) */
|
||||
} fluid_winmidi_driver_t;
|
||||
|
||||
static char fluid_winmidi_error_buffer[256];
|
||||
|
@ -76,9 +70,7 @@ void delete_fluid_winmidi_driver(fluid_midi_driver_t* p);
|
|||
|
||||
void CALLBACK fluid_winmidi_callback(HMIDIIN hmi, UINT wMsg, DWORD_PTR dwInstance,
|
||||
DWORD_PTR msg, DWORD_PTR extra);
|
||||
static fluid_thread_return_t fluid_winmidi_add_sysex_thread (void *data);
|
||||
static char* fluid_winmidi_input_error(int no);
|
||||
int fluid_winmidi_driver_status(fluid_midi_driver_t* p);
|
||||
static char* fluid_winmidi_input_error(MMRESULT no);
|
||||
|
||||
|
||||
void fluid_winmidi_midi_driver_settings(fluid_settings_t* settings)
|
||||
|
@ -86,7 +78,7 @@ void fluid_winmidi_midi_driver_settings(fluid_settings_t* settings)
|
|||
MMRESULT res;
|
||||
MIDIINCAPS in_caps;
|
||||
UINT i, num;
|
||||
fluid_settings_register_str(settings, "midi.winmidi.device", "default", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "midi.winmidi.device", "default", 0);
|
||||
num = midiInGetNumDevs();
|
||||
if (num > 0) {
|
||||
fluid_settings_add_option(settings, "midi.winmidi.device", "default");
|
||||
|
@ -99,6 +91,34 @@ void fluid_winmidi_midi_driver_settings(fluid_settings_t* settings)
|
|||
}
|
||||
}
|
||||
|
||||
/* Thread for re-adding SYSEX buffers */
|
||||
static DWORD WINAPI fluid_winmidi_add_sysex_thread(void *data)
|
||||
{
|
||||
fluid_winmidi_driver_t *dev = (fluid_winmidi_driver_t *)data;
|
||||
MSG msg;
|
||||
int code;
|
||||
|
||||
for (;;) {
|
||||
code = GetMessage(&msg, NULL, 0, 0);
|
||||
|
||||
if (code < 0) {
|
||||
FLUID_LOG(FLUID_ERR, "fluid_winmidi_add_sysex_thread: GetMessage() failed.");
|
||||
break;
|
||||
}
|
||||
|
||||
if (msg.message == WM_CLOSE)
|
||||
break;
|
||||
|
||||
switch (msg.message) {
|
||||
case MM_MIM_LONGDATA:
|
||||
midiInAddBuffer(dev->hmidiin, (LPMIDIHDR)msg.lParam, sizeof(MIDIHDR));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* new_fluid_winmidi_driver
|
||||
*/
|
||||
|
@ -109,7 +129,7 @@ new_fluid_winmidi_driver(fluid_settings_t* settings,
|
|||
fluid_winmidi_driver_t* dev;
|
||||
MIDIHDR *hdr;
|
||||
MMRESULT res;
|
||||
UINT i, err, num, midi_num = 0;
|
||||
UINT i, num, midi_num = 0;
|
||||
MIDIINCAPS in_caps;
|
||||
char* devname = NULL;
|
||||
|
||||
|
@ -124,12 +144,11 @@ new_fluid_winmidi_driver(fluid_settings_t* settings,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
memset (dev, 0, sizeof (fluid_winmidi_driver_t));
|
||||
FLUID_MEMSET (dev, 0, sizeof (fluid_winmidi_driver_t));
|
||||
|
||||
dev->hmidiin = NULL;
|
||||
dev->driver.handler = handler;
|
||||
dev->driver.data = data;
|
||||
fluid_atomic_int_set (&dev->closing, FALSE);
|
||||
|
||||
/* get the device name. if none is specified, use the default device. */
|
||||
if(fluid_settings_dupstr(settings, "midi.winmidi.device", &devname) != FLUID_OK || !devname) {
|
||||
|
@ -169,40 +188,55 @@ new_fluid_winmidi_driver(fluid_settings_t* settings,
|
|||
}
|
||||
|
||||
/* try opening the device */
|
||||
err = midiInOpen(&dev->hmidiin, midi_num,
|
||||
res = midiInOpen(&dev->hmidiin, midi_num,
|
||||
(DWORD_PTR) fluid_winmidi_callback,
|
||||
(DWORD_PTR) dev, CALLBACK_FUNCTION);
|
||||
if (err != MMSYSERR_NOERROR) {
|
||||
if (res != MMSYSERR_NOERROR) {
|
||||
FLUID_LOG(FLUID_ERR, "Couldn't open MIDI input: %s (error %d)",
|
||||
fluid_winmidi_input_error(err), err);
|
||||
fluid_winmidi_input_error(res), res);
|
||||
goto error_recovery;
|
||||
}
|
||||
|
||||
/* Prepare and add SYSEX buffers */
|
||||
for (i = 0; i < MIDI_SYSEX_BUF_COUNT; i++)
|
||||
{
|
||||
fluid_atomic_int_set (&dev->sysExHdrAdd[i], FALSE);
|
||||
hdr = &dev->sysExHdrs[i];
|
||||
|
||||
hdr->lpData = &dev->sysExBuf[i * MIDI_SYSEX_MAX_SIZE];
|
||||
hdr->lpData = (LPSTR)&dev->sysExBuf[i * MIDI_SYSEX_MAX_SIZE];
|
||||
hdr->dwBufferLength = MIDI_SYSEX_MAX_SIZE;
|
||||
|
||||
/* Prepare a buffer for SYSEX data and add it */
|
||||
err = midiInPrepareHeader (dev->hmidiin, hdr, sizeof (MIDIHDR));
|
||||
res = midiInPrepareHeader (dev->hmidiin, hdr, sizeof (MIDIHDR));
|
||||
|
||||
if (err == MMSYSERR_NOERROR)
|
||||
if (res == MMSYSERR_NOERROR)
|
||||
{
|
||||
err = midiInAddBuffer (dev->hmidiin, hdr, sizeof (MIDIHDR));
|
||||
res = midiInAddBuffer (dev->hmidiin, hdr, sizeof (MIDIHDR));
|
||||
|
||||
if (err != MMSYSERR_NOERROR)
|
||||
if (res != MMSYSERR_NOERROR)
|
||||
{
|
||||
FLUID_LOG (FLUID_WARN, "Failed to prepare MIDI SYSEX buffer: %s (error %d)",
|
||||
fluid_winmidi_input_error (err), err);
|
||||
fluid_winmidi_input_error (res), res);
|
||||
midiInUnprepareHeader (dev->hmidiin, hdr, sizeof (MIDIHDR));
|
||||
}
|
||||
}
|
||||
else FLUID_LOG (FLUID_WARN, "Failed to prepare MIDI SYSEX buffer: %s (error %d)",
|
||||
fluid_winmidi_input_error (err), err);
|
||||
fluid_winmidi_input_error (res), res);
|
||||
}
|
||||
|
||||
/* Create thread which processes re-adding SYSEX buffers */
|
||||
dev->hThread = CreateThread(
|
||||
NULL,
|
||||
0,
|
||||
(LPTHREAD_START_ROUTINE)
|
||||
fluid_winmidi_add_sysex_thread,
|
||||
dev,
|
||||
0,
|
||||
&dev->dwThread);
|
||||
|
||||
if (dev->hThread == NULL)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Failed to create SYSEX buffer processing thread");
|
||||
goto error_recovery;
|
||||
}
|
||||
|
||||
/* Start the MIDI input interface */
|
||||
|
@ -211,25 +245,6 @@ new_fluid_winmidi_driver(fluid_settings_t* settings,
|
|||
goto error_recovery;
|
||||
}
|
||||
|
||||
/* Create mutex and condition */
|
||||
dev->mutex = new_fluid_cond_mutex ();
|
||||
dev->cond = new_fluid_cond ();
|
||||
|
||||
if (!dev->mutex || !dev->cond)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||
goto error_recovery;
|
||||
}
|
||||
|
||||
/* Create thread which processes re-adding SYSEX buffers */
|
||||
dev->sysExAddThread = new_fluid_thread ("winmidi-sysex", fluid_winmidi_add_sysex_thread,
|
||||
dev, 0, FALSE);
|
||||
if (!dev->sysExAddThread)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Failed to create SYSEX buffer processing thread");
|
||||
goto error_recovery;
|
||||
}
|
||||
|
||||
if (devname) FLUID_FREE (devname); /* -- free device name */
|
||||
|
||||
return (fluid_midi_driver_t*) dev;
|
||||
|
@ -248,27 +263,22 @@ delete_fluid_winmidi_driver(fluid_midi_driver_t* p)
|
|||
{
|
||||
fluid_winmidi_driver_t* dev = (fluid_winmidi_driver_t*) p;
|
||||
fluid_return_if_fail (dev != NULL);
|
||||
|
||||
if (dev->hmidiin != NULL) {
|
||||
fluid_atomic_int_set (&dev->closing, TRUE);
|
||||
|
||||
if (dev->sysExAddThread)
|
||||
{
|
||||
fluid_cond_mutex_lock (dev->mutex); /* ++ lock */
|
||||
fluid_cond_signal (dev->cond);
|
||||
fluid_cond_mutex_unlock (dev->mutex); /* -- unlock */
|
||||
if (dev->hThread != NULL)
|
||||
{
|
||||
PostThreadMessage(dev->dwThread, WM_CLOSE, 0, 0);
|
||||
WaitForSingleObject(dev->hThread, INFINITE);
|
||||
|
||||
fluid_thread_join (dev->sysExAddThread);
|
||||
}
|
||||
dev->hThread = NULL;
|
||||
}
|
||||
|
||||
if (dev->hmidiin != NULL)
|
||||
{
|
||||
midiInStop(dev->hmidiin);
|
||||
midiInReset(dev->hmidiin);
|
||||
midiInClose(dev->hmidiin);
|
||||
}
|
||||
|
||||
if (dev->mutex) delete_fluid_cond_mutex (dev->mutex);
|
||||
if (dev->cond) delete_fluid_cond (dev->cond);
|
||||
|
||||
FLUID_FREE(dev);
|
||||
}
|
||||
|
||||
|
@ -280,7 +290,6 @@ fluid_winmidi_callback(HMIDIIN hmi, UINT wMsg, DWORD_PTR dwInstance,
|
|||
fluid_midi_event_t event;
|
||||
LPMIDIHDR pMidiHdr;
|
||||
unsigned char *data;
|
||||
int index;
|
||||
unsigned int msg_param = (unsigned int) dwParam1;
|
||||
|
||||
switch (wMsg) {
|
||||
|
@ -306,7 +315,8 @@ fluid_winmidi_callback(HMIDIIN hmi, UINT wMsg, DWORD_PTR dwInstance,
|
|||
break;
|
||||
|
||||
case MIM_LONGDATA: /* SYSEX data */
|
||||
if (fluid_atomic_int_get (&dev->closing)) break; /* Prevent MIM_LONGDATA endless loop, don't re-add buffer if closing */
|
||||
if (dev->hThread == NULL)
|
||||
break;
|
||||
|
||||
pMidiHdr = (LPMIDIHDR)dwParam1;
|
||||
data = (unsigned char *)(pMidiHdr->lpData);
|
||||
|
@ -320,12 +330,7 @@ fluid_winmidi_callback(HMIDIIN hmi, UINT wMsg, DWORD_PTR dwInstance,
|
|||
(*dev->driver.handler)(dev->driver.data, &event);
|
||||
}
|
||||
|
||||
index = (pMidiHdr - dev->sysExHdrs) / sizeof (MIDIHDR);
|
||||
fluid_atomic_int_set (&dev->sysExHdrAdd[index], TRUE);
|
||||
|
||||
fluid_cond_mutex_lock (dev->mutex); /* ++ lock */
|
||||
fluid_cond_signal (dev->cond);
|
||||
fluid_cond_mutex_unlock (dev->mutex); /* -- unlock */
|
||||
PostThreadMessage(dev->dwThread, MM_MIM_LONGDATA, 0, dwParam1);
|
||||
break;
|
||||
|
||||
case MIM_ERROR:
|
||||
|
@ -339,40 +344,8 @@ fluid_winmidi_callback(HMIDIIN hmi, UINT wMsg, DWORD_PTR dwInstance,
|
|||
}
|
||||
}
|
||||
|
||||
/* Thread for re-adding SYSEX buffers */
|
||||
static fluid_thread_return_t
|
||||
fluid_winmidi_add_sysex_thread (void *data)
|
||||
{
|
||||
fluid_winmidi_driver_t *dev = data;
|
||||
int i;
|
||||
|
||||
while (!fluid_atomic_int_get (&dev->closing))
|
||||
{
|
||||
fluid_cond_mutex_lock (dev->mutex); /* ++ lock */
|
||||
fluid_cond_wait (dev->cond, dev->mutex);
|
||||
fluid_cond_mutex_unlock (dev->mutex); /* -- unlock */
|
||||
|
||||
for (i = 0; i < MIDI_SYSEX_BUF_COUNT; i++)
|
||||
{
|
||||
if (fluid_atomic_int_get (&dev->sysExHdrAdd[i]))
|
||||
{
|
||||
fluid_atomic_int_set (&dev->sysExHdrAdd[i], FALSE);
|
||||
midiInAddBuffer (dev->hmidiin, &dev->sysExHdrs[i], sizeof (MIDIHDR));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FLUID_THREAD_RETURN_VALUE;
|
||||
}
|
||||
|
||||
int
|
||||
fluid_winmidi_driver_status(fluid_midi_driver_t* p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char*
|
||||
fluid_winmidi_input_error(int no)
|
||||
fluid_winmidi_input_error(MMRESULT no)
|
||||
{
|
||||
midiInGetErrorText(no, fluid_winmidi_error_buffer, 256);
|
||||
return fluid_winmidi_error_buffer;
|
||||
|
|
|
@ -94,9 +94,9 @@ void process_o_cmd_line_option(fluid_settings_t* settings, char* optarg)
|
|||
if (fluid_settings_get_hints (settings, optarg, &hints) == FLUID_OK
|
||||
&& hints & FLUID_HINT_TOGGLED)
|
||||
{
|
||||
if (FLUID_STRCMP (val, "yes") == 0 || FLUID_STRCMP (val, "True") == 0
|
||||
|| FLUID_STRCMP (val, "TRUE") == 0 || FLUID_STRCMP (val, "true") == 0
|
||||
|| FLUID_STRCMP (val, "T") == 0)
|
||||
if (FLUID_STRCASECMP (val, "yes") == 0
|
||||
|| FLUID_STRCASECMP (val, "true") == 0
|
||||
|| FLUID_STRCASECMP (val, "t") == 0)
|
||||
ival = 1;
|
||||
else ival = atoi (val);
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ delete_fluid_midi_file (fluid_midi_file *mf)
|
|||
/*
|
||||
* Gets the next byte in a MIDI file, taking into account previous running status.
|
||||
*
|
||||
* returns FLUID_FAILED if EOF or read error
|
||||
* returns -1 if EOF or read error
|
||||
*/
|
||||
int
|
||||
fluid_midi_file_getc (fluid_midi_file *mf)
|
||||
|
@ -138,7 +138,7 @@ fluid_midi_file_getc (fluid_midi_file *mf)
|
|||
} else {
|
||||
if (mf->buf_pos >= mf->buf_len) {
|
||||
mf->eof = TRUE;
|
||||
return FLUID_FAILED;
|
||||
return -1;
|
||||
}
|
||||
c = mf->buffer[mf->buf_pos++];
|
||||
mf->trackpos++;
|
||||
|
@ -797,7 +797,6 @@ new_fluid_midi_event ()
|
|||
/**
|
||||
* Delete MIDI event structure.
|
||||
* @param evt MIDI event structure
|
||||
* @return Always returns #FLUID_OK
|
||||
*/
|
||||
void
|
||||
delete_fluid_midi_event(fluid_midi_event_t *evt)
|
||||
|
@ -1259,7 +1258,6 @@ new_fluid_player(fluid_synth_t *synth)
|
|||
/**
|
||||
* Delete a MIDI player instance.
|
||||
* @param player MIDI player instance
|
||||
* @return Always returns #FLUID_OK
|
||||
*/
|
||||
void
|
||||
delete_fluid_player(fluid_player_t *player)
|
||||
|
@ -1293,14 +1291,12 @@ fluid_player_settings(fluid_settings_t *settings)
|
|||
{
|
||||
/* player.timing-source can be either "system" (use system timer)
|
||||
or "sample" (use timer based on number of written samples) */
|
||||
fluid_settings_register_str(settings, "player.timing-source", "sample", 0,
|
||||
NULL, NULL);
|
||||
fluid_settings_register_str(settings, "player.timing-source", "sample", 0);
|
||||
fluid_settings_add_option(settings, "player.timing-source", "sample");
|
||||
fluid_settings_add_option(settings, "player.timing-source", "system");
|
||||
|
||||
/* Selects whether the player should reset the synth between songs, or not. */
|
||||
fluid_settings_register_int(settings, "player.reset-synth", 1, 0, 1,
|
||||
FLUID_HINT_TOGGLED, NULL, NULL);
|
||||
fluid_settings_register_int(settings, "player.reset-synth", 1, 0, 1, FLUID_HINT_TOGGLED);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -263,7 +263,7 @@ int fluid_track_send_events(fluid_track_t* track,
|
|||
#define fluid_track_eot(track) ((track)->cur == NULL)
|
||||
|
||||
|
||||
/**
|
||||
/*
|
||||
* fluid_playlist_item
|
||||
* Used as the `data' elements of the fluid_player.playlist.
|
||||
* Represents either a filename or a pre-loaded memory buffer.
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
*/
|
||||
|
||||
#include "fluid_event_priv.h"
|
||||
#include "fluidsynth_priv.h" // FLUID_NEW, etc
|
||||
#include "fluid_sys.h" // timer, threads, etc...
|
||||
#include "fluid_list.h"
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ enum fluid_loop {
|
|||
FLUID_LOOP_UNTIL_RELEASE = 3
|
||||
};
|
||||
|
||||
/**
|
||||
/*
|
||||
* rvoice ticks-based parameters
|
||||
* These parameters must be updated even if the voice is currently quiet.
|
||||
*/
|
||||
|
@ -77,7 +77,7 @@ struct _fluid_rvoice_envlfo_t
|
|||
fluid_real_t viblfo_to_pitch;
|
||||
};
|
||||
|
||||
/**
|
||||
/*
|
||||
* rvoice parameters needed for dsp interpolation
|
||||
*/
|
||||
struct _fluid_rvoice_dsp_t
|
||||
|
@ -129,7 +129,7 @@ struct _fluid_rvoice_dsp_t
|
|||
ever add surround positioning, or stereo reverb/chorus */
|
||||
#define FLUID_RVOICE_MAX_BUFS (4)
|
||||
|
||||
/**
|
||||
/*
|
||||
* rvoice mixer-related parameters
|
||||
*/
|
||||
struct _fluid_rvoice_buffers_t
|
||||
|
@ -142,7 +142,7 @@ struct _fluid_rvoice_buffers_t
|
|||
};
|
||||
|
||||
|
||||
/**
|
||||
/*
|
||||
* Hard real-time parameters needed to synthesize a voice
|
||||
*/
|
||||
struct _fluid_rvoice_t
|
||||
|
|
|
@ -42,7 +42,7 @@ struct _fluid_rvoice_event_t {
|
|||
void fluid_rvoice_event_dispatch(fluid_rvoice_event_t* event);
|
||||
|
||||
|
||||
/**
|
||||
/*
|
||||
* Bridge between the renderer thread and the midi state thread.
|
||||
* If is_threadsafe is true, that means fluid_rvoice_eventhandler_fetch_all
|
||||
* can be called in parallell with fluid_rvoice_eventhandler_push/flush
|
||||
|
|
|
@ -587,7 +587,7 @@ int delete_fluid_defsfont(fluid_defsfont_t* sfont)
|
|||
/* 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) {
|
||||
if (sample->refcount != 0) {
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
}
|
||||
|
@ -1261,7 +1261,7 @@ delete_fluid_preset_zone(fluid_preset_zone_t* zone)
|
|||
{
|
||||
tmp = mod;
|
||||
mod = mod->next;
|
||||
fluid_mod_delete (tmp);
|
||||
delete_fluid_mod (tmp);
|
||||
}
|
||||
|
||||
FLUID_FREE (zone->name);
|
||||
|
@ -1312,7 +1312,7 @@ fluid_preset_zone_import_sfont(fluid_preset_zone_t* zone, SFZone *sfzone, fluid_
|
|||
for (count = 0, r = sfzone->mod; r != NULL; count++) {
|
||||
|
||||
SFMod* mod_src = (SFMod *)r->data;
|
||||
fluid_mod_t * mod_dest = fluid_mod_new();
|
||||
fluid_mod_t * mod_dest = new_fluid_mod();
|
||||
int type;
|
||||
|
||||
if (mod_dest == NULL){
|
||||
|
@ -1653,7 +1653,7 @@ delete_fluid_inst_zone(fluid_inst_zone_t* zone)
|
|||
{
|
||||
tmp = mod;
|
||||
mod = mod->next;
|
||||
fluid_mod_delete (tmp);
|
||||
delete_fluid_mod (tmp);
|
||||
}
|
||||
|
||||
FLUID_FREE (zone->name);
|
||||
|
@ -1715,7 +1715,7 @@ fluid_inst_zone_import_sfont(fluid_inst_zone_t* zone, SFZone *sfzone, fluid_defs
|
|||
int type;
|
||||
fluid_mod_t* mod_dest;
|
||||
|
||||
mod_dest = fluid_mod_new();
|
||||
mod_dest = new_fluid_mod();
|
||||
if (mod_dest == NULL){
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
|
|
@ -256,7 +256,7 @@ delete_fluid_ramsfont (fluid_ramsfont_t* sfont)
|
|||
/* 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) {
|
||||
if (sam->refcount != 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -1211,7 +1211,6 @@ new_fluid_ramsample (void)
|
|||
/**
|
||||
* Delete a RAM SoundFont sample.
|
||||
* @param sample Sample to delete
|
||||
* @return #FLUID_OK
|
||||
*/
|
||||
void
|
||||
delete_fluid_ramsample (fluid_sample_t* sample)
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
|
||||
|
||||
#define delete_fluid_sfont(_sf) ( ((_sf) && (_sf)->free)? (*(_sf)->free)(_sf) : 0)
|
||||
|
||||
#define fluid_sfont_get_id(_sf) ((_sf)->id)
|
||||
#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)
|
||||
|
|
|
@ -33,7 +33,7 @@ typedef struct _fluid_gen_info_t {
|
|||
float def; /* The default value (cfr. fluid_gen_set_default_values()) */
|
||||
} fluid_gen_info_t;
|
||||
|
||||
/**
|
||||
/*
|
||||
* SoundFont generator structure.
|
||||
*/
|
||||
typedef struct _fluid_gen_t
|
||||
|
@ -44,7 +44,7 @@ typedef struct _fluid_gen_t
|
|||
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
|
||||
|
|
|
@ -383,7 +383,7 @@ fluid_mod_get_value(fluid_mod_t* mod, fluid_channel_t* chan, fluid_voice_t* voic
|
|||
* @return New allocated modulator or NULL if out of memory
|
||||
*/
|
||||
fluid_mod_t*
|
||||
fluid_mod_new()
|
||||
new_fluid_mod()
|
||||
{
|
||||
fluid_mod_t* mod = FLUID_NEW (fluid_mod_t);
|
||||
if (mod == NULL) {
|
||||
|
@ -398,7 +398,7 @@ fluid_mod_new()
|
|||
* @param mod Modulator to free
|
||||
*/
|
||||
void
|
||||
fluid_mod_delete (fluid_mod_t *mod)
|
||||
delete_fluid_mod (fluid_mod_t *mod)
|
||||
{
|
||||
FLUID_FREE(mod);
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "fluidsynth_priv.h"
|
||||
#include "fluid_conv.h"
|
||||
|
||||
/**
|
||||
/*
|
||||
* Modulator structure. See SoundFont 2.04 PDF section 8.2.
|
||||
*/
|
||||
struct _fluid_mod_t
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
* 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "fluid_synth.h"
|
||||
#include "fluid_sys.h"
|
||||
#include "fluid_chan.h"
|
||||
|
@ -43,10 +41,6 @@ static int fluid_synth_noteon_LOCAL(fluid_synth_t* synth, int chan, int key,
|
|||
int vel);
|
||||
static int fluid_synth_noteoff_LOCAL(fluid_synth_t* synth, int chan, int key);
|
||||
static int fluid_synth_cc_LOCAL(fluid_synth_t* synth, int channum, int num);
|
||||
static int fluid_synth_update_device_id (fluid_synth_t *synth, char *name,
|
||||
int value);
|
||||
static int fluid_synth_update_overflow (fluid_synth_t *synth, char *name,
|
||||
fluid_real_t value);
|
||||
static int fluid_synth_sysex_midi_tuning (fluid_synth_t *synth, const char *data,
|
||||
int len, char *response,
|
||||
int *response_len, int avail_response,
|
||||
|
@ -71,13 +65,7 @@ fluid_synth_get_preset_by_sfont_name(fluid_synth_t* synth, const char *sfontname
|
|||
unsigned int banknum, unsigned int prognum);
|
||||
|
||||
static void fluid_synth_update_presets(fluid_synth_t* synth);
|
||||
static int fluid_synth_update_sample_rate(fluid_synth_t* synth,
|
||||
char* name, double value);
|
||||
static int fluid_synth_update_gain(fluid_synth_t* synth,
|
||||
char* name, double value);
|
||||
static void fluid_synth_update_gain_LOCAL(fluid_synth_t* synth);
|
||||
static int fluid_synth_update_polyphony(fluid_synth_t* synth,
|
||||
char* name, int value);
|
||||
static int fluid_synth_update_polyphony_LOCAL(fluid_synth_t* synth, int new_polyphony);
|
||||
static void init_dither(void);
|
||||
static FLUID_INLINE int roundi (float x);
|
||||
|
@ -109,6 +97,18 @@ static void fluid_synth_set_gen_LOCAL (fluid_synth_t* synth, int chan,
|
|||
static void fluid_synth_stop_LOCAL (fluid_synth_t *synth, unsigned int id);
|
||||
|
||||
|
||||
static int fluid_synth_set_important_channels(fluid_synth_t *synth, const char *channels);
|
||||
|
||||
|
||||
/* Callback handlers for real-time settings */
|
||||
static void fluid_synth_handle_sample_rate(void *data, const char *name, double value);
|
||||
static void fluid_synth_handle_gain(void *data, const char *name, double value);
|
||||
static void fluid_synth_handle_polyphony(void *data, const char *name, int value);
|
||||
static void fluid_synth_handle_device_id(void *data, const char *name, int value);
|
||||
static void fluid_synth_handle_overflow(void *data, const char *name, double value);
|
||||
static void fluid_synth_handle_important_channels(void *data, const char *name,
|
||||
const char *value);
|
||||
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
|
@ -155,77 +155,49 @@ static const fluid_revmodel_presets_t revmodel_preset[] = {
|
|||
* INITIALIZATION & UTILITIES
|
||||
*/
|
||||
|
||||
static void fluid_synth_register_overflow(fluid_settings_t* settings,
|
||||
fluid_num_update_t update_func,
|
||||
void* update_data)
|
||||
{
|
||||
fluid_settings_register_num(settings, "synth.overflow.percussion",
|
||||
4000, -10000, 10000, 0, update_func, update_data);
|
||||
fluid_settings_register_num(settings, "synth.overflow.sustained",
|
||||
-1000, -10000, 10000, 0, update_func, update_data);
|
||||
fluid_settings_register_num(settings, "synth.overflow.released",
|
||||
-2000, -10000, 10000, 0, update_func, update_data);
|
||||
fluid_settings_register_num(settings, "synth.overflow.age",
|
||||
1000, -10000, 10000, 0, update_func, update_data);
|
||||
fluid_settings_register_num(settings, "synth.overflow.volume",
|
||||
500, -10000, 10000, 0, update_func, update_data);
|
||||
}
|
||||
|
||||
void fluid_synth_settings(fluid_settings_t* settings)
|
||||
{
|
||||
fluid_settings_register_int(settings, "synth.verbose", 0, 0, 1,
|
||||
FLUID_HINT_TOGGLED, NULL, NULL);
|
||||
fluid_settings_register_int(settings, "synth.reverb.active", 1, 0, 1,
|
||||
FLUID_HINT_TOGGLED, NULL, NULL);
|
||||
fluid_settings_register_int(settings, "synth.chorus.active", 1, 0, 1,
|
||||
FLUID_HINT_TOGGLED, NULL, NULL);
|
||||
fluid_settings_register_int(settings, "synth.ladspa.active", 0, 0, 1,
|
||||
FLUID_HINT_TOGGLED, NULL, NULL);
|
||||
fluid_settings_register_int(settings, "synth.lock-memory", 1, 0, 1,
|
||||
FLUID_HINT_TOGGLED, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "midi.portname", "", 0, NULL, NULL);
|
||||
fluid_settings_register_int(settings, "synth.verbose", 0, 0, 1, FLUID_HINT_TOGGLED);
|
||||
fluid_settings_register_int(settings, "synth.reverb.active", 1, 0, 1, FLUID_HINT_TOGGLED);
|
||||
fluid_settings_register_int(settings, "synth.chorus.active", 1, 0, 1, FLUID_HINT_TOGGLED);
|
||||
fluid_settings_register_int(settings, "synth.ladspa.active", 0, 0, 1, FLUID_HINT_TOGGLED);
|
||||
fluid_settings_register_int(settings, "synth.lock-memory", 1, 0, 1, FLUID_HINT_TOGGLED);
|
||||
fluid_settings_register_str(settings, "midi.portname", "", 0);
|
||||
|
||||
#ifdef DEFAULT_SOUNDFONT
|
||||
fluid_settings_register_str(settings, "synth.default-soundfont",
|
||||
DEFAULT_SOUNDFONT, 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "synth.default-soundfont", DEFAULT_SOUNDFONT, 0);
|
||||
#endif
|
||||
|
||||
fluid_settings_register_int(settings, "synth.polyphony",
|
||||
256, 1, 65535, 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, 128, 0, NULL, NULL);
|
||||
fluid_settings_register_int(settings, "synth.audio-groups",
|
||||
1, 1, 128, 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, 8000.0f, 96000.0f,
|
||||
0, NULL, NULL);
|
||||
fluid_settings_register_int(settings, "synth.device-id",
|
||||
0, 0, 126, 0, NULL, NULL);
|
||||
fluid_settings_register_int(settings, "synth.cpu-cores", 1, 1, 256, 0, NULL, NULL);
|
||||
fluid_settings_register_int(settings, "synth.polyphony", 256, 1, 65535, 0);
|
||||
fluid_settings_register_int(settings, "synth.midi-channels", 16, 16, 256, 0);
|
||||
fluid_settings_register_num(settings, "synth.gain", 0.2f, 0.0f, 10.0f, 0);
|
||||
fluid_settings_register_int(settings, "synth.audio-channels", 1, 1, 128, 0);
|
||||
fluid_settings_register_int(settings, "synth.audio-groups", 1, 1, 128, 0);
|
||||
fluid_settings_register_int(settings, "synth.effects-channels", 2, 2, 2, 0);
|
||||
fluid_settings_register_num(settings, "synth.sample-rate", 44100.0f, 8000.0f, 96000.0f, 0);
|
||||
fluid_settings_register_int(settings, "synth.device-id", 0, 0, 126, 0);
|
||||
fluid_settings_register_int(settings, "synth.cpu-cores", 1, 1, 256, 0);
|
||||
|
||||
fluid_settings_register_int(settings, "synth.min-note-length", 10, 0, 65535, 0, NULL, NULL);
|
||||
fluid_settings_register_int(settings, "synth.min-note-length", 10, 0, 65535, 0);
|
||||
|
||||
fluid_settings_register_int(settings, "synth.threadsafe-api", 1, 0, 1,
|
||||
FLUID_HINT_TOGGLED, NULL, NULL);
|
||||
fluid_settings_register_int(settings, "synth.parallel-render", 1, 0, 1,
|
||||
FLUID_HINT_TOGGLED, NULL, NULL);
|
||||
fluid_settings_register_int(settings, "synth.threadsafe-api", 1, 0, 1, FLUID_HINT_TOGGLED);
|
||||
fluid_settings_register_int(settings, "synth.parallel-render", 1, 0, 1, FLUID_HINT_TOGGLED);
|
||||
|
||||
fluid_synth_register_overflow(settings, NULL, NULL);
|
||||
fluid_settings_register_num(settings, "synth.overflow.percussion", 4000, -10000, 10000, 0);
|
||||
fluid_settings_register_num(settings, "synth.overflow.sustained", -1000, -10000, 10000, 0);
|
||||
fluid_settings_register_num(settings, "synth.overflow.released", -2000, -10000, 10000, 0);
|
||||
fluid_settings_register_num(settings, "synth.overflow.age", 1000, -10000, 10000, 0);
|
||||
fluid_settings_register_num(settings, "synth.overflow.volume", 500, -10000, 10000, 0);
|
||||
fluid_settings_register_num(settings, "synth.overflow.important", 5000, -50000, 50000, 0);
|
||||
fluid_settings_register_str(settings, "synth.overflow.important-channels", "", 0);
|
||||
|
||||
fluid_settings_register_str(settings, "synth.midi-bank-select", "gs", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "synth.midi-bank-select", "gs", 0);
|
||||
fluid_settings_add_option(settings, "synth.midi-bank-select", "gm");
|
||||
fluid_settings_add_option(settings, "synth.midi-bank-select", "gs");
|
||||
fluid_settings_add_option(settings, "synth.midi-bank-select", "xg");
|
||||
fluid_settings_add_option(settings, "synth.midi-bank-select", "mma");
|
||||
|
||||
fluid_settings_register_str(settings, "synth.volenv", "emu", 0, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "synth.volenv", "emu", 0);
|
||||
fluid_settings_add_option(settings, "synth.volenv", "emu");
|
||||
fluid_settings_add_option(settings, "synth.volenv", "compliant");
|
||||
}
|
||||
|
@ -549,11 +521,9 @@ new_fluid_synth(fluid_settings_t *settings)
|
|||
{
|
||||
fluid_synth_t* synth;
|
||||
fluid_sfloader_t* loader;
|
||||
double gain;
|
||||
char *important_channels;
|
||||
int i, nbuf;
|
||||
int with_ladspa = 0;
|
||||
int with_reverb = 0;
|
||||
int with_chorus = 0;
|
||||
|
||||
/* initialize all the conversion tables and other stuff */
|
||||
if (fluid_atomic_int_compare_and_exchange(&fluid_synth_initialized, 0, 1))
|
||||
|
@ -594,10 +564,8 @@ new_fluid_synth(fluid_settings_t *settings)
|
|||
|
||||
synth->settings = settings;
|
||||
|
||||
fluid_settings_getint(settings, "synth.reverb.active", &with_reverb);
|
||||
fluid_atomic_int_set(&synth->with_reverb, with_reverb);
|
||||
fluid_settings_getint(settings, "synth.chorus.active", &with_chorus);
|
||||
fluid_atomic_int_set(&synth->with_chorus, with_chorus);
|
||||
fluid_settings_getint(settings, "synth.reverb.active", &synth->with_reverb);
|
||||
fluid_settings_getint(settings, "synth.chorus.active", &synth->with_chorus);
|
||||
fluid_settings_getint(settings, "synth.verbose", &synth->verbose);
|
||||
|
||||
fluid_settings_getint(settings, "synth.polyphony", &synth->polyphony);
|
||||
|
@ -606,29 +574,41 @@ new_fluid_synth(fluid_settings_t *settings)
|
|||
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", &gain);
|
||||
synth->gain = gain;
|
||||
fluid_settings_getnum_float(settings, "synth.gain", &synth->gain);
|
||||
fluid_settings_getint(settings, "synth.device-id", &synth->device_id);
|
||||
fluid_settings_getint(settings, "synth.cpu-cores", &synth->cores);
|
||||
|
||||
/* register the callbacks */
|
||||
fluid_settings_register_num(settings, "synth.sample-rate",
|
||||
44100.0f, 8000.0f, 96000.0f, 0,
|
||||
(fluid_num_update_t) fluid_synth_update_sample_rate, synth);
|
||||
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, 1, 65535, 0,
|
||||
(fluid_int_update_t) fluid_synth_update_polyphony,
|
||||
synth);
|
||||
fluid_settings_register_int(settings, "synth.device-id",
|
||||
synth->device_id, 126, 0, 0,
|
||||
(fluid_int_update_t) fluid_synth_update_device_id, synth);
|
||||
fluid_settings_getnum_float(settings, "synth.overflow.percussion", &synth->overflow.percussion);
|
||||
fluid_settings_getnum_float(settings, "synth.overflow.released", &synth->overflow.released);
|
||||
fluid_settings_getnum_float(settings, "synth.overflow.sustained", &synth->overflow.sustained);
|
||||
fluid_settings_getnum_float(settings, "synth.overflow.volume", &synth->overflow.volume);
|
||||
fluid_settings_getnum_float(settings, "synth.overflow.age", &synth->overflow.age);
|
||||
fluid_settings_getnum_float(settings, "synth.overflow.important", &synth->overflow.important);
|
||||
|
||||
/* register the callbacks */
|
||||
fluid_settings_callback_num(settings, "synth.sample-rate",
|
||||
fluid_synth_handle_sample_rate, synth);
|
||||
fluid_settings_callback_num(settings, "synth.gain",
|
||||
fluid_synth_handle_gain, synth);
|
||||
fluid_settings_callback_int(settings, "synth.polyphony",
|
||||
fluid_synth_handle_polyphony, synth);
|
||||
fluid_settings_callback_int(settings, "synth.device-id",
|
||||
fluid_synth_handle_device_id, synth);
|
||||
fluid_settings_callback_num(settings, "synth.overflow.percussion",
|
||||
fluid_synth_handle_overflow, synth);
|
||||
fluid_settings_callback_num(settings, "synth.overflow.sustained",
|
||||
fluid_synth_handle_overflow, synth);
|
||||
fluid_settings_callback_num(settings, "synth.overflow.released",
|
||||
fluid_synth_handle_overflow, synth);
|
||||
fluid_settings_callback_num(settings, "synth.overflow.age",
|
||||
fluid_synth_handle_overflow, synth);
|
||||
fluid_settings_callback_num(settings, "synth.overflow.volume",
|
||||
fluid_synth_handle_overflow, synth);
|
||||
fluid_settings_callback_num(settings, "synth.overflow.important",
|
||||
fluid_synth_handle_overflow, synth);
|
||||
fluid_settings_callback_str(settings, "synth.overflow.important-channels",
|
||||
fluid_synth_handle_important_channels, synth);
|
||||
|
||||
fluid_synth_register_overflow(settings,
|
||||
(fluid_num_update_t) fluid_synth_update_overflow, synth);
|
||||
|
||||
/* do some basic sanity checking on the settings */
|
||||
|
||||
if (synth->midi_channels % 16 != 0) {
|
||||
|
@ -665,7 +645,6 @@ new_fluid_synth(fluid_settings_t *settings)
|
|||
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. */
|
||||
|
@ -674,6 +653,16 @@ new_fluid_synth(fluid_settings_t *settings)
|
|||
nbuf = synth->audio_groups;
|
||||
}
|
||||
|
||||
if (fluid_settings_dupstr(settings, "synth.overflow.important-channels",
|
||||
&important_channels) == FLUID_OK)
|
||||
{
|
||||
if (fluid_synth_set_important_channels(synth, important_channels) != FLUID_OK)
|
||||
{
|
||||
FLUID_LOG(FLUID_WARN, "Failed to set overflow important channels");
|
||||
}
|
||||
FLUID_FREE(important_channels);
|
||||
}
|
||||
|
||||
/* as soon as the synth is created it starts playing. */
|
||||
synth->state = FLUID_SYNTH_PLAYING;
|
||||
synth->sfont_info = NULL;
|
||||
|
@ -760,12 +749,10 @@ new_fluid_synth(fluid_settings_t *settings)
|
|||
}
|
||||
|
||||
fluid_synth_set_sample_rate(synth, synth->sample_rate);
|
||||
|
||||
fluid_synth_update_overflow(synth, "", 0.0f);
|
||||
fluid_synth_update_mixer(synth, fluid_rvoice_mixer_set_polyphony,
|
||||
synth->polyphony, 0.0f);
|
||||
fluid_synth_set_reverb_on(synth, fluid_atomic_int_get(&synth->with_reverb));
|
||||
fluid_synth_set_chorus_on(synth, fluid_atomic_int_get(&synth->with_chorus));
|
||||
fluid_synth_set_reverb_on(synth, synth->with_reverb);
|
||||
fluid_synth_set_chorus_on(synth, synth->with_chorus);
|
||||
|
||||
synth->cur = FLUID_BUFSIZE;
|
||||
synth->curmax = 0;
|
||||
|
@ -818,7 +805,6 @@ new_fluid_synth(fluid_settings_t *settings)
|
|||
/**
|
||||
* Delete a FluidSynth instance.
|
||||
* @param synth FluidSynth instance to delete
|
||||
* @return FLUID_OK
|
||||
*
|
||||
* @note Other users of a synthesizer instance, such as audio and MIDI drivers,
|
||||
* should be deleted prior to freeing the FluidSynth instance.
|
||||
|
@ -931,9 +917,11 @@ delete_fluid_synth(fluid_synth_t* synth)
|
|||
while (default_mod != NULL) {
|
||||
mod = default_mod;
|
||||
default_mod = mod->next;
|
||||
fluid_mod_delete(mod);
|
||||
delete_fluid_mod(mod);
|
||||
}
|
||||
|
||||
FLUID_FREE(synth->overflow.important_channels);
|
||||
|
||||
fluid_rec_mutex_destroy(synth->mutex);
|
||||
|
||||
FLUID_FREE(synth);
|
||||
|
@ -1130,7 +1118,7 @@ fluid_synth_add_default_mod(fluid_synth_t* synth, fluid_mod_t* mod, int mode)
|
|||
}
|
||||
|
||||
/* Add a new modulator (no existing modulator to add / overwrite). */
|
||||
new_mod = fluid_mod_new();
|
||||
new_mod = new_fluid_mod();
|
||||
if (new_mod == NULL)
|
||||
FLUID_API_RETURN(FLUID_FAILED);
|
||||
|
||||
|
@ -1175,7 +1163,7 @@ fluid_synth_remove_default_mod(fluid_synth_t* synth, const fluid_mod_t* mod)
|
|||
{
|
||||
last_mod->next = default_mod->next;
|
||||
}
|
||||
fluid_mod_delete(default_mod);
|
||||
delete_fluid_mod(default_mod);
|
||||
FLUID_API_RETURN(FLUID_OK);
|
||||
}
|
||||
last_mod = default_mod;
|
||||
|
@ -1359,13 +1347,15 @@ fluid_synth_get_cc(fluid_synth_t* synth, int chan, int num, int* pval)
|
|||
/*
|
||||
* Handler for synth.device-id setting.
|
||||
*/
|
||||
static int
|
||||
fluid_synth_update_device_id (fluid_synth_t *synth, char *name, int value)
|
||||
static void
|
||||
fluid_synth_handle_device_id (void *data, const char *name, int value)
|
||||
{
|
||||
fluid_synth_t *synth = (fluid_synth_t *)data;
|
||||
fluid_return_if_fail(synth != NULL);
|
||||
|
||||
fluid_synth_api_enter(synth);
|
||||
synth->device_id = value;
|
||||
fluid_synth_api_exit(synth);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2373,11 +2363,11 @@ fluid_synth_update_presets(fluid_synth_t* synth)
|
|||
}
|
||||
|
||||
/* Handler for synth.sample-rate setting. */
|
||||
static int
|
||||
fluid_synth_update_sample_rate(fluid_synth_t* synth, char* name, double value)
|
||||
static void
|
||||
fluid_synth_handle_sample_rate(void *data, const char* name, double value)
|
||||
{
|
||||
fluid_synth_t *synth = (fluid_synth_t *)data;
|
||||
fluid_synth_set_sample_rate(synth, (float) value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2409,11 +2399,11 @@ fluid_synth_set_sample_rate(fluid_synth_t* synth, float sample_rate)
|
|||
|
||||
|
||||
/* Handler for synth.gain setting. */
|
||||
static int
|
||||
fluid_synth_update_gain(fluid_synth_t* synth, char* name, double value)
|
||||
static void
|
||||
fluid_synth_handle_gain(void *data, const char* name, double value)
|
||||
{
|
||||
fluid_synth_t *synth = (fluid_synth_t *)data;
|
||||
fluid_synth_set_gain(synth, (float) value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2470,11 +2460,11 @@ fluid_synth_get_gain(fluid_synth_t* synth)
|
|||
/*
|
||||
* Handler for synth.polyphony setting.
|
||||
*/
|
||||
static int
|
||||
fluid_synth_update_polyphony(fluid_synth_t* synth, char* name, int value)
|
||||
static void
|
||||
fluid_synth_handle_polyphony(void *data, const char* name, int value)
|
||||
{
|
||||
fluid_synth_t *synth = (fluid_synth_t *)data;
|
||||
fluid_synth_set_polyphony(synth, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3157,34 +3147,45 @@ fluid_synth_render_blocks(fluid_synth_t* synth, int blockcount)
|
|||
}
|
||||
|
||||
|
||||
static int fluid_synth_update_overflow (fluid_synth_t *synth, char *name,
|
||||
fluid_real_t value)
|
||||
/*
|
||||
* Handler for synth.overflow.* settings.
|
||||
*/
|
||||
static void fluid_synth_handle_overflow (void *data, const char *name, double value)
|
||||
{
|
||||
double d;
|
||||
fluid_synth_api_enter(synth);
|
||||
|
||||
fluid_settings_getnum(synth->settings, "synth.overflow.percussion", &d);
|
||||
synth->overflow.percussion = d;
|
||||
fluid_settings_getnum(synth->settings, "synth.overflow.released", &d);
|
||||
synth->overflow.released = d;
|
||||
fluid_settings_getnum(synth->settings, "synth.overflow.sustained", &d);
|
||||
synth->overflow.sustained = d;
|
||||
fluid_settings_getnum(synth->settings, "synth.overflow.volume", &d);
|
||||
synth->overflow.volume = d;
|
||||
fluid_settings_getnum(synth->settings, "synth.overflow.age", &d);
|
||||
synth->overflow.age = d;
|
||||
|
||||
FLUID_API_RETURN(0);
|
||||
}
|
||||
fluid_synth_t *synth = (fluid_synth_t *)data;
|
||||
fluid_return_if_fail(synth != NULL);
|
||||
|
||||
fluid_synth_api_enter(synth);
|
||||
|
||||
if (FLUID_STRCMP(name, "synth.overflow.percussion") == 0) {
|
||||
synth->overflow.percussion = value;
|
||||
}
|
||||
else if (FLUID_STRCMP(name, "synth.overflow.released") == 0) {
|
||||
synth->overflow.released = value;
|
||||
}
|
||||
else if (FLUID_STRCMP(name, "synth.overflow.sustained") == 0) {
|
||||
synth->overflow.sustained = value;
|
||||
}
|
||||
else if (FLUID_STRCMP(name, "synth.overflow.volume") == 0) {
|
||||
synth->overflow.volume = value;
|
||||
}
|
||||
else if (FLUID_STRCMP(name, "synth.overflow.age") == 0) {
|
||||
synth->overflow.age = value;
|
||||
}
|
||||
else if (FLUID_STRCMP(name, "synth.overflow.important") == 0) {
|
||||
synth->overflow.important = value;
|
||||
}
|
||||
|
||||
fluid_synth_api_exit(synth);
|
||||
}
|
||||
|
||||
/* Selects a voice for killing. */
|
||||
static fluid_voice_t*
|
||||
fluid_synth_free_voice_by_kill_LOCAL(fluid_synth_t* synth)
|
||||
{
|
||||
int i;
|
||||
fluid_real_t best_prio = OVERFLOW_PRIO_CANNOT_KILL-1;
|
||||
fluid_real_t this_voice_prio;
|
||||
float best_prio = OVERFLOW_PRIO_CANNOT_KILL-1;
|
||||
float this_voice_prio;
|
||||
fluid_voice_t* voice;
|
||||
int best_voice_index=-1;
|
||||
unsigned int ticks = fluid_synth_get_ticks(synth);
|
||||
|
@ -3311,8 +3312,7 @@ static void
|
|||
fluid_synth_kill_by_exclusive_class_LOCAL(fluid_synth_t* synth,
|
||||
fluid_voice_t* new_voice)
|
||||
{
|
||||
int excl_class = _GEN(new_voice,GEN_EXCLUSIVECLASS);
|
||||
fluid_voice_t* existing_voice;
|
||||
int excl_class = fluid_voice_gen_value(new_voice, GEN_EXCLUSIVECLASS);
|
||||
int i;
|
||||
|
||||
/* Excl. class 0: No exclusive class */
|
||||
|
@ -3320,14 +3320,15 @@ fluid_synth_kill_by_exclusive_class_LOCAL(fluid_synth_t* synth,
|
|||
|
||||
/* Kill all notes on the same channel with the same exclusive class */
|
||||
for (i = 0; i < synth->polyphony; i++) {
|
||||
existing_voice = synth->voice[i];
|
||||
fluid_voice_t* existing_voice = synth->voice[i];
|
||||
int existing_excl_class = fluid_voice_gen_value(existing_voice, GEN_EXCLUSIVECLASS);
|
||||
|
||||
/* If voice is playing, on the same channel, has same exclusive
|
||||
* class and is not part of the same noteon event (voice group), then kill it */
|
||||
|
||||
if (fluid_voice_is_playing(existing_voice)
|
||||
&& fluid_voice_get_channel(existing_voice) == fluid_voice_get_channel(new_voice)
|
||||
&& (int)_GEN (existing_voice, GEN_EXCLUSIVECLASS) == excl_class
|
||||
&& existing_excl_class == excl_class
|
||||
&& fluid_voice_get_id (existing_voice) != fluid_voice_get_id(new_voice))
|
||||
fluid_voice_kill_excl(existing_voice);
|
||||
}
|
||||
|
@ -3810,63 +3811,6 @@ fluid_synth_get_channel_preset(fluid_synth_t* synth, int chan)
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get information on the currently selected preset on a MIDI channel.
|
||||
* @param synth FluidSynth instance
|
||||
* @param chan MIDI channel number (0 to MIDI channel count - 1)
|
||||
* @param info Caller supplied structure to fill with preset information
|
||||
* @return #FLUID_OK on success, #FLUID_FAILED otherwise
|
||||
* @deprecated Provides redundant functionality that can be achieved with
|
||||
* fluid_synth_get_channel_preset() or fluid_synth_get_program().
|
||||
* @since 1.1.1
|
||||
*/
|
||||
int
|
||||
fluid_synth_get_channel_info (fluid_synth_t *synth, int chan,
|
||||
fluid_synth_channel_info_t *info)
|
||||
{
|
||||
fluid_channel_t *channel;
|
||||
fluid_preset_t *preset;
|
||||
const char *name;
|
||||
|
||||
if (info)
|
||||
{
|
||||
info->assigned = FALSE;
|
||||
info->name[0] = '\0';
|
||||
}
|
||||
|
||||
fluid_return_val_if_fail (info != NULL, FLUID_FAILED);
|
||||
FLUID_API_ENTRY_CHAN(FLUID_FAILED);
|
||||
|
||||
channel = synth->channel[chan];
|
||||
preset = channel->preset;
|
||||
|
||||
if (preset)
|
||||
{
|
||||
info->assigned = TRUE;
|
||||
name = fluid_preset_get_name (preset);
|
||||
|
||||
if (name)
|
||||
{
|
||||
strncpy (info->name, name, FLUID_SYNTH_CHANNEL_INFO_NAME_SIZE);
|
||||
info->name[FLUID_SYNTH_CHANNEL_INFO_NAME_SIZE - 1] = '\0';
|
||||
}
|
||||
else info->name[0] = '\0';
|
||||
|
||||
info->sfont_id = preset->sfont->id;
|
||||
info->bank = fluid_preset_get_banknum (preset);
|
||||
info->program = fluid_preset_get_num (preset);
|
||||
}
|
||||
else
|
||||
{
|
||||
info->assigned = FALSE;
|
||||
fluid_channel_get_sfont_bank_prog (channel, &info->sfont_id, &info->bank, &info->program);
|
||||
info->name[0] = '\0';
|
||||
}
|
||||
|
||||
fluid_synth_api_exit(synth);
|
||||
return FLUID_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of currently playing voices.
|
||||
* @param synth FluidSynth instance
|
||||
|
@ -3910,9 +3854,12 @@ fluid_synth_set_reverb_on(fluid_synth_t* synth, int on)
|
|||
{
|
||||
fluid_return_if_fail (synth != NULL);
|
||||
|
||||
fluid_atomic_int_set (&synth->with_reverb, on != 0);
|
||||
fluid_synth_api_enter(synth);
|
||||
|
||||
synth->with_reverb = (on != 0);
|
||||
fluid_synth_update_mixer(synth, fluid_rvoice_mixer_set_reverb_enabled,
|
||||
on != 0, 0.0f);
|
||||
fluid_synth_api_exit(synth);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4114,7 +4061,7 @@ fluid_synth_set_chorus_on(fluid_synth_t* synth, int on)
|
|||
fluid_return_if_fail (synth != NULL);
|
||||
fluid_synth_api_enter(synth);
|
||||
|
||||
fluid_atomic_int_set (&synth->with_chorus, on != 0);
|
||||
synth->with_chorus = (on != 0);
|
||||
fluid_synth_update_mixer(synth, fluid_rvoice_mixer_set_chorus_enabled,
|
||||
on != 0, 0.0f);
|
||||
fluid_synth_api_exit(synth);
|
||||
|
@ -4557,30 +4504,6 @@ fluid_synth_update_voice_tuning_LOCAL (fluid_synth_t *synth, fluid_channel_t *ch
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the tuning of the entire MIDI note scale.
|
||||
* @param synth FluidSynth instance
|
||||
* @param bank Tuning bank number (0-127), not related to MIDI instrument bank
|
||||
* @param prog Tuning preset number (0-127), not related to MIDI instrument program
|
||||
* @param name Label name for this tuning
|
||||
* @param pitch Array of pitch values (length of 128, each value is number of
|
||||
* cents, for example normally note 0 is 0.0, 1 is 100.0, 60 is 6000.0, etc).
|
||||
* Pass NULL to create a equal tempered (normal) scale.
|
||||
* @return FLUID_OK on success, FLUID_FAILED otherwise
|
||||
*
|
||||
* @note Tuning is not applied in realtime to existing notes of the replaced
|
||||
* tuning (if any), use fluid_synth_activate_key_tuning() instead to specify
|
||||
* this behavior.
|
||||
*
|
||||
* @deprecated Use fluid_synth_activate_key_tuning(synth, bank, prog, name, pitch, FALSE) instead.
|
||||
*/
|
||||
int
|
||||
fluid_synth_create_key_tuning(fluid_synth_t* synth, int bank, int prog,
|
||||
const char* name, const double* pitch)
|
||||
{
|
||||
return fluid_synth_activate_key_tuning (synth, bank, prog, name, pitch, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the tuning of the entire MIDI note scale.
|
||||
* @param synth FluidSynth instance
|
||||
|
@ -4621,30 +4544,6 @@ fluid_synth_activate_key_tuning(fluid_synth_t* synth, int bank, int prog,
|
|||
FLUID_API_RETURN(retval);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply an octave tuning to every octave in the MIDI note scale.
|
||||
* @param synth FluidSynth instance
|
||||
* @param bank Tuning bank number (0-127), not related to MIDI instrument bank
|
||||
* @param prog Tuning preset number (0-127), not related to MIDI instrument program
|
||||
* @param name Label name for this tuning
|
||||
* @param pitch Array of pitch values (length of 12 for each note of an octave
|
||||
* starting at note C, values are number of offset cents to add to the normal
|
||||
* tuning amount)
|
||||
* @return FLUID_OK on success, FLUID_FAILED otherwise
|
||||
*
|
||||
* @note Tuning is not applied in realtime to existing notes of the replaced
|
||||
* tuning (if any), use fluid_synth_activate_octave_tuning() instead to specify
|
||||
* this behavior.
|
||||
*
|
||||
* @deprecated Use fluid_synth_activate_octave_tuning(synth, bank, prog, name, pitch, FALSE) instead.
|
||||
*/
|
||||
int
|
||||
fluid_synth_create_octave_tuning(fluid_synth_t* synth, int bank, int prog,
|
||||
const char* name, const double* pitch)
|
||||
{
|
||||
return fluid_synth_activate_octave_tuning (synth, bank, prog, name, pitch, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate an octave tuning on every octave in the MIDI note scale.
|
||||
* @param synth FluidSynth instance
|
||||
|
@ -4739,30 +4638,6 @@ fluid_synth_tune_notes(fluid_synth_t* synth, int bank, int prog,
|
|||
FLUID_API_RETURN(retval);
|
||||
}
|
||||
|
||||
/**
|
||||
* Select a tuning scale on a MIDI channel.
|
||||
* @param synth FluidSynth instance
|
||||
* @param chan MIDI channel number (0 to MIDI channel count - 1)
|
||||
* @param bank Tuning bank number (0-127), not related to MIDI instrument bank
|
||||
* @param prog Tuning preset number (0-127), not related to MIDI instrument program
|
||||
* @return FLUID_OK on success, FLUID_FAILED otherwise
|
||||
*
|
||||
* @note This function does NOT activate tuning in realtime, use
|
||||
* fluid_synth_activate_tuning() instead to specify whether tuning change
|
||||
* should cause existing notes to update.
|
||||
*
|
||||
* @note Prior to version 1.1.0 it was an error to select a tuning that didn't
|
||||
* already exist. Starting with 1.1.0, a default equal tempered scale will be
|
||||
* created, if no tuning exists for the given bank and prog.
|
||||
*
|
||||
* @deprecated Use fluid_synth_activate_tuning(synth, chan, bank, prog, FALSE) instead.
|
||||
*/
|
||||
int
|
||||
fluid_synth_select_tuning(fluid_synth_t* synth, int chan, int bank, int prog)
|
||||
{
|
||||
return fluid_synth_activate_tuning (synth, chan, bank, prog, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate a tuning scale on a MIDI channel.
|
||||
* @param synth FluidSynth instance
|
||||
|
@ -4838,24 +4713,6 @@ fluid_synth_set_tuning_LOCAL (fluid_synth_t *synth, int chan,
|
|||
return FLUID_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear tuning scale on a MIDI channel (set it to the default equal tempered scale).
|
||||
* @param synth FluidSynth instance
|
||||
* @param chan MIDI channel number (0 to MIDI channel count - 1)
|
||||
* @return FLUID_OK on success, FLUID_FAILED otherwise
|
||||
*
|
||||
* @note This function does NOT activate tuning change in realtime, use
|
||||
* fluid_synth_deactivate_tuning() instead to specify whether tuning change
|
||||
* should cause existing notes to update.
|
||||
*
|
||||
* @deprecated Use fluid_synth_deactivate_tuning(synth, chan, FALSE) instead.
|
||||
*/
|
||||
int
|
||||
fluid_synth_reset_tuning(fluid_synth_t* synth, int chan)
|
||||
{
|
||||
return fluid_synth_deactivate_tuning (synth, chan, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear tuning scale on a MIDI channel (use default equal tempered scale).
|
||||
* @param synth FluidSynth instance
|
||||
|
@ -4990,6 +4847,14 @@ fluid_synth_get_settings(fluid_synth_t* synth)
|
|||
return synth->settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as calling \c fluid_synth_set_gen2(synth, chan, param, value, FALSE, FALSE)
|
||||
* @return FLUID_OK on success, FLUID_FAILED otherwise
|
||||
*/
|
||||
int fluid_synth_set_gen(fluid_synth_t* synth, int chan, int param, float value)
|
||||
{
|
||||
return fluid_synth_set_gen2(synth, chan, param, value, FALSE, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a SoundFont generator (effect) value on a MIDI channel in real-time.
|
||||
|
@ -5002,19 +4867,15 @@ fluid_synth_get_settings(fluid_synth_t* synth)
|
|||
* TRUE to take the value as a 0.0-1.0 range and apply it to the valid
|
||||
* generator effect range (scaled and shifted as necessary).
|
||||
* @return FLUID_OK on success, FLUID_FAILED otherwise
|
||||
* @since 2.0.0
|
||||
*
|
||||
* This function allows for setting all effect parameters in real time on a
|
||||
* MIDI channel. Setting absolute to non-zero will cause the value to override
|
||||
* MIDI channel. Setting absolute to non-zero will cause the value to override
|
||||
* any generator values set in the instruments played on the MIDI channel.
|
||||
* See SoundFont 2.01 spec, paragraph 8.1.3, page 48 for details on SoundFont
|
||||
* generator parameters and valid ranges.
|
||||
*
|
||||
* @note The old behaviour of fluid_synth_set_gen() assumed \c absolute and \c normalized to
|
||||
* be FALSE.
|
||||
*/
|
||||
int
|
||||
fluid_synth_set_gen(fluid_synth_t* synth, int chan, int param,
|
||||
fluid_synth_set_gen2(fluid_synth_t* synth, int chan, int param,
|
||||
float value, int absolute, int normalized)
|
||||
{
|
||||
float v;
|
||||
|
@ -5301,3 +5162,77 @@ fluid_ladspa_fx_t *fluid_synth_get_ladspa_fx(fluid_synth_t *synth)
|
|||
|
||||
return synth->ladspa_fx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the important channels for voice overflow priority calculation.
|
||||
*
|
||||
* @param synth FluidSynth instance
|
||||
* @param channels comma-separated list of channel numbers
|
||||
* @return FLUID_OK on success, otherwise FLUID_FAILED
|
||||
*/
|
||||
static int fluid_synth_set_important_channels(fluid_synth_t *synth, const char *channels)
|
||||
{
|
||||
int i;
|
||||
int retval = FLUID_FAILED;
|
||||
int *values = NULL;
|
||||
int num_values;
|
||||
fluid_overflow_prio_t *scores;
|
||||
|
||||
fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
|
||||
|
||||
scores = &synth->overflow;
|
||||
if (scores->num_important_channels < synth->midi_channels)
|
||||
{
|
||||
scores->important_channels = FLUID_REALLOC(scores->important_channels,
|
||||
sizeof(*scores->important_channels) * synth->midi_channels);
|
||||
if (scores->important_channels == NULL)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||
goto exit;
|
||||
}
|
||||
scores->num_important_channels = synth->midi_channels;
|
||||
}
|
||||
|
||||
FLUID_MEMSET(scores->important_channels, FALSE,
|
||||
sizeof(*scores->important_channels) * scores->num_important_channels);
|
||||
|
||||
if (channels != NULL)
|
||||
{
|
||||
values = FLUID_ARRAY(int, synth->midi_channels);
|
||||
if (values == NULL)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||
goto exit;
|
||||
}
|
||||
/* Every channel given in the comma-separated list of channel numbers
|
||||
* is set to TRUE, i.e. flagging it as "important". Channel numbers are
|
||||
* 1-based. */
|
||||
num_values = fluid_settings_split_csv(channels, values, synth->midi_channels);
|
||||
for (i = 0; i < num_values; i++)
|
||||
{
|
||||
if (values[i] > 0 && values[i] <= synth->midi_channels)
|
||||
{
|
||||
scores->important_channels[values[i] - 1] = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
retval = FLUID_OK;
|
||||
|
||||
exit:
|
||||
FLUID_FREE(values);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handler for synth.overflow.important-channels setting.
|
||||
*/
|
||||
static void fluid_synth_handle_important_channels(void *data, const char *name,
|
||||
const char *value)
|
||||
{
|
||||
fluid_synth_t *synth = (fluid_synth_t *)data;
|
||||
|
||||
fluid_synth_api_enter(synth);
|
||||
fluid_synth_set_important_channels(synth, value);
|
||||
fluid_synth_api_exit(synth);
|
||||
}
|
||||
|
|
|
@ -28,17 +28,13 @@
|
|||
* INCLUDES
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#include "fluidsynth_priv.h"
|
||||
#include "fluid_sys.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"
|
||||
#include "fluid_rvoice_event.h"
|
||||
|
||||
/***************************************************************
|
||||
|
@ -78,7 +74,7 @@ enum fluid_synth_status
|
|||
#define SYNTH_REVERB_CHANNEL 0
|
||||
#define SYNTH_CHORUS_CHANNEL 1
|
||||
|
||||
/**
|
||||
/*
|
||||
* Structure used for sfont_info field in #fluid_synth_t for each loaded
|
||||
* SoundFont with the SoundFont instance and additional fields.
|
||||
*/
|
||||
|
@ -113,8 +109,8 @@ struct _fluid_synth_t
|
|||
fluid_settings_t* settings; /**< the synthesizer settings */
|
||||
int device_id; /**< Device ID used for SYSEX messages */
|
||||
int polyphony; /**< Maximum polyphony */
|
||||
fluid_atomic_int_t with_reverb; /**< Should the synth use the built-in reverb unit? */
|
||||
fluid_atomic_int_t with_chorus; /**< Should the synth use the built-in chorus unit? */
|
||||
int with_reverb; /**< Should the synth use the built-in reverb unit? */
|
||||
int with_chorus; /**< Should the synth use the built-in chorus unit? */
|
||||
int verbose; /**< Turn verbose mode on? */
|
||||
double sample_rate; /**< The sample rate */
|
||||
int midi_channels; /**< the number of MIDI channels (>= 16) */
|
||||
|
|
|
@ -368,7 +368,7 @@ 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)
|
||||
fluid_real_t fluid_voice_gen_value(const fluid_voice_t* voice, int num)
|
||||
{
|
||||
/* This is an extension to the SoundFont standard. More
|
||||
* documentation is available at the fluid_synth_set_gen2()
|
||||
|
@ -420,7 +420,9 @@ void fluid_voice_start(fluid_voice_t* voice)
|
|||
|
||||
fluid_voice_calculate_runtime_synthesis_parameters(voice);
|
||||
|
||||
#ifdef WITH_PROFILING
|
||||
voice->ref = fluid_profile_ref();
|
||||
#endif
|
||||
|
||||
voice->status = FLUID_VOICE_ON;
|
||||
|
||||
|
@ -428,6 +430,17 @@ void fluid_voice_start(fluid_voice_t* voice)
|
|||
voice->channel->synth->active_voice_count++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the amplitude of a voice.
|
||||
*
|
||||
* @param gain The gain value in the range [0.0 ; 1.0]
|
||||
* @return An amplitude used by rvoice_mixer's buffers
|
||||
*/
|
||||
static fluid_real_t fluid_voice_calculate_gain_amplitude(const fluid_voice_t* voice, fluid_real_t gain)
|
||||
{
|
||||
return gain * voice->synth_gain / 32768.0f;
|
||||
}
|
||||
|
||||
void
|
||||
fluid_voice_calculate_gen_pitch(fluid_voice_t* voice)
|
||||
{
|
||||
|
@ -438,7 +451,7 @@ fluid_voice_calculate_gen_pitch(fluid_voice_t* voice)
|
|||
* 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,
|
||||
* to fluid_voice_gen_value(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)) {
|
||||
|
@ -601,7 +614,7 @@ calculate_hold_decay_buffers(fluid_voice_t* voice, int gen_base,
|
|||
* 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 - fluid_voice_get_actual_key(voice)));
|
||||
timecents = (fluid_voice_gen_value(voice, gen_base) + fluid_voice_gen_value(voice, gen_key2base) * (60.0 - fluid_voice_get_actual_key(voice)));
|
||||
|
||||
/* Range checking */
|
||||
if (is_decay){
|
||||
|
@ -649,7 +662,7 @@ calculate_hold_decay_buffers(fluid_voice_t* voice, int gen_base,
|
|||
*
|
||||
* 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
|
||||
* NRPN system. fluid_voice_gen_value(voice, generator_enumerator) returns the sum
|
||||
* of all three.
|
||||
*/
|
||||
/**
|
||||
|
@ -663,22 +676,24 @@ calculate_hold_decay_buffers(fluid_voice_t* voice, int gen_base,
|
|||
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, z;
|
||||
// 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.4f;
|
||||
unsigned int count, z;
|
||||
fluid_real_t q_dB;
|
||||
fluid_real_t x = fluid_voice_gen_value(voice, gen);
|
||||
|
||||
|
||||
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;
|
||||
UPDATE_RVOICE_BUFFERS2(fluid_rvoice_buffers_set_amp, 0, voice->amp_left);
|
||||
UPDATE_RVOICE_BUFFERS2(fluid_rvoice_buffers_set_amp, 1, voice->amp_right);
|
||||
voice->pan = x;
|
||||
|
||||
/* left amp */
|
||||
UPDATE_RVOICE_BUFFERS2(fluid_rvoice_buffers_set_amp, 0, fluid_voice_calculate_gain_amplitude(voice, fluid_pan(x, 1)));
|
||||
|
||||
/* right amp */
|
||||
UPDATE_RVOICE_BUFFERS2(fluid_rvoice_buffers_set_amp, 1, fluid_voice_calculate_gain_amplitude(voice, fluid_pan(x, 0)));
|
||||
break;
|
||||
|
||||
case GEN_ATTENUATION:
|
||||
|
@ -699,26 +714,24 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen)
|
|||
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));
|
||||
voice->pitch = (fluid_voice_gen_value(voice, GEN_PITCH)
|
||||
+ 100.0f * fluid_voice_gen_value(voice, GEN_COARSETUNE)
|
||||
+ fluid_voice_gen_value(voice, GEN_FINETUNE));
|
||||
UPDATE_RVOICE_R1(fluid_rvoice_set_pitch, voice->pitch);
|
||||
break;
|
||||
|
||||
case GEN_REVERBSEND:
|
||||
/* The generator unit is 'tenths of a percent'. */
|
||||
voice->reverb_send = _GEN(voice, GEN_REVERBSEND) / 1000.0f;
|
||||
voice->reverb_send = x / 1000.0f;
|
||||
fluid_clip(voice->reverb_send, 0.0, 1.0);
|
||||
voice->amp_reverb = voice->reverb_send * voice->synth_gain / 32768.0f;
|
||||
UPDATE_RVOICE_BUFFERS2(fluid_rvoice_buffers_set_amp, 2, voice->amp_reverb);
|
||||
UPDATE_RVOICE_BUFFERS2(fluid_rvoice_buffers_set_amp, 2, fluid_voice_calculate_gain_amplitude(voice, voice->reverb_send));
|
||||
break;
|
||||
|
||||
case GEN_CHORUSSEND:
|
||||
/* The generator unit is 'tenths of a percent'. */
|
||||
voice->chorus_send = _GEN(voice, GEN_CHORUSSEND) / 1000.0f;
|
||||
voice->chorus_send = x / 1000.0f;
|
||||
fluid_clip(voice->chorus_send, 0.0, 1.0);
|
||||
voice->amp_chorus = voice->chorus_send * voice->synth_gain / 32768.0f;
|
||||
UPDATE_RVOICE_BUFFERS2(fluid_rvoice_buffers_set_amp, 3, voice->amp_chorus);
|
||||
UPDATE_RVOICE_BUFFERS2(fluid_rvoice_buffers_set_amp, 3, fluid_voice_calculate_gain_amplitude(voice, voice->chorus_send));
|
||||
break;
|
||||
|
||||
case GEN_OVERRIDEROOTKEY:
|
||||
|
@ -754,14 +767,13 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen)
|
|||
* modulation. The allowed range is tested in the 'fluid_ct2hz'
|
||||
* function [PH,20021214]
|
||||
*/
|
||||
x = _GEN(voice, GEN_FILTERFC);
|
||||
UPDATE_RVOICE_FILTER1(fluid_iir_filter_set_fres, x);
|
||||
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;
|
||||
q_dB = x / 10.0f;
|
||||
|
||||
/* Range: SF2.01 section 8.1.3 # 8 (convert from cB to dB => /10) */
|
||||
fluid_clip(q_dB, 0.0f, 96.0f);
|
||||
|
@ -787,25 +799,21 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen)
|
|||
break;
|
||||
|
||||
case GEN_MODLFOTOPITCH:
|
||||
x = _GEN(voice, GEN_MODLFOTOPITCH);
|
||||
fluid_clip(x, -12000.0, 12000.0);
|
||||
UPDATE_RVOICE_R1(fluid_rvoice_set_modlfo_to_pitch, x);
|
||||
break;
|
||||
|
||||
case GEN_MODLFOTOVOL:
|
||||
x = _GEN(voice, GEN_MODLFOTOVOL);
|
||||
fluid_clip(x, -960.0, 960.0);
|
||||
UPDATE_RVOICE_R1(fluid_rvoice_set_modlfo_to_vol, x);
|
||||
break;
|
||||
|
||||
case GEN_MODLFOTOFILTERFC:
|
||||
x = _GEN(voice, GEN_MODLFOTOFILTERFC);
|
||||
fluid_clip(x, -12000, 12000);
|
||||
UPDATE_RVOICE_R1(fluid_rvoice_set_modlfo_to_fc, x);
|
||||
break;
|
||||
|
||||
case GEN_MODLFODELAY:
|
||||
x = _GEN(voice, GEN_MODLFODELAY);
|
||||
fluid_clip(x, -12000.0f, 5000.0f);
|
||||
z = (unsigned int) (voice->output_rate * fluid_tc2sec_delay(x));
|
||||
UPDATE_RVOICE_ENVLFO_I1(fluid_lfo_set_delay, modlfo, z);
|
||||
|
@ -815,7 +823,6 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen)
|
|||
/* - 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);
|
||||
x = (4.0f * FLUID_BUFSIZE * fluid_act2hz(x) / voice->output_rate);
|
||||
UPDATE_RVOICE_ENVLFO_R1(fluid_lfo_set_incr, modlfo, x);
|
||||
|
@ -827,21 +834,18 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen)
|
|||
* - 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);
|
||||
x = 4.0f * FLUID_BUFSIZE * fluid_act2hz(x) / voice->output_rate;
|
||||
UPDATE_RVOICE_ENVLFO_R1(fluid_lfo_set_incr, viblfo, x);
|
||||
break;
|
||||
|
||||
case GEN_VIBLFODELAY:
|
||||
x = _GEN(voice,GEN_VIBLFODELAY);
|
||||
fluid_clip(x, -12000.0f, 5000.0f);
|
||||
z = (unsigned int) (voice->output_rate * fluid_tc2sec_delay(x));
|
||||
UPDATE_RVOICE_ENVLFO_I1(fluid_lfo_set_delay, viblfo, z);
|
||||
break;
|
||||
|
||||
case GEN_VIBLFOTOPITCH:
|
||||
x = _GEN(voice, GEN_VIBLFOTOPITCH);
|
||||
fluid_clip(x, -12000.0, 12000.0);
|
||||
UPDATE_RVOICE_R1(fluid_rvoice_set_viblfo_to_pitch, x);
|
||||
break;
|
||||
|
@ -860,7 +864,7 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen)
|
|||
* never be released on a noteoff event
|
||||
*/
|
||||
#if 0
|
||||
x = _GEN(voice, GEN_KEYNUM);
|
||||
x = fluid_voice_gen_value(voice, GEN_KEYNUM);
|
||||
if (x >= 0){
|
||||
voice->key = x;
|
||||
}
|
||||
|
@ -876,12 +880,12 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen)
|
|||
* There is a flag, which should indicate, whether a generator is
|
||||
* enabled or not. But here we rely on the default value of -1.
|
||||
*/
|
||||
/* 2017-09-02: do not change the voice's velocity here, user
|
||||
/* 2017-09-02: do not change the voice's velocity here, use
|
||||
* fluid_voice_get_actual_velocity() to get the value of this generator
|
||||
* if active.
|
||||
*/
|
||||
#if 0
|
||||
x = _GEN(voice, GEN_VELOCITY);
|
||||
x = fluid_voice_gen_value(voice, GEN_VELOCITY);
|
||||
if (x > 0) {
|
||||
voice->vel = x;
|
||||
}
|
||||
|
@ -889,14 +893,11 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen)
|
|||
break;
|
||||
|
||||
case GEN_MODENVTOPITCH:
|
||||
x = _GEN(voice, GEN_MODENVTOPITCH);
|
||||
fluid_clip(x, -12000.0, 12000.0);
|
||||
UPDATE_RVOICE_R1(fluid_rvoice_set_modenv_to_pitch, x);
|
||||
break;
|
||||
|
||||
case GEN_MODENVTOFILTERFC:
|
||||
x = _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
|
||||
|
@ -919,39 +920,47 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen)
|
|||
*/
|
||||
case GEN_STARTADDROFS: /* SF2.01 section 8.1.3 # 0 */
|
||||
case GEN_STARTADDRCOARSEOFS: /* SF2.01 section 8.1.3 # 4 */
|
||||
if (voice->sample != NULL) {
|
||||
z = (voice->sample->start
|
||||
+ (int) _GEN(voice, GEN_STARTADDROFS)
|
||||
+ 32768 * (int) _GEN(voice, GEN_STARTADDRCOARSEOFS));
|
||||
UPDATE_RVOICE_I1(fluid_rvoice_set_start, z);
|
||||
if (voice->sample != NULL)
|
||||
{
|
||||
fluid_real_t start_fine = fluid_voice_gen_value(voice, GEN_STARTADDROFS);
|
||||
fluid_real_t start_coar = fluid_voice_gen_value(voice, GEN_STARTADDRCOARSEOFS);
|
||||
|
||||
z = voice->sample->start + (int)start_fine + 32768 * (int)start_coar;
|
||||
UPDATE_RVOICE_I1(fluid_rvoice_set_start, z);
|
||||
}
|
||||
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) {
|
||||
z = (voice->sample->end
|
||||
+ (int) _GEN(voice, GEN_ENDADDROFS)
|
||||
+ 32768 * (int) _GEN(voice, GEN_ENDADDRCOARSEOFS));
|
||||
UPDATE_RVOICE_I1(fluid_rvoice_set_end, z);
|
||||
if (voice->sample != NULL)
|
||||
{
|
||||
fluid_real_t end_fine = fluid_voice_gen_value(voice, GEN_ENDADDROFS);
|
||||
fluid_real_t end_coar = fluid_voice_gen_value(voice, GEN_ENDADDRCOARSEOFS);
|
||||
|
||||
z = voice->sample->end + (int)end_fine + 32768 * (int)end_coar;
|
||||
UPDATE_RVOICE_I1(fluid_rvoice_set_end, z);
|
||||
}
|
||||
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) {
|
||||
z = (voice->sample->loopstart
|
||||
+ (int) _GEN(voice, GEN_STARTLOOPADDROFS)
|
||||
+ 32768 * (int) _GEN(voice, GEN_STARTLOOPADDRCOARSEOFS));
|
||||
UPDATE_RVOICE_I1(fluid_rvoice_set_loopstart, z);
|
||||
if (voice->sample != NULL)
|
||||
{
|
||||
fluid_real_t lstart_fine = fluid_voice_gen_value(voice, GEN_STARTLOOPADDROFS);
|
||||
fluid_real_t lstart_coar = fluid_voice_gen_value(voice, GEN_STARTLOOPADDRCOARSEOFS);
|
||||
|
||||
z = voice->sample->loopstart + (int)lstart_fine + 32768 * (int)lstart_coar;
|
||||
UPDATE_RVOICE_I1(fluid_rvoice_set_loopstart, z);
|
||||
}
|
||||
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) {
|
||||
z = (voice->sample->loopend
|
||||
+ (int) _GEN(voice, GEN_ENDLOOPADDROFS)
|
||||
+ 32768 * (int) _GEN(voice, GEN_ENDLOOPADDRCOARSEOFS));
|
||||
UPDATE_RVOICE_I1(fluid_rvoice_set_loopend, z);
|
||||
if (voice->sample != NULL)
|
||||
{
|
||||
fluid_real_t lend_fine = fluid_voice_gen_value(voice, GEN_ENDLOOPADDROFS);
|
||||
fluid_real_t lend_coar = fluid_voice_gen_value(voice, GEN_ENDLOOPADDRCOARSEOFS);
|
||||
|
||||
z = voice->sample->loopend + (int)lend_fine + 32768 * (int)lend_coar;
|
||||
UPDATE_RVOICE_I1(fluid_rvoice_set_loopend, z);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -967,7 +976,6 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen)
|
|||
* - 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);
|
||||
fluid_voice_update_volenv(voice, FLUID_VOICE_ENVDELAY,
|
||||
|
@ -975,7 +983,6 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen)
|
|||
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);
|
||||
fluid_voice_update_volenv(voice, FLUID_VOICE_ENVATTACK,
|
||||
|
@ -992,15 +999,14 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen)
|
|||
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);
|
||||
x = 1.0f - 0.001f * fluid_voice_gen_value(voice, GEN_VOLENVSUSTAIN);
|
||||
fluid_clip(x , 0.0f, 1.0f);
|
||||
count = calculate_hold_decay_buffers(voice, GEN_VOLENVDECAY, GEN_KEYTOVOLENVDECAY, 1); /* 1 for decay */
|
||||
fluid_voice_update_volenv(voice, FLUID_VOICE_ENVDECAY,
|
||||
count, 1.0f, count ? -1.0f / count : 0.0f, y, 2.0f);
|
||||
count, 1.0f, count ? -1.0f / count : 0.0f, x, 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);
|
||||
fluid_voice_update_volenv(voice, FLUID_VOICE_ENVRELEASE,
|
||||
|
@ -1009,14 +1015,12 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen)
|
|||
|
||||
/* Modulation envelope */
|
||||
case GEN_MODENVDELAY: /* SF2.01 section 8.1.3 # 25 */
|
||||
x = _GEN(voice, GEN_MODENVDELAY);
|
||||
fluid_clip(x, -12000.0f, 5000.0f);
|
||||
fluid_voice_update_modenv(voice, FLUID_VOICE_ENVDELAY,
|
||||
NUM_BUFFERS_DELAY(x), 0.0f, 0.0f, -1.0f, 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);
|
||||
fluid_voice_update_modenv(voice, FLUID_VOICE_ENVATTACK,
|
||||
|
@ -1034,14 +1038,13 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen)
|
|||
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);
|
||||
x = 1.0f - 0.001f * fluid_voice_gen_value(voice, GEN_MODENVSUSTAIN);
|
||||
fluid_clip(x, 0.0f, 1.0f);
|
||||
fluid_voice_update_modenv(voice, FLUID_VOICE_ENVDECAY,
|
||||
count, 1.0f, count ? -1.0f / count : 0.0f, y, 2.0f);
|
||||
count, 1.0f, count ? -1.0f / count : 0.0f, x, 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);
|
||||
fluid_voice_update_modenv(voice, FLUID_VOICE_ENVRELEASE,
|
||||
|
@ -1452,7 +1455,7 @@ int fluid_voice_get_channel(const fluid_voice_t* voice)
|
|||
*/
|
||||
int fluid_voice_get_actual_key(const fluid_voice_t* voice)
|
||||
{
|
||||
fluid_real_t x = _GEN(voice, GEN_KEYNUM);
|
||||
fluid_real_t x = fluid_voice_gen_value(voice, GEN_KEYNUM);
|
||||
if (x >= 0)
|
||||
{
|
||||
return (int)x;
|
||||
|
@ -1485,7 +1488,7 @@ int fluid_voice_get_key(const fluid_voice_t* voice)
|
|||
*/
|
||||
int fluid_voice_get_actual_velocity(const fluid_voice_t* voice)
|
||||
{
|
||||
fluid_real_t x = _GEN(voice, GEN_VELOCITY);
|
||||
fluid_real_t x = fluid_voice_gen_value(voice, GEN_VELOCITY);
|
||||
if (x > 0)
|
||||
{
|
||||
return (int)x;
|
||||
|
@ -1589,22 +1592,24 @@ int fluid_voice_set_param(fluid_voice_t* voice, int gen, fluid_real_t nrpn_value
|
|||
|
||||
int fluid_voice_set_gain(fluid_voice_t* voice, fluid_real_t gain)
|
||||
{
|
||||
fluid_real_t left, right, reverb, chorus;
|
||||
|
||||
/* 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;
|
||||
left = fluid_voice_calculate_gain_amplitude(voice, fluid_pan(voice->pan, 1));
|
||||
right = fluid_voice_calculate_gain_amplitude(voice, fluid_pan(voice->pan, 0));
|
||||
reverb = fluid_voice_calculate_gain_amplitude(voice, voice->reverb_send);
|
||||
chorus = fluid_voice_calculate_gain_amplitude(voice, voice->chorus_send);
|
||||
|
||||
UPDATE_RVOICE_R1(fluid_rvoice_set_synth_gain, gain);
|
||||
UPDATE_RVOICE_BUFFERS2(fluid_rvoice_buffers_set_amp, 0, voice->amp_left);
|
||||
UPDATE_RVOICE_BUFFERS2(fluid_rvoice_buffers_set_amp, 1, voice->amp_right);
|
||||
UPDATE_RVOICE_BUFFERS2(fluid_rvoice_buffers_set_amp, 2, voice->amp_reverb);
|
||||
UPDATE_RVOICE_BUFFERS2(fluid_rvoice_buffers_set_amp, 3, voice->amp_chorus);
|
||||
UPDATE_RVOICE_BUFFERS2(fluid_rvoice_buffers_set_amp, 0, left);
|
||||
UPDATE_RVOICE_BUFFERS2(fluid_rvoice_buffers_set_amp, 1, right);
|
||||
UPDATE_RVOICE_BUFFERS2(fluid_rvoice_buffers_set_amp, 2, reverb);
|
||||
UPDATE_RVOICE_BUFFERS2(fluid_rvoice_buffers_set_amp, 3, chorus);
|
||||
|
||||
return FLUID_OK;
|
||||
}
|
||||
|
@ -1681,12 +1686,13 @@ fluid_voice_optimize_sample(fluid_sample_t* s)
|
|||
return FLUID_OK;
|
||||
}
|
||||
|
||||
fluid_real_t
|
||||
float
|
||||
fluid_voice_get_overflow_prio(fluid_voice_t* voice,
|
||||
fluid_overflow_prio_t* score,
|
||||
unsigned int cur_time)
|
||||
{
|
||||
fluid_real_t this_voice_prio = 0;
|
||||
float this_voice_prio = 0;
|
||||
int channel;
|
||||
|
||||
/* Are we already overflowing? */
|
||||
if (!voice->can_access_overflow_rvoice) {
|
||||
|
@ -1734,6 +1740,13 @@ fluid_voice_get_overflow_prio(fluid_voice_t* voice,
|
|||
}
|
||||
this_voice_prio += score->volume / a;
|
||||
}
|
||||
|
||||
/* Check if this voice is on an important channel. If so, then add the
|
||||
* score for important channels */
|
||||
channel = fluid_voice_get_channel(voice);
|
||||
if (channel < score->num_important_channels && score->important_channels[channel]) {
|
||||
this_voice_prio += score->important;
|
||||
}
|
||||
|
||||
return this_voice_prio;
|
||||
}
|
||||
|
|
|
@ -33,15 +33,19 @@
|
|||
|
||||
#define NO_CHANNEL 0xff
|
||||
|
||||
|
||||
typedef struct _fluid_overflow_prio_t fluid_overflow_prio_t;
|
||||
|
||||
struct _fluid_overflow_prio_t
|
||||
{
|
||||
fluid_real_t percussion; /**< Is this voice on the drum channel? Then add this score */
|
||||
fluid_real_t released; /**< Is this voice in release stage? Then add this score (usually negative) */
|
||||
fluid_real_t sustained; /**< Is this voice sustained? Then add this score (usually negative) */
|
||||
fluid_real_t volume; /**< Multiply current (or future) volume (a value between 0 and 1) */
|
||||
fluid_real_t age; /**< This score will be divided by the number of seconds the voice has lasted */
|
||||
float percussion; /**< Is this voice on the drum channel? Then add this score */
|
||||
float released; /**< Is this voice in release stage? Then add this score (usually negative) */
|
||||
float sustained; /**< Is this voice sustained? Then add this score (usually negative) */
|
||||
float volume; /**< Multiply current (or future) volume (a value between 0 and 1) */
|
||||
float age; /**< This score will be divided by the number of seconds the voice has lasted */
|
||||
float important; /**< This score will be added to all important channels */
|
||||
char *important_channels; /**< "important" flags indexed by MIDI channel number */
|
||||
int num_important_channels; /**< Number of elements in the important_channels array */
|
||||
};
|
||||
|
||||
enum fluid_voice_status
|
||||
|
@ -87,16 +91,12 @@ struct _fluid_voice_t
|
|||
|
||||
/* 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;
|
||||
|
||||
/* rvoice control */
|
||||
fluid_rvoice_t* rvoice;
|
||||
|
@ -105,8 +105,10 @@ struct _fluid_voice_t
|
|||
char can_access_overflow_rvoice; /* False if overflow_rvoice is being rendered in separate thread */
|
||||
char has_noteoff; /* Flag set when noteoff has been sent */
|
||||
|
||||
#ifdef WITH_PROFILING
|
||||
/* for debugging */
|
||||
double ref;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
@ -148,7 +150,7 @@ void fluid_voice_stop(fluid_voice_t* voice);
|
|||
void fluid_voice_overflow_rvoice_finished(fluid_voice_t* voice);
|
||||
|
||||
int fluid_voice_kill_excl(fluid_voice_t* voice);
|
||||
fluid_real_t fluid_voice_get_overflow_prio(fluid_voice_t* voice,
|
||||
float fluid_voice_get_overflow_prio(fluid_voice_t* voice,
|
||||
fluid_overflow_prio_t* score,
|
||||
unsigned int cur_time);
|
||||
|
||||
|
@ -179,15 +181,9 @@ fluid_voice_unlock_rvoice(fluid_voice_t* voice)
|
|||
#define _SAMPLEMODE(voice) ((int)(voice)->gen[GEN_SAMPLEMODE].val)
|
||||
|
||||
|
||||
/* FIXME - This doesn't seem to be used anywhere - JG */
|
||||
fluid_real_t fluid_voice_gen_value(fluid_voice_t* voice, int num);
|
||||
fluid_real_t fluid_voice_gen_value(const fluid_voice_t* voice, int num);
|
||||
|
||||
#define fluid_voice_get_loudness(voice) (fluid_adsr_env_get_max_val(&voice->volenv))
|
||||
|
||||
#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)
|
||||
|
||||
|
||||
#endif /* _FLUID_VOICE_H */
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
#include "fluid_sys.h"
|
||||
|
||||
/**
|
||||
/*
|
||||
* Lockless event queue instance.
|
||||
*/
|
||||
struct _fluid_ringbuffer_t
|
||||
|
@ -46,7 +46,7 @@ void delete_fluid_ringbuffer (fluid_ringbuffer_t *queue);
|
|||
/**
|
||||
* Get pointer to next input array element in queue.
|
||||
* @param queue Lockless queue instance
|
||||
* @param count Normally zero, or more if you need to push several items at once
|
||||
* @param offset Normally zero, or more if you need to push several items at once
|
||||
* @return Pointer to array element in queue to store data to or NULL if queue is full
|
||||
*
|
||||
* This function along with fluid_ringbuffer_next_inptr() form a queue "push"
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
* 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "fluidsynth_priv.h"
|
||||
#include "fluid_sys.h"
|
||||
#include "fluid_hash.h"
|
||||
#include "fluid_synth.h"
|
||||
|
@ -87,7 +86,7 @@ typedef struct {
|
|||
} fluid_setting_node_t;
|
||||
|
||||
static fluid_setting_node_t*
|
||||
new_fluid_str_setting(const char* value, const char* def, int hints, fluid_str_update_t fun, void* data)
|
||||
new_fluid_str_setting(const char* value, const char* def, int hints)
|
||||
{
|
||||
fluid_setting_node_t* node;
|
||||
fluid_str_setting_t* str;
|
||||
|
@ -101,14 +100,14 @@ new_fluid_str_setting(const char* value, const char* def, int hints, fluid_str_u
|
|||
}
|
||||
|
||||
node->type = FLUID_STR_TYPE;
|
||||
|
||||
str = &node->str;
|
||||
|
||||
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;
|
||||
str->update = NULL;
|
||||
str->data = NULL;
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -138,8 +137,7 @@ delete_fluid_str_setting(fluid_setting_node_t* node)
|
|||
|
||||
|
||||
static fluid_setting_node_t*
|
||||
new_fluid_num_setting(double min, double max, double def,
|
||||
int hints, fluid_num_update_t fun, void* data)
|
||||
new_fluid_num_setting(double min, double max, double def, int hints)
|
||||
{
|
||||
fluid_setting_node_t* node;
|
||||
fluid_num_setting_t* num;
|
||||
|
@ -153,15 +151,15 @@ new_fluid_num_setting(double min, double max, double def,
|
|||
}
|
||||
|
||||
node->type = FLUID_NUM_TYPE;
|
||||
|
||||
num = &node->num;
|
||||
|
||||
num->value = def;
|
||||
num->def = def;
|
||||
num->min = min;
|
||||
num->max = max;
|
||||
num->hints = hints;
|
||||
num->update = fun;
|
||||
num->data = data;
|
||||
num->update = NULL;
|
||||
num->data = NULL;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
@ -176,8 +174,7 @@ delete_fluid_num_setting(fluid_setting_node_t* node)
|
|||
}
|
||||
|
||||
static fluid_setting_node_t*
|
||||
new_fluid_int_setting(int min, int max, int def,
|
||||
int hints, fluid_int_update_t fun, void* data)
|
||||
new_fluid_int_setting(int min, int max, int def, int hints)
|
||||
{
|
||||
fluid_setting_node_t* node;
|
||||
fluid_int_setting_t* i;
|
||||
|
@ -191,15 +188,15 @@ new_fluid_int_setting(int min, int max, int def,
|
|||
}
|
||||
|
||||
node->type = FLUID_INT_TYPE;
|
||||
|
||||
i = &node->i;
|
||||
|
||||
i->value = def;
|
||||
i->def = def;
|
||||
i->min = min;
|
||||
i->max = max;
|
||||
i->hints = hints;
|
||||
i->update = fun;
|
||||
i->data = data;
|
||||
i->update = NULL;
|
||||
i->data = NULL;
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -471,13 +468,10 @@ fluid_settings_set(fluid_settings_t* settings, const char *name, fluid_setting_n
|
|||
* @param name the setting's name
|
||||
* @param def the default value for the setting
|
||||
* @param hints the hints for the setting
|
||||
* @param fun an update function for the setting
|
||||
* @param data user supplied data
|
||||
* @return #FLUID_OK if the value has been register correctly, #FLUID_FAILED otherwise
|
||||
*/
|
||||
int
|
||||
fluid_settings_register_str(fluid_settings_t* settings, const char* name, const char* def, int hints,
|
||||
fluid_str_update_t fun, void* data)
|
||||
fluid_settings_register_str(fluid_settings_t* settings, const char* name, const char* def, int hints)
|
||||
{
|
||||
fluid_setting_node_t *node;
|
||||
int retval = FLUID_FAILED;
|
||||
|
@ -489,15 +483,13 @@ fluid_settings_register_str(fluid_settings_t* settings, const char* name, const
|
|||
fluid_rec_mutex_lock (settings->mutex);
|
||||
|
||||
if (fluid_settings_get(settings, name, &node) != FLUID_OK) {
|
||||
node = new_fluid_str_setting(def, def, hints, fun, data);
|
||||
node = new_fluid_str_setting(def, def, hints);
|
||||
retval = fluid_settings_set(settings, name, node);
|
||||
if (retval != FLUID_OK) delete_fluid_str_setting (node);
|
||||
} else {
|
||||
/* if variable already exists, don't change its value. */
|
||||
if (node->type == FLUID_STR_TYPE) {
|
||||
fluid_str_setting_t* setting = &node->str;
|
||||
setting->update = fun;
|
||||
setting->data = data;
|
||||
setting->def = def? FLUID_STRDUP(def) : NULL;
|
||||
setting->hints = hints;
|
||||
retval = FLUID_OK;
|
||||
|
@ -520,14 +512,11 @@ fluid_settings_register_str(fluid_settings_t* settings, const char* name, const
|
|||
* @param min the smallest allowed value for the setting
|
||||
* @param max the largest allowed value for the setting
|
||||
* @param hints the hints for the setting
|
||||
* @param fun an update function for the setting
|
||||
* @param data user supplied data
|
||||
* @return #FLUID_OK if the value has been register correctly, #FLUID_FAILED otherwise
|
||||
*/
|
||||
int
|
||||
fluid_settings_register_num(fluid_settings_t* settings, const char* name, double def,
|
||||
double min, double max, int hints,
|
||||
fluid_num_update_t fun, void* data)
|
||||
double min, double max, int hints)
|
||||
{
|
||||
fluid_setting_node_t *node;
|
||||
int retval = FLUID_FAILED;
|
||||
|
@ -543,15 +532,13 @@ fluid_settings_register_num(fluid_settings_t* settings, const char* name, double
|
|||
|
||||
if (fluid_settings_get(settings, name, &node) != FLUID_OK) {
|
||||
/* insert a new setting */
|
||||
node = new_fluid_num_setting(min, max, def, hints, fun, data);
|
||||
node = new_fluid_num_setting(min, max, def, hints);
|
||||
retval = fluid_settings_set(settings, name, node);
|
||||
if (retval != FLUID_OK) delete_fluid_num_setting (node);
|
||||
} else {
|
||||
if (node->type == FLUID_NUM_TYPE) {
|
||||
/* update the existing setting but don't change its value */
|
||||
fluid_num_setting_t* setting = &node->num;
|
||||
setting->update = fun;
|
||||
setting->data = data;
|
||||
setting->min = min;
|
||||
setting->max = max;
|
||||
setting->def = def;
|
||||
|
@ -577,14 +564,11 @@ fluid_settings_register_num(fluid_settings_t* settings, const char* name, double
|
|||
* @param min the smallest allowed value for the setting
|
||||
* @param max the largest allowed value for the setting
|
||||
* @param hints the hints for the setting
|
||||
* @param fun an update function for the setting
|
||||
* @param data user supplied data
|
||||
* @return #FLUID_OK if the value has been register correctly, #FLUID_FAILED otherwise
|
||||
*/
|
||||
int
|
||||
fluid_settings_register_int(fluid_settings_t* settings, const char* name, int def,
|
||||
int min, int max, int hints,
|
||||
fluid_int_update_t fun, void* data)
|
||||
int min, int max, int hints)
|
||||
{
|
||||
fluid_setting_node_t *node;
|
||||
int retval = FLUID_FAILED;
|
||||
|
@ -600,15 +584,13 @@ fluid_settings_register_int(fluid_settings_t* settings, const char* name, int de
|
|||
|
||||
if (fluid_settings_get(settings, name, &node) != FLUID_OK) {
|
||||
/* insert a new setting */
|
||||
node = new_fluid_int_setting(min, max, def, hints, fun, data);
|
||||
node = new_fluid_int_setting(min, max, def, hints);
|
||||
retval = fluid_settings_set(settings, name, node);
|
||||
if (retval != FLUID_OK) delete_fluid_int_setting (node);
|
||||
} else {
|
||||
if (node->type == FLUID_INT_TYPE) {
|
||||
/* update the existing setting but don't change its value */
|
||||
fluid_int_setting_t* setting = &node->i;
|
||||
setting->update = fun;
|
||||
setting->data = data;
|
||||
setting->min = min;
|
||||
setting->max = max;
|
||||
setting->def = def;
|
||||
|
@ -625,6 +607,114 @@ fluid_settings_register_int(fluid_settings_t* settings, const char* name, int de
|
|||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a callback for the specified string setting.
|
||||
*
|
||||
* @param settings a settings object
|
||||
* @param name the setting's name
|
||||
* @param callback an update function for the setting
|
||||
* @param data user supplied data passed to the update function
|
||||
* @return #FLUID_OK if the callback has been set, #FLUID_FAILED otherwise
|
||||
*/
|
||||
int fluid_settings_callback_str(fluid_settings_t* settings, const char* name,
|
||||
fluid_str_update_t callback, void* data)
|
||||
{
|
||||
fluid_setting_node_t *node;
|
||||
fluid_str_setting_t *setting;
|
||||
|
||||
fluid_return_val_if_fail (settings != NULL, FLUID_FAILED);
|
||||
fluid_return_val_if_fail (name != NULL, FLUID_FAILED);
|
||||
fluid_return_val_if_fail (name[0] != '\0', FLUID_FAILED);
|
||||
|
||||
fluid_rec_mutex_lock (settings->mutex);
|
||||
|
||||
if ((fluid_settings_get(settings, name, &node) != FLUID_OK)
|
||||
|| node->type != FLUID_STR_TYPE)
|
||||
{
|
||||
fluid_rec_mutex_unlock(settings->mutex);
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
setting = &node->str;
|
||||
setting->update = callback;
|
||||
setting->data = data;
|
||||
|
||||
fluid_rec_mutex_unlock(settings->mutex);
|
||||
return FLUID_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a callback for the specified numeric setting.
|
||||
*
|
||||
* @param settings a settings object
|
||||
* @param name the setting's name
|
||||
* @param callback an update function for the setting
|
||||
* @param data user supplied data passed to the update function
|
||||
* @return #FLUID_OK if the callback has been set, #FLUID_FAILED otherwise
|
||||
*/
|
||||
int fluid_settings_callback_num(fluid_settings_t* settings, const char* name,
|
||||
fluid_num_update_t callback, void* data)
|
||||
{
|
||||
fluid_setting_node_t *node;
|
||||
fluid_num_setting_t *setting;
|
||||
|
||||
fluid_return_val_if_fail (settings != NULL, FLUID_FAILED);
|
||||
fluid_return_val_if_fail (name != NULL, FLUID_FAILED);
|
||||
fluid_return_val_if_fail (name[0] != '\0', FLUID_FAILED);
|
||||
|
||||
fluid_rec_mutex_lock (settings->mutex);
|
||||
|
||||
if ((fluid_settings_get(settings, name, &node) != FLUID_OK)
|
||||
|| node->type != FLUID_NUM_TYPE)
|
||||
{
|
||||
fluid_rec_mutex_unlock(settings->mutex);
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
setting = &node->num;
|
||||
setting->update = callback;
|
||||
setting->data = data;
|
||||
|
||||
fluid_rec_mutex_unlock(settings->mutex);
|
||||
return FLUID_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a callback for the specified int setting.
|
||||
*
|
||||
* @param settings a settings object
|
||||
* @param name the setting's name
|
||||
* @param callback an update function for the setting
|
||||
* @param data user supplied data passed to the update function
|
||||
* @return #FLUID_OK if the callback has been set, #FLUID_FAILED otherwise
|
||||
*/
|
||||
int fluid_settings_callback_int(fluid_settings_t* settings, const char* name,
|
||||
fluid_int_update_t callback, void* data)
|
||||
{
|
||||
fluid_setting_node_t *node;
|
||||
fluid_int_setting_t *setting;
|
||||
|
||||
fluid_return_val_if_fail (settings != NULL, FLUID_FAILED);
|
||||
fluid_return_val_if_fail (name != NULL, FLUID_FAILED);
|
||||
fluid_return_val_if_fail (name[0] != '\0', FLUID_FAILED);
|
||||
|
||||
fluid_rec_mutex_lock (settings->mutex);
|
||||
|
||||
if ((fluid_settings_get(settings, name, &node) != FLUID_OK)
|
||||
|| node->type != FLUID_INT_TYPE)
|
||||
{
|
||||
fluid_rec_mutex_unlock(settings->mutex);
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
setting = &node->i;
|
||||
setting->update = callback;
|
||||
setting->data = data;
|
||||
|
||||
fluid_rec_mutex_unlock(settings->mutex);
|
||||
return FLUID_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of the setting with the given name
|
||||
*
|
||||
|
@ -741,55 +831,54 @@ int
|
|||
fluid_settings_setstr(fluid_settings_t* settings, const char *name, const char *str)
|
||||
{
|
||||
fluid_setting_node_t *node;
|
||||
int retval = FLUID_FAILED;
|
||||
fluid_str_setting_t *setting;
|
||||
char *new_value = NULL;
|
||||
fluid_str_update_t callback = NULL;
|
||||
void *data = NULL;
|
||||
|
||||
fluid_return_val_if_fail (settings != NULL, retval);
|
||||
fluid_return_val_if_fail (name != NULL, retval);
|
||||
fluid_return_val_if_fail (name[0] != '\0', retval);
|
||||
fluid_return_val_if_fail (settings != NULL, FLUID_FAILED);
|
||||
fluid_return_val_if_fail (name != NULL, FLUID_FAILED);
|
||||
fluid_return_val_if_fail (name[0] != '\0', FLUID_FAILED);
|
||||
|
||||
fluid_rec_mutex_lock (settings->mutex);
|
||||
|
||||
if (fluid_settings_get (settings, name, &node) == FLUID_OK) {
|
||||
if (node->type == FLUID_STR_TYPE) {
|
||||
fluid_str_setting_t *setting = &node->str;
|
||||
|
||||
if (setting->value) FLUID_FREE (setting->value);
|
||||
setting->value = str ? FLUID_STRDUP (str) : NULL;
|
||||
|
||||
/* Call under lock to keep update() synchronized with the current value */
|
||||
if (setting->update) (*setting->update)(setting->data, name, str);
|
||||
retval = FLUID_OK;
|
||||
}
|
||||
else if (node->type == FLUID_INT_TYPE) /* Handle yes/no for boolean values for backwards compatibility */
|
||||
{
|
||||
fluid_int_setting_t *setting = &node->i;
|
||||
|
||||
if (setting->hints & FLUID_HINT_TOGGLED)
|
||||
{
|
||||
if (FLUID_STRCMP (str, "yes") == 0)
|
||||
{
|
||||
setting->value = TRUE;
|
||||
if (setting->update) (*setting->update)(setting->data, name, TRUE);
|
||||
retval = FLUID_OK;
|
||||
}
|
||||
else if (FLUID_STRCMP (str, "no") == 0)
|
||||
{
|
||||
setting->value = FALSE;
|
||||
if (setting->update) (*setting->update)(setting->data, name, FALSE);
|
||||
retval = FLUID_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* insert a new setting */
|
||||
node = new_fluid_str_setting(str, NULL, 0, NULL, NULL);
|
||||
retval = fluid_settings_set(settings, name, node);
|
||||
if (retval != FLUID_OK) delete_fluid_str_setting (node);
|
||||
if ((fluid_settings_get (settings, name, &node) != FLUID_OK)
|
||||
|| (node->type != FLUID_STR_TYPE)) {
|
||||
goto error_recovery;
|
||||
}
|
||||
|
||||
setting = &node->str;
|
||||
|
||||
if (setting->value) {
|
||||
FLUID_FREE (setting->value);
|
||||
}
|
||||
|
||||
if (str) {
|
||||
new_value = FLUID_STRDUP (str);
|
||||
if (new_value == NULL) {
|
||||
FLUID_LOG (FLUID_ERR, "Out of memory");
|
||||
goto error_recovery;
|
||||
}
|
||||
}
|
||||
|
||||
setting->value = new_value;
|
||||
|
||||
callback = setting->update;
|
||||
data = setting->data;
|
||||
|
||||
/* Release the mutex before calling the update callback, to avoid
|
||||
* possible deadlocks with FluidSynths API lock */
|
||||
fluid_rec_mutex_unlock (settings->mutex);
|
||||
|
||||
return retval;
|
||||
if (callback) {
|
||||
(*callback)(data, name, new_value);
|
||||
}
|
||||
|
||||
return FLUID_OK;
|
||||
|
||||
error_recovery:
|
||||
fluid_rec_mutex_unlock (settings->mutex);
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -830,7 +919,6 @@ fluid_settings_copystr(fluid_settings_t* settings, const char *name,
|
|||
if (setting->value)
|
||||
{
|
||||
FLUID_STRNCPY (str, setting->value, len);
|
||||
str[len - 1] = 0; /* Force terminate, in case of truncation */
|
||||
}
|
||||
|
||||
retval = FLUID_OK;
|
||||
|
@ -842,7 +930,6 @@ fluid_settings_copystr(fluid_settings_t* settings, const char *name,
|
|||
if (setting->hints & FLUID_HINT_TOGGLED)
|
||||
{
|
||||
FLUID_STRNCPY (str, setting->value ? "yes" : "no", len);
|
||||
str[len - 1] = 0; /* Force terminate, in case of truncation */
|
||||
|
||||
retval = FLUID_OK;
|
||||
}
|
||||
|
@ -1087,41 +1174,45 @@ int
|
|||
fluid_settings_setnum(fluid_settings_t* settings, const char *name, double val)
|
||||
{
|
||||
fluid_setting_node_t *node;
|
||||
int retval = FLUID_FAILED;
|
||||
fluid_num_setting_t *setting;
|
||||
fluid_num_update_t callback = NULL;
|
||||
void *data = NULL;
|
||||
|
||||
fluid_return_val_if_fail (settings != NULL, retval);
|
||||
fluid_return_val_if_fail (name != NULL, retval);
|
||||
fluid_return_val_if_fail (name[0] != '\0', retval);
|
||||
fluid_return_val_if_fail (settings != NULL, FLUID_FAILED);
|
||||
fluid_return_val_if_fail (name != NULL, FLUID_FAILED);
|
||||
fluid_return_val_if_fail (name[0] != '\0', FLUID_FAILED);
|
||||
|
||||
fluid_rec_mutex_lock (settings->mutex);
|
||||
|
||||
if (fluid_settings_get(settings, name, &node) == FLUID_OK) {
|
||||
if (node->type == FLUID_NUM_TYPE) {
|
||||
fluid_num_setting_t* setting = &node->num;
|
||||
|
||||
if (val < setting->min || val > setting->max)
|
||||
{
|
||||
FLUID_LOG(FLUID_DBG, "requested set value for %s out of range", name);
|
||||
return retval;
|
||||
}
|
||||
|
||||
setting->value = val;
|
||||
|
||||
/* Call under lock to keep update() synchronized with the current value */
|
||||
if (setting->update) (*setting->update)(setting->data, name, val);
|
||||
retval = FLUID_OK;
|
||||
}
|
||||
} else {
|
||||
/* insert a new setting */
|
||||
node = new_fluid_num_setting(-1e10, 1e10, 0.0f, 0, NULL, NULL);
|
||||
node->num.value = val;
|
||||
retval = fluid_settings_set(settings, name, node);
|
||||
if (retval != FLUID_OK) delete_fluid_num_setting (node);
|
||||
if ((fluid_settings_get (settings, name, &node) != FLUID_OK)
|
||||
|| (node->type != FLUID_NUM_TYPE)) {
|
||||
goto error_recovery;
|
||||
}
|
||||
|
||||
setting = &node->num;
|
||||
if (val < setting->min || val > setting->max) {
|
||||
FLUID_LOG(FLUID_DBG, "requested set value for %s out of range", name);
|
||||
goto error_recovery;
|
||||
}
|
||||
|
||||
setting->value = val;
|
||||
|
||||
callback = setting->update;
|
||||
data = setting->data;
|
||||
|
||||
/* Release the mutex before calling the update callback, to avoid
|
||||
* possible deadlocks with FluidSynths API lock */
|
||||
fluid_rec_mutex_unlock (settings->mutex);
|
||||
|
||||
return retval;
|
||||
if (callback) {
|
||||
(*callback)(data, name, val);
|
||||
}
|
||||
|
||||
return FLUID_OK;
|
||||
|
||||
error_recovery:
|
||||
fluid_rec_mutex_unlock (settings->mutex);
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1157,6 +1248,27 @@ fluid_settings_getnum(fluid_settings_t* settings, const char *name, double* val)
|
|||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* float-typed wrapper for fluid_settings_getnum
|
||||
*
|
||||
* @param settings a settings object
|
||||
* @param name a setting's name
|
||||
* @param val variable pointer to receive the setting's float value
|
||||
* @return #FLUID_OK if the value exists, #FLUID_FAILED otherwise
|
||||
*/
|
||||
int fluid_settings_getnum_float(fluid_settings_t *settings, const char *name, float *val)
|
||||
{
|
||||
double tmp;
|
||||
|
||||
if (fluid_settings_getnum(settings, name, &tmp) == FLUID_OK)
|
||||
{
|
||||
*val = tmp;
|
||||
return FLUID_OK;
|
||||
}
|
||||
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the range of values of a numeric setting
|
||||
*
|
||||
|
@ -1239,41 +1351,45 @@ int
|
|||
fluid_settings_setint(fluid_settings_t* settings, const char *name, int val)
|
||||
{
|
||||
fluid_setting_node_t *node;
|
||||
int retval = FLUID_FAILED;
|
||||
fluid_int_setting_t *setting;
|
||||
fluid_int_update_t callback = NULL;
|
||||
void *data = NULL;
|
||||
|
||||
fluid_return_val_if_fail (settings != NULL, retval);
|
||||
fluid_return_val_if_fail (name != NULL, retval);
|
||||
fluid_return_val_if_fail (name[0] != '\0', retval);
|
||||
fluid_return_val_if_fail (settings != NULL, FLUID_FAILED);
|
||||
fluid_return_val_if_fail (name != NULL, FLUID_FAILED);
|
||||
fluid_return_val_if_fail (name[0] != '\0', FLUID_FAILED);
|
||||
|
||||
fluid_rec_mutex_lock (settings->mutex);
|
||||
|
||||
if (fluid_settings_get(settings, name, &node) == FLUID_OK) {
|
||||
if (node->type == FLUID_INT_TYPE) {
|
||||
fluid_int_setting_t* setting = &node->i;
|
||||
|
||||
if (val < setting->min || val > setting->max)
|
||||
{
|
||||
FLUID_LOG(FLUID_DBG, "requested set value for %s out of range", name);
|
||||
return retval;
|
||||
}
|
||||
|
||||
setting->value = val;
|
||||
|
||||
/* Call under lock to keep update() synchronized with the current value */
|
||||
if (setting->update) (*setting->update)(setting->data, name, val);
|
||||
retval = FLUID_OK;
|
||||
}
|
||||
} else {
|
||||
/* insert a new setting */
|
||||
node = new_fluid_int_setting(INT_MIN, INT_MAX, 0, 0, NULL, NULL);
|
||||
node->i.value = val;
|
||||
retval = fluid_settings_set(settings, name, node);
|
||||
if (retval != FLUID_OK) delete_fluid_int_setting (node);
|
||||
if ((fluid_settings_get (settings, name, &node) != FLUID_OK)
|
||||
|| (node->type != FLUID_INT_TYPE)) {
|
||||
goto error_recovery;
|
||||
}
|
||||
|
||||
setting = &node->i;
|
||||
if (val < setting->min || val > setting->max) {
|
||||
FLUID_LOG(FLUID_DBG, "requested set value for %s out of range", name);
|
||||
goto error_recovery;
|
||||
}
|
||||
|
||||
setting->value = val;
|
||||
|
||||
callback = setting->update;
|
||||
data = setting->data;
|
||||
|
||||
/* Release the mutex before calling the update callback, to avoid
|
||||
* possible deadlocks with FluidSynths API lock */
|
||||
fluid_rec_mutex_unlock (settings->mutex);
|
||||
|
||||
return retval;
|
||||
if (callback) {
|
||||
(*callback)(data, name, val);
|
||||
}
|
||||
|
||||
return FLUID_OK;
|
||||
|
||||
error_recovery:
|
||||
fluid_rec_mutex_unlock (settings->mutex);
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1621,3 +1737,36 @@ fluid_settings_foreach (fluid_settings_t* settings, void* data,
|
|||
|
||||
delete_fluid_list (bag.names); /* -- Free names list */
|
||||
}
|
||||
|
||||
/**
|
||||
* Split a comma-separated list of integers and fill the passed
|
||||
* in buffer with the parsed values.
|
||||
*
|
||||
* @param str the comma-separated string to split
|
||||
* @param buf user-supplied buffer to hold the parsed numbers
|
||||
* @param buf_len length of user-supplied buffer
|
||||
* @return number of parsed values or -1 on failure
|
||||
*/
|
||||
int fluid_settings_split_csv(const char *str, int *buf, int buf_len)
|
||||
{
|
||||
char *s;
|
||||
char *tok;
|
||||
char *tokstr;
|
||||
int n = 0;
|
||||
|
||||
s = tokstr = FLUID_STRDUP(str);
|
||||
if (s == NULL)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
while ((tok = fluid_strtok(&tokstr, ",")) && n < buf_len)
|
||||
{
|
||||
buf[n++] = atoi(tok);
|
||||
}
|
||||
|
||||
FLUID_FREE(s);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
|
|
@ -26,22 +26,30 @@ int fluid_settings_add_option(fluid_settings_t* settings, const char* name, cons
|
|||
int fluid_settings_remove_option(fluid_settings_t* settings, const char* name, const char* s);
|
||||
|
||||
|
||||
typedef int (*fluid_str_update_t)(void* data, const char* name, const char* value);
|
||||
typedef void (*fluid_str_update_t)(void* data, const char* name, const char* value);
|
||||
|
||||
int fluid_settings_register_str(fluid_settings_t* settings, const char* name, const char* def, int hints,
|
||||
int fluid_settings_register_str(fluid_settings_t* settings, const char* name, const char* def, int hints);
|
||||
int fluid_settings_callback_str(fluid_settings_t* settings, const char* name,
|
||||
fluid_str_update_t fun, void* data);
|
||||
|
||||
|
||||
typedef int (*fluid_num_update_t)(void* data, const char* name, double value);
|
||||
typedef void (*fluid_num_update_t)(void* data, const char* name, double value);
|
||||
|
||||
int fluid_settings_register_num(fluid_settings_t* settings, const char* name, double def,
|
||||
double min, double max, int hints,
|
||||
double min, double max, int hints);
|
||||
int fluid_settings_callback_num(fluid_settings_t* settings, const char* name,
|
||||
fluid_num_update_t fun, void* data);
|
||||
|
||||
/* Type specific wrapper for fluid_settings_getnum */
|
||||
int fluid_settings_getnum_float(fluid_settings_t *settings, const char *name, float *val);
|
||||
|
||||
typedef int (*fluid_int_update_t)(void* data, const char* name, int value);
|
||||
|
||||
typedef void (*fluid_int_update_t)(void* data, const char* name, int value);
|
||||
int fluid_settings_register_int(fluid_settings_t* settings, const char* name, int def,
|
||||
int min, int max, int hints,
|
||||
int min, int max, int hints);
|
||||
int fluid_settings_callback_int(fluid_settings_t* settings, const char* name,
|
||||
fluid_int_update_t fun, void* data);
|
||||
|
||||
int fluid_settings_split_csv(const char *str, int *buf, int buf_len);
|
||||
|
||||
#endif /* _FLUID_SETTINGS_H */
|
||||
|
|
|
@ -129,7 +129,6 @@ typedef guint64 uint64_t;
|
|||
#if defined(WIN32) && HAVE_WINDOWS_H
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h> /* Provides also socklen_t */
|
||||
#include <windows.h>
|
||||
|
||||
/* WIN32 special defines */
|
||||
#define DSOUND_SUPPORT 1
|
||||
|
@ -215,6 +214,7 @@ typedef struct _fluid_sample_timer_t fluid_sample_timer_t;
|
|||
#define FLUID_MAX_EVENT_QUEUES 16 /**< Maximum number of unique threads queuing events */
|
||||
#define FLUID_DEFAULT_AUDIO_RT_PRIO 60 /**< Default setting for audio.realtime-prio */
|
||||
#define FLUID_DEFAULT_MIDI_RT_PRIO 50 /**< Default setting for midi.realtime-prio */
|
||||
#define FLUID_NUM_MOD 64 /**< Maximum number of modulators in a voice */
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue