Постепенно / постепенно изменять шаг сигнала с течением времени с помощью кода octave / matlab

Я могу сдвинуть весь сигнал с помощью resample, и я попробовал код фазового вокодера здесь.

Я также пробовал repmat и интерполяции и я заглянул в fft и interp1

как я могу постепенно / постепенно изменять высоту сигнала с течением времени? Я включил пример Исходный Сигнал и что я пытаюсь получить обрабатывается Сигнал чтобы звучать как (я создал обработанный сигнал, используя Audacity и используя их эффект Sliding time scale / pitch shift) но хотел бы создать этот сигнал в Октаве 4.0. Если вы слушаете Обработанный Сигнал вы можете услышать каждый шаг файл постепенно увеличивается, но файл такой же длины (в секундах) в качестве Исходный Сигнал.

Я использую Октаву 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 ответов


мой ответ не дает точно такой же результат, как тот, который вы опубликовали, но я думаю, что это интересно и достаточно просто, чтобы дать вам важные концепции растяжки питча. Я не нашел метода, который предлагаю в интернете, но я не могу представить, что никто не думал об этом раньше, поэтому у него может быть название.

первое, что нужно понять, это то, что если вы хотите применить преобразования к шагу со временем, а не просто компенсировать это по всей конечно, вам нужно работать с шаговыми "функциями", которые определены в каждый момент времени-точке (например, частотно-временные преобразования), в отличие от тех, которые суммируют все содержимое сигнала (например, Фурье).

важно понять это, потому что становится очевидным, что нам нужно задействовать такие вещи, как мгновенная частота вашего сигнала, который определяется как производная фазы Гильберта (обычно берется как (1/2Pi) * dPhi/ dt для работы В Гц вместо рад/с).

предполагая, что мы можем преобразовать мгновенную частоту сигнала, мы можем затем перевести идею"увеличение шага постепенно" официально в "добавление линейно увеличивающегося смещения к мгновенной частоте". И хорошая новость заключается в том, что мы можем преобразовать мгновенную частоту сигнала довольно легко, используя аналитические преобразования. Вот как:

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 (для работы в радианах). В нашем случае Интеграл линейной функции является просто квадратичной функцией, но вы можете играть с более сложными вещами:)