All of lore.kernel.org
 help / color / mirror / Atom feed
* OSS SNDCTL_DSP_GETISPACE, non-blocking read: messy :-\
@ 2003-10-25 20:02 Andreas Mohr
  2003-10-27 12:01 ` Takashi Iwai
  0 siblings, 1 reply; 8+ messages in thread
From: Andreas Mohr @ 2003-10-25 20:02 UTC (permalink / raw)
  To: alsa-devel; +Cc: Jaroslav Kysela

Hi all,

RAT (Robust Audio Tool, http://www-mice.cs.ucl.ac.uk/multimedia/software/rat/)
shows quite miserable behaviour on ALSA/OSS (current CVS):

andi@note:/home/andi$ rat 193.8.230.138/2074
audio_read: Resource temporarily unavailable
audio_read: Resource temporarily unavailable
audio_read: Resource temporarily unavailable
audio_read: Resource temporarily unavailable
audio_read: Resource temporarily unavailable
audio_read: Resource temporarily unavailable
audio_read: Resource temporarily unavailable
audio_read: Resource temporarily unavailable
audio_read: Resource temporarily unavailable
audio_read: Resource temporarily unavailable
.
.
.
andi@note:/home/andi$

I've been analyzing the reason for about 1.5 hours now,
and I guess I know what the problem is, but I'm uncertain as to how it should
be fixed (I could probably fix it, but I REALLY want to leave it to much more
experienced people since I'm afraid that code is VERY easy to break...).

Our SNDCTL_DSP_GETISPACE implementation in alsa-driver/acore/oss/pcm_oss.c
calls snd_pcm_oss_get_space(), which returns the number of bytes available
to read (e.g. 224).

RAT then does a read() with exactly this amount of bytes.

The read() causes alsa-kernel/core/oss/pcm_oss.c/snd_pcm_oss_read()
to be called, with this amount of bytes passed.

This now calls snd_pcm_oss_read1(), with the bytes set to the same amount
again.

For some stupid reason, _read1() now ALWAYS calls into snd_pcm_oss_read2()
with an amount of runtime->oss.period_bytes bytes to be read, which happens
to be 256.

With a blocking read, this would probably be no problem, since we just wait
until we have enough data in the buffer, however with a non-blocking read,
snd_pcm_lib_read(), which gets called by snd_pcm_oss_read3() that's being
called by snd_pcm_oss_read2(), simply returns -EAGAIN since it cannot handle
the much too large request.


Or, as a short summary:
The application is perfectly well aware of how many bytes there are left
to read (from calling SNDCTL_DSP_GETISPACE) and then does a read() with
this amount of bytes, however since the ALSA OSS layer attempts to read
this byte amount in blocks of runtime->oss.period_bytes bytes from the sound
device, we ARTIFICIALLY cause a -EAGAIN to be returned due to insufficient
available data, thus potentially confusing many OSS applications.

Now what to do here?

Thanks!

Andreas Mohr


-------------------------------------------------------
This SF.net email is sponsored by: The SF.net Donation Program.
Do you like what SourceForge.net is doing for the Open
Source Community?  Make a contribution, and help us add new
features and functionality. Click here: http://sourceforge.net/donate/

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

* Re: OSS SNDCTL_DSP_GETISPACE, non-blocking read: messy :-\
  2003-10-25 20:02 OSS SNDCTL_DSP_GETISPACE, non-blocking read: messy :-\ Andreas Mohr
@ 2003-10-27 12:01 ` Takashi Iwai
  2003-10-27 12:11   ` Andreas Mohr
  0 siblings, 1 reply; 8+ messages in thread
From: Takashi Iwai @ 2003-10-27 12:01 UTC (permalink / raw)
  To: andi; +Cc: alsa-devel

At Sat, 25 Oct 2003 22:02:21 +0200,
Andreas Mohr wrote:
> 
> Hi all,
> 
> RAT (Robust Audio Tool, http://www-mice.cs.ucl.ac.uk/multimedia/software/rat/)
> shows quite miserable behaviour on ALSA/OSS (current CVS):
> 
> andi@note:/home/andi$ rat 193.8.230.138/2074
> audio_read: Resource temporarily unavailable
> audio_read: Resource temporarily unavailable
> audio_read: Resource temporarily unavailable
> audio_read: Resource temporarily unavailable
> audio_read: Resource temporarily unavailable
> audio_read: Resource temporarily unavailable
> audio_read: Resource temporarily unavailable
> audio_read: Resource temporarily unavailable
> audio_read: Resource temporarily unavailable
> audio_read: Resource temporarily unavailable
> .
> .
> .
> andi@note:/home/andi$
> 
> I've been analyzing the reason for about 1.5 hours now,
> and I guess I know what the problem is, but I'm uncertain as to how it should
> be fixed (I could probably fix it, but I REALLY want to leave it to much more
> experienced people since I'm afraid that code is VERY easy to break...).
> 
> Our SNDCTL_DSP_GETISPACE implementation in alsa-driver/acore/oss/pcm_oss.c
> calls snd_pcm_oss_get_space(), which returns the number of bytes available
> to read (e.g. 224).
> 
> RAT then does a read() with exactly this amount of bytes.
> 
> The read() causes alsa-kernel/core/oss/pcm_oss.c/snd_pcm_oss_read()
> to be called, with this amount of bytes passed.
> 
> This now calls snd_pcm_oss_read1(), with the bytes set to the same amount
> again.
> 
> For some stupid reason, _read1() now ALWAYS calls into snd_pcm_oss_read2()
> with an amount of runtime->oss.period_bytes bytes to be read, which happens
> to be 256.
> 
> With a blocking read, this would probably be no problem, since we just wait
> until we have enough data in the buffer, however with a non-blocking read,
> snd_pcm_lib_read(), which gets called by snd_pcm_oss_read3() that's being
> called by snd_pcm_oss_read2(), simply returns -EAGAIN since it cannot handle
> the much too large request.
> 
> 
> Or, as a short summary:
> The application is perfectly well aware of how many bytes there are left
> to read (from calling SNDCTL_DSP_GETISPACE) and then does a read() with
> this amount of bytes, however since the ALSA OSS layer attempts to read
> this byte amount in blocks of runtime->oss.period_bytes bytes from the sound
> device, we ARTIFICIALLY cause a -EAGAIN to be returned due to insufficient
> available data, thus potentially confusing many OSS applications.
> 
> Now what to do here?

this problem is a bit touch, because the ALSA OSS layer does the
sample-rate conversion, etc.
when the sample rate is converted between 44.1kHz and 48kHz, some
round error may happen and it will be accumulated.   hence, the size
will be different between two cases: reading a whole period once and
reading a period by multiple calls.

i'll take a more deeper look...


Takashi


-------------------------------------------------------
This SF.net email is sponsored by: The SF.net Donation Program.
Do you like what SourceForge.net is doing for the Open
Source Community?  Make a contribution, and help us add new
features and functionality. Click here: http://sourceforge.net/donate/

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

* Re: OSS SNDCTL_DSP_GETISPACE, non-blocking read: messy :-\
  2003-10-27 12:01 ` Takashi Iwai
