linux/sound/oss/midi_synth.c
<<
>>
Prefs
   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
  26static int      midi2synth[MAX_MIDI_DEV];
  27static int      sysex_state[MAX_MIDI_DEV] =
  28{0};
  29static 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
  43void
  44do_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}
  87EXPORT_SYMBOL(do_midi_msg);
  88
  89static void
  90midi_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
 114static int
 115prefix_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
 123static void
 124midi_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
 234static void
 235leave_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
 252static void
 253midi_synth_output(int dev)
 254{
 255        /*
 256         * Currently NOP
 257         */
 258}
 259
 260int 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}
 280EXPORT_SYMBOL(midi_synth_ioctl);
 281
 282int
 283midi_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}
 347EXPORT_SYMBOL(midi_synth_kill_note);
 348
 349int
 350midi_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}
 370EXPORT_SYMBOL(midi_synth_set_instr);
 371
 372int
 373midi_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}
 412EXPORT_SYMBOL(midi_synth_start_note);
 413
 414void
 415midi_synth_reset(int dev)
 416{
 417
 418        leave_sysex(dev);
 419}
 420EXPORT_SYMBOL(midi_synth_reset);
 421
 422int
 423midi_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}
 453EXPORT_SYMBOL(midi_synth_open);
 454
 455void
 456midi_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}
 469EXPORT_SYMBOL(midi_synth_close);
 470
 471void
 472midi_synth_hw_control(int dev, unsigned char *event)
 473{
 474}
 475EXPORT_SYMBOL(midi_synth_hw_control);
 476
 477int
 478midi_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                get_user(*(unsigned char *) &data, (unsigned char __user *) &((addr)[hdr_size + i]));
 527
 528                eox_seen = (i > 0 && data & 0x80);      /* End of sysex */
 529
 530                if (eox_seen && data != 0xf7)
 531                        data = 0xf7;
 532
 533                if (i == 0)
 534                {
 535                        if (data != 0xf0)
 536                        {
 537                                printk(KERN_WARNING "midi_synth: Sysex start missing\n");
 538                                return -EINVAL;
 539                        }
 540                }
 541                while (!midi_devs[orig_dev]->outputc(orig_dev, (unsigned char) (data & 0xff)) &&
 542                        !signal_pending(current))
 543                        schedule();
 544
 545                if (!first_byte && data & 0x80)
 546                        return 0;
 547                first_byte = 0;
 548        }
 549
 550        if (!eox_seen)
 551                midi_outc(orig_dev, 0xf7);
 552        return 0;
 553}
 554EXPORT_SYMBOL(midi_synth_load_patch);
 555
 556void midi_synth_panning(int dev, int channel, int pressure)
 557{
 558}
 559EXPORT_SYMBOL(midi_synth_panning);
 560
 561void midi_synth_aftertouch(int dev, int channel, int pressure)
 562{
 563        int             orig_dev = synth_devs[dev]->midi_dev;
 564        int             msg, chn;
 565
 566        if (pressure < 0 || pressure > 127)
 567                return;
 568        if (channel < 0 || channel > 15)
 569                return;
 570
 571        leave_sysex(dev);
 572
 573        msg = prev_out_status[orig_dev] & 0xf0;
 574        chn = prev_out_status[orig_dev] & 0x0f;
 575
 576        if (msg != 0xd0 || chn != channel)      /*
 577                                                 * Test for running status
 578                                                 */
 579          {
 580                  if (!prefix_cmd(orig_dev, 0xd0 | (channel & 0x0f)))
 581                          return;
 582                  midi_outc(orig_dev, 0xd0 | (channel & 0x0f));         /*
 583                                                                         * Channel pressure
 584                                                                         */
 585        } else if (!prefix_cmd(orig_dev, pressure))
 586                return;
 587
 588        midi_outc(orig_dev, pressure);
 589}
 590EXPORT_SYMBOL(midi_synth_aftertouch);
 591
 592void
 593midi_synth_controller(int dev, int channel, int ctrl_num, int value)
 594{
 595        int             orig_dev = synth_devs[dev]->midi_dev;
 596        int             chn, msg;
 597
 598        if (ctrl_num < 0 || ctrl_num > 127)
 599                return;
 600        if (channel < 0 || channel > 15)
 601                return;
 602
 603        leave_sysex(dev);
 604
 605        msg = prev_out_status[orig_dev] & 0xf0;
 606        chn = prev_out_status[orig_dev] & 0x0f;
 607
 608        if (msg != 0xb0 || chn != channel)
 609          {
 610                  if (!prefix_cmd(orig_dev, 0xb0 | (channel & 0x0f)))
 611                          return;
 612                  midi_outc(orig_dev, 0xb0 | (channel & 0x0f));
 613        } else if (!prefix_cmd(orig_dev, ctrl_num))
 614                return;
 615
 616        midi_outc(orig_dev, ctrl_num);
 617        midi_outc(orig_dev, value & 0x7f);
 618}
 619EXPORT_SYMBOL(midi_synth_controller);
 620
 621void
 622midi_synth_bender(int dev, int channel, int value)
 623{
 624        int             orig_dev = synth_devs[dev]->midi_dev;
 625        int             msg, prev_chn;
 626
 627        if (channel < 0 || channel > 15)
 628                return;
 629
 630        if (value < 0 || value > 16383)
 631                return;
 632
 633        leave_sysex(dev);
 634
 635        msg = prev_out_status[orig_dev] & 0xf0;
 636        prev_chn = prev_out_status[orig_dev] & 0x0f;
 637
 638        if (msg != 0xd0 || prev_chn != channel)         /*
 639                                                         * Test for running status
 640                                                         */
 641          {
 642                  if (!prefix_cmd(orig_dev, 0xe0 | (channel & 0x0f)))
 643                          return;
 644                  midi_outc(orig_dev, 0xe0 | (channel & 0x0f));
 645        } else if (!prefix_cmd(orig_dev, value & 0x7f))
 646                return;
 647
 648        midi_outc(orig_dev, value & 0x7f);
 649        midi_outc(orig_dev, (value >> 7) & 0x7f);
 650}
 651EXPORT_SYMBOL(midi_synth_bender);
 652
 653void
 654midi_synth_setup_voice(int dev, int voice, int channel)
 655{
 656}
 657EXPORT_SYMBOL(midi_synth_setup_voice);
 658
 659int
 660midi_synth_send_sysex(int dev, unsigned char *bytes, int len)
 661{
 662        int             orig_dev = synth_devs[dev]->midi_dev;
 663        int             i;
 664
 665        for (i = 0; i < len; i++)
 666          {
 667                  switch (bytes[i])
 668                    {
 669                    case 0xf0:  /* Start sysex */
 670                            if (!prefix_cmd(orig_dev, 0xf0))
 671                                    return 0;
 672                            sysex_state[dev] = 1;
 673                            break;
 674
 675                    case 0xf7:  /* End sysex */
 676                            if (!sysex_state[dev])      /* Orphan sysex end */
 677                                    return 0;
 678                            sysex_state[dev] = 0;
 679                            break;
 680
 681                    default:
 682                            if (!sysex_state[dev])
 683                                    return 0;
 684
 685                            if (bytes[i] & 0x80)        /* Error. Another message before sysex end */
 686                              {
 687                                      bytes[i] = 0xf7;  /* Sysex end */
 688                                      sysex_state[dev] = 0;
 689                              }
 690                    }
 691
 692                  if (!midi_devs[orig_dev]->outputc(orig_dev, bytes[i]))
 693                    {
 694/*
 695 * Hardware level buffer is full. Abort the sysex message.
 696 */
 697
 698                            int             timeout = 0;
 699
 700                            bytes[i] = 0xf7;
 701                            sysex_state[dev] = 0;
 702
 703                            while (!midi_devs[orig_dev]->outputc(orig_dev, bytes[i]) &&
 704                                   timeout < 1000)
 705                                    timeout++;
 706                    }
 707                  if (!sysex_state[dev])
 708                          return 0;
 709          }
 710
 711        return 0;
 712}
 713EXPORT_SYMBOL(midi_synth_send_sysex);
 714
 715