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. leave_sysex
  6. midi_synth_output
  7. midi_synth_ioctl
  8. midi_synth_kill_note
  9. midi_synth_set_instr
  10. midi_synth_start_note
  11. midi_synth_reset
  12. midi_synth_open
  13. midi_synth_close
  14. midi_synth_hw_control
  15. midi_synth_load_patch
  16. midi_synth_panning
  17. midi_synth_aftertouch
  18. midi_synth_controller
  19. midi_synth_patchmgr
  20. midi_synth_bender
  21. midi_synth_setup_voice
  22. midi_synth_send_sysex

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

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