@ 2003-10-27 12:11   ` Andreas Mohr
  2003-10-28 11:21     ` Takashi Iwai
  0 siblings, 1 reply; 8+ messages in thread
From: Andreas Mohr @ 2003-10-27 12:11 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel

Hello Takashi,

On Mon, Oct 27, 2003 at 01:01:37PM +0100, Takashi Iwai wrote:
> At Sat, 25 Oct 2003 22:02:21 +0200,
> Andreas Mohr wrote:
> > Or, as a short summary:
> > The application is perfectly well aware of how many bytes there are left
> > to read (from calling SNDCTL_DSP_GETISPACE) and then does a read() with
> > this amount of bytes, however since the ALSA OSS layer attempts to read
> > this byte amount in blocks of runtime->oss.period_bytes bytes from the sound
> > device, we ARTIFICIALLY cause a -EAGAIN to be returned due to insufficient
> > available data, thus potentially confusing many OSS applications.
> > 
> > Now what to do here?
> 
> this problem is a bit touch, because the ALSA OSS layer does the
> sample-rate conversion, etc.
> when the sample rate is converted between 44.1kHz and 48kHz, some
> round error may happen and it will be accumulated.   hence, the size
> will be different between two cases: reading a whole period once and
> reading a period by multiple calls.
> 
> i'll take a more deeper look...
Ah, thanks! (also for the explanation given above)

