1 /*
2 * Copyright 2006, Haiku.
3 *
4 * Copyright (c) 2002-2003 Matthijs Hollemans
5 * Copyright (c) 2002 Michael Pfeiffer
6 * Copyright (c) 2002 Jerome Leveque
7 * Copyright (c) 2002 Paul Stadler
8 * Distributed under the terms of the MIT License.
9 *
10 * Authors:
11 * Matthijs Hollemans
12 * Michael Pfeiffer
13 * Jérôme Leveque
14 * Paul Stadler
15 */
16
17 #include <List.h>
18 #include <Midi.h>
19 #include <MidiProducer.h>
20
21 #include "MidiGlue.h"
22 #include "debug.h"
23
24 using namespace BPrivate;
25
26
27 status_t
_run_thread(void * data)28 _run_thread(void* data)
29 {
30 BMidi* midi = (BMidi*)data;
31 midi->Run();
32 midi->fIsRunning = false;
33 return 0;
34 }
35
36
BMidi()37 BMidi::BMidi()
38 {
39 fConnections = new BList;
40 fThreadId = -1;
41 fIsRunning = false;
42
43 fProducer = new BMidiLocalProducer("MidiGlue(out)");
44 fConsumer = new BMidiGlue(this, "MidiGlue(in)");
45 }
46
47
~BMidi()48 BMidi::~BMidi()
49 {
50 Stop();
51
52 status_t result;
53 wait_for_thread(fThreadId, &result);
54
55 fProducer->Release();
56 fConsumer->Release();
57
58 delete fConnections;
59 }
60
61
62 void
NoteOff(uchar channel,uchar note,uchar velocity,uint32 time)63 BMidi::NoteOff(uchar channel, uchar note, uchar velocity, uint32 time)
64 {
65 // do nothing
66 }
67
68
69 void
NoteOn(uchar channel,uchar note,uchar velocity,uint32 time)70 BMidi::NoteOn(uchar channel, uchar note, uchar velocity, uint32 time)
71 {
72 // do nothing
73 }
74
75
76 void
KeyPressure(uchar channel,uchar note,uchar pressure,uint32 time)77 BMidi::KeyPressure(
78 uchar channel, uchar note, uchar pressure, uint32 time)
79 {
80 // do nothing
81 }
82
83
84 void
ControlChange(uchar channel,uchar controlNumber,uchar controlValue,uint32 time)85 BMidi::ControlChange(
86 uchar channel, uchar controlNumber, uchar controlValue, uint32 time)
87 {
88 // do nothing
89 }
90
91
92 void
ProgramChange(uchar channel,uchar programNumber,uint32 time)93 BMidi::ProgramChange(uchar channel, uchar programNumber, uint32 time)
94 {
95 // do nothing
96 }
97
98
99 void
ChannelPressure(uchar channel,uchar pressure,uint32 time)100 BMidi::ChannelPressure(uchar channel, uchar pressure, uint32 time)
101 {
102 // do nothing
103 }
104
105
106 void
PitchBend(uchar channel,uchar lsb,uchar msb,uint32 time)107 BMidi::PitchBend(uchar channel, uchar lsb, uchar msb, uint32 time)
108 {
109 // do nothing
110 }
111
112
113 void
SystemExclusive(void * data,size_t length,uint32 time)114 BMidi::SystemExclusive(void* data, size_t length, uint32 time)
115 {
116 // do nothing
117 }
118
119
120 void
SystemCommon(uchar status,uchar data1,uchar data2,uint32 time)121 BMidi::SystemCommon(uchar status, uchar data1, uchar data2, uint32 time)
122 {
123 // do nothing
124 }
125
126
127 void
SystemRealTime(uchar status,uint32 time)128 BMidi::SystemRealTime(uchar status, uint32 time)
129 {
130 // do nothing
131 }
132
133
134 void
TempoChange(int32 beatsPerMinute,uint32 time)135 BMidi::TempoChange(int32 beatsPerMinute, uint32 time)
136 {
137 // do nothing
138 }
139
140
141 void
AllNotesOff(bool justChannel,uint32 time)142 BMidi::AllNotesOff(bool justChannel, uint32 time)
143 {
144 for (uchar channel = 1; channel <= 16; ++channel) {
145 SprayControlChange(channel, B_ALL_NOTES_OFF, 0, time);
146
147 if (!justChannel) {
148 for (uchar note = 0; note <= 0x7F; ++note) {
149 SprayNoteOff(channel, note, 0, time);
150 }
151 }
152 }
153 }
154
155
156 status_t
Start()157 BMidi::Start()
158 {
159 if (fIsRunning)
160 return B_OK;
161
162 status_t err = spawn_thread(
163 _run_thread, "MidiRunThread", B_URGENT_PRIORITY, this);
164
165 if (err < B_OK)
166 return err;
167
168 fThreadId = err;
169 fIsRunning = true;
170
171 err = resume_thread(fThreadId);
172 if (err != B_OK) {
173 fThreadId = -1;
174 fIsRunning = false;
175 }
176
177 return err;
178 }
179
180
181 void
Stop()182 BMidi::Stop()
183 {
184 AllNotesOff();
185 fThreadId = -1;
186 }
187
188
189 bool
IsRunning() const190 BMidi::IsRunning() const
191 {
192 return fIsRunning;
193 }
194
195
196 void
Connect(BMidi * toObject)197 BMidi::Connect(BMidi* toObject)
198 {
199 if (toObject != NULL) {
200 if (fProducer->Connect(toObject->fConsumer) == B_OK) {
201 fConnections->AddItem(toObject);
202 }
203 }
204 }
205
206
207 void
Disconnect(BMidi * fromObject)208 BMidi::Disconnect(BMidi* fromObject)
209 {
210 if (fromObject == NULL)
211 return;
212
213 if (fProducer->Disconnect(fromObject->fConsumer) == B_OK) {
214 fConnections->RemoveItem(fromObject);
215 }
216 }
217
218
219 bool
IsConnected(BMidi * toObject) const220 BMidi::IsConnected(BMidi* toObject) const
221 {
222 if (toObject != NULL)
223 return fProducer->IsConnected(toObject->fConsumer);
224
225 return false;
226 }
227
228
229 BList*
Connections() const230 BMidi::Connections() const
231 {
232 return fConnections;
233 }
234
235
236 void
SnoozeUntil(uint32 time) const237 BMidi::SnoozeUntil(uint32 time) const
238 {
239 snooze_until(MAKE_BIGTIME(time), B_SYSTEM_TIMEBASE);
240 }
241
242
243 bool
KeepRunning()244 BMidi::KeepRunning()
245 {
246 return (fThreadId != -1);
247 }
248
249
_ReservedMidi1()250 void BMidi::_ReservedMidi1() {}
_ReservedMidi2()251 void BMidi::_ReservedMidi2() {}
_ReservedMidi3()252 void BMidi::_ReservedMidi3() {}
253
254
255 void
Run()256 BMidi::Run()
257 {
258 // do nothing
259 }
260
261
262 void
SprayNoteOff(uchar channel,uchar note,uchar velocity,uint32 time) const263 BMidi::SprayNoteOff(
264 uchar channel, uchar note, uchar velocity, uint32 time) const
265 {
266 fProducer->SprayNoteOff(
267 channel - 1, note, velocity, MAKE_BIGTIME(time));
268 }
269
270
271 void
SprayNoteOn(uchar channel,uchar note,uchar velocity,uint32 time) const272 BMidi::SprayNoteOn(
273 uchar channel, uchar note, uchar velocity, uint32 time) const
274 {
275 fProducer->SprayNoteOn(
276 channel - 1, note, velocity, MAKE_BIGTIME(time));
277 }
278
279
280 void
SprayKeyPressure(uchar channel,uchar note,uchar pressure,uint32 time) const281 BMidi::SprayKeyPressure(
282 uchar channel, uchar note, uchar pressure, uint32 time) const
283 {
284 fProducer->SprayKeyPressure(
285 channel - 1, note, pressure, MAKE_BIGTIME(time));
286 }
287
288
289 void
SprayControlChange(uchar channel,uchar controlNumber,uchar controlValue,uint32 time) const290 BMidi::SprayControlChange(
291 uchar channel, uchar controlNumber, uchar controlValue,
292 uint32 time) const
293 {
294 fProducer->SprayControlChange(
295 channel - 1, controlNumber, controlValue, MAKE_BIGTIME(time));
296 }
297
298
299 void
SprayProgramChange(uchar channel,uchar programNumber,uint32 time) const300 BMidi::SprayProgramChange(
301 uchar channel, uchar programNumber, uint32 time) const
302 {
303 fProducer->SprayProgramChange(
304 channel - 1, programNumber, MAKE_BIGTIME(time));
305 }
306
307
308 void
SprayChannelPressure(uchar channel,uchar pressure,uint32 time) const309 BMidi::SprayChannelPressure(
310 uchar channel, uchar pressure, uint32 time) const
311 {
312 fProducer->SprayChannelPressure(
313 channel - 1, pressure, MAKE_BIGTIME(time));
314 }
315
316
317 void
SprayPitchBend(uchar channel,uchar lsb,uchar msb,uint32 time) const318 BMidi::SprayPitchBend(
319 uchar channel, uchar lsb, uchar msb, uint32 time) const
320 {
321 fProducer->SprayPitchBend(channel - 1, lsb, msb, MAKE_BIGTIME(time));
322 }
323
324
325 void
SpraySystemExclusive(void * data,size_t length,uint32 time) const326 BMidi::SpraySystemExclusive(
327 void* data, size_t length, uint32 time) const
328 {
329 fProducer->SpraySystemExclusive(data, length, MAKE_BIGTIME(time));
330 }
331
332
333 void
SpraySystemCommon(uchar status,uchar data1,uchar data2,uint32 time) const334 BMidi::SpraySystemCommon(
335 uchar status, uchar data1, uchar data2, uint32 time) const
336 {
337 fProducer->SpraySystemCommon(status, data1, data2, MAKE_BIGTIME(time));
338 }
339
340
341 void
SpraySystemRealTime(uchar status,uint32 time) const342 BMidi::SpraySystemRealTime(uchar status, uint32 time) const
343 {
344 fProducer->SpraySystemRealTime(status, MAKE_BIGTIME(time));
345 }
346
347
348 void
SprayTempoChange(int32 beatsPerMinute,uint32 time) const349 BMidi::SprayTempoChange(int32 beatsPerMinute, uint32 time) const
350 {
351 fProducer->SprayTempoChange(beatsPerMinute, MAKE_BIGTIME(time));
352 }
353
354