annotate matlab/bmm/carfac/SAI_StabilizeLayer.m @ 609:aefe2ca0674f

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