Given that 1.0 is approaching, it'd certainly be useful to get such a
problem fixed ;-)

Andreas Mohr


-------------------------------------------------------
This SF.net email is sponsored by: The SF.net Donation Program.
Do you like what SourceForge.net is doing for the Open
Source Community?  Make a contribution, and help us add new
features and functionality. Click here: http://sourceforge.net/donate/

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

* Re: OSS SNDCTL_DSP_GETISPACE, non-blocking read: messy :-\
  2003-10-27 12:11   ` Andreas Mohr
@ 2003-10-28 11:21     ` Takashi Iwai
  2003-10-28 12:36       ` Jaroslav Kysela
  0 siblings, 1 reply; 8+ messages in thread
From: Takashi Iwai @ 2003-10-28 11:21 UTC (permalink / raw)
  To: andi; +Cc: alsa-devel

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

At Mon, 27 Oct 2003 13:11:58 +0100,
Andreas Mohr wrote:
> 
> Hello Takashi,
> 
> On Mon, Oct 27, 2003 at 01:01:37PM +0100, Takashi Iwai wrote:
> > At Sat, 25 Oct 2003 22:02:21 +0200,
> > Andreas Mohr wrote:
> > > Or, as a short summary:
> > > The application is perfectly well aware of how many bytes there are left
> > > to read (from calling SNDCTL_DSP_GETISPACE) and then does a read() with
> > > this amount of bytes, however since the ALSA OSS layer attempts to read
> > > this byte amount in blocks of runtime->oss.period_bytes bytes from the sound
> > > device, we ARTIFICIALLY cause a -EAGAIN to be returned due to insufficient
> > > available data, thus potentially confusing many OSS applications.
> > > 
> > > Now what to do here?
> > 
> > this problem is a bit touch, because the ALSA OSS layer does the
> > sample-rate conversion, etc.
> > when the sample rate is converted between 44.1kHz and 48kHz, some
> > round error may happen and it will be accumulated.   hence, the size
> > will be different between two cases: reading a whole period once and
> > reading a period by multiple calls.
> > 
> > i'll take a more deeper look...
> Ah, thanks! (also for the explanation given above)
> 
> Given that 1.0 is approaching, it'd certainly be useful to get such a
> problem fixed ;-)

i come to believe that it's a bug, too.
as you wrote, the fix is easy except for the rare problem what i
mentioned above.  in that case (e.g. the sample-rate conversion
between 44.1 and 48khz required), you'll still get -EAGAIN
occasionally.  but normally, it seems ok.

the attached is the patch to fix the original problem.
to take back to the old behavior (always reading a whole period),
you can write "whole-frag" command to the proc file.

anyway, i'll try a bit more to solve the problem above.


Takashi

[-- Attachment #2: oss-capture-fix.dif --]
[-- Type: application/octet-stream, Size: 2517 bytes --]

Index: alsa-kernel/core/oss/pcm_oss.c
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/core/oss/pcm_oss.c,v
retrieving revision 1.42
diff -u -r1.42 pcm_oss.c
--- alsa-kernel/core/oss/pcm_oss.c	30 Sep 2003 10:08:04 -0000	1.42
+++ alsa-kernel/core/oss/pcm_oss.c	27 Oct 2003 18:12:14 -0000
@@ -665,6 +665,10 @@
 		ret = snd_pcm_oss_capture_position_fixup(substream, &delay);
 		if (ret < 0)
 			break;
+#if 0 // xxx
+		if (delay < frames)
+			printk(KERN_DEBUG "insanity read %d to req %d\n", (int)delay, (int)frames);
+#endif
 		if (in_kernel) {
 			mm_segment_t fs;
 			fs = snd_enter_user();
@@ -879,16 +883,23 @@
 	while (bytes > 0) {
 		if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) {
 			if (runtime->oss.buffer_used == 0) {
-				tmp = snd_pcm_oss_read2(substream, runtime->oss.buffer, runtime->oss.period_bytes, 1);
+				size_t filled;
+				if ((! substream->oss.setup || ! substream->oss.setup->wholefrag) &&
+				    bytes < runtime->oss.period_bytes)
+					filled = bytes;
+				else
+					filled = runtime->oss.period_bytes;
+				tmp = snd_pcm_oss_read2(substream, runtime->oss.buffer, filled, 1);
 				if (tmp <= 0)
 					return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
 				runtime->oss.bytes += tmp;
-				runtime->oss.buffer_used = runtime->oss.period_bytes;
+				runtime->oss.buffer_used = filled;
+				runtime->oss.buffer_filled = filled;
 			}
 			tmp = bytes;
 			if ((size_t) tmp > runtime->oss.buffer_used)
 				tmp = runtime->oss.buffer_used;
-			if (copy_to_user(buf, runtime->oss.buffer + (runtime->oss.period_bytes - runtime->oss.buffer_used), tmp))
+			if (copy_to_user(buf, runtime->oss.buffer + (runtime->oss.buffer_filled - runtime->oss.buffer_used), tmp))
 				return xfer > 0 ? (snd_pcm_sframes_t)xfer : -EFAULT;
 			buf += tmp;
 			bytes -= tmp;
Index: alsa-kernel/include/pcm_oss.h
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/include/pcm_oss.h,v
retrieving revision 1.6
diff -u -r1.6 pcm_oss.h
--- alsa-kernel/include/pcm_oss.h	30 Sep 2003 10:08:16 -0000	1.6
+++ alsa-kernel/include/pcm_oss.h	27 Oct 2003 16:54:00 -0000
@@ -57,6 +57,7 @@
 	size_t mmap_bytes;
 	char *buffer;				/* vmallocated period */
 	size_t buffer_used;			/* used length from period buffer */
+	size_t buffer_filled;			/* filled size in the period buffer */
 	snd_pcm_plugin_t *plugin_first;
 	snd_pcm_plugin_t *plugin_last;
 	unsigned int prev_hw_ptr_interrupt;

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

* Re: OSS SNDCTL_DSP_GETISPACE, non-blocking read: messy :-\
  2003-10-28 11:21     ` Takashi Iwai
