Linux ALSA音频采集PCM

采集流程:
1.打开PCM(snd_pcm_open)
2.配置PCM硬件配置空间容器(设置采样格式、采样率、声道、周期等等)
3.读取音频数据

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

int main()
{
    snd_pcm_t *handle;//PCM句柄

    //打开一个PCM(PCM捕获)
    int ret = snd_pcm_open(&handle,"hw:1",SND_PCM_STREAM_CAPTURE,0);
    if(ret < 0){
        fprintf(stderr,"unable to open pcm device: %s\n",snd_strerror(ret));
        exit(1);
    }

    //配置硬件参数结构体(PCM硬件配置空间容器)
    snd_pcm_hw_params_t *params;
    //params申请内存(使用标准alloca分配无效的snd_pcm_hw_参数)
    snd_pcm_hw_params_alloca(&params);
    //使用pcm设备初始化hwparams(用PCM的完整配置空间填充参数)
    snd_pcm_hw_params_any(handle,params);
    //设置多路数据在buffer中的存储方式
    //SND_PCM_ACCESS_RW_INTERLEAVED每个周期(period)左右声道的数据交叉存放
    snd_pcm_hw_params_set_access(handle,params,SND_PCM_ACCESS_RW_INTERLEAVED);
    //设置16位采样格式
    snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_LE);
    //设置声道数2
    snd_pcm_hw_params_set_channels(handle,params,2);

    int dir = 0;
    unsigned int sampleRate = 44100;
    //设置采样率44100,如果采样率不支持,会用硬件支持最接近的采样率
    snd_pcm_hw_params_set_rate_near(handle,params,&sampleRate,&dir);

    snd_pcm_uframes_t frames = 32;
    //设置周期大小(将配置空间限制为最接近目标的周期大小)
    snd_pcm_hw_params_set_period_size_near(handle,params,&frames,&dir);

    //让这些参数作用于PCM设备(安装从配置空间和SND_PCM_PREPARE选自配置空间的PCM硬件配置)
    ret = snd_pcm_hw_params(handle,params);
    if(ret <0){
        fprintf(stderr,"unable toset hw params: %s\n",snd_strerror(ret));
        exit(1);
    }
    //从配置空间中提取周期大小。
    snd_pcm_hw_params_get_period_size(params,&frames,&dir);
    int size = frames *4;

    char* pcmBuff = (char*)malloc(size);

    //从配置空间中提取周期时间
    unsigned int val =0;
    snd_pcm_hw_params_get_period_time(params,&val,&dir);


    //打开输出文件
    FILE* pFile;
    pFile = fopen("test.pcm","wb");

    int index=0;
    while(1)
    {
        //从PCM读取交错帧
        ret = snd_pcm_readi(handle,pcmBuff,frames);
        if(ret == -EPIPE){//发生暂停事件(Stream被暂停并等待应用程序恢复)
            fprintf(stderr,"overrun.... \n");
            snd_pcm_prepare(handle);
        }
        else if(ret < 0){
            fprintf(stderr,"error read: %s\n",snd_strerror(ret));
        }
        else if(ret != frames ){
            fprintf(stderr,"less read: %s\n",ret);
        }
        ret = fwrite(pcmBuff,sizeof(char),size,pFile);
        if(ret != size){
            fprintf(stderr,"less write: %s\n",ret);
        }
        printf("%d\n",index);
        index++;
    }

    snd_pcm_drain(handle);
    snd_pcm_close(handle);

    free(pcmBuff);
    fclose(pFile);


    printf("audio capture exit.. \n");

    return 0;

}

注意事项:
1.camke需要引入动态链接库

target_link_libraries(文件名
    "/usr/lib/libasound.so"
)

2. hw:1表示的card1

snd_pcm_open(&handle,"hw:1",SND_PCM_STREAM_CAPTURE,0);

在这里插入图片描述

3.使用ffplay播放pcm(注意ffplay会一直播放,读到文件末尾也不会停)

ffplay -ar 44100 -channels 2 -f s16le -i test.pcm
  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奋斗吧!骚年!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值