Mercurial > hg > aimc
changeset 619:2e456754fe20
Better functionization of SAI, and new way to make picture with lag
marginal and smoothed history of lag marginal.
author | dicklyon@google.com |
---|---|
date | Mon, 13 May 2013 21:15:56 +0000 |
parents | e01caec17186 |
children | 9c268a806bf2 |
files | trunk/matlab/bmm/carfac/MakeMovieFromPngsAndWav.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 | 6 files changed, 96 insertions(+), 63 deletions(-) [+] |
line wrap: on
line diff
--- a/trunk/matlab/bmm/carfac/MakeMovieFromPngsAndWav.m Fri May 10 20:12:49 2013 +0000 +++ b/trunk/matlab/bmm/carfac/MakeMovieFromPngsAndWav.m Mon May 13 21:15:56 2013 +0000 @@ -20,7 +20,7 @@ function MakeMovieFromPngsAndWav(frame_rate, png_name_pattern, ... wav_filename, out_filename) -system(['rm ', out_filename]); +system(['rm "', out_filename, '"']); if ~exist(wav_filename, 'file') error('wave file is missing', wav_filename) @@ -29,8 +29,8 @@ ffmpeg_command = ['/opt/local/bin/ffmpeg' ... ' -r ' num2str(frame_rate) ... ' -i ' png_name_pattern ... - ' -i ' wav_filename ... - ' -b:v 1024k' ... - ' ' out_filename]; + ' -i "' wav_filename ... + '" -b:v 1024k' ... + ' "' out_filename '"']; system(ffmpeg_command);
--- a/trunk/matlab/bmm/carfac/SAI_BlendFrameIntoComposite.m Fri May 10 20:12:49 2013 +0000 +++ b/trunk/matlab/bmm/carfac/SAI_BlendFrameIntoComposite.m Mon May 13 21:15:56 2013 +0000 @@ -17,9 +17,10 @@ % See the License for the specific language governing permissions and % limitations under the License. -function composite_frame = SAI_BlendFrameIntoComposite(new_frame, ... +function composite_frame = SAI_BlendFrameIntoComposite( ... layer_struct, composite_frame) +new_frame = layer_struct.frame; 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 10 20:12:49 2013 +0000 +++ b/trunk/matlab/bmm/carfac/SAI_DesignLayers.m Mon May 13 21:15:56 2013 +0000 @@ -49,15 +49,15 @@ if nargin < 2 width_per_layer = 32; % resolution "half life" in space end -future_lags = 3 * width_per_layer; -width_first_layer = future_lags + 2 * width_per_layer; +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? -min_window_width = 2*width_per_layer; % or somewhere on that order +min_window_width = 1*width_per_layer; % or somewhere on that order window_exponent = 1.4; -alpha_max = 0.5; +alpha_max = 1; % Start with NAP_samples_per_SAI_sample, declining to 1 from here: max_samples_per = 2^(n_layers - 1); @@ -121,6 +121,9 @@ layer_array(layer).alpha = alpha * alpha_max; offset = offset + width; % total width from left through this layer. + + % Smooth across channels a little before picking triggers: + layer_array(layer).channel_smoothing_scale = 0.25*(layer-1); end total_width = offset; % Return size of SAI this will make. @@ -165,8 +168,9 @@ % location in the range of the window to a fixed location. Assume % using two window placements overlapped 50%. n_triggers = 2; + layer_array(layer).n_window_pos = n_triggers; layer_array(layer).buffer_width = layer_array(layer).frame_width + ... - ceil((1 + (n_triggers - 1)/2) * layer_array(layer).window_width); + floor((1 + (n_triggers - 1)/2) * layer_array(layer).window_width); end return
--- a/trunk/matlab/bmm/carfac/SAI_RunLayered.m Fri May 10 20:12:49 2013 +0000 +++ b/trunk/matlab/bmm/carfac/SAI_RunLayered.m Mon May 13 21:15:56 2013 +0000 @@ -41,7 +41,7 @@ % Make the composite SAI image array. composite_frame = zeros(n_ch, total_width); -seglen = round(fs * 0.020); % Pick about 20 ms segments +seglen = round(fs / 30); % Pick about 60 fps frame_rate = fs / seglen; n_segs = ceil(n_samp / seglen); @@ -49,8 +49,14 @@ for layer = 1:n_layers layer_array(layer).nap_buffer = zeros(layer_array(layer).buffer_width, n_ch); layer_array(layer).nap_fraction = 0; % leftover fraction to shift in. + % The SAI frame is transposed to be image-like. + layer_array(layer).frame = zeros(n_ch, layer_array(layer).frame_width); end +n_marginal_rows = 34; +marginals = []; + +average_frame = 0; for seg_num = 1:n_segs % k_range is the range of input sample indices for this segment if seg_num == n_segs @@ -75,69 +81,36 @@ for layer = n_layers:-1:1 % blend from coarse to fine update_interval = layer_array(layer).update_interval; if 0 == mod(seg_num, update_interval) - nap_buffer = real(layer_array(layer).nap_buffer); - n_buffer_times = size(nap_buffer, 1); - width = layer_array(layer).frame_width; % To render linear SAI to. - new_frame = zeros(n_ch, width); - - % Make the window to use for all the channels at this layer. - layer_factor = 1.5; - window_size = layer_array(layer).window_width; - after_samples = layer_array(layer).future_lags; - - window_range = (1:window_size) + ... - (n_buffer_times - window_size) - after_samples; - window = sin((1:window_size)' * pi / window_size); - % This should not go negative! - offset_range = (1:width) + ... - (n_buffer_times - width - window_size); - % CHECK - if any(offset_range < 0) - error; - end - - % smooth across channels; more in later layers - smoothed_buffer = smooth1d(nap_buffer', 0.25*(layer - 2))'; - - % For each buffer column (channel), pick a trigger and align into SAI_frame - for ch = 1:n_ch - smooth_wave = smoothed_buffer(:, ch); % for the trigger - - [peak_val, trigger_time] = max(smooth_wave(window_range) .* window); - nap_wave = nap_buffer(:, ch); % for the waveform - if peak_val <= 0 % just use window center instead - [peak_val, trigger_time] = max(window); - end - if layer == n_layers % mark the trigger points to display as imaginary. - layer_array(layer).nap_buffer(trigger_time + window_range(1) - 1, ch) = ... - layer_array(layer).nap_buffer(trigger_time + window_range(1) - 1, ch) + 1i; - end - new_frame(ch, :) = nap_wave(trigger_time + offset_range)'; - end - composite_frame = SAI_BlendFrameIntoComposite(new_frame, ... + 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 - - + + if isempty(marginals) + composite_width = size(composite_frame, 2); + marginals = zeros(n_marginal_rows, composite_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, :)); + end lag_marginal = mean(composite_frame, 1); % means max out near 1 or 2 - frame_bottom = zeros(size(composite_frame)); % will end up being 1/3 - n_bottom_rows = size(frame_bottom, 1); - for height = 1:n_bottom_rows - big_ones = lag_marginal > 1*height/n_bottom_rows; - frame_bottom(n_bottom_rows - height + 1, big_ones) = 2; % 2 for black + for row = 10:-1:1 + marginals(row, :) = (lag_marginal - smooth1d(lag_marginal, 30)') - ... + (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))]; - trigger_gram = 2 * (imag(coc_gram) ~= 0); - coc_gram = real(coc_gram); end - display_frame = [coc_gram; trigger_gram; ... - composite_frame(floor(1:0.5:end), :); frame_bottom]; + display_frame = [coc_gram; ... + composite_frame(floor(1:0.5:end), :); 20*max(0,marginals)]; cmap = jet; cmap = 1 - gray; % jet
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/trunk/matlab/bmm/carfac/SAI_StabilizeLayer.m Mon May 13 21:15:56 2013 +0000 @@ -0,0 +1,55 @@ +function layer_struct = SAI_StabilizeLayer(layer_struct) +% Pick trigger points in buffer, shift rows to offset_from_end, +% and blend into frame + +frame = layer_struct.frame; + +nap_buffer = real(layer_struct.nap_buffer); +n_buffer_times = size(nap_buffer, 1); +[n_ch, width] = size(frame); + +% Make the window to use for all the channels at this layer. +window_size = layer_struct.window_width; +n_window_pos = layer_struct.n_window_pos; +% Windows are always (approx) 50% overlapped: +d_win = window_size / 2; + +after_samples = layer_struct.future_lags; + +window_range = (1:window_size) + ... + (n_buffer_times - window_size) - after_samples - ... + floor((n_window_pos - 1) * d_win); +window = sin((1:window_size)' * pi / window_size); +% This should not go negative! +offset_range = (1:width) + ... + (n_buffer_times - width - window_size) - floor((n_window_pos - 1) * d_win); +% CHECK +if any(offset_range < 0) + error; +end + +% smooth across channels; more in later layers +smoothed_buffer = smooth1d(nap_buffer', layer_struct.channel_smoothing_scale)'; + +% For each buffer column (channel), pick a trigger and align into SAI_frame +for ch = 1:n_ch + smooth_wave = smoothed_buffer(:, ch); % for the trigger + + % Do several window positions and triggers + for w = 1:n_window_pos + % move the window to later and go aggain + [peak_val, trigger_time] = max(smooth_wave(window_range + ... + floor((w - 1) * d_win)) .* window); + nap_wave = nap_buffer(:, ch); % for the waveform + 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)' + ... + (1 - alpha) * frame(ch, :); + end +end + +layer_struct.frame = frame;
--- a/trunk/matlab/bmm/carfac/SAI_UpdateBuffers.m Fri May 10 20:12:49 2013 +0000 +++ b/trunk/matlab/bmm/carfac/SAI_UpdateBuffers.m Mon May 13 21:15:56 2013 +0000 @@ -37,7 +37,7 @@ % Array of what to shift in to first or next layer. new_chunk = seg_naps; -gain = 1.1; % gain from layer to layer; could be layer dependent. +gain = 1.05; % gain from layer to layer; could be layer dependent. %% % Decimate using a 2-3-4-filter and partial differencing emphasize onsets: