merge (squash) with scenechange topic branch to provide MIDI-driven scene change...
[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 MIDI;
27
28 Channel::Channel (MIDI::byte channelnum, Port &p) 
29         : _port (p)
30 {
31         _channel_number = channelnum;
32
33         reset (0, 1, false);
34 }       
35
36 void
37 Channel::connect_signals ()
38 {
39         _port.parser()->channel_pressure[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_chanpress, this, _1, _2));
40         _port.parser()->channel_note_on[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_note_on, this, _1, _2));
41         _port.parser()->channel_note_off[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_note_off, this, _1, _2));
42         _port.parser()->channel_poly_pressure[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_polypress, this, _1, _2));
43         _port.parser()->channel_program_change[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_program_change, this, _1, _2));
44         _port.parser()->channel_controller[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_controller, this, _1, _2));
45         _port.parser()->channel_pitchbend[_channel_number].connect_same_thread (*this, boost::bind (&Channel::process_pitchbend, this, _1, _2));
46
47         _port.parser()->reset.connect_same_thread (*this, boost::bind (&Channel::process_reset, this, _1));
48 }
49
50 void
51 Channel::reset (timestamp_t timestamp, framecnt_t /*nframes*/, bool notes_off)
52 {
53         _program_number = _channel_number;
54         _bank_number = 0;
55         _pitch_bend = 0;
56
57         _last_note_on = 0;
58         _last_note_off = 0;
59         _last_on_velocity = 0;
60         _last_off_velocity = 0;
61
62         if (notes_off) {
63                 all_notes_off (timestamp);
64         }
65
66         memset (_polypress, 0, sizeof (_polypress));
67         memset (_controller_msb, 0, sizeof (_controller_msb));
68         memset (_controller_lsb, 0, sizeof (_controller_lsb));
69        
70         /* zero all controllers XXX not necessarily the right thing */
71
72         memset (_controller_val, 0, sizeof (_controller_val));
73
74         for (int n = 0; n < 128; n++) {
75                 _controller_14bit[n] = false;
76         }
77
78         _rpn_msb = 0;
79         _rpn_lsb = 0;
80         _nrpn_msb = 0;
81         _nrpn_lsb = 0;
82
83         _omni = true;
84         _poly = false;
85         _mono = true;
86         _notes_on = 0;
87 }
88
89 void
90 Channel::process_note_off (Parser & /*parser*/, EventTwoBytes *tb) 
91 {
92         _last_note_off = tb->note_number;
93         _last_off_velocity = tb->velocity;
94
95         if (_notes_on) {
96                 _notes_on--;
97         }
98 }
99
100 void
101 Channel::process_note_on (Parser & /*parser*/, EventTwoBytes *tb) 
102 {
103         _last_note_on = tb->note_number;
104         _last_on_velocity = tb->velocity;
105         _notes_on++;
106 }
107
108 void
109 Channel::process_controller (Parser & /*parser*/, EventTwoBytes *tb) 
110 {
111         unsigned short cv;
112
113         /* XXX arguably need a lock here to protect non-atomic changes
114            to controller_val[...]. or rather, need to make sure that
115            all changes *are* atomic.
116         */
117
118         if (tb->controller_number < 32) { /* unsigned: no test for >= 0 */
119
120                 /* if this controller is already known to use 14 bits,
121                    then treat this value as the MSB, and combine it 
122                    with the existing LSB.
123
124                    otherwise, just treat it as a 7 bit value, and set
125                    it directly.
126                 */
127
128                 cv = (unsigned short) _controller_val[tb->controller_number];
129
130                 if (_controller_14bit[tb->controller_number]) {
131                         cv = ((tb->value & 0x7f) << 7) | (cv & 0x7f);
132                 } else {
133                         cv = tb->value;
134                 }
135
136                 _controller_val[tb->controller_number] = (controller_value_t)cv;
137
138         } else if ((tb->controller_number >= 32 && 
139                     tb->controller_number <= 63)) {
140                    
141                 cv = (unsigned short) _controller_val[tb->controller_number];
142
143                 /* LSB for CC 0-31 arrived. 
144
145                    If this is the first time (i.e. its currently
146                    flagged as a 7 bit controller), mark the
147                    controller as 14 bit, adjust the existing value
148                    to be the MSB, and OR-in the new LSB value. 
149
150                    otherwise, OR-in the new low 7bits with the old
151                    high 7.
152                 */
153
154                 int cn = tb->controller_number - 32;
155                    
156                 if (_controller_14bit[cn] == false) {
157                         _controller_14bit[cn] = true;
158                         cv = (cv << 7) | (tb->value & 0x7f);
159                 } else {
160                         cv = (cv & 0x3f80) | (tb->value & 0x7f);
161                 }
162
163                 /* update the 14 bit value */
164                 _controller_val[cn] = (controller_value_t) cv;
165
166                 /* also store the "raw" 7 bit value in the incoming controller
167                    value store
168                 */
169                 _controller_val[tb->controller_number] = (controller_value_t) tb->value;
170
171         } else {
172
173                 /* controller can only take 7 bit values */
174                 
175                 _controller_val[tb->controller_number] = 
176                         (controller_value_t) tb->value;
177         }
178
179         /* bank numbers are special, in that they have their own signal
180          */
181
182         if (tb->controller_number == 0 || tb->controller_number == 0x20) {
183                 _bank_number = _controller_val[0];
184                 _port.parser()->bank_change (*_port.parser(), _bank_number);
185                 _port.parser()->channel_bank_change[_channel_number] (*_port.parser(), _bank_number);
186         }
187 }
188
189 void
190 Channel::process_program_change (Parser & /*parser*/, MIDI::byte val) 
191 {
192         _program_number = val;
193 }
194
195 void
196 Channel::process_chanpress (Parser & /*parser*/, MIDI::byte val) 
197 {
198         _chanpress = val;
199 }
200
201 void
202 Channel::process_polypress (Parser & /*parser*/, EventTwoBytes *tb) 
203 {
204         _polypress[tb->note_number] = tb->value;
205 }
206
207 void
208 Channel::process_pitchbend (Parser & /*parser*/, pitchbend_t val) 
209 {
210         _pitch_bend = val;
211 }
212
213 void
214 Channel::process_reset (Parser & /*parser*/) 
215 {
216         reset (0, 1);
217 }
218
219 /** Write a message to a channel.
220  * \return true if success
221  */
222 bool
223 Channel::channel_msg (MIDI::byte id, MIDI::byte val1, MIDI::byte val2, timestamp_t timestamp)
224 {
225         unsigned char msg[3];
226         int len = 0;
227
228         msg[0] = id | (_channel_number & 0xf);
229
230         switch (id) {
231         case off:
232                 msg[1] = val1 & 0x7F;
233                 msg[2] = val2 & 0x7F;
234                 len = 3;
235                 break;
236
237         case on:
238                 msg[1] = val1 & 0x7F;
239                 msg[2] = val2 & 0x7F;
240                 len = 3;
241                 break;
242
243         case MIDI::polypress:
244                 msg[1] = val1 & 0x7F;
245                 msg[2] = val2 & 0x7F;
246                 len = 3;
247                 break;
248
249         case controller:
250                 msg[1] = val1 & 0x7F;
251                 msg[2] = val2 & 0x7F;
252                 len = 3;
253                 break;
254
255         case MIDI::program:
256                 msg[1] = val1 & 0x7F;
257                 len = 2;
258                 break;
259
260         case MIDI::chanpress:
261                 msg[1] = val1 & 0x7F;
262                 len = 2;
263                 break;
264
265         case MIDI::pitchbend:
266                 msg[1] = val1 & 0x7F;
267                 msg[2] = val2 & 0x7F;
268                 len = 3;
269                 break;
270         }
271
272         return _port.midimsg (msg, len, timestamp);
273 }