2017-06-22 23 views
6

我可以使用resample對整個信號進行音高移位,並嘗試了相位聲碼器代碼here使用倍頻程/ matlab代碼隨時間遞增/逐漸改變信號音調

我也試過repmat and interpolation,我看着fft and interp1

我怎樣才能逐步/逐步改變信號的音高隨着時間的推移?我已經包含了一個Original Signal的示例,我試圖讓Processed Signal聽起來像(我使用Audacity創建了處理後的信號並使用其效果Sliding time scale/pitch shift)但是想要在Octave 4.0中創建此信號。 如果您聆聽Processed Signal,則可以聽到文件的音高逐漸增加,但該文件與Original Signal文件的長度(秒)相同。

我使用倍頻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 
+0

既然你似乎有興趣爲語音信號做這個,那麼你可能想看看分析/重新合成工具,如[PSOLA](https://en.wikipedia.org/wiki/PSOLA)。像這樣的工具應該給予更自然的音高變化。 (請注意,PSOLA相當長 - 現在可能會有更好的選擇。) –

+0

大膽使用[sbsms](https://sourceforge.net/projects/sbsms/)用於Subband Sinusoidal Modeling的庫。如果你想要你可以重寫所有的MATLAB/Octave,或者你可以編譯它並將它用作mex/oct – rahnema1

回答

6

我的回答不會給完全相同的結果,你張貼的,但我認爲這是有趣的,很簡單,給你的重要概念背後的間距拉伸。我還沒有找到我在網上其他地方提出的方法,但我無法想象之前沒有人想到這個,所以它可能有一個名字。

實現的第一件事是,如果你想隨着時間的推移來轉換應用到俯仰,而不是僅僅抵消它在整個時間過程,你需要的是在每個定義間距「功能」工作時間點(例如時間頻率變換),而不是總結整個信號內容(例如傅立葉)的那些。

意識到這一點,因爲它變得很明顯,我們需要涉及到的東西像你的信號,這是defined as瞬時頻率希爾伯特階段(通常作爲(1/2Pi) * dPhi/ dt的導數以Hz工作,而不是很重要弧度/秒)。

假設我們可以改變一個信號的瞬時頻率,我們就可以的「增加音高增量」的思想翻譯成正式「添加線性增加偏移量的瞬時頻率」。 好消息是,我們可以使用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 

在前面的代碼中的唯一非明顯的一點是,我們需要把它應用到階段之前的「線性增加傾角補償」(或任何瞬時頻率的變換)整合,並乘以2Pi(以弧度工作)。在我們的例子中,線性函數的積分只是一個二次函數,但你可以玩更復雜的東西:)

+0

這真的很高雅,如果我想以某個頻率結束,是否有任何方法可以計算出正確的斜率?例如,如果原始歌唱聲信號的最大共振頻率爲326.8hz,我希望它以402.3hz結束? –

+1

我認爲這是可能的,它應該僅取決於頻率(delta-y)和信號長度(delta-x)的差異。我很忙,但我會考慮更多,並在幾天內編輯我的帖子。 – Sheljohn

+0

我在數學部分發布了這個問題,這個公式有用嗎? https://math.stackexchange.com/posts/comments/4816923?noredirect=1 –