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

1 篇文章 0 订阅

最近在研究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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值