超声波扬声器校准和发射校准信号


10

我正在尝试校准超声波扬声器,以发出可预测的信号,但可惜我一直遇到麻烦,这可能是由于缺乏DSP-fu所致。

一点背景

我希望能够播放尽可能接近我已校准的录音的声音。据我了解的理论,我需要找到扬声器的传递函数,并解卷积我想随其发出的信号。像这样(在频域中):

X -> H -> XH

其中X是所发射的信号H是扬声器传递函数和XHXH./现在除法()应该给我H

现在,为了发射校准信号,应将其除以H

X/H -> H -> X

做了什么

  • 在三脚架上相隔1 m放置扬声器和已校准的麦克风。
  • 记录了30多次150KHz-20KHz,20ms长的线性扫描,并以500 KS / s的速度记录。
  • 使用下面的Matlab / Octave脚本对齐和平均后的信号,在该脚本下可以看到生成的信号。
files = dir('Mandag*');

rng = [1.5e6, 1.52e6];

[X, fs] = wavread(files(1).name, rng);
X = X(:,1);

for i=2:length(files)
    [Y, fs] = wavread(files(i).name, rng);
    sig = Y(:,1);
    [x, off] = max(xcorr(X', sig'));
    off = length(X) - off;
    if(off < 0)
        sig = [zeros(1, -off), sig(1:end+off)'];
    elseif (off > 0)
        sig = [sig(off:end)', zeros(1, off-1)];
    end
    X = X + sig';
end
X = X/length(files);

对齐和平均的信号

  • 进行傅立叶变换XXH进行了上述计算,结果似乎是合理的。以下是H(紫色)和X/H(绿色)的归一化图。

    H和X / H的频率图

该图已被截断为相关频率。

请让我知道我是否打算以错误的方式进行操作。

我的问题

计算X/H完之后,我需要将其转换回时域,我认为这将是一个简单的ifft(X./H)wavwrite,但是到目前为止,我的所有尝试都未能获得任何合理的答案。频率向量HfHX可以在此处以mat7-binary格式找到。

也许我只是累了,这里有一个简单的解决方案,但此刻我看不到它。任何帮助/建议都将不胜感激。



是的,发现我的错误,谢谢吉姆。我只考虑信号的幅度,这导致了零相位时间信号。看来我现在得到了正确的结果,我将其添加为答案。
2012年

Answers:


3

查看吉姆·克莱在评论中提到的参考文献后找到答案,谢谢吉姆。

我犯了一个错误,即仅考虑会导致零相位信号并且无法明智地用于发射的幅度,至少在此设置中不这样做。

我最终使用的代码可以在下面看到。

该脚本遵循命名约定,即时域信号应小写,频域信号应大写。

% Align and sum all files called Mandag*
files = dir('Mandag*');

% Where in the recordings the signal is
rng = [1.5e6, 1.52e6];

% Initialize the xh vector
[xh, fs] = wavread(files(1).name, rng);
xh = xh(:,1);

for i=2:length(files)
    y = wavread(files(i).name, rng);
    y = y(:,1);
    % Determine offset between xh and y
    [~, off] = max(xcorr(xh', y'));
    off = length(xh) - off;
    % Shift signal appropriately
    if(off < 0)
        y = [zeros(1, -off), y(1:end+off)'];
    elseif (off > 0)
        y = [y(off:end)', zeros(1, off-1)];
    end
    xh = xh + y';
end

% Average
xh = xh/length(files);

% Location of the 20ms signal
xh = xh(2306:12306-1);

% Normalize
xh = xh / max(xh);

% Apply a moving average filter on xh to reduce noise. Window size of 4 was
% experimentally determined to give the best results
n = 4;
B = zeros(n, 1);
for i=1:n
  B(i) = 1/n;
end
xh = filter(B, 1, xh);
xh = xh / max(xh);

x = wavread('sweep.wav');
x = x(1:2:end);            % Sweep generated @ 1MHz, decimate
                           % to have same length as xh

% Transform x into frequency domain and determine H
X = fft(x);
H = fft(xh) ./ X;

% Vector indices to choose only frequencies of interest
starti =  20e3 / 50;
endi   = 100e3 / 50;
rng    = starti:endi;
irng   = (length(x) - endi) : (length(x) - starti);

% Zero out unwanted frequencies
X = [zeros(1,      starti - 1   ), X( rng)', zeros(1, length(X)/2 - endi) ...
     zeros(1, length(X)/2 - endi), X(irng)', zeros(1,      starti - 1   )]';

% Deconvolve x with h
X_deconv_H = X ./ H;

% Transform X/H to time domain and normalise
x_deconv_h = real(ifft(X_deconv_H));
x_deconv_h = x_deconv_h / max(x_deconv_h);

% Save the deconvolved sweep
wavwrite(x_deconv_h, fs, 'deconvolved_sweep.wav');

% Generate  spectrograms of xh and x_deconv_h
winsize = 512;
overlap = round(.99 * winsize);
figure(1)
specgram(xh, winsize, fs, hann(winsize), overlap)
colorbar
figure(2)
specgram(x_deconv_h, winsize, fs, hann(winsize), overlap)
colorbar

的谱图x conv hx deconv h可以看到如下:

x转换的频谱图 x deconv h的频谱图

尽管去卷积信号中有些噪声,但这些对我来说似乎是合理的。

下一个测试将是查看发射是否x_deconv_y给人类似x的声音,除非扬声器无法发射那些频率。

更新测试结果

我们使用对数向下扫描重做上述测量。这些结果似乎表明该方法有效。

验证测试包括发射X / H并期望X返回,即所有频率下的能量相等。由于最差的输出频率比最差的输出频率弱约20dB,因此预计最高的输出电平会低得多。

发出的信号:

发射信号的时间序列

所记录信号的时间序列和频谱图如下所示:

发射信号的时间序列 发射信号的时间序列


这事有进一步更新吗?您发出的信号看起来如何?
Lance

@Busk:感谢您的关注。由于该设备正在其他地方使用,因此我还没有机会对其进行测试。完成测试后,我将发布结果。
2012年

@Busk:我们现在已经对其进行了测试,它似乎可以正常工作:-)。
2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.