MATLAB - 音高转换音频信号

Posted

技术标签:

【中文标题】MATLAB - 音高转换音频信号【英文标题】:MATLAB - Pitch Shifting an Audio Signal 【发布时间】:2013-11-19 15:59:24 【问题描述】:

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

(这不是实时处理)

【问题讨论】:

音高转换可以通过几种方式实现,您可以改变信号的相位,也可以下采样但继续以更高的采样率播放。第一个选项不会扭曲时间,但第二个会 第一种方法称为相位声码。 Phase Vocoder 【参考方案1】:

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

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

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

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

但是,无论您提高采样率的任何因素,这都会缩短音频文件的长度。

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

【讨论】:

代码已公开 : Page not found 找不到请求的页面。 我认为是这个(新网址,不能再编辑之前的评论了..):ee.columbia.edu/~dpwe/resources/matlab/pvoc【参考方案2】:

比哥伦比亚算法简单一点(性能不高,但可能让您了解它的工作原理)会是这样的:

    参加 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

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

【讨论】:

我以前从未尝试过这个,但肯定 +1 可以向我介绍一些稍微不同的东西。 我不喜欢把死者从坟墓里带回来,但这里的重采样可能有问题。用于生成插值的新时间点的行似乎不适合将音高移动 1 个全音。应该是:t2 = t1/2^(2/12);【参考方案3】:

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

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

【讨论】:

以上是关于MATLAB - 音高转换音频信号的主要内容,如果未能解决你的问题,请参考以下文章

MATLAB之图像与音频信号处理

使用自相关算法从语音信号中估计音高

怎么用MATLAB进行两个语音信号.wav文件的卷积混合?

使用 Swift 使用 AVAudioEngine 实时进行音高转换

Matlab信号处理基础

Matlab 音频信号处理