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

Reply via email to