Estou tentando calibrar um alto-falante ultrassônico com o objetivo de emitir sinais previsíveis, mas infelizmente continuo tendo problemas, provavelmente devido à minha falta de DSP-fu.
Um pouco de fundo
Quero poder reproduzir sons o mais próximo possível de uma gravação calibrada que possuo. Tanto quanto eu entendo a teoria, preciso encontrar a função de transferência de alto-falantes e desconvolver os sinais que quero emitir com ela. Algo assim (no domínio da frequência):
X -> H -> XH
Onde X
está o sinal emitido H
é a função de transferência dos alto-falantes e XH
é X
vezes H
. Uma divisão ( ./
) agora deve me dar H
.
Agora, para emitir um sinal calibrado, ele deve ser dividido por H
:
X/H -> H -> X
O que foi feito
- Alto-falante colocado e um microfone calibrado com 1 m de distância nos tripés.
- Gravou mais de 30 varreduras lineares de 150 KHz a 20 KHz, 20 ms de comprimento e gravou a 500 KS / s.
- Sinais alinhados e calculados com o script Matlab / Octave abaixo, abaixo do script, o sinal resultante pode ser visto.
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);
Fourier transformou
X
eXH
fez os cálculos mencionados acima, o resultado parece plausível. Abaixo está um gráfico normalizado deH
(roxo) eX/H
(verde).
O gráfico foi truncado para as frequências relevantes.
Por favor, deixe-me saber se estou fazendo isso da maneira errada.
Minha pergunta
Depois de calcular X/H
que preciso transformá-lo de volta ao domínio do tempo, presumi que isso seria simples ifft(X./H)
e wavwrite
, mas todas as minhas tentativas até agora não conseguiram obter nenhuma resposta plausível. Um vector de frequência Hf
, H
e X
pode ser encontrada aqui em formato mat7-binário.
Talvez eu esteja apenas cansado e haja uma solução simples aqui, mas no momento não consigo vê-lo. Qualquer ajuda / conselho é muito apreciada.
Respostas:
Encontrei a resposta depois de examinar as referências mencionadas por Jim Clay nos comentários, obrigado Jim.
Cometi o erro de considerar apenas a magnitude que resulta em sinal de fase zero e não pode ser sensatamente usado para emissão, pelo menos não nesta configuração.
O código que finalmente acabei usando pode ser visto abaixo.
O script segue a convenção de nomenclatura de manter os sinais do domínio do tempo em minúsculas e os sinais do domínio de frequência em maiúsculas.
Os espectrogramas de
x conv h
ex deconv h
podem ser vistos abaixo:Isso me parece plausível, embora exista algum ruído no sinal não envolvido.
O próximo teste será ver se a emissão
x_deconv_y
dá algo semelhante àx
restrição daquelas frequências que o falante não pode emitir.Atualizar com os resultados do teste
Nós refazemos as medidas descritas acima usando uma varredura logarítmica para baixo. Esses resultados parecem sugerir que o método funciona.
O teste de verificação consistiu em emitir
X / H
e esperarX
voltar, ou seja, energia igual em todas as frequências. Como a pior frequência de saída é cerca de 20dB mais fraca que a melhor, espera-se que o nível de saída mais alto seja muito menor.O sinal que foi emitido:
A série temporal e o espectrograma do sinal gravado são assim:
fonte