All of lore.kernel.org
 help / color / mirror / Atom feed
* Alsa-OSS Duplex bug (revisited)
@ 2007-05-27 22:23 Alan Horstmann
  2007-05-29 16:55 ` Takashi Iwai
  0 siblings, 1 reply; 16+ messages in thread
From: Alan Horstmann @ 2007-05-27 22:23 UTC (permalink / raw)
  To: ALSA devel; +Cc: Takashi Iwai

[-- Attachment #1: Type: text/plain, Size: 2714 bytes --]

About a year ago I posted an explaination of the cause of non-functioning with 
Alsa-OSS in duplex, together with a workaround patch.  After some discussion 
the thread ended.  However since then there has been a steady trickle of 
downloads of the patches from my host (it can also be found elsewhere) and 
some reports of great success,eg

	http://audacityteam.org/forum/thread/1388  (2nd page especially)

In attempting to tidy up some loose ends, I hope you can bear with me 
revisiting this and making the case for it's acceptance.  I am aware the 
Alsa-OSS is not of much interest to developers, and it might be said 'use 
native Alsa'; however that is not possible or desirable in all applications, 
and anyway, why provide an OSS emulation that cannot be made to work 
properly?

To summarise the problem first:

OSS provides a single SNDCTL_DSP_CHANNELS ioctl; where a device is duplex the 
number of capture and playback channels cannot be set separately.  With 
original OSS this was not a problem AFAIK because separate devices are 
created for capture and playback, ie they are not used duplex.  However 
Alsa-OSS in most cases creates a single combined device, which only operates 
correctly when an equal number of capture and playback channels are used.

The Workaround:

The workaround I proposed and now use constantly is like a secret trapdoor.  
Where the existing interface is adequate (ie captue channels == playback 
channels, or non-duplex) nothing changes, and SNDCTL_DSP_CHANNELS is set with 
a number between 0 and 128.  It is fully compatible with apps that don't know 
of the secret door -the front door is used!

However, if an app needs to set capture channels != playback channels, in 
duplex, at present the stream will malfunction every time.  But with this 
patch applied, if the app knows the workaround, then it can simply set 
SNDCTL_DSP_CHANNELS as  playback + 256*capture channels, and this will be 
interpreted correctly in the patched Alsa-OSS and the stream functions 
correctly.

As I say, there is therefore no loss of compatibility in either direction.  
Providing the app only uses the special formula when necessary rather than 
always, it is only providing a way to fix something that is broken.  It would 
seem to me of value to add the patch to Alsa so that the workaround can be 
effected by changes to the app only, without also having to patch and compile 
a replacement Alsa.  Whilst it is by no means ideal, it does overcome the 
underlying problem successfully.  Details of the workaround could be added to 
the  OSS-Emulation.html document.

Patch for 1.0.14rc4 is attached for consideration, together with example 
portaudio patch.

Regards  Alan









[-- Attachment #2: pcm_oss.c-1.0.14rc4-duplex-channels-set.diff --]
[-- Type: text/x-diff, Size: 2826 bytes --]

--- alsa-kernel/core/oss/pcm_oss-orig.c	2006-04-13 11:51:24.000000000 +0100
+++ alsa-kernel/core/oss/pcm_oss.c	2006-06-19 11:08:07.000000000 +0100
@@ -1665,25 +1665,65 @@
 	return substream->runtime->oss.rate;
 }
 
+static int snd_pcm_oss_get_substream_channels(struct snd_pcm_oss_file *pcm_oss_file, int substrindx)
+{
+	struct snd_pcm_substream *substream;
+	int err = -1;
+
+	if (substrindx < 0 || substrindx > 1)
+		return err;
+	substream = pcm_oss_file->streams[substrindx];
+	if (substream == NULL)
+		return 0; /* Don't complain, consider as zero active channels */
+	return substream->runtime->oss.channels;
+}
+
 static int snd_pcm_oss_set_channels(struct snd_pcm_oss_file *pcm_oss_file, unsigned int channels)
 {
-	int idx;
+	struct snd_pcm_substream *substream;
+	int playback_channels, capture_channels, channels_set = -1;
+
 	if (channels < 1)
 		channels = 1;
-	if (channels > 128)
+	if (channels > 65025)
 		return -EINVAL;
-	for (idx = 1; idx >= 0; --idx) {
-		struct snd_pcm_substream *substream = pcm_oss_file->streams[idx];
-		struct snd_pcm_runtime *runtime;
-		if (substream == NULL)
-			continue;
-		runtime = substream->runtime;
-		if (runtime->oss.channels != channels) {
-			runtime->oss.params = 1;
-			runtime->oss.channels = channels;
+
+	playback_channels = channels & 255;
+			/* lower 8 bits always set playback channels */
+	if (playback_channels > 128)
+		return -EINVAL;
+	substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
+	if (substream != NULL)
+		if (substream->runtime->oss.channels != playback_channels) {
+			substream->runtime->oss.params = 1;
+			substream->runtime->oss.channels = playback_channels;
 		}
+
+	substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
+	if (channels >255) { /* Enhanced channel set mode */
+		capture_channels = channels / 256 & 255;
+			 /* 2nd 8 bits set capture channels */
+		if (capture_channels > 128)
+			return -EINVAL;
+		if (substream != NULL)
+			if (substream->runtime->oss.channels != capture_channels) {
+				substream->runtime->oss.params = 1;
+				substream->runtime->oss.channels = capture_channels;
+			}
+		channels_set = snd_pcm_oss_get_substream_channels(
+				   pcm_oss_file, SNDRV_PCM_STREAM_PLAYBACK)
+				   + 256 * snd_pcm_oss_get_substream_channels(
+				   pcm_oss_file, SNDRV_PCM_STREAM_CAPTURE);
+	} else {  /* Standard mode, same num channels play and capture */
+		if (substream != NULL)
+			if (substream->runtime->oss.channels != channels) {
+				 /* Capture channels same as playback */
+				substream->runtime->oss.params = 1;
+				substream->runtime->oss.channels = channels;
+			}
+		channels_set = snd_pcm_oss_get_channels(pcm_oss_file);
 	}
-	return snd_pcm_oss_get_channels(pcm_oss_file);
+	return channels_set;
 }

 static int snd_pcm_oss_get_channels(struct snd_pcm_oss_file *pcm_oss_file)

[-- Attachment #3: pa-oss-duplex-chans-fix.diff --]
[-- Type: text/x-diff, Size: 2978 bytes --]

--- lib-src/portaudio/pa_unix_oss/pa_unix-orig.c	2004-11-18 06:17:34.000000000 +0000
+++ lib-src/portaudio/pa_unix_oss/pa_unix.c	2006-07-05 15:23:19.000000000 +0100
@@ -5,6 +5,8 @@
  *
  * Copyright (c) 1999-2000 Phil Burk
  *
+ *  Linux-Duplex-'bug' fix Alan Horstmann  26.6.06
+ *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files
  * (the "Software"), to deal in the Software without restriction,
@@ -778,12 +781,11 @@
 
     /* ------------------------- OPEN DEVICE -----------------------*/
 
-    /* just output */
     if (past->past_OutputDeviceID == past->past_InputDeviceID)
     {
 
         if ((past->past_NumOutputChannels > 0) && (past->past_NumInputChannels > 0) )
-        {
+        {  /* Duplex; input and output from same device */
             pad = Pa_GetInternalDevice( past->past_OutputDeviceID );
             DBUG(("PaHost_OpenStream: attempt to open %s for O_RDWR\n", pad->pad_DeviceName ));
 
@@ -806,17 +807,30 @@
                 result = paHostError;
                 goto error;
             }
+
+            int format_NumChannels, latency_NumChannels;
+
+            if (past->past_NumInputChannels > past->past_NumOutputChannels )
+                latency_NumChannels = past->past_NumInputChannels;
+            else
+                latency_NumChannels = past->past_NumOutputChannels ;
+
+            if (past->past_NumOutputChannels == past->past_NumInputChannels)
+                format_NumChannels = past->past_NumOutputChannels ;
+            else  /* Use new AH enhanced OSS channel setting feature  */
+                format_NumChannels = past->past_NumOutputChannels  + 256 * past->past_NumInputChannels;
+
             Pa_SetLatency( pahsc->pahsc_OutputHandle,
                            past->past_NumUserBuffers, past->past_FramesPerUserBuffer,
-                           past->past_NumOutputChannels );
+                           latency_NumChannels );
             result = Pa_SetupDeviceFormat( pahsc->pahsc_OutputHandle,
-                                           past->past_NumOutputChannels, (int)past->past_SampleRate );
+                                           format_NumChannels, (int)past->past_SampleRate );
         }
     }
     else
     {
         if (past->past_NumOutputChannels > 0)
-        {
+        {  /*  Output only  */
             pad = Pa_GetInternalDevice( past->past_OutputDeviceID );
             DBUG(("PaHost_OpenStream: attempt to open %s for O_WRONLY\n", pad->pad_DeviceName ));
             /* dmazzoni: test it first in nonblocking mode to
@@ -845,7 +857,7 @@
         }
 
         if (past->past_NumInputChannels > 0)
-        {
+        {  /*  Input capture only  */
             pad = Pa_GetInternalDevice( past->past_InputDeviceID );
             DBUG(("PaHost_OpenStream: attempt to open %s for O_RDONLY\n", pad->pad_DeviceName ));
             /* dmazzoni: test it first in nonblocking mode to

[-- Attachment #4: Type: text/plain, Size: 160 bytes --]

_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Alsa-OSS Duplex bug (revisited)
  2007-05-27 22:23 Alsa-OSS Duplex bug (revisited) Alan Horstmann
@ 2007-05-29 16:55 ` Takashi Iwai
  2007-05-29 22:16   ` Alan Horstmann
  0 siblings, 1 reply; 16+ messages in thread
From: Takashi Iwai @ 2007-05-29 16:55 UTC (permalink / raw)
  To: Alan Horstmann; +Cc: ALSA devel

At Sun, 27 May 2007 23:23:13 +0100,
Alan Horstmann wrote:
> 
> About a year ago I posted an explaination of the cause of non-functioning with 
> Alsa-OSS in duplex, together with a workaround patch.  After some discussion 
> the thread ended.  However since then there has been a steady trickle of 
> downloads of the patches from my host (it can also be found elsewhere) and 
> some reports of great success,eg
> 
> 	http://audacityteam.org/forum/thread/1388  (2nd page especially)
> 
> In attempting to tidy up some loose ends, I hope you can bear with me 
> revisiting this and making the case for it's acceptance.  I am aware the 
> Alsa-OSS is not of much interest to developers, and it might be said 'use 
> native Alsa'; however that is not possible or desirable in all applications, 
> and anyway, why provide an OSS emulation that cannot be made to work 
> properly?
> 
> To summarise the problem first:
> 
> OSS provides a single SNDCTL_DSP_CHANNELS ioctl; where a device is duplex the 
> number of capture and playback channels cannot be set separately.  With 
> original OSS this was not a problem AFAIK because separate devices are 
> created for capture and playback, ie they are not used duplex.  However 
> Alsa-OSS in most cases creates a single combined device, which only operates 
> correctly when an equal number of capture and playback channels are used.
> 
> The Workaround:
> 
> The workaround I proposed and now use constantly is like a secret trapdoor.  
> Where the existing interface is adequate (ie captue channels == playback 
> channels, or non-duplex) nothing changes, and SNDCTL_DSP_CHANNELS is set with 
> a number between 0 and 128.  It is fully compatible with apps that don't know 
> of the secret door -the front door is used!
> 
> However, if an app needs to set capture channels != playback channels, in 
> duplex, at present the stream will malfunction every time.  But with this 
> patch applied, if the app knows the workaround, then it can simply set 
> SNDCTL_DSP_CHANNELS as  playback + 256*capture channels, and this will be 
> interpreted correctly in the patched Alsa-OSS and the stream functions 
> correctly.
> 
> As I say, there is therefore no loss of compatibility in either direction.  
> Providing the app only uses the special formula when necessary rather than 
> always, it is only providing a way to fix something that is broken.  It would 
> seem to me of value to add the patch to Alsa so that the workaround can be 
> effected by changes to the app only, without also having to patch and compile 
> a replacement Alsa.  Whilst it is by no means ideal, it does overcome the 
> underlying problem successfully.  Details of the workaround could be added to 
> the  OSS-Emulation.html document.
> 
> Patch for 1.0.14rc4 is attached for consideration, together with example 
> portaudio patch.

Thanks for the patch.  I see how you struggled with this problem.

Well, this is a bit hard problem to decide which to go.
While I see the advantage by your hack (small and backward
compatible), I feel that it's too hackish -- it introduces an
incompatible way of the existing ioctl.

So, I'm not fully convinced by this change yet.

OK, let's whip this dead horse again.

After a quick thought, another possible fix would be to let apps open
each direction separately.  For that,

- add some way to make the given PCM stream to non-fullduplex
  (proc or module options?)

or

- change portaudio to open each direction separately, O_RDONLY and
  O_WRONLY at first, then use O_RDWR as fallback
  
Are these feasible?


Takashi

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Alsa-OSS Duplex bug (revisited)
  2007-05-29 16:55 ` Takashi Iwai
