Linux Alsa库,遍历播放、录音设备信息,aplay、arecord扒源码(暂未注释)

it2025-02-05  12

最近在研究Linux的alsa录音、播放相关知识,调用libasound的第一步,都是要获取相关设备的句柄,但是光看官方文档,实在是云里雾里,只要先从alsa的命令工具入手

alsa的命令 aplay -l 和 arecord -l,可以遍历PC的所有录音设备和播放设备

然后扒了一下这个命令的源码,在alsa-util的aplay.c文件里,然后重新整理了一下,去除了一些不需要的#define宏和全局变量

得到如下代码

附带上libasound.so依赖库,就能直接运行获得设备列表

#include <sys/poll.h> #include <sys/uio.h> #include <sys/time.h> #include <sys/stat.h> #include <sys/types.h> #include <fcntl.h> #include <alsa/asoundlib.h> #include <iostream> #include <unistd.h> static void device_list(void) { //一个是播放设备,一个是采集设备 snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK //SND_PCM_STREAM_CAPTURE; snd_ctl_t *handle; int card, err, dev, idx; snd_ctl_card_info_t *info; snd_pcm_info_t *pcminfo; snd_ctl_card_info_alloca(&info); snd_pcm_info_alloca(&pcminfo); card = -1; if (snd_card_next(&card) < 0 || card < 0) { printf("no soundcards found...\n"); return; } printf("**** List of %s Hardware Devices ****\n", snd_pcm_stream_name(stream)); while (card >= 0) { char name[32]; sprintf(name, "hw:%d", card); if ((err = snd_ctl_open(&handle, name, 0)) < 0) { printf("control open (%i): %s\n", card, snd_strerror(err)); goto next_card; } if ((err = snd_ctl_card_info(handle, info)) < 0) { printf("control hardware info (%i): %s\n", card, snd_strerror(err)); snd_ctl_close(handle); goto next_card; } dev = -1; while (1) { unsigned int count; if (snd_ctl_pcm_next_device(handle, &dev) < 0) printf("snd_ctl_pcm_next_device\n"); if (dev < 0) break; snd_pcm_info_set_device(pcminfo, dev); snd_pcm_info_set_subdevice(pcminfo, 0); snd_pcm_info_set_stream(pcminfo, stream); if ((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) { if (err != -ENOENT) printf("control digital audio info (%i): %s\n", card, snd_strerror(err)); continue; } printf("card %i: %s [%s], device %i: %s [%s]\n", card, snd_ctl_card_info_get_id(info), snd_ctl_card_info_get_name(info), dev, snd_pcm_info_get_id(pcminfo), snd_pcm_info_get_name(pcminfo)); count = snd_pcm_info_get_subdevices_count(pcminfo); printf(" Subdevices: %i/%i\n", snd_pcm_info_get_subdevices_avail(pcminfo), count); for (idx = 0; idx < (int)count; idx++) { snd_pcm_info_set_subdevice(pcminfo, idx); if ((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) { printf("control digital audio playback info (%i): %s\n", card, snd_strerror(err)); } else { printf(" Subdevice #%i: %s\n", idx, snd_pcm_info_get_subdevice_name(pcminfo)); } } } snd_ctl_close(handle); next_card: if (snd_card_next(&card) < 0) { printf("snd_card_next\n"); break; } } } int main() { device_list(); return 0; }

 

最新回复(0)