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