Постепенно/постепенно меняйте высоту сигнала с течением времени, используя код октавы/матлаба

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

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

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

Я использую 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

person Rick T    schedule 22.06.2017    source источник
comment
Поскольку вы, кажется, заинтересованы в том, чтобы сделать это для речевых сигналов, вы можете рассмотреть инструменты анализа/ресинтеза, такие как ПСОЛА. Подобные инструменты должны давать гораздо более естественное изменение высоты тона. (Обратите внимание, что PSOLA довольно давно в зубах - в наши дни могут быть лучшие альтернативы.)   -  person Paul R    schedule 22.06.2017
comment
Audacity использует библиотеку sbsms для моделирования синусоидальных поддиапазонов. Если вы хотите, вы можете переписать все в MATLAB/Octave или вы можете скомпилировать его и использовать как mex/oct   -  person rahnema1    schedule 24.06.2017


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

person Jonathan H    schedule 24.06.2017