Ультразвуковая калибровка колонок и испускание калиброванных сигналов


10

Я пытаюсь откалибровать ультразвуковой громкоговоритель, чтобы излучать предсказуемые сигналы, но, увы, я продолжаю сталкиваться с проблемами, вероятно, из-за отсутствия DSP-фу.

Немного фона

Я хочу иметь возможность воспроизводить звуки как можно ближе к откалиброванной записи, которая у меня есть. Насколько я понимаю теорию, мне нужно найти передаточную функцию динамиков и деконволюции сигналов, которые я хочу испустить с ее помощью. Как то так (в частотной области):

X -> H -> XH

Где Xэто излучаемый сигнал Hявляется передаточная функция колонки и XHэто Xраз H. Разделение ( ./) теперь должно дать мне H.

Теперь, чтобы испустить калиброванный сигнал, его следует разделить на H:

X/H -> H -> X

Что сделано

  • Размещен динамик и калиброванный микрофон на расстоянии 1 м на штативах.
  • Записано 30+ линейных разверток 150 кГц-20 кГц, длиной 20 мс и записано при 500 кС / с.
  • Выровненные и усредненные сигналы с помощью сценария 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);

Выровненные и усредненные сигналы

  • Фурье преобразился Xи, XHвыполнив вычисления, упомянутые выше, результат выглядит правдоподобно. Ниже приведен нормализованный график H(фиолетовый) и X/H(зеленый).

    Частотный график H и X / H

Сюжет был усечен до соответствующих частот.

Пожалуйста, дайте мне знать, если я поступаю неправильно.

Мой вопрос

После вычисления X/Hмне нужно преобразовать его обратно во временную область, я предположил, что это будет просто ifft(X./H)и wavwrite, но все мои попытки до сих пор не дали никакого правдоподобного ответа. Вектор частоты Hf, Hи Xможет быть найден здесь в mat7 двоичного формата.

Может быть, я просто устал, и здесь есть простое решение, но сейчас я его не вижу. Любая помощь / совет очень ценится.


1
Этот поток - dsp.stackexchange.com/questions/953/… - и этот - dsp.stackexchange.com/questions/2705/… - может быть полезен для вас.
Джим Клэй,

Да, нашел мою ошибку, спасибо, Джим. Я рассматривал только величину сигналов, что приводит к нулевой фазе сигнала времени. Похоже, у меня сейчас правильный результат, и я добавлю его в качестве ответа.
Тор

Ответы:


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 hи x deconv hможно увидеть ниже:

спектрограмма х конв ч спектрограмма х деконв ч

Мне это кажется правдоподобным, хотя в разложенном сигнале есть некоторый шум.

Следующим тестом будет выяснить, x_deconv_yдает ли излучение что-то похожее на xте частоты, которые динамик не может излучать.

Обновление с результатами теста

Мы переделали измерения, описанные выше, используя логарифмическую развертку. Эти результаты показывают, что метод работает.

Проверочный тест состоял из излучения X / Hи ожидания Xвозврата, то есть равной энергии на всех частотах. Поскольку наихудшая выходная частота примерно на 20 дБ слабее, чем наивысшая, ожидается, что самый высокий выходной уровень будет намного ниже.

Сигнал, который был испущен:

Временные ряды излучаемого сигнала

Временной ряд и спектрограмма записанного сигнала выглядят так:

Временные ряды излучаемого сигнала Временные ряды излучаемого сигнала


Любое обновление по этому поводу? Как вы излучали сигнал?
Ланс

@Busk: спасибо за интерес. У меня еще не было возможности протестировать его, поскольку оборудование используется в других местах. Я опубликую результаты, когда я сделаю тест.
Тор

@Busk: сейчас мы проверили это, и похоже, что оно работает :-).
Тор
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.