首页 > > > 10877 「人耳对相位不敏感」到底是什么意思(续)
写完了上、下两篇后,我又想到了一个有趣的数学问题,于是就再写下这篇「续」。
在下篇的第一、二节,我把滤波器的相位响应分成了「群延时」和「净相移」两部分。如果一个滤波器的相位响应为
,则它的群延时为

净相移为
![\begin{align} \Delta\phi_\text{net}(\omega) &= \Delta\phi(\omega) - [-\omega \cdot \tau_g(\omega)] \\ &= \Delta\phi(\omega) - \omega \cdot \frac{\text{d}\Delta\phi(\omega)}{\text{d}\omega} \\ \end{align} \\](https://image.z.itpub.net/zitpub.net/JPG/2020-06-19/84EA5EF10E93B1E71E10334A22E814B2.jpg)
现在问题来了:给定了想要的净相移
,如何求「毛相移」
?
我们简化一下符号,把毛相移记作
,净相移记作
,于是它们之间的关系就是
。这是一个微分方程,已知
,求
。怎么解呢?
像所有的参考答案一样,我要使用一次「神来之笔」:方程右边很像两个函数之商的导数公式。原来,
。这样,微分方程就可以化成:
![\left[ \frac{f(\omega)}{\omega} \right]' = -\frac{g(\omega)}{\omega^2} \\](https://image.z.itpub.net/zitpub.net/JPG/2020-06-19/48501C55E69CCD25530A6A91382197BF.jpg)
两边积分,就得到了解:

注意,右边的不定积分算出来之后,别忘了加积分常数!
下面来看两个例子。

【例 1】想让净相移呈线性变化,当归一化角频率从 0 变化至
时,净相移从 0 变化至
,即
。求毛相移
和群延时。
解:毛相移

群延时

不妨取
,此时毛相移、群延时、净相移的图象如下。这个群延时是为了得到想要的净相移所必须付出的代价。调整
可以让群延时曲线整体上移或下移,相当于把信号整体提前或推迟,实际上没有什么用。群延时在极低频处会比较大,不过好在极低频的声音是听不见的,所以没有关系。

【例 2】想让净相移分段为常数:

求毛相移
和群延时。
解:在任一区间上,若
为常数
,则
。也就是说,这是一条截距为
的直线上的一段。
本题的
把横轴
平分成了四个区间,我们从左到右一个一个看:
。不妨取
,于是在这一段上
,其右端点为
。
。又由于这一段上的
必须过
才能保证
在整体上是连续的,可以解出这一段上的
,
。这一段的右端点为
。
。考虑到
必须过
,可以解得这一段上
,其右端点为
。
。考虑到
必须过
,可以解得这一段上
。由此可得毛相移和群延时:


但是,眼看着群延时一段比一段大,不太爽。事实上,在第四段上,可以认为
,因为反正
的相移跟
的相移是一回事。这样,就可以重新计算最后一段的毛相移和群延时:


群延时横跨的范围由
缩小至
。在想要的净相移为分段函数时,通过在各段上增减
,有可能起到缩小群延时范围的作用,这算是面对命运的一点儿抗争。
有了根据净相移计算毛相移的方法,我们就可以随心所欲地修改信号了!比如,我们用最后得到的毛相移处理「电灯比油灯进步多了」这段声音,代码如下:
[x, fs] = audioread('diandeng.wav'); % 读入声音
X = fft(x); % 求频谱
% 按刚刚计算出的公式构造毛相移向量
omega = linspace(0, pi, length(X) / 2 + 1)'; % 自变量:归一化角频率,从0到pi
f = zeros(size(omega)); % 因变量:毛相移
f(omega > 0 & omega < pi/4) = -pi/4; % 注意归一化角频率等于0或pi处最好不要乱动
f(omega >= pi/4 & omega < pi/2) = pi/4 - 2 * omega(omega >= pi/4 & omega < pi/2);
f(omega >= pi/2 & omega < 3*pi/4) = pi/2 - 5/2 * omega(omega >= pi/2 & omega < 3*pi/4);
f(omega >= 3*pi/4 & omega < pi) = -pi - 1/2 * omega(omega >= 3*pi/4 & omega < pi);
H = exp(1i * f); % 把毛相移转化成滤波器的传输函数
H = [H; conj(H(end-1:-1:2))]; % 补齐共轭对称的另一半
Y = X .* H; % 改造声音的频谱!
y = real(ifft(Y)); % 逆变换得到相移后的声音
soundsc(y, fs); % 播放!实验结果如下。因为群延时最大只有 2.5 个采样点,所以在语谱图上几乎看不出来,当然听就更听不出来啦。
https://
原文作者:;如有侵权,请联系管理员删除。