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