0

我的小组正在开发一个简单的 MATLAB 图形用户界面 (GUI),它应该记录来自麦克风的音频 - 插入或内置到计算机中 - 并播放信号。到目前为止,我们已经完成了。我们的 GUI 还可以加载样本(.wav 文件等)并使用 GUI 上相同的“播放”按钮进行播放。我们有一个播放、录制、加载和保存按钮。现在对于加载或记录的样本的音高偏移......我们知道我们需要一个峰值拾取算法来找到信号的基本频率。然后我们认为我们可以将这些值中的每一个乘以一个常数来改变所有这些频率的音高。我们的目标是使用这个算法并将单独的班次分配给不同的按钮或单选按钮,我们可以在其中加载我们的样本,按下按钮并通过这样做来操纵音高,然后播放。使用峰值拾取算法会充分改变我们信号的音高,还是会在播放过程中搞砸信号?

(这不是实时处理)

4

3 回答 3

4

正如我在上面的评论中提到的,您可以使用两种方法,相位声码器或更高的采样率。第一种方法,使用声码器将保持信号长度,同时将包含的频率移得更高。我不打算详细介绍如何执行此操作的算法,但哥伦比亚大学对此公开提供了代码 - http://www.ee.columbia.edu/ln/labrosa/matlab/pvoc/

第二种方法是简单地将 *.wav 文件写入更高的采样率。

假设您有一个 440 Hz 的信号,您想要 880 Hz,只需将采样率加倍即可。

所以不要说wavwrite(signal,fs,'file'),使用wavwrite(signal,2*fs,'file')

但是,这将通过您增加采样率的任何因素来缩短音频文件的长度。

总的来说,我认为更好、更令人印象深刻的方法是声码器,我不建议只是盲目地使用哥伦比亚的代码,而是要花时间去理解它并能够用数学方式解释它背后的逻辑

于 2013-11-19T16:23:16.167 回答
3

比 Columbia 算法更简单的东西(性能不高,但可能会让您了解它的工作原理)会是这样的:

  1. 采取 FFT
  2. 用于interp1以更高的采样率重新采样 FFT;例如,要上移 1 个全音符(2 个半音符),您可以这样做

F1 = fft(originalSignal);
N = numel(F1);
F1a = F1(1:N/2);         % the lower half of the fft
F1b = F1(end:-1:N/2+1);  % the upper half of the fft - flipped "the right way around"
t1 = 1:N/2;              % indices of the lower half
t2 = 1+ (t1-1) / (1 + 2.^(2/12)); % finer sampling... will make peaks appear higher
F2a = interp1(t1, F1a, t2); % perform sampling of lower half
F2b = interp1(t1, F1b, t2); % resample upper half
F2 = [F2a F2b(end:-1:1)];   % put the two together again
shiftedSignal = ifft(F2);   % and do the inverse FFT

我没有做任何窗口等,所以这是“近似的”。实际上,您希望一次处理一个重叠的小数据块,而不是一次处理整个文件。因此,以上内容应该被认为是“仅用于说明”,而不是工作代码。

于 2013-11-19T17:52:29.923 回答
0

Pitch Shift 的一个重要特征是改变音高而不改变声音的速度,如果你改变采样率,你的速度就会改变,你需要重新采样你的信号。

如果你的麦克风输入总是单声道的,你应该考虑PSOLA方法,工作在时域,你可以在语音信号中得到很好的结果

于 2013-11-19T23:36:57.137 回答