Discussion:
snd_pcm_hw_params_set_buffer_time_near: invalid argument
Jean-Yves Avenard
2011-03-06 11:49:28 UTC
Permalink
Hi there.

I'm a bit puzzled as to what values are considered valids and which
one aren't when it comes to setting the buffer time with
snd_pcm_hw_params_set_buffer_time_near.

For example setting a value of 295ms : all ok. From 300ms to 450ms ->
"Invalid argument".
but 500ms for example is okay.

What's the logic behind it ?
It's obviously related to the sampling rate, the audio format and the
number of channels ; as the values giving me "Invalid argument" change
then.

Any comments would be greatly appreciated.

Thanks!
JY
Raymond Yau
2011-03-06 12:01:34 UTC
Permalink
Post by Jean-Yves Avenard
Hi there.
I'm a bit puzzled as to what values are considered valids and which
one aren't when it comes to setting the buffer time with
snd_pcm_hw_params_set_buffer_time_near.
For example setting a value of 295ms : all ok. From 300ms to 450ms ->
"Invalid argument".
but 500ms for example is okay.
What's the logic behind it ?
Different sound card driver have different hardware constraints

e.g. HDA-Intel has the following constraints

snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
128);
snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
128);

Attach a program buffertime.c to find out those buffer time with invalid
argument ?
Raymond Yau
2011-03-07 12:24:28 UTC
Permalink
Post by Jean-Yves Avenard
Hi there.
I'm a bit puzzled as to what values are considered valids and which
one aren't when it comes to setting the buffer time with
snd_pcm_hw_params_set_buffer_time_near.
For example setting a value of 295ms : all ok. From 300ms to 450ms ->
"Invalid argument".
but 500ms for example is okay.
What's the logic behind it ?
It's obviously related to the sampling rate, the audio format and the
number of channels ; as the values giving me "Invalid argument" change
then.
Any comments would be greatly appreciated.
Thanks!
JY
This seem to be bug in alsa-lib as I can reproduce using alsa-lib/test/pcm.c
with buffer time 120000 and my hda codec support both 11025Hz and 22050Hz

using buffer time 160000 is OK


./pcm -Dhw:CARD=Intel,DEV=0 -b 120000 -r 22050 -c 2
Playback device is hw:CARD=Intel,DEV=0
Stream parameters are 22050Hz, S16_LE, 2 channels
Sine wave rate is 440.0000Hz
Using transfer method: write
Unable to set buffer time 120000 for playback: Invalid argument
Setting of hwparams failed: Invalid argument


./pcm -Dhw:CARD=Intel,DEV=0 -b 120000 -r 11025 -c 2
Playback device is hw:CARD=Intel,DEV=0
Stream parameters are 11025Hz, S16_LE, 2 channels
Sine wave rate is 440.0000Hz
Using transfer method: write
Unable to set buffer time 120000 for playback: Invalid argument
Setting of hwparams failed: Invalid argument



./pcm -Dhw:CARD=Intel,DEV=0 -b 160000 -r 11025 -c 2
Playback device is hw:CARD=Intel,DEV=0
Stream parameters are 11025Hz, S16_LE, 2 channels
Sine wave rate is 440.0000Hz
Using transfer method: write
Jean-Yves Avenard
2011-03-07 22:32:22 UTC
Permalink
Post by Raymond Yau
This seem to be bug in alsa-lib as I can reproduce using alsa-lib/test/pcm.c
with buffer time 120000 and my hda codec support both 11025Hz and 22050Hz
using buffer time 160000 is OK
Yes.. It's hard to understand why 120ms wouldn't be okay, but 160ms would.

Could you check is 400ms works for you ? I found this to be a value
that generally do not work when using 44.1kHz 6 channels audio.

For the time being, I made my application use 500ms buffer; this is
what many media players are using (including mplayer) , so I'm
guessing it would be fine under most circumstances otherwise we would
have heard about it before.

Jean-Yves
Raymond Yau
2011-03-08 13:25:25 UTC
Permalink
Post by Raymond Yau
Post by Raymond Yau
This seem to be bug in alsa-lib as I can reproduce using
alsa-lib/test/pcm.c
Post by Raymond Yau
with buffer time 120000 and my hda codec support both 11025Hz and 22050Hz
using buffer time 160000 is OK
Yes.. It's hard to understand why 120ms wouldn't be okay, but 160ms would.
Could you check is 400ms works for you ? I found this to be a value
that generally do not work when using 44.1kHz 6 channels audio.
For the time being, I made my application use 500ms buffer; this is
what many media players are using (including mplayer) , so I'm
guessing it would be fine under most circumstances otherwise we would
have heard about it before.
Jean-Yves
It seem that hda-intel does not really has AZX_MAX_BUF_SIZE 1024x1024x1024
on 32bits machine , buffer bytes was reduced to 64K bytes at the beginning
by "Rule 23"

