diff options
author | swallace <swallace@FreeBSD.org> | 1994-10-01 02:17:17 +0000 |
---|---|---|
committer | swallace <swallace@FreeBSD.org> | 1994-10-01 02:17:17 +0000 |
commit | 3b7740a11ff2432cc8bbcfa2524ebc859cc4b643 (patch) | |
tree | 09d7913c895c85fdedc9a099ad0b7ac3ee4b3ef1 /sys/i386/isa/sound/gus_wave.c | |
parent | c2da26491490b8f15ad302a5fdf2a9532a07df5d (diff) | |
download | FreeBSD-src-3b7740a11ff2432cc8bbcfa2524ebc859cc4b643.zip FreeBSD-src-3b7740a11ff2432cc8bbcfa2524ebc859cc4b643.tar.gz |
Merged in changes to Hannu Savolainen's VoxWare sound drivers, version 2.9.
Diffstat (limited to 'sys/i386/isa/sound/gus_wave.c')
-rw-r--r-- | sys/i386/isa/sound/gus_wave.c | 1080 |
1 files changed, 382 insertions, 698 deletions
diff --git a/sys/i386/isa/sound/gus_wave.c b/sys/i386/isa/sound/gus_wave.c index 621286f..dddb527 100644 --- a/sys/i386/isa/sound/gus_wave.c +++ b/sys/i386/isa/sound/gus_wave.c @@ -3,7 +3,7 @@ * * Driver for the Gravis UltraSound wave table synth. * - * Copyright by Hannu Savolainen 1993 + * Copyright by Hannu Savolainen 1993, 1994 * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: gus_wave.c,v 1.9 1994/08/02 07:40:02 davidg Exp $ */ #include "sound_config.h" @@ -77,23 +77,23 @@ struct voice_info }; +static struct voice_alloc_info *voice_alloc; + extern int gus_base; extern int gus_irq, gus_dma; -extern char *snd_raw_buf[MAX_DSP_DEV][DSP_BUFFCOUNT]; -extern unsigned long snd_raw_buf_phys[MAX_DSP_DEV][DSP_BUFFCOUNT]; -extern int snd_raw_count[MAX_DSP_DEV]; static long gus_mem_size = 0; static long free_mem_ptr = 0; static int gus_busy = 0; static int nr_voices = 0; static int gus_devnum = 0; static int volume_base, volume_scale, volume_method; -static int gus_line_vol = 100, gus_mic_vol = 0; static int gus_recmask = SOUND_MASK_MIC; static int recording_active = 0; int gus_wave_volume = 60; int gus_pcm_volume = 80; +int have_gus_max = 0; +static int gus_line_vol = 100, gus_mic_vol = 0; static unsigned char mix_image = 0x00; /* @@ -102,13 +102,9 @@ static unsigned char mix_image = 0x00; */ static int active_device = 0; -#define GUS_DEV_WAVE 1 /* - * * * Wave table synth */ -#define GUS_DEV_PCM_DONE 2 /* - * * * PCM device, transfer done */ -#define GUS_DEV_PCM_CONTINUE 3 /* - * * * PCM device, transfer the - * second * * * chn */ +#define GUS_DEV_WAVE 1 /* Wave table synth */ +#define GUS_DEV_PCM_DONE 2 /* PCM device, transfer done */ +#define GUS_DEV_PCM_CONTINUE 3 /* PCM device, transfer done ch. 1/2 */ static int gus_sampling_speed; static int gus_sampling_channels; @@ -119,33 +115,13 @@ DEFINE_WAIT_QUEUE (dram_sleeper, dram_sleep_flag); /* * Variables and buffers for PCM output */ -#define MAX_PCM_BUFFERS (32*MAX_REALTIME_FACTOR) /* - * * * Don't - * * * change - * - */ - -static int pcm_bsize, /* - * Current blocksize - */ - pcm_nblk, /* - * Current # of blocks - */ - pcm_banksize; /* - - - * * * * # bytes allocated for channels */ -static int pcm_datasize[MAX_PCM_BUFFERS]; /* +#define MAX_PCM_BUFFERS (32*MAX_REALTIME_FACTOR) /* Don't change */ - - * * * * Actual # of bytes - * in blk * */ -static volatile int pcm_head, pcm_tail, pcm_qlen; /* - - - * * * * DRAM queue - * */ +static int pcm_bsize, pcm_nblk, pcm_banksize; +static int pcm_datasize[MAX_PCM_BUFFERS]; +static volatile int pcm_head, pcm_tail, pcm_qlen; static volatile int pcm_active; +static volatile int dma_active; static int pcm_opened = 0; static int pcm_current_dev; static int pcm_current_block; @@ -157,63 +133,25 @@ struct voice_info voices[32]; static int freq_div_table[] = { - 44100, /* - * 14 - */ - 41160, /* - * 15 - */ - 38587, /* - * 16 - */ - 36317, /* - * 17 - */ - 34300, /* - * 18 - */ - 32494, /* - * 19 - */ - 30870, /* - * 20 - */ - 29400, /* - * 21 - */ - 28063, /* - * 22 - */ - 26843, /* - * 23 - */ - 25725, /* - * 24 - */ - 24696, /* - * 25 - */ - 23746, /* - * 26 - */ - 22866, /* - * 27 - */ - 22050, /* - * 28 - */ - 21289, /* - * 29 - */ - 20580, /* - * 30 - */ - 19916, /* - * 31 - */ - 19293 /* - * 32 - */ + 44100, /* 14 */ + 41160, /* 15 */ + 38587, /* 16 */ + 36317, /* 17 */ + 34300, /* 18 */ + 32494, /* 19 */ + 30870, /* 20 */ + 29400, /* 21 */ + 28063, /* 22 */ + 26843, /* 23 */ + 25725, /* 24 */ + 24696, /* 25 */ + 23746, /* 26 */ + 22866, /* 27 */ + 22050, /* 28 */ + 21289, /* 29 */ + 20580, /* 30 */ + 19916, /* 31 */ + 19293 /* 32 */ }; static struct patch_info *samples; @@ -236,10 +174,8 @@ static void compute_volume (int voice, int volume); static void do_volume_irq (int voice); static void set_input_volumes (void); -#define INSTANT_RAMP -1 /* - * * * Dont use ramping */ -#define FAST_RAMP 0 /* - * * * Fastest possible ramp */ +#define INSTANT_RAMP -1 /* Instant change. No ramping */ +#define FAST_RAMP 0 /* Fastest possible ramp */ static void reset_sample_memory (void) @@ -253,12 +189,10 @@ reset_sample_memory (void) for (i = 0; i < 32; i++) patch_map[i] = -1; - gus_poke (0, 0); /* - * Put silence here - */ + gus_poke (0, 0); /* Put a silent sample to the beginning */ gus_poke (1, 0); - free_mem_ptr = 2; + free_sample = 0; for (i = 0; i < MAX_PATCH; i++) @@ -276,7 +210,7 @@ gus_delay (void) static void gus_poke (long addr, unsigned char data) -{ +{ /* Writes a byte to the DRAM */ unsigned long flags; DISABLE_INTR (flags); @@ -292,7 +226,7 @@ gus_poke (long addr, unsigned char data) static unsigned char gus_peek (long addr) -{ +{ /* Reads a byte from the DRAM */ unsigned long flags; unsigned char tmp; @@ -311,7 +245,7 @@ gus_peek (long addr) void gus_write8 (int reg, unsigned int data) -{ +{ /* Writes to an indirect register (8 bit) */ unsigned long flags; DISABLE_INTR (flags); @@ -324,7 +258,7 @@ gus_write8 (int reg, unsigned int data) unsigned char gus_read8 (int reg) -{ +{ /* Reads from an indirect register (8 bit). Offset 0x80. */ unsigned long flags; unsigned char val; @@ -338,7 +272,7 @@ gus_read8 (int reg) unsigned char gus_look8 (int reg) -{ +{ /* Reads from an indirect register (8 bit). No additional offset. */ unsigned long flags; unsigned char val; @@ -352,7 +286,7 @@ gus_look8 (int reg) void gus_write16 (int reg, unsigned int data) -{ +{ /* Writes to an indirect register (16 bit) */ unsigned long flags; DISABLE_INTR (flags); @@ -367,7 +301,7 @@ gus_write16 (int reg, unsigned int data) unsigned short gus_read16 (int reg) -{ +{ /* Reads from an indirect register (16 bit). Offset 0x80. */ unsigned long flags; unsigned char hi, lo; @@ -385,9 +319,11 @@ gus_read16 (int reg) void gus_write_addr (int reg, unsigned long address, int is16bit) -{ +{ /* Writes an 24 bit memory address */ unsigned long hold_address; + unsigned long flags; + DISABLE_INTR (flags); if (is16bit) { /* @@ -406,6 +342,7 @@ gus_write_addr (int reg, unsigned long address, int is16bit) gus_delay (); gus_write16 (reg, (unsigned short) ((address >> 7) & 0xffff)); gus_write16 (reg + 1, (unsigned short) ((address << 9) & 0xffff)); + RESTORE_INTR (flags); } static void @@ -425,7 +362,7 @@ gus_select_max_voices (int nvoices) if (nvoices > 32) nvoices = 32; - nr_voices = nvoices; + voice_alloc->max_voice = nr_voices = nvoices; gus_write8 (0x0e, (nvoices - 1) | 0xc0); } @@ -449,14 +386,8 @@ gus_voice_mode (unsigned int m) { unsigned char mode = (unsigned char) (m & 0xff); - gus_write8 (0x00, (gus_read8 (0x00) & 0x03) | (mode & 0xfc)); /* - * Don't - * start - * or - * stop - * * - * voice - */ + gus_write8 (0x00, (gus_read8 (0x00) & 0x03) | + (mode & 0xfc)); /* Don't touch last two bits */ gus_delay (); gus_write8 (0x00, (gus_read8 (0x00) & 0x03) | (mode & 0xfc)); } @@ -476,9 +407,7 @@ gus_voice_freq (unsigned long freq) static void gus_voice_volume (unsigned int vol) { - gus_write8 (0x0d, 0x03); /* - * Stop ramp before setting volume - */ + gus_write8 (0x0d, 0x03); /* Stop ramp before setting volume */ gus_write16 (0x09, (unsigned short) (vol << 4)); } @@ -516,14 +445,8 @@ gus_ramp_mode (unsigned int m) { unsigned char mode = (unsigned char) (m & 0xff); - gus_write8 (0x0d, (gus_read8 (0x0d) & 0x03) | (mode & 0xfc)); /* - * Don't - * start - * or - * stop - * * - * ramping - */ + gus_write8 (0x0d, (gus_read8 (0x0d) & 0x03) | + (mode & 0xfc)); /* Leave the last 2 bits alone */ gus_delay (); gus_write8 (0x0d, (gus_read8 (0x0d) & 0x03) | (mode & 0xfc)); } @@ -556,15 +479,10 @@ gus_voice_init (int voice) DISABLE_INTR (flags); gus_select_voice (voice); gus_voice_volume (0); - gus_write_addr (0x0a, 0, 0); /* - * Set current position to 0 - */ - gus_write8 (0x00, 0x03); /* - * Voice off - */ - gus_write8 (0x0d, 0x03); /* - * Ramping off - */ + gus_write_addr (0x0a, 0, 0); /* Set current position to 0 */ + gus_write8 (0x00, 0x03); /* Voice off */ + gus_write8 (0x0d, 0x03); /* Ramping off */ + voice_alloc->map[voice] = 0; RESTORE_INTR (flags); } @@ -604,17 +522,14 @@ step_envelope (int voice) gus_select_voice (voice); gus_rampoff (); RESTORE_INTR (flags); - return; /* - * Sustain - */ - } - - if (voices[voice].env_phase >= 5) - { + return; /* - * Shoot the voice off + * Sustain phase begins. Continue envelope after receiving note off. */ + } + if (voices[voice].env_phase >= 5) + { /* Envelope finished. Shoot the voice down */ gus_voice_init (voice); return; } @@ -631,20 +546,14 @@ step_envelope (int voice) gus_voice_volume (prev_vol); - gus_write8 (0x06, rate); /* - * Ramping rate - */ + gus_write8 (0x06, rate); /* Ramping rate */ voices[voice].volume_irq_mode = VMODE_ENVELOPE; - if (((vol - prev_vol) / 64) == 0) /* - * No significant volume change - */ + if (((vol - prev_vol) / 64) == 0) /* No significant volume change */ { RESTORE_INTR (flags); - step_envelope (voice); /* - * Continue with the next phase - */ + step_envelope (voice); /* Continue the envelope on the next step */ return; } @@ -653,18 +562,14 @@ step_envelope (int voice) if (vol >= (4096 - 64)) vol = 4096 - 65; gus_ramp_range (0, vol); - gus_rampon (0x20); /* - * Increasing, irq - */ + gus_rampon (0x20); /* Increasing volume, with IRQ */ } else { if (vol <= 64) vol = 65; gus_ramp_range (vol, 4030); - gus_rampon (0x60); /* - * Decreasing, irq - */ + gus_rampon (0x60); /* Decreasing volume, with IRQ */ } voices[voice].current_volume = vol; RESTORE_INTR (flags); @@ -683,19 +588,13 @@ static void start_release (int voice, long int flags) { if (gus_read8 (0x00) & 0x03) - return; /* - * Voice already stopped - */ + return; /* Voice already stopped */ - voices[voice].env_phase = 2; /* - * Will be incremented by step_envelope - */ + voices[voice].env_phase = 2; /* Will be incremented by step_envelope */ voices[voice].current_volume = voices[voice].initial_volume = - gus_read16 (0x09) >> 4; /* - * Get current volume - */ + gus_read16 (0x09) >> 4; /* Get current volume */ voices[voice].mode &= ~WAVE_SUSTAIN_ON; gus_rampoff (); @@ -714,18 +613,13 @@ gus_voice_fade (int voice) if (instr_no < 0 || instr_no > MAX_SAMPLE) { - gus_write8 (0x00, 0x03); /* - * Hard stop - */ + gus_write8 (0x00, 0x03); /* Hard stop */ + voice_alloc->map[voice] = 0; RESTORE_INTR (flags); return; } - is16bits = (samples[instr_no].mode & WAVE_16_BITS) ? 1 : 0; /* - * 8 or 16 - * bit - * samples - */ + is16bits = (samples[instr_no].mode & WAVE_16_BITS) ? 1 : 0; /* 8 or 16 bits */ if (voices[voice].mode & WAVE_ENVELOPES) { @@ -736,9 +630,7 @@ gus_voice_fade (int voice) /* * Ramp the volume down but not too quickly. */ - if ((gus_read16 (0x09) >> 4) < 100) /* - * Get current volume - */ + if ((int) (gus_read16 (0x09) >> 4) < 100) /* Get current volume */ { gus_voice_off (); gus_rampoff (); @@ -748,9 +640,7 @@ gus_voice_fade (int voice) gus_ramp_range (65, 4030); gus_ramp_rate (2, 4); - gus_rampon (0x40 | 0x20); /* - * Down, once, irq - */ + gus_rampon (0x40 | 0x20); /* Down, once, with IRQ */ voices[voice].volume_irq_mode = VMODE_HALT; RESTORE_INTR (flags); } @@ -767,25 +657,16 @@ gus_reset (void) for (i = 0; i < 32; i++) { - gus_voice_init (i); /* - * Turn voice off - */ + gus_voice_init (i); /* Turn voice off */ gus_voice_init2 (i); } - INB (u_Status); /* - * Touch the status register - */ + INB (u_Status); /* Touch the status register */ - gus_look8 (0x41); /* - * Clear any pending DMA IRQs - */ - gus_look8 (0x49); /* - * Clear any pending sample IRQs - */ - gus_read8 (0x0f); /* - * Clear pending IRQs - */ + gus_look8 (0x41); /* Clear any pending DMA IRQs */ + gus_look8 (0x49); /* Clear any pending sample IRQs */ + + gus_read8 (0x0f); /* Clear pending IRQs */ } @@ -793,7 +674,7 @@ static void gus_initialize (void) { unsigned long flags; - register unsigned char dma_image, irq_image, tmp; + unsigned char dma_image, irq_image, tmp; static unsigned char gus_irq_map[16] = {0, 0, 1, 3, 0, 2, 0, 4, 0, 0, 0, 5, 6, 0, 0, 7}; @@ -802,16 +683,11 @@ gus_initialize (void) {0, 1, 0, 2, 0, 3, 4, 5}; DISABLE_INTR (flags); - - gus_write8 (0x4c, 0); /* - * Reset GF1 - */ + gus_write8 (0x4c, 0); /* Reset GF1 */ gus_delay (); gus_delay (); - gus_write8 (0x4c, 1); /* - * Release Reset - */ + gus_write8 (0x4c, 1); /* Release Reset */ gus_delay (); gus_delay (); @@ -819,49 +695,25 @@ gus_initialize (void) * Clear all interrupts */ - gus_write8 (0x41, 0); /* - * DMA control - */ - gus_write8 (0x45, 0); /* - * Timer control - */ - gus_write8 (0x49, 0); /* - * Sample control - */ + gus_write8 (0x41, 0); /* DMA control */ + gus_write8 (0x45, 0); /* Timer control */ + gus_write8 (0x49, 0); /* Sample control */ gus_select_max_voices (24); - INB (u_Status); /* - * Touch the status register - */ + INB (u_Status); /* Touch the status register */ - gus_look8 (0x41); /* - * Clear any pending DMA IRQs - */ - gus_look8 (0x49); /* - * Clear any pending sample IRQs - */ - gus_read8 (0x0f); /* - * Clear pending IRQs - */ + gus_look8 (0x41); /* Clear any pending DMA IRQs */ + gus_look8 (0x49); /* Clear any pending sample IRQs */ + gus_read8 (0x0f); /* Clear pending IRQs */ - gus_reset (); /* - * Resets all voices - */ + gus_reset (); /* Resets all voices */ - gus_look8 (0x41); /* - * Clear any pending DMA IRQs - */ - gus_look8 (0x49); /* - * Clear any pending sample IRQs - */ - gus_read8 (0x0f); /* - * Clear pending IRQs - */ + gus_look8 (0x41); /* Clear any pending DMA IRQs */ + gus_look8 (0x49); /* Clear any pending sample IRQs */ + gus_read8 (0x0f); /* Clear pending IRQs */ - gus_write8 (0x4c, 7); /* - * Master reset | DAC enable | IRQ enable - */ + gus_write8 (0x4c, 7); /* Master reset | DAC enable | IRQ enable */ /* * Set up for Digital ASIC @@ -869,9 +721,7 @@ gus_initialize (void) OUTB (0x05, gus_base + 0x0f); - mix_image |= 0x02; /* - * Disable line out - */ + mix_image |= 0x02; /* Disable line out */ OUTB (mix_image, u_Mixer); OUTB (0x00, u_IRQDMAControl); @@ -893,13 +743,9 @@ gus_initialize (void) if (!tmp) printk ("Warning! GUS IRQ not selected\n"); irq_image |= tmp; - irq_image |= 0x40; /* - * Combine IRQ1 (GF1) and IRQ2 (Midi) - */ + irq_image |= 0x40; /* Combine IRQ1 (GF1) and IRQ2 (Midi) */ - dma_image = 0x40; /* - * Combine DMA1 (DRAM) and IRQ2 (ADC) - */ + dma_image = 0x40; /* Combine DMA1 (DRAM) and IRQ2 (ADC) */ tmp = gus_dma_map[gus_dma]; if (!tmp) printk ("Warning! GUS DMA not selected\n"); @@ -913,60 +759,34 @@ gus_initialize (void) * Doing it first time */ - OUTB (mix_image, u_Mixer); /* - * Select DMA control - */ - OUTB (dma_image | 0x80, u_IRQDMAControl); /* - * Set DMA address - */ + OUTB (mix_image, u_Mixer); /* Select DMA control */ + OUTB (dma_image | 0x80, u_IRQDMAControl); /* Set DMA address */ - OUTB (mix_image | 0x40, u_Mixer); /* - * Select IRQ control - */ - OUTB (irq_image, u_IRQDMAControl); /* - * Set IRQ address - */ + OUTB (mix_image | 0x40, u_Mixer); /* Select IRQ control */ + OUTB (irq_image, u_IRQDMAControl); /* Set IRQ address */ /* * Doing it second time */ - OUTB (mix_image, u_Mixer); /* - * Select DMA control - */ - OUTB (dma_image, u_IRQDMAControl); /* - * Set DMA address - */ + OUTB (mix_image, u_Mixer); /* Select DMA control */ + OUTB (dma_image, u_IRQDMAControl); /* Set DMA address */ - OUTB (mix_image | 0x40, u_Mixer); /* - * Select IRQ control - */ - OUTB (irq_image, u_IRQDMAControl); /* - * Set IRQ address - */ + OUTB (mix_image | 0x40, u_Mixer); /* Select IRQ control */ + OUTB (irq_image, u_IRQDMAControl); /* Set IRQ address */ - gus_select_voice (0); /* - * This disables writes to IRQ/DMA reg - */ + gus_select_voice (0); /* This disables writes to IRQ/DMA reg */ - mix_image &= ~0x02; /* - * Enable line out - */ - mix_image |= 0x08; /* - * Enable IRQ - */ + mix_image &= ~0x02; /* Enable line out */ + mix_image |= 0x08; /* Enable IRQ */ OUTB (mix_image, u_Mixer); /* * Turn mixer channels on * Note! Mic in is left off. */ - gus_select_voice (0); /* - * This disables writes to IRQ/DMA reg - */ + gus_select_voice (0); /* This disables writes to IRQ/DMA reg */ - gusintr (0); /* - * Serve pending interrupts - */ + gusintr (0); /* Serve pending interrupts */ RESTORE_INTR (flags); } @@ -1073,16 +893,13 @@ guswave_set_instr (int dev, int voice, int instr_no) if (sample_no < 0) { printk ("GUS: Undefined patch %d for voice %d\n", instr_no, voice); - return RET_ERROR (EINVAL);/* - * Patch not defined - */ + return RET_ERROR (EINVAL);/* Patch not defined */ } - if (sample_ptrs[sample_no] == -1) /* - * Sample not loaded - */ + if (sample_ptrs[sample_no] == -1) /* Sample not loaded */ { - printk ("GUS: Sample #%d not loaded for patch %d (voice %d)\n", sample_no, instr_no, voice); + printk ("GUS: Sample #%d not loaded for patch %d (voice %d)\n", + sample_no, instr_no, voice); return RET_ERROR (EINVAL); } @@ -1092,15 +909,12 @@ guswave_set_instr (int dev, int voice, int instr_no) } static int -#ifdef FUTURE_VERSION guswave_kill_note (int dev, int voice, int note, int velocity) -#else -guswave_kill_note (int dev, int voice, int velocity) -#endif { unsigned long flags; DISABLE_INTR (flags); + voice_alloc->map[voice] = 0xffff; if (voices[voice].volume_irq_mode == VMODE_START_NOTE) { voices[voice].kill_pending = 1; @@ -1121,26 +935,20 @@ guswave_aftertouch (int dev, int voice, int pressure) short lo_limit, hi_limit; unsigned long flags; - return; /* - * Currently disabled - */ + return; /* Procedure currently disabled */ if (voice < 0 || voice > 31) return; if (voices[voice].mode & WAVE_ENVELOPES && voices[voice].env_phase != 2) - return; /* - * Don't mix with envelopes - */ + return; /* Don't mix with envelopes */ if (pressure < 32) { DISABLE_INTR (flags); gus_select_voice (voice); gus_rampoff (); - compute_and_set_volume (voice, 255, 0); /* - * Back to original volume - */ + compute_and_set_volume (voice, 255, 0); /* Back to original volume */ RESTORE_INTR (flags); return; } @@ -1159,9 +967,7 @@ guswave_aftertouch (int dev, int voice, int pressure) } gus_ramp_range (lo_limit, hi_limit); gus_ramp_rate (3, 8); - gus_rampon (0x58); /* - * Bidirectional, Down, Loop - */ + gus_rampon (0x58); /* Bidirectional, dow, loop */ RESTORE_INTR (flags); } @@ -1241,9 +1047,7 @@ compute_and_set_volume (int voice, int volume, int ramp_time) rate = 16; gus_ramp_rate (0, rate); - if ((target - current) / 64 == 0) /* - * Too close - */ + if ((target - current) / 64 == 0) /* Close enough to target. */ { gus_rampoff (); gus_voice_volume (target); @@ -1256,9 +1060,7 @@ compute_and_set_volume (int voice, int volume, int ramp_time) if (target > (4095 - 65)) target = 4095 - 65; gus_ramp_range (current, target); - gus_rampon (0x00); /* - * Ramp up, once, no irq - */ + gus_rampon (0x00); /* Ramp up, once, no IRQ */ } else { @@ -1266,9 +1068,7 @@ compute_and_set_volume (int voice, int volume, int ramp_time) target = 65; gus_ramp_range (target, current); - gus_rampon (0x40); /* - * Ramp down, once, no irq - */ + gus_rampon (0x40); /* Ramp down, once, no irq */ } RESTORE_INTR (flags); } @@ -1281,15 +1081,11 @@ dynamic_volume_change (int voice) DISABLE_INTR (flags); gus_select_voice (voice); - status = gus_read8 (0x00); /* - * Voice status - */ + status = gus_read8 (0x00); /* Get voice status */ RESTORE_INTR (flags); if (status & 0x03) - return; /* - * Voice not started - */ + return; /* Voice was not running */ if (!(voices[voice].mode & WAVE_ENVELOPES)) { @@ -1303,14 +1099,10 @@ dynamic_volume_change (int voice) DISABLE_INTR (flags); gus_select_voice (voice); - status = gus_read8 (0x0d); /* - * Ramping status - */ + status = gus_read8 (0x0d); /* Ramping status */ RESTORE_INTR (flags); - if (status & 0x03) /* - * Sustain phase? - */ + if (status & 0x03) /* Sustain phase? */ { compute_and_set_volume (voice, voices[voice].midi_volume, 1); return; @@ -1321,16 +1113,6 @@ dynamic_volume_change (int voice) compute_volume (voice, voices[voice].midi_volume); -#if 0 /* - * * * Is this really required */ - voices[voice].current_volume = - gus_read16 (0x09) >> 4; /* - * Get current volume - */ - - voices[voice].env_phase--; - step_envelope (voice); -#endif } static void @@ -1349,7 +1131,8 @@ guswave_controller (int dev, int voice, int ctrl_num, int value) if (voices[voice].volume_irq_mode != VMODE_START_NOTE) { - freq = compute_finetune (voices[voice].orig_freq, value, voices[voice].bender_range); + freq = compute_finetune (voices[voice].orig_freq, value, + voices[voice].bender_range); voices[voice].current_freq = freq; DISABLE_INTR (flags); @@ -1362,10 +1145,8 @@ guswave_controller (int dev, int voice, int ctrl_num, int value) case CTRL_PITCH_BENDER_RANGE: voices[voice].bender_range = value; break; -#ifdef FUTURE_VERSION case CTL_EXPRESSION: value /= 128; -#endif case CTRL_EXPRESSION: if (volume_method == VOL_METHOD_ADAGIO) { @@ -1375,14 +1156,12 @@ guswave_controller (int dev, int voice, int ctrl_num, int value) } break; -#ifdef FUTURE_VERSION case CTL_PAN: voices[voice].panning = (value * 2) - 128; break; case CTL_MAIN_VOLUME: value = (value * 100) / 16383; -#endif case CTRL_MAIN_VOLUME: voices[voice].main_vol = value; @@ -1390,9 +1169,7 @@ guswave_controller (int dev, int voice, int ctrl_num, int value) dynamic_volume_change (voice); break; - default: /* - * Ignore - */ + default: break; } } @@ -1454,7 +1231,8 @@ guswave_start_note2 (int dev, int voice, int note_num, int volume) best_sample = samplep; best_delta = delta_freq; } - if (samples[samplep].low_note <= note_freq && note_freq <= samples[samplep].high_note) + if (samples[samplep].low_note <= note_freq && + note_freq <= samples[samplep].high_note) sample = samplep; else samplep = samples[samplep].key; /* @@ -1467,16 +1245,10 @@ guswave_start_note2 (int dev, int voice, int note_num, int volume) if (sample == -1) { printk ("GUS: Patch %d not defined for note %d\n", patch, note_num); - return 0; /* - * Should play default patch ??? - */ + return 0; /* Should play default patch ??? */ } - is16bits = (samples[sample].mode & WAVE_16_BITS) ? 1 : 0; /* - * 8 or 16 - * bit - * samples - */ + is16bits = (samples[sample].mode & WAVE_16_BITS) ? 1 : 0; voices[voice].mode = samples[sample].mode; voices[voice].patch_vol = samples[sample].volume; @@ -1493,9 +1265,7 @@ guswave_start_note2 (int dev, int voice, int note_num, int volume) sample_map[voice] = sample; - base_note = samples[sample].base_note / 100; /* - * To avoid overflows - */ + base_note = samples[sample].base_note / 100; /* Try to avoid overflows */ note_freq /= 100; freq = samples[sample].base_freq * note_freq / base_note; @@ -1507,7 +1277,8 @@ guswave_start_note2 (int dev, int voice, int note_num, int volume) * have to calculate the bending now. */ - freq = compute_finetune (voices[voice].orig_freq, voices[voice].bender, voices[voice].bender_range); + freq = compute_finetune (voices[voice].orig_freq, voices[voice].bender, + voices[voice].bender_range); voices[voice].current_freq = freq; pan = (samples[sample].panning + voices[voice].panning) / 32; @@ -1519,9 +1290,7 @@ guswave_start_note2 (int dev, int voice, int note_num, int volume) if (samples[sample].mode & WAVE_16_BITS) { - mode |= 0x04; /* - * 16 bits - */ + mode |= 0x04; /* 16 bits */ if ((sample_ptrs[sample] >> 18) != ((sample_ptrs[sample] + samples[sample].len) >> 18)) printk ("GUS: Sample address error\n"); @@ -1533,9 +1302,7 @@ guswave_start_note2 (int dev, int voice, int note_num, int volume) DISABLE_INTR (flags); gus_select_voice (voice); - gus_voice_off (); /* - * It may still be running - */ + gus_voice_off (); gus_rampoff (); RESTORE_INTR (flags); @@ -1553,22 +1320,17 @@ guswave_start_note2 (int dev, int voice, int note_num, int volume) if (samples[sample].mode & WAVE_LOOP_BACK) gus_write_addr (0x0a, sample_ptrs[sample] + samples[sample].len - - voices[voice].offset_pending, is16bits); /* Sample - * start=end */ + voices[voice].offset_pending, is16bits); /* start=end */ else gus_write_addr (0x0a, sample_ptrs[sample] + voices[voice].offset_pending, is16bits); /* Sample start=begin */ if (samples[sample].mode & WAVE_LOOPING) { - mode |= 0x08; /* - * Looping on - */ + mode |= 0x08; if (samples[sample].mode & WAVE_BIDIR_LOOP) - mode |= 0x10; /* - * Bidirectional looping on - */ + mode |= 0x10; if (samples[sample].mode & WAVE_LOOP_BACK) { @@ -1578,36 +1340,20 @@ guswave_start_note2 (int dev, int voice, int note_num, int volume) mode |= 0x40; } - gus_write_addr (0x02, sample_ptrs[sample] + samples[sample].loop_start, is16bits); /* - * Loop - * start - * location - */ - gus_write_addr (0x04, sample_ptrs[sample] + samples[sample].loop_end, is16bits); /* - * Loop - * end - * location - */ + gus_write_addr (0x02, sample_ptrs[sample] + samples[sample].loop_start, + is16bits);/* Loop start location */ + gus_write_addr (0x04, sample_ptrs[sample] + samples[sample].loop_end, + is16bits);/* Loop end location */ } else { - mode |= 0x20; /* - * Loop irq at the end - */ - voices[voice].loop_irq_mode = LMODE_FINISH; /* - * Ramp it down at - * the * end - */ + mode |= 0x20; /* Loop IRQ at the end */ + voices[voice].loop_irq_mode = LMODE_FINISH; /* Ramp down at the end */ voices[voice].loop_irq_parm = 1; - gus_write_addr (0x02, sample_ptrs[sample], is16bits); /* - * Loop start - * location - */ - gus_write_addr (0x04, sample_ptrs[sample] + samples[sample].len - 1, is16bits); /* - * Loop - * end - * location - */ + gus_write_addr (0x02, sample_ptrs[sample], + is16bits);/* Loop start location */ + gus_write_addr (0x04, sample_ptrs[sample] + samples[sample].len - 1, + is16bits);/* Loop end location */ } gus_voice_freq (freq); gus_voice_balance (pan); @@ -1618,9 +1364,10 @@ guswave_start_note2 (int dev, int voice, int note_num, int volume) } /* - * * New guswave_start_note by Andrew J. Robinson attempts to minimize - * clicking * when the note playing on the voice is changed. It uses volume - * ramping. */ + * New guswave_start_note by Andrew J. Robinson attempts to minimize clicking + * when the note playing on the voice is changed. It uses volume + * ramping. + */ static int guswave_start_note (int dev, int voice, int note_num, int volume) @@ -1661,7 +1408,7 @@ guswave_start_note (int dev, int voice, int note_num, int volume) DISABLE_INTR (flags); } - if ((mode & 0x01) || ((gus_read16 (0x09) >> 4) < 2065)) + if ((mode & 0x01) || (int) ((gus_read16 (0x09) >> 4) < 2065)) { ret_val = guswave_start_note2 (dev, voice, note_num, volume); } @@ -1704,7 +1451,7 @@ guswave_open (int dev, int mode) gus_initialize (); - if ((err = DMAbuf_open_dma (gus_devnum))) + if ((err = DMAbuf_open_dma (gus_devnum)) < 0) return err; RESET_WAIT_QUEUE (dram_sleeper, dram_sleep_flag); @@ -1736,11 +1483,7 @@ guswave_load_patch (int dev, int format, snd_rw_buf * addr, unsigned long blk_size, blk_end, left, src_offs, target; - sizeof_patch = (long) &patch.data[0] - (long) &patch; /* - * Size of - * the header - * * info - */ + sizeof_patch = (long) &patch.data[0] - (long) &patch; /* Header size */ if (format != GUS_PATCH) { @@ -1805,9 +1548,7 @@ guswave_load_patch (int dev, int format, snd_rw_buf * addr, } } - free_mem_ptr = (free_mem_ptr + 31) & ~31; /* - * Alignment 32 bytes - */ + free_mem_ptr = (free_mem_ptr + 31) & ~31; /* 32 byte alignment */ #define GUS_BANK_SIZE (256*1024) @@ -1825,17 +1566,13 @@ guswave_load_patch (int dev, int format, snd_rw_buf * addr, if ((free_mem_ptr / GUS_BANK_SIZE) != ((free_mem_ptr + patch.len) / GUS_BANK_SIZE)) { - unsigned long tmp_mem = /* - * Align to 256K*N - */ + unsigned long tmp_mem = /* Aling to 256K */ ((free_mem_ptr / GUS_BANK_SIZE) + 1) * GUS_BANK_SIZE; if ((tmp_mem + patch.len) > gus_mem_size) return RET_ERROR (ENOSPC); - free_mem_ptr = tmp_mem; /* - * This leaves unusable memory - */ + free_mem_ptr = tmp_mem; /* This leaves unusable memory */ } } @@ -1868,11 +1605,9 @@ guswave_load_patch (int dev, int format, snd_rw_buf * addr, src_offs = 0; target = free_mem_ptr; - while (left) /* - * Not all moved - */ + while (left) /* Not completely transferred yet */ { - blk_size = sound_buffsizes[gus_devnum]; + blk_size = audio_devs[gus_devnum]->buffsize; if (blk_size > left) blk_size = left; @@ -1882,9 +1617,7 @@ guswave_load_patch (int dev, int format, snd_rw_buf * addr, blk_end = target + blk_size; if ((target >> 18) != (blk_end >> 18)) - { /* - * Have to split the block - */ + { /* Split the block */ blk_end &= ~(256 * 1024 - 1); blk_size = blk_end - target; @@ -1904,14 +1637,11 @@ guswave_load_patch (int dev, int format, snd_rw_buf * addr, if (patch.mode & WAVE_UNSIGNED) if (!(patch.mode & WAVE_16_BITS) || (i & 0x01)) - data ^= 0x80; /* - * Convert to signed - */ + data ^= 0x80; /* Convert to signed */ gus_poke (target + i, data); } } -#else /* - * * * GUS_NO_DMA */ +#else /* GUS_NO_DMA */ { unsigned long address, hold_address; unsigned char dma_command; @@ -1921,15 +1651,14 @@ guswave_load_patch (int dev, int format, snd_rw_buf * addr, * OK, move now. First in and then out. */ - COPY_FROM_USER (snd_raw_buf[gus_devnum][0], + COPY_FROM_USER (audio_devs[gus_devnum]->dmap->raw_buf[0], addr, sizeof_patch + src_offs, blk_size); DISABLE_INTR (flags); /******** INTERRUPTS DISABLED NOW ********/ - gus_write8 (0x41, 0); /* - * Disable GF1 DMA - */ - DMAbuf_start_dma (gus_devnum, snd_raw_buf_phys[gus_devnum][0], + gus_write8 (0x41, 0); /* Disable GF1 DMA */ + DMAbuf_start_dma (gus_devnum, + audio_devs[gus_devnum]->dmap->raw_buf_phys[0], blk_size, DMA_MODE_WRITE); /* @@ -1938,7 +1667,7 @@ guswave_load_patch (int dev, int format, snd_rw_buf * addr, address = target; - if (sound_dsp_dmachan[gus_devnum] > 3) + if (audio_devs[gus_devnum]->dmachan > 3) { hold_address = address; address = address >> 1; @@ -1946,33 +1675,21 @@ guswave_load_patch (int dev, int format, snd_rw_buf * addr, address |= (hold_address & 0x000c0000L); } - gus_write16 (0x42, (address >> 4) & 0xffff); /* - * DRAM DMA address - */ + gus_write16 (0x42, (address >> 4) & 0xffff); /* DRAM DMA address */ /* * Start the DMA transfer */ - dma_command = 0x21; /* - * IRQ enable, DMA start - */ + dma_command = 0x21; /* IRQ enable, DMA start */ if (patch.mode & WAVE_UNSIGNED) - dma_command |= 0x80; /* - * Invert MSB - */ + dma_command |= 0x80; /* Invert MSB */ if (patch.mode & WAVE_16_BITS) - dma_command |= 0x40; /* - * 16 bit _DATA_ - */ - if (sound_dsp_dmachan[gus_devnum] > 3) - dma_command |= 0x04; /* - * 16 bit DMA channel - */ + dma_command |= 0x40; /* 16 bit _DATA_ */ + if (audio_devs[gus_devnum]->dmachan > 3) + dma_command |= 0x04; /* 16 bit DMA _channel_ */ - gus_write8 (0x41, dma_command); /* - * Let's go luteet (=bugs) - */ + gus_write8 (0x41, dma_command); /* Lets bo luteet (=bugs) */ /* * Sleep here until the DRAM DMA done interrupt is served @@ -1984,8 +1701,7 @@ guswave_load_patch (int dev, int format, snd_rw_buf * addr, printk ("GUS: DMA Transfer timed out\n"); RESTORE_INTR (flags); } -#endif /* - * * * GUS_NO_DMA */ +#endif /* GUS_NO_DMA */ /* * Now the next part @@ -1995,9 +1711,7 @@ guswave_load_patch (int dev, int format, snd_rw_buf * addr, src_offs += blk_size; target += blk_size; - gus_write8 (0x41, 0); /* - * Stop DMA - */ + gus_write8 (0x41, 0); /* Stop DMA */ } free_mem_ptr += patch.len; @@ -2042,9 +1756,7 @@ guswave_hw_control (int dev, unsigned char *event) case _GUS_VOICEON: DISABLE_INTR (flags); gus_select_voice (voice); - p1 &= ~0x20; /* - * Disable intr - */ + p1 &= ~0x20; /* Don't allow interrupts */ gus_voice_on (p1); RESTORE_INTR (flags); break; @@ -2063,9 +1775,7 @@ guswave_hw_control (int dev, unsigned char *event) case _GUS_VOICEMODE: DISABLE_INTR (flags); gus_select_voice (voice); - p1 &= ~0x20; /* - * Disable intr - */ + p1 &= ~0x20; /* Don't allow interrupts */ gus_voice_mode (p1); RESTORE_INTR (flags); break; @@ -2091,18 +1801,14 @@ guswave_hw_control (int dev, unsigned char *event) RESTORE_INTR (flags); break; - case _GUS_VOICEVOL2: /* - * Just update the voice value - */ + case _GUS_VOICEVOL2: /* Just update the software voice level */ voices[voice].initial_volume = voices[voice].current_volume = p1; break; case _GUS_RAMPRANGE: if (voices[voice].mode & WAVE_ENVELOPES) - break; /* - * NO-NO - */ + break; /* NO-NO */ DISABLE_INTR (flags); gus_select_voice (voice); gus_ramp_range (p1, p2); @@ -2111,9 +1817,7 @@ guswave_hw_control (int dev, unsigned char *event) case _GUS_RAMPRATE: if (voices[voice].mode & WAVE_ENVELOPES) - break; /* - * NO-NO - */ + break; /* NJET-NJET */ DISABLE_INTR (flags); gus_select_voice (voice); gus_ramp_rate (p1, p2); @@ -2122,37 +1826,27 @@ guswave_hw_control (int dev, unsigned char *event) case _GUS_RAMPMODE: if (voices[voice].mode & WAVE_ENVELOPES) - break; /* - * NO-NO - */ + break; /* NO-NO */ DISABLE_INTR (flags); gus_select_voice (voice); - p1 &= ~0x20; /* - * Disable intr - */ + p1 &= ~0x20; /* Don't allow interrupts */ gus_ramp_mode (p1); RESTORE_INTR (flags); break; case _GUS_RAMPON: if (voices[voice].mode & WAVE_ENVELOPES) - break; /* - * NO-NO - */ + break; /* EI-EI */ DISABLE_INTR (flags); gus_select_voice (voice); - p1 &= ~0x20; /* - * Disable intr - */ + p1 &= ~0x20; /* Don't allow interrupts */ gus_rampon (p1); RESTORE_INTR (flags); break; case _GUS_RAMPOFF: if (voices[voice].mode & WAVE_ENVELOPES) - break; /* - * NO-NO - */ + break; /* NEJ-NEJ */ DISABLE_INTR (flags); gus_select_voice (voice); gus_rampoff (); @@ -2249,7 +1943,7 @@ gus_sampling_ioctl (int dev, unsigned int cmd, unsigned int arg, int local) return IOCTL_OUT (arg, gus_sampling_channels); break; - case SNDCTL_DSP_SAMPLESIZE: + case SNDCTL_DSP_SETFMT: if (local) return gus_sampling_set_bits (arg); return IOCTL_OUT (arg, gus_sampling_set_bits (IOCTL_IN (arg))); @@ -2260,9 +1954,7 @@ gus_sampling_ioctl (int dev, unsigned int cmd, unsigned int arg, int local) return gus_sampling_bits; return IOCTL_OUT (arg, gus_sampling_bits); - case SOUND_PCM_WRITE_FILTER: /* - * NOT YET IMPLEMENTED - */ + case SOUND_PCM_WRITE_FILTER: /* NOT POSSIBLE */ return IOCTL_OUT (arg, RET_ERROR (EINVAL)); break; @@ -2302,6 +1994,7 @@ gus_sampling_open (int dev, int mode) gus_select_max_voices (14); pcm_active = 0; + dma_active = 0; pcm_opened = 1; if (mode & OPEN_READ) { @@ -2361,24 +2054,18 @@ play_next_pcm_block (void) for (chn = 0; chn < gus_sampling_channels; chn++) { mode[chn] = 0x00; - ramp_mode[chn] = 0x03; /* - * Ramping and rollover off - */ + ramp_mode[chn] = 0x03; /* Ramping and rollover off */ if (chn == 0) { - mode[chn] |= 0x20; /* - * Loop irq - */ + mode[chn] |= 0x20; /* Loop IRQ */ voices[chn].loop_irq_mode = LMODE_PCM; } if (gus_sampling_bits != 8) { is16bits = 1; - mode[chn] |= 0x04; /* - * 16 bit data - */ + mode[chn] |= 0x04; /* 16 bit data */ } else is16bits = 0; @@ -2386,23 +2073,15 @@ play_next_pcm_block (void) dram_loc = this_one * pcm_bsize; dram_loc += chn * pcm_banksize; - if (this_one == (pcm_nblk - 1)) /* - * Last of the DRAM buffers - */ + if (this_one == (pcm_nblk - 1)) /* Last fragment of the DRAM buffer */ { - mode[chn] |= 0x08; /* - * Enable loop - */ - ramp_mode[chn] = 0x03;/* - * Disable rollover - */ + mode[chn] |= 0x08; /* Enable loop */ + ramp_mode[chn] = 0x03;/* Disable rollover bit */ } else { if (chn == 0) - ramp_mode[chn] = 0x04; /* - * Enable rollover bit - */ + ramp_mode[chn] = 0x04; /* Enable rollover bit */ } DISABLE_INTR (flags); @@ -2410,21 +2089,13 @@ play_next_pcm_block (void) gus_voice_freq (speed); if (gus_sampling_channels == 1) - gus_voice_balance (7); /* - * mono - */ + gus_voice_balance (7); /* mono */ else if (chn == 0) - gus_voice_balance (0); /* - * left - */ + gus_voice_balance (0); /* left */ else - gus_voice_balance (15); /* - * right - */ + gus_voice_balance (15); /* right */ - if (!pcm_active) /* - * Voice not started yet - */ + if (!pcm_active) /* Playback not already active */ { /* * The playback was not started yet (or there has been a pause). @@ -2433,67 +2104,42 @@ play_next_pcm_block (void) * the normal loop with irq. */ - gus_voice_off (); /* - * It could already be running - */ + gus_voice_off (); gus_rampoff (); gus_voice_volume (1530 + (25 * gus_pcm_volume)); gus_ramp_range (65, 1530 + (25 * gus_pcm_volume)); - gus_write_addr (0x0a, dram_loc, is16bits); /* - * Starting position - */ - gus_write_addr (0x02, chn * pcm_banksize, is16bits); /* - * Loop start - * location - */ + gus_write_addr (0x0a, dram_loc, is16bits); /* Starting position */ + gus_write_addr (0x02, chn * pcm_banksize, is16bits); /* Loop start */ if (chn != 0) gus_write_addr (0x04, pcm_banksize + (pcm_bsize * pcm_nblk), - is16bits); /* - * Loop end location - */ + is16bits); /* Loop end location */ } if (chn == 0) - gus_write_addr (0x04, dram_loc + pcm_datasize[this_one], is16bits); /* - * Loop - * end - * location - */ + gus_write_addr (0x04, dram_loc + pcm_datasize[this_one], + is16bits); /* Loop end location */ else - mode[chn] |= 0x08; /* - * Enable loop - */ + mode[chn] |= 0x08; /* Enable looping */ if (pcm_datasize[this_one] != pcm_bsize) { /* - * Incomplete block. Possibly the last one. + * Incompletely filled block. Possibly the last one. */ if (chn == 0) { - mode[chn] &= ~0x08; /* - * Disable loop - */ - mode[chn] |= 0x20;/* - * Enable loop IRQ - */ + mode[chn] &= ~0x08; /* Disable looping */ + mode[chn] |= 0x20;/* Enable IRQ at the end */ voices[0].loop_irq_mode = LMODE_PCM_STOP; - ramp_mode[chn] = 0x03; /* - * No rollover bit - */ + ramp_mode[chn] = 0x03; /* No rollover bit */ } else { - gus_write_addr (0x04, dram_loc + pcm_datasize[this_one], is16bits); /* - * Loop - * end - * location - */ - mode[chn] &= ~0x08; /* - * Disable loop - */ + gus_write_addr (0x04, dram_loc + pcm_datasize[this_one], + is16bits); /* Loop end location */ + mode[chn] &= ~0x08; /* Disable looping */ } } @@ -2547,15 +2193,13 @@ gus_transfer_output_block (int dev, unsigned long buf, else this_one = pcm_current_block; - gus_write8 (0x41, 0); /* - * Disable GF1 DMA - */ + gus_write8 (0x41, 0); /* Disable GF1 DMA */ DMAbuf_start_dma (dev, buf + (chn * count), count, DMA_MODE_WRITE); address = this_one * pcm_bsize; address += chn * pcm_banksize; - if (sound_dsp_dmachan[dev] > 3) + if (audio_devs[dev]->dmachan > 3) { hold_address = address; address = address >> 1; @@ -2563,49 +2207,40 @@ gus_transfer_output_block (int dev, unsigned long buf, address |= (hold_address & 0x000c0000L); } - gus_write16 (0x42, (address >> 4) & 0xffff); /* - * DRAM DMA address - */ + gus_write16 (0x42, (address >> 4) & 0xffff); /* DRAM DMA address */ - dma_command = 0x21; /* - * IRQ enable, DMA start - */ + dma_command = 0x21; /* IRQ enable, DMA start */ if (gus_sampling_bits != 8) - dma_command |= 0x40; /* - * 16 bit _DATA_ - */ + dma_command |= 0x40; /* 16 bit _DATA_ */ else - dma_command |= 0x80; /* - * Invert MSB - */ + dma_command |= 0x80; /* Invert MSB */ - if (sound_dsp_dmachan[dev] > 3) - dma_command |= 0x04; /* - * 16 bit DMA channel - */ + if (audio_devs[dev]->dmachan > 3) + dma_command |= 0x04; /* 16 bit DMA channel */ - gus_write8 (0x41, dma_command); /* - * Kick on - */ + gus_write8 (0x41, dma_command); /* Kickstart */ - if (chn == (gus_sampling_channels - 1)) /* - * Last channel - */ + if (chn == (gus_sampling_channels - 1)) /* Last channel */ { /* * Last (right or mono) channel data */ + dma_active = 1; /* DMA started. There is a unacknowledged buffer */ active_device = GUS_DEV_PCM_DONE; - if (!pcm_active && (pcm_qlen > 2 || count < pcm_bsize)) + if (!pcm_active && (pcm_qlen > 0 || count < pcm_bsize)) { play_next_pcm_block (); } } - else /* - * * * Left channel data. The right channel - * is * * * transferred after DMA interrupt */ - active_device = GUS_DEV_PCM_CONTINUE; + else + { + /* + * Left channel data. The right channel + * is transferred after DMA interrupt + */ + active_device = GUS_DEV_PCM_CONTINUE; + } RESTORE_INTR (flags); } @@ -2632,21 +2267,13 @@ gus_sampling_start_input (int dev, unsigned long buf, int count, DMAbuf_start_dma (dev, buf, count, DMA_MODE_READ); - mode = 0xa0; /* - * DMA IRQ enable, invert MSB - */ + mode = 0xa0; /* DMA IRQ enabled, invert MSB */ - if (sound_dsp_dmachan[dev] > 3) - mode |= 0x04; /* - * 16 bit DMA channel - */ + if (audio_devs[dev]->dmachan > 3) + mode |= 0x04; /* 16 bit DMA channel */ if (gus_sampling_channels > 1) - mode |= 0x02; /* - * Stereo - */ - mode |= 0x01; /* - * DMA enable - */ + mode |= 0x02; /* Stereo */ + mode |= 0x01; /* DMA enable */ gus_write8 (0x49, mode); @@ -2660,9 +2287,7 @@ gus_sampling_prepare_for_input (int dev, int bsize, int bcount) rate = (9878400 / (gus_sampling_speed + 2)) / 16; - gus_write8 (0x48, rate & 0xff); /* - * Set sampling frequency - */ + gus_write8 (0x48, rate & 0xff); /* Set sampling rate */ if (gus_sampling_bits != 8) { @@ -2705,9 +2330,9 @@ gus_sampling_prepare_for_output (int dev, int bsize, int bcount) } static int -gus_has_output_drained (int dev) +gus_local_qlen (int dev) { - return !pcm_qlen; + return pcm_qlen; } static void @@ -2765,6 +2390,8 @@ static struct audio_operations gus_sampling_operations = { "Gravis UltraSound", NEEDS_RESTART, + AFMT_U8 | AFMT_S16_LE, + NULL, gus_sampling_open, gus_sampling_close, gus_sampling_output_block, @@ -2774,11 +2401,10 @@ static struct audio_operations gus_sampling_operations = gus_sampling_prepare_for_output, gus_sampling_reset, gus_sampling_reset, - gus_has_output_drained, + gus_local_qlen, gus_copy_from_user }; -#ifdef FUTURE_VERSION static void guswave_bender (int dev, int voice, int value) { @@ -2786,7 +2412,8 @@ guswave_bender (int dev, int voice, int value) unsigned long flags; voices[voice].bender = value - 8192; - freq = compute_finetune (voices[voice].orig_freq, value, voices[voice].bender_range); + freq = compute_finetune (voices[voice].orig_freq, value, + voices[voice].bender_range); voices[voice].current_freq = freq; DISABLE_INTR (flags); @@ -2795,8 +2422,6 @@ guswave_bender (int dev, int voice, int value) RESTORE_INTR (flags); } -#endif - static int guswave_patchmgr (int dev, struct patmgr_info *rec) { @@ -2826,9 +2451,7 @@ guswave_patchmgr (int dev, struct patmgr_info *rec) while (ptr >= 0 && ptr < free_sample) { rec->data.data8[i]++; - ptr = samples[ptr].key; /* - * Follow link - */ + ptr = samples[ptr].key; /* Follow link */ } } return 0; @@ -2843,9 +2466,7 @@ guswave_patchmgr (int dev, struct patmgr_info *rec) while (ptr >= 0 && ptr < free_sample) { rec->data.data32[n++] = ptr; - ptr = samples[ptr].key; /* - * Follow link - */ + ptr = samples[ptr].key; /* Follow link */ } } rec->parm1 = n; @@ -2865,12 +2486,8 @@ guswave_patchmgr (int dev, struct patmgr_info *rec) pat = (struct patch_info *) rec->data.data8; - pat->key = GUS_PATCH; /* - * Restore patch type - */ - rec->parm1 = sample_ptrs[ptr]; /* - * DRAM address - */ + pat->key = GUS_PATCH; /* Restore patch type */ + rec->parm1 = sample_ptrs[ptr]; /* DRAM location */ rec->parm2 = sizeof (struct patch_info); } return 0; @@ -2886,14 +2503,10 @@ guswave_patchmgr (int dev, struct patmgr_info *rec) pat = (struct patch_info *) rec->data.data8; - if (pat->len > samples[ptr].len) /* - * Cannot expand sample - */ + if (pat->len > samples[ptr].len) /* Cannot expand sample */ return RET_ERROR (EINVAL); - pat->key = samples[ptr].key; /* - * Ensure the link is correct - */ + pat->key = samples[ptr].key; /* Ensure the link is correct */ memcpy ((char *) &samples[ptr], rec->data.data8, sizeof (struct patch_info)); @@ -2903,9 +2516,7 @@ guswave_patchmgr (int dev, struct patmgr_info *rec) return 0; break; - case PM_READ_PATCH: /* - * Returns a block of wave data from the DRAM - */ + case PM_READ_PATCH: /* Returns a block of wave data from the DRAM */ { int sample = rec->parm1; int n; @@ -2916,13 +2527,9 @@ guswave_patchmgr (int dev, struct patmgr_info *rec) return RET_ERROR (EINVAL); if (offs < 0 || offs >= samples[sample].len) - return RET_ERROR (EINVAL); /* - * Invalid offset - */ + return RET_ERROR (EINVAL); /* Invalid offset */ - n = samples[sample].len - offs; /* - * Nr of bytes left - */ + n = samples[sample].len - offs; /* Num of bytes left */ if (l > n) l = n; @@ -2998,12 +2605,49 @@ guswave_patchmgr (int dev, struct patmgr_info *rec) } } +static int +guswave_alloc (int dev, int chn, int note, struct voice_alloc_info *alloc) +{ + int i, p; + + p = alloc->ptr; + /* + * First look for a completely stopped voice + */ + + for (i = 0; i < alloc->max_voice; i++) + { + if (alloc->map[p] == 0) + { + alloc->ptr = p; + return p; + } + p = (p + 1) % alloc->max_voice; + } + + /* + * Then look for a releasing voice + */ + + for (i = 0; i < alloc->max_voice; i++) + { + if (alloc->map[p] == 0xffff) + { + alloc->ptr = p; + return p; + } + p = (p + 1) % alloc->max_voice; + } + printk ("GUS: Out of free voices\n"); + + alloc->ptr = p; + return p; +} + static struct synth_operations guswave_operations = { &gus_info, -#ifdef FUTURE_VERSION 0, -#endif SYNTH_TYPE_SAMPLE, SAMPLE_TYPE_GUS, guswave_open, @@ -3020,9 +2664,8 @@ static struct synth_operations guswave_operations = guswave_panning, guswave_volume_method, guswave_patchmgr, -#ifdef FUTURE_VERSION - guswave_bender -#endif + guswave_bender, + guswave_alloc }; static void @@ -3130,10 +2773,7 @@ gus_default_mixer_ioctl (int dev, unsigned int cmd, unsigned int arg) if (active_device == GUS_DEV_WAVE) for (voice = 0; voice < nr_voices; voice++) - dynamic_volume_change (voice); /* - * Apply the new - * volume - */ + dynamic_volume_change (voice); /* Apply the new vol */ return IOCTL_OUT (arg, gus_wave_volume | (gus_wave_volume << 8)); } @@ -3229,7 +2869,7 @@ gus_wave_init (long mem_start, int irq, int dma) val = INB (gus_base + 0x0f); RESTORE_INTR (flags); - if (val != 0xff && (val & 0x06)) /* Should be 0x02? */ + if (val != 0xff && (val & 0x06)) /* Should be 0x02?? */ { /* * It has the digital ASIC so the card is at least v3.4. @@ -3263,6 +2903,31 @@ gus_wave_init (long mem_start, int irq, int dma) model_num = "MAX"; gus_type = 0x40; mixer_type = CS4231; +#ifndef EXCLUDE_GUSMAX + { + unsigned char max_config = 0x40; /* Codec enable */ + + if (dma > 3) + max_config |= 0x30; /* 16 bit playback and capture DMAs */ + + max_config |= (gus_base >> 4) & 0x0f; /* Extract the X from 2X0 */ + + OUTB (max_config, gus_base + 0x106); /* UltraMax control */ + } + + if (ad1848_detect (gus_base + 0x10c)) + { + gus_mic_vol = gus_line_vol = gus_pcm_volume = 100; + gus_wave_volume = 90; + have_gus_max = 1; + ad1848_init ("GUS MAX", gus_base + 0x10c, + -irq, + dma, + dma); + } + else + printk ("[Where's the CS4231?]"); +#endif } } else @@ -3278,9 +2943,9 @@ gus_wave_init (long mem_start, int irq, int dma) #ifdef __FreeBSD__ printk ("snd4: <Gravis UltraSound %s (%dk)>", model_num, (int) gus_mem_size / 1024); -#else +#else /* __FreeBSD__ */ printk (" <Gravis UltraSound %s (%dk)>", model_num, (int) gus_mem_size / 1024); -#endif +#endif /* __FreeBSD__ */ #ifndef SCO sprintf (gus_info.name, "Gravis UltraSound %s (%dk)", model_num, (int) gus_mem_size / 1024); @@ -3304,7 +2969,10 @@ gus_wave_init (long mem_start, int irq, int dma) if (num_synths >= MAX_SYNTH_DEV) printk ("GUS Error: Too many synthesizers\n"); else - synth_devs[num_synths++] = &guswave_operations; + { + voice_alloc = &guswave_operations.alloc; + synth_devs[num_synths++] = &guswave_operations; + } PERMANENT_MALLOC (struct patch_info *, samples, (MAX_SAMPLE + 1) * sizeof (*samples), mem_start); @@ -3313,13 +2981,17 @@ gus_wave_init (long mem_start, int irq, int dma) gus_initialize (); - if (num_dspdevs < MAX_DSP_DEV) + if (num_audiodevs < MAX_AUDIO_DEV) { - dsp_devs[gus_devnum = num_dspdevs++] = &gus_sampling_operations; - sound_dsp_dmachan[gus_devnum] = dma; - sound_buffcounts[gus_devnum] = DSP_BUFFCOUNT; - sound_buffsizes[gus_devnum] = DSP_BUFFSIZE; - sound_dma_automode[gus_devnum] = 0; + audio_devs[gus_devnum = num_audiodevs++] = &gus_sampling_operations; + audio_devs[gus_devnum]->dmachan = dma; +#ifndef NO_AUTODMA + audio_devs[gus_devnum]->buffcount = 1; +#else + audio_devs[gus_devnum]->flags &= ~DMA_AUTOMODE; + audio_devs[gus_devnum]->buffcount = DSP_BUFFCOUNT; +#endif + audio_devs[gus_devnum]->buffsize = DSP_BUFFSIZE; } else printk ("GUS: Too many PCM devices available\n"); @@ -3331,11 +3003,12 @@ gus_wave_init (long mem_start, int irq, int dma) switch (mixer_type) { case ICS2101: - gus_line_vol=gus_mic_vol=gus_wave_volume = gus_pcm_volume = 100; + gus_mic_vol = gus_line_vol = gus_pcm_volume = 100; + gus_wave_volume = 90; return ics2101_mixer_init (mem_start); case CS4231: - /* Available soon */ + /* Initialized elsewhere (ad1848.c) */ default: return gus_default_mixer_init (mem_start); } @@ -3370,7 +3043,7 @@ do_loop_irq (int voice) * Final loop finished, shoot volume down */ - if ((gus_read16 (0x09) >> 4) < 100) /* + if ((int) (gus_read16 (0x09) >> 4) < 100) /* * Get current volume */ { @@ -3390,12 +3063,11 @@ do_loop_irq (int voice) break; case LMODE_PCM_STOP: - pcm_active = 0; /* - * Requires extensive processing - */ + pcm_active = 0; /* Signal to the play_next_pcm_block routine */ case LMODE_PCM: { int orig_qlen = pcm_qlen; + int flag; /* 0 or 2 */ pcm_qlen--; pcm_head = (pcm_head + 1) % pcm_nblk; @@ -3404,18 +3076,27 @@ do_loop_irq (int voice) play_next_pcm_block (); } else - { /* - * Out of data. Just stop the voice - */ + { /* Underrun. Just stop the voice */ gus_voice_off (); gus_rampoff (); pcm_active = 0; } - if (orig_qlen == pcm_nblk) + /* + * If the queue was full before this interrupt, the DMA transfer was + * suspended. Let it continue now. + */ + if (dma_active) { - DMAbuf_outputintr (gus_devnum, 0); + if (pcm_qlen == 0) + flag = 1; /* Underflow */ + else + flag = 0; + dma_active = 0; } + else + flag = 2; /* Just notify the dmabuf.c */ + DMAbuf_outputintr (gus_devnum, flag); } break; @@ -3465,7 +3146,9 @@ do_volume_irq (int voice) guswave_start_note2 (voices[voice].dev_pending, voice, voices[voice].note_pending, voices[voice].volume_pending); if (voices[voice].kill_pending) - guswave_kill_note (voices[voice].dev_pending, voice, 0); + guswave_kill_note (voices[voice].dev_pending, voice, + voices[voice].note_pending, 0); + if (voices[voice].sample_pending >= 0) { guswave_set_instr (voices[voice].dev_pending, voice, @@ -3504,7 +3187,7 @@ gus_voice_irq (void) if (!(src & 0x80)) /* * Wave IRQ pending */ - if (!(wave_ignore & voice_bit) && voice < nr_voices) /* + if (!(wave_ignore & voice_bit) && (int) voice < nr_voices) /* * Not done * yet */ @@ -3516,7 +3199,7 @@ gus_voice_irq (void) if (!(src & 0x40)) /* * Volume IRQ pending */ - if (!(volume_ignore & voice_bit) && voice < nr_voices) /* + if (!(volume_ignore & voice_bit) && (int) voice < nr_voices) /* * Not done * yet */ @@ -3532,12 +3215,8 @@ guswave_dma_irq (void) { unsigned char status; - status = gus_look8 (0x41); /* - * Get DMA IRQ Status - */ - if (status & 0x40) /* - * DMA Irq pending - */ + status = gus_look8 (0x41); /* Get DMA IRQ Status */ + if (status & 0x40) /* DMA interrupt pending */ switch (active_device) { case GUS_DEV_WAVE: @@ -3545,16 +3224,21 @@ guswave_dma_irq (void) WAKE_UP (dram_sleeper, dram_sleep_flag); break; - case GUS_DEV_PCM_CONTINUE: + case GUS_DEV_PCM_CONTINUE: /* Left channel data transferred */ gus_transfer_output_block (pcm_current_dev, pcm_current_buf, pcm_current_count, pcm_current_intrflag, 1); break; - case GUS_DEV_PCM_DONE: + case GUS_DEV_PCM_DONE: /* Right or mono channel data transferred */ if (pcm_qlen < pcm_nblk) { - DMAbuf_outputintr (gus_devnum, pcm_qlen == 0); + int flag = (1 - dma_active) * 2; /* 0 or 2 */ + + if (pcm_qlen == 0) + flag = 1; /* Underrun */ + dma_active = 0; + DMAbuf_outputintr (gus_devnum, flag); } break; |