@ 2003-10-28 12:36       ` Jaroslav Kysela
  2003-10-28 13:24         ` Takashi Iwai
  2003-10-28 13:30         ` Jaroslav Kysela
  0 siblings, 2 replies; 8+ messages in thread
From: Jaroslav Kysela @ 2003-10-28 12:36 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: andi, alsa-devel

On Tue, 28 Oct 2003, Takashi Iwai wrote:

> At Mon, 27 Oct 2003 13:11:58 +0100,
> Andreas Mohr wrote:
> >
> > Hello Takashi,
> >
> > On Mon, Oct 27, 2003 at 01:01:37PM +0100, Takashi Iwai wrote:
> > > At Sat, 25 Oct 2003 22:02:21 +0200,
> > > Andreas Mohr wrote:
> > > > Or, as a short summary:
> > > > The application is perfectly well aware of how many bytes there are left
> > > > to read (from calling SNDCTL_DSP_GETISPACE) and then does a read() with
> > > > this amount of bytes, however since the ALSA OSS layer attempts to read
> > > > this byte amount in blocks of runtime->oss.period_bytes bytes from the sound
> > > > device, we ARTIFICIALLY cause a -EAGAIN to be returned due to insufficient
> > > > available data, thus potentially confusing many OSS applications.
> > > >
> > > > Now what to do here?
> > >
> > > this problem is a bit touch, because the ALSA OSS layer does the
> > > sample-rate conversion, etc.
> > > when the sample rate is converted between 44.1kHz and 48kHz, some
> > > round error may happen and it will be accumulated.   hence, the size
> > > will be different between two cases: reading a whole period once and
> > > reading a period by multiple calls.
> > >
> > > i'll take a more deeper look...
> > Ah, thanks! (also for the explanation given above)
> >
> > Given that 1.0 is approaching, it'd certainly be useful to get such a
> > problem fixed ;-)
>
> i come to believe that it's a bug, too.
> as you wrote, the fix is easy except for the rare problem what i
> mentioned above.  in that case (e.g. the sample-rate conversion
> between 44.1 and 48khz required), you'll still get -EAGAIN
> occasionally.  but normally, it seems ok.
>
> the attached is the patch to fix the original problem.
> to take back to the old behavior (always reading a whole period),
> you can write "whole-frag" command to the proc file.
>
> anyway, i'll try a bit more to solve the problem above.

I think that the problem is at another place. I'm investigating the bug in
code now.

						Jaroslav

-----
Jaroslav Kysela <perex@suse.cz>
Linux Kernel Sound Maintainer
ALSA Project, SuSE Labs


-------------------------------------------------------
This SF.net email is sponsored by: The SF.net Donation Program.
Do you like what SourceForge.net is doing for the Open
Source Community?  Make a contribution, and help us add new
features and functionality. Click here: http://sourceforge.net/donate/

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

* Re: OSS SNDCTL_DSP_GETISPACE, non-blocking read: messy :-\
  2003-10-28 12:36       ` Jaroslav Kysela
