root/drivers/sound/midi_synth.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. do_midi_msg
  2. midi_outc
  3. prefix_cmd
  4. midi_synth_input
  5. midi_synth_output
  6. midi_synth_ioctl
  7. midi_synth_kill_note
  8. midi_synth_set_instr
  9. midi_synth_start_note
  10. midi_synth_reset
  11. midi_synth_open
  12. midi_synth_close
  13. midi_synth_hw_control
  14. midi_synth_load_patch
  15. midi_synth_panning
  16. midi_synth_aftertouch
  17. midi_synth_controller
  18. midi_synth_patchmgr
  19. midi_synth_bender
  20. midi_synth_setup_voice

   1 /*
   2  * sound/midi_synth.c
   3  *
   4  * High level midi sequencer manager for dumb MIDI interfaces.
   5  *
   6  * Copyright by Hannu Savolainen 1993
   7  *
   8  * Redistribution and use in source and binary forms, with or without
   9  * modification, are permitted provided that the following conditions are
  10  * met: 1. Redistributions of source code must retain the above copyright
  11  * notice, this list of conditions and the following disclaimer. 2.
  12  * Redistributions in binary form must reproduce the above copyright notice,
  13  * this list of conditions and the following disclaimer in the documentation
  14  * and/or other materials provided with the distribution.
  15  *
  16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
  17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
  20  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  22  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  23  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  26  * SUCH DAMAGE.
  27  *
  28  */
  29 
  30 #define USE_SEQ_MACROS
  31 #define USE_SIMPLE_MACROS
  32 
  33 #include "sound_config.h"
  34 
  35 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_MIDI)
  36 
  37 #define _MIDI_SYNTH_C_
  38 
  39 DEFINE_WAIT_QUEUE (sysex_sleeper, sysex_sleep_flag);
  40 
  41 #include "midi_synth.h"
  42 
  43 static int      midi2synth[MAX_MIDI_DEV];
  44 static unsigned char prev_out_status[MAX_MIDI_DEV];
  45 
  46 #define STORE(cmd) \
  47 { \
  48   int len; \
  49   unsigned char obuf[8]; \
  50   cmd; \
  51   seq_input_event(obuf, len); \
  52 }
  53 #define _seqbuf obuf
  54 #define _seqbufptr 0
  55 #define _SEQ_ADVBUF(x) len=x
  56 
  57 void
  58 do_midi_msg (int synthno, unsigned char *msg, int mlen)
     /* [previous][next][first][last][top][bottom][index][help] */
  59 {
  60   switch (msg[0] & 0xf0)
  61     {
  62     case 0x90:
  63       if (msg[2] != 0)
  64         {
  65           STORE (SEQ_START_NOTE (synthno, msg[0] & 0x0f, msg[1], msg[2]));
  66           break;
  67         }
  68       msg[2] = 64;
  69 
  70     case 0x80:
  71       STORE (SEQ_STOP_NOTE (synthno, msg[0] & 0x0f, msg[1], msg[2]));
  72       break;
  73 
  74     case 0xA0:
  75       STORE (SEQ_KEY_PRESSURE (synthno, msg[0] & 0x0f, msg[1], msg[2]));
  76       break;
  77 
  78     case 0xB0:
  79       STORE (SEQ_CONTROL (synthno, msg[0] & 0x0f,
  80                           msg[1], msg[2]));
  81       break;
  82 
  83     case 0xC0:
  84       STORE (SEQ_SET_PATCH (synthno, msg[0] & 0x0f, msg[1]));
  85       break;
  86 
  87     case 0xD0:
  88       STORE (SEQ_CHN_PRESSURE (synthno, msg[0] & 0x0f, msg[1]));
  89       break;
  90 
  91     case 0xE0:
  92       STORE (SEQ_BENDER (synthno, msg[0] & 0x0f,
  93                          (msg[1] % 0x7f) | ((msg[2] & 0x7f) << 7)));
  94       break;
  95 
  96     default:
  97       /* printk ("MPU: Unknown midi channel message %02x\n", msg[0]); */
  98     }
  99 }
 100 
 101 static void
 102 midi_outc (int midi_dev, int data)
     /* [previous][next][first][last][top][bottom][index][help] */
 103 {
 104   int             timeout;
 105 
 106   for (timeout = 0; timeout < 32000; timeout++)
 107     if (midi_devs[midi_dev]->putc (midi_dev, (unsigned char) (data & 0xff)))
 108       {
 109         if (data & 0x80)        /*
 110                                  * Status byte
 111                                  */
 112           prev_out_status[midi_dev] =
 113             (unsigned char) (data & 0xff);      /*
 114                                                  * Store for running status
 115                                                  */
 116         return;                 /*
 117                                  * Mission complete
 118                                  */
 119       }
 120 
 121   /*
 122    * Sorry! No space on buffers.
 123    */
 124   printk ("Midi send timed out\n");
 125 }
 126 
 127 static int
 128 prefix_cmd (int midi_dev, unsigned char status)
     /* [previous][next][first][last][top][bottom][index][help] */
 129 {
 130   if ((char *) midi_devs[midi_dev]->prefix_cmd == NULL)
 131     return 1;
 132 
 133   return midi_devs[midi_dev]->prefix_cmd (midi_dev, status);
 134 }
 135 
 136 static void
 137 midi_synth_input (int orig_dev, unsigned char data)
     /* [previous][next][first][last][top][bottom][index][help] */
 138 {
 139   int             dev;
 140   struct midi_input_info *inc;
 141 
 142   static unsigned char len_tab[] =      /* # of data bytes following a status
 143                                          */
 144   {
 145     2,                          /* 8x */
 146     2,                          /* 9x */
 147     2,                          /* Ax */
 148     2,                          /* Bx */
 149     1,                          /* Cx */
 150     1,                          /* Dx */
 151     2,                          /* Ex */
 152     0                           /* Fx */
 153   };
 154 
 155   if (orig_dev < 0 || orig_dev > num_midis)
 156     return;
 157 
 158   if (data == 0xfe)             /* Ignore active sensing */
 159     return;
 160 
 161   dev = midi2synth[orig_dev];
 162   inc = &midi_devs[orig_dev]->in_info;
 163 
 164   switch (inc->m_state)
 165     {
 166     case MST_INIT:
 167       if (data & 0x80)          /* MIDI status byte */
 168         {
 169           if ((data & 0xf0) == 0xf0)    /* Common message */
 170             {
 171               switch (data)
 172                 {
 173                 case 0xf0:      /* Sysex */
 174                   inc->m_state = MST_SYSEX;
 175                   break;        /* Sysex */
 176 
 177                 case 0xf1:      /* MTC quarter frame */
 178                 case 0xf3:      /* Song select */
 179                   inc->m_state = MST_DATA;
 180                   inc->m_ptr = 1;
 181                   inc->m_left = 1;
 182                   inc->m_buf[0] = data;
 183                   break;
 184 
 185                 case 0xf2:      /* Song position pointer */
 186                   inc->m_state = MST_DATA;
 187                   inc->m_ptr = 1;
 188                   inc->m_left = 2;
 189                   inc->m_buf[0] = data;
 190                   break;
 191 
 192                 default:
 193                   inc->m_buf[0] = data;
 194                   inc->m_ptr = 1;
 195                   do_midi_msg (dev, inc->m_buf, inc->m_ptr);
 196                   inc->m_ptr = 0;
 197                   inc->m_left = 0;
 198                 }
 199             }
 200           else
 201             {
 202               inc->m_state = MST_DATA;
 203               inc->m_ptr = 1;
 204               inc->m_left = len_tab[(data >> 4) - 8];
 205               inc->m_buf[0] = inc->m_prev_status = data;
 206             }
 207         }
 208       else if (inc->m_prev_status & 0x80)       /* Ignore if no previous status (yet) */
 209         {                       /* Data byte (use running status) */
 210           inc->m_state = MST_DATA;
 211           inc->m_ptr = 2;
 212           inc->m_left = len_tab[(data >> 4) - 8] - 1;
 213           inc->m_buf[0] = inc->m_prev_status;
 214           inc->m_buf[1] = data;
 215         }
 216       break;                    /* MST_INIT */
 217 
 218     case MST_DATA:
 219       inc->m_buf[inc->m_ptr++] = data;
 220       if (--inc->m_left <= 0)
 221         {
 222           inc->m_state = MST_INIT;
 223           do_midi_msg (dev, inc->m_buf, inc->m_ptr);
 224           inc->m_ptr = 0;
 225         }
 226       break;                    /* MST_DATA */
 227 
 228     case MST_SYSEX:
 229       if (data == 0xf7)         /* Sysex end */
 230         {
 231           inc->m_state = MST_INIT;
 232           inc->m_left = 0;
 233           inc->m_ptr = 0;
 234         }
 235       break;                    /* MST_SYSEX */
 236 
 237     default:
 238       printk ("MIDI%d: Unexpected state %d (%02x)\n", orig_dev, inc->m_state,
 239               (int) data);
 240       inc->m_state = MST_INIT;
 241     }
 242 }
 243 
 244 static void
 245 midi_synth_output (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 246 {
 247   /*
 248    * Currently NOP
 249    */
 250 }
 251 
 252 int
 253 midi_synth_ioctl (int dev,
     /* [previous][next][first][last][top][bottom][index][help] */
 254                   unsigned int cmd, unsigned int arg)
 255 {
 256   /*
 257    * int orig_dev = synth_devs[dev]->midi_dev;
 258    */
 259 
 260   switch (cmd)
 261     {
 262 
 263     case SNDCTL_SYNTH_INFO:
 264       IOCTL_TO_USER ((char *) arg, 0, synth_devs[dev]->info,
 265                      sizeof (struct synth_info));
 266 
 267       return 0;
 268       break;
 269 
 270     case SNDCTL_SYNTH_MEMAVL:
 271       return 0x7fffffff;
 272       break;
 273 
 274     default:
 275       return RET_ERROR (EINVAL);
 276     }
 277 }
 278 
 279 int
 280 midi_synth_kill_note (int dev, int channel, int note, int velocity)
     /* [previous][next][first][last][top][bottom][index][help] */
 281 {
 282   int             orig_dev = synth_devs[dev]->midi_dev;
 283   int             msg, chn;
 284 
 285   if (note < 0 || note > 127)
 286     return 0;
 287   if (channel < 0 || channel > 15)
 288     return 0;
 289   if (velocity < 0)
 290     velocity = 0;
 291   if (velocity > 127)
 292     velocity = 127;
 293 
 294   msg = prev_out_status[orig_dev] & 0xf0;
 295   chn = prev_out_status[orig_dev] & 0x0f;
 296 
 297   if (chn == channel && ((msg == 0x90 && velocity == 64) || msg == 0x80))
 298     {                           /*
 299                                  * Use running status
 300                                  */
 301       if (!prefix_cmd (orig_dev, note))
 302         return 0;
 303 
 304       midi_outc (orig_dev, note);
 305 
 306       if (msg == 0x90)          /*
 307                                  * Running status = Note on
 308                                  */
 309         midi_outc (orig_dev, 0);        /*
 310                                            * Note on with velocity 0 == note
 311                                            * off
 312                                          */
 313       else
 314         midi_outc (orig_dev, velocity);
 315     }
 316   else
 317     {
 318       if (velocity == 64)
 319         {
 320           if (!prefix_cmd (orig_dev, 0x90 | (channel & 0x0f)))
 321             return 0;
 322           midi_outc (orig_dev, 0x90 | (channel & 0x0f));        /*
 323                                                                  * Note on
 324                                                                  */
 325           midi_outc (orig_dev, note);
 326           midi_outc (orig_dev, 0);      /*
 327                                          * Zero G
 328                                          */
 329         }
 330       else
 331         {
 332           if (!prefix_cmd (orig_dev, 0x80 | (channel & 0x0f)))
 333             return 0;
 334           midi_outc (orig_dev, 0x80 | (channel & 0x0f));        /*
 335                                                                  * Note off
 336                                                                  */
 337           midi_outc (orig_dev, note);
 338           midi_outc (orig_dev, velocity);
 339         }
 340     }
 341 
 342   return 0;
 343 }
 344 
 345 int
 346 midi_synth_set_instr (int dev, int channel, int instr_no)
     /* [previous][next][first][last][top][bottom][index][help] */
 347 {
 348   int             orig_dev = synth_devs[dev]->midi_dev;
 349 
 350   if (instr_no < 0 || instr_no > 127)
 351     return 0;
 352   if (channel < 0 || channel > 15)
 353     return 0;
 354 
 355   if (!prefix_cmd (orig_dev, 0xc0 | (channel & 0x0f)))
 356     return 0;
 357   midi_outc (orig_dev, 0xc0 | (channel & 0x0f));        /*
 358                                                          * Program change
 359                                                          */
 360   midi_outc (orig_dev, instr_no);
 361 
 362   return 0;
 363 }
 364 
 365 int
 366 midi_synth_start_note (int dev, int channel, int note, int velocity)
     /* [previous][next][first][last][top][bottom][index][help] */
 367 {
 368   int             orig_dev = synth_devs[dev]->midi_dev;
 369   int             msg, chn;
 370 
 371   if (note < 0 || note > 127)
 372     return 0;
 373   if (channel < 0 || channel > 15)
 374     return 0;
 375   if (velocity < 0)
 376     velocity = 0;
 377   if (velocity > 127)
 378     velocity = 127;
 379 
 380   msg = prev_out_status[orig_dev] & 0xf0;
 381   chn = prev_out_status[orig_dev] & 0x0f;
 382 
 383   if (chn == channel && msg == 0x90)
 384     {                           /*
 385                                  * Use running status
 386                                  */
 387       if (!prefix_cmd (orig_dev, note))
 388         return 0;
 389       midi_outc (orig_dev, note);
 390       midi_outc (orig_dev, velocity);
 391     }
 392   else
 393     {
 394       if (!prefix_cmd (orig_dev, 0x90 | (channel & 0x0f)))
 395         return 0;
 396       midi_outc (orig_dev, 0x90 | (channel & 0x0f));    /*
 397                                                          * Note on
 398                                                          */
 399       midi_outc (orig_dev, note);
 400       midi_outc (orig_dev, velocity);
 401     }
 402   return 0;
 403 }
 404 
 405 void
 406 midi_synth_reset (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 407 {
 408 }
 409 
 410 int
 411 midi_synth_open (int dev, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 412 {
 413   int             orig_dev = synth_devs[dev]->midi_dev;
 414   int             err;
 415   unsigned long   flags;
 416   struct midi_input_info *inc;
 417 
 418   if (orig_dev < 0 || orig_dev > num_midis)
 419     return RET_ERROR (ENXIO);
 420 
 421   midi2synth[orig_dev] = dev;
 422   prev_out_status[orig_dev] = 0;
 423 
 424   if ((err = midi_devs[orig_dev]->open (orig_dev, mode,
 425                                   midi_synth_input, midi_synth_output)) < 0)
 426     return err;
 427 
 428   inc = &midi_devs[orig_dev]->in_info;
 429 
 430   DISABLE_INTR (flags);
 431   inc->m_busy = 0;
 432   inc->m_state = MST_INIT;
 433   inc->m_ptr = 0;
 434   inc->m_left = 0;
 435   inc->m_prev_status = 0x00;
 436   RESTORE_INTR (flags);
 437 
 438   return 1;
 439 }
 440 
 441 void
 442 midi_synth_close (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 443 {
 444   int             orig_dev = synth_devs[dev]->midi_dev;
 445 
 446   /*
 447      * Shut up the synths by sending just single active sensing message.
 448    */
 449   midi_devs[orig_dev]->putc (orig_dev, 0xfe);
 450 
 451   midi_devs[orig_dev]->close (orig_dev);
 452 }
 453 
 454 void
 455 midi_synth_hw_control (int dev, unsigned char *event)
     /* [previous][next][first][last][top][bottom][index][help] */
 456 {
 457 }
 458 
 459 int
 460 midi_synth_load_patch (int dev, int format, snd_rw_buf * addr,
     /* [previous][next][first][last][top][bottom][index][help] */
 461                        int offs, int count, int pmgr_flag)
 462 {
 463   int             orig_dev = synth_devs[dev]->midi_dev;
 464 
 465   struct sysex_info sysex;
 466   int             i;
 467   unsigned long   left, src_offs, eox_seen = 0;
 468   int             first_byte = 1;
 469   int             hdr_size = (unsigned long) &sysex.data[0] - (unsigned long) &sysex;
 470 
 471   if (!prefix_cmd (orig_dev, 0xf0))
 472     return 0;
 473 
 474   if (format != SYSEX_PATCH)
 475     {
 476       printk ("MIDI Error: Invalid patch format (key) 0x%x\n", format);
 477       return RET_ERROR (EINVAL);
 478     }
 479 
 480   if (count < hdr_size)
 481     {
 482       printk ("MIDI Error: Patch header too short\n");
 483       return RET_ERROR (EINVAL);
 484     }
 485 
 486   count -= hdr_size;
 487 
 488   /*
 489    * Copy the header from user space but ignore the first bytes which have
 490    * been transferred already.
 491    */
 492 
 493   COPY_FROM_USER (&((char *) &sysex)[offs], addr, offs, hdr_size - offs);
 494 
 495   if (count < sysex.len)
 496     {
 497       printk ("MIDI Warning: Sysex record too short (%d<%d)\n",
 498               count, (int) sysex.len);
 499       sysex.len = count;
 500     }
 501 
 502   left = sysex.len;
 503   src_offs = 0;
 504 
 505   RESET_WAIT_QUEUE (sysex_sleeper, sysex_sleep_flag);
 506 
 507   for (i = 0; i < left && !PROCESS_ABORTING (sysex_sleeper, sysex_sleep_flag); i++)
 508     {
 509       unsigned char   data;
 510 
 511       GET_BYTE_FROM_USER (data, addr, hdr_size + i);
 512 
 513       eox_seen = (i > 0 && data & 0x80);        /* End of sysex */
 514 
 515       if (eox_seen && data != 0xf7)
 516         data = 0xf7;
 517 
 518       if (i == 0)
 519         {
 520           if (data != 0xf0)
 521             {
 522               printk ("Error: Sysex start missing\n");
 523               return RET_ERROR (EINVAL);
 524             }
 525         }
 526 
 527       while (!midi_devs[orig_dev]->putc (orig_dev, (unsigned char) (data & 0xff)) &&
 528              !PROCESS_ABORTING (sysex_sleeper, sysex_sleep_flag))
 529         DO_SLEEP (sysex_sleeper, sysex_sleep_flag, 1);  /* Wait for timeout */
 530 
 531       if (!first_byte && data & 0x80)
 532         return 0;
 533       first_byte = 0;
 534     }
 535 
 536   if (!eox_seen)
 537     midi_outc (orig_dev, 0xf7);
 538   return 0;
 539 }
 540 
 541 void
 542 midi_synth_panning (int dev, int channel, int pressure)
     /* [previous][next][first][last][top][bottom][index][help] */
 543 {
 544 }
 545 
 546 void
 547 midi_synth_aftertouch (int dev, int channel, int pressure)
     /* [previous][next][first][last][top][bottom][index][help] */
 548 {
 549   int             orig_dev = synth_devs[dev]->midi_dev;
 550   int             msg, chn;
 551 
 552   if (pressure < 0 || pressure > 127)
 553     return;
 554   if (channel < 0 || channel > 15)
 555     return;
 556 
 557   msg = prev_out_status[orig_dev] & 0xf0;
 558   chn = prev_out_status[orig_dev] & 0x0f;
 559 
 560   if (msg != 0xd0 || chn != channel)    /*
 561                                          * Test for running status
 562                                          */
 563     {
 564       if (!prefix_cmd (orig_dev, 0xd0 | (channel & 0x0f)))
 565         return;
 566       midi_outc (orig_dev, 0xd0 | (channel & 0x0f));    /*
 567                                                          * Channel pressure
 568                                                          */
 569     }
 570   else if (!prefix_cmd (orig_dev, pressure))
 571     return;
 572 
 573   midi_outc (orig_dev, pressure);
 574 }
 575 
 576 void
 577 midi_synth_controller (int dev, int channel, int ctrl_num, int value)
     /* [previous][next][first][last][top][bottom][index][help] */
 578 {
 579   int             orig_dev = synth_devs[dev]->midi_dev;
 580   int             chn, msg;
 581 
 582   if (ctrl_num < 1 || ctrl_num > 127)
 583     return;                     /* NOTE! Controller # 0 ignored */
 584   if (channel < 0 || channel > 15)
 585     return;
 586 
 587   msg = prev_out_status[orig_dev] & 0xf0;
 588   chn = prev_out_status[orig_dev] & 0x0f;
 589 
 590   if (msg != 0xb0 || chn != channel)
 591     {
 592       if (!prefix_cmd (orig_dev, 0xb0 | (channel & 0x0f)))
 593         return;
 594       midi_outc (orig_dev, 0xb0 | (channel & 0x0f));
 595     }
 596   else if (!prefix_cmd (orig_dev, ctrl_num))
 597     return;
 598 
 599   midi_outc (orig_dev, ctrl_num);
 600   midi_outc (orig_dev, value & 0x7f);
 601 }
 602 
 603 int
 604 midi_synth_patchmgr (int dev, struct patmgr_info *rec)
     /* [previous][next][first][last][top][bottom][index][help] */
 605 {
 606   return RET_ERROR (EINVAL);
 607 }
 608 
 609 void
 610 midi_synth_bender (int dev, int channel, int value)
     /* [previous][next][first][last][top][bottom][index][help] */
 611 {
 612   int             orig_dev = synth_devs[dev]->midi_dev;
 613   int             msg, prev_chn;
 614 
 615   if (channel < 0 || channel > 15)
 616     return;
 617 
 618   if (value < 0 || value > 16383)
 619     return;
 620 
 621   msg = prev_out_status[orig_dev] & 0xf0;
 622   prev_chn = prev_out_status[orig_dev] & 0x0f;
 623 
 624   if (msg != 0xd0 || prev_chn != channel)       /*
 625                                                  * Test for running status
 626                                                  */
 627     {
 628       if (!prefix_cmd (orig_dev, 0xe0 | (channel & 0x0f)))
 629         return;
 630       midi_outc (orig_dev, 0xe0 | (channel & 0x0f));
 631     }
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 641 {
 642 }
 643 
 644 #endif

/* [previous][next][first][last][top][bottom][index][help] */