从正弦扫描中计算频率响应的问题

4
我目前正在尝试计算 iPhone 扬声器/麦克风往返的频率响应。我在扬声器上播放正弦扫描,通过麦克风录制它,然后尝试从中获取频率响应。最终目标是能够将 FR 乘以任何给定的声音,使其听起来像 iPhone 的扬声器/麦克风。 我的代码如下:
//apply window function
vDSP_vmul(sineSweepMic,1,hammingWindow,1,sineSweepMic,1,n);
vDSP_vmul(sineSweepFile,1,hammingWindow,1,sineSweepFile,1,n);

//put both signals in complex arrays
vDSP_ctoz((DSPComplex *)sineSweepMic, 2, &fftSineSweepMic, 1, nOver2);
vDSP_ctoz((DSPComplex *)sineSweepFile, 2, &fftSineSweepFile, 1, nOver2);

//fft of both file and mic sweeps
vDSP_fft_zrip(fftSetup, &fftSineSweepFile, 1, log2n, FFT_FORWARD);
vDSP_fft_zrip(fftSetup, &fftSineSweepMic, 1, log2n, FFT_FORWARD);

//back to interleaved
vDSP_ztoc(&fftSineSweepFile, 1, (COMPLEX *)sineSweepFile, 2, nOver2);
vDSP_ztoc(&fftSineSweepMic, 1, (COMPLEX *)sineSweepMic, 2, nOver2);

//divide mic-sweep by file-sweep to create frequency response
vDSP_vdiv(sineSweepFile, 1, sineSweepMic, 1, frequencyResponse, 1, n);

到目前为止这个方法是可行的,当我用初始文件扫描乘以FR时,听起来像麦克风扫描。

我的问题: 这只对生成FR的确切文件(扫描)有效。一旦我使用FR修改其他声音,例如音乐,只会听到噪音。

我是这样使用FR的(都在频域内,交错排列,不复杂,甚至长度相同):

    vDSP_vmul(soundToModify, 1, frequencyResponse, 1, soundToModify, 1, n);

我的来自文件的正弦扫描在扬声器上播放: enter image description here

我的记录的正弦扫描(衰减的低频可见): enter image description here

我在代码中生成的FR与上述内容相乘的文件正弦扫描:

enter image description here

我的目标: 据我所知,频率响应是关于每个频率的信息,系统通过多少衰减或放大它(在我的例子中,它无法再现低频)。为了获得这种信息,我会生成包含每个所需频率的声音(正弦扫描),播放它并分析每个频率如何被修改,即通过除以记录到的扫描/文件扫描(代码中的除法)。

将此频率响应(FR)在频率域中与任何声音相乘,是否应该修改频率幅度以模拟在我的系统上播放?

谢谢!


更新: 最终问题出在缺少复杂算术上,正弦扫描和粉色噪声都很好地作为恢复脉冲响应的冲激。

要获得可工作的代码,只需通过初步扫描fft数据进行复杂除法即可。


如果您只想测量频率响应,则可以生成几秒钟的白噪声(高斯噪声),收集多个FFT并平均得到结果功率谱。还要注意,尝试像这样“校正”频率响应在数值上本质上是不稳定的。请搜索“去卷积”。 - Paul R
我在上面添加了更多的信息。我的正弦扫频对此不太合适,因为它包含了每个所需的频率,改变分析信号为粉色噪声会解决我的问题吗?通过在FFT之后将记录/原始分割来获取FR的方法正确吗? - Maximilian Körner
如果您在时间域中进行频率响应,则使用(缓慢的)正弦扫描是可以的-对于频率域测量,请使用噪声。但更大的问题是,您正在以本质上有缺陷的方式进行反卷积。 - Paul R
1个回答

3
如果您想重新创建iPhone扬声器/麦克风的声音,最好找到系统的脉冲响应。您正在犯的错误:找到正弦扫描的FFT是无意义的,因为输入频率首先会发生变化(线性或指数或其他),然后系统会施加自己的频率响应。如Paul R上面建议的那样,找到白噪声的FFT更有意义,因为在许多统计平坦的输入频率上进行平均将为您提供实际的频率响应。但是,如果您的目标是重新创建系统的声音,则还需要注意相位,这在以上任一方法中都没有完成。“理想”的方法是在完全安静干燥(无反射)的环境中捕获iPhone扬声器/麦克风系统对“脉冲”的响应。有3种方法可以做到: 1. 使用气球爆炸声或合成的脉冲声来实现此目的。 2. 使用Golay代码,这是一个平均许多脉冲响应测量的简单方法 3. 使用正弦扫描,但然后使用相关性找到脉冲响应。
参考资料:https://ccrma.stanford.edu/realsimple/imp_meas/imp_meas.pdf 一旦获得了脉冲响应测量值,请将其与您要“着色”的信号卷积,或者获取两个信号的FFT,在频域中相乘,然后取反FFT以获得彩色信号。
解释: 我会尽我所知尝试解释一下:- 当您对脉冲响应进行FR时,您获取其FFT的幅度,丢弃相位数据。因此,有许多具有相同幅度FR的滤波器(系统)将为您提供根本不同的输出。案例在于全通滤波器 - 它们都具有平坦的FR,但如果您将脉冲传递到它们中,您可以从过滤器参数依赖性地获得正弦扫描。显然,这应该表明尽管您始终可以从IR到FR,但反向返回意味着您正在做出任意选择。因此,即使是粗略的估计,也不能丢弃相位。我们无法听到相位的事实意味着我们可以查看FR以获取有关系统的信息,但并不允许我们在建模系统时忽略相位。希望有帮助! 对于使用正弦扫描,请执行以下操作-如果s(t)= sin(A(t)),则A(t)= integral [0 to t](w(t)dt),相关信号e(t)= corr(v (t),sin(A(t))其中v(t)= 2 * abs(dw / dt)将产生一个脉冲。因此,如果您用测量信号替换该相关性中的正弦扫描,则应获得其脉冲响应。希望有所帮助!对于数学问题感到抱歉。

据我理解,脉冲响应是傅里叶变换后的频率响应的反演。(正如我所说,我对这一切都很新,所以请随时纠正我!:D)从正弦扫描到粉色/白噪声的变化是否显著,因为FFT数据是时间不变的(?),只有每个频率的总功率相关,而且由于我首先将信号相关以尽可能最佳地对齐它们,它们应该包含相同的数据。由于我不需要完美的数据,而只需要一个粗略的估计,我可以忽略相位,只关注通过FR进行的频率幅度修改吗?感谢提供参考! - Maximilian Körner
好的,我想我现在有一个关于IR和FR如何相关的想法了。回到我的方法:据我所知,我所做的一切就是用正弦扫描方法创建脉冲响应(在这里解释:http://www.dspguide.com/ch9/2.htm): 1.播放正弦扫描并记录它 2.对两者进行反卷积以协商实际扫描数据并留下响应。(使用vdsp_vdiv()进行反卷积,因为在频域中除法就是反卷积) 3.通过卷积应用IR(或在我的情况下,通过乘法应用FR)我的错误可能是,这些用于实数的函数无法进行复数除法/乘法? - Maximilian Körner
是的,在频域中进行算术运算肯定需要使用复数 - 这就是问题所在 - 通过取复数的幅度,您正在丢失所需的数据 - 要么尝试进行复杂的算术运算并发布您得到的结果,要么尝试我在解释中发布的保持实数的算术运算。请写下结果以及最终起作用的方法! - e7mac

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