@ 2007-05-29 22:16   ` Alan Horstmann
  2007-05-30  6:47     ` Clemens Ladisch
  0 siblings, 1 reply; 16+ messages in thread
From: Alan Horstmann @ 2007-05-29 22:16 UTC (permalink / raw)
  To: ALSA devel; +Cc: Takashi Iwai

On Tuesday 29 May 2007 17:55, you wrote:
> At Sun, 27 May 2007 23:23:13 +0100,
>
> Alan Horstmann wrote:
.......................................
> > Patch for 1.0.14rc4 is attached for consideration, together with example
> > portaudio patch.
>
> Thanks for the patch.  I see how you struggled with this problem.

Thanks for giving this some consideration...

> Well, this is a bit hard problem to decide which to go.
> While I see the advantage by your hack (small and backward
> compatible), I feel that it's too hackish -- it introduces an
> incompatible way of the existing ioctl.
>
Do you mean in that ioctls in general are not meant to work like that, in 
effect passing 2 numbers rather than one?

> So, I'm not fully convinced by this change yet.
>
> OK, let's whip this dead horse again.
>
> After a quick thought, another possible fix would be to let apps open
> each direction separately.  For that,
>
> - add some way to make the given PCM stream to non-fullduplex
>   (proc or module options?)

Are you thinking that if an option were set, Alsa-OSS would create separate 
devices for capture and playback rather than a single duplex device?  That 
would remove the problem, I think.

> or
>
> - change portaudio to open each direction separately, O_RDONLY and
>   O_WRONLY at first, then use O_RDWR as fallback

Do you mean O_RDONLY first, set capture channels, then O_WRONLY and set 
playback channels before finally O_RDWR in such a way that the previous 
values are retained?  This sounds tricky to implement depending on the apps 
code structure, but might be effective.

> Are these feasible?

The advantage of my proposal is that the ioctl value is a simple integer, and 
can pass between functions as a parameter, or be part of a varible structure 
in just the same way as the present channels number.  Therefore changes to 
the app are very small (portaudio is just one example).

What is frustrating is that the Alsa-OSS stream is fine in duplex with 
variable numbers of channels, but it is simply the lack of a way to pass the 
two numbers to the stream since the OSS ioctl only has one number.  If two 
had been used originally, all would be fine!

Alan

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Alsa-OSS Duplex bug (revisited)
  2007-05-29 22:16   ` Alan Horstmann
@ 2007-05-30  6:47     ` Clemens Ladisch
  2007-05-30 17:05       ` Takashi Iwai
  2007-05-31 21:00       ` Alan Horstmann
  0 siblings, 2 replies; 16+ messages in thread
From: Clemens Ladisch @ 2007-05-30  6:47 UTC (permalink / raw)
  To: Alan Horstmann, ALSA devel; +Cc: Takashi Iwai

Alan Horstmann wrote:
> On Tuesday 29 May 2007 17:55, you wrote:
> > While I see the advantage by your hack (small and backward
> > compatible), I feel that it's too hackish -- it introduces an
> > incompatible way of the existing ioctl.
> 
> Do you mean in that ioctls in general are not meant to work like that, in 
> effect passing 2 numbers rather than one?

No, packing two values into one numbers is done with other ioctls too,
e.g., SNDCTL_DSP_SETFRAGMENT.

The problem I see is that your patch changes the OSS API in a way that
is incompatible with every implementation other than ALSA's.  The whole
purpose of providing the OSS API in the first place is to be compatible
with other implementations.

