使用octave / matlab代码逐渐/逐渐改变信号的音高

时间:2017-06-22 11:45:19

标签: matlab signal-processing fft octave pitch-shifting

我可以使用重新采样来移动整个信号并尝试相位声码器代码 here

我也试过repmat and interpolation,然后我调查了fft and interp1

我如何逐步/逐渐改变信号的音高?我已经包含了Original Signal的一个示例以及我想要获得的内容Processed Signal听起来像(我使用Audacity创建处理过的信号并使用它们的效果Sliding time scale / pitch shift)但是想在Octave 4.0中创建这个信号。 如果您收听Processed Signal,您可以听到文件的音高逐渐增加,但文件的长度({秒})与Original Signal文件相同。

我使用Octave 4.0,就像Matlab

这里的代码可以改变整个信号的音高,并在几秒钟内保持原始信号的相同长度,但我不知道如何让它逐渐改变信号的音高随着时间的推移。谢谢rayryeng让我这么远。

clear, clc
[ya, fs, nbitsraw] = wavread('/tmp/original_signal.wav');

num_per_sec=2.4; %// Define total number of times we see the signal

%// Get total number of integer times we see the signal
num_whole = floor(num_per_sec);

%// Replicate signal
yb=repmat(ya,num_whole,1);

%// Determine how many samples the partial signal consists of
portion = floor((num_per_sec - num_whole)*length(ya));

%// Sample from the original signal and stack this on top of replicated signal
yb = [yb; ya(1:portion)];

%interpolation
xxo=linspace(0,1,length(yb))'; 
xxi=linspace(0,1,length(ya))'; 
yi_t=interp1(xxo,yb,xxi,'linear');

wavwrite([yi_t'] ,fs,16,strcat('/tmp/processed_signal.wav'));  % export file

1 个答案:

答案 0 :(得分:6)

我的回答并没有给出与你发布的结果完全相同的结果,但我认为它很有趣也很简单,可以为你提供音高拉伸背后的重要概念。我还没有找到我在网上其他地方提出的方法,但我无法想象以前没有人想过这个,所以它可能有一个名字。

首先要意识到的是,如果你想将变换应用于音高随着时间的推移,而不仅仅是在整个时间段上对其进行偏移,你需要使用音高“特征”定义在每个时间点(例如时间 - 频率变换),而不是总结整个信号内容的那些(例如傅立叶)。

重要的是要意识到这一点,因为很明显我们需要涉及信号的瞬时频率之类的事情,这是Hilbert阶段的导数defined as(通常采用如(1/2Pi) * dPhi/ dt以Hz而不是rad / s工作。

假设我们可以转换信号的瞬时频率,我们可以将“递增地增加音高”的概念正式转换为“向瞬时频率添加线性增加的偏移量”。 好消息是,我们可以使用analytic transform非常轻松地转换信号的瞬时频率。方法如下:

function y = add_linear_pitch( x, fs, df )
%
% y = add_linear_pitch( x, fs, df )
%
% x, fs: audio signal (1-dimensional)
% df: the amplitude of frequency offset, in Hz
%
% See also: hilbert
%

    x = x(:);
    n = numel(x); % number of timepoints
    m = mean(x); % average of the signal
    k = transpose(0:n-1); 

    h = hilbert( x - m ); % analytic signal
    e = abs(h); % envelope
    p = angle(h) + df*pi*k.^2/fs/n; % phase + linearly increasing offset
    y = m - imag(hilbert( e .* sin(p) )); % inverse-transform

end

前面代码中唯一不明显的事情是我们需要在将其应用到相位之前对“线性增加的音调偏移”(或瞬时频率的任何变换)进行积分,并将其乘以{{1} (以弧度工作)。在我们的例子中,线性函数的积分只是一个二次函数,但你可以玩更复杂的东西:)