两个音频文件的频谱图(相加后)

3
假设我有两个输入信号f1和f2。我可以将这些信号相加,产生第三个信号f3 = f1 + f2。然后,我将计算f3的频谱图作为log(|stft(f3)|^2)。
不幸的是,我没有原始信号f1和f2。但是,我有它们的频谱图A = log(|stft(f1)|^2)和B = log(|stft(f2)|^2)。我要寻找的是一种使用A和B尽可能接近地逼近log(|stft(f3)|^2)的方法。如果我们进行一些数学推导,我们可以得出: log(|stft(f1 + f2)|^2) = log(|stft(f1) + stft(f2)|^2)
表示stft(f1) = x1 + i * y1和stft(f2) = x2 + i * y2,以此来编写
... = log(|x1 + i * y1 + x2 + i * y2|^2)
... = log((x1 + x2)^2 + (y1 + y2)^2)
... = log(x1^2 + x2^2 + y1^2 + y2^2 + 2 * (x1 * x2 + y1 * y2))
... = log(|stft(f1)|^2 + |stft(f2)|^2 + 2 * (x1 * x2 + y1 * y2))
因此,此时我可以使用以下近似值: log(|stft(f3)|^2) ≈ log(exp(A) + exp(B))
但是我会忽略最后一部分2 * (x1 * x2 + y1 * y2)。所以我的问题是:有没有更好的逼近方法?
有什么想法吗?谢谢。

1
平方幅值操作不是线性的,因此会产生一个不可分离的交叉项(正如你所发现的那样)。 - SleuthEye
那么没有其他办法吗?你知道任何聪明的近似方法吗?或者有什么我可以用来处理真实世界的音频文件吗? - user667804
我真的不明白实际问题是什么。你有两个信号(时间上的真实振幅),你有它们的和,那么为什么不能同时绘制这三个信号的频谱图(f1,f2,f1+f2)呢? - roadrunner66
由于某种原因,我只想使用我拥有的f1和f2的频谱图。想象一下获取f1和f2的音频信号非常昂贵。因此,我希望在不使用原始音频信号的情况下计算f3 = f1 + f2的频谱图。 - user667804
然后将它们相加,再像你之前做的那样进行转换。或者先对它们进行傅里叶变换,然后相加,再平方。正如其他人指出的那样,傅里叶变换是线性的,但取强度(绝对值平方或z * z)则不是。但如果你有f1和f2的所有数据,那么问题就不存在了。我仍然不理解实际问题是什么。如果你只有f1和(f1+f2)的FT平方,并想要重新生成f2,那么情况会有所不同。但你已经拥有振幅级别的所有信息(时间上为实数,傅里叶上为复数)。将两个时间信号相加既不费时,也不费力(在时间域和FT之前^2都是如此)。因此,我建议重新措辞问题。 - roadrunner66
显示剩余3条评论
3个回答

0

对2个对数幅度取exp(),相加,然后取总和的对数。


我正在做这件事,但是它不正确。我缺少交叉项2 *(x1 * x2 + y1 * y2)。我认为这个近似值可能足够好,但如果你有更接近真相的东西,我想知道。 - user667804

0

从数学上讲,我们可以发现,在基本层面上这是不可能的。

  • 考虑一个第一信号f1,它是频率为F、振幅为A的纯音。
  • 考虑一个第二个信号f2,它是频率为F、振幅为A的纯音,但与f1完全反相。

在这种情况下,f1和f2的频谱图是相同的。

现在考虑两个可能的组合信号。

  • f1加到自身上是频率为F、振幅为2A的纯音。
  • f1加上f2是完全静音。

仅从f1和f2的频谱图(它们是相同的)中,你无法知道你处于这些非常不同的情况中的哪一个。这不仅适用于纯音。任何信号及其关于轴的反射都会遇到同样的问题。更进一步地概括,就是没有办法知道你的基本信号有多少会相互抵消,有多少会互相强化。尽管如此,也有限制。如果对于特定频率,您的基本信号具有振幅A1和A2,则最大可能振幅为A1+A2,最小可能振幅为abs(A1-A2)。


0

我不完全理解你的符号表示,但我会尝试解释。在时间域中进行加法对应于在频率域中进行加法。将两个时间域信号x1和x2相加会产生第三个时间域信号x3。x1、x2和x3均具有频率域谱,即F(x1)、F(x2)和F(x3)。F(x3)也等于F(x1)+F(x2),其中加法是通过将F(x1)的实部加上F(x2)的实部,并将F(x1)的虚部加上F(x2)的虚部来完成的。因此,如果x1[0]为1+0j,x2[0]为0.5+0.5j,则它们的和为1.5+0.5j。根据你的符号表示,你似乎想要对幅度进行求和,而以这个示例为例,这将是|1+0j| + |0.5+0.5j| = sqrt(1*1) + sqrt(0.5*0.5+0.5*0.5) = sqrt(2) + sqrt(0.5)。很明显这不是同一件事情。我认为你想要像这样做:

log((|stft(a) + stft(b)|)^2) = log(|stft(a)|^2) + log(|stft(b)|^2)

我重新改写了我的问题,以使我遇到的问题更加清楚。我认为你正确理解了我的问题,但你最后一句话似乎有误。绝对值运算符不是线性的,对吗? - user667804
我在dsp.stackexchange网站上有一个问题 (https://dsp.stackexchange.com/questions/62645/mixing-signal-with-noise-in-frequency-space-stft),也许你能回答。 - Stefan Falk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接