> > After a quick thought, another possible fix would be to let apps open
> > each direction separately.  For that,
> >
> > - add some way to make the given PCM stream to non-fullduplex
> >   (proc or module options?)
> 
> Are you thinking that if an option were set, Alsa-OSS would create separate 
> devices for capture and playback rather than a single duplex device? 

No; just a way to disable DSP_CAP_DUPLEX and/or SNDCTL_DSP_SETDUPLEX.
When these do not work, applications are forced to open the playback
and capture devices separately, e.g.:

fd_playback = open("/dev/dsp", O_WRONLY);
fd_capture = open("/dev/dsp", O_RDONLY);

> > - change portaudio to open each direction separately, O_RDONLY and
> >   O_WRONLY at first, then use O_RDWR as fallback

This would be the preferred way.  After all, this is the only way that
is possible with the existing OSS API when you want to use different
sample formats, and it is recommended in all cases (see
<http://manuals.opensound.com/developer/full_duplex.html>).


Regards,
Clemens

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Alsa-OSS Duplex bug (revisited)
  2007-05-30  6:47     ` Clemens Ladisch
@ 2007-05-30 17:05       ` Takashi Iwai
  2007-05-30 22:12         ` Alan Horstmann
  2007-05-31 21:00       ` Alan Horstmann
  1 sibling, 1 reply; 16+ messages in thread
From: Takashi Iwai @ 2007-05-30 17:05 UTC (permalink / raw)
  To: Clemens Ladisch; +Cc: ALSA devel

At Wed, 30 May 2007 08:47:14 +0200,
Clemens Ladisch wrote:
> 
> Alan Horstmann wrote:
> > On Tuesday 29 May 2007 17:55, you wrote:
> > > While I see the advantage by your hack (small and backward
> > > compatible), I feel that it's too hackish -- it introduces an
> > > incompatible way of the existing ioctl.
> > 
> > Do you mean in that ioctls in general are not meant to work like that, in 
> > effect passing 2 numbers rather than one?
> 
> No, packing two values into one numbers is done with other ioctls too,
> e.g., SNDCTL_DSP_SETFRAGMENT.
> 
> The problem I see is that your patch changes the OSS API in a way that
> is incompatible with every implementation other than ALSA's.  The whole
> purpose of providing the OSS API in the first place is to be compatible
> with other implementations.

Exactly.

> > > After a quick thought, another possible fix would be to let apps open
> > > each direction separately.  For that,
> > >
> > > - add some way to make the given PCM stream to non-fullduplex
> > >   (proc or module options?)
> > 
> > Are you thinking that if an option were set, Alsa-OSS would create separate 
> > devices for capture and playback rather than a single duplex device? 
> 
> No; just a way to disable DSP_CAP_DUPLEX and/or SNDCTL_DSP_SETDUPLEX.
> When these do not work, applications are forced to open the playback
> and capture devices separately, e.g.:
> 
> fd_playback = open("/dev/dsp", O_WRONLY);
> fd_capture = open("/dev/dsp", O_RDONLY);

I thought of a similar hack but it seems that many apps don't check /
set DUPLEX capability.  So, this might not work on many apps.

> > > - change portaudio to open each direction separately, O_RDONLY and
> > >   O_WRONLY at first, then use O_RDWR as fallback
> 
> This would be the preferred way.  After all, this is the only way that
> is possible with the existing OSS API when you want to use different
> sample formats, and it is recommended in all cases (see
> <http://manuals.opensound.com/developer/full_duplex.html>).

Right.  For example, in the case of audacity, the change would be like
the following patch (untested).


Takashi

--- lib-src/portaudio/pa_unix_oss/pa_unix.c-dist	2007-05-30 17:52:10.000000000 +0200
+++ lib-src/portaudio/pa_unix_oss/pa_unix.c	2007-05-30 18:22:09.000000000 +0200
@@ -720,12 +720,45 @@ int Pa_GetMinNumBuffers( int framesPerBu
 }
 
 /*******************************************************************/
+
+static int do_open(internalPortAudioDevice *pad, int flags, int verbose)
+{
+    int fd = open(pad->pad_DeviceName, flags);
+    if (fd < 0)
+    {
+	if (verbose)
+	    ERR_RPT(("PaHost_OpenStream: could not open %s for %s\n",
+		     pad->pad_DeviceName,
+		     (flags == O_RDONLY ? "O_RDONLY" :
+		      (flags == O_WRONLY ? "O_WRONLY" : "O_RDWR"))));
+    }
+    return fd;
+}
+
+static int open_device(internalPortAudioDevice *pad, int flags, int verbose)
+{
+    int fd;
+
+    /* dmazzoni: test it first in nonblocking mode to
+       make sure the device is not busy */
+    fd = do_open(pad->pad_DeviceName, flags|O_NONBLOCK, verbose);
+    if (fd < 0)
+	return BAD_DEVICE_ID;
+    close(fd);
+
+    fd = do_open(pad->pad_DeviceName, flags, verbose);
+    if (fd < 0)
+	return BAD_DEVICE_ID;
+    return fd;
+}
+
 PaError PaHost_OpenStream( internalPortAudioStream   *past )
 {
     PaError          result = paNoError;
     PaHostSoundControl *pahsc;
     unsigned int     minNumBuffers;
     internalPortAudioDevice *pad;
+    int full_duplex;
     DBUG(("PaHost_OpenStream() called.\n" ));
 
     /* Allocate and initialize host data. */
@@ -778,102 +811,89 @@ PaError PaHost_OpenStream( internalPortA
 
     /* ------------------------- OPEN DEVICE -----------------------*/
 
-    /* just output */
-    if (past->past_OutputDeviceID == past->past_InputDeviceID)
-    {
-
-        if ((past->past_NumOutputChannels > 0) && (past->past_NumInputChannels > 0) )
-        {
-            pad = Pa_GetInternalDevice( past->past_OutputDeviceID );
-            DBUG(("PaHost_OpenStream: attempt to open %s for O_RDWR\n", pad->pad_DeviceName ));
-
-            /* dmazzoni: test it first in nonblocking mode to
-               make sure the device is not busy */
-            pahsc->pahsc_InputHandle = open(pad->pad_DeviceName,O_RDWR|O_NONBLOCK);
-            if(pahsc->pahsc_InputHandle==-1)
-            {
-                ERR_RPT(("PaHost_OpenStream: could not open %s for O_RDWR\n", pad->pad_DeviceName ));
-                result = paHostError;
-                goto error;
-            }
-            close(pahsc->pahsc_InputHandle);
-
-            pahsc->pahsc_OutputHandle = pahsc->pahsc_InputHandle =
-                                            open(pad->pad_DeviceName,O_RDWR);
-            if(pahsc->pahsc_InputHandle==-1)
-            {
-                ERR_RPT(("PaHost_OpenStream: could not open %s for O_RDWR\n", pad->pad_DeviceName ));
-                result = paHostError;
-                goto error;
-            }
-            Pa_SetLatency( pahsc->pahsc_OutputHandle,
-                           past->past_NumUserBuffers, past->past_FramesPerUserBuffer,
-                           past->past_NumOutputChannels );
-            result = Pa_SetupDeviceFormat( pahsc->pahsc_OutputHandle,
-                                           past->past_NumOutputChannels, (int)past->past_SampleRate );
-        }
-    }
+    if (past->past_OutputDeviceID == past->past_InputDeviceID &&
+        past->past_NumOutputChannels > 0 &&
+	past->past_NumInputChannels > 0)
+	full_duplex = 1;
     else
+	full_duplex = 0;
+
+    /* try to open each direction separately, at first */
+    if (past->past_NumOutputChannels > 0)
     {
-        if (past->past_NumOutputChannels > 0)
-        {
-            pad = Pa_GetInternalDevice( past->past_OutputDeviceID );
-            DBUG(("PaHost_OpenStream: attempt to open %s for O_WRONLY\n", pad->pad_DeviceName ));
-            /* dmazzoni: test it first in nonblocking mode to
-               make sure the device is not busy */
-            pahsc->pahsc_OutputHandle = open(pad->pad_DeviceName,O_WRONLY|O_NONBLOCK);
-            if(pahsc->pahsc_OutputHandle==-1)
-            {
-                ERR_RPT(("PaHost_OpenStream: could not open %s for O_WRONLY\n", pad->pad_DeviceName ));
-                result = paHostError;
-                goto error;
-            }
-            close(pahsc->pahsc_OutputHandle);
-
-            pahsc->pahsc_OutputHandle = open(pad->pad_DeviceName,O_WRONLY);
-            if(pahsc->pahsc_OutputHandle==-1)
-            {
-                ERR_RPT(("PaHost_OpenStream: could not open %s for O_WRONLY\n", pad->pad_DeviceName ));
-                result = paHostError;
-                goto error;
-            }
-            Pa_SetLatency( pahsc->pahsc_OutputHandle,
-                           past->past_NumUserBuffers, past->past_FramesPerUserBuffer,
-                           past->past_NumOutputChannels );
-            result = Pa_SetupOutputDeviceFormat( pahsc->pahsc_OutputHandle,
-                                           past->past_NumOutputChannels, (int)past->past_SampleRate );
-        }
+	pad = Pa_GetInternalDevice( past->past_OutputDeviceID );
+	DBUG(("PaHost_OpenStream: attempt to open %s for O_WRONLY\n", pad->pad_DeviceName ));
+	pahsc->pahsc_OutputHandle = open_device(pad, O_WRONLY,
+						!full_duplex);
+	if (pahsc->pahsc_OutputHandle < 0)
+	{
+	    result = paHostError;
+	    goto check_duplex;
+	}
+	Pa_SetLatency( pahsc->pahsc_OutputHandle,
+		       past->past_NumUserBuffers, past->past_FramesPerUserBuffer,
+		       past->past_NumOutputChannels );
+	result = Pa_SetupOutputDeviceFormat( pahsc->pahsc_OutputHandle,
+					     past->past_NumOutputChannels, (int)past->past_SampleRate );
+	if (result < 0)
+	{
+	    close(pahsc->pahsc_OutputHandle);
+	    pahsc->pahsc_OutputHandle = BAD_DEVICE_ID;
+	    goto check_duplex;
+	}
+    }
+
+    if (past->past_NumInputChannels > 0)
+    {
+	pad = Pa_GetInternalDevice( past->past_InputDeviceID );
+
+	DBUG(("PaHost_OpenStream: attempt to open %s for O_RDONLY\n", pad->pad_DeviceName ));
+	pahsc->pahsc_InputHandle = open_device(pad, O_RDONLY,
+					       !full_duplex);
+	if (pahsc->pahsc_InputHandle < 0)
+	{
+	    result = paHostError;
+	    goto check_duplex;
+	}
+	Pa_SetLatency( pahsc->pahsc_InputHandle, /* DH20010115 - was OutputHandle! */
+		       past->past_NumUserBuffers, past->past_FramesPerUserBuffer,
+		       past->past_NumInputChannels );
+	result = Pa_SetupInputDeviceFormat( pahsc->pahsc_InputHandle,
+					    past->past_NumInputChannels, (int)past->past_SampleRate );
+	if (result < 0)
+	{
+	    close(pahsc->pahsc_InputHandle);
+	    pahsc->pahsc_InputHandle = BAD_DEVICE_ID;
+	    goto check_duplex;
+	}
+    }
+
+ check_duplex:
+    /* if opening one of the direction fails for full-duplex,
+     * try to open a single device with O_RDWR
+     */
+    if (full_duplex &&
+	(phasc->phasc_OutputHandle < 0 || phasc->phasc_InputHandle < 0))
+    {
+	pad = Pa_GetInternalDevice( past->past_OutputDeviceID );
+	DBUG(("PaHost_OpenStream: attempt to open %s for O_RDWR\n", pad->pad_DeviceName ));
 
-        if (past->past_NumInputChannels > 0)
-        {
-            pad = Pa_GetInternalDevice( past->past_InputDeviceID );
-            DBUG(("PaHost_OpenStream: attempt to open %s for O_RDONLY\n", pad->pad_DeviceName ));
-            /* dmazzoni: test it first in nonblocking mode to
-               make sure the device is not busy */
-            pahsc->pahsc_InputHandle = open(pad->pad_DeviceName,O_RDONLY|O_NONBLOCK);
-            if(pahsc->pahsc_InputHandle==-1)
-            {
-                ERR_RPT(("PaHost_OpenStream: could not open %s for O_RDONLY\n", pad->pad_DeviceName ));
-                result = paHostError;
-                goto error;
-            }
-            close(pahsc->pahsc_InputHandle);
-
-            pahsc->pahsc_InputHandle = open(pad->pad_DeviceName,O_RDONLY);
-            if(pahsc->pahsc_InputHandle==-1)
-            {
-                ERR_RPT(("PaHost_OpenStream: could not open %s for O_RDONLY\n", pad->pad_DeviceName ));
-                result = paHostError;
-                goto error;
-            }
-            Pa_SetLatency( pahsc->pahsc_InputHandle, /* DH20010115 - was OutputHandle! */
-                           past->past_NumUserBuffers, past->past_FramesPerUserBuffer,
-                           past->past_NumInputChannels );
-            result = Pa_SetupInputDeviceFormat( pahsc->pahsc_InputHandle,
-                                           past->past_NumInputChannels, (int)past->past_SampleRate );
-        }
+	pahsc->pahsc_OutputHandle = open_device(pad, O_RDWR, 1);
+	if (phasc->pahsc_OutputHandle < 0)
+	{
+	    result = paHostError;
+	    goto error;
+	}
+	phasc->phasc_InputHandle = phasc->phasc_OutputHandle;
+	Pa_SetLatency( pahsc->pahsc_OutputHandle,
+		       past->past_NumUserBuffers, past->past_FramesPerUserBuffer,
+		       past->past_NumOutputChannels );
+	result = Pa_SetupDeviceFormat( pahsc->pahsc_OutputHandle,
+				       past->past_NumOutputChannels, (int)past->past_SampleRate );
+	    
     }
-
+    if (result < 0)
+	goto error;
 
     DBUG(("PaHost_OpenStream: SUCCESS - result = %d\n", result ));
     return result;

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Alsa-OSS Duplex bug (revisited)
  2007-05-30 17:05       ` Takashi Iwai
@ 2007-05-30 22:12         ` Alan Horstmann
  0 siblings, 0 replies; 16+ messages in thread
From: Alan Horstmann @ 2007-05-30 22:12 UTC (permalink / raw)
  To: ALSA devel; +Cc: Takashi Iwai

On Wednesday 30 May 2007 18:05, Takashi wrote:
> At Wed, 30 May 2007 08:47:14 +0200,
>
> Clemens Ladisch wrote:
> > Alan Horstmann wrote:
> > > On Tuesday 29 May 2007 17:55, Takashi wrote:
>
> > > > After a quick thought, another possible fix would be to let apps open
> > > > each direction separately.  For that,
> > > >
> > > > - add some way to make the given PCM stream to non-fullduplex
> > > >   (proc or module options?)
> > >
> > > Are you thinking that if an option were set, Alsa-OSS would create
> > > separate devices for capture and playback rather than a single duplex
> > > device?
> >
> > No; just a way to disable DSP_CAP_DUPLEX and/or SNDCTL_DSP_SETDUPLEX.
> > When these do not work, applications are forced to open the playback
> > and capture devices separately, e.g.:
> >
> > fd_playback = open("/dev/dsp", O_WRONLY);
> > fd_capture = open("/dev/dsp", O_RDONLY);

So are you saying that the same device can reliably be opened both O_RDONLY 
and O_WRONLY -AT THE SAME TIME but with different numbers of channels?  That 
is a bit counter-intuitive given the ONLY part, but if true would probably 
provide a workable solution.

> I thought of a similar hack but it seems that many apps don't check /
> set DUPLEX capability.  So, this might not work on many apps.
>
> > > > - change portaudio to open each direction separately, O_RDONLY and
> > > >   O_WRONLY at first, then use O_RDWR as fallback
> >
> > This would be the preferred way.  After all, this is the only way that
> > is possible with the existing OSS API when you want to use different
> > sample formats, and it is recommended in all cases (see
> > <http://manuals.opensound.com/developer/full_duplex.html>).

But note that the 4front OSS creates lots of devices -see 
http://manuals.opensound.com/developer/oss_devices.html
so they can be opened sparately always.

> Right.  For example, in the case of audacity, the change would be like
> the following patch (untested).

Well I quickly hacked something similar to try, and did seem to be able to 
open input_handle and output_handle separately, and have Audacity 'Duplex 
recording' so that could be fine.  I will do more testing and report back!

Alan

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Alsa-OSS Duplex bug (revisited)
  2007-05-30  6:47     ` Clemens Ladisch
  2007-05-30 17:05       ` Takashi Iwai
@ 2007-05-31 21:00       ` Alan Horstmann
  2007-06-01  9:56         ` Takashi Iwai
  1 sibling, 1 reply; 16+ messages in thread
From: Alan Horstmann @ 2007-05-31 21:00 UTC (permalink / raw)
  To: Clemens Ladisch; +Cc: Takashi Iwai, ALSA devel

On Wednesday 30 May 2007 07:47, you wrote:
> Alan Horstmann wrote:
> > On Tuesday 29 May 2007 17:55, you wrote:
> > > While I see the advantage by your hack (small and backward
> > > compatible), I feel that it's too hackish -- it introduces an
> > > incompatible way of the existing ioctl.
> >
> > Do you mean in that ioctls in general are not meant to work like that, in
> > effect passing 2 numbers rather than one?
>
> No, packing two values into one numbers is done with other ioctls too,
> e.g., SNDCTL_DSP_SETFRAGMENT.
>
> The problem I see is that your patch changes the OSS API in a way that
> is incompatible with every implementation other than ALSA's.  The whole
> purpose of providing the OSS API in the first place is to be compatible
> with other implementations.
>
> > > After a quick thought, another possible fix would be to let apps open
> > > each direction separately.  For that,
> > >
> > > - add some way to make the given PCM stream to non-fullduplex
> > >   (proc or module options?)
> >
> > Are you thinking that if an option were set, Alsa-OSS would create
> > separate devices for capture and playback rather than a single duplex
> > device?
>
> No; just a way to disable DSP_CAP_DUPLEX and/or SNDCTL_DSP_SETDUPLEX.
> When these do not work, applications are forced to open the playback
> and capture devices separately, e.g.:
>
> fd_playback = open("/dev/dsp", O_WRONLY);
> fd_capture = open("/dev/dsp", O_RDONLY);
>
> > > - change portaudio to open each direction separately, O_RDONLY and
> > >   O_WRONLY at first, then use O_RDWR as fallback
>
> This would be the preferred way.  After all, this is the only way that
> is possible with the existing OSS API when you want to use different
> sample formats, and it is recommended in all cases (see
> <http://manuals.opensound.com/developer/full_duplex.html>).

My reading of the 4Front info is different.  I read that they recommend best 
opening SEPARATE devices, one O_RDONLY and the other O_WRONLY, in their 
scheme called 'twodevice'.  It also states in fulldup.c:-

"... The one device full duplex scheme requires that the device file is opened 
with O_RDWR."

Whereas what is being suggested here is to open /dev/dsp twice simultaneously, 
O_RDONLY and O_WRONLY which 4Front definitely doesn't propose.

The crutial point is that Alsa-OSS at present isn't really compatible with 
4Front etc BECAUSE they implement separate NON-duplex devices for each 
capture and playback channel pair, whereas Alsa-OSS just has one, duplex!  If 
for example I use the 4Front driver for my DMX6fire, then 
(-see:	http://manuals.opensound.com/developer/oss_devices.html)

I would have 11 non-duplex devices, which can be opened separately to record 
and play to the card without the channels-set problem.  With Alsa-OSS I have 
just one!  Even if Alsa-OSS had just the 'all outputs' and 'all inputs' 
devices that would be fine.

It seems odd that an OSS emulated device is provided to an audio card that 
could have differing numbers of capture and playback channels, eg 4 capture 
and 2 playback, but it is impossible to set 4C and 2P when opening it for 
simultaneous capture and playback.  The underlying stream has no problem with 
doing so, it is just there is no way to pass the numbers.  My workaround is 
to solve an incompatibility that already exists.  It seems 4Front avoids this 
by creating non-duplex devices.  The patch extends the functionality of the 
ioctl in a way that only Alsa-OSS may need, (or perhaps all OSS should 
adopt?).

Alan

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Alsa-OSS Duplex bug (revisited)
  2007-05-31 21:00       ` Alan Horstmann
@ 2007-06-01  9:56         ` Takashi Iwai
  2007-06-03 19:55           ` Alan Horstmann
  0 siblings, 1 reply; 16+ messages in thread
From: Takashi Iwai @ 2007-06-01  9:56 UTC (permalink / raw)
  To: Alan Horstmann; +Cc: ALSA devel

At Thu, 31 May 2007 22:00:25 +0100,
Alan Horstmann wrote:
> 
> On Wednesday 30 May 2007 07:47, you wrote:
> > Alan Horstmann wrote:
> > > On Tuesday 29 May 2007 17:55, you wrote:
> > > > While I see the advantage by your hack (small and backward
> > > > compatible), I feel that it's too hackish -- it introduces an
> > > > incompatible way of the existing ioctl.
> > >
> > > Do you mean in that ioctls in general are not meant to work like that, in
> > > effect passing 2 numbers rather than one?
> >
> > No, packing two values into one numbers is done with other ioctls too,
> > e.g., SNDCTL_DSP_SETFRAGMENT.
> >
> > The problem I see is that your patch changes the OSS API in a way that
> > is incompatible with every implementation other than ALSA's.  The whole
> > purpose of providing the OSS API in the first place is to be compatible
> > with other implementations.
> >
> > > > After a quick thought, another possible fix would be to let apps open
> > > > each direction separately.  For that,
> > > >
> > > > - add some way to make the given PCM stream to non-fullduplex
> > > >   (proc or module options?)
> > >
> > > Are you thinking that if an option were set, Alsa-OSS would create
> > > separate devices for capture and playback rather than a single duplex
> > > device?
> >
> > No; just a way to disable DSP_CAP_DUPLEX and/or SNDCTL_DSP_SETDUPLEX.
> > When these do not work, applications are forced to open the playback
> > and capture devices separately, e.g.:
> >
> > fd_playback = open("/dev/dsp", O_WRONLY);
> > fd_capture = open("/dev/dsp", O_RDONLY);
> >
> > > > - change portaudio to open each direction separately, O_RDONLY and
> > > >   O_WRONLY at first, then use O_RDWR as fallback
> >
> > This would be the preferred way.  After all, this is the only way that
> > is possible with the existing OSS API when you want to use different
> > sample formats, and it is recommended in all cases (see
> > <http://manuals.opensound.com/developer/full_duplex.html>).
> 
> My reading of the 4Front info is different.  I read that they recommend best 
> opening SEPARATE devices, one O_RDONLY and the other O_WRONLY, in their 
> scheme called 'twodevice'.  It also states in fulldup.c:-
> 
> "... The one device full duplex scheme requires that the device file is opened 
> with O_RDWR."
> 
> Whereas what is being suggested here is to open /dev/dsp twice simultaneously, 
> O_RDONLY and O_WRONLY which 4Front definitely doesn't propose.
> 
> The crutial point is that Alsa-OSS at present isn't really compatible with 
> 4Front etc BECAUSE they implement separate NON-duplex devices for each 
> capture and playback channel pair, whereas Alsa-OSS just has one, duplex!  If 
> for example I use the 4Front driver for my DMX6fire, then 
> (-see:	http://manuals.opensound.com/developer/oss_devices.html)
> 
> I would have 11 non-duplex devices, which can be opened separately to record 
> and play to the card without the channels-set problem.  With Alsa-OSS I have 
> just one!  Even if Alsa-OSS had just the 'all outputs' and 'all inputs' 
> devices that would be fine.

Well, I'd say that the current ALSA-OSS implementation _is_ compatible
to OSS API.  What they do is also a pure hack, as you know, just a
workaround because the API doesn't provide the functionality
properly for full-duplex with multi-channels.  The solution might be
different, but it's not the question about "compatibility".

> It seems odd that an OSS emulated device is provided to an audio card that 
> could have differing numbers of capture and playback channels, eg 4 capture 
> and 2 playback, but it is impossible to set 4C and 2P when opening it for 
> simultaneous capture and playback.  The underlying stream has no problem with 
> doing so, it is just there is no way to pass the numbers.  My workaround is 
> to solve an incompatibility that already exists.  It seems 4Front avoids this 
> by creating non-duplex devices.  The patch extends the functionality of the 
> ioctl in a way that only Alsa-OSS may need, (or perhaps all OSS should 
> adopt?).

The problem is that your patch introduces a real "incompatibility",
because it's an extension.  That is what I don't like.
And, in your way, you'll have to change _both_ kernel and apps.

Following this thread, I come to believe that the problem with
audacity is actually the application problem.  It tries to open a
full-duplex device with different number of channels for both
directions.  It cannot work because it's not defined in API.  OTOH, if
the number of channels are same for both directions, it should work
with O_RDWR.

So, the fix would be simply like below...


Takashi

--- lib-src/portaudio/pa_unix_oss/pa_unix.c-dist	2007-05-30 17:52:10.000000000 +0200
+++ lib-src/portaudio/pa_unix_oss/pa_unix.c	2007-06-01 11:51:35.000000000 +0200
@@ -779,7 +779,8 @@ PaError PaHost_OpenStream( internalPortA
     /* ------------------------- OPEN DEVICE -----------------------*/
 
     /* just output */
-    if (past->past_OutputDeviceID == past->past_InputDeviceID)
+    if (past->past_OutputDeviceID == past->past_InputDeviceID &&
+        past->past_NumOutputChannels == past->past_NumInputChannels)
     {
 
         if ((past->past_NumOutputChannels > 0) && (past->past_NumInputChannels > 0) )

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Alsa-OSS Duplex bug (revisited)
  2007-06-01  9:56         ` Takashi Iwai
@ 2007-06-03 19:55           ` Alan Horstmann
  2007-06-04  8:45             ` Clemens Ladisch
  2007-06-04  8:50             ` Takashi Iwai
  0 siblings, 2 replies; 16+ messages in thread
From: Alan Horstmann @ 2007-06-03 19:55 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: ALSA devel

On Friday 01 June 2007 10:56, you wrote:
> At Thu, 31 May 2007 22:00:25 +0100,
>
> Alan Horstmann wrote:
> > On Wednesday 30 May 2007 07:47, you wrote:
> > > Alan Horstmann wrote:

<< Edited snippets >>

> > > fd_playback = open("/dev/dsp", O_WRONLY);
> > > fd_capture = open("/dev/dsp", O_RDONLY);
> > >
> > > > > - change portaudio to open each direction separately, O_RDONLY and
> > > > >   O_WRONLY at first, then use O_RDWR as fallback
> > >
> > > This would be the preferred way.  After all, this is the only way that
> > > is possible with the existing OSS API when you want to use different
> > > sample formats, and it is recommended in all cases (see
> > > <http://manuals.opensound.com/developer/full_duplex.html>).
> >
> > My reading of the 4Front info is different.  I read that they recommend
> > best opening SEPARATE devices, one O_RDONLY and the other O_WRONLY, in
> > their scheme called 'twodevice'.  It also states in fulldup.c:-
> >
> > "... The one device full duplex scheme requires that the device file is
> > opened with O_RDWR."
> >

> Well, I'd say that the current ALSA-OSS implementation _is_ compatible
> to OSS API.  What they do is also a pure hack, as you know, just a
> workaround because the API doesn't provide the functionality
> properly for full-duplex with multi-channels.  The solution might be
> different, but it's not the question about "compatibility".
>
>
> Following this thread, I come to believe that the problem with
> audacity is actually the application problem.  It tries to open a
> full-duplex device with different number of channels for both
> directions.  It cannot work because it's not defined in API.  OTOH, if
> the number of channels are same for both directions, it should work
> with O_RDWR.
>

Thanks for sticking with it so far -hopefully we are moving towards a 
conclusion so that the result is a definitive recommendation for how to solve 
the problem of the OSS API limitation.

So that there is no misunderstanding, are you willing to confirm that, as far 
as Alsa-OSS goes, opening both
	input_handle = open("/dev/dsp", O_RDONLY)
and
	output_handle = open("/dev/dsp", O_WRONLY)
at the same time is a reliable way to open the device bi-directional, enabling 
different sample formats and/or numbers of channels to be set?  (Actually, I 
am curious whether different sample rates would also work?)

Provided this is so, the recommendation then for duplex as I understand it 
is:-
	a) where the format and no.channels is the same in each direction, 
	    use 
		input_handle = output_handle = open("device", O_RDWR)

	b) where the 2 directions have different format or no.channels use
		input_handle = open("device", O_RDONLY)
		output_handle = open("device", O_WRONLY)

since a) may improve compatibility with other OSS's but b) is necessary due to 
the limitations of the OSS API, whether or not it works with other OSS's.

Alan

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Alsa-OSS Duplex bug (revisited)
  2007-06-03 19:55           ` Alan Horstmann
@ 2007-06-04  8:45             ` Clemens Ladisch
  2007-06-04 11:51               ` Alan Horstmann
  2007-06-04  8:50             ` Takashi Iwai
  1 sibling, 1 reply; 16+ messages in thread
From: Clemens Ladisch @ 2007-06-04  8:45 UTC (permalink / raw)
  To: Alan Horstmann; +Cc: ALSA devel

Alan Horstmann wrote:
> So that there is no misunderstanding, are you willing to confirm that, as far 
> as Alsa-OSS goes, opening both
> 	input_handle = open("/dev/dsp", O_RDONLY)
> and
> 	output_handle = open("/dev/dsp", O_WRONLY)
> at the same time is a reliable way to open the device bi-directional, enabling 
> different sample formats and/or numbers of channels to be set?  (Actually, I 
> am curious whether different sample rates would also work?)

Yes; yes.

This is the _only_ way.  If the hardware supports it, any driver (not
only ALSA) has no choice but to support this.


Regards,
Clemens

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Alsa-OSS Duplex bug (revisited)
  2007-06-03 19:55           ` Alan Horstmann
  2007-06-04  8:45             ` Clemens Ladisch
@ 2007-06-04  8:50             ` Takashi Iwai
  2007-06-04 11:53               ` Alan Horstmann
  1 sibling, 1 reply; 16+ messages in thread
From: Takashi Iwai @ 2007-06-04  8:50 UTC (permalink / raw)
  To: Alan Horstmann; +Cc: ALSA devel

At Sun, 3 Jun 2007 20:55:27 +0100,
Alan Horstmann wrote:
> 
> On Friday 01 June 2007 10:56, you wrote:
> > At Thu, 31 May 2007 22:00:25 +0100,
> >
> > Alan Horstmann wrote:
> > > On Wednesday 30 May 2007 07:47, you wrote:
> > > > Alan Horstmann wrote:
> 
> << Edited snippets >>
> 
> > > > fd_playback = open("/dev/dsp", O_WRONLY);
> > > > fd_capture = open("/dev/dsp", O_RDONLY);
> > > >
> > > > > > - change portaudio to open each direction separately, O_RDONLY and
> > > > > >   O_WRONLY at first, then use O_RDWR as fallback
> > > >
> > > > This would be the preferred way.  After all, this is the only way that
> > > > is possible with the existing OSS API when you want to use different
> > > > sample formats, and it is recommended in all cases (see
> > > > <http://manuals.opensound.com/developer/full_duplex.html>).
> > >
> > > My reading of the 4Front info is different.  I read that they recommend
> > > best opening SEPARATE devices, one O_RDONLY and the other O_WRONLY, in
> > > their scheme called 'twodevice'.  It also states in fulldup.c:-
> > >
> > > "... The one device full duplex scheme requires that the device file is
> > > opened with O_RDWR."
> > >
> 
> > Well, I'd say that the current ALSA-OSS implementation _is_ compatible
> > to OSS API.  What they do is also a pure hack, as you know, just a
> > workaround because the API doesn't provide the functionality
> > properly for full-duplex with multi-channels.  The solution might be
> > different, but it's not the question about "compatibility".
> >
> >
> > Following this thread, I come to believe that the problem with
> > audacity is actually the application problem.  It tries to open a
> > full-duplex device with different number of channels for both
> > directions.  It cannot work because it's not defined in API.  OTOH, if
> > the number of channels are same for both directions, it should work
> > with O_RDWR.
> >
> 
> Thanks for sticking with it so far -hopefully we are moving towards a 
> conclusion so that the result is a definitive recommendation for how to solve 
> the problem of the OSS API limitation.
> 
> So that there is no misunderstanding, are you willing to confirm that, as far 
> as Alsa-OSS goes, opening both
> 	input_handle = open("/dev/dsp", O_RDONLY)
> and
> 	output_handle = open("/dev/dsp", O_WRONLY)
> at the same time is a reliable way to open the device bi-directional, enabling 
> different sample formats and/or numbers of channels to be set?  (Actually, I 
> am curious whether different sample rates would also work?)

Yes, although I didn't confirm it.  If it doesn't work, we should
really fix it.  The dirrerent sample rates should work, too, because
they are different streams.

> Provided this is so, the recommendation then for duplex as I understand it 
> is:-
> 	a) where the format and no.channels is the same in each direction, 
> 	    use 
> 		input_handle = output_handle = open("device", O_RDWR)
> 
> 	b) where the 2 directions have different format or no.channels use
> 		input_handle = open("device", O_RDONLY)
> 		output_handle = open("device", O_WRONLY)
> 
> since a) may improve compatibility with other OSS's but b) is necessary due to 
> the limitations of the OSS API, whether or not it works with other OSS's.

Exactly.  But, remember that the solution for this kind of problems
must be practical - if the theory above isn't true for the practice,
it's of course useless :)


Takashi

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Alsa-OSS Duplex bug (revisited)
  2007-06-04  8:45             ` Clemens Ladisch
@ 2007-06-04 11:51               ` Alan Horstmann
  0 siblings, 0 replies; 16+ messages in thread
From: Alan Horstmann @ 2007-06-04 11:51 UTC (permalink / raw)
  To: Clemens Ladisch; +Cc: ALSA devel

On Monday 04 June 2007 09:45, you wrote:
> Alan Horstmann wrote:
> > So that there is no misunderstanding, are you willing to confirm that, as
> > far as Alsa-OSS goes, opening both
> > 	input_handle = open("/dev/dsp", O_RDONLY)
> > and
> > 	output_handle = open("/dev/dsp", O_WRONLY)
> > at the same time is a reliable way to open the device bi-directional,
> > enabling different sample formats and/or numbers of channels to be set? 
> > (Actually, I am curious whether different sample rates would also work?)
>
> Yes; yes.
>
> This is the _only_ way.  If the hardware supports it, any driver (not
> only ALSA) has no choice but to support this.
>

Thanks Clemens for confirming that, and your earlier inputs.

Alan

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Alsa-OSS Duplex bug (revisited)
  2007-06-04  8:50             ` Takashi Iwai
@ 2007-06-04 11:53               ` Alan Horstmann
  2007-06-04 12:21                 ` Takashi Iwai
  0 siblings, 1 reply; 16+ messages in thread
From: Alan Horstmann @ 2007-06-04 11:53 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: ALSA devel

On Monday 04 June 2007 09:50, you wrote:
> At Sun, 3 Jun 2007 20:55:27 +0100,
>
> Alan Horstmann wrote:
> > On Friday 01 June 2007 10:56, you wrote:
> > > At Thu, 31 May 2007 22:00:25 +0100,
> > >
> > > Alan Horstmann wrote:
> > > > On Wednesday 30 May 2007 07:47, you wrote:
> > > > > Alan Horstmann wrote:
> >
> > << Edited snippets >>
> >
> > > > > fd_playback = open("/dev/dsp", O_WRONLY);
> > > > > fd_capture = open("/dev/dsp", O_RDONLY);
> > > > >
> > > > > > > - change portaudio to open each direction separately, O_RDONLY
> > > > > > > and O_WRONLY at first, then use O_RDWR as fallback
> > > > >
> > > > > This would be the preferred way.  After all, this is the only way
> > > > > that is possible with the existing OSS API when you want to use
> > > > > different sample formats, and it is recommended in all cases (see
> > > > > <http://manuals.opensound.com/developer/full_duplex.html>).
> > > >
> > > > My reading of the 4Front info is different.  I read that they
> > > > recommend best opening SEPARATE devices, one O_RDONLY and the other
> > > > O_WRONLY, in their scheme called 'twodevice'.  It also states in
> > > > fulldup.c:-
> > > >
> > > > "... The one device full duplex scheme requires that the device file
> > > > is opened with O_RDWR."
> > >
> > > Well, I'd say that the current ALSA-OSS implementation _is_ compatible
> > > to OSS API.  What they do is also a pure hack, as you know, just a
> > > workaround because the API doesn't provide the functionality
> > > properly for full-duplex with multi-channels.  The solution might be
> > > different, but it's not the question about "compatibility".
> > >
> > >
> > > Following this thread, I come to believe that the problem with
> > > audacity is actually the application problem.  It tries to open a
> > > full-duplex device with different number of channels for both
> > > directions.  It cannot work because it's not defined in API.  OTOH, if
> > > the number of channels are same for both directions, it should work
> > > with O_RDWR.
> >
> > Thanks for sticking with it so far -hopefully we are moving towards a
> > conclusion so that the result is a definitive recommendation for how to
> > solve the problem of the OSS API limitation.
> >
> > So that there is no misunderstanding, are you willing to confirm that, as
> > far as Alsa-OSS goes, opening both
> > 	input_handle = open("/dev/dsp", O_RDONLY)
> > and
> > 	output_handle = open("/dev/dsp", O_WRONLY)
> > at the same time is a reliable way to open the device bi-directional,
> > enabling different sample formats and/or numbers of channels to be set? 
> > (Actually, I am curious whether different sample rates would also work?)
>
> Yes, although I didn't confirm it.  If it doesn't work, we should
> really fix it.  The dirrerent sample rates should work, too, because
> they are different streams.
>
> > Provided this is so, the recommendation then for duplex as I understand
> > it is:-
> > 	a) where the format and no.channels is the same in each direction,
> > 	    use
> > 		input_handle = output_handle = open("device", O_RDWR)
> >
> > 	b) where the 2 directions have different format or no.channels use
> > 		input_handle = open("device", O_RDONLY)
> > 		output_handle = open("device", O_WRONLY)
> >
> > since a) may improve compatibility with other OSS's but b) is necessary
> > due to the limitations of the OSS API, whether or not it works with other
> > OSS's.
>
> Exactly.  But, remember that the solution for this kind of problems
> must be practical - if the theory above isn't true for the practice,
> it's of course useless :)
>

Confirm it is working on my system apparently OK.  

I will now take this up with portaudio/audacity, and provide substitute 
patches on the known postings that relate to this, so there is some 
consistency.

Might it be worth adding a paragraph to 'OSS-Emulation.txt' (or.html), eg as 
below?  Apart from that I will close off on this issue now!

Thanks again

Alan



Duplex Streams
============

When attempting to use a single device file for playback and capture, the OSS 
API provides no way to set the format, sample rate or number of channels 
different in each direction.  Thus 
		io_handle = open("device", O_RDWR)
will only function correctly if the values are the same in each direction.

To use different values in the two directions, use both
 		input_handle = open("device", O_RDONLY)
 		output_handle = open("device", O_WRONLY)
and set the values for the corresponding handle.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Alsa-OSS Duplex bug (revisited)
  2007-06-04 11:53               ` Alan Horstmann
@ 2007-06-04 12:21                 ` Takashi Iwai
  2007-06-04 20:42                   ` Alan Horstmann
  0 siblings, 1 reply; 16+ messages in thread
From: Takashi Iwai @ 2007-06-04 12:21 UTC (permalink / raw)
  To: Alan Horstmann; +Cc: ALSA devel

At Mon, 4 Jun 2007 12:53:06 +0100,
Alan Horstmann wrote:
> 
> On Monday 04 June 2007 09:50, you wrote:
> > At Sun, 3 Jun 2007 20:55:27 +0100,
> >
> > Alan Horstmann wrote:
> > > On Friday 01 June 2007 10:56, you wrote:
> > > > At Thu, 31 May 2007 22:00:25 +0100,
> > > >
> > > > Alan Horstmann wrote:
> > > > > On Wednesday 30 May 2007 07:47, you wrote:
> > > > > > Alan Horstmann wrote:
> > >
> > > << Edited snippets >>
> > >
> > > > > > fd_playback = open("/dev/dsp", O_WRONLY);
> > > > > > fd_capture = open("/dev/dsp", O_RDONLY);
> > > > > >
> > > > > > > > - change portaudio to open each direction separately, O_RDONLY
> > > > > > > > and O_WRONLY at first, then use O_RDWR as fallback
> > > > > >
> > > > > > This would be the preferred way.  After all, this is the only way
> > > > > > that is possible with the existing OSS API when you want to use
> > > > > > different sample formats, and it is recommended in all cases (see
> > > > > > <http://manuals.opensound.com/developer/full_duplex.html>).
> > > > >
> > > > > My reading of the 4Front info is different.  I read that they
> > > > > recommend best opening SEPARATE devices, one O_RDONLY and the other
> > > > > O_WRONLY, in their scheme called 'twodevice'.  It also states in
> > > > > fulldup.c:-
> > > > >
> > > > > "... The one device full duplex scheme requires that the device file
> > > > > is opened with O_RDWR."
> > > >
> > > > Well, I'd say that the current ALSA-OSS implementation _is_ compatible
> > > > to OSS API.  What they do is also a pure hack, as you know, just a
> > > > workaround because the API doesn't provide the functionality
> > > > properly for full-duplex with multi-channels.  The solution might be
> > > > different, but it's not the question about "compatibility".
> > > >
> > > >
> > > > Following this thread, I come to believe that the problem with
> > > > audacity is actually the application problem.  It tries to open a
> > > > full-duplex device with different number of channels for both
> > > > directions.  It cannot work because it's not defined in API.  OTOH, if
> > > > the number of channels are same for both directions, it should work
> > > > with O_RDWR.
> > >
> > > Thanks for sticking with it so far -hopefully we are moving towards a
> > > conclusion so that the result is a definitive recommendation for how to
> > > solve the problem of the OSS API limitation.
> > >
> > > So that there is no misunderstanding, are you willing to confirm that, as
> > > far as Alsa-OSS goes, opening both
> > > 	input_handle = open("/dev/dsp", O_RDONLY)
> > > and
> > > 	output_handle = open("/dev/dsp", O_WRONLY)
> > > at the same time is a reliable way to open the device bi-directional,
> > > enabling different sample formats and/or numbers of channels to be set? 
> > > (Actually, I am curious whether different sample rates would also work?)
> >
> > Yes, although I didn't confirm it.  If it doesn't work, we should
> > really fix it.  The dirrerent sample rates should work, too, because
> > they are different streams.
> >
> > > Provided this is so, the recommendation then for duplex as I understand
> > > it is:-
> > > 	a) where the format and no.channels is the same in each direction,
> > > 	    use
> > > 		input_handle = output_handle = open("device", O_RDWR)
> > >
> > > 	b) where the 2 directions have different format or no.channels use
> > > 		input_handle = open("device", O_RDONLY)
> > > 		output_handle = open("device", O_WRONLY)
> > >
> > > since a) may improve compatibility with other OSS's but b) is necessary
> > > due to the limitations of the OSS API, whether or not it works with other
> > > OSS's.
> >
> > Exactly.  But, remember that the solution for this kind of problems
> > must be practical - if the theory above isn't true for the practice,
> > it's of course useless :)
> >
> 
> Confirm it is working on my system apparently OK.  
> 
> I will now take this up with portaudio/audacity, and provide substitute 
> patches on the known postings that relate to this, so there is some 
> consistency.

Thanks, that'll be helpful.

> Might it be worth adding a paragraph to 'OSS-Emulation.txt' (or.html), eg as 
> below?  Apart from that I will close off on this issue now!

Looks fine.  Could you make a patch?


thanks,

Takashi

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Alsa-OSS Duplex bug (revisited)
  2007-06-04 12:21                 ` Takashi Iwai
@ 2007-06-04 20:42                   ` Alan Horstmann
  2007-06-04 21:14                     ` Takashi Iwai
  0 siblings, 1 reply; 16+ messages in thread
From: Alan Horstmann @ 2007-06-04 20:42 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: ALSA devel

[-- Attachment #1: Type: text/plain, Size: 615 bytes --]

On Monday 04 June 2007 13:21, you wrote:
> At Mon, 4 Jun 2007 12:53:06 +0100,
> Alan Horstmann wrote:

> > Might it be worth adding a paragraph to 'OSS-Emulation.txt' (or.html), eg
> > as below?  Apart from that I will close off on this issue now!
>
> Looks fine.  Could you make a patch?

Patch attached and also for your html version in case useful.

Also just in case -signed-off etc though the content is from yourselves 
anyway.

Alan

OSS-Emulation.txt-duplex-streams.diff

Add paragraph to the OSS document to clarify correct use of duplex streams.

Signed-off-by: Alan Horstmann <gineera@aspect135.co.uk>



[-- Attachment #2: OSS-Emulation.txt-duplex-streams.diff --]
[-- Type: text/x-diff, Size: 796 bytes --]

--- alsa-kernel/Documentation/OSS-Emulation-orig.txt	2007-05-02 09:02:20.000000000 +0100
+++ alsa-kernel/Documentation/OSS-Emulation.txt	2007-06-04 20:50:51.000000000 +0100
@@ -278,6 +278,21 @@
 image.
 
 
+Duplex Streams
+==============
+
+Note that when attempting to use a single device file for playback and
+capture, the OSS API provides no way to set the format, sample rate or
+number of channels different in each direction.  Thus
+	io_handle = open("device", O_RDWR)
+will only function correctly if the values are the same in each direction.
+
+To use different values in the two directions, use both
+	input_handle = open("device", O_RDONLY)
+	output_handle = open("device", O_WRONLY)
+and set the values for the corresponding handle.
+
+
 Unsupported Features
 ====================
 

[-- Attachment #3: OSS-Emulation.html-duplex-streams.diff --]
[-- Type: text/x-diff, Size: 895 bytes --]

--- OSS-Emulation-orig.html	2007-06-04 10:57:39.000000000 +0100
+++ OSS-Emulation.html	2007-06-04 21:18:54.000000000 +0100
@@ -381,6 +381,27 @@
 
 
     <p>
+    <h2>Duplex Streams</h2>
+
+    <P>
+      Note that when attempting to use a single device file for playback
+      and capture, the OSS API provides no way to set the format, sample
+      rate or number of channels different in each direction. Thus
+<pre>
+	io_handle = open(&quot;device&quot;, O_RDWR)
+</pre>
+      will only function correctly if the values are the same in each
+      direction.
+    <P>
+      To use different values in the two directions, use both
+<pre>
+	input_handle = open(&quot;device&quot;, O_RDONLY)
+	output_handle = open(&quot;device&quot;, O_WRONLY)
+</pre>
+      and set values for the corresponding handle.
+
+
+    <p>
     <h2>Unsupported Features</h2>
 
     <h3>MMAP on ICE1712 driver</h3>

[-- Attachment #4: Type: text/plain, Size: 160 bytes --]

_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Alsa-OSS Duplex bug (revisited)
  2007-06-04 20:42                   ` Alan Horstmann
@ 2007-06-04 21:14                     ` Takashi Iwai
  0 siblings, 0 replies; 16+ messages in thread
From: Takashi Iwai @ 2007-06-04 21:14 UTC (permalink / raw)
  To: Alan Horstmann; +Cc: ALSA devel

At Mon, 4 Jun 2007 21:42:10 +0100,
Alan Horstmann wrote:
> 
> On Monday 04 June 2007 13:21, you wrote:
> > At Mon, 4 Jun 2007 12:53:06 +0100,
> > Alan Horstmann wrote:
> 
> > > Might it be worth adding a paragraph to 'OSS-Emulation.txt' (or.html), eg
> > > as below?  Apart from that I will close off on this issue now!
> >
> > Looks fine.  Could you make a patch?
> 
> Patch attached and also for your html version in case useful.
> 
> Also just in case -signed-off etc though the content is from yourselves 
> anyway.
> 
> Alan
> 
> OSS-Emulation.txt-duplex-streams.diff
> 
> Add paragraph to the OSS document to clarify correct use of duplex streams.
> 
> Signed-off-by: Alan Horstmann <gineera@aspect135.co.uk>

Thanks, I applied it now.


Takashi

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2007-06-04 21:14 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-05-27 22:23 Alsa-OSS Duplex bug (revisited) Alan Horstmann
2007-05-29 16:55 ` Takashi Iwai
2007-05-29 22:16   ` Alan Horstmann
2007-05-30  6:47     ` Clemens Ladisch
2007-05-30 17:05       ` Takashi Iwai
2007-05-30 22:12         ` Alan Horstmann
2007-05-31 21:00       ` Alan Horstmann
2007-06-01  9:56         ` Takashi Iwai
2007-06-03 19:55           ` Alan Horstmann
2007-06-04  8:45             ` Clemens Ladisch
2007-06-04 11:51               ` Alan Horstmann
2007-06-04  8:50             ` Takashi Iwai
2007-06-04 11:53               ` Alan Horstmann
2007-06-04 12:21                 ` Takashi Iwai
2007-06-04 20:42                   ` Alan Horstmann
2007-06-04 21:14                     ` 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.