linux环境用usb麦克风阵列ALSA音频设备录音
编译:
gcc read_microphone.c -o read_microphone -lasound
生成read_microphone可执行文件,运行:
./read_microphone
注意:此处采用6麦麦克风阵列
音频设备名,可以使用audacity软件查看,hw:1,0
或使用aplay -l 查看
//https://blog.csdn.net/maowendi/article/details/82348690
// gcc read_microphone.c -o read_microphone -lasound/*
read from the default PCM device and writes to standard output for 5 seconds of data
修改声音采集配置时候,除了修改声音通道数量,还应该考虑申请的缓冲区时候足够大
*/#define ALSA_PCM_NEW_HW_PARAMS_API#include </usr/include/alsa/asoundlib.h>int main()
{long loops; //一个长整型变量, int rc; //一个int变量 ,用来存放 snd_pcm_open(访问硬件)的返回值 int size; //一个int变量 snd_pcm_t * handle; // 一个指向snd_pcm_t的指针 snd_pcm_hw_params_t * params; // 一个指向 snd_pcm_hw_params_t的指针 unsigned int val; // 无符号整型变量 ,用来存放录音时候的采样率 int dir; // 整型变量 snd_pcm_uframes_t frames; // snd_pcm_uframes_t 型变量 char * buffer; // 一个字符型指针 FILE * out_fd; // 一个指向文件的指针 out_fd = fopen("out_pcm.raw","wb+"); /* 将流与文件之间的关系建立起来,文件名为 out_pcm.raw,w是以文本方式打开文件,wb是二进制方式打开文件wb+ 读写打开或建立一个二进制文件,允许读和写。*/ /* open PCM device for recording (capture). */// 访问硬件,并判断硬件是否访问成功 // hw:直接访问硬件 plughw:经过采样率和格式转换插件//rc = snd_pcm_open(&handle, "default",SND_PCM_STREAM_CAPTURE, 0);//rc = snd_pcm_open(&handle, "hw:1,0",SND_PCM_STREAM_CAPTURE,0);rc = snd_pcm_open(&handle, "plughw:1,0",SND_PCM_STREAM_CAPTURE,0);//printf("%d",rc);if( rc < 0 ){fprintf(stderr,"unable to open pcm device: %s\n",snd_strerror(rc));exit(1);}/* allocate a hardware parameters object */// 分配一个硬件变量对象 snd_pcm_hw_params_alloca(¶ms);/* fill it with default values. */// 按照默认设置对硬件对象进行设置 snd_pcm_hw_params_any(handle,params);/* set the desired hardware parameters *//* interleaved mode 设置数据为交叉模式*/snd_pcm_hw_params_set_access(handle,params,SND_PCM_ACCESS_RW_INTERLEAVED);/* signed 16-bit little-endian format */// 设置数据编码格式为PCM、有符号、16bit、LE格式 snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_LE);/* two channels(stereo) */// 设置单声道/多声道snd_pcm_hw_params_set_channels(handle,params,8);/* sampling rate */// 设置采样率 val = 44100;snd_pcm_hw_params_set_rate_near(handle,params,&val,&dir);/* set period size */// 周期长度(帧数) frames = 32;snd_pcm_hw_params_set_period_size_near(handle,params,&frames,&dir);/* write parameters to the driver */// 将配置写入驱动程序中// 判断是否已经配置正确 rc = snd_pcm_hw_params(handle,params);if ( rc < 0 ){fprintf(stderr,"unable to set hw parameters: %s\n",snd_strerror(rc));exit(1);}/* use a buffer large enough to hold one period */// 配置一个缓冲区用来缓冲数据,缓冲区要足够大,此处看意思应该是只配置了// 够两个声道用的缓冲内存 snd_pcm_hw_params_get_period_size(params,&frames,&dir);size = frames * 16; // 2 bytes/sample, 2channels buffer = ( char * ) malloc(size);/* loop for 5 seconds */// 记录五秒长的声音 snd_pcm_hw_params_get_period_time(params, &val, &dir);loops = 5000000 / val;while( loops > 0 ){loops--;rc = snd_pcm_readi(handle,buffer,frames); //从声卡读取声音数据printf("%d\n",rc);if ( rc == -EPIPE ){/* EPIPE means overrun */fprintf(stderr,"overrun occured\n");snd_pcm_prepare(handle);}else if ( rc < 0 ){fprintf(stderr,"error from read: %s\n",snd_strerror(rc));}else if ( rc != (int)frames){fprintf(stderr,"short read, read %d frames\n",rc);}// 将音频数据写入文件 rc = fwrite(buffer, 1, size, out_fd);// rc = write(1, buffer, size);if ( rc != size ){fprintf(stderr,"short write: wrote %d bytes\n",rc);}}snd_pcm_drain(handle);snd_pcm_close(handle);free(buffer);fclose(out_fd);
}
其他(未验证):
//
// gcc recorder.c -o recorder -lasound//#include "head4audio.h"
#include </usr/include/alsa/asoundlib.h>// 根据本系统的具体字节序处理的存放格式
#if __BYTE_ORDER == __LITTLE_ENDIAN#define RIFF ('F'<<24 | 'F'<<16 | 'I'<<8 | 'R'<<0)#define WAVE ('E'<<24 | 'V'<<16 | 'A'<<8 | 'W'<<0)#define FMT (' '<<24 | 't'<<16 | 'm'<<8 | 'f'<<0)#define DATA ('a'<<24 | 't'<<16 | 'a'<<8 | 'd'<<0)#define LE_SHORT(val) (val) #define LE_INT(val) (val) #elif __BYTE_ORDER == __BIG_ENDIAN#define RIFF ('R'<<24 | 'I'<<16 | 'F'<<8 | 'F'<<0)#define WAVE ('W'<<24 | 'A'<<16 | 'V'<<8 | 'E'<<0)#define FMT ('f'<<24 | 'm'<<16 | 't'<<8 | ' '<<0)#define DATA ('d'<<24 | 'a'<<16 | 't'<<8 | 'a'<<0)#define LE_SHORT(val) bswap_16(val) #define LE_INT(val) bswap_32(val) #endif#define DURATION_TIME 3// 准备WAV格式参数
void prepare_wav_params(wav_format *wav)
{wav->format.fmt_id = FMT;wav->format.fmt_size = LE_INT(16);wav->format.fmt = LE_SHORT(WAV_FMT_PCM);wav->format.channels = LE_SHORT(2); // 声道数目wav->format.sample_rate = LE_INT(44100); // 采样频率wav->format.bits_per_sample = LE_SHORT(16); // 量化位数wav->format.block_align = LE_SHORT(wav->format.channels* wav->format.bits_per_sample/8);wav->format.byte_rate = LE_INT(wav->format.sample_rate* wav->format.block_align);wav->data.data_id = DATA;wav->data.data_size = LE_INT(DURATION_TIME* wav->format.byte_rate);wav->head.id = RIFF;wav->head.format = WAVE;wav->head.size = LE_INT(36 + wav->data.data_size);
}// 设置WAV格式参数
void set_wav_params(pcm_container *sound, wav_format *wav)
{// 1:定义并分配一个硬件参数空间snd_pcm_hw_params_t *hwparams;snd_pcm_hw_params_alloca(&hwparams);// 2:初始化硬件参数空间snd_pcm_hw_params_any(sound->handle, hwparams);// 3:设置访问模式为交错模式(即帧连续模式)snd_pcm_hw_params_set_access(sound->handle, hwparams,SND_PCM_ACCESS_RW_INTERLEAVED);// 4:设置量化参数snd_pcm_format_t pcm_format = SND_PCM_FORMAT_S16_LE;snd_pcm_hw_params_set_format(sound->handle,hwparams, pcm_format);sound->format = pcm_format;// 5:设置声道数目snd_pcm_hw_params_set_channels(sound->handle,hwparams, LE_SHORT(wav->format.channels));sound->channels = LE_SHORT(wav->format.channels);// 6:设置采样频率// 注意:最终被设置的频率被存放在来exact_rate中uint32_t exact_rate = LE_INT(wav->format.sample_rate);snd_pcm_hw_params_set_rate_near(sound->handle,gcc read_microphone.c -o read_microphone -lasoundhwparams, &exact_rate, 0);// 7:设置buffer size为声卡支持的最大值snd_pcm_uframes_t buffer_size;snd_pcm_hw_params_get_buffer_size_max(hwparams,&buffer_size);snd_pcm_hw_params_set_buffer_size_near(sound->handle,hwparams, &buffer_size);// 8:根据buffer size设置period sizesnd_pcm_uframes_t period_size = buffer_size / 4;snd_pcm_hw_params_set_period_size_near(sound->handle,hwparams, &period_size, 0);// 9:安装这些PCM设备参数snd_pcm_hw_params(sound->handle, hwparams);// 10:获取buffer size和period size// 注意:他们均以 frame 为单位 (frame = 声道数 * 量化级)snd_pcm_hw_params_get_buffer_size(hwparams,&sound->frames_per_buffer);snd_pcm_hw_params_get_period_size(hwparams,&sound->frames_per_period, 0);// 11:保存一些参数sound->bits_per_sample =snd_pcm_format_physical_width(pcm_format);sound->bytes_per_frame =sound->bits_per_sample/8 * wav->format.channels;// 12:分配一个周期数据空间sound->period_buf =(uint8_t *)calloc(1,sound->frames_per_period * sound->bytes_per_frame);
}snd_pcm_uframes_t read_pcm_data(pcm_container *sound,snd_pcm_uframes_t frames)
{snd_pcm_uframes_t exact_frames = 0;snd_pcm_uframes_t n = 0;uint8_t *p = sound->period_buf;while(frames > 0) {n = snd_pcm_readi(sound->handle, p, frames);frames -= n;exact_frames += n;p += (n * sound->bytes_per_frame);}return exact_frames;
}// 从PCM设备录取音频数据,并写入fd中
void recorder(int fd, pcm_container *sound, wav_format *wav)
{// 1:写WAV格式的文件头write(fd, &wav->head, sizeof(wav->head));write(fd, &wav->format, sizeof(wav->format));write(fd, &wav->data, sizeof(wav->data));// 2:写PCM数据uint32_t total_bytes = wav->data.data_size;while(total_bytes > 0){uint32_t total_frames =total_bytes / (sound->bytes_per_frame);snd_pcm_uframes_t n =MIN(total_frames, sound->frames_per_period);uint32_t frames_read = read_pcm_data(sound, n);write(fd, sound->period_buf,frames_read * sound->bytes_per_frame);total_bytes -=(frames_read * sound->bytes_per_frame);}
}int main(int argc, char **argv)
{if(argc != 2){printf("Usage: %s <wav-file>\n", argv[0]);exit(1);}// 1:打开WAV格式文件int fd = open(argv[1], O_CREAT|O_WRONLY|O_TRUNC, 0777);// 2: 打开PCM设备文件pcm_container *sound = calloc(1, sizeof(pcm_container));//snd_pcm_open(&sound->handle, "default",SND_PCM_STREAM_CAPTURE, 0);snd_pcm_open(&sound->handle, "hw:1,0",SND_PCM_STREAM_CAPTURE,0);// 3: 准备并设置WAV格式参数wav_format *wav = calloc(1, sizeof(wav_format));prepare_wav_params(wav);set_wav_params(sound, wav);// 4: 开始从PCM设备"plughw:0,0"录制音频数据// 并且以WAV格式写到fd中recorder(fd, sound, wav);// 5: 释放相关资源snd_pcm_drain(sound->handle);close(fd);snd_pcm_close(sound->handle);free(sound->period_buf);free(sound);free(wav);return 0;
}
linux环境用usb麦克风阵列ALSA音频设备录音相关推荐
- linux mic阵列通道丢数据,基于XMOS平台的USB麦克风阵列多声道采集装置
技术领域 本实用新型涉及麦克风阵列多声道声音采集领域,尤其涉及基于XMOS平台的USB麦克风阵列多声道采集装置. 背景技术 麦克风阵列(Array Microphone),是由2个以上数量的声学数字或 ...
- Linux ARM 使用USB麦克风ALSA音频设备编程
近期有一个项目要用到音频处理,先是对标准的麦克风输入设备进行了测试,后来使用的USB麦克风,在编程时遇到了小问题,所以记下笔记. 一.环境 1.系统Linux (Lubuntu) 2.硬件CPU: R ...
- android usb麦克风阵列,语音设备 SDK 麦克风阵列建议
您现在访问的是微软AZURE全球版技术文档网站,若需要访问由世纪互联运营的MICROSOFT AZURE中国区技术文档网站,请访问 https://docs.azure.cn. 语音设备 SDK 麦克 ...
- Linux环境下USB的原理、驱动和配置
什么是USB? USB是英文Universal Serial Bus的缩写,意为通用串行总线.USB最初是为了替代许多不同的低速总线(包括并行.串行和键盘连接)而设计的,它以单一类型的总线连接各种不同 ...
- linux下usb驱动配置文件,Linux环境下USB的原理、驱动和配置
随着生活水平的提高,人们对USB设备的使用也越来越多,鉴于Linux在硬件配置上尚不能全部即插即用,因此关于Linux如何配置和使用,成为困扰我们的一大问题.本文引用地址:http://www.eep ...
- linux usb驱动u盘启动不了,Linux环境下USB的原理、驱动和配置(4)
在探测函数中会对每一个接口进行一次探测,所以我们在写USB驱动程序的时候,只要做好第一个端点,其它的端点就会自动完成探测.在探测函数中我们要注意的是在内核中用结构体struct usb_host_en ...
- 麦克风阵列声源定位效果测试
下列图片如果不清楚可以直接访问淘宝链接,从链接中的网盘资料进行拉取.从此链接看到的购买可以跟客服说,提我可以便宜50块钱~~~ 店铺链接:首页-智能语音开发者联盟-淘宝网 产品链接:https://i ...
- 阵列信号处理及matlab实现_麦克风阵列原理及应用
01 - 什么是麦克风阵列 麦克风阵列是由一定数目的麦克风组成,对声场的空间特性进行采样并滤波的系统. 目前常用的麦克风阵列可以按布局形状分为:线性阵列,平面阵列,以及立体阵列.其几何构型是按设计已知 ...
- 遨博协作机器人ROS开发 - 麦克风阵列语音模块ROS驱动
目录 一.简介 二.环境版本 三.学习目标 四.知识储备 五.任务实施 六.任务拓展 七.课堂小结 八.课后练习 一.简介 大家好,欢迎关注遨博学院带来的系列技术分享文章(协作机器人ROS开发),在前 ...
最新文章
- 关于学习Python的一点学习总结(10->设置字符串格式)
- java8 遍历目录_使用java8API遍历过滤文件目录及子目录及隐藏文件
- new 实例化对象是啥意思_二. 初步认识JS中的类和对象
- 数据库查询语句慢如何优化_常见Mysql的慢查询优化方式
- 这8种常见的SQL错误用法,你还在用吗?
- DataGridView绑定对象数组 c# 1614236580
- 【3】数据筛选3 - BeautifulSoup4
- [Python] L1-045 宇宙无敌大招呼-PAT团体程序设计天梯赛GPLT
- 【概率证明】—— sum and product rules of probability
- json与字面量定义对象的区别,请不要混淆,与字符串转换
- 计算机微课论文参考文献,关于信息技术论文范文资料 与初中信息技术课堂中微课应用策略有关论文参考文献...
- Linux下解压分包文件zip(zip/z01/z02)【转】
- 金坛php开发,金坛公布2021年民生实事
- Pytorch 小白记事本 1
- CSS面试须知--显示模式及三大特性
- matlab nan变成0_最优化计算与matlab实现(17)——粒子群优化算法——带压缩因子的粒子群算法...
- 一个数据分析的真实失败案例,让我突然有点恍惚了
- rgret白鹭 开发html游戏,白鹭推HTML5首款生态产品Egret Runtime
- CSharp 基本知识-数组
- 设置chrome浏览器的开发调试工具主题为dark模式
热门文章
- Python图书数据可视化分析
- 虚拟现实在招聘中的应用
- “Implementing SCORM 1.3” 研习营心得摘要(胡正亨)
- ubuntu18.04 ros melodic Autoware1.14源码编译安装(完整版,全过程)
- 【云原生】Apache Livy on k8s 讲解与实战操作
- 【工作精华】抵质押与贷款授信的关系
- 国内洗地机品牌有哪些,分享几款好用的洗地机
- set_false_path 与 set_disable_timing 的区别
- EditPlus_3.4及注册码
- K折交叉验证代码示例