求问音频补码算法,变声成小黄人声音后怎么保证音频时长一致?

问题描述

我是用js实现了简单的采集录音数据进行改造,把采样的数据的偶数位挤压在一起作为输出数据,这样就会导致时长减少了一半。

问题出现的环境背景及自己尝试过哪些方法

找了网上的文章都是说不同的场景有不同的补码算法,但没有说过一个,我根本不知道怎样才能补码成功啊。

我尝试了各种补码方式,可是我搞不懂为什么补上之后又会没有声音了,搞不懂outputData[sample] 与inputData[sample*2]到底是一个怎样的对应关系才能达到我想要的效果呢。

相关代码

var scriptNode = audioctx.createScriptProcessor(4096, 1, 1);

    scriptNode.onaudioprocess = function(audioProcessingEvent) {
    var inputBuffer = audioProcessingEvent.inputBuffer;
    var outputBuffer = audioProcessingEvent.outputBuffer;
    for (var channel = 0; channel < outputBuffer.numberOfChannels; channel++) {
        var inputData = inputBuffer.getChannelData(channel);
        var outputData = outputBuffer.getChannelData(channel);
        // Loop through the 4096 samples
        for (var sample = 0; sample < inputBuffer.length; sample++) {
          if(sample%2==0){
               outputData[sample] = inputData[sample*2];}
           else{
               outputData[sample] = inputData[(sample-1)*2];
          }
        }
      }
    }

你期待的结果是什么?实际看到的错误信息又是什么?

希望大佬们能解释一下outputData到底该填什么样的数据才能达到效果呢,只要能听到小黄人声音保证同样的音频时长就行,感谢🙏

阅读 3.4k
2 个回答

看了你的问题和评论之后,你的实际需求在音频处理被叫做声音基频的修改。

基频的修改在音频处理里是一个很基本的问题,但是没有太简单的方法。常用的比如 PSOLA ,但是需要先做基频的提取,实现起来并不那么简单。

另外插一句,我以前看过汤姆猫的变声结果,它其实没有改基频,而只是将声音通过了一个滤波器。这个实现起来就简单多了,前提是你得知道怎么设计滤波器。

从提问来看,题主对数字信号处理并没有基本概念。你做的只是一个简单重采样的过程(还没考虑aliasing),但是实际上你的需求是变调不变速,这通过简单重采样是不可能做到的,因为重采样之后按照原采样率播放,音调和速度之间是完全耦合的。

你想要的实际上都是通过一些“非传统”的方式去做(当然也有很多年的历史)。变调不变速,或者反过来变速不变调,或者更自由的任意调制音高与速度,大致上有两种技术路线:

  • 完全基于时域处理的OLA方法,比如WSOLA、PSOLA。基本套路就是将输入音频(按照你期望的变速)切成小片,(可能进行变调处理之后)再接回去。
  • 基于时频变换的相位声码器。基本套路是将输入音频(按你期望的变速)切成小片,FFT变换到频域,进行各种骚操作,再逆FFT变回来,然后拼回去。

它们各自都有一些独特的问题,比如PSOLA变换人声音质比较好,因为保留了“共振峰”,听着没有小黄人味,但是必须已知音高,且只能处理单一音高的成分,否则工作不正常。相位声码器由于在频域工作,进行一些频域操作的灵活性非常大,但是合成时的一部分相位细节需要靠“相位锁”获得,音质细节差,有股相位声码器的独特拧巴味。

你要是期望一个可以立即工作的方案,可以看看开源库rubber band

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题