patch-2.1.28 linux/drivers/sound/gus_wave.c
Next file: linux/drivers/sound/ics2101.c
Previous file: linux/drivers/sound/gus_vol.c
Back to the patch index
Back to the overall index
- Lines: 558
- Date:
Wed Feb 26 02:35:16 1997
- Orig file:
v2.1.27/linux/drivers/sound/gus_wave.c
- Orig date:
Fri Nov 15 00:15:21 1996
diff -u --recursive --new-file v2.1.27/linux/drivers/sound/gus_wave.c linux/drivers/sound/gus_wave.c
@@ -4,7 +4,7 @@
* Driver for the Gravis UltraSound wave table synth.
*/
/*
- * Copyright (C) by Hannu Savolainen 1993-1996
+ * Copyright (C) by Hannu Savolainen 1993-1997
*
* OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
* Version 2 (June 1991). See the "COPYING" file distributed with this software
@@ -33,6 +33,7 @@
unsigned long orig_freq;
unsigned long current_freq;
unsigned long mode;
+ int fixed_pitch;
int bender;
int bender_range;
int panning;
@@ -128,7 +129,7 @@
extern int *gus_osp;
-struct voice_info voices[32];
+static struct voice_info voices[32];
static int freq_div_table[] =
{
@@ -261,7 +262,7 @@
restore_flags (flags);
}
-unsigned char
+static unsigned char
gus_read8 (int reg)
{ /* Reads from an indirect register (8 bit). Offset 0x80. */
unsigned long flags;
@@ -276,7 +277,7 @@
return val;
}
-unsigned char
+static unsigned char
gus_look8 (int reg)
{ /* Reads from an indirect register (8 bit). No additional offset. */
unsigned long flags;
@@ -291,7 +292,7 @@
return val;
}
-void
+static void
gus_write16 (int reg, unsigned int data)
{ /* Writes to an indirect register (16 bit) */
unsigned long flags;
@@ -307,7 +308,7 @@
restore_flags (flags);
}
-unsigned short
+static unsigned short
gus_read16 (int reg)
{ /* Reads from an indirect register (16 bit). Offset 0x80. */
unsigned long flags;
@@ -326,7 +327,7 @@
return ((hi << 8) & 0xff00) | lo;
}
-unsigned short
+static unsigned short
gus_look16 (int reg)
{ /* Reads from an indirect register (16 bit). No additional offset. */
unsigned long flags;
@@ -345,7 +346,7 @@
return ((hi << 8) & 0xff00) | lo;
}
-void
+static void
gus_write_addr (int reg, unsigned long address, int frac, int is16bit)
{ /* Writes an 24 bit memory address */
unsigned long hold_address;
@@ -541,6 +542,7 @@
voices[voice].patch_vol = 127;
voices[voice].expression_vol = 127;
voices[voice].sample_pending = -1;
+ voices[voice].fixed_pitch = 0;
}
static void
@@ -1107,11 +1109,7 @@
{
case SNDCTL_SYNTH_INFO:
gus_info.nr_voices = nr_voices;
- {
- char *fixit = (char *) &gus_info;
-
- copy_to_user (&((char *) arg)[0], fixit, sizeof (gus_info));
- };
+ memcpy ((&((char *) arg)[0]), (char *) &gus_info, sizeof (gus_info));
return 0;
break;
@@ -1362,7 +1360,7 @@
if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
{
freq = compute_finetune (voices[voice].orig_freq, value,
- voices[voice].bender_range);
+ voices[voice].bender_range, 0);
voices[voice].current_freq = freq;
save_flags (flags);
@@ -1494,10 +1492,17 @@
sample_map[voice] = sample;
- base_note = samples[sample].base_note / 100; /* Try to avoid overflows */
- note_freq /= 100;
+ if (voices[voice].fixed_pitch) /* Fixed pitch */
+ {
+ freq = samples[sample].base_freq;
+ }
+ else
+ {
+ base_note = samples[sample].base_note / 100;
+ note_freq /= 100;
- freq = samples[sample].base_freq * note_freq / base_note;
+ freq = samples[sample].base_freq * note_freq / base_note;
+ }
voices[voice].orig_freq = freq;
@@ -1507,7 +1512,7 @@
*/
freq = compute_finetune (voices[voice].orig_freq, voices[voice].bender,
- voices[voice].bender_range);
+ voices[voice].bender_range, 0);
voices[voice].current_freq = freq;
pan = (samples[sample].panning + voices[voice].panning) / 32;
@@ -1894,7 +1899,6 @@
{
get_user (data, (unsigned char *) &((addr)[sizeof_patch + i]));
if (patch.mode & WAVE_UNSIGNED)
-
if (!(patch.mode & WAVE_16_BITS) || (i & 0x01))
data ^= 0x80; /* Convert to signed */
gus_poke (target + i, data);
@@ -1932,7 +1936,7 @@
address = target;
- if (audio_devs[gus_devnum]->dmachan1 > 3)
+ if (audio_devs[gus_devnum]->dmap_out->dma > 3)
{
hold_address = address;
address = address >> 1;
@@ -1951,7 +1955,7 @@
dma_command |= 0x80; /* Invert MSB */
if (patch.mode & WAVE_16_BITS)
dma_command |= 0x40; /* 16 bit _DATA_ */
- if (audio_devs[gus_devnum]->dmachan1 > 3)
+ if (audio_devs[gus_devnum]->dmap_out->dma > 3)
dma_command |= 0x04; /* 16 bit DMA _channel_ */
gus_write8 (0x41, dma_command); /* Lets go luteet (=bugs) */
@@ -2217,63 +2221,49 @@
}
static int
-gus_audio_ioctl (int dev, unsigned int cmd, caddr_t arg, int local)
+gus_audio_ioctl (int dev, unsigned int cmd, caddr_t arg)
{
int val;
switch (cmd)
{
case SOUND_PCM_WRITE_RATE:
- if (local)
- return gus_audio_set_speed ((int) arg);
- get_user (val, (int *) arg);
- return ioctl_out (arg, gus_audio_set_speed (val));
+ val = *(int *) arg;
+ return (*(int *) arg = gus_audio_set_speed (val));
break;
case SOUND_PCM_READ_RATE:
- if (local)
- return gus_audio_speed;
- return ioctl_out (arg, gus_audio_speed);
+ return (*(int *) arg = gus_audio_speed);
break;
case SNDCTL_DSP_STEREO:
- if (local)
- return gus_audio_set_channels ((int) arg + 1) - 1;
- get_user (val, (int *) arg);
- return ioctl_out (arg, gus_audio_set_channels (val + 1) - 1);
+ val = *(int *) arg;
+ return (*(int *) arg = gus_audio_set_channels (val + 1) - 1);
break;
case SOUND_PCM_WRITE_CHANNELS:
- if (local)
- return gus_audio_set_channels ((int) arg);
- get_user (val, (int *) arg);
- return ioctl_out (arg, gus_audio_set_channels (val));
+ val = *(int *) arg;
+ return (*(int *) arg = gus_audio_set_channels (val));
break;
case SOUND_PCM_READ_CHANNELS:
- if (local)
- return gus_audio_channels;
- return ioctl_out (arg, gus_audio_channels);
+ return (*(int *) arg = gus_audio_channels);
break;
case SNDCTL_DSP_SETFMT:
- if (local)
- return gus_audio_set_bits ((int) arg);
- get_user (val, (int *) arg);
- return ioctl_out (arg, gus_audio_set_bits (val));
+ val = *(int *) arg;
+ return (*(int *) arg = gus_audio_set_bits (val));
break;
case SOUND_PCM_READ_BITS:
- if (local)
- return gus_audio_bits;
- return ioctl_out (arg, gus_audio_bits);
+ return (*(int *) arg = gus_audio_bits);
case SOUND_PCM_WRITE_FILTER: /* NOT POSSIBLE */
- return ioctl_out (arg, -EINVAL);
+ return (*(int *) arg = -EINVAL);
break;
case SOUND_PCM_READ_FILTER:
- return ioctl_out (arg, -EINVAL);
+ return (*(int *) arg = -EINVAL);
break;
}
@@ -2530,7 +2520,7 @@
address = this_one * pcm_bsize;
address += chn * pcm_banksize;
- if (audio_devs[dev]->dmachan1 > 3)
+ if (audio_devs[dev]->dmap_out->dma > 3)
{
hold_address = address;
address = address >> 1;
@@ -2547,7 +2537,7 @@
else
dma_command |= 0x80; /* Invert MSB */
- if (audio_devs[dev]->dmachan1 > 3)
+ if (audio_devs[dev]->dmap_out->dma > 3)
dma_command |= 0x04; /* 16 bit DMA channel */
gus_write8 (0x41, dma_command); /* Kick start */
@@ -2578,7 +2568,7 @@
static void
gus_audio_output_block (int dev, unsigned long buf, int total_count,
- int intrflag, int restart_dma)
+ int intrflag)
{
pcm_current_buf = buf;
pcm_current_count = total_count;
@@ -2589,7 +2579,7 @@
static void
gus_audio_start_input (int dev, unsigned long buf, int count,
- int intrflag, int restart_dma)
+ int intrflag)
{
unsigned long flags;
unsigned char mode;
@@ -2597,11 +2587,11 @@
save_flags (flags);
cli ();
- DMAbuf_start_dma (dev, buf, count, DMA_MODE_READ);
+ /* DMAbuf_start_dma (dev, buf, count, DMA_MODE_READ); */
mode = 0xa0; /* DMA IRQ enabled, invert MSB */
- if (audio_devs[dev]->dmachan2 > 3)
+ if (audio_devs[dev]->dmap_in->dma > 3)
mode |= 0x04; /* 16 bit DMA channel */
if (gus_audio_channels > 1)
mode |= 0x02; /* Stereo */
@@ -2657,6 +2647,7 @@
if (gus_audio_bits != 8 && pcm_banksize == (256 * 1024))
pcm_nblk--;
+ gus_write8 (0x41, 0); /* Disable GF1 DMA */
return 0;
}
@@ -2728,20 +2719,10 @@
gus_audio_prepare_for_input,
gus_audio_prepare_for_output,
gus_audio_reset,
- gus_audio_reset,
gus_local_qlen,
gus_copy_from_user
};
-static struct audio_operations gus_audio_operations =
-{
- "Gravis UltraSound",
- NEEDS_RESTART,
- AFMT_U8 | AFMT_S16_LE,
- NULL,
- &gus_audio_driver
-};
-
static void
guswave_setup_voice (int dev, int voice, int chn)
{
@@ -2756,7 +2737,11 @@
(info->controllers[CTL_MAIN_VOLUME] * 100) / (unsigned) 128;
voices[voice].panning =
(info->controllers[CTL_PAN] * 2) - 128;
- voices[voice].bender = info->bender_value;
+ voices[voice].bender = 0;
+ voices[voice].bender_range = info->bender_range;
+
+ if (chn == 9)
+ voices[voice].fixed_pitch = 1;
}
static void
@@ -2767,7 +2752,7 @@
voices[voice].bender = value - 8192;
freq = compute_finetune (voices[voice].orig_freq, value - 8192,
- voices[voice].bender_range);
+ voices[voice].bender_range, 0);
voices[voice].current_freq = freq;
save_flags (flags);
@@ -2825,6 +2810,7 @@
static struct synth_operations guswave_operations =
{
+ "GUS",
&gus_info,
0,
SYNTH_TYPE_SAMPLE,
@@ -2894,23 +2880,23 @@
SOUND_MASK_SYNTH|SOUND_MASK_PCM)
if (((cmd >> 8) & 0xff) == 'M')
{
- if (_IOC_DIR (cmd) & _IOC_WRITE)
+ if (_SIOC_DIR (cmd) & _SIOC_WRITE)
switch (cmd & 0xff)
{
case SOUND_MIXER_RECSRC:
- get_user (gus_recmask, (int *) arg);
+ gus_recmask = *(int *) arg;
gus_recmask &= MIX_DEVS;
if (!(gus_recmask & (SOUND_MASK_MIC | SOUND_MASK_LINE)))
gus_recmask = SOUND_MASK_MIC;
/* Note! Input volumes are updated during next open for recording */
- return ioctl_out (arg, gus_recmask);
+ return (*(int *) arg = gus_recmask);
break;
case SOUND_MIXER_MIC:
{
int vol;
- get_user (vol, (int *) arg);
+ vol = *(int *) arg;
vol &= 0xff;
if (vol < 0)
@@ -2919,7 +2905,7 @@
vol = 100;
gus_mic_vol = vol;
set_input_volumes ();
- return ioctl_out (arg, vol | (vol << 8));
+ return (*(int *) arg = vol | (vol << 8));
}
break;
@@ -2927,7 +2913,7 @@
{
int vol;
- get_user (vol, (int *) arg);
+ vol = *(int *) arg;
vol &= 0xff;
if (vol < 0)
@@ -2936,26 +2922,26 @@
vol = 100;
gus_line_vol = vol;
set_input_volumes ();
- return ioctl_out (arg, vol | (vol << 8));
+ return (*(int *) arg = vol | (vol << 8));
}
break;
case SOUND_MIXER_PCM:
- get_user (gus_pcm_volume, (int *) arg);
+ gus_pcm_volume = *(int *) arg;
gus_pcm_volume &= 0xff;
if (gus_pcm_volume < 0)
gus_pcm_volume = 0;
if (gus_pcm_volume > 100)
gus_pcm_volume = 100;
gus_audio_update_volume ();
- return ioctl_out (arg, gus_pcm_volume | (gus_pcm_volume << 8));
+ return (*(int *) arg = gus_pcm_volume | (gus_pcm_volume << 8));
break;
case SOUND_MIXER_SYNTH:
{
int voice;
- get_user (gus_wave_volume, (int *) arg);
+ gus_wave_volume = *(int *) arg;
gus_wave_volume &= 0xff;
if (gus_wave_volume < 0)
@@ -2967,7 +2953,7 @@
for (voice = 0; voice < nr_voices; voice++)
dynamic_volume_change (voice); /* Apply the new vol */
- return ioctl_out (arg, gus_wave_volume | (gus_wave_volume << 8));
+ return (*(int *) arg = gus_wave_volume | (gus_wave_volume << 8));
}
break;
@@ -2981,39 +2967,39 @@
{
case SOUND_MIXER_RECSRC:
- return ioctl_out (arg, gus_recmask);
+ return (*(int *) arg = gus_recmask);
break;
case SOUND_MIXER_DEVMASK:
- return ioctl_out (arg, MIX_DEVS);
+ return (*(int *) arg = MIX_DEVS);
break;
case SOUND_MIXER_STEREODEVS:
- return ioctl_out (arg, 0);
+ return (*(int *) arg = 0);
break;
case SOUND_MIXER_RECMASK:
- return ioctl_out (arg, SOUND_MASK_MIC | SOUND_MASK_LINE);
+ return (*(int *) arg = SOUND_MASK_MIC | SOUND_MASK_LINE);
break;
case SOUND_MIXER_CAPS:
- return ioctl_out (arg, 0);
+ return (*(int *) arg = 0);
break;
case SOUND_MIXER_MIC:
- return ioctl_out (arg, gus_mic_vol | (gus_mic_vol << 8));
+ return (*(int *) arg = gus_mic_vol | (gus_mic_vol << 8));
break;
case SOUND_MIXER_LINE:
- return ioctl_out (arg, gus_line_vol | (gus_line_vol << 8));
+ return (*(int *) arg = gus_line_vol | (gus_line_vol << 8));
break;
case SOUND_MIXER_PCM:
- return ioctl_out (arg, gus_pcm_volume | (gus_pcm_volume << 8));
+ return (*(int *) arg = gus_pcm_volume | (gus_pcm_volume << 8));
break;
case SOUND_MIXER_SYNTH:
- return ioctl_out (arg, gus_wave_volume | (gus_wave_volume << 8));
+ return (*(int *) arg = gus_wave_volume | (gus_wave_volume << 8));
break;
default:
@@ -3214,6 +3200,7 @@
samples = (struct patch_info *) (sound_mem_blocks[sound_nblocks] = vmalloc ((MAX_SAMPLE + 1) * sizeof (*samples)));
+ sound_mem_sizes[sound_nblocks] = (MAX_SAMPLE + 1) * sizeof (*samples);
if (sound_nblocks < 1024)
sound_nblocks++;;
if (samples == NULL)
@@ -3224,7 +3211,7 @@
conf_printf (tmp2, hw_config);
tmp2[sizeof (gus_info.name) - 1] = 0;
- strncpy (gus_info.name, tmp2, strlen (tmp2));
+ strcpy (gus_info.name, tmp2);
if (num_synths >= MAX_SYNTH_DEV)
printk ("GUS Error: Too many synthesizers\n");
@@ -3244,15 +3231,23 @@
if (gus_mem_size > 0)
if (num_audiodevs < MAX_AUDIO_DEV)
{
- audio_devs[gus_devnum = num_audiodevs++] = &gus_audio_operations;
- audio_devs[gus_devnum]->dmachan1 = dma;
- audio_devs[gus_devnum]->dmachan2 = dma2;
- audio_devs[gus_devnum]->buffsize = DSP_BUFFSIZE;
+
+ if ((gus_devnum = sound_install_audiodrv (AUDIO_DRIVER_VERSION,
+ "Ultrasound",
+ &gus_audio_driver,
+ sizeof (struct audio_driver),
+ NEEDS_RESTART |
+ ((dma2 != dma && dma2 != -1) ?
+ DMA_DUPLEX : 0),
+ AFMT_U8 | AFMT_S16_LE,
+ NULL,
+ dma,
+ dma2)) < 0)
+ return;
+
audio_devs[gus_devnum]->min_fragment = 9;
audio_devs[gus_devnum]->mixer_dev = num_mixers; /* Next mixer# */
audio_devs[gus_devnum]->flags |= DMA_HARDSTOP;
- if (dma2 != dma && dma2 != -1)
- audio_devs[gus_devnum]->flags |= DMA_DUPLEX;
}
else
printk ("GUS: Too many audio devices available\n");
@@ -3518,12 +3513,14 @@
break;
case GUS_DEV_PCM_CONTINUE: /* Left channel data transferred */
+ gus_write8 (0x41, 0); /* Disable GF1 DMA */
gus_transfer_output_block (pcm_current_dev, pcm_current_buf,
pcm_current_count,
pcm_current_intrflag, 1);
break;
case GUS_DEV_PCM_DONE: /* Right or mono channel data transferred */
+ gus_write8 (0x41, 0); /* Disable GF1 DMA */
if (pcm_qlen < pcm_nblk)
{
int flag = (1 - dma_active) * 2; /* 0 or 2 */
@@ -3641,6 +3638,7 @@
static struct sound_lowlev_timer gus_tmr =
{
0,
+ 1,
gus_tmr_start,
gus_tmr_disable,
gus_tmr_restart
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov