Browse Source

add a design example that outlines the process of designing a simple A to B encoder

Fernando Pablo Lopez-Lezcano 9 years ago
parent
commit
90b5eadd79
1 changed files with 150 additions and 0 deletions
  1. 150 0
      calibration/src/sphear_design_example.m

+ 150 - 0
calibration/src/sphear_design_example.m

@@ -0,0 +1,150 @@
+%% -*- mode: octave -*-
+%%
+%% *SpHEAR Project
+%%
+%% Design a simple A2B encoder, static matrix and four (WXYZ) FIR filters
+%%
+%% Copyright 2016-2017, Fernando Lopez-Lezcano, All Rights Reserved
+%% nando@ccrma.stanford.edu
+%%
+%%  This program is free software: you can redistribute it and/or modify
+%%  it under the terms of the GNU General Public License as published by
+%%  the Free Software Foundation, either version 3 of the License, or
+%%  (at your option) any later version.
+%%
+%%  This program is distributed in the hope that it will be useful,
+%%  but WITHOUT ANY WARRANTY; without even the implied warranty of
+%%  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+%%  GNU General Public License for more details.
+%%
+%%  You should have received a copy of the GNU General Public License
+%%  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+%% root of the data files, assume we are running in the src/ directory
+DATA = "../data/";
+
+%% default for location of current measurements
+CURRENT = "current/";
+
+%% data is assumed to be in ../data/current/ which is usually a symbolic
+%% link to the real measurement directory
+
+%% before we start the design process we need to equalize the measurements
+%% to take into account the frequency response of the speaker used. The first
+%% step is to use the reference microphone measurement to design a filter that
+%% inverts the frequency response of the speaker. We use DRC to do this. 
+
+%% calculate speaker calibration filter from reference microphone
+%% (shell code, uses DRC for filter calculation)
+%% ./sphear_make_reference_filter emm-6-5850
+
+%% at this point we should have the raw impulse responses and a calibration
+%% filter in ../data/current/cal/drc-filter.wav (see the script for details
+%% on how this is done). We process all impulse responses through the filter
+%% and write calibrated impulse responses that are used for the rest of the
+%% design process. 
+
+%% read raw impulse response data and generate calibrated impulse responses
+
+sphear_af_calibrate((1:16), 0.0045, 0.001);
+
+%% (this is a version for the Octathingy which relies on recording two four
+%% channel impulse responses in Aliki - keep in mind that both recordings
+%% have to be processed and trimmed alike, otherwise there will be a mismatch
+%% in arrival times of the impulses)
+
+sphear_octa_af_calibrate((1:16), 0.004, 0.001);
+
+%% read all the calibrated A-format files
+[AF, FS] = sphear_af_read((1:16));
+
+%% just for checking the data, this plots the frequency response of each
+%% measurement for each capsule. 
+
+sphear_capsule_plot_frequency_response(AF, [1:16], 300, 20000, -60, -10, 48000, 8192);
+
+sphear_af_plot_frequency_response(AF, 300, 20000, -60, -10, 48000, 8192);
+
+%% calculate signal power in reference frequency interval for all
+%% measurements and capsules
+
+[R] = sphear_signal_power(AF, FS, 600, 1000, 8192);
+
+%% check that capsule signals are reasonable
+
+sphear_plot_r(R, 0);
+
+%% calculate a static A2B matrix based on the power measurements in the reference band
+
+[A2B, PV, COND] = sphear_calculate_a2b(R);
+
+%% generate a B-format signal using the A-format signal and the static A to B matrix
+
+[BF] = sphear_af_to_bf(AF, A2B);
+				  
+%% plot frequency response of B-format components for each measurement direction (just a test)
+
+sphear_bf_plot_frequency_response(BF, 300, 20000, -60, 0, 48000, 8192);
+
+%% calculate power of B-format signals in logarithmically spaced frequency bands
+
+[B, FC, FE] = sphear_signal_power_all(BF, FS, 300, 20000, 1200, 2400, 16, 8192);
+
+%% above the transition frequency (see plots above) the B-format behavior
+%% deviates from the ideal as the capsules are no longer co-located, we use
+%% the signal power to extract filter shapes from the B-format signals. 
+
+%% extract the shapes of wxyz filters
+
+[W X Y Z] = sphear_bf_extract_filter_shapes(B, OCTA_CARDINALS);
+
+[W X Y Z] = sphear_bf_extract_filter_shapes(B, TETRA_CARDINALS);
+
+[W X Y Z] = sphear_bf_extract_filter_shapes(B, [1:16]);
+
+%% now design four FIR filters, one for each B-format component
+
+[FIR] = sphear_design_fir_filters(FC, 512, 15, 48000, W, X, Y);
+
+%% in the case of the Octathingy we do use Z for now (this is a hack!)
+%%
+%% W needs a longer filter for our microphone, 512 really flattens,
+%% 256 makes a little bump at around 5KHz. XYZ are happy with a lot
+%% less, 128 seems fine
+
+[FIR] = sphear_design_fir_filters(FC, 512, 15, 48000, W, X, Y, Z);
+
+%% look at the shapes of the filters
+%% for tetrahedral microphones Z is an average estimation so do not plot it
+
+sphear_bf_plot_filters(FC, W, X, Y);
+
+sphear_bf_plot_filters(FC, W, X, Y, Z);
+
+%% re-calculate the full B-format signal with the filters
+
+[BF, BFF] = sphear_af_to_bf(AF, A2B, FIR, 8192);
+
+%% plot the frequency response of the B-format components for each measurement
+%% direction, they should all be flat
+
+sphear_bf_plot_frequency_response(BFF, 300, 20000, -35, -3, 48000, 8192);
+
+%% a revealing plot that highlights the cardinal direction response versus
+%% the diagonal direction response (incomplete code for the 8 capsule case)
+
+sphear_plot_directions(BFF, 300, 20000, -15, 3, 48000, 8192, 1);
+
+%% plot the polar response of the B-format components
+
+sphear_bf_plot_polar_response(BFF, 800, 1600, 300, 20000, 3, 8192, FS);
+
+%% replace the Z polar response with a virtual cardioid pointing in the forward direction
+
+sphear_bf_plot_polar_response(BFF, 800, 1600, 300, 20000, 3, 8192, FS, 1.0);
+
+%% write a simple Faust A to B encoder that includes the static matrix
+%% and all FIR filters (not efficient but works)
+
+sphear_write_simple_a2b_encoder(A2B, FIR);
+