背景

最近做一个基于Qt + FFmpeg实时音视频推流的项目,利用OpenCV实时美颜已经OK。计划用SoundTouch再做变声处理,本来希望男声变女声,大叔变萝莉、单车变摩托的效果,但是多次测试后梦醒了,基本不太可能,只能实现基本的变声,这种应该需要比较专业的算法处理在里面。
但不可否认SoundTouch是个很好的音频处理库,实现基本的变调、变速效果还是不错的,就不勉强更理想的效果了,毕竟定位就不同,常见的音频处理需求SoundTouch可以胜任。

说明

现在看SoundTouch的使用还是比较简单的,但还是摸索一两天才玩透彻。网上的资料在搜索的时候感觉并不多,而且好多是Android相关的。并且还受到了不少误导,因此记录一下,也希望需要的人少走弯路有所帮助。

库的编译

官网很好找,直接下载的库看到有动态库dll,直接使用报错,应该是有问题,最好自己编译静态库
方式:
下载最新源码,结构如下图,使用CMake进行编译,然后如VS2017 IDE,再打开SoundTouch文件夹,一般需要重定解决方案,选中项目右键点击生成,默认配置已经设置好,即可得到静态库。比较简单,不具体叙述。
注意:
直接用VS2017编译生成的静态库使用中存在链接报错,可能我的编译选项设置有问题。建议用CMake先执行下再编译生成就正常了,仍有问题可留言。


库的使用

三方库的配置都是类似的,可以移步另一篇讲库的配置的文章,重头戏是代码。
网上好不容易找到SoundTouch相关的文章有的是互相照抄的,有的不知道是搬运的哪的代码,缺头少尾不知道变量从哪来的, 什么作用,就找到两三篇比较合适的文章。还是转头去找SoundTouch本身提供的例子(官方的最权威,其它库也一样),是一个把变速、变调等功能做成命令行程序的源码,此源码是对输入的Wav音频文件做变速、变调处理后再输出为一个新的Wav文件。不断地查看源码算是理清的头绪,其实就是把一个个采样点的音频数据,送到SoundTouch里进行处理,然后处理完返回一定个数的采样点数据,返回得到的数据就是变速、变调处理后的数据,就可以进行其它操作。库内部的处理算法复杂没看太懂,不过不影响使用。
下面是梳理清楚后写的一份简洁的代码:文件中读取PCM数据处理后输出一个新的PCM文件,目的是表现出最核心的逻辑,先不迷失在其它的一些细节上。理清逻辑后完全可以从内存里取数据,处理后再写到内存,或者其它复杂的处理,逻辑都是一样的。注释很详细,阅读代码即可。

   //源码默认6720 改动为最大4*2*1024 (32位 2通道 1024帧大小)#define MAX_BUFF_SIZE 8192//打开文件QString inPcmFileName = "48000_2_s16le.pcm";QFile inPcmFile(inPcmFileName);if(!inPcmFile.open(QIODevice::ReadOnly)){qDebug() << "read inPcmFile error";return;}QString outPcmFileName = "outPcm.pcm";QFile outPcmFile(outPcmFileName);outPcmFile.open(QIODevice::WriteOnly);//音频数据参数int sampleRate = 48000;int channel = 2;int bytePerSample = 16 / 8;//音频数据缓存 读取一帧原始音频数据(可修改)int inPcmSize = channel * bytePerSample * 1024;uint8_t *inPcmBuf = new uint8_t[inPcmSize];//soundtouch数据缓存 格式需要为SAMPLETYPE(short)SAMPLETYPE touchBuffer[MAX_BUFF_SIZE];//soundTouch设置soundtouch::SoundTouch soundTouch;soundTouch.setSampleRate(sampleRate); // 设置采样率soundTouch.setChannels(channel);      // 设置通道数soundTouch.setTempo(1.0);      //变速soundTouch.setPitch(0.8);      //变调//接收处理后sample个数的最大值int maxRecv = MAX_BUFF_SIZE / channel / bytePerSample;//sample个数int nSamples = 0;//循环读取文件信息while(1){int readLen = inPcmFile.read((char *)inPcmBuf, inPcmSize);if(readLen <= 0)break;//char*类型读取的内容进行转换 uint8转short16for (int i=0; i<readLen/2; i++){touchBuffer[i] = (inPcmBuf[i * 2] | (inPcmBuf[i * 2 + 1] << 8));}//计算此次读取数据中包含的sample个数nSamples = readLen / channel / bytePerSample;//将nSamples个数的样本写入soundTouch进行处理 注:需要数据缓冲,可能putSamples多次,才能receiveSamples收到处理后的音频数据soundTouch.putSamples(touchBuffer, nSamples);//循环接收处理后的音频数据 因为putSamples与receiveSamples的个数不一定对等,存在多次才接收完的情况while(1){//返回处理好的样本个数 每次接收个数不会超过最大值maxRecv 防止一次接收的数据量过大nSamples = soundTouch.receiveSamples(touchBuffer, maxRecv);if(nSamples == 0)break;//根据样本数,计算处理后的数据长度int length = nSamples * channel * bytePerSample;outPcmFile.write((char*)touchBuffer, length);}}//存在剩余的处理好的数据,冲刷一下soundTouch.flush();while(1){//接收处理后的数据,步骤与上相同nSamples = soundTouch.receiveSamples(touchBuffer, maxRecv);if(nSamples == 0)break;int length = nSamples * channel * bytePerSample;outPcmFile.write((char*)touchBuffer, length);}qDebug() << "Finish";//释放资源inPcmFile.close();outPcmFile.close();delete[] inPcmBuf;inPcmBuf = nullptr;

