Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >大话音频变声原理 附简单示例代码

大话音频变声原理 附简单示例代码

原创
作者头像
cpuimage
发布于 2018-08-26 12:05:18
发布于 2018-08-26 12:05:18
2.7K00
代码可运行
举报
文章被收录于专栏:算法+算法+
运行总次数:0
代码可运行

关于音频变声算法,这个是一个很多人特别感兴趣的话题。

当然也有不少开源算法可以参阅学习,有基于时域,也有基于频域的算法。

最终算法想要达到的目的是一致。

最近也有不少网友问过关于变声算法的一些细节问题,邮件询问我。

要给出一个比较合理或者说通俗易懂的解释,看似简单,其实还蛮难的。

按照大概的一个逻辑思路,稍微理一理,所以这个主题必须加上“大话”这个前缀。

也不打算讲特别高深的,当然也是因为讲不来。

之于图像算法领域,非常重要的算法是高斯模糊,

当然也可以认为是卷积,高斯模糊是卷积的一种特例,这里就不展开了。

而之于音频,也许你也猜到了,基于时间的,毫无疑问,就是重采样算法。

音频采样率是指录音设备在一秒钟内对声音信号的采样次数,

采样频率越高声音的还原就越真实越自然。

在当今的主流采集卡上,采样频率一般共分为22.05KHz、44.1KHz、48KHz三个等级,

22.05KHz只能达到FM广播的声音品质,

44.1KHz则是理论上的CD音质界限,48KHz则更加精确一些。

看到这里,也许大多数人还是没法理解采样频率大概是什么意思。

换个角度来说的话,就是假设一个人说“你好”,花了20毫秒,而机器在这20毫秒内,

采集的数据多少就可以理解为采样率高低。

也就是说,20毫秒内,采集到的数据量就是可以大概认为目前的采样率,数据量越大,精度越高,采样率越高。

那么,我们再换一个思路,想一个问题。

如果在同样的速率的情况下,

一个人的语速快,一个人的语速慢,那也可能造成采样数据分布不一致。

这里就可以展开一个音频算法,就是变速。

嗯,是的,就是变速。

从原理上来讲的话,其实变速就是在同样的采样率环境下,对采样数据进行拉伸或压缩。

从算法的角度上来说的话,可以认为是插值或抽值。

如果你让一个人讲话的速度变得更快怎么做,

很明显,就是在同样的采样率下,抽掉一些样本。

反之,降速则是插入一些样本。

最终决定变速效果的就是插入样本和抽离样本的权重计算。

例如原来采样到的数据是

1234

加速的时候,抽离样本 1 和 4

23

降速的时候,增加样本 

11223344

当然只是举个例子,便于大家理解这个概念逻辑。

看到这里,肯定有人会问,

那声音的大小呢?或者说信号的强弱呢?

其实也就是提升音量和降低音量,我想这个应该不用解释。

变速是时域变,空间不变。

而音量则反之,时域不变,空间变。

可以简单粗暴地理解,就是线性拉伸。

例如原来采样到的数据是

1234

每个样本+4,直接拉伸为

5678

也有采用乘法进行拉伸的,

例如 乘以2

2468

上面是增大音量,降低音量反之就是减和除。

而最终不管变速还是音量调节,

最终算法要做的事情就是确定对应位置的对应权重。

当然也要看最终想要达到什么样的效果,适配权重。

饶了这么一大圈,还是没有说到变声的问题。

其实,变声就是变速+音量调节。

以上变速也好,音量调节也好,相对而言都是线性拉伸,

直接的加减乘除然后插值抽值就能达到的。

而变声的概念其实也是类似的,

就是在在同一时域内同时调节对应时域的音量权重。

换言之就是在同一个采样率内,同时控制语速和音量在一个特定的权重内。

其实就是一个时域和空间的二维拉伸。

理解这个逻辑确实有点绕。

用采样算法来做一个简单的示例。

参阅前面的文章《简洁明了的插值音频重采样算法例子 (附完整C代码)》

