Matt Garman wrote:
> Is there a way to query alsa to see what sample rates and formats
> the sound hardware natively supports?

Try the attached program.


HTH
Clemens
/*
 * hw_params.c - print hardware capabilities
 *
 * compile with: gcc -o hw_params hw_params.c -lasound
 */

#include <stdio.h>
#include <alsa/asoundlib.h>

#define ARRAY_SIZE(a) (sizeof(a) / sizeof *(a))

static const snd_pcm_access_t accesses[] = {
        SND_PCM_ACCESS_MMAP_INTERLEAVED,
        SND_PCM_ACCESS_MMAP_NONINTERLEAVED,
        SND_PCM_ACCESS_MMAP_COMPLEX,
        SND_PCM_ACCESS_RW_INTERLEAVED,
        SND_PCM_ACCESS_RW_NONINTERLEAVED,
};

static const snd_pcm_format_t formats[] = {
        SND_PCM_FORMAT_S8,
        SND_PCM_FORMAT_U8,
        SND_PCM_FORMAT_S16_LE,
        SND_PCM_FORMAT_S16_BE,
        SND_PCM_FORMAT_U16_LE,
        SND_PCM_FORMAT_U16_BE,
        SND_PCM_FORMAT_S24_LE,
        SND_PCM_FORMAT_S24_BE,
        SND_PCM_FORMAT_U24_LE,
        SND_PCM_FORMAT_U24_BE,
        SND_PCM_FORMAT_S32_LE,
        SND_PCM_FORMAT_S32_BE,
        SND_PCM_FORMAT_U32_LE,
        SND_PCM_FORMAT_U32_BE,
        SND_PCM_FORMAT_FLOAT_LE,
        SND_PCM_FORMAT_FLOAT_BE,
        SND_PCM_FORMAT_FLOAT64_LE,
        SND_PCM_FORMAT_FLOAT64_BE,
        SND_PCM_FORMAT_IEC958_SUBFRAME_LE,
        SND_PCM_FORMAT_IEC958_SUBFRAME_BE,
        SND_PCM_FORMAT_MU_LAW,
        SND_PCM_FORMAT_A_LAW,
        SND_PCM_FORMAT_IMA_ADPCM,
        SND_PCM_FORMAT_MPEG,
        SND_PCM_FORMAT_GSM,
        SND_PCM_FORMAT_SPECIAL,
        SND_PCM_FORMAT_S24_3LE,
        SND_PCM_FORMAT_S24_3BE,
        SND_PCM_FORMAT_U24_3LE,
        SND_PCM_FORMAT_U24_3BE,
        SND_PCM_FORMAT_S20_3LE,
        SND_PCM_FORMAT_S20_3BE,
        SND_PCM_FORMAT_U20_3LE,
        SND_PCM_FORMAT_U20_3BE,
        SND_PCM_FORMAT_S18_3LE,
        SND_PCM_FORMAT_S18_3BE,
        SND_PCM_FORMAT_U18_3LE,
        SND_PCM_FORMAT_U18_3BE,
};

static const unsigned int rates[] = {
        5512,
        8000,
        11025,
        16000,
        22050,
        32000,
        44100,
        48000,
        64000,
        88200,
        96000,
        176400,
        192000,
};

