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 Library General Public License
7 * as published by the Free Software Foundation; either version 2 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 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the Free
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 * 02111-1307, USA
19 */
20
21 #include "fluid.h"
22 #include "sfont.h"
23 #include "gen.h"
24
25 namespace FluidS {
26
27 //---------------------------------------------------------
28 // Channel
29 //---------------------------------------------------------
30
Channel(Fluid * s,int num)31 Channel::Channel(Fluid* s, int num)
32 {
33 synth = s;
34 channum = num;
35 _preset = 0;
36 banknum = 0;
37 prognum = 0;
38 reset();
39 }
40
41 //---------------------------------------------------------
42 // reset
43 //---------------------------------------------------------
44
reset()45 void Channel::reset()
46 {
47 init();
48 initCtrl();
49 }
50
51 //---------------------------------------------------------
52 // init
53 //---------------------------------------------------------
54
init()55 void Channel::init()
56 {
57 sfontnum = 0;
58 setPreset(synth->find_preset(banknum, prognum));
59 interp_method = FLUID_INTERP_DEFAULT;
60 nrpn_select = 0;
61 }
62
63 //---------------------------------------------------------
64 // initCtrl
65 //---------------------------------------------------------
66
initCtrl()67 void Channel::initCtrl()
68 {
69 channel_pressure = 0;
70 pitch_bend = 0x2000; // Range is 0x4000, pitch bend wheel starts in centered position
71 pitch_wheel_sensitivity = 12; /* twelve semi-tones */
72 bank_msb = 0;
73
74 for (int i = 0; i < GEN_LAST; i++) {
75 gen[i] = 0.0f;
76 gen_abs[i] = 0;
77 }
78
79 /* Reset key pressure and CCs for all possible values */
80 for (int i = 0; i < 128; i++) {
81 // For MuseScore purposes, default to 80 for poly aftertouch
82 setKeyPressure(i, 80);
83 setCC(i, 0);
84 }
85
86 /* Volume / initial attenuation (MSB & LSB) */
87 setCC(VOLUME_MSB, 127);
88 setCC(VOLUME_LSB, 0);
89
90 /* Pan (MSB & LSB) */
91 setCC(PAN_MSB, 64);
92 setCC(PAN_LSB, 64);
93
94 /* Expression (MSB & LSB) */
95 setCC(EXPRESSION_MSB, 127);
96 setCC(EXPRESSION_LSB, 127);
97 }
98
99 //---------------------------------------------------------
100 // setcc
101 //---------------------------------------------------------
102
setcc(int num,int value)103 void Channel::setcc(int num, int value)
104 {
105 cc[num] = value;
106
107 //printf("setcc %d %d\n", num, value);
108
109 switch (num) {
110 case SUSTAIN_SWITCH:
111 if (value < 64)
112 synth->damp_voices(channum);
113 break;
114
115 case BANK_SELECT_MSB:
116 {
117 bank_msb = value & 0x7f;
118 setBanknum(bank_msb << 7);
119 }
120 break;
121
122 case BANK_SELECT_LSB:
123 /* FIXME: according to the Downloadable Sounds II specification,
124 bit 31 should be set when we receive the message on channel
125 10 (drum channel) */
126 setBanknum((value & 0x7f) + (bank_msb << 7));
127 break;
128
129 case ALL_NOTES_OFF:
130 synth->allNotesOff(channum);
131 break;
132
133 case ALL_SOUND_OFF:
134 synth->allSoundsOff(channum);
135 break;
136
137 case ALL_CTRL_OFF:
138 initCtrl();
139 synth->modulate_voices_all(channum);
140 break;
141
142 case DATA_ENTRY_MSB:
143 {
144 int data = (value << 7) + cc[DATA_ENTRY_LSB];
145
146 /* SontFont 2.01 NRPN Message (Sect. 9.6, p. 74) */
147 if ((cc[NRPN_MSB] == 120) && (cc[NRPN_LSB] < 100)) {
148 float val = fluid_gen_scale_nrpn(nrpn_select, data);
149 qDebug("%s: %d: Data = %d, value = %f", __FILE__, __LINE__, data, val);
150 synth->set_gen(channum, nrpn_select, val);
151 }
152 break;
153 }
154
155 case NRPN_MSB:
156 cc[NRPN_LSB] = 0;
157 nrpn_select = 0;
158 break;
159
160 case NRPN_LSB:
161 /* SontFont 2.01 NRPN Message (Sect. 9.6, p. 74) */
162 if (cc[NRPN_MSB] == 120) {
163 if (value == 100)
164 nrpn_select += 100;
165 else if (value == 101)
166 nrpn_select += 1000;
167 else if (value == 102)
168 nrpn_select += 10000;
169 else if (value < 100) {
170 nrpn_select += value;
171 qDebug("%s: %d: NRPN Select = %d", __FILE__, __LINE__, nrpn_select);
172 }
173 }
174 break;
175
176 case RPN_MSB:
177 break;
178
179 case RPN_LSB:
180 /* erase any previously received NRPN message */
181 cc[NRPN_MSB] = 0;
182 cc[NRPN_LSB] = 0;
183 nrpn_select = 0;
184 break;
185
186 default:
187 synth->modulate_voices(channum, true, num);
188 }
189 }
190
191 //---------------------------------------------------------
192 // getCC
193 //---------------------------------------------------------
194
getCC(int num)195 int Channel::getCC(int num)
196 {
197 return ((num >= 0) && (num < 128))? cc[num] : 0;
198 }
199
getFromKeyPortamento()200 int Channel::getFromKeyPortamento() {
201 if (synth)
202 return synth->getFromKeyPortamento();
203 return -1;
204 }
205
206 //---------------------------------------------------------
207 // pitchBend
208 //---------------------------------------------------------
209
pitchBend(int val)210 void Channel::pitchBend(int val)
211 {
212 pitch_bend = val;
213 synth->modulate_voices(channum, false, FLUID_MOD_PITCHWHEEL);
214 }
215
216 //---------------------------------------------------------
217 // setChannelPressure
218 //---------------------------------------------------------
219
setChannelPressure(int val)220 void Channel::setChannelPressure(int val)
221 {
222 channel_pressure = val;
223 synth->modulate_voices(channum, false, FLUID_MOD_CHANNELPRESSURE);
224 }
225
226 //---------------------------------------------------------
227 // setKeyPressure
228 //---------------------------------------------------------
229
setKeyPressure(int key,int val)230 void Channel::setKeyPressure(int key, int val)
231 {
232 key_pressure[key] = val;
233 synth->modulate_voices(channum, false, FLUID_MOD_KEYPRESSURE);
234 }
235
236 //---------------------------------------------------------
237 // pitchWheelSens
238 //---------------------------------------------------------
239
pitchWheelSens(int val)240 void Channel::pitchWheelSens(int val)
241 {
242 pitch_wheel_sensitivity = val;
243 synth->modulate_voices(channum, false, FLUID_MOD_PITCHWHEELSENS);
244 }
245
246 //---------------------------------------------------------
247 // setPreset
248 //---------------------------------------------------------
249
setPreset(Preset * p)250 void Channel::setPreset(Preset* p)
251 {
252 if (_preset != p) {
253 if (p)
254 p->loadSamples();
255 _preset = p;
256 }
257 }
258
259 }
260
261