10、记录使用科大讯飞的语音唤醒硬件生成PCM文件,通过ffmpeg库去生成MP3音频文件

基本思想:不太会ffmpeg解析pcm的音频文件,所以记录一下结合具体的场景和具体的应用

具体生成的pcm使用的官方代码,不详细叙述,官方的唤醒模块将会产生一个pcm文件,可使用下列命令或者代码将pcm转成mp3文件,将进行后续处理,具体业务保密,不累述;

图片来自轮趣科技:其语音主控板主要是 R818 降噪板,其内部集成科大讯飞语音算法,利用麦克风阵列的空域滤波特性,通过唤醒人的角度定位,形成定向拾音波束,并对
波束以外的噪声进行抑制, 提升远场拾音质量。附测试的pcm文件

链接: https://pan.baidu.com/s/1zL7k3w6JLWN9m4vp7B597A?pwd=rre7 提取码: rre7

命令转pcm到mp3

ubuntu@ubuntu:~$ ffmpeg -y -ac 1 -ar 16000 -f s16le -i /home/ubuntu/audio_xufei_arm/cmake-build-debug/vvui_deno.pcm -c:a libmp3lame -q:a 2 output.mp3
ffmpeg version 4.2.7-0ubuntu0.1 Copyright (c) 2000-2022 the FFmpeg developersbuilt with gcc 9 (Ubuntu 9.4.0-1ubuntu1~20.04.1)configuration: --prefix=/usr --extra-version=0ubuntu0.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-nvenc --enable-chromaprint --enable-frei0r --enable-libx264 --enable-sharedlibavutil      56. 31.100 / 56. 31.100libavcodec     58. 54.100 / 58. 54.100libavformat    58. 29.100 / 58. 29.100libavdevice    58.  8.100 / 58.  8.100libavfilter     7. 57.100 /  7. 57.100libavresample   4.  0.  0 /  4.  0.  0libswscale      5.  5.100 /  5.  5.100libswresample   3.  5.100 /  3.  5.100libpostproc    55.  5.100 / 55.  5.100
[s16le @ 0x5648e442e740] Estimating duration from bitrate, this may be inaccurate
Guessed Channel Layout for Input Stream #0.0 : mono
Input #0, s16le, from '/home/ubuntu/audio_xufei_arm/cmake-build-debug/vvui_deno.pcm':Duration: 00:00:04.77, bitrate: 256 kb/sStream #0:0: Audio: pcm_s16le, 16000 Hz, mono, s16, 256 kb/s
Stream mapping:Stream #0:0 -> #0:0 (pcm_s16le (native) -> mp3 (libmp3lame))
Press [q] to stop, [?] for help
Output #0, mp3, to 'output.mp3':Metadata:TSSE            : Lavf58.29.100Stream #0:0: Audio: mp3 (libmp3lame), 16000 Hz, mono, s16pMetadata:encoder         : Lavc58.54.100 libmp3lame
size=      26kB time=00:00:04.79 bitrate=  44.3kbits/s speed= 424x    
video:0kB audio:26kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.856164%

cmakelists.txt

cmake_minimum_required(VERSION 3.16)
project(untitled2)set(CMAKE_CXX_STANDARD 14)add_executable(untitled2 main.cpp)
target_link_libraries(untitled2 -lswresample -lavformat -lavcodec -lswscale -lavutil -lz)

main.cpp 代码修改为采样率为16000 声音为mono 读取字节为512 调整采样为单倍,注意集成项目中需要*.c文件,因为c无法找到cpp文件,或者用extern包裹一下

