Fazemos o som nos fones de ouvido tridimensional. Processamento de sinal digital para uso doméstico

Se você já ouviu música por meio de fones de ouvido e alto-falantes, deve ter notado que soa diferente. Os fones de ouvido geralmente dão a sensação de que a fonte de som está em algum lugar dentro da cabeça. Existem outros efeitos negativos: algumas gravações mais antigas são feitas de forma que, por exemplo, a guitarra seja completamente mixada no canal esquerdo, e a bateria - no direito. Nos alto-falantes, parece normal - como se o guitarrista estivesse parado perto de um dos alto-falantes, mas em fones de ouvido é muito desagradável, porque não é natural: na natureza não existe tal coisa que apenas um ouvido possa ouvir o som.





Direi mais: a grande maioria das gravações de áudio comerciais são projetadas especificamente para ouvir através de alto-falantes. Ou seja, o engenheiro de som, ao preparar a gravação, faz de tudo para que soe corretamente (de acordo com as ideias do autor) em monitores de estúdio, e como ficará nos fones de ouvido muito provavelmente nem será verificado.





Parece que, se você gostar, sempre poderá ouvir pelos alto-falantes. Mas, infelizmente, existem limitações: você deseja ouvir música no escritório, no transporte ou apenas tarde da noite, quando os filhos / pais / vizinhos já estão dormindo há muito tempo. Além disso, o custo dos sistemas de alto-falantes de alta qualidade é várias vezes superior ao custo dos fones de ouvido de alta qualidade. E então ainda pode ser necessário um amplificador separado, tratamento acústico da sala, etc. Às vezes simplesmente não há lugar para os alto-falantes no apartamento ... Com fones de ouvido, tudo é mais fácil.





O que fazer?

Um minuto! Mas quando ouvimos música pelos alto-falantes (ou mesmo sentamos em uma sala de concerto), um sinal acústico muito específico chega a cada ouvido. Portanto, se você gravar esse sinal com um pequeno microfone localizado dentro de cada aurícula e depois reproduzi-lo com bons fones de ouvido, teremos a mesma sensação de estar no corredor. Exceto para sinais de baixa frequência sentidos pelo peito. No entanto, este é um procedimento muito complicado, embora tais gravações (são chamadas de binaurais) às vezes sejam feitas e até vendidas.





E se você tocar algum sinal de teste pelos alto-falantes, gravá-lo com esses minúsculos microfones em seus ouvidos, determinar como o sinal foi convertido e, em seguida, transformar da mesma forma sua música favorita antes de tocá-la nos fones de ouvido?





HRTF e HRIR

, , , , . . x(t). , . , , "" . , : , , , . . , , , , , , . , , XL(t), - XR(t). , : XL(t)=FL(x(t)) XR(t)=FR(x(t)).





, - - - - , , ( *), :





XL(t) = hL(t) * x(t) XR(t) = hR(t) * x(t),





hL(t) hR(t) - .





? , ( ). , 2003- IRCAM () . , , , , , , . . , . . Head-Related Impulse Response - . HRTF, .





, . IRCAM , , , 30 , FIR- . , …





, - Sennheizer, AKG, Beyerdynamic, Sony . . . - : "" "" . , . , "Harman Target Curves". , , "" , , . "" - , , . , HRTF.





, "" HRTF , - .





, - .





, : hR(t) hL(t). , "" HRTF ( hR(t) ) , , FR(), hR(t). , , XL(t) - . hcorr(t). : hcorr(t)*hR(t)*x(t)=hL(t)*x(t). hR(t), . ( ): hcorr(t)*hR(t)=hL(t).





, , , . . , - , . fft(). :

fft(hcorr(t)) ⋅ fft(hR(t)) = fft(hL(t))

( ).

, , :

fft(hcorr(t)) = fft(hL(t)) / fft(hR(t)).





( ), !





, , - , - . : .





, , , , , , .





, , , . . , .





: ( ) ( "target curve") - . , , . , , , . / .





, - - . - - , cross-feed. - . / . . , , , , "" . , , - ( ).





, , - Dolby Headphones. - foobar2000, Dolby. . -, . , ( ). , - . - . , , Dolby, , . , Windows. , , , , reverse-engineering, .





, - GitHub, - , . . , readme.md .





Matlab. , - GNU Octave. , .





, IRCAM. +-30 - , . -, , , (, ), , , , . IRC_1006_R_R0195_T030_P000.wav IRC_1006_R_R0195_T330_P000.wav, , , , - .





1006 - , 0195 - , 030/330 - (0 - , 90 , 180 - , 270 - ), 000 - . IRCAM xml- - , , , . . .





Impulso direto
Direct impulse
Impulso oposto
Opposite impulse

8192 , 44.1. 186, 63. , , ( 2 !) , . 1024..4096 . :





channel_idx = 1; % Channel index, used from input files: 1 - left, 2 - right
max_impulse_len = 4096;
[impulse, fs] = audioread(fname);
len = min(rows(impulse), max_impulse_len);
      
      



.





impulse = impulse(1 : len, channel_idx);
      
      



:





fft_div = fft(impulse_opposite) ./ fft(impulse_direct);
impulse_tf = real(ifft(fft_div));
      
      



- deconvolution system identification (. . ). , :





Deconvolução FFT
FFT deconvolution

- :) , . , - . ... , , hcorr(t) * hR(t) = hL(t).

, " ":





plot(conv(impulsedirect, impulsetf)(1:4096) - impulseopposite);
      
      



Erro FFT
FFT error

, , . ...





. , : . , . - () -. Matlab, , ( , - ).





, :





Deconvolução LMS
LMS deconvolution

" ":





Erro LMS
LMS error

, .





:





Deconvolução LMS, ampliada
LMS deconvolution, zoomed-in

, . , , 20 ( ) :





lpf = remez(2 * round(fs / 600), [0 20000 / (fs / 2) 21000 / (fs / 2) 1], [1 1 0 0]); % For Matlab environment change "remez" to "firpm". 
filteredImpulse=conv(impulse_tf, lpf, 'same');
      
      



LMS deconvolution, LPF
LMS deconvolution, LPF

.

, . . , , .





, … , 8192 - , . - ! , , , .





, , , , , DRC, , . , DRC :)

, , ...





, . , :





avgDelay = round(median(grpdelay(impulse_tf)));
      
      



.





wnd = window(@blackman, 2 * (size(impulse_tf)(1) - avgDelay));
% Cut the window in size
wnd = flipud(wnd(1:size(impulse_tf)));
% Apply window
impulse_tf = impulse_tf .* wnd;
      
      



LMS deconvolution, LPF, windowing
LMS deconvolution, LPF, windowing

. . , 2..4 , . - . , .





( FFT). , , - ( ), :





. ( :)) - , . , , .





-, .





impulse_tf_stereo_L(:, 2) = impulse_tf;
impulse_tf_stereo_L(1, 1) = 1;
impulse_tf_stereo_R(:, 1) = impulse_tf;
impulse_tf_stereo_R(1, 2) = 1;
audiowrite(strcat(directory, fname_direct, '_TF_stereo_L.wav'), impulse_tf_stereo_L, fs);
audiowrite(strcat(directory, fname_direct, '_TF_stereo_R.wav'), impulse_tf_stereo_R, fs);
      
      



, . foobar2000 "Stereo Convolver". :





- , … , .





- IRCAM . - .





, . . .





- .





GNU Octave GitHub.





, . .












All Articles