* Changes over dmix: 1.0.11rc4 and future
@ 2006-03-27 16:35 Takashi Iwai
2006-03-28 23:00 ` James Courtier-Dutton
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Takashi Iwai @ 2006-03-27 16:35 UTC (permalink / raw)
To: alsa-devel
[-- Attachment #1: Type: text/plain, Size: 2132 bytes --]
Hi,
it looks like the 1.0.11rc4 announcement isn't sent out, so here I'd
like to explain what has been changed over dmix recently.
As of 1.0.11rc4, dmix accepts more flexible buffer sizes than the
earlier versions did. The buffer size is basically arbitrary. The
only restriction is that it's aligned to the period size, and the
minimal periods are two.
With this change, some applications have positive influences, and some
have negative. The regression, for example with speaker-test, happens
because there was no upper limit of buffer size. It's already fixed
in the CVS version (by setting max periods = 1024).
If you have a problem with dmix what didn't happen ago, try to define
defaults.pcm.dmix_variable_buffer false
in ~/.asoundrc.
Also, you can try ALSA CVS version. It includes more fixes about the
dmix. Or wait for ALSA 1.0.11-final, which (hopefully) will be
released soon.
So far so good. Now, about the future changes.
Currently, dmix forks a resource server to share the opened file
descriptor. (Don't misunderstand, it's not a mixing server but just
manages the file descriptor.) This behavior seems causing troubles in
some applications. I've been trying to reduce this mess.
The below (first one) is a patch to add O_APPEND support to PCM. If a
PCM is opened with O_APPEND, it shares the alreay opened stream.
And the second patch is to alsa-lib to use this new O_APPEND feature.
Since the resource can be shared via O_APPEND, we don't need dmix
server.
I'm not sure whether it's a 2.6.17 material or a post-2.6.17. Maybe
we need a bit discussion whether this O_APPEND hack is right or not.
Beware that the patch is against the very latest CVS version. The
anon tree doesn't have it yet right now.
Any comments or test reports are appreciated.
For further implementation, we could get rid of shared memory by a
small addition to the kernel, too. At least, two different things
would be needed:
- Missing GET_HW_PARAMS and GET_SW_PARAMS ioctls
(Why don't we have them?)
- Anonymous mmap for the shared sum area of dmix
This requires more detailed discussion, I think.
Takashi
[-- Attachment #2: pcm-oappend.diff --]
[-- Type: application/octet-stream, Size: 14226 bytes --]
Index: alsa-kernel/core/pcm.c
===================================================================
RCS file: /home/iwai/cvs/alsa/alsa-kernel/core/pcm.c,v
retrieving revision 1.63
diff -u -r1.63 pcm.c
--- alsa-kernel/core/pcm.c 27 Mar 2006 14:38:28 -0000 1.63
+++ alsa-kernel/core/pcm.c 27 Mar 2006 16:31:13 -0000
@@ -829,6 +829,26 @@
return -EINVAL;
}
+ if (file->f_flags & O_APPEND) {
+ if (prefer_subdevice < 0) {
+ if (pstr->substream_count > 1)
+ return -EINVAL; /* must be unique */
+ substream = pstr->substream;
+ } else {
+ for (substream = pstr->substream; substream;
+ substream = substream->next)
+ if (substream->number == prefer_subdevice)
+ break;
+ }
+ if (! substream)
+ return -ENODEV;
+ if (! SUBSTREAM_BUSY(substream))
+ return -EBADFD;
+ substream->ref_count++;
+ *rsubstream = substream;
+ return 0;
+ }
+
if (prefer_subdevice >= 0) {
for (substream = pstr->substream; substream; substream = substream->next)
if (!SUBSTREAM_BUSY(substream) && substream->number == prefer_subdevice)
@@ -873,7 +893,8 @@
substream->runtime = runtime;
substream->private_data = pcm->private_data;
- substream->ffile = file;
+ substream->ref_count = 1;
+ substream->f_flags = file->f_flags;
pstr->substream_opened++;
*rsubstream = substream;
return 0;
@@ -882,7 +903,7 @@
void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime;
- substream->file = NULL;
+
runtime = substream->runtime;
snd_assert(runtime != NULL, return);
if (runtime->private_free != NULL)
Index: alsa-kernel/core/pcm_lib.c
===================================================================
RCS file: /home/iwai/cvs/alsa/alsa-kernel/core/pcm_lib.c,v
retrieving revision 1.71
diff -u -r1.71 pcm_lib.c
--- alsa-kernel/core/pcm_lib.c 27 Mar 2006 14:38:28 -0000 1.71
+++ alsa-kernel/core/pcm_lib.c 27 Mar 2006 16:31:13 -0000
@@ -2299,7 +2299,7 @@
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD;
- nonblock = !!(substream->ffile->f_flags & O_NONBLOCK);
+ nonblock = !!(substream->f_flags & O_NONBLOCK);
if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED &&
runtime->channels > 1)
@@ -2362,7 +2362,7 @@
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD;
- nonblock = !!(substream->ffile->f_flags & O_NONBLOCK);
+ nonblock = !!(substream->f_flags & O_NONBLOCK);
if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED)
return -EINVAL;
@@ -2572,7 +2572,7 @@
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD;
- nonblock = !!(substream->ffile->f_flags & O_NONBLOCK);
+ nonblock = !!(substream->f_flags & O_NONBLOCK);
if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED)
return -EINVAL;
return snd_pcm_lib_read1(substream, (unsigned long)buf, size, nonblock, snd_pcm_lib_read_transfer);
@@ -2629,7 +2629,7 @@
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD;
- nonblock = !!(substream->ffile->f_flags & O_NONBLOCK);
+ nonblock = !!(substream->f_flags & O_NONBLOCK);
if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED)
return -EINVAL;
return snd_pcm_lib_read1(substream, (unsigned long)bufs, frames, nonblock, snd_pcm_lib_readv_transfer);
Index: alsa-kernel/core/pcm_native.c
===================================================================
RCS file: /home/iwai/cvs/alsa/alsa-kernel/core/pcm_native.c,v
retrieving revision 1.114
diff -u -r1.114 pcm_native.c
--- alsa-kernel/core/pcm_native.c 27 Mar 2006 14:38:28 -0000 1.114
+++ alsa-kernel/core/pcm_native.c 27 Mar 2006 16:31:13 -0000
@@ -1275,13 +1275,16 @@
/*
* prepare ioctl
*/
-static int snd_pcm_pre_prepare(struct snd_pcm_substream *substream, int state)
+/* we use the second argument for updating f_flags */
+static int snd_pcm_pre_prepare(struct snd_pcm_substream *substream,
+ int f_flags)
{
struct snd_pcm_runtime *runtime = substream->runtime;
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD;
if (snd_pcm_running(substream))
return -EBUSY;
+ substream->f_flags = f_flags;
return 0;
}
@@ -1310,17 +1313,26 @@
/**
* snd_pcm_prepare
* @substream: the PCM substream instance
+ * @file: file to refer f_flags
*
* Prepare the PCM substream to be triggerable.
*/
-static int snd_pcm_prepare(struct snd_pcm_substream *substream)
+static int snd_pcm_prepare(struct snd_pcm_substream *substream,
+ struct file *file)
{
int res;
struct snd_card *card = substream->pcm->card;
+ int f_flags;
+
+ if (file)
+ f_flags = file->f_flags;
+ else
+ f_flags = substream->f_flags;
snd_power_lock(card);
if ((res = snd_power_wait(card, SNDRV_CTL_POWER_D0)) >= 0)
- res = snd_pcm_action_nonatomic(&snd_pcm_action_prepare, substream, 0);
+ res = snd_pcm_action_nonatomic(&snd_pcm_action_prepare,
+ substream, f_flags);
snd_power_unlock(card);
return res;
}
@@ -1331,7 +1343,7 @@
static int snd_pcm_pre_drain_init(struct snd_pcm_substream *substream, int state)
{
- if (substream->ffile->f_flags & O_NONBLOCK)
+ if (substream->f_flags & O_NONBLOCK)
return -EAGAIN;
substream->runtime->trigger_master = substream;
return 0;
@@ -2006,6 +2018,10 @@
void snd_pcm_release_substream(struct snd_pcm_substream *substream)
{
+ substream->ref_count--;
+ if (substream->ref_count > 0)
+ return;
+
snd_pcm_drop(substream);
if (substream->pcm_release)
substream->pcm_release(substream);
@@ -2028,6 +2044,11 @@
err = snd_pcm_attach_substream(pcm, stream, file, &substream);
if (err < 0)
return err;
+ if (substream->ref_count > 1) {
+ *rsubstream = substream;
+ return 0;
+ }
+
substream->no_mmap_ctrl = 0;
err = snd_pcm_hw_constraints_init(substream);
if (err < 0) {
@@ -2071,17 +2092,20 @@
if (err < 0)
return err;
- pcm_file = kzalloc(sizeof(*pcm_file), GFP_KERNEL);
- if (pcm_file == NULL) {
- snd_pcm_release_substream(substream);
- return -ENOMEM;
+ if (substream->ref_count > 1)
+ pcm_file = substream->file;
+ else {
+ pcm_file = kzalloc(sizeof(*pcm_file), GFP_KERNEL);
+ if (pcm_file == NULL) {
+ snd_pcm_release_substream(substream);
+ return -ENOMEM;
+ }
+ str = substream->pstr;
+ substream->file = pcm_file;
+ substream->pcm_release = pcm_release_private;
+ pcm_file->substream = substream;
+ snd_pcm_add_file(str, pcm_file);
}
- str = substream->pstr;
- substream->file = pcm_file;
- substream->pcm_release = pcm_release_private;
- pcm_file->substream = substream;
- snd_pcm_add_file(str, pcm_file);
-
file->private_data = pcm_file;
*rpcm_file = pcm_file;
return 0;
@@ -2491,7 +2515,8 @@
return 0;
}
-static int snd_pcm_common_ioctl1(struct snd_pcm_substream *substream,
+static int snd_pcm_common_ioctl1(struct file *file,
+ struct snd_pcm_substream *substream,
unsigned int cmd, void __user *arg)
{
snd_assert(substream != NULL, return -ENXIO);
@@ -2516,7 +2541,7 @@
case SNDRV_PCM_IOCTL_CHANNEL_INFO:
return snd_pcm_channel_info_user(substream, arg);
case SNDRV_PCM_IOCTL_PREPARE:
- return snd_pcm_prepare(substream);
+ return snd_pcm_prepare(substream, file);
case SNDRV_PCM_IOCTL_RESET:
return snd_pcm_reset(substream);
case SNDRV_PCM_IOCTL_START:
@@ -2558,7 +2583,8 @@
return -ENOTTY;
}
-static int snd_pcm_playback_ioctl1(struct snd_pcm_substream *substream,
+static int snd_pcm_playback_ioctl1(struct file *file,
+ struct snd_pcm_substream *substream,
unsigned int cmd, void __user *arg)
{
snd_assert(substream != NULL, return -ENXIO);
@@ -2634,10 +2660,11 @@
return result < 0 ? result : 0;
}
}
- return snd_pcm_common_ioctl1(substream, cmd, arg);
+ return snd_pcm_common_ioctl1(file, substream, cmd, arg);
}
-static int snd_pcm_capture_ioctl1(struct snd_pcm_substream *substream,
+static int snd_pcm_capture_ioctl1(struct file *file,
+ struct snd_pcm_substream *substream,
unsigned int cmd, void __user *arg)
{
snd_assert(substream != NULL, return -ENXIO);
@@ -2713,7 +2740,7 @@
return result < 0 ? result : 0;
}
}
- return snd_pcm_common_ioctl1(substream, cmd, arg);
+ return snd_pcm_common_ioctl1(file, substream, cmd, arg);
}
static long snd_pcm_playback_ioctl(struct file *file, unsigned int cmd,
@@ -2726,7 +2753,8 @@
if (((cmd >> 8) & 0xff) != 'A')
return -ENOTTY;
- return snd_pcm_playback_ioctl1(pcm_file->substream, cmd, (void __user *)arg);
+ return snd_pcm_playback_ioctl1(file, pcm_file->substream, cmd,
+ (void __user *)arg);
}
static long snd_pcm_capture_ioctl(struct file *file, unsigned int cmd,
@@ -2739,7 +2767,8 @@
if (((cmd >> 8) & 0xff) != 'A')
return -ENOTTY;
- return snd_pcm_capture_ioctl1(pcm_file->substream, cmd, (void __user *)arg);
+ return snd_pcm_capture_ioctl1(file, pcm_file->substream, cmd,
+ (void __user *)arg);
}
int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
@@ -2751,12 +2780,12 @@
fs = snd_enter_user();
switch (substream->stream) {
case SNDRV_PCM_STREAM_PLAYBACK:
- result = snd_pcm_playback_ioctl1(substream,
- cmd, (void __user *)arg);
+ result = snd_pcm_playback_ioctl1(NULL, substream, cmd,
+ (void __user *)arg);
break;
case SNDRV_PCM_STREAM_CAPTURE:
- result = snd_pcm_capture_ioctl1(substream,
- cmd, (void __user *)arg);
+ result = snd_pcm_capture_ioctl1(NULL, substream, cmd,
+ (void __user *)arg);
break;
default:
result = -EINVAL;
Index: alsa-kernel/core/oss/pcm_oss.c
===================================================================
RCS file: /home/iwai/cvs/alsa/alsa-kernel/core/oss/pcm_oss.c,v
retrieving revision 1.91
diff -u -r1.91 pcm_oss.c
--- alsa-kernel/core/oss/pcm_oss.c 27 Mar 2006 14:42:54 -0000 1.91
+++ alsa-kernel/core/oss/pcm_oss.c 27 Mar 2006 16:31:13 -0000
@@ -850,7 +850,7 @@
if (runtime->oss.period_ptr == 0 ||
runtime->oss.period_ptr == runtime->oss.buffer_used)
runtime->oss.buffer_used = 0;
- else if ((substream->ffile->f_flags & O_NONBLOCK) != 0)
+ else if ((substream->f_flags & O_NONBLOCK) != 0)
return xfer > 0 ? xfer : -EAGAIN;
}
} else {
@@ -863,7 +863,7 @@
buf += tmp;
bytes -= tmp;
xfer += tmp;
- if ((substream->ffile->f_flags & O_NONBLOCK) != 0 &&
+ if ((substream->f_flags & O_NONBLOCK) != 0 &&
tmp != runtime->oss.period_bytes)
break;
}
@@ -1101,10 +1101,10 @@
* finish sync: drain the buffer
*/
__direct:
- saved_f_flags = substream->ffile->f_flags;
- substream->ffile->f_flags &= ~O_NONBLOCK;
+ saved_f_flags = substream->f_flags;
+ substream->f_flags &= ~O_NONBLOCK;
err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, NULL);
- substream->ffile->f_flags = saved_f_flags;
+ substream->f_flags = saved_f_flags;
if (err < 0)
return err;
runtime->oss.prepare = 1;
@@ -1681,9 +1681,9 @@
substream->oss.oss = 1;
substream->oss.setup = *setup;
if (setup->nonblock)
- substream->ffile->f_flags |= O_NONBLOCK;
- else
- substream->ffile->f_flags &= ~O_NONBLOCK;
+ substream->f_flags |= O_NONBLOCK;
+ else if (setup->block)
+ substream->f_flags &= ~O_NONBLOCK;
runtime = substream->runtime;
runtime->oss.params = 1;
runtime->oss.trigger = 1;
@@ -1740,6 +1740,7 @@
(pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX))
f_mode = FMODE_WRITE;
+ file->f_flags &= ~O_APPEND;
for (idx = 0; idx < 2; idx++) {
if (setup[idx].disable)
continue;
@@ -2056,6 +2057,7 @@
substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
if (substream == NULL)
return -ENXIO;
+ substream->f_flags = file->f_flags & O_NONBLOCK;
#ifndef OSS_DEBUG
return snd_pcm_oss_read1(substream, buf, count);
#else
@@ -2077,6 +2079,7 @@
substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
if (substream == NULL)
return -ENXIO;
+ substream->f_flags = file->f_flags & O_NONBLOCK;
result = snd_pcm_oss_write1(substream, buf, count);
#ifdef OSS_DEBUG
printk("pcm_oss: write %li bytes (wrote %li bytes)\n", (long)count, (long)result);
Index: alsa-kernel/include/asound.h
===================================================================
RCS file: /home/iwai/cvs/alsa/alsa-kernel/include/asound.h,v
retrieving revision 1.48
diff -u -r1.48 asound.h
--- alsa-kernel/include/asound.h 17 Nov 2005 13:44:05 -0000 1.48
+++ alsa-kernel/include/asound.h 27 Mar 2006 16:31:13 -0000
@@ -137,7 +137,7 @@
* *
*****************************************************************************/
-#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 7)
+#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 8)
typedef unsigned long snd_pcm_uframes_t;
typedef signed long snd_pcm_sframes_t;
Index: alsa-kernel/include/pcm.h
===================================================================
RCS file: /home/iwai/cvs/alsa/alsa-kernel/include/pcm.h,v
retrieving revision 1.66
diff -u -r1.66 pcm.h
--- alsa-kernel/include/pcm.h 27 Mar 2006 14:38:28 -0000 1.66
+++ alsa-kernel/include/pcm.h 27 Mar 2006 16:31:13 -0000
@@ -368,7 +368,8 @@
struct snd_pcm_group *group; /* pointer to current group */
/* -- assigned files -- */
struct snd_pcm_file *file;
- struct file *ffile;
+ int ref_count;
+ unsigned int f_flags;
void (*pcm_release)(struct snd_pcm_substream *);
#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
/* -- OSS things -- */
@@ -385,7 +386,7 @@
unsigned int hw_opened: 1;
};
-#define SUBSTREAM_BUSY(substream) ((substream)->file != NULL)
+#define SUBSTREAM_BUSY(substream) ((substream)->ref_count > 0)
struct snd_pcm_str {
Index: alsa-kernel/usb/usx2y/usx2yhwdeppcm.c
===================================================================
RCS file: /home/iwai/cvs/alsa/alsa-kernel/usb/usx2y/usx2yhwdeppcm.c,v
retrieving revision 1.10
diff -u -r1.10 usx2yhwdeppcm.c
--- alsa-kernel/usb/usx2y/usx2yhwdeppcm.c 16 Jan 2006 16:41:38 -0000 1.10
+++ alsa-kernel/usb/usx2y/usx2yhwdeppcm.c 27 Mar 2006 16:31:13 -0000
@@ -632,7 +632,7 @@
for (s = 0; s < 2; ++s) {
struct snd_pcm_substream *substream;
substream = pcm->streams[s].substream;
- if (substream && substream->ffile != NULL)
+ if (SUBSTREAM_BUSY(substream))
err = -EBUSY;
}
}
[-- Attachment #3: dmix-using-oappend.diff --]
[-- Type: application/octet-stream, Size: 12563 bytes --]
Index: alsa-lib/src/pcm/pcm_direct.c
===================================================================
RCS file: /home/iwai/cvs/alsa/alsa-lib/src/pcm/pcm_direct.c,v
retrieving revision 1.57
diff -u -r1.57 pcm_direct.c
--- alsa-lib/src/pcm/pcm_direct.c 24 Mar 2006 14:51:26 -0000 1.57
+++ alsa-lib/src/pcm/pcm_direct.c 27 Mar 2006 16:31:27 -0000
@@ -82,6 +82,8 @@
return 0;
}
+#define SND_PCM_DIRECT_MAGIC 0xa15ad319
+
/*
* global shared memory area
*/
@@ -121,7 +123,13 @@
buf.shm_perm.gid = dmix->ipc_gid;
shmctl(dmix->shmid, IPC_SET, &buf);
}
+ dmix->shmptr->magic = SND_PCM_DIRECT_MAGIC;
return 1;
+ } else {
+ if (dmix->shmptr->magic != SND_PCM_DIRECT_MAGIC) {
+ snd_pcm_direct_shm_discard(dmix);
+ return -errno;
+ }
}
return 0;
}
@@ -1028,6 +1036,14 @@
dmix->slave_boundary = spcm->boundary;
spcm->donot_close = 1;
+
+ {
+ int ver = 0;
+ ioctl(spcm->poll_fd, SNDRV_PCM_IOCTL_PVERSION, &ver);
+ if (ver < SNDRV_PROTOCOL_VERSION(2, 0, 8))
+ dmix->shmptr->use_server = 1;
+ }
+
return 0;
}
@@ -1148,6 +1164,36 @@
return 0;
}
+/*
+ * open a slave PCM as secondary client (dup'ed fd)
+ */
+int snd_pcm_direct_initialize_secondary_slave(snd_pcm_direct_t *dmix, snd_pcm_t *spcm, struct slave_params *params)
+{
+ int ret;
+
+ spcm->donot_close = 1;
+ spcm->setup = 1;
+ /* we copy the slave setting */
+ spcm->buffer_size = dmix->shmptr->s.buffer_size;
+ spcm->sample_bits = dmix->shmptr->s.sample_bits;
+ spcm->channels = dmix->shmptr->s.channels;
+ spcm->format = dmix->shmptr->s.format;
+ spcm->boundary = recalc_boundary_size(dmix->shmptr->s.boundary, spcm->buffer_size);
+ spcm->info = dmix->shmptr->s.info;
+
+ /* Use the slave setting as SPCM, so far */
+ dmix->slave_buffer_size = spcm->buffer_size;
+ dmix->slave_period_size = dmix->shmptr->s.period_size;
+ dmix->slave_boundary = spcm->boundary;
+
+ ret = snd_pcm_mmap(spcm);
+ if (ret < 0) {
+ SNDERR("unable to mmap channels");
+ return ret;
+ }
+ return 0;
+}
+
int snd_pcm_direct_set_timer_params(snd_pcm_direct_t *dmix)
{
snd_timer_params_t *params;
Index: alsa-lib/src/pcm/pcm_direct.h
===================================================================
RCS file: /home/iwai/cvs/alsa/alsa-lib/src/pcm/pcm_direct.h,v
retrieving revision 1.22
diff -u -r1.22 pcm_direct.h
--- alsa-lib/src/pcm/pcm_direct.h 20 Mar 2006 18:21:15 -0000 1.22
+++ alsa-lib/src/pcm/pcm_direct.h 27 Mar 2006 16:31:27 -0000
@@ -51,8 +51,10 @@
};
typedef struct {
+ unsigned int magic; /* magic number */
char socket_name[256]; /* name of communication socket */
snd_pcm_type_t type; /* PCM type (currently only hw) */
+ int use_server;
struct {
unsigned int format;
snd_interval_t rate;
@@ -168,6 +170,7 @@
int snd_pcm_direct_client_connect(snd_pcm_direct_t *dmix);
int snd_pcm_direct_client_discard(snd_pcm_direct_t *dmix);
int snd_pcm_direct_initialize_slave(snd_pcm_direct_t *dmix, snd_pcm_t *spcm, struct slave_params *params);
+int snd_pcm_direct_initialize_secondary_slave(snd_pcm_direct_t *dmix, snd_pcm_t *spcm, struct slave_params *params);
int snd_pcm_direct_initialize_poll_fd(snd_pcm_direct_t *dmix);
int snd_pcm_direct_check_interleave(snd_pcm_direct_t *dmix, snd_pcm_t *pcm);
int snd_pcm_direct_parse_bindings(snd_pcm_direct_t *dmix, snd_config_t *cfg);
Index: alsa-lib/src/pcm/pcm_dmix.c
===================================================================
RCS file: /home/iwai/cvs/alsa/alsa-lib/src/pcm/pcm_dmix.c,v
retrieving revision 1.72
diff -u -r1.72 pcm_dmix.c
--- alsa-lib/src/pcm/pcm_dmix.c 24 Mar 2006 14:51:26 -0000 1.72
+++ alsa-lib/src/pcm/pcm_dmix.c 27 Mar 2006 16:31:27 -0000
@@ -651,8 +651,10 @@
if (dmix->client)
snd_pcm_direct_client_discard(dmix);
shm_sum_discard(dmix);
- snd_pcm_direct_shm_discard(dmix);
- snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT);
+ if (snd_pcm_direct_shm_discard(dmix))
+ snd_pcm_direct_semaphore_discard(dmix);
+ else
+ snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT);
free(dmix->bindings);
pcm->private_data = NULL;
free(dmix);
@@ -878,28 +880,54 @@
dmix->spcm = spcm;
- dmix->server_free = dmix_server_free;
+ if (dmix->shmptr->use_server) {
+ dmix->server_free = dmix_server_free;
- ret = snd_pcm_direct_server_create(dmix);
- if (ret < 0) {
- SNDERR("unable to create server");
- goto _err;
+ ret = snd_pcm_direct_server_create(dmix);
+ if (ret < 0) {
+ SNDERR("unable to create server");
+ goto _err;
+ }
}
dmix->shmptr->type = spcm->type;
} else {
- /* up semaphore to avoid deadlock */
- snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT);
- ret = snd_pcm_direct_client_connect(dmix);
- if (ret < 0) {
- SNDERR("unable to connect client");
- goto _err_nosem;
- }
+ if (dmix->shmptr->use_server) {
+ /* up semaphore to avoid deadlock */
+ snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT);
+ ret = snd_pcm_direct_client_connect(dmix);
+ if (ret < 0) {
+ SNDERR("unable to connect client");
+ goto _err_nosem;
+ }
- snd_pcm_direct_semaphore_down(dmix, DIRECT_IPC_SEM_CLIENT);
- ret = snd_pcm_direct_open_secondary_client(&spcm, dmix, "dmix_client");
- if (ret < 0)
- goto _err;
+ snd_pcm_direct_semaphore_down(dmix, DIRECT_IPC_SEM_CLIENT);
+ ret = snd_pcm_direct_open_secondary_client(&spcm, dmix, "dmix_client");
+ if (ret < 0)
+ goto _err;
+ } else {
+
+ ret = snd_pcm_open_slave(&spcm, root, sconf, stream,
+ mode | SND_PCM_NONBLOCK |
+ SND_PCM_APPEND,
+ NULL);
+ if (ret < 0) {
+ SNDERR("unable to open slave");
+ goto _err;
+ }
+ if (snd_pcm_type(spcm) != SND_PCM_TYPE_HW) {
+ SNDERR("dmix plugin can be only connected to hw plugin");
+ ret = -EINVAL;
+ goto _err;
+ }
+
+ ret = snd_pcm_direct_initialize_secondary_slave(dmix, spcm, params);
+ if (ret < 0) {
+ SNDERR("unable to initialize slave");
+ goto _err;
+ }
+ }
+
dmix->spcm = spcm;
}
Index: alsa-lib/src/pcm/pcm_dshare.c
===================================================================
RCS file: /home/iwai/cvs/alsa/alsa-lib/src/pcm/pcm_dshare.c,v
retrieving revision 1.37
diff -u -r1.37 pcm_dshare.c
--- alsa-lib/src/pcm/pcm_dshare.c 20 Mar 2006 18:21:15 -0000 1.37
+++ alsa-lib/src/pcm/pcm_dshare.c 27 Mar 2006 16:31:27 -0000
@@ -464,8 +464,10 @@
snd_pcm_direct_server_discard(dshare);
if (dshare->client)
snd_pcm_direct_client_discard(dshare);
- snd_pcm_direct_shm_discard(dshare);
- snd_pcm_direct_semaphore_up(dshare, DIRECT_IPC_SEM_CLIENT);
+ if (snd_pcm_direct_shm_discard(dshare))
+ snd_pcm_direct_semaphore_discard(dshare);
+ else
+ snd_pcm_direct_semaphore_up(dshare, DIRECT_IPC_SEM_CLIENT);
free(dshare->bindings);
pcm->private_data = NULL;
free(dshare);
@@ -688,27 +690,53 @@
dshare->spcm = spcm;
- ret = snd_pcm_direct_server_create(dshare);
- if (ret < 0) {
- SNDERR("unable to create server");
- goto _err;
+ if (dshare->shmptr->use_server) {
+ ret = snd_pcm_direct_server_create(dshare);
+ if (ret < 0) {
+ SNDERR("unable to create server");
+ goto _err;
+ }
}
dshare->shmptr->type = spcm->type;
} else {
- /* up semaphore to avoid deadlock */
- snd_pcm_direct_semaphore_up(dshare, DIRECT_IPC_SEM_CLIENT);
- ret = snd_pcm_direct_client_connect(dshare);
- if (ret < 0) {
- SNDERR("unable to connect client");
- goto _err_nosem;
- }
+ if (dshare->shmptr->use_server) {
+ /* up semaphore to avoid deadlock */
+ snd_pcm_direct_semaphore_up(dshare, DIRECT_IPC_SEM_CLIENT);
+ ret = snd_pcm_direct_client_connect(dshare);
+ if (ret < 0) {
+ SNDERR("unable to connect client");
+ goto _err_nosem;
+ }
- snd_pcm_direct_semaphore_down(dshare, DIRECT_IPC_SEM_CLIENT);
- ret = snd_pcm_direct_open_secondary_client(&spcm, dshare, "dshare_client");
- ret = snd_pcm_hw_open_fd(&spcm, "dshare_client", dshare->hw_fd, 0, 0);
- if (ret < 0)
- goto _err;
+ snd_pcm_direct_semaphore_down(dshare, DIRECT_IPC_SEM_CLIENT);
+ ret = snd_pcm_direct_open_secondary_client(&spcm, dshare, "dshare_client");
+ if (ret < 0)
+ goto _err;
+
+ } else {
+
+ ret = snd_pcm_open_slave(&spcm, root, sconf, stream,
+ mode | SND_PCM_NONBLOCK |
+ SND_PCM_APPEND,
+ NULL);
+ if (ret < 0) {
+ SNDERR("unable to open slave");
+ goto _err;
+ }
+ if (snd_pcm_type(spcm) != SND_PCM_TYPE_HW) {
+ SNDERR("dshare plugin can be only connected to hw plugin");
+ ret = -EINVAL;
+ goto _err;
+ }
+
+ ret = snd_pcm_direct_initialize_secondary_slave(dshare, spcm, params);
+ if (ret < 0) {
+ SNDERR("unable to initialize slave");
+ goto _err;
+ }
+ }
+
dshare->spcm = spcm;
}
Index: alsa-lib/src/pcm/pcm_dsnoop.c
===================================================================
RCS file: /home/iwai/cvs/alsa/alsa-lib/src/pcm/pcm_dsnoop.c,v
retrieving revision 1.37
diff -u -r1.37 pcm_dsnoop.c
--- alsa-lib/src/pcm/pcm_dsnoop.c 20 Mar 2006 18:21:15 -0000 1.37
+++ alsa-lib/src/pcm/pcm_dsnoop.c 27 Mar 2006 16:31:28 -0000
@@ -360,8 +360,10 @@
snd_pcm_direct_server_discard(dsnoop);
if (dsnoop->client)
snd_pcm_direct_client_discard(dsnoop);
- snd_pcm_direct_shm_discard(dsnoop);
- snd_pcm_direct_semaphore_up(dsnoop, DIRECT_IPC_SEM_CLIENT);
+ if (snd_pcm_direct_shm_discard(dsnoop))
+ snd_pcm_direct_semaphore_discard(dsnoop);
+ else
+ snd_pcm_direct_semaphore_up(dsnoop, DIRECT_IPC_SEM_CLIENT);
free(dsnoop->bindings);
pcm->private_data = NULL;
free(dsnoop);
@@ -570,27 +572,53 @@
dsnoop->spcm = spcm;
- ret = snd_pcm_direct_server_create(dsnoop);
- if (ret < 0) {
- SNDERR("unable to create server");
- goto _err;
+ if (dsnoop->shmptr->use_server) {
+ ret = snd_pcm_direct_server_create(dsnoop);
+ if (ret < 0) {
+ SNDERR("unable to create server");
+ goto _err;
+ }
}
dsnoop->shmptr->type = spcm->type;
} else {
- /* up semaphore to avoid deadlock */
- snd_pcm_direct_semaphore_up(dsnoop, DIRECT_IPC_SEM_CLIENT);
- ret = snd_pcm_direct_client_connect(dsnoop);
- if (ret < 0) {
- SNDERR("unable to connect client");
- goto _err_nosem;
- }
+ if (dsnoop->shmptr->use_server) {
+ /* up semaphore to avoid deadlock */
+ snd_pcm_direct_semaphore_up(dsnoop, DIRECT_IPC_SEM_CLIENT);
+ ret = snd_pcm_direct_client_connect(dsnoop);
+ if (ret < 0) {
+ SNDERR("unable to connect client");
+ goto _err_nosem;
+ }
- snd_pcm_direct_semaphore_down(dsnoop, DIRECT_IPC_SEM_CLIENT);
+ snd_pcm_direct_semaphore_down(dsnoop, DIRECT_IPC_SEM_CLIENT);
+
+ ret = snd_pcm_direct_open_secondary_client(&spcm, dsnoop, "dsnoop_client");
+ if (ret < 0)
+ goto _err;
+ } else {
+
+ ret = snd_pcm_open_slave(&spcm, root, sconf, stream,
+ mode | SND_PCM_NONBLOCK |
+ SND_PCM_APPEND,
+ NULL);
+ if (ret < 0) {
+ SNDERR("unable to open slave");
+ goto _err;
+ }
+ if (snd_pcm_type(spcm) != SND_PCM_TYPE_HW) {
+ SNDERR("dsnoop plugin can be only connected to hw plugin");
+ ret = -EINVAL;
+ goto _err;
+ }
+
+ ret = snd_pcm_direct_initialize_secondary_slave(dsnoop, spcm, params);
+ if (ret < 0) {
+ SNDERR("unable to initialize slave");
+ goto _err;
+ }
+ }
- ret = snd_pcm_direct_open_secondary_client(&spcm, dsnoop, "dsnoop_client");
- if (ret < 0)
- goto _err;
dsnoop->spcm = spcm;
}
Index: alsa-lib/src/pcm/pcm_hw.c
===================================================================
RCS file: /home/iwai/cvs/alsa/alsa-lib/src/pcm/pcm_hw.c,v
retrieving revision 1.113
diff -u -r1.113 pcm_hw.c
--- alsa-lib/src/pcm/pcm_hw.c 20 Mar 2006 11:15:55 -0000 1.113
+++ alsa-lib/src/pcm/pcm_hw.c 27 Mar 2006 16:31:28 -0000
@@ -1233,6 +1233,8 @@
fmode |= O_NONBLOCK;
if (mode & SND_PCM_ASYNC)
fmode |= O_ASYNC;
+ if (mode & SND_PCM_APPEND)
+ fmode |= O_APPEND;
fd = snd_open_device(filename, fmode);
if (fd < 0) {
ret = -errno;
Index: alsa-lib/src/pcm/pcm_local.h
===================================================================
RCS file: /home/iwai/cvs/alsa/alsa-lib/src/pcm/pcm_local.h,v
retrieving revision 1.100
diff -u -r1.100 pcm_local.h
--- alsa-lib/src/pcm/pcm_local.h 3 Mar 2006 16:42:03 -0000 1.100
+++ alsa-lib/src/pcm/pcm_local.h 27 Mar 2006 16:31:28 -0000
@@ -746,6 +746,8 @@
int snd_pcm_slave_conf(snd_config_t *root, snd_config_t *conf,
snd_config_t **pcm_conf, unsigned int count, ...);
+#define SND_PCM_APPEND (1<<8)
+
int snd_pcm_open_slave(snd_pcm_t **pcmp, snd_config_t *root,
snd_config_t *conf, snd_pcm_stream_t stream,
int mode, snd_config_t *parent_conf);
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: Changes over dmix: 1.0.11rc4 and future
2006-03-27 16:35 Changes over dmix: 1.0.11rc4 and future Takashi Iwai
@ 2006-03-28 23:00 ` James Courtier-Dutton
2006-04-01 19:19 ` Lee Revell
2006-04-03 17:17 ` Takashi Iwai
2 siblings, 0 replies; 7+ messages in thread
From: James Courtier-Dutton @ 2006-03-28 23:00 UTC (permalink / raw)
To: Takashi Iwai; +Cc: alsa-devel
Takashi Iwai wrote:
> Hi,
>
> it looks like the 1.0.11rc4 announcement isn't sent out, so here I'd
> like to explain what has been changed over dmix recently.
>
> As of 1.0.11rc4, dmix accepts more flexible buffer sizes than the
> earlier versions did. The buffer size is basically arbitrary. The
> only restriction is that it's aligned to the period size, and the
> minimal periods are two.
>
> With this change, some applications have positive influences, and some
> have negative. The regression, for example with speaker-test, happens
> because there was no upper limit of buffer size. It's already fixed
> in the CVS version (by setting max periods = 1024).
>
> If you have a problem with dmix what didn't happen ago, try to define
>
> defaults.pcm.dmix_variable_buffer false
>
> in ~/.asoundrc.
>
> Also, you can try ALSA CVS version. It includes more fixes about the
> dmix. Or wait for ALSA 1.0.11-final, which (hopefully) will be
> released soon.
>
>
> So far so good. Now, about the future changes.
>
> Currently, dmix forks a resource server to share the opened file
> descriptor. (Don't misunderstand, it's not a mixing server but just
> manages the file descriptor.) This behavior seems causing troubles in
> some applications. I've been trying to reduce this mess.
>
> The below (first one) is a patch to add O_APPEND support to PCM. If a
> PCM is opened with O_APPEND, it shares the alreay opened stream.
> And the second patch is to alsa-lib to use this new O_APPEND feature.
> Since the resource can be shared via O_APPEND, we don't need dmix
> server.
>
> I'm not sure whether it's a 2.6.17 material or a post-2.6.17. Maybe
> we need a bit discussion whether this O_APPEND hack is right or not.
>
> Beware that the patch is against the very latest CVS version. The
> anon tree doesn't have it yet right now.
>
> Any comments or test reports are appreciated.
>
>
> For further implementation, we could get rid of shared memory by a
> small addition to the kernel, too. At least, two different things
> would be needed:
>
> - Missing GET_HW_PARAMS and GET_SW_PARAMS ioctls
> (Why don't we have them?)
> - Anonymous mmap for the shared sum area of dmix
>
> This requires more detailed discussion, I think.
>
>
> Takashi
This all sounds good. I will test the dmix buffer size improvement.
I remember asking for this some time ago.
This might fix problems people are having with Doom3 and the like.
James
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Changes over dmix: 1.0.11rc4 and future
2006-03-27 16:35 Changes over dmix: 1.0.11rc4 and future Takashi Iwai
2006-03-28 23:00 ` James Courtier-Dutton
@ 2006-04-01 19:19 ` Lee Revell
2006-04-03 9:59 ` Takashi Iwai
2006-04-03 17:17 ` Takashi Iwai
2 siblings, 1 reply; 7+ messages in thread
From: Lee Revell @ 2006-04-01 19:19 UTC (permalink / raw)
To: Takashi Iwai; +Cc: alsa-devel
On Mon, 2006-03-27 at 18:35 +0200, Takashi Iwai wrote:
> Hi,
>
> it looks like the 1.0.11rc4 announcement isn't sent out, so here I'd
> like to explain what has been changed over dmix recently.
>
> As of 1.0.11rc4, dmix accepts more flexible buffer sizes than the
> earlier versions did. The buffer size is basically arbitrary. The
> only restriction is that it's aligned to the period size, and the
> minimal periods are two.
>
> With this change, some applications have positive influences, and some
> have negative. The regression, for example with speaker-test, happens
> because there was no upper limit of buffer size. It's already fixed
> in the CVS version (by setting max periods = 1024).
>
> If you have a problem with dmix what didn't happen ago, try to define
>
> defaults.pcm.dmix_variable_buffer false
>
> in ~/.asoundrc.
>
Does not work (alsa-lib and utils from today's CVS):
$ aplay -Dplug:dmix51 /usr/share/sounds/error.wav
ALSA lib pcm.c:6650:(snd_pcm_slave_conf) Unknown field
variable_buffer_size
aplay: main:547: audio open error: Invalid argument
.asoundrc:
defaults.pcm.dmix_variable_buffer false
pcm.dmix51 {
type upmix
slave.pcm {
type dmix
ipc_key {
@func refer
name defaults.pcm.ipc_key
}
ipc_gid {
@func refer
name defaults.pcm.ipc_gid
}
slave {
pcm "hw:0,0"
period_size 512
periods 10
channels 6
variable_buffer_size true
}
}
}
Lee
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: Changes over dmix: 1.0.11rc4 and future
2006-04-01 19:19 ` Lee Revell
@ 2006-04-03 9:59 ` Takashi Iwai
2006-04-03 16:29 ` Lee Revell
0 siblings, 1 reply; 7+ messages in thread
From: Takashi Iwai @ 2006-04-03 9:59 UTC (permalink / raw)
To: Lee Revell; +Cc: alsa-devel
At Sat, 01 Apr 2006 14:19:13 -0500,
Lee Revell wrote:
>
> On Mon, 2006-03-27 at 18:35 +0200, Takashi Iwai wrote:
> > Hi,
> >
> > it looks like the 1.0.11rc4 announcement isn't sent out, so here I'd
> > like to explain what has been changed over dmix recently.
> >
> > As of 1.0.11rc4, dmix accepts more flexible buffer sizes than the
> > earlier versions did. The buffer size is basically arbitrary. The
> > only restriction is that it's aligned to the period size, and the
> > minimal periods are two.
> >
> > With this change, some applications have positive influences, and some
> > have negative. The regression, for example with speaker-test, happens
> > because there was no upper limit of buffer size. It's already fixed
> > in the CVS version (by setting max periods = 1024).
> >
> > If you have a problem with dmix what didn't happen ago, try to define
> >
> > defaults.pcm.dmix_variable_buffer false
> >
> > in ~/.asoundrc.
> >
>
> Does not work (alsa-lib and utils from today's CVS):
>
> $ aplay -Dplug:dmix51 /usr/share/sounds/error.wav
> ALSA lib pcm.c:6650:(snd_pcm_slave_conf) Unknown field
> variable_buffer_size
> aplay: main:547: audio open error: Invalid argument
>
> .asoundrc:
>
> defaults.pcm.dmix_variable_buffer false
> pcm.dmix51 {
> type upmix
> slave.pcm {
> type dmix
> ipc_key {
> @func refer
> name defaults.pcm.ipc_key
> }
> ipc_gid {
> @func refer
> name defaults.pcm.ipc_gid
> }
> slave {
> pcm "hw:0,0"
> period_size 512
> periods 10
> channels 6
> variable_buffer_size true
> }
> }
> }
My bad, a syntax error in the dmix51 definition I posted.
pcm.dmix51 {
type upmix
slave.pcm {
type dmix
ipc_key {
@func refer
name defaults.pcm.ipc_key
}
ipc_gid {
@func refer
name defaults.pcm.ipc_gid
}
slave {
pcm "hw:0,0"
period_size 512
periods 10
channels 6
}
variable_buffer_size true
}
}
If you still get an error regarding variable_buffer_size, just remove
that line.
And note that this won't work with emu10k1.
Takashi
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: Changes over dmix: 1.0.11rc4 and future
2006-04-03 9:59 ` Takashi Iwai
@ 2006-04-03 16:29 ` Lee Revell
2006-04-03 16:42 ` Takashi Iwai
0 siblings, 1 reply; 7+ messages in thread
From: Lee Revell @ 2006-04-03 16:29 UTC (permalink / raw)
To: Takashi Iwai; +Cc: alsa-devel
On Mon, 2006-04-03 at 11:59 +0200, Takashi Iwai wrote:
>
> If you still get an error regarding variable_buffer_size, just remove
> that line.
>
> And note that this won't work with emu10k1.
I now get:
Playing WAVE '/usr/share/sounds/error.wav' : Signed 16 bit Little
Endian, Rate 44100 Hz, Mono
ALSA lib pcm_params.c:2152:(snd_pcm_hw_refine_slave) Slave PCM not
usable
aplay: set_params:879: Broken configuration for this PCM: no
configurations available
Which I think is normal as hw:0,0 on the emu10k1 is only a stereo
device.
Lee
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Changes over dmix: 1.0.11rc4 and future
2006-04-03 16:29 ` Lee Revell
@ 2006-04-03 16:42 ` Takashi Iwai
0 siblings, 0 replies; 7+ messages in thread
From: Takashi Iwai @ 2006-04-03 16:42 UTC (permalink / raw)
To: Lee Revell; +Cc: alsa-devel
At Mon, 03 Apr 2006 12:29:25 -0400,
Lee Revell wrote:
>
> On Mon, 2006-04-03 at 11:59 +0200, Takashi Iwai wrote:
> >
> > If you still get an error regarding variable_buffer_size, just remove
> > that line.
> >
> > And note that this won't work with emu10k1.
>
> I now get:
>
> Playing WAVE '/usr/share/sounds/error.wav' : Signed 16 bit Little
> Endian, Rate 44100 Hz, Mono
> ALSA lib pcm_params.c:2152:(snd_pcm_hw_refine_slave) Slave PCM not
> usable
> aplay: set_params:879: Broken configuration for this PCM: no
> configurations available
>
> Which I think is normal as hw:0,0 on the emu10k1 is only a stereo
> device.
Yes, exactly.
I'll make a patch to support dmix on multiple hw streams, but it'll be
after 1.0.11-final release... Or, at least, after cvs on sourceforge
gets back. I already have too many pending patches on my local tree.
Takashi
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Changes over dmix: 1.0.11rc4 and future
2006-03-27 16:35 Changes over dmix: 1.0.11rc4 and future Takashi Iwai
2006-03-28 23:00 ` James Courtier-Dutton
2006-04-01 19:19 ` Lee Revell
@ 2006-04-03 17:17 ` Takashi Iwai
2 siblings, 0 replies; 7+ messages in thread
From: Takashi Iwai @ 2006-04-03 17:17 UTC (permalink / raw)
To: Takashi Iwai; +Cc: alsa-devel
At Mon, 27 Mar 2006 18:35:47 +0200,
I wrote:
>
> Hi,
>
> it looks like the 1.0.11rc4 announcement isn't sent out, so here I'd
> like to explain what has been changed over dmix recently.
>
> As of 1.0.11rc4, dmix accepts more flexible buffer sizes than the
> earlier versions did. The buffer size is basically arbitrary. The
> only restriction is that it's aligned to the period size, and the
> minimal periods are two.
>
> With this change, some applications have positive influences, and some
> have negative. The regression, for example with speaker-test, happens
> because there was no upper limit of buffer size. It's already fixed
> in the CVS version (by setting max periods = 1024).
>
> If you have a problem with dmix what didn't happen ago, try to define
>
> defaults.pcm.dmix_variable_buffer false
>
> in ~/.asoundrc.
>
> Also, you can try ALSA CVS version. It includes more fixes about the
> dmix. Or wait for ALSA 1.0.11-final, which (hopefully) will be
> released soon.
It seems that some applications don't like the dmix buffer bigger than
the actual buffer of slave PCM. The below is a patch to fix. (It's
not in CVS since CVS tree is stilll broken...)
Now, "variable_buffer_size" option is removed, and another new option,
"max_periods" is introduced. This specifies the max periods
available for the pcm. Specifying -1 means to stick with the slave
PCM, i.e. the old behavior. Specifying 0 (or 1) means to limit the
max periods to slave periods.
The default size is defined as "defaults.pcm.dmix_max_periods". It's
defined as 0 in /usr/share/alsa/alsa.conf, and can be overridden by a
definition in ~/.asoundrc or /etc/asound.conf.
Anyhow, usually you don't have to take care of this option. It should
work as it is.
The O_APPEND patch in my early mail can be applied on this, too.
Takashi
Index: alsa-lib/src/conf/alsa.conf
===================================================================
RCS file: /home/iwai/cvs/alsa/alsa-lib/src/conf/alsa.conf,v
retrieving revision 1.26
diff -u -r1.26 alsa.conf
--- alsa-lib/src/conf/alsa.conf 21 Mar 2006 10:19:43 -0000 1.26
+++ alsa-lib/src/conf/alsa.conf 3 Apr 2006 14:56:56 -0000
@@ -57,7 +57,7 @@
defaults.pcm.ipc_key 5678293
defaults.pcm.ipc_gid audio
defaults.pcm.ipc_perm 0660
-defaults.pcm.dmix_variable_buffer true
+defaults.pcm.dmix_max_periods 0
defaults.pcm.front.card defaults.pcm.card
defaults.pcm.front.device defaults.pcm.device
defaults.pcm.rear.card defaults.pcm.card
Index: alsa-lib/src/conf/pcm/dmix.conf
===================================================================
RCS file: /home/iwai/cvs/alsa/alsa-lib/src/conf/pcm/dmix.conf,v
retrieving revision 1.11
diff -u -r1.11 dmix.conf
--- alsa-lib/src/conf/pcm/dmix.conf 21 Mar 2006 10:19:43 -0000 1.11
+++ alsa-lib/src/conf/pcm/dmix.conf 3 Apr 2006 14:56:56 -0000
@@ -92,9 +92,4 @@
default 16
}
}
- # Allow apps different buffer sizes
- variable_buffer_size {
- @func refer
- name defaults.pcm.dmix_variable_buffer
- }
}
Index: alsa-lib/src/pcm/pcm_direct.c
===================================================================
RCS file: /home/iwai/cvs/alsa/alsa-lib/src/pcm/pcm_direct.c,v
retrieving revision 1.57
diff -u -r1.57 pcm_direct.c
--- alsa-lib/src/pcm/pcm_direct.c 24 Mar 2006 14:51:26 -0000 1.57
+++ alsa-lib/src/pcm/pcm_direct.c 3 Apr 2006 14:56:56 -0000
@@ -697,7 +697,7 @@
&dshare->shmptr->hw.period_time);
if (err < 0)
return err;
- if (! dshare->variable_buffer_size) {
+ if (dshare->max_periods < 0) {
err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_BUFFER_SIZE,
&dshare->shmptr->hw.buffer_size);
if (err < 0)
@@ -711,13 +711,13 @@
(1<<SND_PCM_HW_PARAM_BUFFER_SIZE)|
(1<<SND_PCM_HW_PARAM_BUFFER_TIME))) {
int changed;
+ unsigned int max_periods = dshare->max_periods;
+ if (max_periods < 2)
+ max_periods = dshare->slave_buffer_size / dshare->slave_period_size;
do {
changed = 0;
- /* Set min/max size to [2:1024] since INT_MAX as the
- * upper-limit results in a too big buffer on some apps.
- */
err = hw_param_interval_refine_minmax(params, SND_PCM_HW_PARAM_PERIODS,
- 2, 1024);
+ 2, max_periods);
if (err < 0)
return err;
changed |= err;
@@ -1382,17 +1382,19 @@
return (direction << 1) + (device << 2) + (subdevice << 8) + (card << 12);
}
-int snd_pcm_direct_get_slave_ipc_offset(snd_config_t *root,
+static int snd_pcm_direct_get_slave_ipc_offset(snd_config_t *root,
snd_config_t *sconf,
int direction)
{
return _snd_pcm_direct_get_slave_ipc_offset(root, sconf, direction, 0);
}
-int snd_pcm_direct_parse_open_conf(snd_config_t *conf, struct snd_pcm_direct_open_conf *rec)
+int snd_pcm_direct_parse_open_conf(snd_config_t *root, snd_config_t *conf,
+ int stream, struct snd_pcm_direct_open_conf *rec)
{
snd_config_iterator_t i, next;
int ipc_key_add_uid = 0;
+ snd_config_t *n;
int err;
rec->slave = NULL;
@@ -1401,10 +1403,18 @@
rec->ipc_perm = 0600;
rec->ipc_gid = -1;
rec->slowptr = 0;
- rec->variable_buffer_size = 0;
+ rec->max_periods = 0;
+
+ /* read defaults */
+ if (snd_config_search(root, "defaults.pcm.dmix_max_periods", &n) >= 0) {
+ long val;
+ err = snd_config_get_integer(n, &val);
+ if (err >= 0)
+ rec->max_periods = val;
+ }
snd_config_for_each(i, next, conf) {
- snd_config_t *n = snd_config_iterator_entry(i);
+ n = snd_config_iterator_entry(i);
const char *id;
if (snd_config_get_id(n, &id) < 0)
continue;
@@ -1488,11 +1498,12 @@
rec->slowptr = err;
continue;
}
- if (strcmp(id, "variable_buffer_size") == 0) {
- err = snd_config_get_bool(n);
+ if (strcmp(id, "max_periods") == 0) {
+ long val;
+ err = snd_config_get_integer(n, &val);
if (err < 0)
return err;
- rec->variable_buffer_size = err;
+ rec->max_periods = val;
continue;
}
SNDERR("Unknown field %s", id);
@@ -1502,11 +1513,16 @@
SNDERR("slave is not defined");
return -EINVAL;
}
- if (ipc_key_add_uid)
- rec->ipc_key += getuid();
if (!rec->ipc_key) {
SNDERR("Unique IPC key is not defined");
return -EINVAL;
}
+ if (ipc_key_add_uid)
+ rec->ipc_key += getuid();
+ err = snd_pcm_direct_get_slave_ipc_offset(root, rec->slave, stream);
+ if (err < 0)
+ return err;
+ rec->ipc_key += err;
+
return 0;
}
Index: alsa-lib/src/pcm/pcm_direct.h
===================================================================
RCS file: /home/iwai/cvs/alsa/alsa-lib/src/pcm/pcm_direct.h,v
retrieving revision 1.22
diff -u -r1.22 pcm_direct.h
--- alsa-lib/src/pcm/pcm_direct.h 20 Mar 2006 18:21:15 -0000 1.22
+++ alsa-lib/src/pcm/pcm_direct.h 3 Apr 2006 14:56:56 -0000
@@ -117,7 +117,7 @@
snd_timer_t *timer; /* timer used as poll_fd */
int interleaved; /* we have interleaved buffer */
int slowptr; /* use slow but more precise ptr updates */
- int variable_buffer_size; /* allow the variable buffer size */
+ int max_periods; /* max periods (-1 = fixed periods, 0 = max buffer size) */
unsigned int channels; /* client's channels */
unsigned int *bindings;
union {
@@ -187,7 +187,6 @@
void snd_pcm_direct_clear_timer_queue(snd_pcm_direct_t *dmix);
int snd_pcm_direct_set_timer_params(snd_pcm_direct_t *dmix);
int snd_pcm_direct_open_secondary_client(snd_pcm_t **spcmp, snd_pcm_direct_t *dmix, const char *client_name);
-int snd_pcm_direct_get_slave_ipc_offset(snd_config_t *root, snd_config_t *sconf, int direction);
int snd_timer_async(snd_timer_t *timer, int sig, pid_t pid);
struct timespec snd_pcm_hw_fast_tstamp(snd_pcm_t *pcm);
@@ -197,9 +196,9 @@
mode_t ipc_perm;
int ipc_gid;
int slowptr;
- int variable_buffer_size;
+ int max_periods;
snd_config_t *slave;
snd_config_t *bindings;
};
-int snd_pcm_direct_parse_open_conf(snd_config_t *conf, struct snd_pcm_direct_open_conf *rec);
+int snd_pcm_direct_parse_open_conf(snd_config_t *root, snd_config_t *conf, int stream, struct snd_pcm_direct_open_conf *rec);
Index: alsa-lib/src/pcm/pcm_dmix.c
===================================================================
RCS file: /home/iwai/cvs/alsa/alsa-lib/src/pcm/pcm_dmix.c,v
retrieving revision 1.72
diff -u -r1.72 pcm_dmix.c
--- alsa-lib/src/pcm/pcm_dmix.c 24 Mar 2006 14:51:26 -0000 1.72
+++ alsa-lib/src/pcm/pcm_dmix.c 3 Apr 2006 14:56:56 -0000
@@ -437,6 +437,7 @@
if (err < 0)
return err;
/* fallthru */
+ snd_pcm_dmix_sync_area(pcm);
case SNDRV_PCM_STATE_PREPARED:
case SNDRV_PCM_STATE_SUSPENDED:
case STATE_RUN_PENDING:
@@ -487,8 +488,7 @@
static void reset_slave_ptr(snd_pcm_t *pcm, snd_pcm_direct_t *dmix)
{
dmix->slave_appl_ptr = dmix->slave_hw_ptr = *dmix->spcm->hw.ptr;
- if (! dmix->variable_buffer_size ||
- pcm->buffer_size > pcm->period_size * 2)
+ if (pcm->buffer_size > pcm->period_size * 2)
return;
/* If we have too litte periods, better to align the start position
* to the period boundary so that the interrupt can be handled properly
@@ -851,7 +851,7 @@
pcm->private_data = dmix;
dmix->state = SND_PCM_STATE_OPEN;
dmix->slowptr = opts->slowptr;
- dmix->variable_buffer_size = opts->variable_buffer_size;
+ dmix->max_periods = opts->max_periods;
dmix->sync_ptr = snd_pcm_dmix_sync_ptr;
if (first_instance) {
@@ -1092,10 +1092,9 @@
struct slave_params params;
struct snd_pcm_direct_open_conf dopen;
int bsize, psize;
- int ipc_offset;
int err;
- err = snd_pcm_direct_parse_open_conf(conf, &dopen);
+ err = snd_pcm_direct_parse_open_conf(root, conf, stream, &dopen);
if (err < 0)
return err;
@@ -1134,13 +1133,6 @@
params.period_size = psize;
params.buffer_size = bsize;
- ipc_offset = snd_pcm_direct_get_slave_ipc_offset(root, sconf, stream);
- if (ipc_offset < 0) {
- snd_config_delete(sconf);
- return ipc_offset;
- }
- dopen.ipc_key += ipc_offset;
-
err = snd_pcm_dmix_open(pcmp, name, &dopen, ¶ms,
root, sconf, stream, mode);
if (err < 0)
Index: alsa-lib/src/pcm/pcm_dshare.c
===================================================================
RCS file: /home/iwai/cvs/alsa/alsa-lib/src/pcm/pcm_dshare.c,v
retrieving revision 1.37
diff -u -r1.37 pcm_dshare.c
--- alsa-lib/src/pcm/pcm_dshare.c 20 Mar 2006 18:21:15 -0000 1.37
+++ alsa-lib/src/pcm/pcm_dshare.c 3 Apr 2006 14:56:56 -0000
@@ -662,7 +662,7 @@
pcm->private_data = dshare;
dshare->state = SND_PCM_STATE_OPEN;
dshare->slowptr = opts->slowptr;
- dshare->variable_buffer_size = opts->variable_buffer_size;
+ dshare->max_periods = opts->max_periods;
dshare->sync_ptr = snd_pcm_dshare_sync_ptr;
if (first_instance) {
@@ -835,10 +835,9 @@
struct slave_params params;
struct snd_pcm_direct_open_conf dopen;
int bsize, psize;
- int ipc_offset;
int err;
- err = snd_pcm_direct_parse_open_conf(conf, &dopen);
+ err = snd_pcm_direct_parse_open_conf(root, conf, stream, &dopen);
if (err < 0)
return err;
@@ -869,13 +868,6 @@
params.period_size = psize;
params.buffer_size = bsize;
- ipc_offset = snd_pcm_direct_get_slave_ipc_offset(root, sconf, stream);
- if (ipc_offset < 0) {
- snd_config_delete(sconf);
- return ipc_offset;
- }
- dopen.ipc_key += ipc_offset;
-
err = snd_pcm_dshare_open(pcmp, name, &dopen, ¶ms,
root, sconf, stream, mode);
if (err < 0)
Index: alsa-lib/src/pcm/pcm_dsnoop.c
===================================================================
RCS file: /home/iwai/cvs/alsa/alsa-lib/src/pcm/pcm_dsnoop.c,v
retrieving revision 1.37
diff -u -r1.37 pcm_dsnoop.c
--- alsa-lib/src/pcm/pcm_dsnoop.c 20 Mar 2006 18:21:15 -0000 1.37
+++ alsa-lib/src/pcm/pcm_dsnoop.c 3 Apr 2006 14:56:56 -0000
@@ -544,7 +544,7 @@
pcm->private_data = dsnoop;
dsnoop->state = SND_PCM_STATE_OPEN;
dsnoop->slowptr = opts->slowptr;
- dsnoop->variable_buffer_size = opts->variable_buffer_size;
+ dsnoop->max_periods = opts->max_periods;
dsnoop->sync_ptr = snd_pcm_dsnoop_sync_ptr;
if (first_instance) {
@@ -707,10 +707,9 @@
struct slave_params params;
struct snd_pcm_direct_open_conf dopen;
int bsize, psize;
- int ipc_offset;
int err;
- err = snd_pcm_direct_parse_open_conf(conf, &dopen);
+ err = snd_pcm_direct_parse_open_conf(root, conf, stream, &dopen);
if (err < 0)
return err;
@@ -741,13 +740,6 @@
params.period_size = psize;
params.buffer_size = bsize;
- ipc_offset = snd_pcm_direct_get_slave_ipc_offset(root, sconf, stream);
- if (ipc_offset < 0) {
- snd_config_delete(sconf);
- return ipc_offset;
- }
- dopen.ipc_key += ipc_offset;
-
err = snd_pcm_dsnoop_open(pcmp, name, &dopen, ¶ms,
root, sconf, stream, mode);
if (err < 0)
Index: alsa-lib/src/pcm/pcm_rate.c
===================================================================
RCS file: /home/iwai/cvs/alsa/alsa-lib/src/pcm/pcm_rate.c,v
retrieving revision 1.88
diff -u -r1.88 pcm_rate.c
--- alsa-lib/src/pcm/pcm_rate.c 30 Mar 2006 10:15:03 -0000 1.88
+++ alsa-lib/src/pcm/pcm_rate.c 3 Apr 2006 14:56:56 -0000
@@ -617,7 +617,12 @@
static int snd_pcm_rate_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
{
+ snd_pcm_rate_t *rate = pcm->private_data;
snd_pcm_rate_hwsync(pcm);
+ /* call slave's delay callback although the value is overwritten.
+ * it's needed for a better sync of dmix on aoss.
+ */
+ snd_pcm_delay(rate->gen.slave, delayp);
if (pcm->stream == SND_PCM_STREAM_PLAYBACK)
*delayp = snd_pcm_mmap_playback_hw_avail(pcm);
else
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2006-04-03 17:17 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-03-27 16:35 Changes over dmix: 1.0.11rc4 and future Takashi Iwai
2006-03-28 23:00 ` James Courtier-Dutton
2006-04-01 19:19 ` Lee Revell
2006-04-03 9:59 ` Takashi Iwai
2006-04-03 16:29 ` Lee Revell
2006-04-03 16:42 ` Takashi Iwai
2006-04-03 17:17 ` Takashi Iwai
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.