#include <iostream>#ifdef __cplusplus
extern "C"
{
#endif
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavutil/imgutils.h"
#include "libavutil/log.h"
#include "libswresample/swresample.h"#include "libavutil/avutil.h"
#include "libavutil/opt.h"
#ifdef __cplusplus
}
#endif
using namespace std;#define CHANNEL 1
#define OSR 16000/*** pcm 转 mp3格式,输入文件路径*/
int pcm_to_mp3(const char *pcm_file_path, const char *mp3_file_path)
{FILE *pcm_file = NULL;FILE *mp3_file = NULL;int result;// 获取mp3编码器cout << "获取mp3编码器" << endl;const AVCodec *avCodec = avcodec_find_encoder(AV_CODEC_ID_MP3);if (!avCodec){cout << "初始化mp3 编码器失败" << endl;return -1;}// 创建编码器上下文AVCodecContext *avCodecContext = avcodec_alloc_context3(avCodec);if (!avCodecContext){cout << "avcodec_alloc_context3 失败" << avCodecContext << endl;return -1;}avCodecContext->bit_rate = 64000;avCodecContext->channels = CHANNEL;avCodecContext->channel_layout = AV_CH_LAYOUT_MONO;avCodecContext->sample_rate = OSR;avCodecContext->sample_fmt = AV_SAMPLE_FMT_S16P;avCodecContext->time_base = av_get_time_base_q();// 打开编码器cout << "打开mp3编码器" << endl;result = avcodec_open2(avCodecContext, avCodec, NULL);if (result < 0){cout << "avcodec_open2失败: " << result << endl;return result;}cout << "打开mp3文件" << mp3_file_path << endl;// 打开输出文件mp3_file = fopen(mp3_file_path, "wb");if (!mp3_file){cout << "打开mp3文件失败" << endl;return -1;}// AVFrame 接受重采样的每一帧的音频数据 每帧的样本大小为1152AVFrame *avFrame = av_frame_alloc();if (!avFrame){cout << "分配avFrame帧失败" << endl;return -1;}// mp3一帧的样本数为1152avFrame->nb_samples = 256;avFrame->channels = CHANNEL;avFrame->channel_layout = AV_CH_LAYOUT_MONO;avFrame->format = AV_SAMPLE_FMT_S16P;// 给帧分配内存空间result = av_frame_get_buffer(avFrame, 0);if (result < 0){cout << "分配帧内存失败" << endl;return result;}// 重采样  创建音频重采样上下文cout << "配置重采样器上下文" << endl;SwrContext *swrContext = swr_alloc();if (!swrContext){cout << "配置重采样上下文失败" << endl;return -1;}// 设置重采样输入pcm参数:通道布局:立体声 采样率:44100  样本格式 s16交错存储av_opt_set_int(swrContext, "in_channel_layout", AV_CH_LAYOUT_MONO, 0);av_opt_set_int(swrContext, "in_sample_rate", OSR, 0);av_opt_set_sample_fmt(swrContext, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0);// 设置重采样输出mp3参数:通道布局:立体声 采样率:44100  样本格式 s16平面存储av_opt_set_int(swrContext, "out_channel_layout", AV_CH_LAYOUT_MONO, 0);av_opt_set_int(swrContext, "out_sample_rate", OSR, 0);av_opt_set_sample_fmt(swrContext, "out_sample_fmt", AV_SAMPLE_FMT_S16P, 0);// 重采样初始化result = swr_init(swrContext);if (result < 0){cout << "重采样器初始化失败,error=" << result << endl;return result;}uint8_t **input_data = NULL;uint8_t **output_data = NULL;int input_linesize, output_linesize;// 打开pcm文件cout << "打开源 pcm 文件 " << pcm_file_path << endl;pcm_file = fopen(pcm_file_path, "rb");if (!pcm_file){cout << "打开 pcm 文件失败" << endl;return -1;}cout << "开始编码转换" << endl;// 给pcm文件数据分配空间result = av_samples_alloc_array_and_samples(&input_data, &input_linesize, 2, avFrame->nb_samples, AV_SAMPLE_FMT_S16, 0);if (result < 0){cout << "给pcm文件分配空间失败, result = " << result << endl;return result;}// 缓存重采样数据的空间分配result = av_samples_alloc_array_and_samples(&output_data, &output_linesize, 2, avFrame->nb_samples, AV_SAMPLE_FMT_S16P, 0);if (result < 0){cout << "获取mp3 重采样数据失败, result=" << result << endl;return result;}// 存放编码后的数据AVPacket *avPacket = av_packet_alloc();if (!avPacket){cout << "分配 avPacket 内存失败" << endl;return -1;}cout << "==========循环读入帧==========" << endl;long total_size = 0;while (!feof(pcm_file)){long read_size = (long)fread(input_data[0], 1, avFrame->nb_samples * 2, pcm_file);total_size += read_size;if ((total_size / read_size) % 50 == 0){cout << "读取数据:" << read_size << "字节; 累计:" << total_size << " 字节 " << endl;}if (read_size <= 0){break;}// 重采样result = swr_convert(swrContext, output_data, avFrame->nb_samples, (const uint8_t **)input_data, avFrame->nb_samples);if (result < 0){cout << "音频编码失败,错误信息" << result << endl;return result;}// 将重采样后的数据存入frame,MP3是s16p 先存放左声道的数据 后存放右声道的数据, data[0]是左声道,1是右声道avFrame->data[0] = output_data[0];avFrame->data[1] = output_data[1];// 编码,写入mp3文件,实际上是对frame这个结构体里面的数据进行编码操作,发送到编码线程:使用编码器  和 存储数据的frameresult = avcodec_send_frame(avCodecContext, avFrame);if (result < 0){cout << "mp3编码失败,错误信息:" << result << endl;return result;}while (result >= 0){// 接收编码后的数据,使用编码器 和 存储编码数据的pkt, 有可能需要多次才能接收完成result = avcodec_receive_packet(avCodecContext, avPacket);// AVERROR_EOF表示没有数据了 这两个错误不影响继续接收数据if (result == AVERROR_EOF || result == AVERROR(EAGAIN)){continue;}else if (result < 0){break;}fwrite(avPacket->data, 1, avPacket->size, mp3_file);av_packet_unref(avPacket);}}// 告诉解码器没有帧了,如果没有这几行的逻辑,在关闭 avCodecContext 可能会提示 * fames left in the queu on closingavcodec_send_frame(avCodecContext, __null);while(avcodec_receive_packet(avCodecContext, avPacket)!=AVERROR_EOF);// 关闭缓存if (input_data){av_free(input_data);}if (output_data){av_free(output_data);}cout << "关闭文件" << endl;fclose(pcm_file);fclose(mp3_file);cout << "释放资源" << endl;// s释放 frame pktav_frame_free(&avFrame);av_packet_free(&avPacket);// 释放重采样上下文swr_free(&swrContext);// 释放编码器上下文avcodec_free_context(&avCodecContext);cout << "转码完成" << endl;return 0;
}int main(int argc, char *argv[])
{const char *input = "vvui_deno.pcm";const char *output = "vvui_deno.mp3";pcm_to_mp3(input, output);return 0;
}

