A40i使用笔记:QT使用alsa采集音频pcm信息

news2024/11/26 22:49:10

一、前言

目的是实现一种效果,就是在音频识别时,能够实时显示当前人员说话的声音幅度,通过波形曲线的形式显示出来。如下效果(非我实现)

还可以实现在实时采集的同时,将需要的数据保存成指定格式文件,如csv,wav,pcm等。 

目前函数大部分时存储为pcm格式,如需转成其他格式需要使用不同的库函数或者按照协议格式重写

二、环境

全志A40i

linux3.10

alsa

三、正文

从硬件上首先要具备Audio音频部分,这里硬件支持的话具备硬件电路接口就不同多说什么了,其次就主要是软件层次了

首先要在linux上使用音频采集,就要使用标注你的alsa库,交叉安装alsa库的方式也有很多

有的平台环境上和硬件上都默认是已经包含的了,可以通过find -name libasound.so查看

这里我是用的是qt交叉编译程序,一开始总是没有找到libasound库,后来把lib去掉才能正常识别

在pro文件中加入

LIBS +=   -L/root/workspace/allwinner/A40i/bsp/lichee/out/sun8iw11p1/linux/common/buildroot/host/usr/arm-buildroot-linux-gnueabihf/sysroot/usr/lib/ -lasound

头文件中加入

#include <alsa/asoundlib.h>

至此,我终于能够在我的编译环境中正常不报错的编译程序了,但是才刚刚入坑,后面的问题一把又一把的出现,每次都是以为解决当前的问题后面就都不是问题了,结果,,,哎,都是泪

我是用的源码如下:

void menu::on_btn_Ingames_2_clicked()
{



    snd_pcm_t *handle;//PCM句柄
    snd_pcm_hw_params_t *params;//配置硬件参数结构体(PCM硬件配置空间容器)

//    snd_pcm_close(handle);
    int ret = snd_pcm_open(&handle,"hw:/dev/snd/controlC0",SND_PCM_STREAM_CAPTURE,0);//SND_PCM_STREAM_PLAYBACK 或 SND_PCM_STREAM_CAPTURE,分别表示播放和录音的PCM流
    if(ret < 0){
        fprintf(stderr,"unable to open pcm device: %s\n",snd_strerror(ret));
        exit(1);
    }
    else{
        qDebug()<<QString("open pcm device:%1").arg(snd_strerror(ret));
    }
    //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);//SND_PCM_ACCESS_RW_INTERLEAVED//SND_PCM_ACCESS_RW_NONINTERLEAVED
    //设置16位采样格式
   snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_LE);
   //设置声道数1
   ret = snd_pcm_hw_params_set_channels(handle,params,1);
   if(ret <0){
       fprintf(stderr,"Error setting channels.\n");
       exit(1);
   }
   else
      qDebug()<<"set channels ok";


   int dir=0;
   int rate = 44100; /* Sample rate */
   unsigned int exact_rate;   /* Sample rate returned by */
   //设置采样率44100,如果采样率不支持,会用硬件支持最接近的采样率
   exact_rate=rate;
   ret = snd_pcm_hw_params_set_rate_near(handle,params,&exact_rate,0);
  if(ret <0){
      fprintf(stderr,"Error setting rate.\n");
      exit(1);
  }
  else
     qDebug()<<"set rate ok";
  if (rate != exact_rate) {
    fprintf(stderr, "The rate %d Hz is not supported by your hardware.\n Using %d Hz instead.\n", rate, exact_rate);
  }
  else
      qDebug()<<"best rate is "<<QString::number(exact_rate);



//    int periods = 2; //2      /* Number of periods */
//    /* Set number of periods. Periods used to be called fragments. */
//   ret = snd_pcm_hw_params_set_periods(handle,params,periods,0);
//   if(ret <0){
//       fprintf(stderr,"Error setting periods.\n");
//       exit(1);
//   }
//   else
//      qDebug()<<"set periods ok ,periods is "<<QString::number(periods);


   long unsigned int frames = 128;//32
//    //设置周期大小(将配置空间限制为最接近目标的周期大小)
//   snd_pcm_hw_params_set_period_size_near(handle,params,&frames,0);//0
//   qDebug()<<"frames near "<<QString::number(frames);


//   snd_pcm_uframes_t periodsize = 4096;
//   if (snd_pcm_hw_params_set_buffer_size(handle, params, (periodsize * periods)>>2) < 0) {
//         fprintf(stderr, "Error setting buffersize.\n");
//         exit(1);
//       }
//   else
//       qDebug()<<"set buffersize ok";

//让这些参数作用于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);
   }
   else
       qDebug()<<"set hw params ok";


   //
