sphear_octa_af_calibrate_measurements.m 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. %% -*- mode: octave -*-
  2. %%
  3. %% *SpHEAR Project
  4. %%
  5. %% sphear_af_octa_calibrate_all: read all raw impulse response sweep
  6. %% measurements, convolve with the inverse sweep to calculate
  7. %% the impulse response, pre-trim the impulse, convolve with
  8. %% the speaker inverse filter (calculated with DRC), trim to
  9. %% eliminate the first reflection and beyond, window with a
  10. %% blackman window
  11. %%
  12. %% usage:
  13. %% [] = sphear_af_octa_calibrate_all(path, first)
  14. %%
  15. %% path: path to measurements, defaults to "../data/current/"
  16. %% first: first reflection arrival time in seconds referenced to peak
  17. %%
  18. %% Copyright 2016-2018, Fernando Lopez-Lezcano, All Rights Reserved
  19. %% nando@ccrma.stanford.edu
  20. %%
  21. %% This program is free software: you can redistribute it and/or modify
  22. %% it under the terms of the GNU General Public License as published by
  23. %% the Free Software Foundation, either version 3 of the License, or
  24. %% (at your option) any later version.
  25. %%
  26. %% This program is distributed in the hope that it will be useful,
  27. %% but WITHOUT ANY WARRANTY; without even the implied warranty of
  28. %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  29. %% GNU General Public License for more details.
  30. %%
  31. %% You should have received a copy of the GNU General Public License
  32. %% along with this program. If not, see <http://www.gnu.org/licenses/>.
  33. function [] = sphear_octa_af_calibrate_measurements(path, first);
  34. if (strcmp(path, ""))
  35. path = "../data/current/";
  36. end
  37. %% location of sweep exported from aliki
  38. sweep_path = strcat(path, "export/sweep-001-F.wav");
  39. %% location of reverse sweep as exported from aliki
  40. rsweep_path = strcat(path, "export/sweep-001-I.wav");
  41. %% read sweep for file length
  42. [sweep, FS] = wavread(sweep_path);
  43. %%
  44. %% calculate impulse response of reference microphone
  45. %%
  46. printf("processing reference sweep\n");
  47. %% XXXX ref_ir = fconvolver(strcat(path, "capture/REF-001.wav"), rsweep_path);
  48. ref_ir = fconvolver(strcat(path, "capture/reference-001.wav"), rsweep_path);
  49. %% trim to exclude first reflections
  50. printf("finding peak...\n");
  51. [amps, locs, widths, residue] = sphear_findpeaks(abs(ref_ir), 10);
  52. %% now trim the ir (symmetric) to just before the first reflection
  53. ref_ir_trim = ref_ir(round(locs(1)) - (first*FS):(round(locs(1)) + (first*FS)));
  54. %% apply a blackman window
  55. ref_win = blackman(size(ref_ir_trim, 1));
  56. ref_ir_win = ref_ir_trim .* ref_win;
  57. %% and write it
  58. wavwrite(ref_ir_win, 24, strcat(path, "cal/reference-001-1.wav"));
  59. %% read inverse filter for the speaker
  60. %% this has to be calculated from the reference impulse response above...
  61. %% we need to recognize this and print a message so that this is run twice...
  62. ref = wavread(strcat(path, "cal/drc-filter.wav"));
  63. %% read measurement index file
  64. [measurements, azims, elevs, files] = textread(strcat(path, "capture/index.txt"), "%d %f %f %s");
  65. %% process all files
  66. for measurement = 1:size(measurements);
  67. printf("processing measurement %d, az=%f, el=%f, %s\n", measurement, azims(measurement), elevs(measurement), files(measurement){1,1});
  68. af = wavread(strcat(path, "capture/", regexprep(files(measurement){1,1}, "\"", "")));
  69. for capsule = 1:size(af, 2);
  70. %% process each capsule
  71. printf(" capsule %d\n", capsule);
  72. raw = strcat(path, "af/", "a-format-", sprintf("%.3d-%d.wav", measurement, capsule));
  73. wavwrite(af(:,capsule), FS, 24, raw);
  74. %% convolve captured data with reverse sweep and get ir
  75. printf(" convolving...\n");
  76. ir = fconvolver(raw, rsweep_path);
  77. %% trim to the valid region
  78. ir = ir(numel(sweep):numel(sweep)+numel(af(:,capsule)));
  79. %% FOR TESTING
  80. %% write raw impulse to file
  81. raw_file = strcat(path, "raw/", "a-format-", sprintf("%.3d-%d.wav", measurement, capsule));
  82. printf(" writing %s\n", raw_file);
  83. wavwrite(ir, FS, 24, raw_file);
  84. %% discard most of the impulse response data around the main peak,
  85. %% can be much shorter (almost down to the first reflection)
  86. trim = 0.050;
  87. if (measurement == 1 && capsule == 1)
  88. %% only find the peak in the first measurement and first capsule,
  89. %% we maintain the same trim after that to preserve the timing
  90. %% of all capsules and measurements
  91. [amps, locs, widths, residue] = sphear_findpeaks(abs(ir), 10);
  92. end
  93. ir_trim = ir(round(locs(1)) - (trim*FS):(round(locs(1)) + (trim*FS)));
  94. %% equalize ir with inverse filter for speaker
  95. ir_eq = conv(ir_trim, ref);
  96. if (measurement == 1 && capsule == 1)
  97. %% and find main peak for first measurement and capsule
  98. [eamps, elocs, ewidths, eresidue] = sphear_findpeaks(abs(ir_eq), 10);
  99. end
  100. %% now trim the ir (symmetric) to just before the first reflection
  101. ir_eq_trim = ir_eq(round(elocs(1)) - (first*FS):(round(elocs(1)) + (first*FS)));
  102. %% apply a blackman window
  103. win = blackman(size(ir_eq_trim, 1));
  104. ir_eq_win = ir_eq_trim .* win;
  105. %% write calibrated ir to file
  106. cal_file = strcat(path, "cal/", "a-format-", sprintf("%.3d-%d.wav", measurement, capsule));
  107. printf(" writing %s\n", cal_file);
  108. wavwrite(ir_eq_win, FS, 24, cal_file);
  109. ir_eq_win_all(:,capsule) = ir_eq_win;
  110. end
  111. %% write a multichannel version of the calibrated impulse response file
  112. %% all_file = strcat(path, "cal/", "a-format-", sprintf("%.3d.wav", measurement));
  113. %% printf(" writing %s\n", all_file);
  114. %% wavwrite(ir_eq_win_all, FS, 24, all_file);
  115. end
  116. end