int main(int argc, char *argv[])
{
        const char *device_name = "hw";
        snd_pcm_t *pcm;
        snd_pcm_hw_params_t *hw_params;
        unsigned int i;
        unsigned int min, max;
        int any_rate;
        int err;

        if (argc > 1)
                device_name = argv[1];

        err = snd_pcm_open(&pcm, device_name, SND_PCM_STREAM_PLAYBACK, 
SND_PCM_NONBLOCK);
        if (err < 0) {
                fprintf(stderr, "cannot open device '%s': %s\n", device_name, 
snd_strerror(err));
                return 1;
        }

        snd_pcm_hw_params_alloca(&hw_params);
        err = snd_pcm_hw_params_any(pcm, hw_params);
        if (err < 0) {
                fprintf(stderr, "cannot get hardware parameters: %s\n", 
snd_strerror(err));
                snd_pcm_close(pcm);
                return 1;
        }

        printf("Device: %s (type: %s)\n", device_name, 
snd_pcm_type_name(snd_pcm_type(pcm)));

        printf("Access types:");
        for (i = 0; i < ARRAY_SIZE(accesses); ++i) {
                if (!snd_pcm_hw_params_test_access(pcm, hw_params, accesses[i]))
                        printf(" %s", snd_pcm_access_name(accesses[i]));
        }
        putchar('\n');

        printf("Formats:");
        for (i = 0; i < ARRAY_SIZE(formats); ++i) {
                if (!snd_pcm_hw_params_test_format(pcm, hw_params, formats[i]))
                        printf(" %s", snd_pcm_format_name(formats[i]));
        }
        putchar('\n');

        err = snd_pcm_hw_params_get_channels_min(hw_params, &min);
        if (err < 0) {
                fprintf(stderr, "cannot get minimum channels count: %s\n", 
snd_strerror(err));
                snd_pcm_close(pcm);
                return 1;
        }
        err = snd_pcm_hw_params_get_channels_max(hw_params, &max);
        if (err < 0) {
                fprintf(stderr, "cannot get maximum channels count: %s\n", 
snd_strerror(err));
                snd_pcm_close(pcm);
                return 1;
        }
        printf("Channels:");
        for (i = min; i <= max; ++i) {
                if (!snd_pcm_hw_params_test_channels(pcm, hw_params, i))
                        printf(" %u", i);
        }
        putchar('\n');

        err = snd_pcm_hw_params_get_rate_min(hw_params, &min, NULL);
        if (err < 0) {
                fprintf(stderr, "cannot get minimum rate: %s\n", 
snd_strerror(err));
                snd_pcm_close(pcm);
                return 1;
        }
        err = snd_pcm_hw_params_get_rate_max(hw_params, &max, NULL);
        if (err < 0) {
                fprintf(stderr, "cannot get maximum rate: %s\n", 
snd_strerror(err));
                snd_pcm_close(pcm);
                return 1;
        }
        printf("Sample rates:");
        if (min == max)
                printf(" %u", min);
        else if (!snd_pcm_hw_params_test_rate(pcm, hw_params, min + 1, 0))
                printf(" %u-%u", min, max);
        else {
                any_rate = 0;
                for (i = 0; i < ARRAY_SIZE(rates); ++i) {
                        if (!snd_pcm_hw_params_test_rate(pcm, hw_params, 
rates[i], 0)) {
                                any_rate = 1;
                                printf(" %u", rates[i]);
                        }
                }
                if (!any_rate)
                        printf(" %u-%u", min, max);
        }
        putchar('\n');

        err = snd_pcm_hw_params_get_period_time_min(hw_params, &min, NULL);
        if (err < 0) {
                fprintf(stderr, "cannot get minimum period time: %s\n", 
snd_strerror(err));
                snd_pcm_close(pcm);
                return 1;
        }
        err = snd_pcm_hw_params_get_period_time_max(hw_params, &max, NULL);
        if (err < 0) {
                fprintf(stderr, "cannot get maximum period time: %s\n", 
snd_strerror(err));
                snd_pcm_close(pcm);
                return 1;
        }
        printf("Interrupt interval: %u-%u us\n", min, max);

        err = snd_pcm_hw_params_get_buffer_time_min(hw_params, &min, NULL);
        if (err < 0) {
                fprintf(stderr, "cannot get minimum buffer time: %s\n", 
snd_strerror(err));
                snd_pcm_close(pcm);
                return 1;
        }
        err = snd_pcm_hw_params_get_buffer_time_max(hw_params, &max, NULL);
        if (err < 0) {
                fprintf(stderr, "cannot get maximum buffer time: %s\n", 
snd_strerror(err));
                snd_pcm_close(pcm);
                return 1;
        }
        printf("Buffer size: %u-%u us\n", min, max);

        snd_pcm_close(pcm);
        return 0;
}
------------------------------------------------------------------------------
Stay on top of everything new and different, both inside and 
around Java (TM) technology - register by April 22, and save
$200 on the JavaOne (SM) conference, June 2-5, 2009, San Francisco.
300 plus technical and hands-on sessions. Register today. 
Use priority code J9JMT32. http://p.sf.net/sfu/p
_______________________________________________
Alsa-user mailing list
Alsa-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/alsa-user

Reply via email to