这个示例中的采样函数是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void resampler(char *in_file, char *out_file) {
    //音频采样率
    uint32_t in_sampleRate = 0;
    //总音频采样数
    uint64_t totalSampleCount = 0;
    int16_t *data_in = wavRead_int16(in_file, &in_sampleRate, &totalSampleCount);
    uint32_t out_sampleRate = in_sampleRate * 2;
    uint32_t out_size = (uint32_t) (totalSampleCount * ((float) out_sampleRate / in_sampleRate));
    int16_t *data_out = (int16_t *) malloc(out_size * sizeof(int16_t));
    //如果加载成功
    if (data_in != NULL && data_out != NULL) {
        resampleData(data_in, in_sampleRate, (uint32_t) totalSampleCount, data_out, out_sampleRate);
        wavWrite_int16(out_file, data_out, out_sampleRate, (uint32_t) out_size);
        free(data_in);
        free(data_out);
    } else {
        if (data_in) free(data_in);
        if (data_out) free(data_out);
    }
}

让我们稍微变通一下,设一个采样速率,用来调节声音的速度,同时保证采样率不变。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void resampler(char *in_file, char *out_file) {
    //音频采样率
    uint32_t in_sampleRate = 0;
    //总音频采样数
    uint64_t totalSampleCount = 0;
    int16_t *data_in = wavRead_int16(in_file, &in_sampleRate, &totalSampleCount);
    float speed = 0.88;//增加一个速度权重
    uint32_t out_sampleRate = in_sampleRate * speed;
    uint32_t out_size = (uint32_t) (totalSampleCount * ((float) out_sampleRate / in_sampleRate));
    int16_t *data_out = (int16_t *) malloc(out_size * sizeof(int16_t));
    //如果加载成功
    if (data_in != NULL && data_out != NULL) {
        resampleData(data_in, in_sampleRate, (uint32_t) totalSampleCount, data_out, out_sampleRate);
        //out_sampleRate改为输出一样的采样率in_sampleRate
        wavWrite_int16(out_file, data_out, in_sampleRate, (uint32_t) out_size);
        free(data_in);
        free(data_out);
    } else {
        if (data_in) free(data_in);
        if (data_out) free(data_out);
    }
}

修改后是这个样子的。

有心的朋友发现了。out_size数值有可能增大或缩小了。

以上示例代码,就是一个简单的变速算法。

变速就是这么一个原理,音量增大降低就不做示例了。

而变声是一个什么算法呢?

说白了,就是变速的同时保证out_size还是原来的totalSampleCount。

那要怎么保证呢?

答案就是插值,如果简单粗暴一点,补0或者删0即可。

当然这样做的话,可能会导致音量不一致,最终发声不对的情况。

这肯定是不科学的,最终的插值时候的权重和对应的内容,产生的效果就看各家本领了。

以上原理,也说得差不多了,具体怎么实现的话,

大家自行参阅相关的开源代码,再去理解一下。

另外说一下前面《声音变调算法PitchShift(模拟汤姆猫) 附完整C++算法实现代码》

这篇文章中的sin和cos 没有在有效区间内,所以fastsin fastcos计算的结果是有问题的。

详情大家还是参阅作者原算法吧。

当然,后面有时间我会放出,

简单清晰的变声算法的完整c代码和对应的示例代码。

而关于基于傅里叶变换的重采样算法,《基于傅里叶变换的音频重采样算法 (附完整c代码)》

在对应的github 项目fftResample上,我也做了算法逻辑上的修正。

发表过的文章一般很少进行二次编辑了,

关于后期的一些修正和变更,大家还是关注一下github项目的更新比较直接一点。

具体变声的实现原理,

如上所述,希望通过这篇文章,

大家对音频变声算法能有比较直观的理解和认识。

以上,权当抛砖引玉。

独乐乐不如一起玩乐。

若有其他相关问题或者需求也可以邮件联系俺探讨。

