MusicalTime => Beats.
[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                 int cn = tb->controller_number - 32;
142
143                 cv = (unsigned short) _controller_val[cn];
144
145                 /* LSB for CC 0-31 arrived. 
146
147                    If this is the first time (i.e. its currently
148                    flagged as a 7 bit controller), mark the
149                    controller as 14 bit, adjust the existing value
150                    to be the MSB, and OR-in the new LSB value. 
151
152                    otherwise, OR-in the new low 7bits with the old
153                    high 7.
154                 */
155
156                    
157                 if (_controller_14bit[cn] == false) {
158                         _controller_14bit[cn] = true;
159                         cv = (cv << 7) | (tb->value & 0x7f);
160                 } else {
161                         cv = (cv & 0x3f80) | (tb->value & 0x7f);
162                 }
163
164                 /* update the 14 bit value */
165                 _controller_val[cn] = (controller_value_t) cv;
166
167                 /* also store the "raw" 7 bit value in the incoming controller
168                    value store
169                 */
170                 _controller_val[tb->controller_number] = (controller_value_t) tb->value;
171
172         } else {
173
174                 /* controller can only take 7 bit values */
175                 
176                 _controller_val[tb->controller_number] = 
177                         (controller_value_t) tb->value;
178         }
179
180         /* bank numbers are special, in that they have their own signal
181          */
182
183         if (tb->controller_number == 0 || tb->controller_number == 0x20) {
184                 _bank_number = _controller_val[0];
185                 _port.parser()->bank_change (*_port.parser(), _bank_number);
186                 _port.parser()->channel_bank_change[_channel_number] (*_port.parser(), _bank_number);
187         }
188 }
189
190 void
191 Channel::process_program_change (Parser & /*parser*/, MIDI::byte val) 
192 {
193         _program_number = val;
194 }
195
196 void
197 Channel::process_chanpress (Parser & /*parser*/, MIDI::byte val) 
198 {
199         _chanpress = val;
200 }
201
202 void
203 Channel::process_polypress (Parser & /*parser*/, EventTwoBytes *tb) 
204 {
205         _polypress[tb->note_number] = tb->value;
206 }
207
208 void
209 Channel::process_pitchbend (Parser & /*parser*/, pitchbend_t val) 
210 {
211         _pitch_bend = val;
212 }
213
214 void
215 Channel::process_reset (Parser & /*parser*/) 
216 {
217         reset (0, 1);
218 }
219
220 /** Write a message to a channel.
221  * \return true if success
222  */
223 bool
224 Channel::channel_msg (MIDI::byte id, MIDI::byte val1, MIDI::byte val2, timestamp_t timestamp)
225 {
226         unsigned char msg[3];
227         int len = 0;
228
229         msg[0] = id | (_channel_number & 0xf);
230
231         switch (id) {
232         case off:
233                 msg[1] = val1 & 0x7F;
234                 msg[2] = val2 & 0x7F;
235                 len = 3;
236                 break;
237
238         case on:
239                 msg[1] = val1 & 0x7F;
240                 msg[2] = val2 & 0x7F;
241                 len = 3;
242                 break;
243
244         case MIDI::polypress:
245                 msg[1] = val1 & 0x7F;
246                 msg[2] = val2 & 0x7F;
247                 len = 3;
248                 break;
249
250         case controller:
251                 msg[1] = val1 & 0x7F;
252                 msg[2] = val2 & 0x7F;
253                 len = 3;
254                 break;
255
256         case MIDI::program:
257                 msg[1] = val1 & 0x7F;
258                 len = 2;
259                 break;
260
261         case MIDI::chanpress:
262                 msg[1] = val1 & 0x7F;
263                 len = 2;
264                 break;
265
266         case MIDI::pitchbend:
267                 msg[1] = val1 & 0x7F;
268                 msg[2] = val2 & 0x7F;
269                 len = 3;
270                 break;
271         }
272
273         return _port.midimsg (msg, len, timestamp);
274 }