OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [sound/] [midi_synth.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.