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