Calibrazione ultrasonica degli altoparlanti ed emissione di segnali calibrati


10

Sto cercando di calibrare un altoparlante ad ultrasuoni con l'obiettivo di emettere segnali prevedibili, ma purtroppo continuo a correre nei guai, probabilmente a causa della mia mancanza di DSP-fu.

Un piccolo sfondo

Voglio essere in grado di riprodurre i suoni il più vicino possibile a una registrazione calibrata che ho. Per quanto ho capito la teoria, devo trovare la funzione di trasferimento degli altoparlanti e deconvolgere i segnali che voglio emettere con essa. Qualcosa del genere (nel dominio della frequenza):

X -> H -> XH

Dov'è Xil segnale emesso Hè la funzione di trasferimento degli altoparlanti ed XHè il Xtempo H. Una divisione ( ./) ora dovrebbe darmi H.

Ora, per emettere un segnale calibrato, dovrebbe essere diviso per H:

X/H -> H -> X

Cosa è stato fatto

  • Altoparlante posizionato e microfono calibrato a 1 m di distanza sui treppiedi.
  • Oltre 30 sweep lineari registrati da 150 KHz a 20 KHz, lunghi 20 ms e registrati a 500 KS / s.
  • Segnali allineati e medi con lo script Matlab / Octave di seguito, sotto lo script è possibile vedere il segnale risultante.
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);

Segnali allineati e medi

  • Fourier si è trasformato Xe ha XHfatto i calcoli sopra menzionati, il risultato sembra plausibile. Di seguito è riportato un diagramma normalizzato di H(viola) e X/H(verde).

    Grafico della frequenza di H e X / H

La trama è stata troncata alle frequenze pertinenti.

Per favore fatemi sapere se sto andando in questo modo nel modo sbagliato.

La mia domanda

Dopo il calcolo X/Hho bisogno di riportarlo nel dominio del tempo, ho pensato che sarebbe stato un semplice ifft(X./H)e wavwrite, ma tutti i miei tentativi finora non sono riusciti a ottenere una risposta plausibile. Un vettore di frequenza Hf, He Xpuò essere trovato qui in formato mat7-binario.

Forse sono solo stanco e qui c'è una soluzione semplice, ma al momento non riesco a vederlo. Qualsiasi aiuto / consiglio è molto apprezzato.



Sì, ho trovato il mio errore grazie Jim. Stavo solo considerando l'entità dei segnali, che si traduce in un segnale temporale a fase zero. Sembra che ora abbia il risultato giusto e lo aggiungerò come risposta.
Thor,

Risposte:


3

Ho trovato la risposta dopo aver esaminato i riferimenti che Jim Clay ha menzionato nei commenti, grazie Jim.

Ho commesso l'errore di considerare solo la grandezza che si traduce in un segnale a fase zero e non può essere sensibilmente utilizzato per l'emissione, almeno non in questa configurazione.

Il codice che ho finito per usare può essere visto sotto.

Lo script aderisce alla convenzione di denominazione di mantenere i segnali del dominio del tempo in minuscolo e i segnali del dominio della frequenza in maiuscolo.

% 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

Di seguito sono riportati gli spettrogrammi di x conv he x deconv h:

spettrogramma di x conv h spettrogramma di x deconv h

Mi sembrano plausibili sebbene ci sia del rumore nel segnale deconvolto.

Il prossimo test sarà vedere se l'emissione x_deconv_ydà qualcosa di simile al xblocco di quelle frequenze che l'altoparlante non può emettere.

Aggiornamento con risultati del test

Abbiamo ridefinito le misure sopra descritte utilizzando una scansione discendente logaritmica. Questi risultati sembrano suggerire che il metodo funzioni.

Il test di verifica consisteva nell'emettere X / He aspettarsi di Xtornare, vale a dire pari energia in tutte le frequenze. Poiché la peggiore frequenza di uscita è circa 20 dB più debole della migliore, il livello di uscita più alto dovrebbe essere molto più basso.

Il segnale che è stato emesso:

Serie temporali del segnale emesso

Le serie temporali e lo spettrogramma del segnale registrato si presentano così:

Serie temporali del segnale emesso Serie temporali del segnale emesso


Qualche aggiornamento a questo proposito? Come hai emesso il segnale?
Lancia

@Busk: grazie per l'interesse. Non ho ancora avuto la possibilità di testarlo poiché l'apparecchiatura viene utilizzata altrove. Pubblicherò i risultati quando avrò fatto il test.
Thor

@Busk: ora lo abbiamo testato e sembra funzionare :-).
Thor,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.