Fix unused parameter warnings since GCC apparently doesn't feel like listening to...
[ardour.git] / libs / midi++2 / channel.cc
1 /*
2     Copyright (C) 1998-99 Paul Barton-Davis 
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18     $Id$
19 */
20
21 #include <cstring>
22 #include "midi++/types.h"
23 #include "midi++/port.h"
24 #include "midi++/channel.h"
25
26 using namespace sigc;
27 using namespace MIDI;
28
29 Channel::Channel (byte channelnum, Port &p) : _port (p)
30 {
31         _channel_number = channelnum;
32
33         reset (0, 1, false);
34 }       
35
36 void
37 Channel::connect_input_signals ()
38
39 {
40         _port.input()->channel_pressure[_channel_number].connect
41                 (mem_fun (*this, &Channel::process_chanpress));
42         _port.input()->channel_note_on[_channel_number].connect
43                 (mem_fun (*this, &Channel::process_note_on));
44         _port.input()->channel_note_off[_channel_number].connect
45                 (mem_fun (*this, &Channel::process_note_off));
46         _port.input()->channel_poly_pressure[_channel_number].connect
47                 (mem_fun (*this, &Channel::process_polypress));
48         _port.input()->channel_program_change[_channel_number].connect
49                 (mem_fun (*this, &Channel::process_program_change));
50         _port.input()->channel_controller[_channel_number].connect
51                 (mem_fun (*this, &Channel::process_controller));
52         _port.input()->channel_pitchbend[_channel_number].connect
53                 (mem_fun (*this, &Channel::process_pitchbend));
54         _port.input()->reset.connect (mem_fun (*this, &Channel::process_reset));
55 }
56
57 void
58 Channel::connect_output_signals ()
59
60 {
61         _port.output()->channel_pressure[_channel_number].connect
62                 (mem_fun (*this, &Channel::process_chanpress));
63         _port.output()->channel_note_on[_channel_number].connect
64                 (mem_fun (*this, &Channel::process_note_on));
65         _port.output()->channel_note_off[_channel_number].connect
66                 (mem_fun (*this, &Channel::process_note_off));
67         _port.output()->channel_poly_pressure[_channel_number].connect
68                 (mem_fun (*this, &Channel::process_polypress));
69         _port.output()->channel_program_change[_channel_number].connect
70                 (mem_fun (*this, &Channel::process_program_change));
71         _port.output()->channel_controller[_channel_number].connect
72                 (mem_fun (*this, &Channel::process_controller));
73         _port.output()->channel_pitchbend[_channel_number].connect
74                 (mem_fun (*this, &Channel::process_pitchbend));
75         _port.output()->reset.connect (mem_fun (*this, &Channel::process_reset));
76 }
77
78 void
79 Channel::reset (timestamp_t timestamp, nframes_t /*nframes*/, bool notes_off)
80 {
81         _program_number = _channel_number;
82         _bank_number = 0;
83         _pitch_bend = 0;
84
85         _last_note_on = 0;
86         _last_note_off = 0;
87         _last_on_velocity = 0;
88         _last_off_velocity = 0;
89
90         if (notes_off) {
91                 all_notes_off (timestamp);
92         }
93
94         memset (_polypress, 0, sizeof (_polypress));
95         memset (_controller_msb, 0, sizeof (_controller_msb));
96         memset (_controller_lsb, 0, sizeof (_controller_lsb));
97        
98         /* zero all controllers XXX not necessarily the right thing */
99
100         memset (_controller_val, 0, sizeof (_controller_val));
101
102         for (int n = 0; n < 128; n++) {
103                 _controller_14bit[n] = false;
104         }
105
106         _rpn_msb = 0;
107         _rpn_lsb = 0;
108         _nrpn_msb = 0;
109         _nrpn_lsb = 0;
110
111         _omni = true;
112         _poly = false;
113         _mono = true;
114         _notes_on = 0;
115 }
116
117 void
118 Channel::process_note_off (Parser & /*parser*/, EventTwoBytes *tb) 
119 {
120         _last_note_off = tb->note_number;
121         _last_off_velocity = tb->velocity;
122
123         if (_notes_on) {
124                 _notes_on--;
125         }
126 }
127
128 void
129 Channel::process_note_on (Parser & /*parser*/, EventTwoBytes *tb) 
130 {
131         _last_note_on = tb->note_number;
132         _last_on_velocity = tb->velocity;
133         _notes_on++;
134 }
135
136 void
137 Channel::process_controller (Parser & /*parser*/, EventTwoBytes *tb) 
138 {
139         unsigned short cv;
140
141         /* XXX arguably need a lock here to protect non-atomic changes
142            to controller_val[...]. or rather, need to make sure that
143            all changes *are* atomic.
144         */
145
146         if (tb->controller_number <= 31) { /* unsigned: no test for >= 0 */
147
148                 /* if this controller is already known to use 14 bits,
149                    then treat this value as the MSB, and combine it 
150                    with the existing LSB.
151
152                    otherwise, just treat it as a 7 bit value, and set
153                    it directly.
154                 */
155
156                 cv = (unsigned short) _controller_val[tb->controller_number];
157
158                 if (_controller_14bit[tb->controller_number]) {
159                         cv = ((tb->value << 7) | (cv & 0x7f));
160                 } else {
161                         cv = tb->value;
162                 }
163
164                 _controller_val[tb->controller_number] = (controller_value_t)cv;
165
166         } else if ((tb->controller_number >= 32 && 
167                     tb->controller_number <= 63)) {
168                    
169                 cv = (unsigned short) _controller_val[tb->controller_number];
170
171                 /* LSB for CC 0-31 arrived. 
172
173                    If this is the first time (i.e. its currently
174                    flagged as a 7 bit controller), mark the
175                    controller as 14 bit, adjust the existing value
176                    to be the MSB, and OR-in the new LSB value. 
177
178                    otherwise, OR-in the new low 7bits with the old
179                    high 7.
180                 */
181
182                 int cn = tb->controller_number - 32;
183                    
184                 if (_controller_14bit[cn] == false) {
185                         _controller_14bit[cn] = true;
186                         cv = (cv << 7) | (tb->value & 0x7f);
187                 } else {
188                         cv = (cv & 0x3f80) | (tb->value & 0x7f);
189                 }
190
191                 _controller_val[tb->controller_number] = 
192                         (controller_value_t) cv;
193         } else {
194
195                 /* controller can only take 7 bit values */
196                 
197                 _controller_val[tb->controller_number] = 
198                         (controller_value_t) tb->value;
199         }
200
201         /* bank numbers are special, in that they have their own signal
202          */
203
204         if (tb->controller_number == 0) {
205                 _bank_number = (unsigned short) _controller_val[0];
206                 if (_port.input()) {
207                         _port.input()->bank_change (*_port.input(), _bank_number);
208                         _port.input()->channel_bank_change[_channel_number] 
209                                 (*_port.input(), _bank_number);
210                 }
211         }
212
213 }
214
215 void
216 Channel::process_program_change (Parser & /*parser*/, byte val) 
217 {
218         _program_number = val;
219 }
220
221 void
222 Channel::process_chanpress (Parser & /*parser*/, byte val) 
223 {
224         _chanpress = val;
225 }
226
227 void
228 Channel::process_polypress (Parser & /*parser*/, EventTwoBytes *tb) 
229 {
230         _polypress[tb->note_number] = tb->value;
231 }
232
233 void
234 Channel::process_pitchbend (Parser & /*parser*/, pitchbend_t val) 
235 {
236         _pitch_bend = val;
237 }
238
239 void
240 Channel::process_reset (Parser & /*parser*/) 
241 {
242         reset (0, 1);
243 }
244
245 /** Write a message to a channel.
246  * \return true if success
247  */
248 bool
249 Channel::channel_msg (byte id, byte val1, byte val2, timestamp_t timestamp)
250 {
251         unsigned char msg[3];
252         int len = 0;
253
254         msg[0] = id | (_channel_number & 0xf);
255
256         switch (id) {
257         case off:
258                 msg[1] = val1 & 0x7F;
259                 msg[2] = val2 & 0x7F;
260                 len = 3;
261                 break;
262
263         case on:
264                 msg[1] = val1 & 0x7F;
265                 msg[2] = val2 & 0x7F;
266                 len = 3;
267                 break;
268
269         case MIDI::polypress:
270                 msg[1] = val1 & 0x7F;
271                 msg[2] = val2 & 0x7F;
272                 len = 3;
273                 break;
274
275         case controller:
276                 msg[1] = val1 & 0x7F;
277                 msg[2] = val2 & 0x7F;
278                 len = 3;
279                 break;
280
281         case MIDI::program:
282                 msg[1] = val1 & 0x7F;
283                 len = 2;
284                 break;
285
286         case MIDI::chanpress:
287                 msg[1] = val1 & 0x7F;
288                 len = 2;
289                 break;
290
291         case MIDI::pitchbend:
292                 msg[1] = val1 & 0x7F;
293                 msg[2] = val2 & 0x7F;
294                 len = 3;
295                 break;
296         }
297
298         return _port.midimsg (msg, len, timestamp);
299 }