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