随时间以对数/指数方式改变输入信号的音高

时间:2017-07-14 14:27:28

标签: matlab signal-processing octave exponential natural-logarithm

如何随时间以对数/指数方式更改导入信号的音高?

请注意,将要使用的导入信号不是单一频率,因此简单的扫描或啁啾命令将无法工作,因为我将导入声音音频文件,我刚刚创建了以下示例,因此它们可以正常工作并且可以测试/显示我遇到的问题。

我可以随时间线性改变信号的音高,这可以很好地看到下面的测试代码和频率图的第1部分。感谢Sheljohn的代码

%Sweep question part 1
clear all,clf reset,tic,clc 
pkg load signal  %load packages

%%%----create signal
start_freq=500;
end_freq=20;
fs=22050
len_of_sig=7; %in seconds
t=linspace(0,2*pi*len_of_sig,fs*len_of_sig);
orig_sig1=.8*sin(start_freq*t);
wavwrite([orig_sig1(:)] ,fs,16,strcat('/tmp/0_sig.wav'));  % export file

%%%---import signal
[ya, fs, nbitsraw] = wavread('/tmp/0_sig.wav');

orig_total_samples=length(ya); %make this the same length as signal wave
t_import=linspace(0,2*pi*(orig_total_samples/fs),orig_total_samples);

%%%%----Begin linsweep 
x = ya(:);
fac=(end_freq-start_freq)/length(x); %linear slope

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

h = hilbert( x - m ); % analytic signal
env1 = abs(h); % envelope
sweep=fac*pi*k.^2/(fs); %linearly increasing offset original %alter curve here
p = angle(h) + sweep; % phase + linearly increasing offset original

y = m - imag(hilbert( env1 .* sin(p) )); % inverse-transform
wavwrite([y(:)] ,fs,16,strcat('/tmp/0_sweep.wav'));  % export file

%%%----------Used for plotting
z = hilbert(y);
instfreq = fs/(2*pi)*diff(unwrap(angle(z))); %orginal
t_new=t_import/(2*pi); %converts it to seconds

plot(t_new(2:end),instfreq,'-r')

xlabel('Time (secnds)')
ylabel('Frequency (Hz)')
grid on
title('Instantaneous Frequency')

Linear Plot

以下代码的问题是:

1)频率不以正确的频率开始或结束。

2)它没有正确的斜率

我认为它与变量 fac 扫描有关。我只是不确定如何正确计算它们。

fac=log(start_freq/end_freq)/length(x); %slope
sweep=-(start_freq)*exp(fac*k); %alter curve here

-

%-----------------Sweep question part 2
clear all,clf reset,tic,clc 
pkg load signal  %load packages

%%%----create signal
start_freq=500;
end_freq=20;
fs=22050
len_of_sig=7; %in seconds
t=linspace(0,2*pi*len_of_sig,fs*len_of_sig);
orig_sig1=.8*sin(start_freq*t);
wavwrite([orig_sig1(:)] ,fs,16,strcat('/tmp/0_sig.wav'));  % export file

%%%---import signal
[ya, fs, nbitsraw] = wavread('/tmp/0_sig.wav');

orig_total_samples=length(ya); %make this the same length as signal wave
t_import=linspace(0,2*pi*(orig_total_samples/fs),orig_total_samples);

%%%%----Begin linsweep 
x = ya(:);
fac=log(start_freq/end_freq)/length(x); %slope

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

h = hilbert( x - m ); % analytic signal
env1 = abs(h); % envelope
sweep=-(start_freq)*exp(fac*k); %alter curve here
p = angle(h) + sweep; % phase +  increasing offset

y = m - imag(hilbert( env1 .* sin(p) )); % inverse-transform
wavwrite([y(:)] ,fs,16,strcat('/tmp/0_sweep.wav'));  % export file

%%%----------Used for plotting
z = hilbert(y);
instfreq = fs/(2*pi)*diff(unwrap(angle(z))); %orginal
t_new=t_import/(2*pi); %converts it to seconds

plot(t_new(2:end),instfreq,'-r')

xlabel('Time (seconds)')
ylabel('Frequency (Hz)')
grid on
title('Instantaneous Frequency')

Incorrect frequency and slope

我想要获得的斜率是当起始频率从500hz开始并达到20hz时。当起始频率从20hz开始并达到500hz时。请参见下面的图表:注意:这些频率会发生变化,因此我正在尝试获取正确的公式/公式,以便在需要时计算这些斜率。

500hz to 20hz

20hz to 500hz

Ps:我使用的是Octave 4.0,类似于Matlab。

请注意,将要使用的导入信号不是单一频率,因此简单的扫描或啁啾命令将无法工作,因为我将导入声音音频文件,我刚刚创建了以下示例,因此它们可以正常工作并且可以测试/显示我遇到的问题。

1 个答案:

答案 0 :(得分:0)

通过对代码进行以下更改,我可以使扫描看起来像您感兴趣的绘图。其中一些只是为了我的缘故(例如我喜欢我的时间变量以整数秒为单位)。

desired slope

相关变化:
从:

 t=linspace(0,2*pi*len_of_sig,fs*len_of_sig);
 orig_sig1=.8*sin(start_freq*t);
 fac=log(start_freq/end_freq)/length(x); %slope

致:

t=linspace(0,len_of_sig,fs*len_of_sig);
orig_sig1=0.8*sin(start_freq*t*2*pi);    
fac=log(end_freq/start_freq)/length(x);
sweep=(start_freq*2*pi/fs)*exp(fac*k); %alter curve here 

这是我做的其他一些改变,

y = env1.*sin(p);      
% and later for consistency
t_import=linspace(0,orig_total_samples/fs,orig_total_samples);
t_new=t_import; %t is seconds

在我看来,fac将与您的开始和结束有所不同,因此它将是:log(endFreq)-log(startFreq)log(endFreq/startFreq),其长度会有额外的标准化。这可以在前面用负号翻转。

当您使用它来计算p=angle(h)+sweep; angle(h)以弧度为单位时,可能会发生扫描的一个问题。

弧度与Hz单位问题可能会造成一些困难。