I'm trying to calibrate an ultrasonic speaker with the aim of emitting predictable signals, but alas I keep running into trouble, probably due to my lack of DSP-fu.
A little background
I want to be able to playback sounds as close as possible to a calibrated recording I have. As far as I understand the theory, I need to find the speakers transfer function and deconvolve the signals I want to emit with it. Something like this (in the frequency domain):
X -> H -> XH
X is the emitted signal
H is the speakers transfer function and
H. A division (
./) should now give me
Now, in order to emit a calibrated signal, it should be divided by
X/H -> H -> X
What's been done
- Placed speaker and a calibrated microphone 1 m apart on tripods.
- Recorded 30+ linear sweeps 150KHz-20KHz, 20ms long, and recorded @ 500 KS/s.
- Aligned and averaged signals with the Matlab/Octave script below, under the script the resulting signal can be seen.
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);
XHand did the calculations mentioned above, the result looks plausible. Below is a normalized plot of
The plot has been truncated to the relevant frequencies.
Please let me know if I'm going about this the wrong way.
X/H I need to transform it back to the time domain, I assumed this would be a simple
wavwrite, but all my attempts so far have failed to get any plausible answer. A frequency vector
X can be found here in mat7-binary format.
Maybe I'm just tired and there is a simple solution here, but at the moment I can't see it. Any help/advice is much appreciated.