2017-03-07 60 views
1

作为一项学习练习,我试图实现一个Java类,它能够根据另一个音频效果文件应用一些语音变化。音频信号调制产生语音变化效果

E.G.比方说,我有一个音频样本,用来说出“hello world”和另一个“呼吸噪音”的音频样本,我想用噪音来调节声音,以达到类似于“达斯维达”效果的效果。

谷歌搜索了一下,我发现这可以通过使用频率调制来实现,所以我的第一个疑问是:频率调制是我的问题的正确答案? (我不想意识到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功能的最好和最有效的方式?它会用于我的目的吗?

+0

我发现我正在寻找的特定调制可能是环形调制。那是对的吗? – ChaSIem

回答

0

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

的主要思想是像 “颤音” 的效果,通过简单地将信号数字阵列乘以颤音变化,即:

H [I] = inner_product(C [1],M [I])

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

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

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