Tabs to spaces, more consistent formatting.
[AROS.git] / workbench / libs / camd / midifromdriver.c
blob72e90586cd065e9f14f1c022e97567464def09cf
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: English
7 */
10 #include <proto/exec.h>
11 #include <proto/dos.h>
13 #include "camd_intern.h"
18 /*****************************************************
19 *****************************************************/
21 void Receiver_SetError(
22 struct DriverData *driverdata,
23 ULONG errorcode
25 struct MidiLink *midilink;
26 struct MyMidiNode *mymidinode;
28 ObtainSemaphoreShared(&driverdata->incluster->semaphore);
30 if(! (IsListEmpty(&driverdata->incluster->cluster.mcl_Receivers))){
31 midilink=(struct MidiLink *)driverdata->incluster->cluster.mcl_Receivers.lh_Head;
33 while(midilink->ml_Node.ln_Succ!=NULL){
34 if(midilink->ml_Node.ln_Type!=NT_USER-MLTYPE_NTypes){
35 mymidinode=(struct MyMidiNode *)midilink->ml_MidiNode;
36 ObtainSemaphore(&mymidinode->receiversemaphore);
37 mymidinode->error |= errorcode;
38 ReleaseSemaphore(&mymidinode->receiversemaphore);
40 midilink=(struct MidiLink *)midilink->ml_Node.ln_Succ;
44 ReleaseSemaphore(&driverdata->incluster->semaphore);
48 /*****************************************************
49 *****************************************************/
51 void Receiver_SysExSuperTreat(
52 struct DriverData *driverdata,
53 UBYTE data
55 struct MidiLink *midilink;
56 struct MyMidiNode *mymidinode;
58 ObtainSemaphoreShared(&driverdata->incluster->semaphore);
60 if(! (IsListEmpty(&driverdata->incluster->cluster.mcl_Receivers))){
61 midilink=(struct MidiLink *)driverdata->incluster->cluster.mcl_Receivers.lh_Head;
63 while(midilink->ml_Node.ln_Succ!=NULL){
64 if(midilink->ml_Node.ln_Type!=NT_USER-MLTYPE_NTypes){
65 mymidinode=(struct MyMidiNode *)midilink->ml_MidiNode;
66 ObtainSemaphore(&mymidinode->receiversemaphore);
67 PutSysEx2Link(midilink,data);
68 ReleaseSemaphore(&mymidinode->receiversemaphore);
70 midilink=(struct MidiLink *)midilink->ml_Node.ln_Succ;
74 ReleaseSemaphore(&driverdata->incluster->semaphore);
78 void Receiver_SuperTreat2(
79 struct DriverData *driverdata,
80 struct MyMidiMessage2 *msg2
82 struct MidiLink *midilink;
83 struct MyMidiNode *mymidinode;
84 ULONG msg;
86 ObtainSemaphoreShared(&driverdata->incluster->semaphore);
88 if(! (IsListEmpty(&driverdata->incluster->cluster.mcl_Receivers))){
90 midilink=(struct MidiLink *)driverdata->incluster->cluster.mcl_Receivers.lh_Head;
92 while(midilink->ml_Node.ln_Succ!=NULL){
93 if(midilink->ml_Node.ln_Type==NT_USER-MLTYPE_NTypes){ // Only happens if called from ParseMidi
94 if(driverdata->lastsysex==NULL){ // If a realtime-message are inside of a sysexmessage.
95 msg=(msg2->status<<24)|(msg2->data1<<16)|(msg2->data2<<8);
96 while(Midi2Driver_internal((struct DriverData *)midilink,msg,10000)==FALSE){
97 CamdWait();
100 }else{
101 mymidinode=(struct MyMidiNode *)midilink->ml_MidiNode;
102 ObtainSemaphore(&mymidinode->receiversemaphore);
103 PutMidi2Link(
104 midilink,
105 msg2,
106 *mymidinode->midinode.mi_TimeStamp
108 ReleaseSemaphore(&mymidinode->receiversemaphore);
110 midilink=(struct MidiLink *)midilink->ml_Node.ln_Succ;
114 ReleaseSemaphore(&driverdata->incluster->semaphore);
118 #define Receiver_SuperTreat(a) Receiver_SuperTreat2(driverdata,&driverdata->msg2);
122 /******************************************
123 Status
124 ******************************************/
126 void Receiver_NewSysEx(
127 struct DriverData *driverdata
129 void Receiver_NewSysCom(
130 struct DriverData *driverdata,
131 UBYTE status
133 void Receiver_General3_first(
134 struct DriverData *driverdata,
135 UBYTE data
137 void Receiver_General2_first(
138 struct DriverData *driverdata,
139 UBYTE data
142 void Receiver_NewStatus(
143 struct DriverData *driverdata,
144 UBYTE status
147 driverdata->msg2.status=status;
149 switch(status & 0xf0){
150 case 0x80:
151 case 0x90:
152 case 0xa0:
153 case 0xb0:
154 case 0xe0:
155 driverdata->msg2.len=3;
156 driverdata->Input_Treat=Receiver_General3_first;
157 break;
158 case 0xc0:
159 case 0xd0:
160 driverdata->msg2.len=2;
161 driverdata->Input_Treat=Receiver_General2_first;
162 break;
163 case 0xf0:
164 if(status==0xf0){
165 Receiver_NewSysEx(driverdata);
166 }else{
167 Receiver_NewSysCom(driverdata,status);
169 break;
173 void Receiver_ErrorAndNewStatus(
174 struct DriverData *driverdata,
175 UBYTE status
177 Receiver_SetError(driverdata,CMEF_MsgErr);
178 Receiver_NewStatus(driverdata,status);
181 void Receiver_NewStatus_first(
182 struct DriverData *driverdata,
183 UBYTE status
185 if(status<0x80){
186 D(bug("Error, Receiver_NewStatus_first, status: %ld\n",status));
187 Receiver_SetError(driverdata,CMEF_MsgErr);
188 }else{
189 Receiver_NewStatus(driverdata,status);
193 /******************************************
194 SysEx
195 ******************************************/
197 void Receiver_SysEx(
198 struct DriverData *driverdata,
199 UBYTE data
201 if(data>=0x80){
202 if(data==0xf7){
203 Receiver_SysExSuperTreat(driverdata,0xf7);
204 driverdata->Input_Treat=Receiver_NewStatus_first;
205 }else{
206 Receiver_SysExSuperTreat(driverdata,0xff);
207 D(bug("Error, Receiver_SysEx, data: %ld\n",data));
208 Receiver_ErrorAndNewStatus(driverdata,data);
210 }else{
211 Receiver_SysExSuperTreat(driverdata,data);
213 return;
216 void Receiver_NewSysEx(
217 struct DriverData *driverdata
219 Receiver_SysExSuperTreat(driverdata,0xf0);
220 driverdata->Input_Treat=Receiver_SysEx;
221 return;
226 /******************************************
227 System Common
228 ******************************************/
230 void Receiver_SysCom3_2(
231 struct DriverData *driverdata,
232 UBYTE data
234 if(data>=0x80){
235 D(bug("Error, Receiver_SysCom3_2, data: %ld\n",data));
236 Receiver_ErrorAndNewStatus(driverdata,data);
237 }else{
238 driverdata->msg2.data2=data;
239 Receiver_SuperTreat(driverdata);
240 driverdata->Input_Treat=Receiver_NewStatus_first;
244 void Receiver_SysCom3_1(
245 struct DriverData *driverdata,
246 UBYTE data
248 if(data>=0x80){
249 D(bug("Error, Receiver_SysCom3_1, data: %ld\n",data));
250 Receiver_ErrorAndNewStatus(driverdata,data);
251 }else{
252 driverdata->msg2.data1=data;
253 driverdata->Input_Treat=Receiver_SysCom3_2;
257 void Receiver_SysCom2(
258 struct DriverData *driverdata,
259 UBYTE data
261 if(data>=0x80){
262 D(bug("Error, Receiver_SysCom2, data: %ld\n",data));
263 Receiver_ErrorAndNewStatus(driverdata,data);
264 }else{
265 driverdata->msg2.data1=data;
266 Receiver_SuperTreat(driverdata);
267 driverdata->Input_Treat=Receiver_NewStatus_first;
272 void Receiver_NewSysCom(
273 struct DriverData *driverdata,
274 UBYTE status
276 switch(status){
277 case 0xf2:
278 driverdata->msg2.len=3;
279 driverdata->Input_Treat=Receiver_SysCom3_1;
280 break;
281 case 0xf1:
282 case 0xf3:
283 driverdata->msg2.len=2;
284 driverdata->Input_Treat=Receiver_SysCom2;
285 break;
286 case 0xf6:
287 driverdata->msg2.len=1;
288 Receiver_SuperTreat(driverdata);
289 driverdata->Input_Treat=Receiver_NewStatus_first;
290 break;
291 case 0xf7:
292 D(bug("Error, Receiver_NewSysCom, status: 0xf7\n"));
293 Receiver_SetError(driverdata,CMEF_MsgErr);
294 driverdata->Input_Treat=Receiver_NewStatus_first;
295 break;
296 default:
297 // Undefined SysCom. Topic: should the error not be set?
298 D(bug("Error, Receiver_NewSysCom, status: %ld\n",status));
299 Receiver_SetError(driverdata,CMEF_MsgErr);
300 driverdata->Input_Treat=Receiver_NewStatus_first;
301 break;
303 return;
308 /******************************************
309 Channel messages, length 3.
310 ******************************************/
312 void Receiver_General3_1(struct DriverData *driverdata,UBYTE data);
314 void Receiver_General3_2(
315 struct DriverData *driverdata,
316 UBYTE data
318 if(data>=0x80){
319 D(bug("Error, Receiver_General3_2, data: %ld\n",data));
320 Receiver_ErrorAndNewStatus(driverdata,data);
321 }else{
322 driverdata->msg2.data2=data;
323 Receiver_SuperTreat(driverdata);
324 driverdata->Input_Treat=Receiver_General3_1;
328 void Receiver_General3_1(
329 struct DriverData *driverdata,
330 UBYTE data
332 if(data>=0x80){
333 Receiver_NewStatus(driverdata,data);
334 }else{
335 driverdata->msg2.data1=data;
336 driverdata->Input_Treat=Receiver_General3_2;
340 void Receiver_General3_first(
341 struct DriverData *driverdata,
342 UBYTE data
344 if(data>=0x80){
345 D(bug("Error, Receiver_General3_first, data: %ld\n",data));
346 Receiver_ErrorAndNewStatus(driverdata,data);
347 }else{
348 driverdata->msg2.data1=data;
349 driverdata->Input_Treat=Receiver_General3_2;
354 /******************************************
355 Channel messages, length 2.
356 ******************************************/
358 void Receiver_General2(
359 struct DriverData *driverdata,
360 UBYTE data
362 if(data>=0x80){
363 Receiver_NewStatus(driverdata,data);
364 }else{
365 driverdata->msg2.data1=data;
366 Receiver_SuperTreat(driverdata);
368 return;
371 void Receiver_General2_first(
372 struct DriverData *driverdata,
373 UBYTE data
375 if(data>=0x80){
376 D(bug("Error, Receiver_General2_first, data: %ld\n",data));
377 Receiver_ErrorAndNewStatus(driverdata,data);
378 }else{
379 driverdata->msg2.data1=data;
380 Receiver_SuperTreat(driverdata);
381 driverdata->Input_Treat=Receiver_General2;
383 return;
386 /******************************************
387 Realtime
388 ******************************************/
390 void Receiver_RealTime(
391 struct DriverData *driverdata,
392 UBYTE status
394 struct MyMidiMessage2 msg2;
395 msg2.status=status;
396 msg2.len=1;
397 Receiver_SuperTreat2(driverdata,&msg2);
398 return;
401 /******************************************
402 Init, only used until first non-data
403 non-realtime non-sysex-end message is received.
404 ******************************************/
406 void Receiver_init(
407 struct DriverData *driverdata,
408 UBYTE data
410 if(data<0x80 || data==0xf7) return;
412 Receiver_NewStatus(driverdata,data);
417 /******************************************
418 First function to be called from the
419 receiver process.
420 ******************************************/
422 void Receiver_first(
423 struct DriverData *driverdata
425 UWORD input;
427 input=*driverdata->re_read;
428 driverdata->re_read++;
429 if(driverdata->re_read==driverdata->re_end){
430 driverdata->re_read=driverdata->re_start;
433 if(input&0x8000){
434 D(bug("Error, Receiver_first. Overflow: %lx\n",input));
435 Receiver_SetError(driverdata,CMEF_RecvOverflow);
438 input&=0xff;
440 if(input>=0xf8){
441 Receiver_RealTime(driverdata,input);
442 }else{
443 (*driverdata->Input_Treat)(driverdata,input);
446 driverdata->unpicked--;
451 /******************************************
452 Code called from driver.
453 ******************************************/
455 #ifdef __amigaos4__
456 void Receiver(
457 UWORD input,
458 struct DriverData *driverdata
459 #else
460 SAVEDS void ASM Receiver(
461 REG(d0) UWORD input,
462 REG(a2) struct DriverData *driverdata
463 #endif
465 *driverdata->re_write=input;
466 driverdata->re_write++;
467 if(driverdata->re_write==driverdata->re_end){
468 driverdata->re_write=driverdata->re_start;
470 driverdata->unpicked++;
471 Signal(&driverdata->ReceiverProc->pr_Task,1L<<driverdata->ReceiverSig);