@ 2003-10-28 13:24         ` Takashi Iwai
  2003-10-28 13:30         ` Jaroslav Kysela
  1 sibling, 0 replies; 8+ messages in thread
From: Takashi Iwai @ 2003-10-28 13:24 UTC (permalink / raw)
  To: Jaroslav Kysela; +Cc: andi, alsa-devel

At Tue, 28 Oct 2003 13:36:37 +0100 (CET),
Jaroslav wrote:
> 
> On Tue, 28 Oct 2003, Takashi Iwai wrote:
> 
> > At Mon, 27 Oct 2003 13:11:58 +0100,
> > Andreas Mohr wrote:
> > >
> > > Hello Takashi,
> > >
> > > On Mon, Oct 27, 2003 at 01:01:37PM +0100, Takashi Iwai wrote:
> > > > At Sat, 25 Oct 2003 22:02:21 +0200,
> > > > Andreas Mohr wrote:
> > > > > Or, as a short summary:
> > > > > The application is perfectly well aware of how many bytes there are left
> > > > > to read (from calling SNDCTL_DSP_GETISPACE) and then does a read() with
> > > > > this amount of bytes, however since the ALSA OSS layer attempts to read
> > > > > this byte amount in blocks of runtime->oss.period_bytes bytes from the sound
> > > > > device, we ARTIFICIALLY cause a -EAGAIN to be returned due to insufficient
> > > > > available data, thus potentially confusing many OSS applications.
> > > > >
> > > > > Now what to do here?
> > > >
> > > > this problem is a bit touch, because the ALSA OSS layer does the
> > > > sample-rate conversion, etc.
> > > > when the sample rate is converted between 44.1kHz and 48kHz, some
> > > > round error may happen and it will be accumulated.   hence, the size
> > > > will be different between two cases: reading a whole period once and
> > > > reading a period by multiple calls.
> > > >
> > > > i'll take a more deeper look...
> > > Ah, thanks! (also for the explanation given above)
> > >
> > > Given that 1.0 is approaching, it'd certainly be useful to get such a
> > > problem fixed ;-)
> >
> > i come to believe that it's a bug, too.
> > as you wrote, the fix is easy except for the rare problem what i
> > mentioned above.  in that case (e.g. the sample-rate conversion
> > between 44.1 and 48khz required), you'll still get -EAGAIN
> > occasionally.  but normally, it seems ok.
> >
> > the attached is the patch to fix the original problem.
> > to take back to the old behavior (always reading a whole period),
> > you can write "whole-frag" command to the proc file.
> >
> > anyway, i'll try a bit more to solve the problem above.
> 
> I think that the problem is at another place. I'm investigating the bug in
> code now.

thanks.

just to avoid confusion: there are two "bugs" here discussed.

1. the original problem, read() returns -EAGAIN when trying to read
   the bytes returned by GETISPACE ioctl.  this is because
   snd_pcm_oss_read2() always reads a whole period.
   my last patch is for this problem.

2. read() return -EAGAIN occasionally.  likely  because of the rate
   plugin.


Takashi


