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 / sys_timer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-18  |  5.9 KB  |  305 lines

  1. /*
  2.  * sound/sys_timer.c
  3.  *
  4.  * The default timer for the Level 2 sequencer interface
  5.  * Uses the (100HZ) timer of kernel.
  6.  *
  7.  * Copyright by Hannu Savolainen 1993
  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.  */
  30.  
  31. #define SEQUENCER_C
  32. #include "sound_config.h"
  33.  
  34. #ifdef CONFIGURE_SOUNDCARD
  35.  
  36. #ifndef EXCLUDE_SEQUENCER
  37.  
  38. static volatile int opened = 0, tmr_running = 0;
  39. static volatile time_t tmr_offs, tmr_ctr;
  40. static volatile unsigned long ticks_offs;
  41. static volatile int curr_tempo, curr_timebase;
  42. static volatile unsigned long curr_ticks;
  43. static volatile unsigned long next_event_time;
  44. static unsigned long prev_event_time;
  45.  
  46. static void     poll_def_tmr (unsigned long dummy);
  47.  
  48. DEFINE_TIMER (def_tmr, poll_def_tmr);
  49.  
  50. static unsigned long
  51. tmr2ticks (int tmr_value)
  52. {
  53.   /*
  54.  *    Convert system timer ticks (HZ) to MIDI ticks
  55.  */
  56.  
  57.   unsigned long   tmp;
  58.   unsigned long   scale;
  59.  
  60.   tmp = (tmr_value * 1000) / HZ;/* Convert to msecs */
  61.  
  62.   scale = (60 * 1000) / (curr_tempo * curr_timebase);    /* msecs per MIDI tick */
  63.  
  64.   return (tmp + (scale / 2)) / scale;
  65. }
  66.  
  67. static void
  68. poll_def_tmr (unsigned long dummy)
  69. {
  70.  
  71.   if (opened)
  72.     {
  73.       ACTIVATE_TIMER (def_tmr, poll_def_tmr, 1);
  74.  
  75.       if (tmr_running)
  76.     {
  77.       tmr_ctr++;
  78.       curr_ticks = ticks_offs + tmr2ticks (tmr_ctr);
  79.  
  80.       if (curr_ticks >= next_event_time)
  81.         {
  82.           next_event_time = 0xffffffff;
  83.           sequencer_timer ();
  84.         }
  85.     }
  86.     }
  87. }
  88.  
  89. static void
  90. tmr_reset (void)
  91. {
  92.   unsigned long   flags;
  93.  
  94.   DISABLE_INTR (flags);
  95.   tmr_offs = 0;
  96.   ticks_offs = 0;
  97.   tmr_ctr = 0;
  98.   next_event_time = 0xffffffff;
  99.   prev_event_time = 0;
  100.   curr_ticks = 0;
  101.   RESTORE_INTR (flags);
  102. }
  103.  
  104. static int
  105. def_tmr_open (int dev, int mode)
  106. {
  107.   if (opened)
  108.     return RET_ERROR (EBUSY);
  109.  
  110.   tmr_reset ();
  111.   curr_tempo = 60;
  112.   curr_timebase = HZ;
  113.   opened = 1;
  114.  
  115.   ACTIVATE_TIMER (def_tmr, poll_def_tmr, 1);
  116.  
  117.   return 0;
  118. }
  119.  
  120. static void
  121. def_tmr_close (int dev)
  122. {
  123.   opened = tmr_running = 0;
  124. }
  125.  
  126. static int
  127. def_tmr_event (int dev, unsigned char *event)
  128. {
  129.   unsigned char   cmd = event[1];
  130.   unsigned long   parm = *(int *) &event[4];
  131.  
  132.   switch (cmd)
  133.     {
  134.     case TMR_WAIT_REL:
  135.       parm += prev_event_time;
  136.     case TMR_WAIT_ABS:
  137.       if (parm > 0)
  138.     {
  139.       long            time;
  140.  
  141.       if (parm <= curr_ticks)    /* It's the time */
  142.         return TIMER_NOT_ARMED;
  143.  
  144.       time = parm;
  145.       next_event_time = prev_event_time = time;
  146.  
  147.       return TIMER_ARMED;
  148.     }
  149.       break;
  150.  
  151.     case TMR_START:
  152.       tmr_reset ();
  153.       tmr_running = 1;
  154.       break;
  155.  
  156.     case TMR_STOP:
  157.       tmr_running = 0;
  158.       break;
  159.  
  160.     case TMR_CONTINUE:
  161.       tmr_running = 1;
  162.       break;
  163.  
  164.     case TMR_TEMPO:
  165.       if (parm)
  166.     {
  167.       if (parm < 8)
  168.         parm = 8;
  169.       if (parm > 250)
  170.         parm = 250;
  171.       tmr_offs = tmr_ctr;
  172.       ticks_offs += tmr2ticks (tmr_ctr);
  173.       tmr_ctr = 0;
  174.       curr_tempo = parm;
  175.     }
  176.       break;
  177.  
  178.     case TMR_ECHO:
  179.       seq_copy_to_input (event, 8);
  180.       break;
  181.  
  182.     default:;
  183.     }
  184.  
  185.   return TIMER_NOT_ARMED;
  186. }
  187.  
  188. static unsigned long
  189. def_tmr_get_time (int dev)
  190. {
  191.   if (!opened)
  192.     return 0;
  193.  
  194.   return curr_ticks;
  195. }
  196.  
  197. static int
  198. def_tmr_ioctl (int dev,
  199.            unsigned int cmd, unsigned int arg)
  200. {
  201.   switch (cmd)
  202.     {
  203.     case SNDCTL_TMR_SOURCE:
  204.       return IOCTL_OUT (arg, TMR_INTERNAL);
  205.       break;
  206.  
  207.     case SNDCTL_TMR_START:
  208.       tmr_reset ();
  209.       tmr_running = 1;
  210.       return 0;
  211.       break;
  212.  
  213.     case SNDCTL_TMR_STOP:
  214.       tmr_running = 0;
  215.       return 0;
  216.       break;
  217.  
  218.     case SNDCTL_TMR_CONTINUE:
  219.       tmr_running = 1;
  220.       return 0;
  221.       break;
  222.  
  223.     case SNDCTL_TMR_TIMEBASE:
  224.       {
  225.     int             val = IOCTL_IN (arg);
  226.  
  227.     if (val)
  228.       {
  229.         if (val < 1)
  230.           val = 1;
  231.         if (val > 1000)
  232.           val = 1000;
  233.         curr_timebase = val;
  234.       }
  235.  
  236.     return IOCTL_OUT (arg, curr_timebase);
  237.       }
  238.       break;
  239.  
  240.     case SNDCTL_TMR_TEMPO:
  241.       {
  242.     int             val = IOCTL_IN (arg);
  243.  
  244.     if (val)
  245.       {
  246.         if (val < 8)
  247.           val = 8;
  248.         if (val > 250)
  249.           val = 250;
  250.         tmr_offs = tmr_ctr;
  251.         ticks_offs += tmr2ticks (tmr_ctr);
  252.         tmr_ctr = 0;
  253.         curr_tempo = val;
  254.       }
  255.  
  256.     return IOCTL_OUT (arg, curr_tempo);
  257.       }
  258.       break;
  259.  
  260.     case SNDCTL_SEQ_CTRLRATE:
  261.       if (IOCTL_IN (arg) != 0)    /* Can't change */
  262.     return RET_ERROR (EINVAL);
  263.  
  264.       return IOCTL_OUT (arg, ((curr_tempo * curr_timebase) + 30) / 60);
  265.       break;
  266.  
  267.     case SNDCTL_TMR_METRONOME:
  268.       /* NOP */
  269.       break;
  270.  
  271.     default:;
  272.     }
  273.  
  274.   return RET_ERROR (EINVAL);
  275. }
  276.  
  277. static void
  278. def_tmr_arm (int dev, long time)
  279. {
  280.   if (time < 0)
  281.     time = curr_ticks + 1;
  282.   else if (time <= curr_ticks)    /* It's the time */
  283.     return;
  284.  
  285.   next_event_time = prev_event_time = time;
  286.  
  287.   return;
  288. }
  289.  
  290. struct sound_timer_operations default_sound_timer =
  291. {
  292.   {"System Timer", 0},
  293.   0,                /* Priority */
  294.   0,                /* Local device link */
  295.   def_tmr_open,
  296.   def_tmr_close,
  297.   def_tmr_event,
  298.   def_tmr_get_time,
  299.   def_tmr_ioctl,
  300.   def_tmr_arm
  301. };
  302.  
  303. #endif
  304. #endif
  305.