home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.2 / LINUX-1.2 / LINUX-1 / linux / drivers / sound / midi_synth.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-18  |  10.5 KB  |  475 lines

  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. #include "sound_config.h"
  31.  
  32. #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_MIDI)
  33.  
  34. #define _MIDI_SYNTH_C_
  35.  
  36. DEFINE_WAIT_QUEUE (sysex_sleeper, sysex_sleep_flag);
  37.  
  38. #include "midi_synth.h"
  39.  
  40. static int      midi2synth[MAX_MIDI_DEV];
  41. static unsigned char prev_out_status[MAX_MIDI_DEV];
  42.  
  43. static void
  44. midi_outc (int midi_dev, int data)
  45. {
  46.   int             timeout;
  47.  
  48.   for (timeout = 0; timeout < 32000; timeout++)
  49.     if (midi_devs[midi_dev]->putc (midi_dev, (unsigned char) (data & 0xff)))
  50.       {
  51.     if (data & 0x80)    /*
  52.                  * Status byte
  53.                  */
  54.       prev_out_status[midi_dev] =
  55.         (unsigned char) (data & 0xff);    /*
  56.                          * Store for running status
  57.                          */
  58.     return;            /*
  59.                  * Mission complete
  60.                  */
  61.       }
  62.  
  63.   /*
  64.    * Sorry! No space on buffers.
  65.    */
  66.   printk ("Midi send timed out\n");
  67. }
  68.  
  69. static int
  70. prefix_cmd (int midi_dev, unsigned char status)
  71. {
  72.   if (midi_devs[midi_dev]->prefix_cmd == NULL)
  73.     return 1;
  74.  
  75.   return midi_devs[midi_dev]->prefix_cmd (midi_dev, status);
  76. }
  77.  
  78. static void
  79. midi_synth_input (int dev, unsigned char data)
  80. {
  81.   int             orig_dev;
  82.  
  83.   if (dev < 0 || dev > num_synths)
  84.     return;
  85.  
  86.   if (data == 0xfe)        /* Ignore active sensing */
  87.     return;
  88.  
  89.   orig_dev = midi2synth[dev];
  90.  
  91. }
  92.  
  93. static void
  94. midi_synth_output (int dev)
  95. {
  96.   /*
  97.    * Currently NOP
  98.    */
  99. }
  100.  
  101. int
  102. midi_synth_ioctl (int dev,
  103.           unsigned int cmd, unsigned int arg)
  104. {
  105.   /*
  106.    * int orig_dev = synth_devs[dev]->midi_dev;
  107.    */
  108.  
  109.   switch (cmd)
  110.     {
  111.  
  112.     case SNDCTL_SYNTH_INFO:
  113.       IOCTL_TO_USER ((char *) arg, 0, synth_devs[dev]->info,
  114.              sizeof (struct synth_info));
  115.  
  116.       return 0;
  117.       break;
  118.  
  119.     case SNDCTL_SYNTH_MEMAVL:
  120.       return 0x7fffffff;
  121.       break;
  122.  
  123.     default:
  124.       return RET_ERROR (EINVAL);
  125.     }
  126. }
  127.  
  128. int
  129. midi_synth_kill_note (int dev, int channel, int note, int velocity)
  130. {
  131.   int             orig_dev = synth_devs[dev]->midi_dev;
  132.   int             msg, chn;
  133.  
  134.   if (note < 0 || note > 127)
  135.     return 0;
  136.   if (channel < 0 || channel > 15)
  137.     return 0;
  138.   if (velocity < 0)
  139.     velocity = 0;
  140.   if (velocity > 127)
  141.     velocity = 127;
  142.  
  143.   msg = prev_out_status[orig_dev] & 0xf0;
  144.   chn = prev_out_status[orig_dev] & 0x0f;
  145.  
  146.   if (chn == channel && ((msg == 0x90 && velocity == 64) || msg == 0x80))
  147.     {                /*
  148.                  * Use running status
  149.                  */
  150.       if (!prefix_cmd (orig_dev, note))
  151.     return 0;
  152.  
  153.       midi_outc (orig_dev, note);
  154.  
  155.       if (msg == 0x90)        /*
  156.                  * Running status = Note on
  157.                  */
  158.     midi_outc (orig_dev, 0);/*
  159.                      * Note on with velocity 0 == note
  160.                      * off
  161.                      */
  162.       else
  163.     midi_outc (orig_dev, velocity);
  164.     }
  165.   else
  166.     {
  167.       if (velocity == 64)
  168.     {
  169.       if (!prefix_cmd (orig_dev, 0x90 | (channel & 0x0f)))
  170.         return 0;
  171.       midi_outc (orig_dev, 0x90 | (channel & 0x0f));    /*
  172.                                  * Note on
  173.                                  */
  174.       midi_outc (orig_dev, note);
  175.       midi_outc (orig_dev, 0);    /*
  176.                      * Zero G
  177.                      */
  178.     }
  179.       else
  180.     {
  181.       if (!prefix_cmd (orig_dev, 0x80 | (channel & 0x0f)))
  182.         return 0;
  183.       midi_outc (orig_dev, 0x80 | (channel & 0x0f));    /*
  184.                                  * Note off
  185.                                  */
  186.       midi_outc (orig_dev, note);
  187.       midi_outc (orig_dev, velocity);
  188.     }
  189.     }
  190.  
  191.   return 0;
  192. }
  193.  
  194. int
  195. midi_synth_set_instr (int dev, int channel, int instr_no)
  196. {
  197.   int             orig_dev = synth_devs[dev]->midi_dev;
  198.  
  199.   if (instr_no < 0 || instr_no > 127)
  200.     return 0;
  201.   if (channel < 0 || channel > 15)
  202.     return 0;
  203.  
  204.   if (!prefix_cmd (orig_dev, 0xc0 | (channel & 0x0f)))
  205.     return 0;
  206.   midi_outc (orig_dev, 0xc0 | (channel & 0x0f));    /*
  207.                              * Program change
  208.                              */
  209.   midi_outc (orig_dev, instr_no);
  210.  
  211.   return 0;
  212. }
  213.  
  214. int
  215. midi_synth_start_note (int dev, int channel, int note, int velocity)
  216. {
  217.   int             orig_dev = synth_devs[dev]->midi_dev;
  218.   int             msg, chn;
  219.  
  220.   if (note < 0 || note > 127)
  221.     return 0;
  222.   if (channel < 0 || channel > 15)
  223.     return 0;
  224.   if (velocity < 0)
  225.     velocity = 0;
  226.   if (velocity > 127)
  227.     velocity = 127;
  228.  
  229.   msg = prev_out_status[orig_dev] & 0xf0;
  230.   chn = prev_out_status[orig_dev] & 0x0f;
  231.  
  232.   if (chn == channel && msg == 0x90)
  233.     {                /*
  234.                  * Use running status
  235.                  */
  236.       if (!prefix_cmd (orig_dev, note))
  237.     return 0;
  238.       midi_outc (orig_dev, note);
  239.       midi_outc (orig_dev, velocity);
  240.     }
  241.   else
  242.     {
  243.       if (!prefix_cmd (orig_dev, 0x90 | (channel & 0x0f)))
  244.     return 0;
  245.       midi_outc (orig_dev, 0x90 | (channel & 0x0f));    /*
  246.                              * Note on
  247.                              */
  248.       midi_outc (orig_dev, note);
  249.       midi_outc (orig_dev, velocity);
  250.     }
  251.   return 0;
  252. }
  253.  
  254. void
  255. midi_synth_reset (int dev)
  256. {
  257. }
  258.  
  259. int
  260. midi_synth_open (int dev, int mode)
  261. {
  262.   int             orig_dev = synth_devs[dev]->midi_dev;
  263.   int             err;
  264.  
  265.   if (orig_dev < 0 || orig_dev > num_midis)
  266.     return RET_ERROR (ENXIO);
  267.  
  268.   midi2synth[orig_dev] = dev;
  269.   prev_out_status[orig_dev] = 0;
  270.  
  271.   if ((err = midi_devs[orig_dev]->open (orig_dev, mode,
  272.                   midi_synth_input, midi_synth_output)) < 0)
  273.     return err;
  274.  
  275.   return 1;
  276. }
  277.  
  278. void
  279. midi_synth_close (int dev)
  280. {
  281.   int             orig_dev = synth_devs[dev]->midi_dev;
  282.  
  283.   /*
  284.  * Shut up the synths by sending just single active sensing message.
  285.  */
  286.   midi_devs[orig_dev]->putc (orig_dev, 0xfe);
  287.  
  288.   midi_devs[orig_dev]->close (orig_dev);
  289. }
  290.  
  291. void
  292. midi_synth_hw_control (int dev, unsigned char *event)
  293. {
  294. }
  295.  
  296. int
  297. midi_synth_load_patch (int dev, int format, snd_rw_buf * addr,
  298.                int offs, int count, int pmgr_flag)
  299. {
  300.   int             orig_dev = synth_devs[dev]->midi_dev;
  301.  
  302.   struct sysex_info sysex;
  303.   int             i;
  304.   unsigned long   left, src_offs, eox_seen = 0;
  305.   int             first_byte = 1;
  306.  
  307.   if (!prefix_cmd (orig_dev, 0xf0))
  308.     return 0;
  309.  
  310.   if (format != SYSEX_PATCH)
  311.     {
  312.       printk ("MIDI Error: Invalid patch format (key) 0x%x\n", format);
  313.       return RET_ERROR (EINVAL);
  314.     }
  315.  
  316.   if (count < sizeof (struct sysex_info))
  317.     {
  318.       printk ("MIDI Error: Patch header too short\n");
  319.       return RET_ERROR (EINVAL);
  320.     }
  321.  
  322.   count -= sizeof (struct sysex_info);
  323.  
  324.   /*
  325.    * Copy the header from user space but ignore the first bytes which have
  326.    * been transferred already.
  327.    */
  328.  
  329.   COPY_FROM_USER (&((char *) &sysex)[offs], addr, offs, sizeof (struct sysex_info) - offs);
  330.  
  331.   if (count < sysex.len)
  332.     {
  333.       printk ("MIDI Warning: Sysex record too short (%d<%d)\n",
  334.           count, (int) sysex.len);
  335.       sysex.len = count;
  336.     }
  337.  
  338.   left = sysex.len;
  339.   src_offs = 0;
  340.  
  341.   RESET_WAIT_QUEUE (sysex_sleeper, sysex_sleep_flag);
  342.  
  343.   for (i = 0; i < left && !PROCESS_ABORTING (sysex_sleeper, sysex_sleep_flag); i++)
  344.     {
  345.       unsigned char   data;
  346.  
  347.       GET_BYTE_FROM_USER (data, addr, sizeof (struct sysex_info) + i);
  348.  
  349.       if (first_byte && data != 0xf0)
  350.     midi_outc (orig_dev, 0xf0);    /* Sysex start */
  351.  
  352.       eox_seen = (data == 0xf7);/*
  353.                      * Last byte was end of sysex
  354.                      */
  355.  
  356.       if (i == 0)
  357.     {
  358.       if (data != 0xf0)    /*
  359.                  * Sysex start
  360.                  */
  361.         return RET_ERROR (EINVAL);
  362.     }
  363.  
  364.       while (!midi_devs[orig_dev]->putc (orig_dev, (unsigned char) (data & 0xff)) &&
  365.          !PROCESS_ABORTING (sysex_sleeper, sysex_sleep_flag))
  366.     DO_SLEEP (sysex_sleeper, sysex_sleep_flag, 1);    /* Wait for timeout */
  367.  
  368.       if (!first_byte && data & 0x80)
  369.     return 0;
  370.       first_byte = 0;
  371.     }
  372.  
  373.   if (!eox_seen)
  374.     midi_outc (orig_dev, 0xf7);
  375.   return 0;
  376. }
  377.  
  378. void
  379. midi_synth_panning (int dev, int channel, int pressure)
  380. {
  381. }
  382.  
  383. void
  384. midi_synth_aftertouch (int dev, int channel, int pressure)
  385. {
  386.   int             orig_dev = synth_devs[dev]->midi_dev;
  387.   int             msg, chn;
  388.  
  389.   if (pressure < 0 || pressure > 127)
  390.     return;
  391.   if (channel < 0 || channel > 15)
  392.     return;
  393.  
  394.   msg = prev_out_status[orig_dev] & 0xf0;
  395.   chn = prev_out_status[orig_dev] & 0x0f;
  396.  
  397.   if (msg != 0xd0 || chn != channel)    /*
  398.                      * Test for running status
  399.                      */
  400.     {
  401.       if (!prefix_cmd (orig_dev, 0xd0 | (channel & 0x0f)))
  402.     return;
  403.       midi_outc (orig_dev, 0xd0 | (channel & 0x0f));    /*
  404.                              * Channel pressure
  405.                              */
  406.     }
  407.   else if (!prefix_cmd (orig_dev, pressure))
  408.     return;
  409.   midi_outc (orig_dev, pressure);
  410. }
  411.  
  412. void
  413. midi_synth_controller (int dev, int channel, int ctrl_num, int value)
  414. {
  415.   int             orig_dev = synth_devs[dev]->midi_dev;
  416.   int             chn, msg;
  417.  
  418.   if (ctrl_num < 1 || ctrl_num > 127)
  419.     return;            /* NOTE! Controller # 0 ignored */
  420.   if (channel < 0 || channel > 15)
  421.     return;
  422.  
  423.   msg = prev_out_status[orig_dev] & 0xf0;
  424.   chn = prev_out_status[orig_dev] & 0x0f;
  425.  
  426.   if (msg != 0xb0 || chn != channel)
  427.     {
  428.       if (!prefix_cmd (orig_dev, 0xb0 | (channel & 0x0f)))
  429.     return;
  430.       midi_outc (orig_dev, 0xb0 | (channel & 0x0f));
  431.     }
  432.   else if (!prefix_cmd (orig_dev, ctrl_num))
  433.     return;
  434.  
  435.   midi_outc (orig_dev, ctrl_num);
  436.   midi_outc (orig_dev, value & 0x7f);
  437. }
  438.  
  439. int
  440. midi_synth_patchmgr (int dev, struct patmgr_info *rec)
  441. {
  442.   return RET_ERROR (EINVAL);
  443. }
  444.  
  445. void
  446. midi_synth_bender (int dev, int channel, int value)
  447. {
  448.   int             orig_dev = synth_devs[dev]->midi_dev;
  449.   int             msg, prev_chn;
  450.  
  451.   if (channel < 0 || channel > 15)
  452.     return;
  453.  
  454.   if (value < 0 || value > 16383)
  455.     return;
  456.  
  457.   msg = prev_out_status[orig_dev] & 0xf0;
  458.   prev_chn = prev_out_status[orig_dev] & 0x0f;
  459.  
  460.   if (msg != 0xd0 || prev_chn != channel)    /*
  461.                          * * Test for running status  */
  462.     {
  463.       if (!prefix_cmd (orig_dev, 0xe0 | (channel & 0x0f)))
  464.     return;
  465.       midi_outc (orig_dev, 0xe0 | (channel & 0x0f));
  466.     }
  467.   else if (!prefix_cmd (orig_dev, value & 0x7f))
  468.     return;
  469.  
  470.   midi_outc (orig_dev, value & 0x7f);
  471.   midi_outc (orig_dev, (value >> 7) & 0x7f);
  472. }
  473.  
  474. #endif
  475.