//long unsigned int frames = 0;//32
 //从配置空间中提取周期大小。
   snd_pcm_hw_params_get_period_size(params,&frames,0);
   int size = frames *4;
   qDebug()<<"frames is "<<QString::number(frames)<<",size is "<<QString::number(size);

   char* pcmBuff = (char*)malloc(size);
//从配置空间中提取周期时间
   unsigned int val =0;
   snd_pcm_hw_params_get_period_time(params,&val,0);
   qDebug()<<"val is "<<QString::number(val);
//打开输出文件
   FILE* pFile;
   pFile = fopen("test.pcm","wb");

  int index=0;
   while(index<10)
   {
        //从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));
           exit(1);
       }
       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");


   ui->label_44->setText(QString::number(qrand()%100));





}

各位看官先不要着急ctrl+c,这里源码未经过最终调试,因为我在第一步snd_pcm_open就卡住了,哭晕。

第一步解决了第二部又出现问题,真是一步一个坎啊,总共需要配置10多个函数,每个函数都要搞明白具体含义是什么,才能具体调试,上述代码是暂时能够简单录制声音,并生成pcm文件,通过audacity-win-2.2.2.exe软件可以播放录制的pcm声音。

程序执行打印信息

pcm文件解析播放声音

 

 

接下来就是详细梳理分析每个使用到的函数功能作用,并加上注释去消化理解,不知不觉凌晨2点了,下面(等哟时间的)功能还差将读取的数据解析细化出来每个帧含义,将数据分类显示成曲线和生成其他格式文件。

四、结语

有时候项目没有调完就写上博客了,为什么呢,所以这个文章的内容主要时干嘛的呢

第一:记录前期环境准备和铺路方式,后续在走就能少走点弯路

第二:立下此flag,以后要解决,以后解决更新此文

第三:把我的问题发布出来,如果有同道中人遇到此问题或有解决方式,可以互相探讨解决。

第四:分享给可能进度还没有到达我这一步的新人们,互相沟通互相交流i互相学习

未完待续

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/423794.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

状态设计模式(State Pattern)[论点:概念、相关角色、图示、示例代码、框架中的运用、适用场景]

文章目录概念组成角色相关图示代码示例框架中的应用适用场景概念 状态模式&#xff08;State Pattern&#xff09;是一种行为型设计模式&#xff0c;用于解决对象在不同状态下的行为问题。它允许一个对象在其内部状态改变时改变它的行为。状态模式主要包含三个部分&#xff1a;…

Day924.自动化测试 -系统重构实战

自动化测试 Hi&#xff0c;我是阿昌&#xff0c;今天学习记录的是关于自动化测试的内容。 自动化测试是一个很容易产生“争议”的话题&#xff0c;也经常会有一些很有意思的问题。 自动化测试不是应该由测试同学来编写吗&#xff0c;开发是不是没有必要学吧&#xff1f;之前…

圆角升级啦,来手把手一起实现自定义ViewGroup的各种圆角与背景

作者&#xff1a;newki 定制圆角与背景的自定义ViewGroup实现 前言 目前线上的一些第三方圆角容器大部分都只支持四周固定圆角&#xff0c;我们一些使用场景只需要顶部圆角&#xff0c;或者底部圆角&#xff0c;或者一个角圆角。 &#xff08;话说为什么我们的UI这么喜欢各种…

webpack plugin源码解析(四) HashedModuleIdsPlugin

文章目录作用涉及 webpack API获取chunkGraph获取当前编译过程中被使用过的 module id&#xff1a;compilation.usedModuleIds获取当前编译过程中所有的模块对象&#xff1a;compilation.modules判断 module 是否需要生成 id&#xff1a;module.needId获取指定module 的 module…

新品首发丨计讯物联智慧灯杆TG473-A6-5“滴水不进”,严苛环境下稳定运行无压力

近年来&#xff0c;智慧灯杆产业快速发展&#xff0c;已广泛应用于智慧城市、智慧交通、智慧园区、智慧停车等细分场景&#xff0c;提质增效、节本降耗的作用突显。值得注意的是&#xff0c;不同的场景有着不同的环境条件&#xff0c;如高低温、潮湿、沙尘等&#xff0c;对智慧…

Nginx学习(9)—— 负载均衡模块

文章目录Nginx负载均衡模块负载均衡配置指令钩子初始化配置初始化请求peer.get和peer.free回调函数小结Nginx负载均衡模块 负载均衡模块用于从”upstream”指令定义的后端主机列表中选取一台主机。nginx先使用负载均衡模块找到一台主机&#xff0c;再使用upstream模块实现与这…

应急响应 - Windows进程分析,Windows网络分析,tasklist,wmic process

「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》 进程网络排查一、Tasklist1、tasklist /v1、tasklist /svc2、tasklist /m二、wmic proces…

JAVAWeb02-CSS

