* sound update causes artsd to fail/abort initialization
@ 2003-08-04 12:52 Mike Galbraith
0 siblings, 0 replies; only message in thread
From: Mike Galbraith @ 2003-08-04 12:52 UTC (permalink / raw)
To: linux kernel mailing list; +Cc: perex, alsa-devel
[-- Attachment #1: Type: text/plain, Size: 909 bytes --]
Greetings,
While testing 2.6.0-test2-mm3-1, I ran into a problem with artsd failing
during X/KDE startup, leaving an error message "cpu overload,
aborting". It takes about 20 seconds to fail, and after X finally does
come up, all seems well with the exception of artsd being AWOL. (I don't
know what artsd has to do with sound, but whatever it is, it doesn't seem
to be terribly important, because xmms seems to work fine without
it) After the initial failure, dropping back to the shell and restarting
X/KDE _usually_ results in artsd starting just fine, though once in a while
I'll get the same hang and failure that I always get the first time around.
Using the "brute-ignorance" method (pick something at random, patch -R it),
I narrowed it down a little. Exactly what I reverted is attached for
reference. Box is a piii/500 with an onboard ymf-740c, and I'm using oss
emulation.
-Mike
[-- Attachment #2: xx.diff --]
[-- Type: application/octet-stream, Size: 21499 bytes --]
diff -Nru a/include/sound/pcm_oss.h b/include/sound/pcm_oss.h
--- a/include/sound/pcm_oss.h Sat Aug 2 12:16:34 2003
+++ b/include/sound/pcm_oss.h Sat Aug 2 12:16:34 2003
@@ -30,7 +30,9 @@
unsigned int disable:1,
direct:1,
block:1,
- nonblock:1;
+ nonblock:1,
+ wholefrag:1,
+ nosilence:1;
unsigned int periods;
unsigned int period_size;
snd_pcm_oss_setup_t *next;
diff -Nru a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
--- a/sound/core/oss/pcm_oss.c Sat Aug 2 12:16:35 2003
+++ b/sound/core/oss/pcm_oss.c Sat Aug 2 12:16:35 2003
@@ -22,6 +22,9 @@
#if 0
#define PLUGIN_DEBUG
#endif
+#if 0
+#define OSS_DEBUG
+#endif
#include <sound/driver.h>
#include <linux/version.h>
@@ -442,7 +445,7 @@
} else {
sw_params->start_threshold = runtime->boundary;
}
- if (atomic_read(&runtime->mmap_count))
+ if (atomic_read(&runtime->mmap_count) || substream->stream == SNDRV_PCM_STREAM_CAPTURE)
sw_params->stop_threshold = runtime->boundary;
else
sw_params->stop_threshold = runtime->buffer_size;
@@ -451,8 +454,18 @@
sw_params->sleep_min = 0;
sw_params->avail_min = runtime->period_size;
sw_params->xfer_align = 1;
- sw_params->silence_threshold = 0;
- sw_params->silence_size = 0;
+ if (atomic_read(&runtime->mmap_count) ||
+ (substream->oss.setup && substream->oss.setup->nosilence)) {
+ sw_params->silence_threshold = 0;
+ sw_params->silence_size = 0;
+ } else {
+ snd_pcm_uframes_t frames;
+ frames = runtime->period_size + 16;
+ if (frames > runtime->buffer_size)
+ frames = runtime->buffer_size;
+ sw_params->silence_threshold = frames;
+ sw_params->silence_size = frames;
+ }
if ((err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_SW_PARAMS, sw_params)) < 0) {
snd_printd("SW_PARAMS failed: %i\n", err);
@@ -567,6 +580,31 @@
return 0;
}
+static int snd_pcm_oss_capture_position_fixup(snd_pcm_substream_t *substream, snd_pcm_sframes_t *delay)
+{
+ snd_pcm_runtime_t *runtime;
+ snd_pcm_uframes_t frames;
+ int err = 0;
+
+ while (1) {
+ err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DELAY, delay);
+ if (err < 0)
+ break;
+ runtime = substream->runtime;
+ if (*delay <= (snd_pcm_sframes_t)runtime->buffer_size)
+ break;
+ /* in case of overrun, skip whole periods like OSS/Linux driver does */
+ /* until avail(delay) <= buffer_size */
+ frames = (*delay - runtime->buffer_size) + runtime->period_size - 1;
+ frames /= runtime->period_size;
+ frames *= runtime->period_size;
+ err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_FORWARD, &frames);
+ if (err < 0)
+ break;
+ }
+ return err;
+}
+
snd_pcm_sframes_t snd_pcm_oss_write3(snd_pcm_substream_t *substream, const char *ptr, snd_pcm_uframes_t frames, int in_kernel)
{
snd_pcm_runtime_t *runtime = substream->runtime;
@@ -574,6 +612,12 @@
while (1) {
if (runtime->status->state == SNDRV_PCM_STATE_XRUN ||
runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
+#ifdef OSS_DEBUG
+ if (runtime->status->state == SNDRV_PCM_STATE_XRUN)
+ printk("pcm_oss: write: recovering from XRUN\n");
+ else
+ printk("pcm_oss: write: recovering from SUSPEND\n");
+#endif
ret = snd_pcm_oss_prepare(substream);
if (ret < 0)
break;
@@ -599,10 +643,17 @@
snd_pcm_sframes_t snd_pcm_oss_read3(snd_pcm_substream_t *substream, char *ptr, snd_pcm_uframes_t frames, int in_kernel)
{
snd_pcm_runtime_t *runtime = substream->runtime;
+ snd_pcm_sframes_t delay;
int ret;
while (1) {
if (runtime->status->state == SNDRV_PCM_STATE_XRUN ||
runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
+#ifdef OSS_DEBUG
+ if (runtime->status->state == SNDRV_PCM_STATE_XRUN)
+ printk("pcm_oss: read: recovering from XRUN\n");
+ else
+ printk("pcm_oss: read: recovering from SUSPEND\n");
+#endif
ret = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, 0);
if (ret < 0)
break;
@@ -611,6 +662,9 @@
if (ret < 0)
break;
}
+ ret = snd_pcm_oss_capture_position_fixup(substream, &delay);
+ if (ret < 0)
+ break;
if (in_kernel) {
mm_segment_t fs;
fs = snd_enter_user();
@@ -640,6 +694,12 @@
while (1) {
if (runtime->status->state == SNDRV_PCM_STATE_XRUN ||
runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
+#ifdef OSS_DEBUG
+ if (runtime->status->state == SNDRV_PCM_STATE_XRUN)
+ printk("pcm_oss: writev: recovering from XRUN\n");
+ else
+ printk("pcm_oss: writev: recovering from SUSPEND\n");
+#endif
ret = snd_pcm_oss_prepare(substream);
if (ret < 0)
break;
@@ -670,6 +730,12 @@
while (1) {
if (runtime->status->state == SNDRV_PCM_STATE_XRUN ||
runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
+#ifdef OSS_DEBUG
+ if (runtime->status->state == SNDRV_PCM_STATE_XRUN)
+ printk("pcm_oss: readv: recovering from XRUN\n");
+ else
+ printk("pcm_oss: readv: recovering from SUSPEND\n");
+#endif
ret = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, 0);
if (ret < 0)
break;
@@ -746,8 +812,9 @@
buf += tmp;
bytes -= tmp;
xfer += tmp;
- if (runtime->oss.buffer_used == runtime->oss.period_bytes) {
- tmp = snd_pcm_oss_write2(substream, runtime->oss.buffer, runtime->oss.period_bytes, 1);
+ if (substream->oss.setup == NULL || !substream->oss.setup->wholefrag ||
+ runtime->oss.buffer_used == runtime->oss.period_bytes) {
+ tmp = snd_pcm_oss_write2(substream, runtime->oss.buffer, runtime->oss.buffer_used, 1);
if (tmp <= 0)
return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
runtime->oss.bytes += tmp;
@@ -855,6 +922,22 @@
return 0;
}
+static int snd_pcm_oss_post(snd_pcm_oss_file_t *pcm_oss_file)
+{
+ snd_pcm_substream_t *substream;
+ int err;
+
+ substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
+ if (substream != NULL) {
+ if ((err = snd_pcm_oss_make_ready(substream)) < 0)
+ return err;
+ snd_pcm_kernel_playback_ioctl(substream, SNDRV_PCM_IOCTL_START, 0);
+ }
+ /* note: all errors from the start action are ignored */
+ /* OSS apps do not know, how to handle them */
+ return 0;
+}
+
static int snd_pcm_oss_sync(snd_pcm_oss_file_t *pcm_oss_file)
{
int err = 0;
@@ -1188,6 +1271,10 @@
snd_pcm_runtime_t *runtime;
snd_pcm_substream_t *psubstream = NULL, *csubstream = NULL;
int err, cmd;
+
+#ifdef OSS_DEBUG
+ printk("pcm_oss: trigger = 0x%x\n", trigger);
+#endif
psubstream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
csubstream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
@@ -1288,7 +1375,7 @@
{
snd_pcm_substream_t *substream;
snd_pcm_runtime_t *runtime;
- snd_pcm_status_t status;
+ snd_pcm_sframes_t delay;
struct count_info info;
int err;
@@ -1306,14 +1393,17 @@
return -EFAULT;
return 0;
}
- memset(&status, 0, sizeof(status));
- err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_STATUS, &status);
+ if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DELAY, &delay);
+ } else {
+ err = snd_pcm_oss_capture_position_fixup(substream, &delay);
+ }
if (err < 0)
return err;
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
- info.bytes = runtime->oss.bytes - snd_pcm_oss_bytes(substream, runtime->buffer_size - status.avail);
+ info.bytes = runtime->oss.bytes - snd_pcm_oss_bytes(substream, delay);
} else {
- info.bytes = runtime->oss.bytes + snd_pcm_oss_bytes(substream, status.avail);
+ info.bytes = runtime->oss.bytes + snd_pcm_oss_bytes(substream, delay);
}
info.ptr = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr % runtime->buffer_size);
if (atomic_read(&runtime->mmap_count)) {
@@ -1326,10 +1416,7 @@
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
snd_pcm_oss_simulate_fill(substream);
} else {
- if (stream == SNDRV_PCM_STREAM_PLAYBACK)
- info.blocks = (runtime->buffer_size - status.avail) / runtime->period_size;
- else
- info.blocks = status.avail / runtime->period_size;
+ info.blocks = delay / runtime->period_size;
}
if (copy_to_user(_info, &info, sizeof(info)))
return -EFAULT;
@@ -1340,7 +1427,7 @@
{
snd_pcm_substream_t *substream;
snd_pcm_runtime_t *runtime;
- snd_pcm_status_t status;
+ snd_pcm_sframes_t avail;
struct audio_buf_info info;
int err;
@@ -1357,7 +1444,6 @@
info.fragsize = runtime->oss.period_bytes;
info.fragstotal = runtime->periods;
- memset(&status, 0, sizeof(status));
if (runtime->oss.prepare) {
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
info.bytes = runtime->oss.period_bytes * runtime->periods;
@@ -1367,21 +1453,21 @@
info.fragments = 0;
}
} else {
- err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_STATUS, &status);
+ if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DELAY, &avail);
+ avail = runtime->buffer_size - avail;
+ } else {
+ err = snd_pcm_oss_capture_position_fixup(substream, &avail);
+ }
if (err < 0)
return err;
- info.bytes = snd_pcm_oss_bytes(substream, status.avail);
- info.fragments = status.avail / runtime->period_size;
+ info.bytes = snd_pcm_oss_bytes(substream, avail);
+ info.fragments = avail / runtime->period_size;
}
-#if 0
- /* very experimental stuff to get Quake2 working */
- runtime->oss.period = (info.periods - 1) << 16;
- for (tmp = info.fragsize; tmp > 1; tmp >>= 1)
- runtime->oss.period++;
- runtime->oss.subdivision = 1; /* disable SUBDIVIDE */
+#ifdef OSS_DEBUG
+ printk("pcm_oss: space: bytes = %i, fragments = %i, fragstotal = %i, fragsize = %i\n", info.bytes, info.fragments, info.fragstotal, info.fragsize);
#endif
- // printk("space: bytes = %i, periods = %i, fragstotal = %i, fragsize = %i\n", info.bytes, info.periods, info.fragstotal, info.fragsize);
if (copy_to_user(_info, &info, sizeof(info)))
return -EFAULT;
return 0;
@@ -1727,6 +1813,9 @@
#endif
if (((cmd >> 8) & 0xff) != 'P')
return -EINVAL;
+#ifdef OSS_DEBUG
+ printk("pcm_oss: ioctl = 0x%x\n", cmd);
+#endif
switch (cmd) {
case SNDCTL_DSP_RESET:
return snd_pcm_oss_reset(pcm_oss_file);
@@ -1782,8 +1871,8 @@
case SOUND_PCM_WRITE_FILTER:
case SOUND_PCM_READ_FILTER:
return -EIO;
- case SNDCTL_DSP_POST: /* to do */
- return 0;
+ case SNDCTL_DSP_POST:
+ return snd_pcm_oss_post(pcm_oss_file);
case SNDCTL_DSP_SUBDIVIDE:
if (get_user(res, (int *)arg))
return -EFAULT;
@@ -1866,7 +1955,15 @@
substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
if (substream == NULL)
return -ENXIO;
+#ifndef OSS_DEBUG
return snd_pcm_oss_read1(substream, buf, count);
+#else
+ {
+ ssize_t res = snd_pcm_oss_read1(substream, buf, count);
+ printk("pcm_oss: read %li bytes (returned %li bytes)\n", (long)count, (long)res);
+ return res;
+ }
+#endif
}
static ssize_t snd_pcm_oss_write(struct file *file, const char *buf, size_t count, loff_t *offset)
@@ -1882,6 +1979,9 @@
up(&file->f_dentry->d_inode->i_sem);
result = snd_pcm_oss_write1(substream, buf, count);
down(&file->f_dentry->d_inode->i_sem);
+#ifdef OSS_DEBUG
+ printk("pcm_oss: write %li bytes (wrote %li bytes)\n", (long)count, (long)result);
+#endif
return result;
}
@@ -1927,12 +2027,20 @@
}
if (csubstream != NULL) {
snd_pcm_runtime_t *runtime = csubstream->runtime;
+ enum sndrv_pcm_state ostate;
poll_wait(file, &runtime->sleep, wait);
snd_pcm_stream_lock_irq(csubstream);
- if (runtime->status->state != SNDRV_PCM_STATE_RUNNING ||
+ if ((ostate = runtime->status->state) != SNDRV_PCM_STATE_RUNNING ||
snd_pcm_oss_capture_ready(csubstream))
mask |= POLLIN | POLLRDNORM;
snd_pcm_stream_unlock_irq(csubstream);
+ if (ostate != SNDRV_PCM_STATE_RUNNING && runtime->oss.trigger) {
+ snd_pcm_oss_file_t ofile;
+ memset(&ofile, 0, sizeof(ofile));
+ ofile.streams[SNDRV_PCM_STREAM_CAPTURE] = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
+ runtime->oss.trigger = 0;
+ snd_pcm_oss_set_trigger(&ofile, PCM_ENABLE_INPUT);
+ }
}
return mask;
@@ -1945,6 +2053,9 @@
snd_pcm_runtime_t *runtime;
int err;
+#ifdef OSS_DEBUG
+ printk("pcm_oss: mmap begin\n");
+#endif
pcm_oss_file = snd_magic_cast(snd_pcm_oss_file_t, file->private_data, return -ENXIO);
switch ((area->vm_flags & (VM_READ | VM_WRITE))) {
case VM_READ | VM_WRITE:
@@ -1988,6 +2099,9 @@
if (err < 0)
return err;
runtime->oss.mmap_bytes = area->vm_end - area->vm_start;
+#ifdef OSS_DEBUG
+ printk("pcm_oss: mmap ok, bytes = 0x%x\n", runtime->oss.mmap_bytes);
+#endif
/* In mmap mode we never stop */
runtime->stop_threshold = runtime->boundary;
@@ -2005,14 +2119,16 @@
snd_pcm_oss_setup_t *setup = pstr->oss.setup_list;
down(&pstr->oss.setup_mutex);
while (setup) {
- snd_iprintf(buffer, "%s %u %u%s%s%s%s\n",
+ snd_iprintf(buffer, "%s %u %u%s%s%s%s%s%s\n",
setup->task_name,
setup->periods,
setup->period_size,
setup->disable ? " disable" : "",
setup->direct ? " direct" : "",
setup->block ? " block" : "",
- setup->nonblock ? " non-block" : "");
+ setup->nonblock ? " non-block" : "",
+ setup->wholefrag ? " whole-frag" : "",
+ setup->nosilence ? " no-silence" : "");
setup = setup->next;
}
up(&pstr->oss.setup_mutex);
@@ -2078,6 +2194,10 @@
template.block = 1;
} else if (!strcmp(str, "non-block")) {
template.nonblock = 1;
+ } else if (!strcmp(str, "whole-frag")) {
+ template.wholefrag = 1;
+ } else if (!strcmp(str, "no-silence")) {
+ template.nosilence = 1;
}
} while (*str);
if (setup == NULL) {
@@ -2269,3 +2389,24 @@
module_init(alsa_pcm_oss_init)
module_exit(alsa_pcm_oss_exit)
+
+#ifndef MODULE
+
+/* format is: snd-pcm-oss=dsp_map,adsp_map[,nonblock_open] */
+
+static int __init alsa_pcm_oss_setup(char *str)
+{
+ static unsigned __initdata nr_dev = 0;
+
+ if (nr_dev >= SNDRV_CARDS)
+ return 0;
+ (void)(get_option(&str,&dsp_map[nr_dev]) == 2 &&
+ get_option(&str,&adsp_map[nr_dev]) == 2);
+ (void)(get_option(&str,&nonblock_open) == 2);
+ nr_dev++;
+ return 1;
+}
+
+__setup("snd-pcm-oss=", alsa_pcm_oss_setup);
+
+#endif /* !MODULE */
diff -Nru a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c
--- a/sound/core/oss/pcm_plugin.c Sat Aug 2 12:16:31 2003
+++ b/sound/core/oss/pcm_plugin.c Sat Aug 2 12:16:31 2003
@@ -56,6 +56,17 @@
return 0;
}
+/*
+ * because some cards might have rates "very close", we ignore
+ * all "resampling" requests within +-5%
+ */
+static int rate_match(unsigned int src_rate, unsigned int dst_rate)
+{
+ unsigned int low = (src_rate * 95) / 100;
+ unsigned int high = (src_rate * 105) / 100;
+ return dst_rate >= low && dst_rate <= high;
+}
+
static int snd_pcm_plugin_alloc(snd_pcm_plugin_t *plugin, snd_pcm_uframes_t frames)
{
snd_pcm_plugin_format_t *format;
@@ -80,11 +91,14 @@
plugin->buf = vmalloc(size);
plugin->buf_frames = frames;
}
- if (!plugin->buf)
+ if (!plugin->buf) {
+ plugin->buf_frames = 0;
return -ENOMEM;
+ }
c = plugin->buf_channels;
if (plugin->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED) {
for (channel = 0; channel < format->channels; channel++, c++) {
+ c->frames = frames;
c->enabled = 1;
c->wanted = 0;
c->area.addr = plugin->buf;
@@ -95,6 +109,7 @@
snd_assert((size % format->channels) == 0,);
size /= format->channels;
for (channel = 0; channel < format->channels; channel++, c++) {
+ c->frames = frames;
c->enabled = 1;
c->wanted = 0;
c->area.addr = plugin->buf + (channel * size);
@@ -420,7 +435,7 @@
/* Format change (linearization) */
if ((srcformat.format != dstformat.format ||
- srcformat.rate != dstformat.rate ||
+ !rate_match(srcformat.rate, dstformat.rate) ||
srcformat.channels != dstformat.channels) &&
!snd_pcm_format_linear(srcformat.format)) {
if (snd_pcm_format_linear(dstformat.format))
@@ -468,7 +483,7 @@
ttable[v * sv + v] = FULL;
}
tmpformat.channels = dstformat.channels;
- if (srcformat.rate == dstformat.rate &&
+ if (rate_match(srcformat.rate, dstformat.rate) &&
snd_pcm_format_linear(dstformat.format))
tmpformat.format = dstformat.format;
err = snd_pcm_plugin_build_route(plug,
@@ -490,7 +505,7 @@
}
/* rate resampling */
- if (srcformat.rate != dstformat.rate) {
+ if (!rate_match(srcformat.rate, dstformat.rate)) {
tmpformat.rate = dstformat.rate;
if (srcformat.channels == dstformat.channels &&
snd_pcm_format_linear(dstformat.format))
diff -Nru a/sound/core/oss/pcm_plugin.h b/sound/core/oss/pcm_plugin.h
--- a/sound/core/oss/pcm_plugin.h Sat Aug 2 12:16:35 2003
+++ b/sound/core/oss/pcm_plugin.h Sat Aug 2 12:16:35 2003
@@ -106,6 +106,7 @@
typedef struct _snd_pcm_plugin_channel {
void *aptr; /* pointer to the allocated area */
snd_pcm_channel_area_t area;
+ snd_pcm_uframes_t frames; /* allocated frames */
unsigned int enabled:1; /* channel need to be processed */
unsigned int wanted:1; /* channel is wanted */
} snd_pcm_plugin_channel_t;
diff -Nru a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
--- a/sound/core/pcm_lib.c Sat Aug 2 12:16:31 2003
+++ b/sound/core/pcm_lib.c Sat Aug 2 12:16:31 2003
@@ -60,7 +60,7 @@
return;
snd_assert(runtime->silence_filled <= runtime->buffer_size, return);
noise_dist = snd_pcm_playback_hw_avail(runtime) + runtime->silence_filled;
- if (noise_dist > (snd_pcm_sframes_t) runtime->silence_threshold)
+ if (noise_dist >= (snd_pcm_sframes_t) runtime->silence_threshold)
return;
frames = runtime->silence_threshold - noise_dist;
if (frames > runtime->silence_size)
@@ -84,10 +84,9 @@
if ((snd_pcm_sframes_t)runtime->silence_start < 0)
runtime->silence_start += runtime->boundary;
}
- frames = runtime->buffer_size;
+ frames = runtime->buffer_size - runtime->silence_filled;
}
- snd_assert(frames >= runtime->silence_filled, return);
- frames -= runtime->silence_filled;
+ snd_assert(frames <= runtime->buffer_size, return);
if (frames == 0)
return;
ofs = (runtime->silence_start + runtime->silence_filled) % runtime->buffer_size;
@@ -1932,7 +1931,7 @@
if (runtime->silence_size >= runtime->boundary) {
frames = 1;
} else if (runtime->silence_size > 0 &&
- runtime->silence_filled < runtime->buffer_size) {
+ runtime->silence_filled < runtime->buffer_size) {
snd_pcm_sframes_t noise_dist;
noise_dist = snd_pcm_playback_hw_avail(runtime) + runtime->silence_filled;
snd_assert(noise_dist <= (snd_pcm_sframes_t)runtime->silence_threshold, );
diff -Nru a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c
--- a/sound/core/pcm_memory.c Sat Aug 2 12:16:34 2003
+++ b/sound/core/pcm_memory.c Sat Aug 2 12:16:34 2003
@@ -22,6 +22,7 @@
#include <sound/driver.h>
#include <asm/io.h>
#include <linux/time.h>
+#include <linux/init.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/info.h>
@@ -568,3 +569,18 @@
}
#endif /* CONFIG_PCI */
+
+#ifndef MODULE
+
+/* format is: snd-pcm=preallocate_dma,maximum_substreams */
+
+static int __init alsa_pcm_setup(char *str)
+{
+ (void)(get_option(&str,&preallocate_dma) == 2 &&
+ get_option(&str,&maximum_substreams) == 2);
+ return 1;
+}
+
+__setup("snd-pcm=", alsa_pcm_setup);
+
+#endif /* ifndef MODULE */
diff -Nru a/sound/core/pcm_native.c b/sound/core/pcm_native.c
--- a/sound/core/pcm_native.c Sat Aug 2 12:16:31 2003
+++ b/sound/core/pcm_native.c Sat Aug 2 12:16:31 2003
@@ -461,9 +461,15 @@
if (params->xfer_align == 0 ||
params->xfer_align % runtime->min_align != 0)
return -EINVAL;
- if ((params->silence_threshold != 0 || params->silence_size < runtime->boundary) &&
- (params->silence_threshold + params->silence_size > runtime->buffer_size))
- return -EINVAL;
+ if (params->silence_size >= runtime->boundary) {
+ if (params->silence_threshold != 0)
+ return -EINVAL;
+ } else {
+ if (params->silence_size > params->silence_threshold)
+ return -EINVAL;
+ if (params->silence_threshold > runtime->buffer_size)
+ return -EINVAL;
+ }
snd_pcm_stream_lock_irq(substream);
runtime->tstamp_mode = params->tstamp_mode;
runtime->sleep_min = params->sleep_min;
diff -Nru a/sound/core/oss/rate.c b/sound/core/oss/rate.c
--- a/sound/core/oss/rate.c Sat Aug 2 12:16:32 2003
+++ b/sound/core/oss/rate.c Sat Aug 2 12:16:32 2003
@@ -85,11 +85,7 @@
#undef PUT_S16_LABELS
void *get = get_s16_labels[data->get];
void *put = put_s16_labels[data->put];
- void *get_s16_end = 0;
signed short sample = 0;
-#define GET_S16_END *get_s16_end
-#include "plugin_ops.h"
-#undef GET_S16_END
for (channel = 0; channel < plugin->src_format.channels; channel++) {
pos = data->pos;
@@ -108,24 +104,16 @@
dst_step = dst_channels[channel].area.step / 8;
src_frames1 = src_frames;
dst_frames1 = dst_frames;
- if (pos & ~R_MASK) {
- get_s16_end = &&after_get1;
- goto *get;
- after_get1:
- pos &= R_MASK;
- S1 = S2;
- S2 = sample;
- src += src_step;
- src_frames1--;
- }
while (dst_frames1-- > 0) {
if (pos & ~R_MASK) {
pos &= R_MASK;
S1 = S2;
if (src_frames1-- > 0) {
- get_s16_end = &&after_get2;
goto *get;
- after_get2:
+#define GET_S16_END after_get
+#include "plugin_ops.h"
+#undef GET_S16_END
+ after_get:
S2 = sample;
src += src_step;
}
@@ -318,6 +306,8 @@
#endif
dst_frames = rate_dst_frames(plugin, frames);
+ if (dst_frames > dst_channels[0].frames)
+ dst_frames = dst_channels[0].frames;
data = (rate_t *)plugin->extra_data;
data->func(plugin, src_channels, dst_channels, frames, dst_frames);
return dst_frames;
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2003-08-04 12:48 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-08-04 12:52 sound update causes artsd to fail/abort initialization Mike Galbraith
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).