Mercurial > hg > aimc
changeset 665:d0ff15c36828
Turn the AGC coeffs inside out: array of structs instead of a struct of little arrays.
In C++ use a vector<AGC_coeffs> for this; each of 4 stages has an entry; many fewer places
need to do indexing by stage, and this removes the temptation to use little eigen arrays
for the 4 stages.
Also latest version of experimental log-lag SAI hacks.
author | dicklyon@google.com |
---|---|
date | Tue, 21 May 2013 04:24:05 +0000 |
parents | 16918ffbf975 |
children | 6ec6b50f13da |
files | trunk/matlab/bmm/carfac/CARFAC_AGC_Step.m trunk/matlab/bmm/carfac/CARFAC_Close_AGC_Loop.m trunk/matlab/bmm/carfac/CARFAC_Design.m trunk/matlab/bmm/carfac/CARFAC_Init.m trunk/matlab/bmm/carfac/CARFAC_SAI_hacking.m trunk/matlab/bmm/carfac/CARFAC_Spatial_Smooth.m trunk/matlab/bmm/carfac/SAI_BlendFrameIntoComposite.m trunk/matlab/bmm/carfac/SAI_DesignLayers.m trunk/matlab/bmm/carfac/SAI_RunLayered.m trunk/matlab/bmm/carfac/SAI_StabilizeLayer.m trunk/matlab/bmm/carfac/SAI_UpdateBuffers.m |
diffstat | 11 files changed, 189 insertions(+), 100 deletions(-) [+] |
line wrap: on
line diff
--- a/trunk/matlab/bmm/carfac/CARFAC_AGC_Step.m Fri May 17 19:52:45 2013 +0000 +++ b/trunk/matlab/bmm/carfac/CARFAC_AGC_Step.m Tue May 21 04:24:05 2013 +0000 @@ -23,7 +23,7 @@ % one time step of the AGC state update; decimates internally stage = 1; -AGC_in = coeffs.detect_scale * detects; +AGC_in = coeffs(1).detect_scale * detects; [state, updated] = CARFAC_AGC_Recurse(coeffs, AGC_in, stage, state); @@ -33,36 +33,37 @@ % stage, state) % decim factor for this stage, relative to input or prev. stage: -decim = coeffs.decimation(stage); +decim = coeffs(stage).decimation; % decim phase of this stage (do work on phase 0 only): -decim_phase = mod(state(1).decim_phase(stage) + 1, decim); -state.decim_phase(stage) = decim_phase; +decim_phase = mod(state(stage).decim_phase + 1, decim); +state(stage).decim_phase = decim_phase; % accumulate input for this stage from detect or previous stage: -state.input_accum(:, stage) = state.input_accum(:, stage) + AGC_in; +state(stage).input_accum = state(stage).input_accum + 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. % 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 + AGC_in = state(stage).input_accum / decim; + state(stage).input_accum(:) = 0; % reset accumulator - if stage < length(coeffs.decimation) % recurse to evaluate next stage(s) + if stage < coeffs(1).n_AGC_stages 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); + AGC_in = AGC_in + ... + coeffs(stage).AGC_stage_gain * state(stage + 1).AGC_memory; end - AGC_stage_state = state.AGC_memory(:, stage); + AGC_stage_state = state(stage).AGC_memory; % first-order recursive smoothing filter update, in time: AGC_stage_state = AGC_stage_state + ... - coeffs.AGC_epsilon(stage) * (AGC_in - AGC_stage_state); + coeffs(stage).AGC_epsilon * (AGC_in - AGC_stage_state); % spatial smooth: AGC_stage_state = ... - CARFAC_Spatial_Smooth(coeffs, stage, 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; + state(stage).AGC_memory = AGC_stage_state; updated = 1; % bool to say we have new state else
--- a/trunk/matlab/bmm/carfac/CARFAC_Close_AGC_Loop.m Fri May 17 19:52:45 2013 +0000 +++ b/trunk/matlab/bmm/carfac/CARFAC_Close_AGC_Loop.m Tue May 21 04:24:05 2013 +0000 @@ -24,7 +24,7 @@ decim1 = CF.AGC_params.decimation(1); for ear = 1:CF.n_ears - undamping = 1 - CF.ears(ear).AGC_state.AGC_memory(:, 1); % stage 1 result + undamping = 1 - CF.ears(ear).AGC_state(1).AGC_memory; % stage 1 result % Update the target stage gain for the new damping: new_g = CARFAC_Stage_g(CF.ears(ear).CAR_coeffs, undamping); % set the deltas needed to get to the new damping:
--- a/trunk/matlab/bmm/carfac/CARFAC_Design.m Fri May 17 19:52:45 2013 +0000 +++ b/trunk/matlab/bmm/carfac/CARFAC_Design.m Tue May 21 04:24:05 2013 +0000 @@ -17,9 +17,10 @@ % See the License for the specific language governing permissions and % limitations under the License. -function CF = CARFAC_Design(n_ears, fs, CF_CAR_params, CF_AGC_params, CF_IHC_params) -% function CF = CARFAC_Design(fs, CF_CAR_params, ... -% CF_AGC_params, ERB_break_freq, ERB_Q, CF_IHC_params) +function CF = CARFAC_Design(n_ears, fs, ... + CF_CAR_params, CF_AGC_params, CF_IHC_params) +% function CF = CARFAC_Design(n_ears, fs, ... +% CF_CAR_params, CF_AGC_params, CF_IHC_params) % % This function designs the CARFAC (Cascade of Asymmetric Resonators with % Fast-Acting Compression); that is, it take bundles of parameters and @@ -125,16 +126,17 @@ pole_Hz = pole_Hz - CF_CAR_params.ERB_per_step * ... ERB_Hz(pole_Hz, CF_CAR_params.ERB_break_freq, CF_CAR_params.ERB_Q); end -% now we have n_ch, the number of channels, and pole_freqs array +% Now we have n_ch, the number of channels, and pole_freqs array. max_channels_per_octave = log(2) / log(pole_freqs(1)/pole_freqs(2)); -% convert to include an ear_array, each w coeffs and state... +% Convert to include an ear_array, each w coeffs and state... CAR_coeffs = CARFAC_DesignFilters(CF_CAR_params, fs, pole_freqs); AGC_coeffs = CARFAC_DesignAGC(CF_AGC_params, fs, n_ch); IHC_coeffs = CARFAC_DesignIHC(CF_IHC_params, fs, n_ch); -% copy same designed coeffs into each ear (can do differently in the -% future: + +% Copy same designed coeffs into each ear (can do differently in the +% future). for ear = 1:n_ears ears(ear).CAR_coeffs = CAR_coeffs; ears(ear).AGC_coeffs = AGC_coeffs; @@ -226,26 +228,30 @@ function AGC_coeffs = CARFAC_DesignAGC(AGC_params, fs, n_ch) n_AGC_stages = AGC_params.n_stages; -AGC_coeffs = struct( ... - 'n_ch', n_ch, ... - 'n_AGC_stages', n_AGC_stages, ... - 'AGC_stage_gain', AGC_params.AGC_stage_gain); % AGC1 pass is smoothing from base toward apex; % AGC2 pass is back, which is done first now (in double exp. version) AGC1_scales = AGC_params.AGC1_scales; AGC2_scales = AGC_params.AGC2_scales; -AGC_coeffs.AGC_epsilon = zeros(1, n_AGC_stages); % the 1/(tau*fs) roughly decim = 1; -AGC_coeffs.decimation = AGC_params.decimation; total_DC_gain = 0; + +%% +% Convert to vector of AGC coeffs +AGC_coeffs = struct([]); for stage = 1:n_AGC_stages + AGC_coeffs(stage).n_ch = n_ch; + AGC_coeffs(stage).n_AGC_stages = n_AGC_stages; + AGC_coeffs(stage).AGC_stage_gain = AGC_params.AGC_stage_gain; + + AGC_coeffs(stage).decimation = AGC_params.decimation(stage); tau = AGC_params.time_constants(stage); % time constant in seconds decim = decim * AGC_params.decimation(stage); % net decim to this stage % epsilon is how much new input to take at each update step: - AGC_coeffs.AGC_epsilon(stage) = 1 - exp(-decim / (tau * fs)); + AGC_coeffs(stage).AGC_epsilon = 1 - exp(-decim / (tau * fs)); + % effective number of smoothings in a time constant: ntimes = tau * (fs / decim); % typically 5 to 50 @@ -262,8 +268,8 @@ dp = delay * (1 - 2*p +p^2)/2; polez1 = p - dp; polez2 = p + dp; - AGC_coeffs.AGC_polez1(stage) = polez1; - AGC_coeffs.AGC_polez2(stage) = polez2; + AGC_coeffs(stage).AGC_polez1 = polez1; + AGC_coeffs(stage).AGC_polez2 = polez2; % try a 3- or 5-tap FIR as an alternative to the double exponential: n_taps = 0; @@ -292,46 +298,56 @@ n_taps, spread_sq, delay, n_iterations); end % when FIR_OK, store the resulting FIR design in coeffs: - AGC_coeffs.AGC_spatial_iterations(stage) = n_iterations; - AGC_coeffs.AGC_spatial_FIR(:,stage) = AGC_spatial_FIR; - AGC_coeffs.AGC_spatial_n_taps(stage) = n_taps; + AGC_coeffs(stage).AGC_spatial_iterations = n_iterations; + AGC_coeffs(stage).AGC_spatial_FIR = AGC_spatial_FIR; + AGC_coeffs(stage).AGC_spatial_n_taps = n_taps; % accumulate DC gains from all the stages, accounting for stage_gain: total_DC_gain = total_DC_gain + AGC_params.AGC_stage_gain^(stage-1); % TODO (dicklyon) -- is this the best binaural mixing plan? if stage == 1 - AGC_coeffs.AGC_mix_coeffs(stage) = 0; + AGC_coeffs(stage).AGC_mix_coeffs = 0; else - AGC_coeffs.AGC_mix_coeffs(stage) = AGC_params.AGC_mix_coeff / ... + AGC_coeffs(stage).AGC_mix_coeffs = AGC_params.AGC_mix_coeff / ... (tau * (fs / decim)); end end -AGC_coeffs.AGC_gain = total_DC_gain; - -% adjust the detect_scale to be the reciprocal DC gain of the AGC filters: -AGC_coeffs.detect_scale = 1 / total_DC_gain; +% adjust stage 1 detect_scale to be the reciprocal DC gain of the AGC filters: +AGC_coeffs(1).detect_scale = 1 / total_DC_gain; %% -function [FIR, OK] = Design_FIR_coeffs(n_taps, var, mn, n_iter) -% function [FIR, OK] = Design_FIR_coeffs(n_taps, spread_sq, delay, n_iter) +function [FIR, OK] = Design_FIR_coeffs(n_taps, delay_variance, ... + mean_delay, n_iter) +% function [FIR, OK] = Design_FIR_coeffs(n_taps, delay_variance, ... +% mean_delay, n_iter) +% The smoothing function is a space-domain smoothing, but it considered +% here by analogy to time-domain smoothing, which is why its potential +% off-centeredness is called a delay. Since it's a smoothing filter, it is +% also analogous to a discrete probability distribution (a p.m.f.), with +% mean corresponding to delay and variance corresponding to squared spatial +% spread (in samples, or channels, and the square thereof, respecitively). +% Here we design a filter implementation's coefficient via the method of +% moment matching, so we get the intended delay and spread, and don't worry +% too much about the shape of the distribution, which will be some kind of +% blob not too far from Gaussian if we run several FIR iterations. % reduce mean and variance of smoothing distribution by n_iterations: -mn = mn / n_iter; -var = var / n_iter; +mean_delay = mean_delay / n_iter; +delay_variance = delay_variance / n_iter; switch n_taps case 3 % based on solving to match mean and variance of [a, 1-a-b, b]: - a = (var + mn*mn - mn) / 2; - b = (var + mn*mn + mn) / 2; + a = (delay_variance + mean_delay*mean_delay - mean_delay) / 2; + b = (delay_variance + mean_delay*mean_delay + mean_delay) / 2; FIR = [a, 1 - a - b, b]; OK = FIR(2) >= 0.2; case 5 % based on solving to match [a/2, a/2, 1-a-b, b/2, b/2]: - a = ((var + mn*mn)*2/5 - mn*2/3) / 2; - b = ((var + mn*mn)*2/5 + mn*2/3) / 2; + a = ((delay_variance + mean_delay*mean_delay)*2/5 - mean_delay*2/3) / 2; + b = ((delay_variance + mean_delay*mean_delay)*2/5 + mean_delay*2/3) / 2; % first and last coeffs are implicitly duplicated to make 5-point FIR: FIR = [a/2, 1 - a - b, b/2]; OK = FIR(2) >= 0.1;
--- a/trunk/matlab/bmm/carfac/CARFAC_Init.m Fri May 17 19:52:45 2013 +0000 +++ b/trunk/matlab/bmm/carfac/CARFAC_Init.m Tue May 21 04:24:05 2013 +0000 @@ -48,13 +48,15 @@ function state = AGC_Init_State(coeffs) -n_ch = coeffs.n_ch; -n_AGC_stages = coeffs.n_AGC_stages; -state = struct( ... - 'AGC_memory', zeros(n_ch, n_AGC_stages), ... - 'input_accum', zeros(n_ch, n_AGC_stages), ... - 'decim_phase', zeros(n_AGC_stages, 1) ... % integer decimator phase - ); +n_ch = coeffs(1).n_ch; +n_AGC_stages = coeffs(1).n_AGC_stages; +state = struct([]); +for stage = 1:n_AGC_stages + % Initialize state recursively... + state(stage).AGC_memory = zeros(n_ch, 1); + state(stage).input_accum = zeros(n_ch, 1); + state(stage).decim_phase = 0; % integer decimator phase +end function state = IHC_Init_State(coeffs)
--- a/trunk/matlab/bmm/carfac/CARFAC_SAI_hacking.m Fri May 17 19:52:45 2013 +0000 +++ b/trunk/matlab/bmm/carfac/CARFAC_SAI_hacking.m Tue May 21 04:24:05 2013 +0000 @@ -28,6 +28,8 @@ dB_list = -40; % -60:20:0 wav_fn = 'plan.wav'; +wav_fn = 'Stiletto44.wav'; +wav_fn = 'You Can Call Me Al.wav'; if ~exist(['./', wav_fn], 'file') error('wav file not found') @@ -36,14 +38,14 @@ wav_fn [file_signal, fs] = wavread(wav_fn); -if fs == 44100 - file_signal = (file_signal(1:2:end-1, :) + file_signal(2:2:end, :)) / 2; - fs = fs / 2; -end - -if fs ~= 22050 - error('unexpected sample rate') -end +% if fs == 44100 +% file_signal = (file_signal(1:2:end-1, :) + file_signal(2:2:end, :)) / 2; +% fs = fs / 2; +% end +% +% if fs ~= 22050 +% error('unexpected sample rate') +% end file_signal = file_signal(:, 1); % mono file_signal = [file_signal; zeros(fs, 1)]; % pad with a second of silence @@ -56,7 +58,7 @@ end %% -CF_struct = CARFAC_Design(1); % default design +CF_struct = CARFAC_Design(1, fs); % default design CF_struct = CARFAC_Init(CF_struct); @@ -70,3 +72,4 @@ %% system('rm -r frames'); +
--- a/trunk/matlab/bmm/carfac/CARFAC_Spatial_Smooth.m Fri May 17 19:52:45 2013 +0000 +++ b/trunk/matlab/bmm/carfac/CARFAC_Spatial_Smooth.m Tue May 21 04:24:05 2013 +0000 @@ -17,17 +17,17 @@ % See the License for the specific language governing permissions and % limitations under the License. -function stage_state = CARFAC_Spatial_Smooth(coeffs, stage, stage_state) +function stage_state = CARFAC_Spatial_Smooth(coeffs, stage_state) % function AGC_state = CARFAC_Spatial_Smooth( ... % n_taps, n_iterations, FIR_coeffs, AGC_state) -n_iterations = coeffs.AGC_spatial_iterations(stage); +n_iterations = coeffs.AGC_spatial_iterations; use_FIR = n_iterations < 4; % or whatever condition we want to try if use_FIR - FIR_coeffs = coeffs.AGC_spatial_FIR(:,stage); - switch coeffs.AGC_spatial_n_taps(stage) + FIR_coeffs = coeffs.AGC_spatial_FIR; + switch coeffs.AGC_spatial_n_taps case 3 for iter = 1:n_iterations stage_state = ...
--- a/trunk/matlab/bmm/carfac/SAI_BlendFrameIntoComposite.m Fri May 17 19:52:45 2013 +0000 +++ b/trunk/matlab/bmm/carfac/SAI_BlendFrameIntoComposite.m Tue May 21 04:24:05 2013 +0000 @@ -21,6 +21,21 @@ layer_struct, composite_frame) new_frame = layer_struct.frame; +n_ch = size(new_frame, 1); + +if layer_struct.right_overlap == 0 % A layer 1 hack only. + for row = 1:n_ch + % Taper new_frame down near zero lag for a nicer result... + taper_size = round(6 + 60*(row/n_ch)^2); % hack + zero_pos = layer_struct.frame_width - layer_struct.future_lags; + taper = [-taper_size:min(taper_size, layer_struct.future_lags)]; + col_range = zero_pos + taper; + taper = (0.4 + 0.6*abs(taper) / taper_size) .^ 2; + taper(taper == 0) = 0.5; + new_frame(row, col_range) = new_frame(row, col_range) .* taper; + end +end + alpha = layer_struct.alpha; lag_curve = layer_struct.lag_curve; target_columns = layer_struct.target_indices;
--- a/trunk/matlab/bmm/carfac/SAI_DesignLayers.m Fri May 17 19:52:45 2013 +0000 +++ b/trunk/matlab/bmm/carfac/SAI_DesignLayers.m Tue May 21 04:24:05 2013 +0000 @@ -17,8 +17,8 @@ % See the License for the specific language governing permissions and % limitations under the License. -function [layer_array, total_width] = SAI_DesignLayers( ... - n_layers, width_per_layer) +function [layer_array, total_width, lag_period_samples] = SAI_DesignLayers( ... + n_layers, width_per_layer, seglen) % function [layer_array, total_width] = SAI_DesignLayers( ... % n_layers, width_per_layer) % @@ -41,24 +41,24 @@ % Other fields could be added to hold state, such as history buffers for % each layer, or those could go in state struct array... - % Elevate these to a param struct? if nargin < 1 - n_layers = 11 + n_layers = 12; end if nargin < 2 - width_per_layer = 32; % resolution "half life" in space + width_per_layer = 24; % resolution "half life" in space; half-semitones end -future_lags = 4 * width_per_layer; -width_first_layer = future_lags + 1 * width_per_layer; -width_extra_last_layer = 2 * width_per_layer; -left_overlap = 15; -right_overlap = 15; -first_window_width = 400; % or maybe use seglen? or 0.020 * fs? +future_lags = 0 * width_per_layer; +width_extra_last_layer = 0 * width_per_layer; +left_overlap = 10; +right_overlap = 10; +first_window_width = seglen; % Less would be a problem. min_window_width = 1*width_per_layer; % or somewhere on that order window_exponent = 1.4; alpha_max = 1; +width_first_layer = future_lags + 2 * width_per_layer; + % Start with NAP_samples_per_SAI_sample, declining to 1 from here: max_samples_per = 2^(n_layers - 1); % Construct the overall lag-warping function: @@ -66,7 +66,11 @@ max_samples_per * ones(1, width_extra_last_layer), ... max_samples_per * ... 2 .^ (-(1:(width_per_layer * (n_layers - 1))) / width_per_layer), ... - ones(1, width_first_layer)]; + ones(1, width_first_layer), ]; % w/o future for now. + +lag_period_samples = cumsum(NAP_samples_per_SAI_sample(end:-1:1)); +lag_period_samples = lag_period_samples(end:-1:1); % Put it back in order. +lag_period_samples = lag_period_samples - lag_period_samples(end - future_lags); % Each layer needs a lag_warp for a portion of that, divided by % 2^(layer-1), where the portion includes some overlap into its neighbors @@ -171,6 +175,11 @@ layer_array(layer).n_window_pos = n_triggers; layer_array(layer).buffer_width = layer_array(layer).frame_width + ... floor((1 + (n_triggers - 1)/2) * layer_array(layer).window_width); + % Make sure it's big enough for next layer to shift in what it wants. + n_shift = ceil(seglen / (2.0^(layer - 1))); + if layer_array(layer).buffer_width < 6 + n_shift; + layer_array(layer).buffer_width = 6 + n_shift; + end end return
--- a/trunk/matlab/bmm/carfac/SAI_RunLayered.m Fri May 17 19:52:45 2013 +0000 +++ b/trunk/matlab/bmm/carfac/SAI_RunLayered.m Tue May 21 04:24:05 2013 +0000 @@ -33,16 +33,32 @@ end fs = CF.fs; +seglen = round(fs / 30); % Pick about 30 fps +frame_rate = fs / seglen; + % Design the composite log-lag SAI using these parameters and defaults. -n_layers = 10; -width_per_layer = 40; -[layer_array, total_width] = SAI_DesignLayers(n_layers, width_per_layer); +n_layers = 15 +width_per_layer = 36; +[layer_array, total_width, lags] = ... + SAI_DesignLayers(n_layers, width_per_layer, seglen); + +% Find where in the lag curve corresponds to the piano black keys: +pitches = fs ./ lags; +key_indices = []; +df = log(2)/width_per_layer; +for f = [BlackKeyFrequencies, 8, 4, 2, 1-df, 1, 1+df, 0.5, 0.25, 0.125, ... + -2000, -1000, -500, -250, -125]; % Augment with beat. + [dist, index] = min((f - pitches).^2); + key_indices = [key_indices, index]; +end +piano = zeros(1, total_width); +piano(key_indices) = 1; +piano = [piano; piano; piano]; + % Make the composite SAI image array. composite_frame = zeros(n_ch, total_width); -seglen = round(fs / 30); % Pick about 60 fps -frame_rate = fs / seglen; n_segs = ceil(n_samp / seglen); % Make the history buffers in the layers_array: @@ -53,10 +69,14 @@ layer_array(layer).frame = zeros(n_ch, layer_array(layer).frame_width); end -n_marginal_rows = 34; +n_marginal_rows = 100; marginals = []; +average_composite = 0; -average_frame = 0; +future_lags = layer_array(1).future_lags; +% marginals_frame = zeros(total_width - future_lags + 2*n_ch, total_width); +marginals_frame = zeros(n_ch, total_width); + for seg_num = 1:n_segs % k_range is the range of input sample indices for this segment if seg_num == n_segs @@ -77,40 +97,54 @@ % Shift new data into some or all of the layer buffers: layer_array = SAI_UpdateBuffers(layer_array, seg_naps, seg_num); - - for layer = n_layers:-1:1 % blend from coarse to fine + for layer = n_layers:-1:1 % Stabilize and blend from coarse to fine update_interval = layer_array(layer).update_interval; if 0 == mod(seg_num, update_interval) layer_array(layer) = SAI_StabilizeLayer(layer_array(layer)); - new_frame = layer_array(layer).frame; composite_frame = SAI_BlendFrameIntoComposite( ... layer_array(layer), composite_frame); end end + + average_composite = average_composite + ... + 0.01 * (composite_frame - average_composite); if isempty(marginals) - composite_width = size(composite_frame, 2); - marginals = zeros(n_marginal_rows, composite_width); + marginals = zeros(n_marginal_rows, total_width); end for row = n_marginal_rows:-1:11 % smooth from row above (lower number) marginals(row, :) = marginals(row, :) + ... - 2^((10 - row)/2) * (1.06*marginals(row - 1, :) - marginals(row, :)); + 2^((10 - row)/8) * (1.01*marginals(row - 1, :) - marginals(row, :)); end lag_marginal = mean(composite_frame, 1); % means max out near 1 or 2 + lag_marginal = lag_marginal - 0.75*smooth1d(lag_marginal, 30)'; + + freq_marginal = mean(layer_array(1).nap_buffer); + % emphasize local peaks: + freq_marginal = freq_marginal - 0.5*smooth1d(freq_marginal, 5)'; + + +% marginals_frame = [marginals_frame(:, 2:end), ... +% [lag_marginal(1:(end - future_lags)), freq_marginal(ceil((1:(2*end))/2))]']; + marginals_frame = [marginals_frame(:, 2:end), freq_marginal(1:end)']; + for row = 10:-1:1 - marginals(row, :) = (lag_marginal - smooth1d(lag_marginal, 30)') - ... - (10 - row) / 40; + marginals(row, :) = lag_marginal - (10 - row) / 40; end if 0 == mod(seg_num, update_interval) || seg_num == 1 coc_gram = layer_array(end).nap_buffer'; [n_ch, n_width] = size(composite_frame); coc_gram = [coc_gram, zeros(n_ch, n_width - size(coc_gram, 2))]; + coc_gram = coc_gram(:, (end-total_width+1):end); end - display_frame = [coc_gram; ... - composite_frame(floor(1:0.5:end), :); 20*max(0,marginals)]; + display_frame = [ ... % coc_gram; ... + 4 * marginals_frame; ... + composite_frame(ceil((1:(2*end))/2), :); ... + piano; ... + 10*max(0,marginals)]; cmap = jet; cmap = 1 - gray; % jet @@ -127,5 +161,13 @@ return +function frequencies = BlackKeyFrequencies +black_indices = []; +for index = 0:87 + if any(mod(index, 12) == [1 4 6 9 11]) + black_indices = [black_indices, index]; + end +end +frequencies = 27.5 * 2.^(black_indices / 12);
--- a/trunk/matlab/bmm/carfac/SAI_StabilizeLayer.m Fri May 17 19:52:45 2013 +0000 +++ b/trunk/matlab/bmm/carfac/SAI_StabilizeLayer.m Tue May 21 04:24:05 2013 +0000 @@ -44,7 +44,6 @@ if peak_val <= 0 % just use window center instead [peak_val, trigger_time] = max(window); end - % TODO(dicklyon): alpha blend here. trigger_time = trigger_time + floor((w - 1) * d_win); alpha = (0.025 + peak_val) / (0.5 + peak_val); % alpha 0.05 to near 1.0 frame(ch, :) = alpha * nap_wave(trigger_time + offset_range)' + ...
--- a/trunk/matlab/bmm/carfac/SAI_UpdateBuffers.m Fri May 17 19:52:45 2013 +0000 +++ b/trunk/matlab/bmm/carfac/SAI_UpdateBuffers.m Tue May 21 04:24:05 2013 +0000 @@ -42,7 +42,7 @@ %% % Decimate using a 2-3-4-filter and partial differencing emphasize onsets: kernel = filter([1 1]/2, 1, filter([1 1 1]/3, 1, [1 1 1 1 0 0 0 0]/4)); -kernel = kernel + 2*diff([0, kernel]); +% kernel = kernel + 2*diff([0, kernel]); % figure(1) % plot(kernel) @@ -65,11 +65,13 @@ n_shift = floor(n_shift); % Grab new stuff from new end (big time indices) of previous layer. % Take twice as many times as we need, + 5, for decimation, and do - % 343 smoothing to get new points. + % smoothing to get new points. new_chunk = ... layer_array(layer - 1).nap_buffer((end - 2*n_shift - 4):end, :); new_chunk = filter(kernel, 1, new_chunk); - new_chunk = gain * new_chunk(7:2:end, :); + % new_chunk = gain * new_chunk(7:2:end, :); + % try a little extra smoothing: + new_chunk = gain * (new_chunk(7:2:end, :) + new_chunk(6:2:(end-1), :))/2; end % Put new stuff in at latest time indices.