首页 文章

MATLAB - 音高转换音频信号

提问于
浏览
0

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

(这不是实时处理)

3 回答

  • 0

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

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

    假设您有一个440 Hz信号,你想要880赫兹,只需加倍采样率 .

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

    但是,这会缩短音频文件的长度,无论您提高采样率的因素是什么 .

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

  • 3

    比哥伦比亚算法更简单的东西(不是高性能,但可能让你了解它是如何工作的)将会是这样的:

    • 进行FFT

    • 使用 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
    

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

  • 4

    音高转换的强大特性是在不改变声音速度的情况下改变音高,如果更改采样率,则速度会发生变化,您需要重新采样信号 .

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

相关问题