annotate trunk/matlab/bmm/carfac/SAI_StabilizeLayer.m @ 675:920a5d853b97

Some cleanups of internal SAI computation to improve readability.
author ronw@google.com
date Fri, 24 May 2013 17:04:33 +0000
parents d0ff15c36828
children 597913e855fd
rev   line source
dicklyon@619 1 function layer_struct = SAI_StabilizeLayer(layer_struct)
dicklyon@619 2 % Pick trigger points in buffer, shift rows to offset_from_end,
dicklyon@619 3 % and blend into frame
dicklyon@619 4
dicklyon@619 5 frame = layer_struct.frame;
dicklyon@619 6
dicklyon@619 7 nap_buffer = real(layer_struct.nap_buffer);
dicklyon@619 8 n_buffer_times = size(nap_buffer, 1);
dicklyon@619 9 [n_ch, width] = size(frame);
dicklyon@619 10
dicklyon@619 11 % Make the window to use for all the channels at this layer.
ronw@675 12 window_width = layer_struct.window_width;
dicklyon@619 13 n_window_pos = layer_struct.n_window_pos;
dicklyon@619 14 % Windows are always (approx) 50% overlapped:
ronw@675 15 window_hop = window_width / 2;
dicklyon@619 16
ronw@675 17 window = sin((1:window_width)' * pi / window_width);
ronw@675 18 window_start = (n_buffer_times - window_width) - ...
ronw@675 19 floor((n_window_pos - 1) * window_hop);
ronw@675 20 window_range = (1:window_width) + window_start - layer_struct.future_lags;
dicklyon@619 21 % This should not go negative!
ronw@675 22 offset_range = (1:width) + window_start - width;
dicklyon@619 23 % CHECK
dicklyon@619 24 if any(offset_range < 0)
dicklyon@619 25 error;
dicklyon@619 26 end
dicklyon@619 27
dicklyon@619 28 % smooth across channels; more in later layers
dicklyon@619 29 smoothed_buffer = smooth1d(nap_buffer', layer_struct.channel_smoothing_scale)';
dicklyon@619 30
dicklyon@619 31 % For each buffer column (channel), pick a trigger and align into SAI_frame
dicklyon@619 32 for ch = 1:n_ch
dicklyon@619 33 smooth_wave = smoothed_buffer(:, ch); % for the trigger
dicklyon@619 34
dicklyon@619 35 % Do several window positions and triggers
dicklyon@619 36 for w = 1:n_window_pos
ronw@675 37 % move the window to later and go again
ronw@675 38 current_window_offset = floor((w - 1) * window_hop);
ronw@675 39 [peak_val, trigger_time] = ...
ronw@675 40 max(smooth_wave(window_range + current_window_offset) .* window);
dicklyon@619 41 nap_wave = nap_buffer(:, ch); % for the waveform
dicklyon@619 42 if peak_val <= 0 % just use window center instead
dicklyon@619 43 [peak_val, trigger_time] = max(window);
dicklyon@619 44 end
ronw@675 45 trigger_time = trigger_time + current_window_offset;
dicklyon@619 46 alpha = (0.025 + peak_val) / (0.5 + peak_val); % alpha 0.05 to near 1.0
dicklyon@619 47 frame(ch, :) = alpha * nap_wave(trigger_time + offset_range)' + ...
dicklyon@619 48 (1 - alpha) * frame(ch, :);
dicklyon@619 49 end
dicklyon@619 50 end
dicklyon@619 51
dicklyon@619 52 layer_struct.frame = frame;