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 #define STORE(cmd) \
  51 { \
  52   int len; \
  53   unsigned char obuf[8]; \
  54   cmd; \
  55   seq_input_event(obuf, len); \
  56 }
  57 #define _seqbuf obuf
  58 #define _seqbufptr 0
  59 #define _SEQ_ADVBUF(x) len=x
  60 
  61 void
  62 do_midi_msg (int synthno, unsigned char *msg, int mlen)
     /* [previous][next][first][last][top][bottom][index][help] */
  63 {
  64   switch (msg[0] & 0xf0)
  65     {
  66     case 0x90:
  67       if (msg[2] != 0)
  68         {
  69           STORE (SEQ_START_NOTE (synthno, msg[0] & 0x0f, msg[1], msg[2]));
  70           break;
  71         }
  72       msg[2] = 64;
  73 
  74     case 0x80:
  75       STORE (SEQ_STOP_NOTE (synthno, msg[0] & 0x0f, msg[1], msg[2]));
  76       break;
  77 
  78     case 0xA0:
  79       STORE (SEQ_KEY_PRESSURE (synthno, msg[0] & 0x0f, msg[1], msg[2]));
  80       break;
  81 
  82     case 0xB0:
  83       STORE (SEQ_CONTROL (synthno, msg[0] & 0x0f,
  84                           msg[1], msg[2]));
  85       break;
  86 
  87     case 0xC0:
  88       STORE (SEQ_SET_PATCH (synthno, msg[0] & 0x0f, msg[1]));
  89       break;
  90 
  91     case 0xD0:
  92       STORE (SEQ_CHN_PRESSURE (synthno, msg[0] & 0x0f, msg[1]));
  93       break;
  94 
  95     case 0xE0:
  96       STORE (SEQ_BENDER (synthno, msg[0] & 0x0f,
  97                          (msg[1] % 0x7f) | ((msg[2] & 0x7f) << 7)));
  98       break;
  99 
 100     default:
 101       /* printk ("MPU: Unknown midi channel message %02x\n", msg[0]); */
 102       ;
 103     }
 104 }
 105 
 106 static void
 107 midi_outc (int midi_dev, int data)
     /* [previous][next][first][last][top][bottom][index][help] */
 108 {
 109   int             timeout;
 110 
 111   for (timeout = 0; timeout < 32000; timeout++)
 112     if (midi_devs[midi_dev]->putc (midi_dev, (unsigned char) (data & 0xff)))
 113       {
 114         if (data & 0x80)        /*
 115                                  * Status byte
 116                                  */
 117           prev_out_status[midi_dev] =
 118             (unsigned char) (data & 0xff);      /*
 119                                                  * Store for running status
 120                                                  */
 121         return;                 /*
 122                                  * Mission complete
 123                                  */
 124       }
 125 
 126   /*
 127    * Sorry! No space on buffers.
 128    */
 129   printk ("Midi send timed out\n");
 130 }
 131 
 132 static int
 133 prefix_cmd (int midi_dev, unsigned char status)
     /* [previous][next][first][last][top][bottom][index][help] */
 134 {
 135   if ((char *) midi_devs[midi_dev]->prefix_cmd == NULL)
 136     return 1;
 137 
 138   return midi_devs[midi_dev]->prefix_cmd (midi_dev, status);
 139 }
 140 
 141 static void
 142 midi_synth_input (int orig_dev, unsigned char data)
     /* [previous][next][first][last][top][bottom][index][help] */
 143 {
 144   int             dev;
 145   struct midi_input_info *inc;
 146 
 147   static unsigned char len_tab[] =      /* # of data bytes following a status
 148                                          */
 149   {
 150     2,                          /* 8x */
 151     2,                          /* 9x */
 152     2,                          /* Ax */
 153     2,                          /* Bx */
 154     1,                          /* Cx */
 155     1,                          /* Dx */
 156     2,                          /* Ex */
 157     0                           /* Fx */
 158   };
 159 
 160   if (orig_dev < 0 || orig_dev > num_midis)
 161     return;
 162 
 163   if (data == 0xfe)             /* Ignore active sensing */
 164     return;
 165 
 166   dev = midi2synth[orig_dev];
 167   inc = &midi_devs[orig_dev]->in_info;
 168 
 169   switch (inc->m_state)
 170     {
 171     case MST_INIT:
 172       if (data & 0x80)          /* MIDI status byte */
 173         {
 174           if ((data & 0xf0) == 0xf0)    /* Common message */
 175             {
 176               switch (data)
 177                 {
 178                 case 0xf0:      /* Sysex */
 179                   inc->m_state = MST_SYSEX;
 180                   break;        /* Sysex */
 181 
 182                 case 0xf1:      /* MTC quarter frame */
 183                 case 0xf3:      /* Song select */
 184                   inc->m_state = MST_DATA;
 185                   inc->m_ptr = 1;
 186                   inc->m_left = 1;
 187                   inc->m_buf[0] = data;
 188                   break;
 189 
 190                 case 0xf2:      /* Song position pointer */
 191                   inc->m_state = MST_DATA;
 192                   inc->m_ptr = 1;
 193                   inc->m_left = 2;
 194                   inc->m_buf[0] = data;
 195                   break;
 196 
 197                 default:
 198                   inc->m_buf[0] = data;
 199                   inc->m_ptr = 1;
 200                   do_midi_msg (dev, inc->m_buf, inc->m_ptr);
 201                   inc->m_ptr = 0;
 202                   inc->m_left = 0;
 203                 }
 204             }
 205           else
 206             {
 207               inc->m_state = MST_DATA;
 208               inc->m_ptr = 1;
 209               inc->m_left = len_tab[(data >> 4) - 8];
 210               inc->m_buf[0] = inc->m_prev_status = data;
 211             }
 212         }
 213       else if (inc->m_prev_status & 0x80)       /* Ignore if no previous status (yet) */
 214         {                       /* Data byte (use running status) */
 215           inc->m_state = MST_DATA;
 216           inc->m_ptr = 2;
 217           inc->m_left = len_tab[(data >> 4) - 8] - 1;
 218           inc->m_buf[0] = inc->m_prev_status;
 219           inc->m_buf[1] = data;
 220         }
 221       break;                    /* MST_INIT */
 222 
 223     case MST_DATA:
 224       inc->m_buf[inc->m_ptr++] = data;
 225       if (--inc->m_left <= 0)
 226         {
 227           inc->m_state = MST_INIT;
 228           do_midi_msg (dev, inc->m_buf, inc->m_ptr);
 229           inc->m_ptr = 0;
 230         }
 231       break;                    /* MST_DATA */
 232 
 233     case MST_SYSEX:
 234       if (data == 0xf7)         /* Sysex end */
 235         {
 236           inc->m_state = MST_INIT;
 237           inc->m_left = 0;
 238           inc->m_ptr = 0;
 239         }
 240       break;                    /* MST_SYSEX */
 241 
 242     default:
 243       printk ("MIDI%d: Unexpected state %d (%02x)\n", orig_dev, inc->m_state,
 244               (int) data);
 245       inc->m_state = MST_INIT;
 246     }
 247 }
 248 
 249 static void
 250 leave_sysex (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 251 {
 252   int             orig_dev = synth_devs[dev]->midi_dev;
 253   int             timeout = 0;
 254 
 255   if (!sysex_state[dev])
 256     return;
 257 
 258   sysex_state[dev] = 0;
 259 
 260   while (!midi_devs[orig_dev]->putc (orig_dev, 0xf7) &&
 261          timeout < 1000)
 262     timeout++;
 263 
 264   sysex_state[dev] = 0;
 265 }
 266 
 267 static void
 268 midi_synth_output (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 269 {
 270   /*
 271    * Currently NOP
 272    */
 273 }
 274 
 275 int
 276 midi_synth_ioctl (int dev,
     /* [previous][next][first][last][top][bottom][index][help] */
 277                   unsigned int cmd, ioctl_arg arg)
 278 {
 279   /*
 280    * int orig_dev = synth_devs[dev]->midi_dev;
 281    */
 282 
 283   switch (cmd)
 284     {
 285 
 286     case SNDCTL_SYNTH_INFO:
 287       memcpy_tofs ((&((char *) arg)[0]), synth_devs[dev]->info, sizeof (struct synth_info));
 288 
 289       return 0;
 290       break;
 291 
 292     case SNDCTL_SYNTH_MEMAVL:
 293       return 0x7fffffff;
 294       break;
 295 
 296     default:
 297       return -EINVAL;
 298     }
 299 }
 300 
 301 int
 302 midi_synth_kill_note (int dev, int channel, int note, int velocity)
     /* [previous][next][first][last][top][bottom][index][help] */
 303 {
 304   int             orig_dev = synth_devs[dev]->midi_dev;
 305   int             msg, chn;
 306 
 307   if (note < 0 || note > 127)
 308     return 0;
 309   if (channel < 0 || channel > 15)
 310     return 0;
 311   if (velocity < 0)
 312     velocity = 0;
 313   if (velocity > 127)
 314     velocity = 127;
 315 
 316   leave_sysex (dev);
 317 
 318   msg = prev_out_status[orig_dev] & 0xf0;
 319   chn = prev_out_status[orig_dev] & 0x0f;
 320 
 321   if (chn == channel && ((msg == 0x90 && velocity == 64) || msg == 0x80))
 322     {                           /*
 323                                  * Use running status
 324                                  */
 325       if (!prefix_cmd (orig_dev, note))
 326         return 0;
 327 
 328       midi_outc (orig_dev, note);
 329 
 330       if (msg == 0x90)          /*
 331                                  * Running status = Note on
 332                                  */
 333         midi_outc (orig_dev, 0);        /*
 334                                            * Note on with velocity 0 == note
 335                                            * off
 336                                          */
 337       else
 338         midi_outc (orig_dev, velocity);
 339     }
 340   else
 341     {
 342       if (velocity == 64)
 343         {
 344           if (!prefix_cmd (orig_dev, 0x90 | (channel & 0x0f)))
 345             return 0;
 346           midi_outc (orig_dev, 0x90 | (channel & 0x0f));        /*
 347                                                                  * Note on
 348                                                                  */
 349           midi_outc (orig_dev, note);
 350           midi_outc (orig_dev, 0);      /*
 351                                          * Zero G
 352                                          */
 353         }
 354       else
 355         {
 356           if (!prefix_cmd (orig_dev, 0x80 | (channel & 0x0f)))
 357             return 0;
 358           midi_outc (orig_dev, 0x80 | (channel & 0x0f));        /*
 359                                                                  * Note off
 360                                                                  */
 361           midi_outc (orig_dev, note);
 362           midi_outc (orig_dev, velocity);
 363         }
 364     }
 365 
 366   return 0;
 367 }
 368 
 369 int
 370 midi_synth_set_instr (int dev, int channel, int instr_no)
     /* [previous][next][first][last][top][bottom][index][help] */
 371 {
 372   int             orig_dev = synth_devs[dev]->midi_dev;
 373 
 374   if (instr_no < 0 || instr_no > 127)
 375     return 0;
 376   if (channel < 0 || channel > 15)
 377     return 0;
 378 
 379   leave_sysex (dev);
 380 
 381   if (!prefix_cmd (orig_dev, 0xc0 | (channel & 0x0f)))
 382     return 0;
 383   midi_outc (orig_dev, 0xc0 | (channel & 0x0f));        /*
 384                                                          * Program change
 385                                                          */
 386   midi_outc (orig_dev, instr_no);
 387 
 388   return 0;
 389 }
 390 
 391 int
 392 midi_synth_start_note (int dev, int channel, int note, int velocity)
     /* [previous][next][first][last][top][bottom][index][help] */
 393 {
 394   int             orig_dev = synth_devs[dev]->midi_dev;
 395   int             msg, chn;
 396 
 397   if (note < 0 || note > 127)
 398     return 0;
 399   if (channel < 0 || channel > 15)
 400     return 0;
 401   if (velocity < 0)
 402     velocity = 0;
 403   if (velocity > 127)
 404     velocity = 127;
 405 
 406   leave_sysex (dev);
 407 
 408   msg = prev_out_status[orig_dev] & 0xf0;
 409   chn = prev_out_status[orig_dev] & 0x0f;
 410 
 411   if (chn == channel && msg == 0x90)
 412     {                           /*
 413                                  * Use running status
 414                                  */
 415       if (!prefix_cmd (orig_dev, note))
 416         return 0;
 417       midi_outc (orig_dev, note);
 418       midi_outc (orig_dev, velocity);
 419     }
 420   else
 421     {
 422       if (!prefix_cmd (orig_dev, 0x90 | (channel & 0x0f)))
 423         return 0;
 424       midi_outc (orig_dev, 0x90 | (channel & 0x0f));    /*
 425                                                          * Note on
 426                                                          */
 427       midi_outc (orig_dev, note);
 428       midi_outc (orig_dev, velocity);
 429     }
 430   return 0;
 431 }
 432 
 433 void
 434 midi_synth_reset (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 435 {
 436 
 437   leave_sysex (dev);
 438 }
 439 
 440 int
 441 midi_synth_open (int dev, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 442 {
 443   int             orig_dev = synth_devs[dev]->midi_dev;
 444   int             err;
 445   unsigned long   flags;
 446   struct midi_input_info *inc;
 447 
 448   if (orig_dev < 0 || orig_dev > num_midis)
 449     return -ENXIO;
 450 
 451   midi2synth[orig_dev] = dev;
 452   sysex_state[dev] = 0;
 453   prev_out_status[orig_dev] = 0;
 454 
 455   if ((err = midi_devs[orig_dev]->open (orig_dev, mode,
 456                                   midi_synth_input, midi_synth_output)) < 0)
 457     return err;
 458 
 459   inc = &midi_devs[orig_dev]->in_info;
 460 
 461   save_flags (flags);
 462   cli ();
 463   inc->m_busy = 0;
 464   inc->m_state = MST_INIT;
 465   inc->m_ptr = 0;
 466   inc->m_left = 0;
 467   inc->m_prev_status = 0x00;
 468   restore_flags (flags);
 469 
 470   return 1;
 471 }
 472 
 473 void
 474 midi_synth_close (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 475 {
 476   int             orig_dev = synth_devs[dev]->midi_dev;
 477 
 478   leave_sysex (dev);
 479 
 480   /*
 481    * Shut up the synths by sending just single active sensing message.
 482    */
 483   midi_devs[orig_dev]->putc (orig_dev, 0xfe);
 484 
 485   midi_devs[orig_dev]->close (orig_dev);
 486 }
 487 
 488 void
 489 midi_synth_hw_control (int dev, unsigned char *event)
     /* [previous][next][first][last][top][bottom][index][help] */
 490 {
 491 }
 492 
 493 int
 494 midi_synth_load_patch (int dev, int format, const snd_rw_buf * addr,
     /* [previous][next][first][last][top][bottom][index][help] */
 495                        int offs, int count, int pmgr_flag)
 496 {
 497   int             orig_dev = synth_devs[dev]->midi_dev;
 498 
 499   struct sysex_info sysex;
 500   int             i;
 501   unsigned long   left, src_offs, eox_seen = 0;
 502   int             first_byte = 1;
 503   int             hdr_size = (unsigned long) &sysex.data[0] - (unsigned long) &sysex;
 504 
 505   leave_sysex (dev);
 506 
 507   if (!prefix_cmd (orig_dev, 0xf0))
 508     return 0;
 509 
 510   if (format != SYSEX_PATCH)
 511     {
 512       printk ("MIDI Error: Invalid patch format (key) 0x%x\n", format);
 513       return -EINVAL;
 514     }
 515 
 516   if (count < hdr_size)
 517     {
 518       printk ("MIDI Error: Patch header too short\n");
 519       return -EINVAL;
 520     }
 521 
 522   count -= hdr_size;
 523 
 524   /*
 525    * Copy the header from user space but ignore the first bytes which have
 526    * been transferred already.
 527    */
 528 
 529   memcpy_fromfs (&((char *) &sysex)[offs], &((addr)[offs]), hdr_size - offs);
 530 
 531   if (count < sysex.len)
 532     {
 533       printk ("MIDI Warning: Sysex record too short (%d<%d)\n",
 534               count, (int) sysex.len);
 535       sysex.len = count;
 536     }
 537 
 538   left = sysex.len;
 539   src_offs = 0;
 540 
 541   {
 542     sysex_sleep_flag.aborting = 0;
 543     sysex_sleep_flag.mode = WK_NONE;
 544   };
 545 
 546   for (i = 0; i < left && !((current->signal & ~current->blocked)); i++)
 547     {
 548       unsigned char   data;
 549 
 550       data = get_fs_byte (&((addr)[hdr_size + i]));
 551 
 552       eox_seen = (i > 0 && data & 0x80);        /* End of sysex */
 553 
 554       if (eox_seen && data != 0xf7)
 555         data = 0xf7;
 556 
 557       if (i == 0)
 558         {
 559           if (data != 0xf0)
 560             {
 561               printk ("Error: Sysex start missing\n");
 562               return -EINVAL;
 563             }
 564         }
 565 
 566       while (!midi_devs[orig_dev]->putc (orig_dev, (unsigned char) (data & 0xff)) &&
 567              !((current->signal & ~current->blocked)))
 568 
 569         {
 570           unsigned long   tl;
 571 
 572           if (1)
 573             tl = current->timeout = jiffies + (1);
 574           else
 575             tl = 0xffffffff;
 576           sysex_sleep_flag.mode = WK_SLEEP;
 577           interruptible_sleep_on (&sysex_sleeper);
 578           if (!(sysex_sleep_flag.mode & WK_WAKEUP))
 579             {
 580               if (current->signal & ~current->blocked)
 581                 sysex_sleep_flag.aborting = 1;
 582               else 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] */