记录 SoundTouch的配置与代码分析相关推荐

  1. AUTOSAR从入门到精通100讲(三十六)-AUTOSAR 通信服务两步走-CanSM概念-配置及代码分析

    CanSM概念 AUTOSAR CanSM模块的分享分为CanSM模块概念详解和CanSM模块配置及代码分析,具体的项目实战请关注本号的后续文章,本篇为CanSM模块的概念详解篇. 1 Introdu ...

  2. AUTOSAR从入门到精通100讲(三十五)-Lin通信协议栈分析三部曲LinTrcv配置及代码分析

    LinTrcv 0.Lin通信协议栈简介: LIN通信服务是一组用于与LIN通信系统进行车辆网络通信的模块.提供统一的LIN网络接口.对应用层程序隐藏协议信息和消息属性的特性. Lin通信服务包括: ...

  3. AUTOSAR从入门到精通100讲(三十七)-AUTOSAR 通信服务-ComM配置及代码分析

    ComM概念详解 1 Introduction and functional overview ComM模块是BSW一个组件成员.ComM作为一个资源管理器封装了底层的通信服务.ComM模块控制与通信 ...

  4. 2017.4.18 静态代码分析工具sonarqube+sonar-runner的安装配置及使用

    配置成功后的代码分析页面: 可以看到对复杂度.语法使用.重复度等等都做了分析,具体到了每一个方法和每一句代码. 四种使用方式: sonarqube + sonar-runner sonarqube + ...

  5. 音频变速变调原理及 soundtouch 代码分析

    音频变速变调原理及 soundtouch 代码分析 作者:floer rivor 2021 年 4 月 30 日 本文字数:5066 字 阅读完需:约 17 分钟 概述 音频变速变调在不同的场景可以分 ...

  6. 20145236《网络攻防》Exp4 恶意代码分析

    20145236<网络攻防>Exp4 恶意代码分析 一.基础问题回答 如果在工作中怀疑一台主机上有恶意代码,但只是猜想,所有想监控下系统一天天的到底在干些什么.请设计下你想监控的操作有哪些 ...

  7. 20145328 《网络对抗技术》恶意代码分析

    20145328 <网络对抗技术>恶意代码分析 ------看到这句话说明还没写完-------- 实践内容: 使用schtasks指令监控系统运行 使用sysmon工具监控系统运行 使用 ...

  8. 2018-2019-2 网络对抗技术 20165324 Exp4:恶意代码分析

    2018-2019-2 网络对抗技术 20165324 网络对抗技术 Exp4:恶意代码分析 课下实验: 实践目标 是监控你自己系统的运行状态,看有没有可疑的程序在运行. 是分析一个恶意软件,就分析E ...

  9. 2018-2019-2 网络对抗技术 20165320 Exp4 恶意代码分析

    2018-2019-2 网络对抗技术 20165320 Exp4 恶意代码分析 一.实践目标 监控你自己系统的运行状态,看有没有可疑的程序在运行 分析一个恶意软件,就分析Exp2或Exp3中生成后门软 ...

最新文章

  1. DATEIF实例说明2
  2. cisco路由器EIGRP配置实例
  3. 刚进入win7系统就提示检测到一个硬盘问题的解决方法
  4. Numpy的基本用法
  5. markdown 换行_markdown傻瓜指南(github)
  6. nssl1320,jzoj(初中)2108-买装备【dfs,水题】
  7. 光端机是做什么的?光端机的作用主要有哪些?
  8. LoadRunner脚本增强技巧之检查点
  9. leetcode 54. 螺旋矩阵(递归)
  10. Linux下OneinStack一键安装JAVA+PHP+Tomcat+Nginx+MySQL网站环境
  11. python灰色预测_灰色系统预测GM(1,1)模型
  12. 细说Linux链接文件类型
  13. iOS架构-cocoaPods之Podfile语法(18)
  14. 英文简历模板计算机专业,2016年计算机专业英文简历模板
  15. 麦吉尔商业与计算机科学,麦吉尔大学与UBC大学那个好考
  16. Android_Provision
  17. 青岛大学计算机调剂群,2019山东青岛大学硕士研究生调剂公告(4月16日更新)...
  18. 在python中import什么意思_python的import是什么意思
  19. 光敏传感器实验报告_光敏传感器光电特性测量实验分析报告.ppt
  20. Cheat sheet FOR Python Packages

热门文章

  1. 最浅显易懂的约瑟夫环讲解
  2. 三菱modbusRTU通讯实例_实例 | 威纶触摸屏与三菱D700变频器通讯
  3. android使用WebView实现显示360°全景H5页面
  4. 28,verilog中的字符串表示
  5. 基金公司算法交易系统架构
  6. springboot基于web儿童教育网站 毕业设计-附源码111123
  7. 微服务的未来 —— 更多层抽象
  8. WIBRAIN I1-也许是你最想要的全天侯UMPC
  9. react @connect
  10. 搜狗图片的获取,使用python实现