Last active
September 26, 2016 13:22
-
-
Save vthanki/7183349e6e62f2f136debfef1e2b47d1 to your computer and use it in GitHub Desktop.
Handy utility to find out supported sample rates from a sound card. Taken from: http://www.spinics.net/linux/fedora/alsa-user/msg07230.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment