[alsa-devel] [PATCH 2/2] Improve hw_params documentation
--- include/pcm.h | 14 +++++++++++++- src/pcm/pcm.c | 10 +++++++++- 2 files changed, 22 insertions(+), 2 deletions(-)
Andrew Eikum wrote:
+++ b/include/pcm.h @@ -44,8 +44,20 @@ extern "C" {
/** PCM generic info container */ typedef struct _snd_pcm_info snd_pcm_info_t; -/** PCM hardware configuration space container */
+/** PCM hardware configuration space container
- snd_pcm_hw_params_t is an opaque structure which contains a set of possible
- PCM hardware configurations. For example, a given instance might include a
- range of buffer sizes, a range of period sizes, and a set of several sample
- formats. Some subset of all possible combinations these sets may be valid,
- but not necessarily any combination will be valid.
- No validation is done by the various snd_pcm_hw_params_set* functions.
These functions do validate the value that the application is trying to set and adjust all other dependent limits.
Regards, Clemens
On Wed, Nov 16, 2011 at 10:20:07PM +0100, Clemens Ladisch wrote:
Andrew Eikum wrote:
+++ b/include/pcm.h @@ -44,8 +44,20 @@ extern "C" {
/** PCM generic info container */ typedef struct _snd_pcm_info snd_pcm_info_t; -/** PCM hardware configuration space container */
+/** PCM hardware configuration space container
- snd_pcm_hw_params_t is an opaque structure which contains a set of possible
- PCM hardware configurations. For example, a given instance might include a
- range of buffer sizes, a range of period sizes, and a set of several sample
- formats. Some subset of all possible combinations these sets may be valid,
- but not necessarily any combination will be valid.
- No validation is done by the various snd_pcm_hw_params_set* functions.
These functions do validate the value that the application is trying to set and adjust all other dependent limits.
I didn't find that to be the case in my testing, at least between periods, period_size, and buffer_size. I've attached a test program here. It sets periods to 10, period_size to 1024, and buffer_size_max to be the same as the return from get_buffer_size_min (in my case, 80). The first call to fail is snd_pcm_hw_params(). If what you said is true, I would expect the set_buffer_size_max() call to fail.
$ gcc -I /usr/include/alsa -lasound -o alsa_period_count alsa_period_count.c $ ./alsa_period_count min_buffer_frames: 80 set max buffer size: 80 snd_pcm_hw_params: -12 $
Andrew
On 11/16/2011 10:31 PM, Andrew Eikum wrote:
On Wed, Nov 16, 2011 at 10:20:07PM +0100, Clemens Ladisch wrote:
Andrew Eikum wrote:
+++ b/include/pcm.h @@ -44,8 +44,20 @@ extern "C" {
/** PCM generic info container */ typedef struct _snd_pcm_info snd_pcm_info_t; -/** PCM hardware configuration space container */
+/** PCM hardware configuration space container
- snd_pcm_hw_params_t is an opaque structure which contains a set of possible
- PCM hardware configurations. For example, a given instance might include a
- range of buffer sizes, a range of period sizes, and a set of several sample
- formats. Some subset of all possible combinations these sets may be valid,
- but not necessarily any combination will be valid.
- No validation is done by the various snd_pcm_hw_params_set* functions.
These functions do validate the value that the application is trying to set and adjust all other dependent limits.
I didn't find that to be the case in my testing, at least between periods, period_size, and buffer_size. I've attached a test program here.
I can reproduce this.
Try running the program with LIBASOUND_DEBUG=1; it appears that there is a bug in the rate plugin. (Normal programs actually set their rate ...)
Regards, Clemens
On Wed, Nov 16, 2011 at 11:08:37PM +0100, Clemens Ladisch wrote:
On 11/16/2011 10:31 PM, Andrew Eikum wrote:
On Wed, Nov 16, 2011 at 10:20:07PM +0100, Clemens Ladisch wrote:
Andrew Eikum wrote:
+++ b/include/pcm.h @@ -44,8 +44,20 @@ extern "C" {
/** PCM generic info container */ typedef struct _snd_pcm_info snd_pcm_info_t; -/** PCM hardware configuration space container */
+/** PCM hardware configuration space container
- snd_pcm_hw_params_t is an opaque structure which contains a set of possible
- PCM hardware configurations. For example, a given instance might include a
- range of buffer sizes, a range of period sizes, and a set of several sample
- formats. Some subset of all possible combinations these sets may be valid,
- but not necessarily any combination will be valid.
- No validation is done by the various snd_pcm_hw_params_set* functions.
These functions do validate the value that the application is trying to set and adjust all other dependent limits.
I didn't find that to be the case in my testing, at least between periods, period_size, and buffer_size. I've attached a test program here.
I can reproduce this.
Try running the program with LIBASOUND_DEBUG=1; it appears that there is a bug in the rate plugin. (Normal programs actually set their rate ...)
This doesn't change the output in any way. I checked the Arch Linux alsa-lib build script[1] and it doesn't seem to disable debugging in any obvious way. Do I have to explicitly enable debugging output and rebuild?
$ LIBASOUND_DEBUG=1 ./alsa_period_count min_buffer_frames: 80 set max buffer size: 80 snd_pcm_hw_params: -12 $
[1] http://projects.archlinux.org/svntogit/packages.git/tree/trunk/PKGBUILD?h=pa...
Andrew
2011/11/17 Andrew Eikum aeikum@codeweavers.com:
On Wed, Nov 16, 2011 at 11:08:37PM +0100, Clemens Ladisch wrote:
On 11/16/2011 10:31 PM, Andrew Eikum wrote:
On Wed, Nov 16, 2011 at 10:20:07PM +0100, Clemens Ladisch wrote:
Andrew Eikum wrote:
+++ b/include/pcm.h @@ -44,8 +44,20 @@ extern "C" {
/** PCM generic info container */ typedef struct _snd_pcm_info snd_pcm_info_t; -/** PCM hardware configuration space container */
+/** PCM hardware configuration space container
- snd_pcm_hw_params_t is an opaque structure which contains a set of possible
- PCM hardware configurations. For example, a given instance might include a
- range of buffer sizes, a range of period sizes, and a set of several sample
- formats. Some subset of all possible combinations these sets may be valid,
- but not necessarily any combination will be valid.
- No validation is done by the various snd_pcm_hw_params_set* functions.
These functions do validate the value that the application is trying to set and adjust all other dependent limits.
I didn't find that to be the case in my testing, at least between periods, period_size, and buffer_size. I've attached a test program here.
I can reproduce this.
Try running the program with LIBASOUND_DEBUG=1; it appears that there is a bug in the rate plugin. (Normal programs actually set their rate ...)
This doesn't change the output in any way. I checked the Arch Linux alsa-lib build script[1] and it doesn't seem to disable debugging in any obvious way. Do I have to explicitly enable debugging output and rebuild?
$ LIBASOUND_DEBUG=1 ./alsa_period_count min_buffer_frames: 80 set max buffer size: 80 snd_pcm_hw_params: -12 $
[1] http://projects.archlinux.org/svntogit/packages.git/tree/trunk/PKGBUILD?h=pa...
There is a bug in your program which set the buffer_size_max to buffer_size_min
err = snd_pcm_hw_params_set_periods(pcm, hw_params, 10, 0); if(err < 0){ printf("snd_pcm_hw_params_set_periods: %d\n", err); return 1; }
err = snd_pcm_hw_params_set_period_size(pcm, hw_params, 1024, 0); if(err < 0){ printf("snd_pcm_hw_params_set_period_size: %d\n", err); return 1; }
The above already set buffer size to 10240, but you set buffer_size_max to buffer_size_min (80)
err = snd_pcm_hw_params_get_buffer_size_min(hw_params, &buffer_frames); if(err < 0){ printf("snd_pcm_hw_params_get_buffer_size: %d\n", err); return 1; } printf("min_buffer_frames: %u\n", buffer_frames);
err = snd_pcm_hw_params_set_buffer_size_max(pcm, hw_params, &buffer_frames); if(err < 0){ printf("snd_pcm_hw_params_get_buffer_size: %d\n", err); return 1; } printf("set max buffer size: %u\n", buffer_frames);
./alsa_period_count pulse refine_soft 'pulse' (begin) ACCESS: RW_INTERLEAVED FORMAT: U8 S16_LE S16_BE S32_LE S32_BE FLOAT_LE FLOAT_BE MU_LAW A_LAW SUBFORMAT: ALL SAMPLE_BITS: ALL FRAME_BITS: ALL CHANNELS: [1 32] RATE: [1 192000] PERIOD_TIME: ALL PERIOD_SIZE: ALL PERIOD_BYTES: ALL PERIODS: ALL BUFFER_TIME: ALL BUFFER_SIZE: ALL BUFFER_BYTES: ALL TICK_TIME: ALL Rule 0 (0x160f80): FORMAT= U8 S16_LE S16_BE S32_LE S32_BE FLOAT_LE FLOAT_BE MU_LAW A_LAW -> U8 S16_LE S16_BE S32_LE S32_BE FLOAT_LE FLOAT_BE MU_LAW A_LAW SAMPLE_BITS=[1 4294967295] Rule 1 (0x160e70): SAMPLE_BITS=[1 4294967295] -> [8 32] FORMAT= U8 S16_LE S16_BE S32_LE S32_BE FLOAT_LE FLOAT_BE MU_LAW A_LAW SAMPLE_BITS=[8 32] Rule 2 (0x160df0): SAMPLE_BITS=[8 32] -> [8 32] FRAME_BITS=[1 4294967295] CHANNELS=[1 32] Rule 3 (0x160d70): FRAME_BITS=[1 4294967295] -> [8 1024] SAMPLE_BITS=[8 32] CHANNELS=[1 32] Rule 4 (0x160cf0): FRAME_BITS=[8 1024] -> [8 1024] PERIOD_BYTES=ALL PERIOD_SIZE=ALL Rule 5 (0x160cf0): FRAME_BITS=[8 1024] -> [8 1024] BUFFER_BYTES=[1 4294967295] BUFFER_SIZE=[1 4294967295] Rule 6 (0x160df0): CHANNELS=[1 32] -> [1 32] FRAME_BITS=[8 1024] SAMPLE_BITS=[8 32] Rule 7 (0x160cf0): RATE=[1 192000] -> [1 192000] PERIOD_SIZE=ALL PERIOD_TIME=ALL Rule 8 (0x160cf0): RATE=[1 192000] -> [1 192000] BUFFER_SIZE=[1 4294967295] BUFFER_TIME=[1 4294967295] Rule 9 (0x160df0): PERIODS=ALL -> (0 4294967295] BUFFER_SIZE=[1 4294967295] PERIOD_SIZE=ALL Rule 10 (0x160df0): PERIOD_SIZE=ALL -> (0 4294967295] BUFFER_SIZE=[1 4294967295] PERIODS=(0 4294967295] Rule 11 (0x160cf0): PERIOD_SIZE=(0 4294967295] -> (0 4294967295] PERIOD_BYTES=ALL FRAME_BITS=[8 1024] Rule 12 (0x160c70): PERIOD_SIZE=(0 4294967295] -> (0 824633721) PERIOD_TIME=ALL RATE=[1 192000] Rule 13 (0x160d70): BUFFER_SIZE=[1 4294967295] -> [1 4294967294] PERIOD_SIZE=(0 824633721) PERIODS=(0 4294967295] Rule 14 (0x160cf0): BUFFER_SIZE=[1 4294967294] -> [1 4294967294] BUFFER_BYTES=[1 4294967295] FRAME_BITS=[8 1024] Rule 15 (0x160c70): BUFFER_SIZE=[1 4294967294] -> [1 824633720] BUFFER_TIME=[1 4294967295] RATE=[1 192000] Rule 16 (0x160c70): PERIOD_BYTES=ALL -> (0 4294967295) PERIOD_SIZE=(0 824633721) FRAME_BITS=[8 1024] Rule 17 (0x160c70): BUFFER_BYTES=[1 4294967295] -> [1 4294967295] BUFFER_SIZE=[1 824633720] FRAME_BITS=[8 1024] Rule 18 (0x160cf0): PERIOD_TIME=ALL -> (0 4294967295) PERIOD_SIZE=(0 824633721) RATE=[1 192000] Rule 19 (0x160cf0): BUFFER_TIME=[1 4294967295] -> (5 4294967295] BUFFER_SIZE=[1 824633720] RATE=[1 192000] Rule 0 (0x160f80): FORMAT= U8 S16_LE S16_BE S32_LE S32_BE FLOAT_LE FLOAT_BE MU_LAW A_LAW -> U8 S16_LE S16_BE S32_LE S32_BE FLOAT_LE FLOAT_BE MU_LAW A_LAW SAMPLE_BITS=[8 32] Rule 2 (0x160df0): SAMPLE_BITS=[8 32] -> [8 32] FRAME_BITS=[8 1024] CHANNELS=[1 32] Rule 4 (0x160cf0): FRAME_BITS=[8 1024] -> [8 1024] PERIOD_BYTES=(0 4294967295) PERIOD_SIZE=(0 824633721) Rule 5 (0x160cf0): FRAME_BITS=[8 1024] -> [8 1024] BUFFER_BYTES=[1 4294967295] BUFFER_SIZE=[1 824633720] Rule 7 (0x160cf0): RATE=[1 192000] -> [1 192000] PERIOD_SIZE=(0 824633721) PERIOD_TIME=(0 4294967295) Rule 8 (0x160cf0): RATE=[1 192000] -> [1 192000] BUFFER_SIZE=[1 824633720] BUFFER_TIME=(5 4294967295] Rule 9 (0x160df0): PERIODS=(0 4294967295] -> (0 4294967295] BUFFER_SIZE=[1 824633720] PERIOD_SIZE=(0 824633721) Rule 10 (0x160df0): PERIOD_SIZE=(0 824633721) -> (0 824633721) BUFFER_SIZE=[1 824633720] PERIODS=(0 4294967295] Rule 11 (0x160cf0): PERIOD_SIZE=(0 824633721) -> (0 824633721) PERIOD_BYTES=(0 4294967295) FRAME_BITS=[8 1024] Rule 12 (0x160c70): PERIOD_SIZE=(0 824633721) -> (0 824633721) PERIOD_TIME=(0 4294967295) RATE=[1 192000] Rule 15 (0x160c70): BUFFER_SIZE=[1 824633720] -> [1 824633720] BUFFER_TIME=(5 4294967295] RATE=[1 192000] min periods 3 max periods 1024 min_buffer_frames: 80 set max buffer size: 80 refine_soft 'pulse' (begin) ACCESS: RW_INTERLEAVED FORMAT: U8 SUBFORMAT: STD SAMPLE_BITS: [8 32] FRAME_BITS: [8 1024] CHANNELS: [1 32] RATE: [1 192000] PERIOD_TIME: (5333 1024000000] PERIOD_SIZE: 1024 PERIOD_BYTES: 1024 PERIODS: 10 BUFFER_TIME: (416 80000000] BUFFER_SIZE: 80 BUFFER_BYTES: 10240 TICK_TIME: ALL Rule 1 (0x160e70): SAMPLE_BITS=[8 32] -> 8 FORMAT= U8 SAMPLE_BITS=8 Rule 3 (0x160d70): FRAME_BITS=[8 1024] -> [8 256] SAMPLE_BITS=8 CHANNELS=[1 32] Rule 4 (0x160cf0): FRAME_BITS=[8 256] -> 8 PERIOD_BYTES=1024 PERIOD_SIZE=1024 Rule 5 (0x160cf0): FRAME_BITS=8 -> NONE BUFFER_BYTES=10240 BUFFER_SIZE=80 refine_soft 'pulse' (end--22) ACCESS: RW_INTERLEAVED FORMAT: U8 SUBFORMAT: STD SAMPLE_BITS: 8 FRAME_BITS: NONE CHANNELS: [1 32] RATE: [1 192000] PERIOD_TIME: (5333 1024000000] PERIOD_SIZE: 1024 PERIOD_BYTES: 1024 PERIODS: 10 BUFFER_TIME: (416 80000000] BUFFER_SIZE: 80 BUFFER_BYTES: 10240 TICK_TIME: ALL snd_pcm_hw_params: -12
On Tue, Nov 22, 2011 at 06:31:03AM +0800, Raymond Yau wrote:
2011/11/17 Andrew Eikum aeikum@codeweavers.com:
On Wed, Nov 16, 2011 at 11:08:37PM +0100, Clemens Ladisch wrote:
On 11/16/2011 10:31 PM, Andrew Eikum wrote:
On Wed, Nov 16, 2011 at 10:20:07PM +0100, Clemens Ladisch wrote:
Andrew Eikum wrote:
+++ b/include/pcm.h @@ -44,8 +44,20 @@ extern "C" {
/** PCM generic info container */ typedef struct _snd_pcm_info snd_pcm_info_t; -/** PCM hardware configuration space container */
+/** PCM hardware configuration space container
- snd_pcm_hw_params_t is an opaque structure which contains a set of possible
- PCM hardware configurations. For example, a given instance might include a
- range of buffer sizes, a range of period sizes, and a set of several sample
- formats. Some subset of all possible combinations these sets may be valid,
- but not necessarily any combination will be valid.
- No validation is done by the various snd_pcm_hw_params_set* functions.
These functions do validate the value that the application is trying to set and adjust all other dependent limits.
I didn't find that to be the case in my testing, at least between periods, period_size, and buffer_size. I've attached a test program here.
I can reproduce this.
Try running the program with LIBASOUND_DEBUG=1; it appears that there is a bug in the rate plugin. (Normal programs actually set their rate ...)
This doesn't change the output in any way. I checked the Arch Linux alsa-lib build script[1] and it doesn't seem to disable debugging in any obvious way. Do I have to explicitly enable debugging output and rebuild?
$ LIBASOUND_DEBUG=1 ./alsa_period_count min_buffer_frames: 80 set max buffer size: 80 snd_pcm_hw_params: -12 $
[1] http://projects.archlinux.org/svntogit/packages.git/tree/trunk/PKGBUILD?h=pa...
There is a bug in your program which set the buffer_size_max to buffer_size_min
err = snd_pcm_hw_params_set_periods(pcm, hw_params, 10, 0); if(err < 0){ printf("snd_pcm_hw_params_set_periods: %d\n", err); return 1; } err = snd_pcm_hw_params_set_period_size(pcm, hw_params, 1024, 0); if(err < 0){ printf("snd_pcm_hw_params_set_period_size: %d\n", err); return 1; }
The above already set buffer size to 10240, but you set buffer_size_max to buffer_size_min (80)
err = snd_pcm_hw_params_get_buffer_size_min(hw_params, &buffer_frames); if(err < 0){ printf("snd_pcm_hw_params_get_buffer_size: %d\n", err); return 1; } printf("min_buffer_frames: %u\n", buffer_frames); err = snd_pcm_hw_params_set_buffer_size_max(pcm, hw_params, &buffer_frames); if(err < 0){ printf("snd_pcm_hw_params_get_buffer_size: %d\n", err); return 1; } printf("set max buffer size: %u\n", buffer_frames);
Yes, that's exactly my point. I would expect set_buffer_size_max() to fail, since it's incompatible with the parameters set earlier. Instead, it succeeds.
Andrew
2011/11/22 Andrew Eikum aeikum@codeweavers.com:
On Tue, Nov 22, 2011 at 06:31:03AM +0800, Raymond Yau wrote:
2011/11/17 Andrew Eikum aeikum@codeweavers.com:
On Wed, Nov 16, 2011 at 11:08:37PM +0100, Clemens Ladisch wrote:
On 11/16/2011 10:31 PM, Andrew Eikum wrote:
On Wed, Nov 16, 2011 at 10:20:07PM +0100, Clemens Ladisch wrote:
Andrew Eikum wrote: > +++ b/include/pcm.h > @@ -44,8 +44,20 @@ extern "C" { > > /** PCM generic info container */ > typedef struct _snd_pcm_info snd_pcm_info_t; > -/** PCM hardware configuration space container */ > + > +/** PCM hardware configuration space container > + * > + * snd_pcm_hw_params_t is an opaque structure which contains a set of possible > + * PCM hardware configurations. For example, a given instance might include a > + * range of buffer sizes, a range of period sizes, and a set of several sample > + * formats. Some subset of all possible combinations these sets may be valid, > + * but not necessarily any combination will be valid. > + * > + * No validation is done by the various snd_pcm_hw_params_set* functions.
These functions do validate the value that the application is trying to set and adjust all other dependent limits.
I didn't find that to be the case in my testing, at least between periods, period_size, and buffer_size. I've attached a test program here.
I can reproduce this.
Try running the program with LIBASOUND_DEBUG=1; it appears that there is a bug in the rate plugin. (Normal programs actually set their rate ...)
This doesn't change the output in any way. I checked the Arch Linux alsa-lib build script[1] and it doesn't seem to disable debugging in any obvious way. Do I have to explicitly enable debugging output and rebuild?
$ LIBASOUND_DEBUG=1 ./alsa_period_count min_buffer_frames: 80 set max buffer size: 80 snd_pcm_hw_params: -12 $
[1] http://projects.archlinux.org/svntogit/packages.git/tree/trunk/PKGBUILD?h=pa...
There is a bug in your program which set the buffer_size_max to buffer_size_min
err = snd_pcm_hw_params_set_periods(pcm, hw_params, 10, 0); if(err < 0){ printf("snd_pcm_hw_params_set_periods: %d\n", err); return 1; }
err = snd_pcm_hw_params_set_period_size(pcm, hw_params, 1024, 0); if(err < 0){ printf("snd_pcm_hw_params_set_period_size: %d\n", err); return 1; }
The above already set buffer size to 10240, but you set buffer_size_max to buffer_size_min (80)
err = snd_pcm_hw_params_get_buffer_size_min(hw_params, &buffer_frames); if(err < 0){ printf("snd_pcm_hw_params_get_buffer_size: %d\n", err); return 1; } printf("min_buffer_frames: %u\n", buffer_frames);
err = snd_pcm_hw_params_set_buffer_size_max(pcm, hw_params, &buffer_frames); if(err < 0){ printf("snd_pcm_hw_params_get_buffer_size: %d\n", err); return 1; } printf("set max buffer size: %u\n", buffer_frames);
Yes, that's exactly my point. I would expect set_buffer_size_max() to fail, since it's incompatible with the parameters set earlier. Instead, it succeeds.
snd_pcm_hw_params_get_buffer_size_min() return a wrong value (80)
so far , your program still work with "hw", "dmix" and "jack"
It seem the bug is only occur with "pulse" plugin.
"pulse" can get the correct value 10240 after you set the format , rate and channels
"dmix" has a default period size of 1024 "jack" support FLOAT only and a default rate obtained from jack server and a channel map in .asoundrc
pcm.jack { type jack playback_ports { 0 alsa_pcm:playback_1 1 alsa_pcm:playback_2 } capture_ports { 0 alsa_pcm:capture_1 1 alsa_pcm:capture_2 } }
./alsa_period_count jack refine_soft 'jack' (begin) ACCESS: MMAP_INTERLEAVED MMAP_NONINTERLEAVED RW_INTERLEAVED RW_NONINTERLEAVED FORMAT: FLOAT_LE SUBFORMAT: ALL SAMPLE_BITS: ALL FRAME_BITS: ALL CHANNELS: 2 RATE: 44100 PERIOD_TIME: ALL PERIOD_SIZE: ALL PERIOD_BYTES: ALL PERIODS: ALL BUFFER_TIME: ALL BUFFER_SIZE: ALL BUFFER_BYTES: ALL TICK_TIME: ALL Rule 0 (0xea7f80): FORMAT= FLOAT_LE -> FLOAT_LE SAMPLE_BITS=[1 4294967295] Rule 1 (0xea7e70): SAMPLE_BITS=[1 4294967295] -> 32 FORMAT= FLOAT_LE SAMPLE_BITS=32 Rule 2 (0xea7df0): SAMPLE_BITS=32 -> 32 FRAME_BITS=[1 4294967295] CHANNELS=2 Rule 3 (0xea7d70): FRAME_BITS=[1 4294967295] -> 64 SAMPLE_BITS=32 CHANNELS=2 Rule 4 (0xea7cf0): FRAME_BITS=64 -> 64 PERIOD_BYTES=ALL PERIOD_SIZE=ALL Rule 5 (0xea7cf0): FRAME_BITS=64 -> 64 BUFFER_BYTES=[1 4294967295] BUFFER_SIZE=[1 4294967295] Rule 6 (0xea7df0): CHANNELS=2 -> 2 FRAME_BITS=64 SAMPLE_BITS=32 Rule 7 (0xea7cf0): RATE=44100 -> 44100 PERIOD_SIZE=ALL PERIOD_TIME=ALL Rule 8 (0xea7cf0): RATE=44100 -> 44100 BUFFER_SIZE=[1 4294967295] BUFFER_TIME=[1 4294967295] Rule 9 (0xea7df0): PERIODS=ALL -> (0 4294967295] BUFFER_SIZE=[1 4294967295] PERIOD_SIZE=ALL Rule 10 (0xea7df0): PERIOD_SIZE=ALL -> (0 4294967295] BUFFER_SIZE=[1 4294967295] PERIODS=(0 4294967295] Rule 11 (0xea7cf0): PERIOD_SIZE=(0 4294967295] -> (0 536870912) PERIOD_BYTES=ALL FRAME_BITS=64 Rule 12 (0xea7c70): PERIOD_SIZE=(0 536870912) -> (0 189408058) PERIOD_TIME=ALL RATE=44100 Rule 13 (0xea7d70): BUFFER_SIZE=[1 4294967295] -> [1 4294967294] PERIOD_SIZE=(0 189408058) PERIODS=(0 4294967295] Rule 14 (0xea7cf0): BUFFER_SIZE=[1 4294967294] -> [1 536870911] BUFFER_BYTES=[1 4294967295] FRAME_BITS=64 Rule 15 (0xea7c70): BUFFER_SIZE=[1 536870911] -> [1 189408057] BUFFER_TIME=[1 4294967295] RATE=44100 Rule 16 (0xea7c70): PERIOD_BYTES=ALL -> (0 1515264464) PERIOD_SIZE=(0 189408058) FRAME_BITS=64 Rule 17 (0xea7c70): BUFFER_BYTES=[1 4294967295] -> [8 1515264456] BUFFER_SIZE=[1 189408057] FRAME_BITS=64 Rule 18 (0xea7cf0): PERIOD_TIME=ALL -> (0 4294967295) PERIOD_SIZE=(0 189408058) RATE=44100 Rule 19 (0xea7cf0): BUFFER_TIME=[1 4294967295] -> (22 4294967279) BUFFER_SIZE=[1 189408057] RATE=44100 Rule 0 (0xea7f80): FORMAT= FLOAT_LE -> FLOAT_LE SAMPLE_BITS=32 Rule 2 (0xea7df0): SAMPLE_BITS=32 -> 32 FRAME_BITS=64 CHANNELS=2 Rule 4 (0xea7cf0): FRAME_BITS=64 -> 64 PERIOD_BYTES=(0 1515264464) PERIOD_SIZE=(0 189408058) Rule 5 (0xea7cf0): FRAME_BITS=64 -> 64 BUFFER_BYTES=[8 1515264456] BUFFER_SIZE=[1 189408057] Rule 7 (0xea7cf0): RATE=44100 -> 44100 PERIOD_SIZE=(0 189408058) PERIOD_TIME=(0 4294967295) Rule 8 (0xea7cf0): RATE=44100 -> 44100 BUFFER_SIZE=[1 189408057] BUFFER_TIME=(22 4294967279) Rule 9 (0xea7df0): PERIODS=(0 4294967295] -> (0 4294967295] BUFFER_SIZE=[1 189408057] PERIOD_SIZE=(0 189408058) Rule 10 (0xea7df0): PERIOD_SIZE=(0 189408058) -> (0 189408058) BUFFER_SIZE=[1 189408057] PERIODS=(0 4294967295] Rule 11 (0xea7cf0): PERIOD_SIZE=(0 189408058) -> (0 189408058) PERIOD_BYTES=(0 1515264464) FRAME_BITS=64 Rule 12 (0xea7c70): PERIOD_SIZE=(0 189408058) -> (0 189408058) PERIOD_TIME=(0 4294967295) RATE=44100 Rule 14 (0xea7cf0): BUFFER_SIZE=[1 189408057] -> [1 189408057] BUFFER_BYTES=[8 1515264456] FRAME_BITS=64 Rule 15 (0xea7c70): BUFFER_SIZE=[1 189408057] -> [1 189408057] BUFFER_TIME=(22 4294967279) RATE=44100 min periods 2 dir 0 max periods 64 dir 0 min_buffer_frames: 10240 set max buffer size: 10240 refine_soft 'jack' (begin) ACCESS: MMAP_INTERLEAVED FORMAT: FLOAT_LE SUBFORMAT: STD SAMPLE_BITS: 32 FRAME_BITS: 64 CHANNELS: 2 RATE: 44100 PERIOD_TIME: (23219 23220) PERIOD_SIZE: 1024 PERIOD_BYTES: 8192 PERIODS: 10 BUFFER_TIME: (232199 232200) BUFFER_SIZE: 10240 BUFFER_BYTES: 81920 TICK_TIME: ALL Rule 4 (0xea7cf0): FRAME_BITS=64 -> 64 PERIOD_BYTES=8192 PERIOD_SIZE=1024 Rule 7 (0xea7cf0): RATE=44100 -> 44100 PERIOD_SIZE=1024 PERIOD_TIME=(23219 23220) Rule 9 (0xea7df0): PERIODS=10 -> 10 BUFFER_SIZE=10240 PERIOD_SIZE=1024 Rule 10 (0xea7df0): PERIOD_SIZE=1024 -> 1024 BUFFER_SIZE=10240 PERIODS=10 Rule 13 (0xea7d70): BUFFER_SIZE=10240 -> 10240 PERIOD_SIZE=1024 PERIODS=10 Rule 16 (0xea7c70): PERIOD_BYTES=8192 -> 8192 PERIOD_SIZE=1024 FRAME_BITS=64 Rule 18 (0xea7cf0): PERIOD_TIME=(23219 23220) -> (23219 23220) PERIOD_SIZE=1024 RATE=44100 min_periods: 2, max_periods: 64, buffer_frames: 10240, period_frames: 1024, buf/per: 10.000000, periods: 10, periods_dir: 0 ALSA <-> JACK PCM I/O Plugin Its setup is: stream : PLAYBACK access : MMAP_INTERLEAVED format : FLOAT_LE subformat : STD channels : 2 rate : 44100 exact rate : 44100 (44100/1) msbits : 32 buffer_size : 10240 period_size : 1024 period_time : 23219 tstamp_mode : NONE period_step : 1 avail_min : 1024 period_event : 0 start_threshold : 1 stop_threshold : 10240 silence_threshold: 0 silence_size : 0 boundary : 1342177280
2011/11/17 Andrew Eikum aeikum@codeweavers.com:
On Wed, Nov 16, 2011 at 10:20:07PM +0100, Clemens Ladisch wrote:
Andrew Eikum wrote:
+++ b/include/pcm.h @@ -44,8 +44,20 @@ extern "C" {
/** PCM generic info container */ typedef struct _snd_pcm_info snd_pcm_info_t; -/** PCM hardware configuration space container */
+/** PCM hardware configuration space container
- snd_pcm_hw_params_t is an opaque structure which contains a set of possible
- PCM hardware configurations. For example, a given instance might include a
- range of buffer sizes, a range of period sizes, and a set of several sample
- formats. Some subset of all possible combinations these sets may be valid,
- but not necessarily any combination will be valid.
- No validation is done by the various snd_pcm_hw_params_set* functions.
These functions do validate the value that the application is trying to set and adjust all other dependent limits.
I didn't find that to be the case in my testing, at least between periods, period_size, and buffer_size. I've attached a test program here. It sets periods to 10, period_size to 1024, and buffer_size_max to be the same as the return from get_buffer_size_min (in my case, 80). The first call to fail is snd_pcm_hw_params(). If what you said is true, I would expect the set_buffer_size_max() call to fail.
$ gcc -I /usr/include/alsa -lasound -o alsa_period_count alsa_period_count.c $ ./alsa_period_count min_buffer_frames: 80 set max buffer size: 80 snd_pcm_hw_params: -12 $
Andrew
The logic of your program is wrong since your program did not set channel, rate and format
There are sound cards which support S16 and U8, mono and stereo.
As "default" device using "plug:dmix" , "pulse" or "hw"
The buffer and period calculation is only valid after you have choose the format and channels
http://www.alsa-project.org/alsa-doc/alsa-lib/pcm.html
Hardware related parameters The ALSA PCM devices use the parameter refining system for hardware parameters - snd_pcm_hw_params_t. It means, that application choose the full-range of configurations at first and then application sets single parameters until all parameters are elementary (definite).
Raymond Yau wrote:
The logic of your program is wrong since your program did not set channel, rate and format
It is allowed to not set some parameters; snd_pcm_hw_params() then chooses some random values for them.
The buffer and period calculation is only valid after you have choose the format and channels
This is wrong; parameters can be set in any order. (As long as format/channels are not yet set, the exact relationship between frames and bytes is not yet known, but this is handled by the parameters being intervals.)
Regards, Clemens
2011/11/17 Clemens Ladisch clemens@ladisch.de:
Raymond Yau wrote:
The logic of your program is wrong since your program did not set channel, rate and format
It is allowed to not set some parameters; snd_pcm_hw_params() then chooses some random values for them.
The buffer and period calculation is only valid after you have choose the format and channels
This is wrong; parameters can be set in any order. (As long as format/channels are not yet set, the exact relationship between frames and bytes is not yet known, but this is handled by the parameters being intervals.)
it return error at snd_pcm_hw_params_set_periods( 10,0)
after I reverted commit 6dab1a91cbbd40d2f52a0c5a1bd961a1db7bb319
pcm: recalculate all rules after changing hw_params flags
params->flags |= SND_PCM_HW_PARAMS_EXPORT_BUFFER; else params->flags &= ~SND_PCM_HW_PARAMS_EXPORT_BUFFER; - params->rmask = ~0; return snd_pcm_hw_refine(pcm, params); }
/alsa_period_count plug:dmix:1 min periods 0 max periods 8623621 ALSA ERROR hw_params: set (PERIODS) value = 10 : Invalid argument ACCESS: MMAP_INTERLEAVED MMAP_NONINTERLEAVED MMAP_COMPLEX RW_INTERLEAVED RW_NONINTERLEAVED FORMAT: S8 U8 S16_LE S16_BE U16_LE U16_BE S24_LE S24_BE U24_LE U24_BE S32_LE S32_BE U32_LE U32_BE FLOAT_LE FLOAT_BE FLOAT64_LE FLOAT64_BE MU_LAW A_LAW IMA_ADPCM S24_3LE S24_3BE U24_3LE U24_3BE S20_3LE S20_3BE U20_3LE U20_3BE S18_3LE S18_3BE U18_3LE U18_3BE SUBFORMAT: STD SAMPLE_BITS: [4 64] FRAME_BITS: [4 640000] CHANNELS: [1 10000] RATE: [4000 4294967295) PERIOD_TIME: (21333 21334) PERIOD_SIZE: (85 91628833) PERIOD_BYTES: (42 4294967295) PERIODS: (0 8623621) BUFFER_TIME: [1 4294967295] BUFFER_SIZE: [170 733007751] BUFFER_BYTES: [85 4294967295] TICK_TIME: ALL snd_pcm_hw_params_set_periods: -22
default prealloc of snd-hda-intel is 64Kbytes, 10 periods of 1024 frame for S32_LE and 2 channels is 80Kbytes
aplay -v --buffer-size=10240 --period-size=1024 -D"plug:'dmix:1'" any.wav Playing WAVE 'any.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo Plug PCM: Rate conversion PCM (48000, sformat=S32_LE) Converter: libspeex (builtin) Protocol version: 10002 Its setup is: stream : PLAYBACK access : RW_INTERLEAVED format : S16_LE subformat : STD channels : 2 rate : 44100 exact rate : 44100 (44100/1) msbits : 16 buffer_size : 7526 period_size : 940 period_time : 21333 tstamp_mode : NONE period_step : 1 avail_min : 940 period_event : 0 start_threshold : 7526 stop_threshold : 7526 silence_threshold: 0 silence_size : 0 boundary : 986447872 Slave: Direct Stream Mixing PCM Its setup is: stream : PLAYBACK access : MMAP_INTERLEAVED format : S32_LE subformat : STD channels : 2 rate : 48000 exact rate : 48000 (48000/1) msbits : 32 buffer_size : 8192 period_size : 1024 period_time : 21333 tstamp_mode : NONE period_step : 1 avail_min : 1024 period_event : 0 start_threshold : 8192 stop_threshold : 8192 silence_threshold: 0 silence_size : 0 boundary : 1073741824 Hardware PCM card 1 'HDA Intel' device 0 subdevice 0 Its setup is: stream : PLAYBACK access : MMAP_INTERLEAVED format : S32_LE subformat : STD channels : 2 rate : 48000 exact rate : 48000 (48000/1) msbits : 32 buffer_size : 8192 period_size : 1024 period_time : 21333 tstamp_mode : ENABLE period_step : 1 avail_min : 1024 period_event : 0 start_threshold : 1 stop_threshold : 1073741824 silence_threshold: 0 silence_size : 1073741824 boundary : 1073741824 appl_ptr : 0 hw_ptr : 0
participants (3)
-
Andrew Eikum
-
Clemens Ladisch
-
Raymond Yau