惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - Franky
N
Netflix TechBlog - Medium
宝玉的分享
宝玉的分享
Google DeepMind News
Google DeepMind News
腾讯CDC
G
Google Developers Blog
Martin Fowler
Martin Fowler
Microsoft Security Blog
Microsoft Security Blog
Recent Announcements
Recent Announcements
爱范儿
爱范儿
Engineering at Meta
Engineering at Meta
Microsoft Azure Blog
Microsoft Azure Blog
A
About on SuperTechFans
aimingoo的专栏
aimingoo的专栏
有赞技术团队
有赞技术团队
Jina AI
Jina AI
人人都是产品经理
人人都是产品经理
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
M
MIT News - Artificial intelligence
罗磊的独立博客
博客园 - 三生石上(FineUI控件)
美团技术团队
WordPress大学
WordPress大学
阮一峰的网络日志
阮一峰的网络日志

博客园 - cpuimage

AIGC图像困局 深度学习优化器算法巧思速览 lora训练之偷师 大话AI绘画技术原理与算法优化 Tensorflow2 深度学习十必知 自 TensorFlow 2.6 起,修正IDE代码自动补全失效的方法 开源发丝分割数据集CelebAHairMask-HQ(国庆献礼) 博文大纲 文字渲染一探 磨皮美颜算法 附完整C代码 Windows下C,C++开发环境搭建指南 一种简单高效的音频降噪算法示例(附完整C代码) 算法踩坑小记 音频算法之我思 wav2midi 音乐旋律提取算法 附可执行demo 图像去模糊算法 循序渐进 附完整代码 音频识别算法思考与阶段性小结 大话音频变声原理 附简单示例代码 c语言智能指针 附完整示例代码
音频算法之小黄人变声 附完整C代码
cpuimage · 2018-09-22 · via 博客园 - cpuimage

前面提及到《大话音频变声原理 附简单示例代码》与《声音变调算法PitchShift(模拟汤姆猫) 附完整C++算法实现代码

都稍微讲过变声的原理和具体实现。

大家都知道,算法从实现到最后工程应用,中间的环节和问题特别多。

尤其是编码的架构设计,好的数据结构和代码逻辑封装肯定是可复用,组件化的。

前几天写完《音频识别算法思考与阶段性小结》的时候,

我也提及到了。

会做一些算法编码优化相关的分享。

而有时候我总觉得文字表达很苍白,

所以我尽可能地把代码写得简洁易懂,

一方面是便于基础差的朋友学习。

另一方面也是为了自己在编码以及思考的时候,能更加清晰。

当然,变声算法绝大多数朋友都会选择一些开源的或者商业sdk去做二次开发。

例如:

https://www.fmod.com/

https://www.surina.net/soundtouch/

但如果仅仅停留在使用的阶段,它就是一个黑盒子。

知其然,却不知其所以然。

是远远不够的。

有时候我们是要站在巨人的肩膀上去看到更美丽的风景。

但是,我希望是一群人,而不是一个人。

也许大家也发现了,我写的大多数算法,是纯c无第三方依赖的。

是不是就会怀疑,我就只会写c语言?

不是的,我所掌握的编程语言:

主要: c,c++,python,汇编 

其次:pascal,c#,js,lua,go等

编程语言只是一个工具,关键还是算法思路。

用纯c写的主要目的,是为了破除一些第三方依赖,

不要一知半解地使用黑盒子。

当然,其次的好处就是跨平台,便携,可复用。

这样,一切了然于心。

为什么不可以造轮子呢?

只要你造的轮子是有用的,

不管是用于观赏用于学习还是其他用途。

在我了解到一些音频算法的思路之后,

变声算法的思路,

我觉得它的思路非常适用于扩展到大多数音频算法实现,

而且可复用度比较高。

所以,将它梳理开源,就显得特别有意义。

而大家可以基于这个实现,进一步去改进或者学习 音频算法,

例如降噪,增益等等。

因为这个编码实现的设计是完全可以适用到音频算法应用场景的。

逻辑也非常清晰。

项目地址:

https://github.com/cpuimage/pitchshift

当然为了便于一些朋友的学习使用,

示例代码提供一个简易的实现,

模拟变声为小黄人。

int main(int argc, char *argv[]) {
    printf("Audio Processing \n");
    printf("blog:http://cpuimage.cnblogs.com/ \n");
    printf("Pitch Shifting Using The Fourier Transform\n");

    if (argc < 2)
        return -1;

    char *in_file = argv[1];
    uint32_t sampleRate = 0;
    uint64_t totalSampleCount = 0;
    uint32_t channels = 0;
    short *data_in = wavRead_s16(in_file, &sampleRate, &totalSampleCount, &channels);
    if (data_in != NULL) {
        float pitchShift = 0.9f;
        size_t ms = 50;
        size_t overSampling = 4;
        size_t frameSize = sampleRate * ms / 1000;
        frameSize += frameSize % 2;
        planData pitchPlanData = {0};
        double startTime = now();
        makePlanData(frameSize, overSampling, sampleRate, &pitchPlanData);
        pitchshift(pitchShift, data_in, data_in, totalSampleCount, &pitchPlanData);
        // turn to minion pitch
        {
            totalSampleCount /= 2;
            short *samples = data_in;
            for (int i = 0; i < totalSampleCount; i++) {
                data_in[i] = samples[0];
                samples += 2;
            }
        }
        double time_interval = calcElapsed(startTime, now());
        freePlanData(&pitchPlanData);
        printf("time interval: %f ms\n ", (time_interval * 1000));
    }
    char drive[3];
    char dir[256];
    char fname[256];
    char ext[256];
    char out_file[1024];
    splitpath(in_file, drive, dir, fname, ext);
    sprintf(out_file, "%s%s%s_out%s", drive, dir, fname, ext);
    wavWrite_s16(out_file, data_in, sampleRate, totalSampleCount);
    if (data_in) {
        free(data_in);
    }
    printf("press any key to exit.\n");
    getchar();
    return 0;
}

不做多解释,大家可以参阅pitchshift函数的实现,

主要实现位于文件PitchShift.h。

整个算法不到200行,逻辑非常清晰,

已经做了一定程度上的工程化优化。

当然还有很大的改进空间,

不过这份代码,更多的意义在于学习。

授人以鱼不如授人以渔。

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

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