]> git.karo-electronics.de Git - mv-sheeva.git/blob - sound/oss/midi_synth.c
Merge master.kernel.org:/home/rmk/linux-2.6-arm
[mv-sheeva.git] / sound / oss / midi_synth.c
1 /*
2  * sound/oss/midi_synth.c
3  *
4  * High level midi sequencer manager for dumb MIDI interfaces.
5  */
6 /*
7  * Copyright (C) by Hannu Savolainen 1993-1997
8  *
9  * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
10  * Version 2 (June 1991). See the "COPYING" file distributed with this software
11  * for more info.
12  */
13 /*
14  * Thomas Sailer   : ioctl code reworked (vmalloc/vfree removed)
15  * Andrew Veliath  : fixed running status in MIDI input state machine
16  */
17 #define USE_SEQ_MACROS
18 #define USE_SIMPLE_MACROS
19
20 #include "sound_config.h"
21
22 #define _MIDI_SYNTH_C_
23
24 #include "midi_synth.h"
25
26 static int      midi2synth[MAX_MIDI_DEV];
27 static int      sysex_state[MAX_MIDI_DEV] =
28 {0};
29 static unsigned char prev_out_status[MAX_MIDI_DEV];
30
31 #define STORE(cmd) \
32 { \
33   int len; \
34   unsigned char obuf[8]; \
35   cmd; \
36   seq_input_event(obuf, len); \
37 }
38
39 #define _seqbuf obuf
40 #define _seqbufptr 0
41 #define _SEQ_ADVBUF(x) len=x
42
43 void
44 do_midi_msg(int synthno, unsigned char *msg, int mlen)
45 {
46         switch (msg[0] & 0xf0)
47           {
48           case 0x90:
49                   if (msg[2] != 0)
50                     {
51                             STORE(SEQ_START_NOTE(synthno, msg[0] & 0x0f, msg[1], msg[2]));
52                             break;
53                     }
54                   msg[2] = 64;
55
56           case 0x80:
57                   STORE(SEQ_STOP_NOTE(synthno, msg[0] & 0x0f, msg[1], msg[2]));
58                   break;
59
60           case 0xA0:
61                   STORE(SEQ_KEY_PRESSURE(synthno, msg[0] & 0x0f, msg[1], msg[2]));
62                   break;
63
64           case 0xB0:
65                   STORE(SEQ_CONTROL(synthno, msg[0] & 0x0f,
66                                     msg[1], msg[2]));
67                   break;
68
69           case 0xC0:
70                   STORE(SEQ_SET_PATCH(synthno, msg[0] & 0x0f, msg[1]));
71                   break;
72
73           case 0xD0:
74                   STORE(SEQ_CHN_PRESSURE(synthno, msg[0] & 0x0f, msg[1]));
75                   break;
76
77           case 0xE0:
78                   STORE(SEQ_BENDER(synthno, msg[0] & 0x0f,
79                               (msg[1] & 0x7f) | ((msg[2] & 0x7f) << 7)));
80                   break;
81
82           default:
83                   /* printk( "MPU: Unknown midi channel message %02x\n",  msg[0]); */
84                   ;
85           }
86 }
87 EXPORT_SYMBOL(do_midi_msg);
88
89 static void
90 midi_outc(int midi_dev, int data)
91 {
92         int             timeout;
93
94         for (timeout = 0; timeout < 3200; timeout++)
95                 if (midi_devs[midi_dev]->outputc(midi_dev, (unsigned char) (data & 0xff)))
96                   {
97                           if (data & 0x80)      /*
98                                                  * Status byte
99                                                  */
100                                   prev_out_status[midi_dev] =
101                                       (unsigned char) (data & 0xff);    /*
102                                                                          * Store for running status
103                                                                          */
104                           return;       /*
105                                          * Mission complete
106                                          */
107                   }
108         /*
109          * Sorry! No space on buffers.
110          */
111         printk("Midi send timed out\n");
112 }
113
114 static int
115 prefix_cmd(int midi_dev, unsigned char status)
116 {
117         if ((char *) midi_devs[midi_dev]->prefix_cmd == NULL)
118                 return 1;
119
120         return midi_devs[midi_dev]->prefix_cmd(midi_dev, status);
121 }
122
123 static void
124 midi_synth_input(int orig_dev, unsigned char data)
125 {
126         int             dev;
127         struct midi_input_info *inc;
128
129         static unsigned char len_tab[] =        /* # of data bytes following a status
130                                                  */
131         {
132                 2,              /* 8x */
133                 2,              /* 9x */
134                 2,              /* Ax */
135                 2,              /* Bx */
136                 1,              /* Cx */
137                 1,              /* Dx */
138                 2,              /* Ex */
139                 0               /* Fx */
140         };
141
142         if (orig_dev < 0 || orig_dev > num_midis || midi_devs[orig_dev] == NULL)
143                 return;
144
145         if (data == 0xfe)       /* Ignore active sensing */
146                 return;
147
148         dev = midi2synth[orig_dev];
149         inc = &midi_devs[orig_dev]->in_info;
150
151         switch (inc->m_state)
152           {
153           case MST_INIT:
154                   if (data & 0x80)      /* MIDI status byte */
155                     {
156                             if ((data & 0xf0) == 0xf0)  /* Common message */
157                               {
158                                       switch (data)
159                                         {
160                                         case 0xf0:      /* Sysex */
161                                                 inc->m_state = MST_SYSEX;
162                                                 break;  /* Sysex */
163
164                                         case 0xf1:      /* MTC quarter frame */
165                                         case 0xf3:      /* Song select */
166                                                 inc->m_state = MST_DATA;
167                                                 inc->m_ptr = 1;
168                                                 inc->m_left = 1;
169                                                 inc->m_buf[0] = data;
170                                                 break;
171
172                                         case 0xf2:      /* Song position pointer */
173                                                 inc->m_state = MST_DATA;
174                                                 inc->m_ptr = 1;
175                                                 inc->m_left = 2;
176                                                 inc->m_buf[0] = data;
177                                                 break;
178
179                                         default:
180                                                 inc->m_buf[0] = data;
181                                                 inc->m_ptr = 1;
182                                                 do_midi_msg(dev, inc->m_buf, inc->m_ptr);
183                                                 inc->m_ptr = 0;
184                                                 inc->m_left = 0;
185                                         }
186                             } else
187                               {
188                                       inc->m_state = MST_DATA;
189                                       inc->m_ptr = 1;
190                                       inc->m_left = len_tab[(data >> 4) - 8];
191                                       inc->m_buf[0] = inc->m_prev_status = data;
192                               }
193                     } else if (inc->m_prev_status & 0x80) {
194                             /* Data byte (use running status) */
195                             inc->m_ptr = 2;
196                             inc->m_buf[1] = data;
197                             inc->m_buf[0] = inc->m_prev_status;
198                             inc->m_left = len_tab[(inc->m_buf[0] >> 4) - 8] - 1;
199                             if (inc->m_left > 0)
200                                     inc->m_state = MST_DATA; /* Not done yet */
201                             else {
202                                     inc->m_state = MST_INIT;
203                                     do_midi_msg(dev, inc->m_buf, inc->m_ptr);
204                                     inc->m_ptr = 0;
205                             }
206                     }
207                   break;        /* MST_INIT */
208
209           case MST_DATA:
210                   inc->m_buf[inc->m_ptr++] = data;
211                   if (--inc->m_left <= 0)
212                     {
213                             inc->m_state = MST_INIT;
214                             do_midi_msg(dev, inc->m_buf, inc->m_ptr);
215                             inc->m_ptr = 0;
216                     }
217                   break;        /* MST_DATA */
218
219           case MST_SYSEX:
220                   if (data == 0xf7)     /* Sysex end */
221                     {
222                             inc->m_state = MST_INIT;
223                             inc->m_left = 0;
224                             inc->m_ptr = 0;
225                     }
226                   break;        /* MST_SYSEX */
227
228           default:
229                   printk("MIDI%d: Unexpected state %d (%02x)\n", orig_dev, inc->m_state, (int) data);
230                   inc->m_state = MST_INIT;
231           }
232 }
233
234 static void
235 leave_sysex(int dev)
236 {
237         int             orig_dev = synth_devs[dev]->midi_dev;
238         int             timeout = 0;
239
240         if (!sysex_state[dev])
241                 return;
242
243         sysex_state[dev] = 0;
244
245         while (!midi_devs[orig_dev]->outputc(orig_dev, 0xf7) &&
246                timeout < 1000)
247                 timeout++;
248
249         sysex_state[dev] = 0;
250 }
251
252 static void
253 midi_synth_output(int dev)
254 {
255         /*
256          * Currently NOP
257          */
258 }
259
260 int midi_synth_ioctl(int dev, unsigned int cmd, void __user *arg)
261 {
262         /*
263          * int orig_dev = synth_devs[dev]->midi_dev;
264          */
265
266         switch (cmd) {
267
268         case SNDCTL_SYNTH_INFO:
269                 if (__copy_to_user(arg, synth_devs[dev]->info, sizeof(struct synth_info)))
270                         return -EFAULT;
271                 return 0;
272                 
273         case SNDCTL_SYNTH_MEMAVL:
274                 return 0x7fffffff;
275
276         default:
277                 return -EINVAL;
278         }
279 }
280 EXPORT_SYMBOL(midi_synth_ioctl);
281
282 int
283 midi_synth_kill_note(int dev, int channel, int note, int velocity)
284 {
285         int             orig_dev = synth_devs[dev]->midi_dev;
286         int             msg, chn;
287
288         if (note < 0 || note > 127)
289                 return 0;
290         if (channel < 0 || channel > 15)
291                 return 0;
292         if (velocity < 0)
293                 velocity = 0;
294         if (velocity > 127)
295                 velocity = 127;
296
297         leave_sysex(dev);
298
299         msg = prev_out_status[orig_dev] & 0xf0;
300         chn = prev_out_status[orig_dev] & 0x0f;
301
302         if (chn == channel && ((msg == 0x90 && velocity == 64) || msg == 0x80))
303           {                     /*
304                                  * Use running status
305                                  */
306                   if (!prefix_cmd(orig_dev, note))
307                           return 0;
308
309                   midi_outc(orig_dev, note);
310
311                   if (msg == 0x90)      /*
312                                          * Running status = Note on
313                                          */
314                           midi_outc(orig_dev, 0);       /*
315                                                            * Note on with velocity 0 == note
316                                                            * off
317                                                          */
318                   else
319                           midi_outc(orig_dev, velocity);
320         } else
321           {
322                   if (velocity == 64)
323                     {
324                             if (!prefix_cmd(orig_dev, 0x90 | (channel & 0x0f)))
325                                     return 0;
326                             midi_outc(orig_dev, 0x90 | (channel & 0x0f));       /*
327                                                                                  * Note on
328                                                                                  */
329                             midi_outc(orig_dev, note);
330                             midi_outc(orig_dev, 0);     /*
331                                                          * Zero G
332                                                          */
333                   } else
334                     {
335                             if (!prefix_cmd(orig_dev, 0x80 | (channel & 0x0f)))
336                                     return 0;
337                             midi_outc(orig_dev, 0x80 | (channel & 0x0f));       /*
338                                                                                  * Note off
339                                                                                  */
340                             midi_outc(orig_dev, note);
341                             midi_outc(orig_dev, velocity);
342                     }
343           }
344
345         return 0;
346 }
347 EXPORT_SYMBOL(midi_synth_kill_note);
348
349 int
350 midi_synth_set_instr(int dev, int channel, int instr_no)
351 {
352         int             orig_dev = synth_devs[dev]->midi_dev;
353
354         if (instr_no < 0 || instr_no > 127)
355                 instr_no = 0;
356         if (channel < 0 || channel > 15)
357                 return 0;
358
359         leave_sysex(dev);
360
361         if (!prefix_cmd(orig_dev, 0xc0 | (channel & 0x0f)))
362                 return 0;
363         midi_outc(orig_dev, 0xc0 | (channel & 0x0f));   /*
364                                                          * Program change
365                                                          */
366         midi_outc(orig_dev, instr_no);
367
368         return 0;
369 }
370 EXPORT_SYMBOL(midi_synth_set_instr);
371
372 int
373 midi_synth_start_note(int dev, int channel, int note, int velocity)
374 {
375         int             orig_dev = synth_devs[dev]->midi_dev;
376         int             msg, chn;
377
378         if (note < 0 || note > 127)
379                 return 0;
380         if (channel < 0 || channel > 15)
381                 return 0;
382         if (velocity < 0)
383                 velocity = 0;
384         if (velocity > 127)
385                 velocity = 127;
386
387         leave_sysex(dev);
388
389         msg = prev_out_status[orig_dev] & 0xf0;
390         chn = prev_out_status[orig_dev] & 0x0f;
391
392         if (chn == channel && msg == 0x90)
393           {                     /*
394                                  * Use running status
395                                  */
396                   if (!prefix_cmd(orig_dev, note))
397                           return 0;
398                   midi_outc(orig_dev, note);
399                   midi_outc(orig_dev, velocity);
400         } else
401           {
402                   if (!prefix_cmd(orig_dev, 0x90 | (channel & 0x0f)))
403                           return 0;
404                   midi_outc(orig_dev, 0x90 | (channel & 0x0f));         /*
405                                                                          * Note on
406                                                                          */
407                   midi_outc(orig_dev, note);
408                   midi_outc(orig_dev, velocity);
409           }
410         return 0;
411 }
412 EXPORT_SYMBOL(midi_synth_start_note);
413
414 void
415 midi_synth_reset(int dev)
416 {
417
418         leave_sysex(dev);
419 }
420 EXPORT_SYMBOL(midi_synth_reset);
421
422 int
423 midi_synth_open(int dev, int mode)
424 {
425         int             orig_dev = synth_devs[dev]->midi_dev;
426         int             err;
427         struct midi_input_info *inc;
428
429         if (orig_dev < 0 || orig_dev >= num_midis || midi_devs[orig_dev] == NULL)
430                 return -ENXIO;
431
432         midi2synth[orig_dev] = dev;
433         sysex_state[dev] = 0;
434         prev_out_status[orig_dev] = 0;
435
436         if ((err = midi_devs[orig_dev]->open(orig_dev, mode,
437                                midi_synth_input, midi_synth_output)) < 0)
438                 return err;
439         inc = &midi_devs[orig_dev]->in_info;
440
441         /* save_flags(flags);
442         cli(); 
443         don't know against what irqhandler to protect*/
444         inc->m_busy = 0;
445         inc->m_state = MST_INIT;
446         inc->m_ptr = 0;
447         inc->m_left = 0;
448         inc->m_prev_status = 0x00;
449         /* restore_flags(flags); */
450
451         return 1;
452 }
453 EXPORT_SYMBOL(midi_synth_open);
454
455 void
456 midi_synth_close(int dev)
457 {
458         int             orig_dev = synth_devs[dev]->midi_dev;
459
460         leave_sysex(dev);
461
462         /*
463          * Shut up the synths by sending just single active sensing message.
464          */
465         midi_devs[orig_dev]->outputc(orig_dev, 0xfe);
466
467         midi_devs[orig_dev]->close(orig_dev);
468 }
469 EXPORT_SYMBOL(midi_synth_close);
470
471 void
472 midi_synth_hw_control(int dev, unsigned char *event)
473 {
474 }
475 EXPORT_SYMBOL(midi_synth_hw_control);
476
477 int
478 midi_synth_load_patch(int dev, int format, const char __user *addr,
479                       int offs, int count, int pmgr_flag)
480 {
481         int             orig_dev = synth_devs[dev]->midi_dev;
482
483         struct sysex_info sysex;
484         int             i;
485         unsigned long   left, src_offs, eox_seen = 0;
486         int             first_byte = 1;
487         int             hdr_size = (unsigned long) &sysex.data[0] - (unsigned long) &sysex;
488
489         leave_sysex(dev);
490
491         if (!prefix_cmd(orig_dev, 0xf0))
492                 return 0;
493
494         if (format != SYSEX_PATCH)
495         {
496 /*                printk("MIDI Error: Invalid patch format (key) 0x%x\n", format);*/
497                   return -EINVAL;
498         }
499         if (count < hdr_size)
500         {
501 /*              printk("MIDI Error: Patch header too short\n");*/
502                 return -EINVAL;
503         }
504         count -= hdr_size;
505
506         /*
507          * Copy the header from user space but ignore the first bytes which have
508          * been transferred already.
509          */
510
511         if(copy_from_user(&((char *) &sysex)[offs], &(addr)[offs], hdr_size - offs))
512                 return -EFAULT;
513  
514         if (count < sysex.len)
515         {
516 /*              printk(KERN_WARNING "MIDI Warning: Sysex record too short (%d<%d)\n", count, (int) sysex.len);*/
517                 sysex.len = count;
518         }
519         left = sysex.len;
520         src_offs = 0;
521
522         for (i = 0; i < left && !signal_pending(current); i++)
523         {
524                 unsigned char   data;
525
526                 if (get_user(data,
527                     (unsigned char __user *)(addr + hdr_size + i)))
528                         return -EFAULT;
529
530                 eox_seen = (i > 0 && data & 0x80);      /* End of sysex */
531
532                 if (eox_seen && data != 0xf7)
533                         data = 0xf7;
534
535                 if (i == 0)
536                 {
537                         if (data != 0xf0)
538                         {
539                                 printk(KERN_WARNING "midi_synth: Sysex start missing\n");
540                                 return -EINVAL;
541                         }
542                 }
543                 while (!midi_devs[orig_dev]->outputc(orig_dev, (unsigned char) (data & 0xff)) &&
544                         !signal_pending(current))
545                         schedule();
546
547                 if (!first_byte && data & 0x80)
548                         return 0;
549                 first_byte = 0;
550         }
551
552         if (!eox_seen)
553                 midi_outc(orig_dev, 0xf7);
554         return 0;
555 }
556 EXPORT_SYMBOL(midi_synth_load_patch);
557
558 void midi_synth_panning(int dev, int channel, int pressure)
559 {
560 }
561 EXPORT_SYMBOL(midi_synth_panning);
562
563 void midi_synth_aftertouch(int dev, int channel, int pressure)
564 {
565         int             orig_dev = synth_devs[dev]->midi_dev;
566         int             msg, chn;
567
568         if (pressure < 0 || pressure > 127)
569                 return;
570         if (channel < 0 || channel > 15)
571                 return;
572
573         leave_sysex(dev);
574
575         msg = prev_out_status[orig_dev] & 0xf0;
576         chn = prev_out_status[orig_dev] & 0x0f;
577
578         if (msg != 0xd0 || chn != channel)      /*
579                                                  * Test for running status
580                                                  */
581           {
582                   if (!prefix_cmd(orig_dev, 0xd0 | (channel & 0x0f)))
583                           return;
584                   midi_outc(orig_dev, 0xd0 | (channel & 0x0f));         /*
585                                                                          * Channel pressure
586                                                                          */
587         } else if (!prefix_cmd(orig_dev, pressure))
588                 return;
589
590         midi_outc(orig_dev, pressure);
591 }
592 EXPORT_SYMBOL(midi_synth_aftertouch);
593
594 void
595 midi_synth_controller(int dev, int channel, int ctrl_num, int value)
596 {
597         int             orig_dev = synth_devs[dev]->midi_dev;
598         int             chn, msg;
599
600         if (ctrl_num < 0 || ctrl_num > 127)
601                 return;
602         if (channel < 0 || channel > 15)
603                 return;
604
605         leave_sysex(dev);
606
607         msg = prev_out_status[orig_dev] & 0xf0;
608         chn = prev_out_status[orig_dev] & 0x0f;
609
610         if (msg != 0xb0 || chn != channel)
611           {
612                   if (!prefix_cmd(orig_dev, 0xb0 | (channel & 0x0f)))
613                           return;
614                   midi_outc(orig_dev, 0xb0 | (channel & 0x0f));
615         } else if (!prefix_cmd(orig_dev, ctrl_num))
616                 return;
617
618         midi_outc(orig_dev, ctrl_num);
619         midi_outc(orig_dev, value & 0x7f);
620 }
621 EXPORT_SYMBOL(midi_synth_controller);
622
623 void
624 midi_synth_bender(int dev, int channel, int value)
625 {
626         int             orig_dev = synth_devs[dev]->midi_dev;
627         int             msg, prev_chn;
628
629         if (channel < 0 || channel > 15)
630                 return;
631
632         if (value < 0 || value > 16383)
633                 return;
634
635         leave_sysex(dev);
636
637         msg = prev_out_status[orig_dev] & 0xf0;
638         prev_chn = prev_out_status[orig_dev] & 0x0f;
639
640         if (msg != 0xd0 || prev_chn != channel)         /*
641                                                          * Test for running status
642                                                          */
643           {
644                   if (!prefix_cmd(orig_dev, 0xe0 | (channel & 0x0f)))
645                           return;
646                   midi_outc(orig_dev, 0xe0 | (channel & 0x0f));
647         } else if (!prefix_cmd(orig_dev, value & 0x7f))
648                 return;
649
650         midi_outc(orig_dev, value & 0x7f);
651         midi_outc(orig_dev, (value >> 7) & 0x7f);
652 }
653 EXPORT_SYMBOL(midi_synth_bender);
654
655 void
656 midi_synth_setup_voice(int dev, int voice, int channel)
657 {
658 }
659 EXPORT_SYMBOL(midi_synth_setup_voice);
660
661 int
662 midi_synth_send_sysex(int dev, unsigned char *bytes, int len)
663 {
664         int             orig_dev = synth_devs[dev]->midi_dev;
665         int             i;
666
667         for (i = 0; i < len; i++)
668           {
669                   switch (bytes[i])
670                     {
671                     case 0xf0:  /* Start sysex */
672                             if (!prefix_cmd(orig_dev, 0xf0))
673                                     return 0;
674                             sysex_state[dev] = 1;
675                             break;
676
677                     case 0xf7:  /* End sysex */
678                             if (!sysex_state[dev])      /* Orphan sysex end */
679                                     return 0;
680                             sysex_state[dev] = 0;
681                             break;
682
683                     default:
684                             if (!sysex_state[dev])
685                                     return 0;
686
687                             if (bytes[i] & 0x80)        /* Error. Another message before sysex end */
688                               {
689                                       bytes[i] = 0xf7;  /* Sysex end */
690                                       sysex_state[dev] = 0;
691                               }
692                     }
693
694                   if (!midi_devs[orig_dev]->outputc(orig_dev, bytes[i]))
695                     {
696 /*
697  * Hardware level buffer is full. Abort the sysex message.
698  */
699
700                             int             timeout = 0;
701
702                             bytes[i] = 0xf7;
703                             sysex_state[dev] = 0;
704
705                             while (!midi_devs[orig_dev]->outputc(orig_dev, bytes[i]) &&
706                                    timeout < 1000)
707                                     timeout++;
708                     }
709                   if (!sysex_state[dev])
710                           return 0;
711           }
712
713         return 0;
714 }
715 EXPORT_SYMBOL(midi_synth_send_sysex);
716