/* * hw_params.c - print hardware capabilities * * compile with: gcc -o hw_params hw_params.c -lasound */ #include #include #define ARRAY_SIZE(x) ( sizeof(x) / sizeof((x)[0]) ) 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:CARD=Intel,DEV=0"; snd_output_t *output = NULL; snd_pcm_t *pcm; snd_pcm_hw_params_t *hw_params; snd_pcm_uframes_t buffer_size; unsigned int buffer_time,bt; unsigned int i,j,k; int format,access; unsigned int min, max, btmin, btmax; int any_rate,rate,dir; int support_rates[16],no_of_rates; int support_format[32],no_of_formats; int support_channel[10],no_of_channels; int mode; int buffertimedir=0; int err; int noerr; if (argc > 1) device_name = argv[1]; if (argc > 2 ) { buffertimedir=atoi(argv[2]); if (buffertimedir<0) buffertimedir=-1; if (buffertimedir>0) buffertimedir=1; } snd_pcm_hw_params_alloca(&hw_params); for (mode=SND_PCM_STREAM_PLAYBACK; mode<=SND_PCM_STREAM_CAPTURE; mode++) { err = snd_pcm_open(&pcm, device_name, mode, SND_PCM_NONBLOCK ); if (err < 0) { continue; } err = snd_pcm_hw_params_any(pcm, hw_params); if (err < 0) { fprintf(stderr, "cannot get hardware parameters: %s\n", snd_strerror(err)); goto close; }; printf("Device: %s (type: %s) %s\n", device_name, snd_pcm_type_name(snd_pcm_type(pcm)) , mode == SND_PCM_STREAM_PLAYBACK ? "Playback" : "Capture"); printf("Formats:"); no_of_formats=0; for (format = SND_PCM_FORMAT_U8; format <= SND_PCM_FORMAT_LAST; format++) if ( snd_pcm_hw_params_test_format(pcm, hw_params, format)== 0) { printf(" %s", snd_pcm_format_name(format)); support_format[no_of_formats]=format; no_of_formats++; }; printf("\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)); goto close; } 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)); goto close; } no_of_channels=0; if (max <= 8 ) { printf("Channels:"); for (i = min; i <= max; ++i) if ( snd_pcm_hw_params_test_channels(pcm, hw_params, i) == 0 ) { printf(" %u", i); support_channel[no_of_channels]=i; no_of_channels++; } printf("\n"); } else { printf("channels : Min %d Max %d\n",min,max); support_channel[no_of_channels]=min; no_of_channels++; if ( max > min ) { support_channel[no_of_channels]=max; no_of_channels++; } }; if ( no_of_channels == 1 ) { err = snd_pcm_hw_params_set_channels(pcm, hw_params, support_channel[0]); } printf("Access types:"); for (access = SND_PCM_ACCESS_MMAP_INTERLEAVED; access <= SND_PCM_ACCESS_LAST; access++) { if ( snd_pcm_hw_params_test_access(pcm, hw_params, access) == 0) printf(" %s", snd_pcm_access_name(access)); } printf("\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)); goto close; } 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)); goto close; } printf("Sample rate : "); any_rate = 0; no_of_rates=0; for (i = 0; i < ARRAY_SIZE(rates); ++i) { rate=rates[i]; dir=0; if ( snd_pcm_hw_params_test_rate(pcm, hw_params, rate, dir) == 0 ) { support_rates[no_of_rates]=rate; no_of_rates++; } } if ( no_of_rates > 2 ) { for (i=0; i 1000 ) btmin = ((min / 1000 ) *1000); else btmin = min ; if ( max > 1000 ) btmax = ((max / 1000 ) *1000); else btmax = max ; printf("btmin %d btmax %d\n",btmin,btmax); for (bt=btmin; bt<=btmax; bt+=1000) { err = snd_pcm_hw_params_any(pcm, hw_params); if (err < 0) { fprintf(stderr, "cannot get hardware parameters: %s\n", snd_strerror(err)); noerr=0; continue; } err = snd_pcm_hw_params_set_channels(pcm, hw_params, support_channel[j]); if (err < 0) { fprintf(stderr, "cannot set channels: %s\n", snd_strerror(err)); noerr=0; continue; }; err = snd_pcm_hw_params_set_format(pcm, hw_params, support_format[k]); if (err < 0) { fprintf(stderr, "cannot set format: %s\n", snd_strerror(err)); noerr=0; continue; } rate=support_rates[i]; dir=0; err=snd_pcm_hw_params_set_rate_near(pcm,hw_params,&rate,&dir); if ( err < 0 ) { fprintf(stderr, "cannot set rate %d : %s\n", rate,snd_strerror(err)); noerr=0; continue; }; err = snd_pcm_hw_params_set_access(pcm, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); if (err < 0) { fprintf(stderr, "cannot set access: %s\n", snd_strerror(err)); noerr=0; continue; } buffer_time=bt; dir=buffertimedir; err = snd_pcm_hw_params_set_buffer_time_near(pcm,hw_params, &buffer_time, &dir); if (err < 0) { fprintf(stderr, "cannot set buffer time %d at rate %d format %s channel %d : %s\n", bt, rate, snd_pcm_format_name(support_format[k]), support_channel[j], snd_strerror(err)); noerr=0; continue; }; err = snd_pcm_hw_params_get_buffer_size(hw_params, &buffer_size); if (err < 0) { fprintf(stderr, "cannot get buffer size %s\n", snd_strerror(err)); noerr=0; continue; }; /* printf("rate %d set buffer time %d get %d - %d\n",rate,bt, buffer_time, buffer_size); */ err = snd_pcm_hw_params(pcm, hw_params); if (err < 0) { fprintf(stderr, "cannot set hw_params : %s\n", snd_strerror(err)); }; /* err = snd_pcm_hw_params_get_buffer_time(hw_params, &buffer_time,NULL); if ( err == 0 ) { err = snd_pcm_hw_params_get_buffer_size(hw_params, &buffer_size); if ( buffer_time != bt ) printf("set %d at rate %d but get %d - %d\n",bt,rate,buffer_time,buffer_size); }; */ }; }; }; }; /* err = snd_output_stdio_attach(&output, stdout, 0); if (err < 0) fprintf(stderr,"Output failed: %s\n", snd_strerror(err)); */ close: snd_pcm_close(pcm); }; }