1. CSS CSS 指的是层叠样式表 (Cascading Style Sheets) 1.1 概述 1.1.1 官方文档 地址: https://www.w3school.com.cn/css/index.asp 1.1.2 为什么需要 CSS 在没有 CSS 之前&#xff0c;我们想要修改 HTML 元素的样式需要为每个 HTML 元素单独定义样式属性&#xff0c;费心…

nodegui搭建/你好/打包

0、github连接问题 警告&#xff1a;如果你的网络有任何有任何有任何有任何有任何有任何有任何有任何有任何有任何连接 github 的问题&#xff0c;彻底放弃该框架 请转到其他框架 electron-egg教程、electron-egg官网&#xff0c;或其他electron项目 Tauri教程、Tauri官网 NW.…

Smartbi电子表格软件架构与差异化特色

选择和Excel结合Smartbi电子表格软件选择与Excel结合的原因在于&#xff0c;Excel一直被模仿&#xff0c;从未被超越。虽然市场上的报表软件很多&#xff0c;但存在太多的不完美。国外的产品功能复杂、难于学习&#xff08;控件方式&#xff09;&#xff0c;做不了中国式复杂格…

SpringBoot使用Redis实现分布式缓存

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

Matlab群体智能优化算法之巨型睡莲优化算法(VAO)

Matlab群体智能优化算法之巨型睡莲优化算法(VAO) 摘要&#xff1a;介绍一种新型智能优化算法&#xff0c;巨型睡莲优化算法。其应用于24个基准测试函数&#xff0c;并与其他10个著名算法进行了比较。提出的算法在10个优化问题上进行了测试&#xff1a;最小生成树、枢纽位置分配…

技术复盘(4)--docker

技术复盘--docker资料地址环境初始docker安装dockerdocker常用命令-都需要先启动dockerdocker容器打包为镜像docker坑docker卸载docker数据卷dockerFile构建过程搭建私有仓库--非图形化界面搭建私有仓库--图形化界面docker理论知识资料地址 docker官网&#xff1a;https://www…

一种供水系统物联网监测系统

1.1供水系统 1.1.1监测范围选择依据 &#xff08;1&#xff09;管网老化区域管网 管网建设年代久远&#xff0c;通常管网发生破损问题较大&#xff0c;根据管网本身属性和历史发生事件的统计分析&#xff0c;结合数理统计&#xff0c;优先选择管网老化区域的管段所在区域进行…

基于imx8m plus开发板全体系开发教程4:Linux系统开发

前言&#xff1a; i.MX8M Plus 开发板是一款拥有 4 个 Cortex-A53 核心&#xff0c;运行频率 1.8GHz;1 个 Cortex-M7 核心&#xff0c;运行频率 800MHz;此外还集成了一个 2.3 TOPS 的 NPU&#xff0c;大大加速机器学习推理。 全文所使用的开发平台均为与NXP官方合作的FS-IMX8…

深入浅出Kafka

这个主题 武哥漫谈IT &#xff0c;作者骆俊武 讲得更好 一、什么是Kafka&#xff1f; 首先我们得去官网看看是怎么介绍Kafka的&#xff1a; https://kafka.apache.org/intro Apache Kafka is an open-source distributed event streaming platform. 翻译成中文就是&#xff1…

Git分布式版本控制软件

1.什么是git git是分布式版本控制软件。 软件&#xff1a;git是从别的地方下载下来安装到我们电脑上的软件。 版本控制&#xff1a;跟毕业论文一样&#xff0c;先写好版本1然后交给导师&#xff0c;导师说不行&#xff0c;然后再改为版本2&#xff0c;然后循环下去&#xff0…

Su+ELK实现网络监测(2)——ELK安装与配置

ELK安装配置文档一、环境准备基础配置二、Jdk1.8环境部署1、安装jdk2、编辑环境变量三、ElasticSearch部署1、安装2、修改文件所有者3、修改配置文件4、启动四、elasticsearch-head部署&#xff08;可不安装&#xff0c;跳过&#xff09;1、nodejs安装2、head插件安装3、修改he…

智慧工厂可视化合集,推动行业数字化转型

图扑软件基于 HTML5&#xff08;Canvas/WebGL/WebVR&#xff09;标准的 Web 技术&#xff0c;满足了工业物联网跨平台云端化部署实施的需求&#xff0c;以低代码的形式自由构建三维数字孪生、大屏可视化、工业组态等等。从 SDK 组件库&#xff0c;到 2D 和 3D 编辑&#xff0c;…

软化水处理知识总结

软化水除了广泛应用在饮用、浴室、厨房、洗衣等生活用水&#xff0c;和酒店、学校、写字楼、公寓、餐饮等商业用水的处理&#xff0c;还可用于锅炉、交换器、蒸发冷凝器、空调、直燃机等系统的补给水的软化。 那什么是软化水&#xff0c;和除盐水、纯水有什么区别&#xff1f;…