Does linux kernel allow ALSA allocate 2/3 of system memory for sound buffer
on a machine iwth 1.5Gbytes memory

64Kbytes is only 371ms of S16_LE 44100Hz stereo


ACCESS = 00000000ffffffffffffffff -> 0000000000000009
FORMAT = 00000000ffffffffffffffff -> 0000000000000404
SUBFORMAT = 00000000ffffffffffffffff -> 0000000000000001
SAMPLE_BITS = [0 4294967295] -> [0 4294967295]
FRAME_BITS = [0 4294967295] -> [0 4294967295]
CHANNELS = [0 4294967295] -> [2 8]
RATE = [0 4294967295] -> [8000 192000]
PERIOD_TIME = [0 4294967295] -> [0 4294967295]
PERIOD_SIZE = [0 4294967295] -> [0 4294967295]
PERIOD_BYTES = [0 4294967295] -> [128 536870912]
PERIODS = [0 4294967295] -> [2 32]
BUFFER_TIME = [0 4294967295] -> [0 4294967295]
BUFFER_SIZE = [0 4294967295] -> [0 4294967295]
BUFFER_BYTES = [0 4294967295] -> [128 1073741824]
TICK_TIME = [0 4294967295] -> [0 4294967295]
Rule 0 [f8ae36f2]: FORMAT = 404 -> 404
Rule 1 [f8ae351b]: SAMPLE_BITS = [0 4294967295] -> [16 32]
Rule 2 [f8ae365f]: SAMPLE_BITS = [16 32] -> [16 32]
Rule 3 [f8ae361d]: FRAME_BITS = [0 4294967295] -> [32 256]
Rule 4 [f8ae35d9]: FRAME_BITS = [32 256] -> [32 256]
Rule 5 [f8ae35d9]: FRAME_BITS = [32 256] -> [32 256]
Rule 6 [f8ae365f]: CHANNELS = [2 8] -> [2 8]
Rule 7 [f8ae35d9]: RATE = [8000 192000] -> [8000 192000]
Rule 8 [f8ae35d9]: RATE = [8000 192000] -> [8000 192000]
Rule 9 [f8ae365f]: PERIODS = [2 32] -> [2 32]
Rule 10 [f8ae365f]: PERIOD_SIZE = [0 4294967295] -> [0 2147483647]
Rule 11 [f8ae35d9]: PERIOD_SIZE = [0 2147483647] -> [4 134217728]
Rule 12 [f8ae3595]: PERIOD_SIZE = [4 134217728] -> [4 134217728]
Rule 13 [f8ae361d]: BUFFER_SIZE = [0 4294967295] -> [8 4294967295]
Rule 14 [f8ae35d9]: BUFFER_SIZE = [8 4294967295] -> [8 268435456]
Rule 15 [f8ae3595]: BUFFER_SIZE = [8 268435456] -> [8 268435456]
Rule 16 [f8ae3595]: PERIOD_BYTES = [128 536870912] -> [128 536870912]
Rule 17 [f8ae3595]: BUFFER_BYTES = [128 1073741824] -> [128 1073741824]
Rule 18 [f8ae35d9]: PERIOD_TIME = [0 4294967295] -> (20 4294967295]
Rule 19 [f8ae35d9]: BUFFER_TIME = [0 4294967295] -> (41 4294967295]
Rule 20 [f8ae5fa6]: BUFFER_BYTES = [128 1073741824] -> [128 1073741824]
Rule 21 [f8ae5fa6]: PERIOD_BYTES = [128 536870912] -> [128 536870912]
Rule 22 [f8ae5fa6]: CHANNELS = [2 8] -> [2 8]
Rule 23 [f8ae34e2]: BUFFER_BYTES = [128 1073741824] -> [128 65536]
Rule 24 [f8ae34bd]: RATE = [8000 192000] -> [8000 192000]
Takashi Iwai
2011-04-04 11:00:00 UTC
Permalink
At Tue, 8 Mar 2011 21:25:25 +0800,
Post by Raymond Yau
Post by Raymond Yau
Post by Raymond Yau
This seem to be bug in alsa-lib as I can reproduce using
alsa-lib/test/pcm.c
Post by Raymond Yau
with buffer time 120000 and my hda codec support both 11025Hz and 22050Hz
using buffer time 160000 is OK
Yes.. It's hard to understand why 120ms wouldn't be okay, but 160ms would.
Could you check is 400ms works for you ? I found this to be a value
that generally do not work when using 44.1kHz 6 channels audio.
For the time being, I made my application use 500ms buffer; this is
what many media players are using (including mplayer) , so I'm
guessing it would be fine under most circumstances otherwise we would
have heard about it before.
Jean-Yves
It seem that hda-intel does not really has AZX_MAX_BUF_SIZE 1024x1024x1024
on 32bits machine , buffer bytes was reduced to 64K bytes at the beginning
by "Rule 23"
It's because of the pre-allocation buffer size.
You can change it via proc file dynamically:
echo 1024 > /proc/asound/card0/pcm0p/sub0/prealloc


