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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [sound/] [midi_synth.c] - Blame information for rev 1777

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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