[alsa-devel] Dsnoop-plugin buffer sizes
Hi,
I'm having issues with garbage data in my audio stream, which I believe is caused by incorrect buffer sizes somewhere in the audio pipeline. The garbage occurs periodically and is always constant in length. This problem only triggers when I use the dsnoo-plugin. If running directly towards the device, the audio stream is fine (no garbage). I've not tested if this occurs with any other plugin.
I'm using Dsnoop to capture a mono stream from a stereo device using arecord, arecord -v -r 16000 -c1 -Daudiosource0 -fS16_LE /tmp/in.wav (where audiosource0 is my dsnoop-device, bound to channel 0)
The verbose info from arecord shows me that ALSA has correctly created the Dsnoop device, with a "buffer_size" of 8000. It also shows that it has opened my Hardware device in MMAP-mode, with a "buffer_size" of 8192.
Here comes the kicker: The length of the garbage seen in my audio stream is always equal to the difference between the two buffer sizes. So in the above case, I'm seeing 8000 valid samples, followed by 192 "garbage" samples.
Furthermore, I've added debugprints to the PCM driver hw_params() function, and in the above configuration, and it shows that the PCM is asked to allocate 4 periods of 8000 bytes each, NOT 8192 bytes as one would expect for the Hardware device.
I added some poisoning to the pre-allocated PCM buffer, and it clearly shows that the garbage comes from ALSA reading data from places in the buffer it has not allocated: ALSA thinks the ring buffer contains periods of size 8192, but the PCM driver is only asked to alloc size 8000.
Here comes the second kicker: I originally noticed this issue as I was adjusting the periods_min parameter of the PCM driver (PCM hardware has some special needs). It seems like for some periods_min, ALSA will "default" to a buffer_size so that the buffer_size of my Dsnoop device AND my hardware device is identical. In this case, everything works. For example, if I set period_min to 4, ALSA will default to Dsnoop buffer_size 8000 and Hardware buffer_size 8192. If I set periods_min to 3, ALSA will instead default Dsnoop buffer_size to 6000 and Hardware buffer_size to 6000. In the latter case, no garbage appears, since there is no buffer size diff.
Now my question is if it's possible that I have some misconfiguration and/or missing constraint in my system? .. or maybe this is just a bug. My first thought was that 8000 was rounded to the nearest page 8192, however, for periods_min=3, both buffers stay at 6000 which is not a page multiple.
Best regards, Magnus
On Mon, 14 Mar 2011, Magnus Olsson wrote:
Hi,
I'm having issues with garbage data in my audio stream, which I believe is caused by incorrect buffer sizes somewhere in the audio pipeline. The garbage occurs periodically and is always constant in length. This problem only triggers when I use the dsnoo-plugin. If running directly towards the device, the audio stream is fine (no garbage). I've not tested if this occurs with any other plugin.
I'm using Dsnoop to capture a mono stream from a stereo device using arecord, arecord -v -r 16000 -c1 -Daudiosource0 -fS16_LE /tmp/in.wav (where audiosource0 is my dsnoop-device, bound to channel 0)
The verbose info from arecord shows me that ALSA has correctly created the Dsnoop device, with a "buffer_size" of 8000. It also shows that it has opened my Hardware device in MMAP-mode, with a "buffer_size" of 8192.
Show us this output from 'arecord -v'.
Jaroslav
----- Jaroslav Kysela perex@perex.cz Linux Kernel Sound Maintainer ALSA Project, Red Hat, Inc.
This output is captured when running periods_min=4.
[root@axis /mnt/flash/root]1335# arecord -v -r 16000 -c1 -Daudiosource0 -fS16_LE /tmp/in.wav Recording WAVE '/tmp/in.wav' : Signed 16 bit Little Endian, Rate 16000 Hz, Mono Direct Snoop PCM Its setup is: stream : CAPTURE access : RW_INTERLEAVED format : S16_LE subformat : STD channels : 1 rate : 16000 exact rate : 16000 (16000/1) msbits : 16 buffer_size : 8000 period_size : 2000 period_time : 125000 tstamp_mode : NONE period_step : 1 avail_min : 2000 period_event : 0 start_threshold : 1 stop_threshold : 8000 silence_threshold: 0 silence_size : 0 boundary : 2097152000 Hardware PCM card 0 'X4 AIC3104 Dual' device 0 subdevice 0 Its setup is: stream : CAPTURE access : MMAP_INTERLEAVED format : S16_LE subformat : STD channels : 2 rate : 16000 exact rate : 16000 (16000/1) msbits : 16 buffer_size : 8192 period_size : 2000 period_time : 125000 tstamp_mode : ENABLE period_step : 1 avail_min : 2000 period_event : 0 start_threshold : 1 stop_threshold : 1073741824 silence_threshold: 0 silence_size : 0 boundary : 1073741824 appl_ptr : 0 hw_ptr : 0
-----Original Message----- From: alsa-devel-bounces@alsa-project.org [mailto:alsa-devel-bounces@alsa-project.org] On Behalf Of Jaroslav Kysela Sent: den 14 mars 2011 11:08 To: Magnus Olsson Cc: alsa-devel@alsa-project.org Subject: Re: [alsa-devel] Dsnoop-plugin buffer sizes
On Mon, 14 Mar 2011, Magnus Olsson wrote:
Hi,
I'm having issues with garbage data in my audio stream, which I believe is caused by incorrect buffer sizes somewhere in the audio pipeline. The garbage occurs periodically and is always constant in length. This problem only triggers when I use the dsnoo-plugin. If running directly towards the device, the audio stream is fine (no garbage). I've not tested if this occurs with any other plugin.
I'm using Dsnoop to capture a mono stream from a stereo device using arecord, arecord -v -r 16000 -c1 -Daudiosource0 -fS16_LE /tmp/in.wav (where audiosource0 is my dsnoop-device, bound to channel 0)
The verbose info from arecord shows me that ALSA has correctly created the Dsnoop device, with a "buffer_size" of 8000. It also shows that it has opened my Hardware device in MMAP-mode, with a "buffer_size" of 8192.
Show us this output from 'arecord -v'.
Jaroslav
----- Jaroslav Kysela perex@perex.cz Linux Kernel Sound Maintainer ALSA Project, Red Hat, Inc.
_______________________________________________ Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
On Mon, 14 Mar 2011, Magnus Olsson wrote:
This output is captured when running periods_min=4.
Direct Snoop PCM buffer_size : 8000 Hardware PCM card 0 'X4 AIC3104 Dual' device 0 subdevice 0 buffer_size : 8192
This may be OK. The buffer sizes between plugins can differ. What are the parameters for direct record ? (use 'arecord -v' with plughw device).
Also, you may try to force the buffer size to 8000 for dsnoop (use period_size 2000, periods 4) in your dmix slave configuration, for example:
type dmix slave { period_size 2000 periods 4 }
If this works, it's probably a bug in the driver.
Jaroslav
----- Jaroslav Kysela perex@perex.cz Linux Kernel Sound Maintainer ALSA Project, Red Hat, Inc.
-----Original Message----- From: Jaroslav Kysela [mailto:perex@perex.cz] Sent: den 14 mars 2011 11:53 To: Magnus Olsson Cc: alsa-devel@alsa-project.org Subject: Re: [alsa-devel] Dsnoop-plugin buffer sizes
Also, you may try to force the buffer size to 8000 for dsnoop (use period_size 2000, periods 4) in your dmix slave configuration, for example:
type dmix slave { period_size 2000 periods 4 }
If this works, it's probably a bug in the driver.
Ah, yes, I traced down the issue in the PCM driver. It assumed params_periods()*params_period_bytes() == params_buffer_bytes() without an integer constraint on number of periods.
Thanks!
Jaroslav
Jaroslav Kysela perex@perex.cz Linux Kernel Sound Maintainer ALSA Project, Red Hat, Inc.
participants (2)
-
Jaroslav Kysela
-
Magnus Olsson