Forwarded from Joshua Haberman.
--- Begin Message ---
Andy,
Let me know if you see anything I've missed that invalidates what I
wrote...
--------------------------------------------
I believe I have discovered a bug in either the behavior or the
documentation of the snd_pcm_hw_params_test_format() function. It is
documented to return 1 if the format is available, 0 otherwise. However,
I have discovered that it actually returns 0 if the format is available,
< 0 otherwise (ie. identical to snd_pcm_hw_params_set_format).
This test program seems to confirm my hypothesis.
---
#include <alsa/asoundlib.h>
#define NOFAIL == 0 || (assert(0), 1)
int main(int argc, char *argv[])
{
snd_pcm_t *pcm;
snd_pcm_hw_params_t *hw_params;
snd_output_t *debug;
snd_output_stdio_attach( &debug, stdout, 0 ) NOFAIL;
snd_pcm_hw_params_malloc( &hw_params ) NOFAIL;
snd_pcm_open( &pcm, argv[1], SND_PCM_STREAM_PLAYBACK, 0 ) NOFAIL;
snd_pcm_hw_params_any( pcm, hw_params ) NOFAIL;
snd_pcm_hw_params_dump( hw_params, debug );
/* according to the documentation, this function returns 1 if the
* format is available, 0 otherwise. However, the function
* seems to return 0 if the format is available, < 0 otherwise. */
#define TEST_FORMAT(format) \
if( snd_pcm_hw_params_test_format( pcm, hw_params, format ) < 0 ) \
printf( "- " #format "\n" ); \
else \
printf( "+ " #format "\n" );
/* test several formats against the output of the previous dump */
TEST_FORMAT(SND_PCM_FORMAT_FLOAT)
TEST_FORMAT(SND_PCM_FORMAT_S16)
TEST_FORMAT(SND_PCM_FORMAT_S24)
TEST_FORMAT(SND_PCM_FORMAT_S32)
TEST_FORMAT(SND_PCM_FORMAT_S8)
TEST_FORMAT(SND_PCM_FORMAT_U8)
return 0;
}
$ ./test_format hw:0
ACCESS: MMAP_INTERLEAVED RW_INTERLEAVED
FORMAT: U8 S16_LE
[...]
- SND_PCM_FORMAT_FLOAT
+ SND_PCM_FORMAT_S16
- SND_PCM_FORMAT_S24
- SND_PCM_FORMAT_S32
- SND_PCM_FORMAT_S8
+ SND_PCM_FORMAT_U8
$ ./test_format plughw:0
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
[...]
+ SND_PCM_FORMAT_FLOAT
+ SND_PCM_FORMAT_S16
+ SND_PCM_FORMAT_S24
+ SND_PCM_FORMAT_S32
+ SND_PCM_FORMAT_S8
I believe this could affect all the snd_pcm_hw_params_test_*() functions,
since they seem to all use the same internal interface.
Josh
--
Joshua Haberman <[EMAIL PROTECTED]>
--- End Message ---