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