-------------------------------------------------------
This SF.net email is sponsored by: The SF.net Donation Program.
Do you like what SourceForge.net is doing for the Open
Source Community?  Make a contribution, and help us add new
features and functionality. Click here: http://sourceforge.net/donate/

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

* Re: OSS SNDCTL_DSP_GETISPACE, non-blocking read: messy :-\
  2003-10-28 12:36       ` Jaroslav Kysela
  2003-10-28 13:24         ` Takashi Iwai
@ 2003-10-28 13:30         ` Jaroslav Kysela
  2003-10-28 14:27           ` Takashi Iwai
  1 sibling, 1 reply; 8+ messages in thread
From: Jaroslav Kysela @ 2003-10-28 13:30 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: andi, alsa-devel

On Tue, 28 Oct 2003, Jaroslav Kysela wrote:

> On Tue, 28 Oct 2003, Takashi Iwai wrote:
>
> > At Mon, 27 Oct 2003 13:11:58 +0100,
> > Andreas Mohr wrote:
> > >
> > > Hello Takashi,
> > >
> > > On Mon, Oct 27, 2003 at 01:01:37PM +0100, Takashi Iwai wrote:
> > > > At Sat, 25 Oct 2003 22:02:21 +0200,
> > > > Andreas Mohr wrote:
> > > > > Or, as a short summary:
> > > > > The application is perfectly well aware of how many bytes there are left
> > > > > to read (from calling SNDCTL_DSP_GETISPACE) and then does a read() with
> > > > > this amount of bytes, however since the ALSA OSS layer attempts to read
> > > > > this byte amount in blocks of runtime->oss.period_bytes bytes from the sound
> > > > > device, we ARTIFICIALLY cause a -EAGAIN to be returned due to insufficient
> > > > > available data, thus potentially confusing many OSS applications.
> > > > >
> > > > > Now what to do here?
> > > >
> > > > this problem is a bit touch, because the ALSA OSS layer does the
> > > > sample-rate conversion, etc.
> > > > when the sample rate is converted between 44.1kHz and 48kHz, some
> > > > round error may happen and it will be accumulated.   hence, the size
> > > > will be different between two cases: reading a whole period once and
> > > > reading a period by multiple calls.
> > > >
> > > > i'll take a more deeper look...
> > > Ah, thanks! (also for the explanation given above)
> > >
> > > Given that 1.0 is approaching, it'd certainly be useful to get such a
> > > problem fixed ;-)
> >
> > i come to believe that it's a bug, too.
> > as you wrote, the fix is easy except for the rare problem what i
> > mentioned above.  in that case (e.g. the sample-rate conversion
> > between 44.1 and 48khz required), you'll still get -EAGAIN
> > occasionally.  but normally, it seems ok.
> >
> > the attached is the patch to fix the original problem.
> > to take back to the old behavior (always reading a whole period),
> > you can write "whole-frag" command to the proc file.
> >
> > anyway, i'll try a bit more to solve the problem above.
>
> I think that the problem is at another place. I'm investigating the bug in
> code now.

Yes, several assumptions were made and the SPACE ioctls were a bit broken.
I've put a fix to our CVS (also included to this e-mail). Hopefully, it
won't break another OSS applications.

						Jaroslav

Index: pcm_oss.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/core/oss/pcm_oss.c,v
retrieving revision 1.53
diff -u -r1.53 pcm_oss.c
--- pcm_oss.c	30 Sep 2003 09:28:26 -0000	1.53
+++ pcm_oss.c	28 Oct 2003 13:26:12 -0000
@@ -125,8 +125,8 @@
 	if (runtime->period_size == runtime->oss.period_bytes)
 		return frames;
 	if (runtime->period_size < runtime->oss.period_bytes)
-		return frames * (runtime->oss.period_bytes / runtime->period_size);
-	return frames / (runtime->period_size / runtime->oss.period_bytes);
+		return (frames * runtime->period_size) / runtime->oss.period_bytes;
+	return (frames * runtime->oss.period_bytes) / runtime->period_size;
 }

 static int snd_pcm_oss_format_from(int format)
@@ -451,7 +451,7 @@
 	sw_params->tstamp_mode = SNDRV_PCM_TSTAMP_NONE;
 	sw_params->period_step = 1;
 	sw_params->sleep_min = 0;
