summaryrefslogtreecommitdiffstats
path: root/sys/i386/isa/sound/gus_wave.c
diff options
context:
space:
mode:
authorswallace <swallace@FreeBSD.org>1994-10-01 02:17:17 +0000
committerswallace <swallace@FreeBSD.org>1994-10-01 02:17:17 +0000
commit3b7740a11ff2432cc8bbcfa2524ebc859cc4b643 (patch)
tree09d7913c895c85fdedc9a099ad0b7ac3ee4b3ef1 /sys/i386/isa/sound/gus_wave.c
parentc2da26491490b8f15ad302a5fdf2a9532a07df5d (diff)
downloadFreeBSD-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.c1080
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;
OpenPOWER on IntegriCloud