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