参考:

音视频开发9. 使用ffmpeg 将pcm转码mp3实践(C++)_编程圈子的博客-CSDN博客_ffmpeg pcm转mp3

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深兰科技亮相2023数博会:硅基知识大模型推动个人数字化产业

近日&#xff0c;2023中国国际大数据产业博览会 “数字经济与实体经济深度融合”论坛在贵阳举行。腾讯云、京东集团、网易、深兰科技等8家企业负责人进行了行业演讲。 作为2023数博会的专业论坛之一&#xff0c;本次论坛以“数融百业 创变赋新”为主题&#xff0c;从数实融合视…

吴怀宇 | 对比欧盟,中国的《人工智能法案》应有什么底座?

来源&#xff1a;OpenDAI 作者&#xff1a;吴怀宇 中国科学院博士、北京大学博士后 2023年6月14日&#xff0c;欧洲议会全体会议表决通过了《人工智能法案》授权草案&#xff0c;标志着该法案将进入欧盟立法严格监管人工智能技术应用的最终谈判阶段。欧洲议会此前曾发出声明&a…

希尔伯特旅馆里,住着AI的某种真相

“无穷”和“无穷1”&#xff0c;哪个更大&#xff1f; 已经吸收了不知道多少数据的AI模型&#xff0c;和比他多学习一条数据的模型&#xff0c;哪个更智能&#xff1f; 想聊聊这个问题&#xff0c;出于一个偶然的机会。很早之前我在测试ChatGPT的时候&#xff0c;突然想问他个…

AI大时代——一次全新的生产力革命

✏笔者按&#xff1a; 我这个人是比较笨的&#xff0c;我是在3月9日左右才恍然意识到一个崭新的AI大时代已经到来了。 全文7339字&#xff0c;阅读需要约10分钟 >>前言 我是在大三时候阅读《游戏编程中的人工智能技术》这本书的时候接触到的人工智能和神经网络的相关…

“AI教父”Geoffrey Hinton:智能进化的下一个阶段

来源 | The Robot Brains Podcast OneFlow编译 翻译 | 杨婷、贾川 ChatGPT等大模型带来的震撼技术革新&#xff0c;让Geoffrey Hinton突然改变了自己的一个想法。 这位75岁的“人工智能教父”意识到&#xff0c;数字智能优于生物智能的进程无法避免&#xff0c;超级智能很快就会…

为什么说 AI 将拯救整个世界?

【CSDN 编者按】AI 会让我们失业吗&#xff1f;AI 会“杀”死人类吗&#xff1f;当一门重要的新技术横空出世的时候&#xff0c;人们总是会担心它给人们带来的种种威胁&#xff0c;基于此&#xff0c;本文作者认为&#xff0c;虽然 AI 风险很高&#xff0c;但也存在非常有影响力…

从破解虫脑到攻克人脑:一条“永生之路”的新赛道?

从破解虫脑到攻克人脑&#xff1a;一条“永生之路”的新赛道&#xff1f; 首张果蝇大脑连接组&#xff1a;耗费十余年&#xff0c;重建三千神经元&#xff0c;超50万突触&#xff01; 论文地址 果蝇幼虫大脑的连接组。 所有脑神经元的形态学都经过了突触分辨率的电子显微镜成像…

