echo_diagnostic.m 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. % Attempts to diagnose AEC problems from recorded samples
  2. %
  3. % out = echo_diagnostic(rec_file, play_file, out_file, tail_length)
  4. %
  5. % Computes the full matrix inversion to cancel echo from the
  6. % recording 'rec_file' using the far end signal 'play_file' using
  7. % a filter length of 'tail_length'. The output is saved to 'out_file'.
  8. function out = echo_diagnostic(rec_file, play_file, out_file, tail_length)
  9. F=fopen(rec_file,'rb');
  10. rec=fread(F,Inf,'short');
  11. fclose (F);
  12. F=fopen(play_file,'rb');
  13. play=fread(F,Inf,'short');
  14. fclose (F);
  15. rec = [rec; zeros(1024,1)];
  16. play = [play; zeros(1024,1)];
  17. N = length(rec);
  18. corr = real(ifft(fft(rec).*conj(fft(play))));
  19. acorr = real(ifft(fft(play).*conj(fft(play))));
  20. [a,b] = max(corr);
  21. if b > N/2
  22. b = b-N;
  23. end
  24. printf ("Far end to near end delay is %d samples\n", b);
  25. if (b > .3*tail_length)
  26. printf ('This is too much delay, try delaying the far-end signal a bit\n');
  27. else if (b < 0)
  28. printf ('You have a negative delay, the echo canceller has no chance to cancel anything!\n');
  29. else
  30. printf ('Delay looks OK.\n');
  31. end
  32. end
  33. end
  34. N2 = round(N/2);
  35. corr1 = real(ifft(fft(rec(1:N2)).*conj(fft(play(1:N2)))));
  36. corr2 = real(ifft(fft(rec(N2+1:end)).*conj(fft(play(N2+1:end)))));
  37. [a,b1] = max(corr1);
  38. if b1 > N2/2
  39. b1 = b1-N2;
  40. end
  41. [a,b2] = max(corr2);
  42. if b2 > N2/2
  43. b2 = b2-N2;
  44. end
  45. drift = (b1-b2)/N2;
  46. printf ('Drift estimate is %f%% (%d samples)\n', 100*drift, b1-b2);
  47. if abs(b1-b2) < 10
  48. printf ('A drift of a few (+-10) samples is normal.\n');
  49. else
  50. if abs(b1-b2) < 30
  51. printf ('There may be (not sure) excessive clock drift. Is the capture and playback done on the same soundcard?\n');
  52. else
  53. printf ('Your clock is drifting! No way the AEC will be able to do anything with that. Most likely, you''re doing capture and playback from two different cards.\n');
  54. end
  55. end
  56. end
  57. acorr(1) = .001+1.00001*acorr(1);
  58. AtA = toeplitz(acorr(1:tail_length));
  59. bb = corr(1:tail_length);
  60. h = AtA\bb;
  61. out = (rec - filter(h, 1, play));
  62. F=fopen(out_file,'w');
  63. fwrite(F,out,'short');
  64. fclose (F);