邮箱地址是:  gaozhihan@vip.qq.com

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
WebRTC 音频采样算法 附完整C++示例代码
之前有大概介绍了音频采样相关的思路,详情见《简洁明了的插值音频重采样算法例子 (附完整C代码)》。 音频方面的开源项目很多很多。 最知名的莫过于谷歌开源的WebRTC, 其中的音频模块就包含有  AGC自动增益补偿(Automatic Gain Control) 自动调麦克风的收音量,使与会者收到一定的音量水平,不会因发言者与麦克风的距离改变时,声音有忽大忽小声的缺点。 ANS背景噪音抑制(Automatic Noise Suppression) 探测出背景固定频率的杂音并消除背景噪音。 AEC是回声消除器
cpuimage
2018/04/24
4.4K0
基于RNN的音频降噪算法 (附完整C代码)
前几天无意间看到一个项目rnnoise。 项目地址: https://github.com/xiph/rnnoise 基于RNN的音频降噪算法。 采用的是 GRU/LSTM 模型。 阅读下训练代码,可惜的是作者没有提供数据训练集。 不过基本可以断定他采用的数据集里,肯定有urbansound8k。 urbansound8k 数据集地址: https://serv.cusp.nyu.edu/projects/urbansounddataset/urbansound8k.html 也可以考虑采用用作者训练的模型
cpuimage
2018/04/12
9.4K0
简洁明了的插值音频重采样算法例子 (附完整C代码)
近一段时间在图像算法以及音频算法之间来回游走。 经常有一些需求,需要将音频进行采样转码处理。 现有的知名开源库,诸如: webrtc , sox等, 代码阅读起来实在闹心。 而音频重采样其实也就是插值算法。 与图像方面的插值算法没有太大的区别。 基于双线性插值的思路。 博主简单实现一个简洁的重采样算法, 用在对采样音质要求不高的情况下,也是够用了。 编解码库采用dr_wav https://github.com/mackron/dr_libs/blob/master/dr_wav.h  近期有点强迫症,纯c
cpuimage
2018/04/12
5.1K0
音频自动增益 与 静音检测 算法 附完整C代码
静音检测 在WebRTC中 是采用计算GMM (Gaussian Mixture Model,高斯混合模型)进行特征提取的。
cpuimage
2018/05/07
3.9K0
音频降噪算法 附完整C代码
音频降噪目前感觉大有所为,像前面分享的《基于RNN的音频降噪算法 (附完整C代码)》
cpuimage
2018/05/07
9.5K5
mp3格式转wav格式 附完整C++算法实现代码
近期偶然间看到一个开源项目minimp3 Minimalistic MP3 decoder single header library 项目地址: https://github.com/lieff/minimp3 单文件头的最小mp3解码器。 一直很想抽时间好好看上一看。 最好的学习方式就是写个实用性的工程项目。 例如实现mp3转wav格式。 嗯,这篇博文就是这么来的。 阅读了下minimp3的源码,有一两处小bug, 这个解码算法可以进一步提速优化的地方还有不少。 后面有时间,再好好庖丁解牛。 基于这个库
cpuimage
2018/04/12
3.1K0
音频算法之小黄人变声 附完整C代码
前面提及到《大话音频变声原理 附简单示例代码》与《声音变调算法PitchShift(模拟汤姆猫) 附完整C++算法实现代码》
cpuimage
2018/09/22
3.3K0
音频压缩编码 opus 附完整C++代码示例
绝大数人都知道mp3格式编码,以及aac,amr等压缩格式编码。 而在语音通信界有一个强悍的音频格式编码opus. 经过实测,压缩比最高可以达到1:10。 100KB 压缩后 10KB 虽然是有损压缩, 但是根据实际对比试听, 几乎听不出差别。 而且还原度还比mp3高,压缩比也比mp3高。 用来压缩传输音频,绝对是一大杀器。 项目官方地址: https://opus-codec.org/ 维基上的描述: Opus是一个有损声音编码的格式,由Xiph.Org基金会开发,之后由互联网工程任务组(IETF)进行标
cpuimage
2018/04/23
3.8K0
分享用于学习C++音频处理的代码示例
与《分享用于学习C++图像处理的代码示例》为姊妹篇。 为了便于学习C++音频处理并研究音频算法, 俺写了一个适合初学者学习的小小框架。 麻雀虽小五脏俱全,仅仅考虑单通道处理。 采用Decoder an
cpuimage
2018/04/12
2.6K0
分享用于学习C++音频处理的代码示例
前端音频合成
AudioContext 属于 Web Audio 中的一个 API,创建音频你可以使用
上山打老虎了
2022/06/15
1.7K0
前端音频合成
音频增益响度分析 ReplayGain 附完整C代码示例
人们所熟知的图像方面的3A算法有: AF自动对焦(Automatic Focus) 自动对焦即调节摄像头焦距自动得到清晰的图像的过程 AE自动曝光(Automatic Exposure) 自动曝光的是为了使感光器件获得合适的曝光量 AW自动白平衡(Automatic White Balance) 白平衡的本质是使白色物体在任何光源下都显示白色 与之相对应的音频方面的3A算法是: AGC自动增益补偿(Automatic Gain Control) 自动调麦克风的收音量,使与会者收到一定的音量水平,不会因发言者
cpuimage
2018/04/16
2K0
shazam音乐检索算法 附完整c代码
https://laplacian.wordpress.com/2009/01/10/how-shazam-works/
cpuimage
2018/08/07
2K0
音频编码(一)——FFmpeg编码
这里为啥讲到了声波,讲到了我们的中学物理上的知识,因为我想大家能从根本理解后面音频编码的各种参数以及原因。当然这些知识网上都能搜到,我只是整合一下。
用户2929716
2018/08/23
5.8K0
音频编码(一)——FFmpeg编码
MP3 编码解码 附完整c代码
图像方面,已经有stb_image,spot,freeimage等编解码库系列,做得特别赞。
cpuimage
2018/08/05
2.2K0
libsonic的原理介绍与应用
在音频处理的时候常常会涉及到音频的变速、变调等方面的操作,使用的场景比较广泛如汤姆猫、男声变女声等,此外某些应用场合下的低延迟的播放器,往往也需要涉及到这方面的处理。目前常用的库是libsonic与libsoundtouch,两者的不同之处主要在于使用的算法上的差异,libsonic主要是使用的基于基音的变速处理,而libsoundtouch则主要基于的是波形相似的原理,在变速处理上libsonic对人声的处理更为优秀,而soundtouch对音乐等场景则更为适合。这里对libsonic的原理、使用介绍包括源代码等做一个分析和介绍。
frankqpfu
2018/08/22
2.9K0
NDK--利用FFmpeg进行音频解码
1.WAV编码 特点:音质非常好,大量软件都支持。 适用场合:多媒体开发的中间文件、保存音乐和音效素材。 2.MP3编码 特点:音质在128Kbit/s以上表现还不错,压缩比比较高,大量软件和硬件都支持,兼容性好。 适用场合:高比特率下对兼容性有要求的音乐欣赏。 3.AAC编码 特点:在小于128Kbit/s的码率下表现优异,并且多用于视频中的音频编码。 适用场合:128Kbit/s以下的音频编码,多用于视频中音频轨的编码。 4.Ogg编码 特点:可以用比MP3更小的码率实现比MP3更好的音质,高中低码率下均有良好的表现,兼容性不够好,流媒体特性不支持。 适用场合:语音聊天的音频消息场景。
aruba
2020/07/02
7060
iOS音频能力提升——PCM基础
前言 音频是移动端很重要的能力,像直播类、在线教育类、唱歌类、短视频类等APP,都离不开音频功能。 具备音频相关知识与能力,对未来的职业发展有很大优势。 本文主要围绕音频知识的基础——PCM,介绍PCM的原理和相关操作。 声音是模拟的连续信号,而计算机只能离散的存储。为了使得计算机具备音频的能力,必须支持连续音频信号的离散化描述,而PCM具备这个能力。 正文 PCM脉冲编码调制(Pulse Code Modulation) 脉冲编码调制就是把一个时间连续,取值连续的模拟信号变换成时间离散,取值离散的数
落影
2018/04/27
2.7K0
iOS音频能力提升——PCM基础
音频基础知识
Nyquist 采样率大于或等于连续信号最高频率分量的 2 倍时,采样信号可以用来完美重构原始连续信号。
Gnep@97
2023/09/06
3.5K0
音频基础知识
声音变调算法PitchShift(模拟汤姆猫) 附完整C++算法实现代码
上周看到一个变调算法,挺有意思的,原本计划尝试用来润色TTS合成效果的。 实测感觉还需要进一步改进,待有空再思考改进方案。 算法细节原文,移步链接: http://blogs.zynaptiq.com/bernsee/pitch-shifting-using-the-ft/ C++开源的项目,比较老的一个项目了。 源码下载地址: http://blogs.zynaptiq.com/bernsee/download/ 本人对这份算法源码进行简单的优化调整。 稍微提升了一点性能。 修改后的完整代码: /****
cpuimage
2018/04/12
2.3K0
FFmpeg进行音频的解码和播放
上一篇FFmpeg 内容介绍 音视频解码和播放 介绍了FFmpeg进行解码的常见函数和,解码的过程。相关的函数介绍忘记了,可以参考上一篇。
包子388321
2020/07/27
6.6K2
相关推荐
WebRTC 音频采样算法 附完整C++示例代码
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验