annotate matlab/bmm/carfac/SAI_StabilizeLayer.m @ 635:0bdd58ee6e92

ffmpeg no longer accepts a qscale value of 0. Changed qscale to 1, which also gives a very high quality output
author sness@sness.net
date Fri, 24 May 2013 22:38:09 +0000
parents a6e67f042b93
children 53a3f355bc4f
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.
ronw@633 12 window_width = layer_struct.window_width;
dicklyon@608 13 n_window_pos = layer_struct.n_window_pos;
dicklyon@608 14 % Windows are always (approx) 50% overlapped:
ronw@633 15 window_hop = window_width / 2;
dicklyon@608 16
ronw@633 17 window = sin((1:window_width)' * pi / window_width);
ronw@633 18 window_start = (n_buffer_times - window_width) - ...
ronw@633 19 floor((n_window_pos - 1) * window_hop);
ronw@633 20 window_range = (1:window_width) + window_start - layer_struct.future_lags;
dicklyon@608 21 % This should not go negative!
ronw@633 22 offset_range = (1:width) + window_start - width;
dicklyon@608 23 % CHECK
dicklyon@608 24 if any(offset_range < 0)
dicklyon@608 25 error;
dicklyon@608 26 end
dicklyon@608 27
dicklyon@608 28 % smooth across channels; more in later layers
dicklyon@608 29 smoothed_buffer = smooth1d(nap_buffer', layer_struct.channel_smoothing_scale)';
dicklyon@608 30
dicklyon@608 31 % For each buffer column (channel), pick a trigger and align into SAI_frame
dicklyon@608 32 for ch = 1:n_ch
dicklyon@608 33 smooth_wave = smoothed_buffer(:, ch); % for the trigger
dicklyon@608 34
dicklyon@608 35 % Do several window positions and triggers
dicklyon@608 36 for w = 1:n_window_pos
ronw@633 37 % move the window to later and go again
ronw@633 38 current_window_offset = floor((w - 1) * window_hop);
ronw@633 39 [peak_val, trigger_time] = ...
ronw@633 40 max(smooth_wave(window_range + current_window_offset) .* window);
dicklyon@608 41 nap_wave = nap_buffer(:, ch); % for the waveform
dicklyon@608 42 if peak_val <= 0 % just use window center instead
dicklyon@608 43 [peak_val, trigger_time] = max(window);
dicklyon@608 44 end
ronw@633 45 trigger_time = trigger_time + current_window_offset;
dicklyon@608 46 alpha = (0.025 + peak_val) / (0.5 + peak_val); % alpha 0.05 to near 1.0
dicklyon@608 47 frame(ch, :) = alpha * nap_wave(trigger_time + offset_range)' + ...
dicklyon@608 48 (1 - alpha) * frame(ch, :);
dicklyon@608 49 end
dicklyon@608 50 end
dicklyon@608 51
dicklyon@608 52 layer_struct.frame = frame;