diff options
Diffstat (limited to 'sys/i386/isa/sound/sound_timer.c')
-rw-r--r-- | sys/i386/isa/sound/sound_timer.c | 344 |
1 files changed, 0 insertions, 344 deletions
diff --git a/sys/i386/isa/sound/sound_timer.c b/sys/i386/isa/sound/sound_timer.c deleted file mode 100644 index cef7596..0000000 --- a/sys/i386/isa/sound/sound_timer.c +++ /dev/null @@ -1,344 +0,0 @@ -/* - * sound/sound_timer.c - * - * Copyright by Hannu Savolainen 1993 - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. 2. - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#define SEQUENCER_C -#include <i386/isa/sound/sound_config.h> - -#if NSND > 0 - -#if defined(CONFIG_SEQUENCER) - -static volatile int initialized = 0, opened = 0, tmr_running = 0; -static volatile time_t tmr_offs, tmr_ctr; -static volatile u_long ticks_offs; -static volatile int curr_tempo, curr_timebase; -static volatile u_long curr_ticks; -static volatile u_long next_event_time; -static u_long prev_event_time; -static volatile u_long usecs_per_tmr; /* Length of the current interval */ - -static struct sound_lowlev_timer *tmr = NULL; - -static u_long -tmr2ticks(int tmr_value) -{ - /* - * Convert timer ticks to MIDI ticks - */ - - u_long tmp; - u_long scale; - - tmp = tmr_value * usecs_per_tmr; /* Convert to usecs */ - - scale = (60 * 1000000) / (curr_tempo * curr_timebase); /* usecs per MIDI tick */ - - return (tmp + (scale / 2)) / scale; -} - -static void -reprogram_timer(void) -{ - u_long usecs_per_tick; - - usecs_per_tick = (60 * 1000000) / (curr_tempo * curr_timebase); - - /* - * Don't kill the system by setting too high timer rate - */ - if (usecs_per_tick < 2000) - usecs_per_tick = 2000; - - usecs_per_tmr = tmr->tmr_start(tmr->dev, usecs_per_tick); -} - -void -sound_timer_syncinterval(u_int new_usecs) -{ - /* - * This routine is called by the hardware level if the clock - * frequency has changed for some reason. - */ - tmr_offs = tmr_ctr; - ticks_offs += tmr2ticks(tmr_ctr); - tmr_ctr = 0; - - usecs_per_tmr = new_usecs; -} - -static void -tmr_reset(void) -{ - u_long flags; - - flags = splhigh(); - tmr_offs = 0; - ticks_offs = 0; - tmr_ctr = 0; - next_event_time = 0xffffffff; - prev_event_time = 0; - curr_ticks = 0; - splx(flags); -} - -static int -timer_open(int dev, int mode) -{ - if (opened) - return -(EBUSY); - - tmr_reset(); - curr_tempo = 60; - curr_timebase = hz; - opened = 1; - reprogram_timer(); - - return 0; -} - -static void -timer_close(int dev) -{ - opened = tmr_running = 0; - tmr->tmr_disable(tmr->dev); -} - -static int -timer_event(int dev, u_char *event) -{ - u_char cmd = event[1]; - u_long parm = *(int *) &event[4]; - - switch (cmd) { - case TMR_WAIT_REL: - parm += prev_event_time; - case TMR_WAIT_ABS: - if (parm > 0) { - long time; - - if (parm <= curr_ticks) /* It's the time */ - return TIMER_NOT_ARMED; - - time = parm; - next_event_time = prev_event_time = time; - - return TIMER_ARMED; - } - break; - - case TMR_START: - tmr_reset(); - tmr_running = 1; - reprogram_timer(); - break; - - case TMR_STOP: - tmr_running = 0; - break; - - case TMR_CONTINUE: - tmr_running = 1; - reprogram_timer(); - break; - - case TMR_TEMPO: - if (parm) { - if (parm < 8) - parm = 8; - if (parm > 250) - parm = 250; - tmr_offs = tmr_ctr; - ticks_offs += tmr2ticks(tmr_ctr); - tmr_ctr = 0; - curr_tempo = parm; - reprogram_timer(); - } - break; - - case TMR_ECHO: - seq_copy_to_input(event, 8); - break; - - default:; - } - - return TIMER_NOT_ARMED; -} - -static u_long -timer_get_time(int dev) -{ - if (!opened) - return 0; - - return curr_ticks; -} - -static int -timer_ioctl(int dev, u_int cmd, ioctl_arg arg) -{ - switch (cmd) { - case SNDCTL_TMR_SOURCE: - return *(int *) arg = TMR_INTERNAL; - break; - - case SNDCTL_TMR_START: - tmr_reset(); - tmr_running = 1; - return 0; - break; - - case SNDCTL_TMR_STOP: - tmr_running = 0; - return 0; - break; - - case SNDCTL_TMR_CONTINUE: - tmr_running = 1; - return 0; - break; - - case SNDCTL_TMR_TIMEBASE: - { - int val = (*(int *) arg); - - if (val) { - if (val < 1) - val = 1; - if (val > 1000) - val = 1000; - curr_timebase = val; - } - return *(int *) arg = curr_timebase; - } - break; - - case SNDCTL_TMR_TEMPO: - { - int val = (*(int *) arg); - - if (val) { - if (val < 8) - val = 8; - if (val > 250) - val = 250; - tmr_offs = tmr_ctr; - ticks_offs += tmr2ticks(tmr_ctr); - tmr_ctr = 0; - curr_tempo = val; - reprogram_timer(); - } - return *(int *) arg = curr_tempo; - } - break; - - case SNDCTL_SEQ_CTRLRATE: - if ((*(int *) arg) != 0) /* Can't change */ - return -(EINVAL); - - return *(int *) arg = ((curr_tempo * curr_timebase) + 30) / 60; - break; - - case SNDCTL_TMR_METRONOME: - /* NOP */ - break; - - default:; - } - - return -(EINVAL); -} - -static void -timer_arm(int dev, long time) -{ - if (time < 0) - time = curr_ticks + 1; - else if (time <= curr_ticks) /* It's the time */ - return; - - next_event_time = prev_event_time = time; - - return; -} - -static struct sound_timer_operations sound_timer = -{ - {"GUS Timer", 0}, - 1, /* Priority */ - 0, /* Local device link */ - timer_open, - timer_close, - timer_event, - timer_get_time, - timer_ioctl, - timer_arm -}; - -void -sound_timer_interrupt(void) -{ - if (!opened) - return; - - tmr->tmr_restart(tmr->dev); - - if (!tmr_running) - return; - - tmr_ctr++; - curr_ticks = ticks_offs + tmr2ticks(tmr_ctr); - - if (curr_ticks >= next_event_time) { - next_event_time = 0xffffffff; - sequencer_timer(0); - } -} - -void -sound_timer_init(struct sound_lowlev_timer * t, char *name) -{ - int n; - - if (initialized || t == NULL) - return; /* There is already a similar timer */ - - initialized = 1; - tmr = t; - - if (num_sound_timers >= MAX_TIMER_DEV) - n = 0; /* Overwrite the system timer */ - else - n = num_sound_timers++; - - snprintf(sound_timer.info.name, sizeof(sound_timer.info.name), "%s", name); - - sound_timer_devs[n] = &sound_timer; -} - -#endif -#endif |