* 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.