Mercurial > hg > aimc
diff matlab/bmm/carfac/CARFAC_AGC_Step.m @ 498:056df17e0898
Simplify AGC_Step, moving multi-aural cross coupling to new function CARFAC_Cross_Couple
author | dicklyon@google.com |
---|---|
date | Tue, 10 Apr 2012 05:40:18 +0000 |
parents | 52f659be9008 |
children | a0869cb1c99b |
line wrap: on
line diff
--- a/matlab/bmm/carfac/CARFAC_AGC_Step.m Mon Apr 09 06:15:05 2012 +0000 +++ b/matlab/bmm/carfac/CARFAC_AGC_Step.m Tue Apr 10 05:40:18 2012 +0000 @@ -17,96 +17,53 @@ % See the License for the specific language governing permissions and % limitations under the License. -function [state, updated] = CARFAC_AGC_Step(AGC_coeffs, detects, state) -% function [state, updated] = CARFAC_AGC_Step(AGC_coeffs, detects, state) +function [state, updated] = CARFAC_AGC_Step(coeffs, detects, state) +% function [state, updated] = CARFAC_AGC_Step(coeffs, detects, state) % -% one time step (at decimated low AGC rate) of the AGC state update - -n_ears = length(state); -[n_ch, n_AGC_stages] = size(state(1).AGC_memory); % number of channels - -optimize_for_mono = n_ears == 1; % mono optimization +% one time step of the AGC state update; decimates internally stage = 1; -ins = AGC_coeffs.detect_scale * detects; -[state, updated] = CARFAC_AGC_Recurse(AGC_coeffs, ins, n_AGC_stages, ... - n_ears, n_ch, optimize_for_mono, stage, state); +AGC_in = coeffs.detect_scale * detects; +[state, updated] = CARFAC_AGC_Recurse(coeffs, AGC_in, stage, state); +function [state, updated] = CARFAC_AGC_Recurse(coeffs, AGC_in, ... + stage, state) +% function [state, updated] = CARFAC_AGC_Recurse(coeffs, AGC_in, ... +% stage, state) - - -function [state, updated] = CARFAC_AGC_Recurse(coeffs, ins, n_stages, ... - n_ears, n_ch, mono, stage, state) -% function [state, updated = CARFAC_AGC_Recurse(coeffs, ins, n_stages, ... -% n_ears, n_ch, mono, stage, state) - -decim = coeffs.decimation(stage); % decim phase for this stage +% decim factor for this stage, relative to input or prev. stage: +decim = coeffs.decimation(stage); +% decim phase of this stage (do work on phase 0 only): decim_phase = mod(state(1).decim_phase(stage) + 1, decim); -state(1).decim_phase(stage) = decim_phase; +state.decim_phase(stage) = decim_phase; % accumulate input for this stage from detect or previous stage: -for ear = 1:n_ears - state(ear).input_accum(:, stage) = ... - state(ear).input_accum(:, stage) + ins(:, ear); -end +state.input_accum(:, stage) = state.input_accum(:, stage) + AGC_in; % nothing else to do if it's not the right decim_phase if decim_phase == 0 - % do lots of work, at decimated rate + % do lots of work, at decimated rate. + % decimated inputs for this stage, and to be decimated more for next: + AGC_in = state.input_accum(:, stage) / decim; + state.input_accum(:, stage) = 0; % reset accumulator - % decimated inputs for this stage, and to be decimated more for next: - for ear = 1:n_ears - ins(:,ear) = state(ear).input_accum(:, stage) / decim; - state(ear).input_accum(:, stage) = 0; % reset accumulator + if stage < length(coeffs.decimation) % recurse to evaluate next stage(s) + state = CARFAC_AGC_Recurse(coeffs, AGC_in, stage+1, state); + % and add its output to this stage input, whether it updated or not: + AGC_in = AGC_in + coeffs.AGC_stage_gain * state.AGC_memory(:, stage+1); end - if stage < n_stages % recurse to evaluate next stage(s) - state = CARFAC_AGC_Recurse(coeffs, ins, n_stages, ... - n_ears, n_ch, mono, stage+1, state); - end + AGC_stage_state = state.AGC_memory(:, stage); + % first-order recursive smoothing filter update, in time: + AGC_stage_state = AGC_stage_state + ... + coeffs.AGC_epsilon(stage) * (AGC_in - AGC_stage_state); + % spatial smooth: + AGC_stage_state = ... + CARFAC_Spatial_Smooth(coeffs, stage, AGC_stage_state); + % and store the state back (in C++, do it all in place?) + state.AGC_memory(:, stage) = AGC_stage_state; - epsilon = coeffs.AGC_epsilon(stage); % for this stage's LPF pole - stage_gain = coeffs.AGC_stage_gain; - - for ear = 1:n_ears - AGC_in = ins(:,ear); % the newly decimated input for this ear - - % add the latest output (state) of next stage... - if stage < n_stages - AGC_in = AGC_in + stage_gain * state(ear).AGC_memory(:, stage+1); - end - - AGC_stage_state = state(ear).AGC_memory(:, stage); - % first-order recursive smoothing filter update, in time: - AGC_stage_state = AGC_stage_state + ... - epsilon * (AGC_in - AGC_stage_state); - % spatial smooth: - AGC_stage_state = ... - CARFAC_Spatial_Smooth(coeffs, stage, AGC_stage_state); - % and store the state back (in C++, do it all in place?) - state(ear).AGC_memory(:, stage) = AGC_stage_state; - - if ~mono - if ear == 1 - this_stage_sum = AGC_stage_state; - else - this_stage_sum = this_stage_sum + AGC_stage_state; - end - end - end - if ~mono - mix_coeff = coeffs.AGC_mix_coeffs(stage); - if mix_coeff > 0 - this_stage_mean = this_stage_sum / n_ears; - for ear = 1:n_ears - state(ear).AGC_memory(:, stage) = ... - state(ear).AGC_memory(:, stage) + ... - mix_coeff * ... - (this_stage_mean - state(ear).AGC_memory(:, stage)); - end - end - end updated = 1; % bool to say we have new state else updated = 0;