diff options
Diffstat (limited to 'libs/fluidsynth/src/fluid_synth_monopoly.c')
-rw-r--r-- | libs/fluidsynth/src/fluid_synth_monopoly.c | 727 |
1 files changed, 727 insertions, 0 deletions
diff --git a/libs/fluidsynth/src/fluid_synth_monopoly.c b/libs/fluidsynth/src/fluid_synth_monopoly.c new file mode 100644 index 0000000000..b7828af5b7 --- /dev/null +++ b/libs/fluidsynth/src/fluid_synth_monopoly.c @@ -0,0 +1,727 @@ +/* FluidSynth - A Software Synthesizer + * + * Copyright (C) 2003 Peter Hanappe and others. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License + * as published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + */ + +#include "fluid_synth.h" +#include "fluid_chan.h" +#include "fluid_defsfont.h" + + +/****************************************************************************** + The legato detector is composed as this, + variables: + - monolist: monophonic list variable. + - prev_note: to store the most recent note before adding on noteon or before + removing on noteoff. + - FLUID_CHANNEL_LEGATO_PLAYING: legato/staccato state bit that informs on + legato or staccato playing. + functions: + - fluid_channel_add_monolist(), for inserting a new note. + - fluid_channel_search_monolist(), for searching the position of a note + into the list. + - fluid_channel_remove_monolist(), for removing a note from the list. + + The monophonic list + +------------------------------------------------+ + | +----+ +----+ +----+ +----+ | + | |note| |note| |note| |note| | + +--->|vel |-->|vel |-->....-->|vel |-->|vel |----+ + +----+ +----+ +----+ +----+ + /|\ /|\ + | | + i_first i_last + + The list allows an easy automatic detection of a legato passage when it is + played on a MIDI keyboard input device. + It is useful also when the input device is an ewi (electronic wind instrument) + or evi (electronic valve instrument) and these instruments are unable to send + MIDI CC legato on/off. + + The list memorizes the notes in playing order. + - (a) On noteOn n2, if a previous note n1 exists, there is a legato + detection with n1 (with or without portamento from n1 to n2 See note below). + - (b) On noteOff of the running note n2, if a previous note n1 exists, + there is a legato detection from n2 to n1, allowing fast trills playing + (with or without portamento from n2 to n1. See note below). + + Notes in the list are inserted to the end of the list that works like a + circular buffer.The features are: + + 1) It is always possible to play an infinite legato passage in + direct order (n1_On,n2_On,n3_On,....). + + 2) Playing legato in the reverse order (n10_Off, n9_Off,,...) helps in + fast trills playing as the list memorizes 10 most recent notes. + + 3) Playing an infinite lagato passage in ascendant or descendant order, + without playing trills is always possible using the usual way like this: + First we begin with an ascendant passage, + n1On, (n2On,n1Off), (n3On,n2Off) , (n4On,n3Off), then + we continue with a descendant passage + (n3On,n4off), (n2On,n3off), (n1On,n2off), n1Off...and so on + + Each MIDI channel have a legato detector. + + Note: + Portamento is a feature independant of the legato detector. So + portamento isn't part of the lagato detector. However portamento + (when enabled) is triggered at noteOn (like legato). Like in legato + situation it is usual to have a portamento from a note 'fromkey' to another + note 'tokey'. Portamento fromkey note choice is determined at noteOn by + fluid_synth_get_fromkey_portamento_legato() (see below). + + More informations in FluidPolyMono-0004.pdf chapter 4 (Appendices). +******************************************************************************/ + + +/***************************************************************************** + Portamento related functions in Poly or Mono mode +******************************************************************************/ + +/** + * fluid_synth_get_fromkey_portamento_legato returns two informations: + * - fromkey note for portamento. + * - fromkey note for legato. + * +-----> fromkey_portamento + * ______|________ + * portamento modes >------->| | + * | get_fromkey | + * Porta.on/off >------------------------->|_______________| + * (PTC) | + * +-----> fromkey_legato + * + * The functions is intended to be call on noteOn mono + * see fluid_synth_noteon_mono_staccato(), fluid_synth_noteon_monopoly_legato() + * ------- + * 1)The function determines if a portamento must occur on next noteOn. + * The value returned is 'fromkey portamento' which is the pitchstart key + * of a portamento, as function of PTC or (default_fromkey, prev_note) both + * if Portamento On. By order of precedence the result is: + * 1.1) PTC have precedence over Portamento On. + * If CC PTC has been received, its value supersedes and any + * portamento pedal On, default_fromkey,prev_note or portamento mode. + * 1.2) Otherwise ,when Portamento On the function takes the following value: + * - default_fromkey if valid + * - otherwise prev_note(prev_note is the note prior the most recent + * note played). + * Then portamento mode is applied to validate the value choosen. + * Where portamento mode is: + * - each note, a portamento occurs on each note. + * - legato only, portamento only on notes played legato. + * - staccato only, portamento only on notes played staccato. + * 1.3) Otherwise, portamento is off,INVALID_NOTE is returned (portamento is disabled). + * ------ + * 2)The function determines if a legato playing must occur on next noteOn. + * 'fromkey legato note' is returned as a function of default_fromkey, PTC, + * current mono/poly mode,actual 'staccato/legato' playing state and prev_note. + * By order of precedence the result is: + * 2.1) If valid, default_fromkey have precedence over any others values. + * 2.2) Otherwise if CC PTC has been received its value is returned. + * 2.3) Otherwise fromkey legato is determined from the mono/poly mode, + * the actual 'staccato/legato' playing state (FLUID_CHANNEL_LEGATO_PLAYING) and prev_note + * as this: + * - in (poly/Mono) staccato , INVALID_NOTE is returned. + * - in poly legato , actually we don't want playing legato. So + * INVALID_NOTE is returned. + * - in mono legato , prev_note is returned. + * + * On input + * @param chan fluid_channel_t. + * @param defaultFromkey, the defaut 'fromkey portamento' note or 'fromkey legato' + * note (see description above). + * + * @return + * 1)'fromkey portamento' is returned in fluid_synth_t.fromkey_portamento. + * If valid,it means that portamento is enabled . + * + * 2)The 'fromkey legato' note is returned. + * + * Notes about usage: + * The function is intended to be called when the following event occurs: + * - On noteOn (Poly or Mono) after insertion in the monophonic list. + * - On noteOff(mono legato playing). In this case, default_fromkey must be valid. + * + * Typical calling usage: + * - In poly, default_fromkey must be INVALID_NOTE. + * - In mono staccato playing,default_fromkey must be INVALID_NOTE. + * - In mono legato playing,default_fromkey must be valid. + */ +static char fluid_synth_get_fromkey_portamento_legato(fluid_channel_t *chan, + int default_fromkey) +{ + unsigned char ptc = fluid_channel_get_cc(chan, PORTAMENTO_CTRL); + + if(fluid_channel_is_valid_note(ptc)) + { + /* CC PTC has been received */ + fluid_channel_clear_portamento(chan); /* clears the CC PTC receive */ + chan->synth->fromkey_portamento = ptc;/* returns fromkey portamento */ + + /* returns fromkey legato */ + if(!fluid_channel_is_valid_note(default_fromkey)) + { + default_fromkey = ptc; + } + } + else + { + /* determines and returns fromkey portamento */ + unsigned char fromkey_portamento = INVALID_NOTE; + + if(fluid_channel_portamento(chan)) + { + /* Portamento when Portamento pedal is On */ + /* 'fromkey portamento'is determined from the portamento mode + and the most recent note played (prev_note)*/ + enum fluid_channel_portamento_mode portamentomode = chan->portamentomode; + + if(fluid_channel_is_valid_note(default_fromkey)) + { + fromkey_portamento = default_fromkey; /* on each note */ + } + else + { + fromkey_portamento = fluid_channel_prev_note(chan); /* on each note */ + } + + if(portamentomode == FLUID_CHANNEL_PORTAMENTO_MODE_LEGATO_ONLY) + { + /* Mode portamento:legato only */ + if(!(chan->mode & FLUID_CHANNEL_LEGATO_PLAYING)) + { + fromkey_portamento = INVALID_NOTE; + } + } + else if(portamentomode == FLUID_CHANNEL_PORTAMENTO_MODE_STACCATO_ONLY) + { + /* Mode portamento:staccato only */ + if(chan->mode & FLUID_CHANNEL_LEGATO_PLAYING) + { + fromkey_portamento = INVALID_NOTE; + } + } + + /* else Mode portamento: on each note (staccato/legato) */ + } + + /* Returns fromkey portamento */ + chan->synth->fromkey_portamento = fromkey_portamento; + + /* Determines and returns fromkey legato */ + if(!fluid_channel_is_valid_note(default_fromkey)) + { + /* in staccato (poly/Mono) returns INVALID_NOTE */ + /* In mono mode legato playing returns the note prior most + recent note played */ + if(fluid_channel_is_playing_mono(chan) && (chan->mode & FLUID_CHANNEL_LEGATO_PLAYING)) + { + default_fromkey = fluid_channel_prev_note(chan); /* note prior last note */ + } + + /* In poly mode legato playing, actually we don't want playing legato. + So returns INVALID_NOTE */ + } + } + + return default_fromkey; /* Returns legato fromkey */ +} + +/***************************************************************************** + noteon - noteoff functions in Mono mode +******************************************************************************/ +/* + * noteon - noteoff on a channel in "monophonic playing". + * + * A channel needs to be played monophonic if this channel has been set in + * monophonic mode by basic channel API.(see fluid_synth_polymono.c). + * A channel needs also to be played monophonic if it has been set in + * polyphonic mode and legato pedal is On during the playing. + * When a channel is in "monophonic playing" state, only one note at a time can be + * played in a staccato or legato manner (with or without portamento). + * More informations in FluidPolyMono-0004.pdf chapter 4 (Appendices). + * _______________ + * ________________ | noteon | + * | legato detector| O-->| mono_staccato |--*-> preset_noteon + * noteon_mono ->| (add_monolist) |--O-- |_______________| | (with or without) + * LOCAL |________________| O /|\ | (portamento) + * /|\ set_onenote | | fromkey | + * | | | portamento| + * noteOn poly >---*------------------* | | + * | | | + * | _____ |________ | + * portamento modes >--- | ->| | | + * | | get_fromkey | | + * Porta.on/off >--------------------- | ->|_______________| | + * (PTC) | | | + * | fromkey | fromkey | + * | legato | portamento| + * | _____\|/_______ | + * *-->| noteon |--/ + * | | monopoly | + * | | legato |----> voices + * legato modes >------- | ->|_______________| triggering + * | (with or without) + * | (portamento) + * | + * | + * noteOff poly >---*----------------- | ---------+ + * | clear | | + * _\|/_____________ | | + * | legato detector | O | + * noteoff_mono->|(search_monolist)|-O-- _____\|/_______ + * LOCAL |(remove_monolist)| O-->| noteoff | + * |_________________| | monopoly |----> noteoff + * Sust.on/off >------------------------->|_______________| + * Sost.on/off +------------------------------------------------------------------------------*/ +int fluid_synth_noteoff_monopoly(fluid_synth_t *synth, int chan, int key, + char Mono); + +int fluid_synth_noteon_monopoly_legato(fluid_synth_t *synth, int chan, + int fromkey, int tokey, int vel); + +/** + * Plays a noteon event for a Synth instance in "monophonic playing" state. + * Please see the description above about "monophonic playing". + * _______________ + * ________________ | noteon | + * | legato detector| O-->| mono_staccato |--->preset_noteon + * noteon_mono ->| (add_monolist) |--O-- |_______________| + * LOCAL |________________| O + * | + * | + * | + * | + * | + * | + * | + * | + * | + * | _______________ + * | | noteon | + * +-->| monopoly | + * | legato |---> voices + * |_______________| triggering + * + * The function uses the legato detector (see above) to determine if the note must + * be played staccato or legato. + * + * @param synth instance. + * @param chan MIDI channel number (0 to MIDI channel count - 1). + * @param key MIDI note number (0-127). + * @param vel MIDI velocity (0-127). + * @return FLUID_OK on success, FLUID_FAILED otherwise. + */ +int fluid_synth_noteon_mono_LOCAL(fluid_synth_t *synth, int chan, + int key, int vel) +{ + fluid_channel_t *channel = synth->channel[chan]; + + /* Adds the note into the monophonic list */ + fluid_channel_add_monolist(channel, key, vel, 0); + + /* in Breath Sync mode, the noteon triggering is postponed + until the musician starts blowing in the breath controller */ + if(!(channel->mode & FLUID_CHANNEL_BREATH_SYNC) || + fluid_channel_breath_msb(channel)) + { + /* legato/staccato playing detection */ + if(channel->mode & FLUID_CHANNEL_LEGATO_PLAYING) + { + /* legato playing */ + /* legato from prev_note to key */ + /* the voices from prev_note key number are to be used to play key number */ + /* fromkey must be valid */ + return fluid_synth_noteon_monopoly_legato(synth, chan, + fluid_channel_prev_note(channel), key, vel); + } + else + { + /* staccato playing */ + return fluid_synth_noteon_mono_staccato(synth, chan, key, vel); + } + } + else + { + return FLUID_OK; + } +} + +/** + * Plays a noteoff event for a Synth instance in "monophonic playing" state. + * Please see the description above about "monophonic playing" + * + * _______________ + * | noteon | + * +-->| monopoly | + * | | legato |----> voices + * | |_______________| triggering + * | (with or without) + * | (portamento) + * | + * | + * | + * | + * | + * | + * _________________ | + * | legato detector | O + * noteoff_mono->|(search_monolist)|-O-- _______________ + * LOCAL |(remove_monolist)| O-->| noteoff | + * |_________________| | monopoly |----> noteoff + * |_______________| + * + * The function uses the legato detector (see above) to determine if the noteoff must + * be played staccato or legato. + * + * @param synth instance. + * @param chan MIDI channel number (0 to MIDI channel count - 1). + * @param key MIDI note number (0-127). + * @return FLUID_OK on success, FLUID_FAILED otherwise. + */ +int fluid_synth_noteoff_mono_LOCAL(fluid_synth_t *synth, int chan, int key) +{ + int status; + int i, i_prev; + fluid_channel_t *channel = synth->channel[chan]; + /* searching the note in the monophonic list */ + i = fluid_channel_search_monolist(channel, key, &i_prev); + + if(i >= 0) + { + /* the note is in the monophonic list */ + /* Removes the note from the monophonic list */ + fluid_channel_remove_monolist(channel, i, &i_prev); + + /* in Breath Sync mode, the noteoff triggering is done + if the musician is blowing in the breath controller */ + if(!(channel->mode & FLUID_CHANNEL_BREATH_SYNC) || + fluid_channel_breath_msb(channel)) + { + /* legato playing detection */ + if(channel->mode & FLUID_CHANNEL_LEGATO_PLAYING) + { + /* the list contains others notes */ + if(i_prev >= 0) + { + /* legato playing detection on noteoff */ + /* legato from key to i_prev key */ + /* the voices from key number are to be used to + play i_prev key number. */ + status = fluid_synth_noteon_monopoly_legato(synth, chan, + key, channel->monolist[i_prev].note, + channel->monolist[i_prev].vel); + } + /* else the note doesn't need to be played off */ + else + { + status = FLUID_OK; + } + } + else + { + /* the monophonic list is empty */ + /* plays the monophonic note noteoff and eventually held + by sustain/sostenuto */ + status = fluid_synth_noteoff_monopoly(synth, chan, key, 1); + } + } + else + { + status = FLUID_OK; + } + } + else + { + /* the note is not found in the list so the note was + played On when the channel was in polyphonic playing */ + /* plays the noteoff as for polyphonic */ + status = fluid_synth_noteoff_monopoly(synth, chan, key, 0); + } + + return status; +} + +/*---------------------------------------------------------------------------- + staccato playing +-----------------------------------------------------------------------------*/ +/** + * Plays noteon for a monophonic note in staccato manner. + * Please see the description above about "monophonic playing". + * _______________ + * | noteon | + * noteon_mono >------------------------>| mono_staccato |----> preset_noteon + * |_______________| (with or without) + * LOCAL /|\ (portamento) + * | fromkey + * | portamento + * | + * | + * ______|________ + * portamento modes >----->| | + * | get_fromkey | + * Porta.on/off >----------------------->|_______________| + * Portamento + * (PTC) + * + * We are in staccato situation (where no previous note have been depressed). + * Before the note been passed to fluid_preset_noteon(), the function must determine + * the from_key_portamento parameter used by fluid_preset_noteon(). + * + * from_key_portamento is returned by fluid_synth_get_fromkey_portamento_legato() function. + * fromkey_portamento is set to valid/invalid key value depending of the portamento + * modes (see portamento mode API) , CC portamento On/Off , and CC portamento control + * (PTC). + * + * @param synth instance. + * @param chan MIDI channel number (0 to MIDI channel count - 1). + * @param key MIDI note number (0-127). + * @param vel MIDI velocity (0-127). + * @return FLUID_OK on success, FLUID_FAILED otherwise. + */ +int +fluid_synth_noteon_mono_staccato(fluid_synth_t *synth, int chan, int key, int vel) +{ + fluid_channel_t *channel = synth->channel[chan]; + + /* Before playing a new note, if a previous monophonic note is currently + sustained it needs to be released */ + fluid_synth_release_voice_on_same_note_LOCAL(synth, chan, channel->key_mono_sustained); + /* Get possible 'fromkey portamento' */ + fluid_synth_get_fromkey_portamento_legato(channel, INVALID_NOTE); + /* The note needs to be played by voices allocation */ + return fluid_preset_noteon(channel->preset, synth, chan, key, vel); +} + +/** + * Plays noteoff for a polyphonic or monophonic note + * Please see the description above about "monophonic playing". + * + * + * noteOff poly >---------------------------------+ + * | + * | + * | + * noteoff_mono _____\|/_______ + * LOCAL >------------------------->| noteoff | + * | monopoly |----> noteoff + * Sust.on/off >------------------------->|_______________| + * Sost.on/off + * + * The function has the same behaviour when the noteoff is poly of mono, except + * that for mono noteoff, if any pedal (sustain or sostenuto ) is depressed, the + * key is memorized. This is neccessary when the next mono note will be played + * staccato, as any current mono note currently sustained will need to be released + * (see fluid_synth_noteon_mono_staccato()). + * Note also that for a monophonic legato passage, the function is called only when + * the last noteoff of the passage occurs. That means that if sustain or sostenuto + * is depressed, only the last note of a legato passage will be sustained. + * + * @param synth instance. + * @param chan MIDI channel number (0 to MIDI channel count - 1). + * @param key MIDI note number (0-127). + * @param Mono, 1 noteoff on monophonic note. + * 0 noteoff on polyphonic note. + * @return FLUID_OK on success, FLUID_FAILED otherwise. + * + * Note: On return, on monophonic, possible sustained note is memorized in + * key_mono_sustained. Memorization is done here on noteOff. + */ +int fluid_synth_noteoff_monopoly(fluid_synth_t *synth, int chan, int key, + char Mono) +{ + int status = FLUID_FAILED; + fluid_voice_t *voice; + int i; + fluid_channel_t *channel = synth->channel[chan]; + + /* Key_sustained is prepared to return no note sustained (INVALID_NOTE) */ + if(Mono) + { + channel->key_mono_sustained = INVALID_NOTE; /* no mono note sustained */ + } + + /* noteoff for all voices with same chan and same key */ + for(i = 0; i < synth->polyphony; i++) + { + voice = synth->voice[i]; + + if(fluid_voice_is_on(voice) && + fluid_voice_get_channel(voice) == chan && + fluid_voice_get_key(voice) == key) + { + if(synth->verbose) + { + int used_voices = 0; + int k; + + for(k = 0; k < synth->polyphony; k++) + { + if(!_AVAILABLE(synth->voice[k])) + { + used_voices++; + } + } + + FLUID_LOG(FLUID_INFO, "noteoff\t%d\t%d\t%d\t%05d\t%.3f\t%d", + fluid_voice_get_channel(voice), fluid_voice_get_key(voice), 0, + fluid_voice_get_id(voice), + (fluid_curtime() - synth->start) / 1000.0f, + used_voices); + } /* if verbose */ + + fluid_voice_noteoff(voice); + + /* noteoff on monophonic note */ + /* Key memorization if the note is sustained */ + if(Mono && + (fluid_voice_is_sustained(voice) || fluid_voice_is_sostenuto(voice))) + { + channel->key_mono_sustained = key; + } + + status = FLUID_OK; + } /* if voice on */ + } /* for all voices */ + + return status; +} + +/*---------------------------------------------------------------------------- + legato playing +-----------------------------------------------------------------------------*/ +/** + * Plays noteon for a monophonic note played legato. + * Please see the description above about "monophonic playing". + * + * + * _______________ + * portamento modes >----->| | + * | get_fromkey | + * Porta.on/off >----------------------->|_______________| + * Portamento | + * (PTC) | +-->preset_noteon + * fromkey | fromkey | (with or without) + * legato | portamento| (portamento) + * _____\|/_______ | + * | noteon |--+ + * noteon_mono >------------------------>| monopoly | + * LOCAL | legato |----->voices + * |_______________| triggering + * /|\ (with or without) + * | (portamento) + * legato modes >-----------------+ + * + * We are in legato situation (where a previous note has been depressed). + * The function must determine the from_key_portamento and from_key_legato parameters + * used respectively by fluid_preset_noteon() function and voices triggering functions. + * + * from_key_portamento and from_key_legato are returned by + * fluid_synth_get_fromkey_portamento_legato() function. + * fromkey_portamento is set to valid/invalid key value depending of the portamento + * modes (see portamento mode API), CC portamento On/Off, and CC portamento control + * (PTC). + * Then, depending of the legato modes (see legato mode API), the function will call + * the appropriate triggering functions. + * @param synth instance. + * @param chan MIDI channel number (0 to MIDI channel count - 1). + * @param fromkey MIDI note number (0-127). + * @param tokey MIDI note number (0-127). + * @param vel MIDI velocity (0-127). + * @return FLUID_OK on success, FLUID_FAILED otherwise. + * + * Note: The voices with key 'fromkey' are to be used to play key 'tokey'. + * The function is able to play legato through Preset Zone(s) (PZ) and + * Instrument Zone(s) (IZ) as far as possible. + * When key tokey is outside the current Instrument Zone, Preset Zone, + * current 'fromkey' voices are released. If necessary new voices + * are restarted when tokey enters inside new Instrument(s) Zones,Preset Zone(s). + * More informations in FluidPolyMono-0004.pdf chapter 4.7 (Appendices). + */ +int fluid_synth_noteon_monopoly_legato(fluid_synth_t *synth, int chan, + int fromkey, int tokey, int vel) +{ + fluid_channel_t *channel = synth->channel[chan]; + enum fluid_channel_legato_mode legatomode = channel->legatomode; + fluid_voice_t *voice; + int i ; + /* Gets possible 'fromkey portamento' and possible 'fromkey legato' note */ + fromkey = fluid_synth_get_fromkey_portamento_legato(channel, fromkey); + + if(fluid_channel_is_valid_note(fromkey)) + { + for(i = 0; i < synth->polyphony; i++) + { + /* searching fromkey voices: only those who don't have 'note off' */ + voice = synth->voice[i]; + + if(fluid_voice_is_on(voice) && + fluid_voice_get_channel(voice) == chan && + fluid_voice_get_key(voice) == fromkey) + { + fluid_zone_range_t *zone_range = voice->zone_range; + + /* Ignores voice when there is no instrument zone (i.e no zone_range). Otherwise + checks if tokey is inside the range of the running voice */ + if(zone_range && fluid_zone_inside_range(zone_range, tokey, vel)) + { + switch(legatomode) + { + case FLUID_CHANNEL_LEGATO_MODE_RETRIGGER: /* mode 0 */ + fluid_voice_release(voice); /* normal release */ + break; + + case FLUID_CHANNEL_LEGATO_MODE_MULTI_RETRIGGER: /* mode 1 */ + /* Skip in attack section */ + fluid_voice_update_multi_retrigger_attack(voice, tokey, vel); + + /* Starts portamento if enabled */ + if(fluid_channel_is_valid_note(synth->fromkey_portamento)) + { + /* Sends portamento parameters to the voice dsp */ + fluid_voice_update_portamento(voice, + synth->fromkey_portamento, + tokey); + } + + /* The voice is now used to play tokey in legato manner */ + /* Marks this Instrument Zone to be ignored during next + fluid_preset_noteon() */ + zone_range->ignore = TRUE; + break; + + default: /* Invalid mode: this should never happen */ + FLUID_LOG(FLUID_WARN, "Failed to execute legato mode: %d", + legatomode); + return FLUID_FAILED; + } + } + else + { + /* tokey note is outside the voice range, so the voice is released */ + fluid_voice_release(voice); + } + } + } + } + + /* May be,tokey will enter in new others Insrument Zone(s),Preset Zone(s), in + this case it needs to be played by voices allocation */ + return fluid_preset_noteon(channel->preset, synth, chan, tokey, vel); +} |