Takashi

Raymond Yau
2011-03-09 03:52:34 UTC
Permalink
Post by Raymond Yau
Post by Raymond Yau
This seem to be bug in alsa-lib as I can reproduce using
alsa-lib/test/pcm.c
Post by Raymond Yau
with buffer time 120000 and my hda codec support both 11025Hz and 22050Hz
using buffer time 160000 is OK
Yes.. It's hard to understand why 120ms wouldn't be okay, but 160ms would.
Could you check is 400ms works for you ? I found this to be a value
that generally do not work when using 44.1kHz 6 channels audio.
For the time being, I made my application use 500ms buffer; this is
what many media players are using (including mplayer) , so I'm
guessing it would be fine under most circumstances otherwise we would
have heard about it before.
Jean-Yves
hda-intel.c only allocate 64Kbytes

/* buffer pre-allocation */
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
snd_dma_pci_data(chip->pci),
1024 * 64, 32 * 1024 * 1024);

user or distribution need to change "prealloc" from 64 to a higher value for
getting 500ms buffer

echo 1024 > /proc/asound/Intel/pcm0p/sub0/prealloc
Jean-Yves Avenard
2011-03-09 12:23:41 UTC
Permalink
Hi
Post by Raymond Yau
hda-intel.c only allocate 64Kbytes
   /* buffer pre-allocation */
   snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
                         snd_dma_pci_data(chip->pci),
                         1024 * 64, 32 * 1024 * 1024);
user or distribution need to change "prealloc" from 64 to a higher value for
getting 500ms buffer
echo 1024 > /proc/asound/Intel/pcm0p/sub0/prealloc
It seems you misunderstood my first message.

For a start, the default memory allocated to alsa in ubuntu is 4096kB.
so the amount of ram isn't the problem.

Setting a buffer of
200ms: ok
300ms: ok
400ms: not ok (invalid argument)
500ms: ok

Why would 400ms gives invalid argument, when 500ms doesn't nor 300.
Memory available is obviously not the issue.

If only 64kB is allocated, requesting 200ms gives you 200ms
300ms -> 300ms
400ms -> invalid argument
500ms -> 371ms
600ms -> 371ms

You would assume that requesting 400ms would work or return what can
fit in what has been pre-allocated.

Jy
Jaroslav Kysela
2011-03-09 12:29:42 UTC
Permalink
Post by Jean-Yves Avenard
Hi
Post by Raymond Yau
hda-intel.c only allocate 64Kbytes
   /* buffer pre-allocation */
   snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
                         snd_dma_pci_data(chip->pci),
                         1024 * 64, 32 * 1024 * 1024);
user or distribution need to change "prealloc" from 64 to a higher value for
getting 500ms buffer
echo 1024 > /proc/asound/Intel/pcm0p/sub0/prealloc
It seems you misunderstood my first message.
For a start, the default memory allocated to alsa in ubuntu is 4096kB.
so the amount of ram isn't the problem.
Setting a buffer of
200ms: ok
300ms: ok
400ms: not ok (invalid argument)
500ms: ok
Why would 400ms gives invalid argument, when 500ms doesn't nor 300.
Memory available is obviously not the issue.
If only 64kB is allocated, requesting 200ms gives you 200ms
300ms -> 300ms
400ms -> invalid argument
500ms -> 371ms
600ms -> 371ms
You would assume that requesting 400ms would work or return what can
fit in what has been pre-allocated.
What is your dir argument (last one) for the near functions? If it's NULL
or value is zero, it means you request the exact value which may not be
available. Use -1 to request specified or smaller value or 1 to request
specified or bigger value.

Jaroslav