-	sw_params->avail_min = runtime->period_size;
+	sw_params->avail_min = 1;
 	sw_params->xfer_align = 1;
 	if (atomic_read(&runtime->mmap_count) ||
 	    (substream->oss.setup && substream->oss.setup->nosilence)) {
@@ -470,7 +470,6 @@
 		snd_printd("SW_PARAMS failed: %i\n", err);
 		goto failure;
 	}
-	runtime->control->avail_min = runtime->period_size;

 	runtime->oss.periods = params_periods(sparams);
 	oss_period_size = snd_pcm_plug_client_size(substream, params_period_size(sparams));
@@ -883,7 +882,7 @@
 				if (tmp <= 0)
 					return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
 				runtime->oss.bytes += tmp;
-				runtime->oss.buffer_used = runtime->oss.period_bytes;
+				runtime->oss.buffer_used = tmp;
 			}
 			tmp = bytes;
 			if ((size_t) tmp > runtime->oss.buffer_used)
@@ -1425,6 +1424,7 @@
 	snd_pcm_substream_t *substream;
 	snd_pcm_runtime_t *runtime;
 	snd_pcm_sframes_t delay;
+	int fixup;
 	struct count_info info;
 	int err;

@@ -1447,9 +1447,13 @@
 		if (err == -EPIPE || err == -ESTRPIPE) {
 			err = 0;
 			delay = 0;
+			fixup = 0;
+		} else {
+			fixup = runtime->oss.buffer_used;
 		}
 	} else {
 		err = snd_pcm_oss_capture_position_fixup(substream, &delay);
+		fixup = -runtime->oss.buffer_used;
 	}
 	if (err < 0)
 		return err;
@@ -1469,7 +1473,8 @@
 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 			snd_pcm_oss_simulate_fill(substream);
 	} else {
-		info.blocks = delay / runtime->period_size;
+		delay = snd_pcm_oss_bytes(substream, delay) + fixup;
+		info.blocks = delay / runtime->oss.period_bytes;
 	}
 	if (copy_to_user(_info, &info, sizeof(info)))
 		return -EFAULT;
@@ -1481,6 +1486,7 @@
 	snd_pcm_substream_t *substream;
 	snd_pcm_runtime_t *runtime;
 	snd_pcm_sframes_t avail;
+	int fixup;
 	struct audio_buf_info info;
 	int err;

@@ -1500,7 +1506,7 @@
 	if (runtime->oss.prepare) {
 		if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
 			info.bytes = runtime->oss.period_bytes * runtime->periods;
-			info.fragments = runtime->periods;
+			info.fragments = runtime->oss.periods;
 		} else {
 			info.bytes = 0;
 			info.fragments = 0;
@@ -1511,16 +1517,19 @@
 			if (err == -EPIPE || err == -ESTRPIPE) {
 				avail = runtime->buffer_size;
 				err = 0;
+				fixup = 0;
 			} else {
 				avail = runtime->buffer_size - avail;
+				fixup = -runtime->oss.buffer_used;
 			}
 		} else {
 			err = snd_pcm_oss_capture_position_fixup(substream, &avail);
+			fixup = runtime->oss.buffer_used;
 		}
 		if (err < 0)
 			return err;
-		info.bytes = snd_pcm_oss_bytes(substream, avail);
-		info.fragments = avail / runtime->period_size;
+		info.bytes = snd_pcm_oss_bytes(substream, avail) + fixup;
+		info.fragments = info.bytes / runtime->oss.period_bytes;
 	}

 #ifdef OSS_DEBUG

-----
Jaroslav Kysela <perex@suse.cz>
Linux Kernel Sound Maintainer
ALSA Project, SuSE Labs


-------------------------------------------------------
This SF.net email is sponsored by: The SF.net Donation Program.
Do you like what SourceForge.net is doing for the Open
Source Community?  Make a contribution, and help us add new
features and functionality. Click here: http://sourceforge.net/donate/

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

* Re: OSS SNDCTL_DSP_GETISPACE, non-blocking read: messy :-\
  2003-10-28 13:30         ` Jaroslav Kysela
@ 2003-10-28 14:27           ` Takashi Iwai
  0 siblings, 0 replies; 8+ messages in thread
