【问题标题】:Changing the pitch of a imported signal logarithmically / exponentially over time随时间以对数/指数方式改变导入信号的音高
【发布时间】:2017-07-14 14:27:27
【问题描述】:

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

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

我可以随时间线性改变信号的音高,效果很好,请参阅下面的测试代码和频率图的第 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')

我下面的代码的问题是:

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

2) 它没有正确的斜率

我认为这与变量 facsweep 有关,我只是不确定如何正确计算它们。

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')

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

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

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

【问题讨论】:

  • 对于其他查看此问题并使用 MATLAB 的人,请注释掉或删除行 pkg load signal %load packages

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


【解决方案1】:

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

相关变化:
来自:

 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) 的单位是弧度。

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

【讨论】:

  • 关于聊天的好讨论。我会暂时保留另一个答案,以防其他人想从这里继续并跳过我最初的一些困惑,但会在另一天左右删除它,因为它不是你想要的。
猜你喜欢
  • 2017-11-25
  • 1970-01-01
  • 1970-01-01
  • 2011-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-08
相关资源
最近更新 更多