Alsa-Devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* 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

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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox