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

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