大模型技术发展概述 -(三)

文本内容参考论文《A Survey of Large Language Models》 论文标题&#xff1a;A Survey of Large Language Models 论文链接&#xff1a;https://arxiv.org/pdf/2303.18223v10.pdf 大模型技术发展概述 -&#xff08;三&#xff09; 5. 适应性调整LLM5.1 指令&#xff08;Instr…

C++爱心代码

C爱心代码 效果图 代码 #include<stdio.h> #include<Windows.h> int main() {float x, y, a;for (y 1.5; y > -1.5; y - 0.1){for (x -1.5; x < 1.5; x 0.05){a x * x y * y - 1;putchar(a * a * a - x * x * y * y * y < 0.0 ? * : );}system(&…

C语言爱心代码,C语言爱心代码合集(附源码)

1、love图案的C语言爱心代码 C语言爱心代码如下&#xff1a; #include <stdio.h>int main(){int i, j, k, n 0, x 0, y 50;//爱心的头部没有规律&#xff0c;所以直接打印printf("\n\n\n\n\n");printf(" lovelove lovelov…

编写爱心代码

# -*- coding: utf-8 -*- from turtle import * def curvemove(): for i in range(200): right(1) forward(1) color(red,pink) begin_fill() left(140) forward(111.65) curvemove() left(120) curvemove() forward(111.65) end_fill() done()

爱心代码—(免费分享)

可加名字 的爱心 可变颜色 方法很简单 首先在桌面新建一个文本&#xff1a; 然后在复制我下面的代码在文本里面并保存&#xff1a; <!DOCTYPE html> <html> <head> <meta charset"utf-8" /> <title>&#x1f497;</ti…

爱心代码编写

HTMLC 代码1&#xff1a; <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE> New Document </TITLE> <META NAME"Generator" CONTENT"EditPlus"> <META NA…

最近很火的爱心代码

爱心代码 <!DOCTYPE html> <html><head><title></title><script src"js/jquery.min.js"></script></head><style>* {padding: 0;margin: 0;}html,body {height: 100%;padding: 0;margin: 0;background: #000…

爱心发射代码带名字升级版

上次的爱心发射发出来之后&#xff0c;群友想问能不能把心爱的人名字放在爱心中间。 当然没问题啊&#xff0c;于是我就改了改代码&#xff0c;让女神王铁蛋显示在爱心中间&#xff0c;同时还可以在屏幕上飘动满屏的王铁蛋&#xff0c;大大小小、快快慢慢的王铁蛋。 这还拿不下…

跳动的爱心代码--李峋爱心代码(完整源码)

本文章分为两部分&#xff1a; 第一部分为实现效果展示&#xff0c;第二部分是实现跳动爱心源码。 关注微信公众号&#xff1a; 先取个名字吧 跳动的爱心效果展示 关注微信公众号&#xff08;先取个名字吧&#xff09;获取完整源码&#xff0c;回复爱心代码。 实现步骤 1.建一…

火爆了的爱心代码

请下载Visual Studio Code或者HBuilder&#xff08;我最喜欢用这个因为是中文版的&#xff09;复制然后粘贴之后用浏览器运行就行然后也可以复制出来发到微信手机也可以打开 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> &l…

跳动爱心代码-李峋爱心代码(手把手教学)

电视剧 点燃我&#xff0c;温暖你 打火机与公主裙 李洵爱心跳动效果。 获取完整代码&#xff0c;公众号「先取个名字吧」 回复爱心代码。 本文分为两种方式讲解如何运行代码&#xff0c;第一种方式比较简单推荐新手&#xff08;完全不懂编程的&#xff09;&#xff0c;第二种…

chatgpt赋能python:Python怎么让输出结果用空格断开

Python怎么让输出结果用空格断开 介绍 Python是一种高级编程语言&#xff0c;语法简洁、易读、易维护&#xff0c;非常适合初学者和中级开发者。在Python编程中&#xff0c;我们经常需要输出结果&#xff0c;而如果我们需要让输出结果用空格断开&#xff0c;该怎么做呢&#…

chatgpt智能提效职场办公-ppt怎么转pdf文件

作者&#xff1a;虚坏叔叔 博客&#xff1a;https://xuhss.com 早餐店不会开到晚上&#xff0c;想吃的人早就来了&#xff01;&#x1f604; 要将PPT转为PDF文件&#xff0c;可以按照以下步骤操作&#xff1a; 1.打开PPT文件&#xff0c;点击“文件”菜单&#xff0c;选择“导出…