From: Takashi Iwai @ 2003-10-28 14:27 UTC (permalink / raw)
  To: Jaroslav Kysela; +Cc: andi, alsa-devel

At Tue, 28 Oct 2003 14:30:33 +0100 (CET),
Jaroslav wrote:
> 
> Yes, several assumptions were made and the SPACE ioctls were a bit broken.
> I've put a fix to our CVS (also included to this e-mail). Hopefully, it
> won't break another OSS applications.
> 
> 						Jaroslav
> 
> Index: pcm_oss.c
> ===================================================================
> RCS file: /cvsroot/alsa/alsa-kernel/core/oss/pcm_oss.c,v
> retrieving revision 1.53
> diff -u -r1.53 pcm_oss.c
> --- pcm_oss.c	30 Sep 2003 09:28:26 -0000	1.53
> +++ pcm_oss.c	28 Oct 2003 13:26:12 -0000
> @@ -125,8 +125,8 @@
>  	if (runtime->period_size == runtime->oss.period_bytes)
>  		return frames;
>  	if (runtime->period_size < runtime->oss.period_bytes)
> -		return frames * (runtime->oss.period_bytes / runtime->period_size);
> -	return frames / (runtime->period_size / runtime->oss.period_bytes);
> +		return (frames * runtime->period_size) / runtime->oss.period_bytes;
> +	return (frames * runtime->oss.period_bytes) / runtime->period_size;
>  }

oh yeah, this is...


>  static int snd_pcm_oss_format_from(int format)
> @@ -451,7 +451,7 @@
>  	sw_params->tstamp_mode = SNDRV_PCM_TSTAMP_NONE;
>  	sw_params->period_step = 1;
>  	sw_params->sleep_min = 0;
> -	sw_params->avail_min = runtime->period_size;
> +	sw_params->avail_min = 1;
>  	sw_params->xfer_align = 1;
>  	if (atomic_read(&runtime->mmap_count) ||
>  	    (substream->oss.setup && substream->oss.setup->nosilence)) {
> @@ -470,7 +470,6 @@
>  		snd_printd("SW_PARAMS failed: %i\n", err);
>  		goto failure;
>  	}
> -	runtime->control->avail_min = runtime->period_size;
> 
>  	runtime->oss.periods = params_periods(sparams);
>  	oss_period_size = snd_pcm_plug_client_size(substream, params_period_size(sparams));
> @@ -883,7 +882,7 @@
>  				if (tmp <= 0)
>  					return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
>  				runtime->oss.bytes += tmp;
> -				runtime->oss.buffer_used = runtime->oss.period_bytes;
> +				runtime->oss.buffer_used = tmp;
>  			}
>  			tmp = bytes;
>  			if ((size_t) tmp > runtime->oss.buffer_used)
> @@ -1425,6 +1424,7 @@

i think the read size should be changed, too.

				tmp = snd_pcm_oss_read2(substream, runtime->oss.buffer, runtime->oss.period_bytes, 1);

also, the line below

			if (copy_to_user(buf, runtime->oss.buffer + (runtime->oss.period_bytes - runtime->oss.buffer_used), tmp))

the offset calculation is broken if you use buffer_used = tmp.
we'll need another field like my patch to calculate the current
offset.


Takashi


-------------------------------------------------------
This SF.net email is sponsored by: SF.net Giveback Program.
Does SourceForge.net help you be more productive?  Does it
help you create better code?   SHARE THE LOVE, and help us help
YOU!  Click Here: http://sourceforge.net/donate/

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

end of thread, other threads:[~2003-10-28 14:27 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-10-25 20:02 OSS SNDCTL_DSP_GETISPACE, non-blocking read: messy :-\ Andreas Mohr
2003-10-27 12:01 ` Takashi Iwai
2003-10-27 12:11   ` Andreas Mohr
2003-10-28 11:21     ` Takashi Iwai
2003-10-28 12:36       ` Jaroslav Kysela
2003-10-28 13:24         ` Takashi Iwai
2003-10-28 13:30         ` Jaroslav Kysela
2003-10-28 14:27           ` 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.