音频信号调制产生变声效果

Audio signal modulation to produce voice changing effects

作为一项学习练习,我正在尝试实现一个 java class,它能够根据另一个音频效果文件应用一些声音变化。

假设我有一个声音样本 "hello world" 和另一个 "breathing noise" 的音频样本,我想用噪声调制声音以实现类似 "Darth Vader" 的效果效果。

谷歌了一下我发现这可以通过使用频率调制来实现,所以我的第一个疑问是:频率调制是我问题的正确答案吗? (我不想实现达斯维德的声音效果,我想让声音听起来像用普通的噪音效果说话)。

假设调频是正确的答案,我试图弄清楚如何在 java 中实现它,结果是这样的:

public void modulate(File voice, File effect, File output) {
   AmplitudeData ampVoice = readAudioFile(voice);
   AmplitudeData ampEffect = readAudioFile(effect);
   FFT fftVoice = FFT(ampVoice);
   FFT fftEffect = FFT(ampVoice);
   FFT fftModulated = FM(fftVoice,fftEffect);
   AmplitudeData ampModulated = IFFT(fftModulated);
   writeAmplitudeToFile(ampModulated, "WAV");
}

我基本上知道如何应用 FFT 和 IFFT,但我仍在寻找任何可能比我的更好的稳定高效的开源代码,所以假设我能够读取音频文件(例如 MP3 ) 转换为幅度表示,然后生成音频文件的 FFT 表示。也可以计算反FFT。

关于 FM(我不是信号处理方面的专家),我找到了使用非常基本的 sin 函数的示例,但没有使用不同载波的示例(即我的噪声效果)。

通过阅读一些论文,我了解到信号屏蔽不是我想要的。例如,要将声音更改为机器人声音或达斯维德效果,我可以在 FFT 上应用一些移动,或一些音高变化,但在这种情况下,我想让声音看起来像是在和另一个人说话声音(例如,想象一把链锯或燃烧的火焰说出类似 hello world 的话)。

所以我的问题是在我的代码中实现 FM 功能的最佳和最有效的方法是什么?它对我有用吗?

解决方案的简化版本似乎是使用调制器信号对载波进行简单的环形调制。

主要思想类似于"tremolo"效果,即通过简单地将信号数字阵列与颤音变化相乘:

h[i] = inner_product(c[i],m[i])

对于每个 i,H 是最终结果,C 是载波,M 是调制器,其中 i 是每个信号的每个数字样本的索引。

在此版本中,信号必须具有相同的长度。

结果可能会受到失真的影响,但对于我的目的来说应该没问题。如果没有人知道更好的解决方案,我认为这将是正确的答案。