1 /* FluidSynth - A Software Synthesizer 2 * 3 * Copyright (C) 2003 Peter Hanappe and others. 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public License 7 * as published by the Free Software Foundation; either version 2.1 of 8 * the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the Free 17 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 * 02110-1301, USA 19 */ 20 21 #ifndef _FLUID_CHAN_H 22 #define _FLUID_CHAN_H 23 24 #include "fluidsynth_priv.h" 25 #include "fluid_midi.h" 26 #include "fluid_tuning.h" 27 28 /* The mononophonic list is part of the legato detector for monophonic mode */ 29 /* see fluid_synth_monopoly.c about a description of the legato detector device */ 30 /* Size of the monophonic list 31 - 1 is the minimum. it allows playing legato passage of any number 32 of notes on noteon only. 33 - Size above 1 allows playing legato on noteon but also on noteOff. 34 This allows the musician to play fast trills. 35 This feature is particularly usful when the MIDI input device is a keyboard. 36 Choosing a size of 10 is sufficient (because most musicians have only 10 37 fingers when playing a monophonic instrument). 38 */ 39 #define FLUID_CHANNEL_SIZE_MONOLIST 10 40 41 /* 42 43 The monophonic list 44 +------------------------------------------------+ 45 | +----+ +----+ +----+ +----+ | 46 | |note| |note| |note| |note| | 47 +--->|vel |-->|vel |-->....-->|vel |-->|vel |----+ 48 +----+ +----+ +----+ +----+ 49 /|\ /|\ 50 | | 51 i_first i_last 52 53 The monophonic list is a circular buffer of FLUID_CHANNEL_SIZE_MONOLIST elements. 54 Each element is linked forward at initialisation time. 55 - when a note is added at noteOn (see fluid_channel_add_monolist()) each 56 element is use in the forward direction and indexed by i_last variable. 57 - when a note is removed at noteOff (see fluid_channel_remove_monolist()), 58 the element concerned is fast unlinked and relinked after the i_last element. 59 60 The most recent note added is indexed by i_last. 61 The most ancient note added is the first note indexed by i_first. i_first is 62 moving in the forward direction in a circular manner. 63 64 */ 65 struct mononote 66 { 67 unsigned char next; /* next note */ 68 unsigned char note; /* note */ 69 unsigned char vel; /* velocity */ 70 }; 71 72 /* 73 * fluid_channel_t 74 * 75 * Mutual exclusion notes (as of 1.1.2): 76 * None - everything should have been synchronized by the synth. 77 */ 78 struct _fluid_channel_t 79 { 80 fluid_synth_t *synth; /**< Parent synthesizer instance */ 81 int channum; /**< MIDI channel number */ 82 83 /* Poly Mono variables see macro access description */ 84 int mode; /**< Poly Mono mode */ 85 int mode_val; /**< number of channel in basic channel group */ 86 87 /* monophonic list - legato detector */ 88 unsigned char i_first; /**< First note index */ 89 unsigned char i_last; /**< most recent note index since the most recent add */ 90 unsigned char prev_note; /**< previous note of the most recent add/remove */ 91 unsigned char n_notes; /**< actual number of notes in the list */ 92 struct mononote monolist[FLUID_CHANNEL_SIZE_MONOLIST]; /**< monophonic list */ 93 94 unsigned char key_mono_sustained; /**< previous sustained monophonic note */ 95 unsigned char previous_cc_breath; /**< Previous Breath */ 96 enum fluid_channel_legato_mode legatomode; /**< legato mode */ 97 enum fluid_channel_portamento_mode portamentomode; /**< portamento mode */ 98 /*- End of Poly/mono variables description */ 99 100 unsigned char cc[128]; /**< MIDI controller values from [0;127] */ 101 unsigned char key_pressure[128]; /**< MIDI polyphonic key pressure from [0;127] */ 102 103 /* Drum channel flag, CHANNEL_TYPE_MELODIC, or CHANNEL_TYPE_DRUM. */ 104 enum fluid_midi_channel_type channel_type; 105 enum fluid_interp interp_method; /**< Interpolation method (enum fluid_interp) */ 106 107 unsigned char channel_pressure; /**< MIDI channel pressure from [0;127] */ 108 unsigned char pitch_wheel_sensitivity; /**< Current pitch wheel sensitivity */ 109 short pitch_bend; /**< Current pitch bend value */ 110 /* Sostenuto order id gives the order of SostenutoOn event. 111 * This value is useful to known when the sostenuto pedal is depressed 112 * (before or after a key note). We need to compare SostenutoOrderId with voice id. 113 */ 114 unsigned int sostenuto_orderid; 115 116 int tuning_bank; /**< Current tuning bank number */ 117 int tuning_prog; /**< Current tuning program number */ 118 fluid_tuning_t *tuning; /**< Micro tuning */ 119 120 fluid_preset_t *preset; /**< Selected preset */ 121 int sfont_bank_prog; /**< SoundFont ID (bit 21-31), bank (bit 7-20), program (bit 0-6) */ 122 123 /* NRPN system */ 124 enum fluid_gen_type nrpn_select; /* Generator ID of SoundFont NRPN message */ 125 char nrpn_active; /* 1 if data entry CCs are for NRPN, 0 if RPN */ 126 127 /* The values of the generators, set by NRPN messages, or by 128 * fluid_synth_set_gen(), are cached in the channel so they can be 129 * applied to future notes. They are copied to a voice's generators 130 * in fluid_voice_init(), which calls fluid_gen_init(). */ 131 fluid_real_t gen[GEN_LAST]; 132 }; 133 134 fluid_channel_t *new_fluid_channel(fluid_synth_t *synth, int num); 135 void fluid_channel_init_ctrl(fluid_channel_t *chan, int is_all_ctrl_off); 136 void delete_fluid_channel(fluid_channel_t *chan); 137 void fluid_channel_reset(fluid_channel_t *chan); 138 int fluid_channel_set_preset(fluid_channel_t *chan, fluid_preset_t *preset); 139 void fluid_channel_set_sfont_bank_prog(fluid_channel_t *chan, int sfont, 140 int bank, int prog); 141 void fluid_channel_set_bank_lsb(fluid_channel_t *chan, int banklsb); 142 void fluid_channel_set_bank_msb(fluid_channel_t *chan, int bankmsb); 143 void fluid_channel_get_sfont_bank_prog(fluid_channel_t *chan, int *sfont, 144 int *bank, int *prog); 145 146 #define fluid_channel_get_preset(chan) ((chan)->preset) 147 #define fluid_channel_set_cc(chan, num, val) \ 148 ((chan)->cc[num] = (val)) 149 #define fluid_channel_get_cc(chan, num) \ 150 ((chan)->cc[num]) 151 #define fluid_channel_get_key_pressure(chan, key) \ 152 ((chan)->key_pressure[key]) 153 #define fluid_channel_set_key_pressure(chan, key, val) \ 154 ((chan)->key_pressure[key] = (val)) 155 #define fluid_channel_get_channel_pressure(chan) \ 156 ((chan)->channel_pressure) 157 #define fluid_channel_set_channel_pressure(chan, val) \ 158 ((chan)->channel_pressure = (val)) 159 #define fluid_channel_get_pitch_bend(chan) \ 160 ((chan)->pitch_bend) 161 #define fluid_channel_set_pitch_bend(chan, val) \ 162 ((chan)->pitch_bend = (val)) 163 #define fluid_channel_get_pitch_wheel_sensitivity(chan) \ 164 ((chan)->pitch_wheel_sensitivity) 165 #define fluid_channel_set_pitch_wheel_sensitivity(chan, val) \ 166 ((chan)->pitch_wheel_sensitivity = (val)) 167 #define fluid_channel_get_num(chan) ((chan)->channum) 168 #define fluid_channel_set_interp_method(chan, new_method) \ 169 ((chan)->interp_method = (new_method)) 170 #define fluid_channel_get_interp_method(chan) \ 171 ((chan)->interp_method); 172 #define fluid_channel_set_tuning(_c, _t) { (_c)->tuning = _t; } 173 #define fluid_channel_has_tuning(_c) ((_c)->tuning != NULL) 174 #define fluid_channel_get_tuning(_c) ((_c)->tuning) 175 #define fluid_channel_get_tuning_bank(chan) \ 176 ((chan)->tuning_bank) 177 #define fluid_channel_set_tuning_bank(chan, bank) \ 178 ((chan)->tuning_bank = (bank)) 179 #define fluid_channel_get_tuning_prog(chan) \ 180 ((chan)->tuning_prog) 181 #define fluid_channel_set_tuning_prog(chan, prog) \ 182 ((chan)->tuning_prog = (prog)) 183 #define fluid_channel_portamentotime(_c) \ 184 ((_c)->cc[PORTAMENTO_TIME_MSB] * 128 + (_c)->cc[PORTAMENTO_TIME_LSB]) 185 #define fluid_channel_portamento(_c) ((_c)->cc[PORTAMENTO_SWITCH] >= 64) 186 #define fluid_channel_breath_msb(_c) ((_c)->cc[BREATH_MSB] > 0) 187 #define fluid_channel_clear_portamento(_c) ((_c)->cc[PORTAMENTO_CTRL] = INVALID_NOTE) 188 #define fluid_channel_legato(_c) ((_c)->cc[LEGATO_SWITCH] >= 64) 189 #define fluid_channel_sustained(_c) ((_c)->cc[SUSTAIN_SWITCH] >= 64) 190 #define fluid_channel_sostenuto(_c) ((_c)->cc[SOSTENUTO_SWITCH] >= 64) 191 #define fluid_channel_set_gen(_c, _n, _v) { (_c)->gen[_n] = _v; } 192 #define fluid_channel_get_gen(_c, _n) ((_c)->gen[_n]) 193 #define fluid_channel_get_min_note_length_ticks(chan) \ 194 ((chan)->synth->min_note_length_ticks) 195 196 /* Macros interface to poly/mono mode variables */ 197 #define MASK_BASICCHANINFOS (FLUID_CHANNEL_MODE_MASK|FLUID_CHANNEL_BASIC|FLUID_CHANNEL_ENABLED) 198 /* Set the basic channel infos for a MIDI basic channel */ 199 #define fluid_channel_set_basic_channel_info(chan,Infos) \ 200 (chan->mode = (chan->mode & ~MASK_BASICCHANINFOS) | (Infos & MASK_BASICCHANINFOS)) 201 /* Reset the basic channel infos for a MIDI basic channel */ 202 #define fluid_channel_reset_basic_channel_info(chan) (chan->mode &= ~MASK_BASICCHANINFOS) 203 204 /* Macros interface to breath variables */ 205 #define FLUID_CHANNEL_BREATH_MASK (FLUID_CHANNEL_BREATH_POLY|FLUID_CHANNEL_BREATH_MONO|FLUID_CHANNEL_BREATH_SYNC) 206 /* Set the breath infos for a MIDI channel */ 207 #define fluid_channel_set_breath_info(chan,BreathInfos) \ 208 (chan->mode = (chan->mode & ~FLUID_CHANNEL_BREATH_MASK) | (BreathInfos & FLUID_CHANNEL_BREATH_MASK)) 209 /* Get the breath infos for a MIDI channel */ 210 #define fluid_channel_get_breath_info(chan) (chan->mode & FLUID_CHANNEL_BREATH_MASK) 211 212 /* Returns true when channel is mono or legato is on */ 213 #define fluid_channel_is_playing_mono(chan) ((chan->mode & FLUID_CHANNEL_POLY_OFF) ||\ 214 fluid_channel_legato(chan)) 215 216 /* Macros interface to monophonic list variables */ 217 #define INVALID_NOTE (255) 218 /* Returns true when a note is a valid note */ 219 #define fluid_channel_is_valid_note(n) (n != INVALID_NOTE) 220 /* Marks prev_note as invalid. */ 221 #define fluid_channel_clear_prev_note(chan) (chan->prev_note = INVALID_NOTE) 222 223 /* Returns the most recent note from i_last entry of the monophonic list */ 224 #define fluid_channel_last_note(chan) (chan->monolist[chan->i_last].note) 225 226 /* Returns the most recent velocity from i_last entry of the monophonic list */ 227 #define fluid_channel_last_vel(chan) (chan->monolist[chan->i_last].vel) 228 229 /* 230 prev_note is used to determine fromkey_portamento as well as 231 fromkey_legato (see fluid_synth_get_fromkey_portamento_legato()). 232 233 prev_note is updated on noteOn/noteOff mono by the legato detector as this: 234 - On noteOn mono, before adding a new note into the monolist,the most 235 recent note in the list (i.e at i_last position) is kept in prev_note. 236 - Similarly, on noteOff mono , before removing a note out of the monolist, 237 the most recent note (i.e those at i_last position) is kept in prev_note. 238 */ 239 #define fluid_channel_prev_note(chan) (chan->prev_note) 240 241 /* Interface to poly/mono mode variables */ 242 enum fluid_channel_mode_flags_internal 243 { 244 FLUID_CHANNEL_BASIC = 0x04, /**< if flag set the corresponding midi channel is a basic channel */ 245 FLUID_CHANNEL_ENABLED = 0x08, /**< if flag set the corresponding midi channel is enabled, else disabled, i.e. channel ignores any MIDI messages */ 246 247 /* 248 FLUID_CHANNEL_LEGATO_PLAYING bit of channel mode keeps trace of the legato /staccato 249 state playing. 250 FLUID_CHANNEL_LEGATO_PLAYING bit is updated on noteOn/noteOff mono by the legato detector: 251 - On noteOn, before inserting a new note into the monolist. 252 - On noteOff, after removing a note out of the monolist. 253 254 - On noteOn, this state is used by fluid_synth_noteon_mono_LOCAL() 255 to play the current note legato or staccato. 256 - On noteOff, this state is used by fluid_synth_noteoff_mono_LOCAL() 257 to play the current noteOff legato with the most recent note. 258 */ 259 /* bit7, 1: means legato playing , 0: means staccato playing */ 260 FLUID_CHANNEL_LEGATO_PLAYING = 0x80 261 }; 262 263 /* End of interface to monophonic list variables */ 264 265 void fluid_channel_add_monolist(fluid_channel_t *chan, unsigned char key, unsigned char vel, unsigned char onenote); 266 int fluid_channel_search_monolist(fluid_channel_t *chan, unsigned char key, int *i_prev); 267 void fluid_channel_remove_monolist(fluid_channel_t *chan, int i, int *i_prev); 268 void fluid_channel_clear_monolist(fluid_channel_t *chan); 269 void fluid_channel_set_onenote_monolist(fluid_channel_t *chan, unsigned char key, unsigned char vel); 270 void fluid_channel_invalid_prev_note_staccato(fluid_channel_t *chan); 271 void fluid_channel_cc_legato(fluid_channel_t *chan, int value); 272 void fluid_channel_cc_breath_note_on_off(fluid_channel_t *chan, int value); 273 274 275 #endif /* _FLUID_CHAN_H */ 276