-----
Jaroslav Kysela <***@perex.cz>
Linux Kernel Sound Maintainer
ALSA Project, Red Hat, Inc.
Raymond Yau
2011-03-10 00:44:54 UTC
Permalink
Post by Jaroslav Kysela
Hi
Post by Raymond Yau
hda-intel.c only allocate 64Kbytes
Post by Raymond Yau
/* buffer pre-allocation */
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
snd_dma_pci_data(chip->pci),
1024 * 64, 32 * 1024 * 1024);
user or distribution need to change "prealloc" from 64 to a higher value for
getting 500ms buffer
echo 1024 > /proc/asound/Intel/pcm0p/sub0/prealloc
It seems you misunderstood my first message.
For a start, the default memory allocated to alsa in ubuntu is 4096kB.
so the amount of ram isn't the problem.
Setting a buffer of
200ms: ok
300ms: ok
400ms: not ok (invalid argument)
500ms: ok
Why would 400ms gives invalid argument, when 500ms doesn't nor 300.
Memory available is obviously not the issue.
If only 64kB is allocated, requesting 200ms gives you 200ms
300ms -> 300ms
400ms -> invalid argument
500ms -> 371ms
600ms -> 371ms
You would assume that requesting 400ms would work or return what can
fit in what has been pre-allocated.
What is your dir argument (last one) for the near functions? If it's NULL
or value is zero, it means you request the exact value which may not be
available. Use -1 to request specified or smaller value or 1 to request
specified or bigger value.
Jaroslav
According to your explanation, it should fail at 500ms buffer time when
rate is 11025Hz and dir=0 or NULL, since half of 11025 is 5512.5

but

alsa-lib/test/pcm -v -Dhw:CARD=Intel,DEV=0 -r 11025 -c 2 -b 500000

Playback device is hw:CARD=Intel,DEV=0
Stream parameters are 11025Hz, S16_LE, 2 channels
Sine wave rate is 440.0000Hz
Using transfer method: write
Hardware PCM card 1 'HDA Intel' device 0 subdevice 0
Its setup is:
stream : PLAYBACK
access : RW_INTERLEAVED
format : S16_LE
subformat : STD
channels : 2
rate : 11025
exact rate : 11025 (11025/1)
msbits : 16
buffer_size : 5504
period_size : 1376
period_time : 124807
tstamp_mode : NONE
period_step : 1
avail_min : 1376
period_event : 0
start_threshold : 5504
stop_threshold : 5504
silence_threshold: 0
silence_size : 0
boundary : 1442840576
appl_ptr : 0
hw_ptr : 0
Jean-Yves Avenard
2011-03-10 00:53:49 UTC
Permalink
Hi
What is your dir argument (last one) for the near functions? If it's NULL or
value is zero, it means you request the exact value which may not be
available. Use -1 to request specified or smaller value or 1 to request
specified or bigger value.
It is zero.

That still doesn't explain the difference in behaviour I'm seeing
between 400ms or 500ms request. Neither of those are possible with a
64kB buffer.

What you are describing isn't what is happening in practice:
Requesting 500ms with the dir=0 (or NULL) provides a buffer of 371ms.
So it doesn't return an exact value, not even close (I found that with
dir=0 or NULL always return a value equal or less than what is
requested. If less the value returned is the maximum allowed by the
prealloc value)

JY
Raymond Yau
2011-03-20 02:01:54 UTC
Permalink
Post by Jaroslav Kysela
Hi
Post by Raymond Yau
hda-intel.c only allocate 64Kbytes
Post by Raymond Yau
/* buffer pre-allocation */
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
snd_dma_pci_data(chip->pci),
1024 * 64, 32 * 1024 * 1024);
user or distribution need to change "prealloc" from 64 to a higher value for
getting 500ms buffer
echo 1024 > /proc/asound/Intel/pcm0p/sub0/prealloc
It seems you misunderstood my first message.
For a start, the default memory allocated to alsa in ubuntu is 4096kB.
so the amount of ram isn't the problem.
Setting a buffer of
200ms: ok
300ms: ok
400ms: not ok (invalid argument)
500ms: ok
Why would 400ms gives invalid argument, when 500ms doesn't nor 300.
Memory available is obviously not the issue.
If only 64kB is allocated, requesting 200ms gives you 200ms
300ms -> 300ms
400ms -> invalid argument
500ms -> 371ms
600ms -> 371ms
You would assume that requesting 400ms would work or return what can
fit in what has been pre-allocated.
What is your dir argument (last one) for the near functions? If it's NULL
or value is zero, it means you request the exact value which may not be
available. Use -1 to request specified or smaller value or 1 to request
specified or bigger value.
Take another example from alsa-lib/test

Try many parameters but still cannot let alsa-lib/test/latency.c work with
alsa-pulse plugin and latency stop without any error message

alsa-lib/test/latency -P pulse -C pulse

adding some debug statement and find that it alway fail in setparams()


if (*bufsize > latency_max) {
+ printf("*bufsize %d > latency_max %d\n",*bufsize,latency_max);
return -1;
}
Loading...