comparison matlab/bmm/carfac/SAI_RunLayered.m @ 608:fc353426eaad

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 ec3a1c74ec54
children b3118c9ed67f
comparison
equal deleted inserted replaced
607:49eef19e4f1d 608:fc353426eaad
39 [layer_array, total_width] = SAI_DesignLayers(n_layers, width_per_layer); 39 [layer_array, total_width] = SAI_DesignLayers(n_layers, width_per_layer);
40 40
41 % Make the composite SAI image array. 41 % Make the composite SAI image array.
42 composite_frame = zeros(n_ch, total_width); 42 composite_frame = zeros(n_ch, total_width);
43 43
44 seglen = round(fs * 0.020); % Pick about 20 ms segments 44 seglen = round(fs / 30); % Pick about 60 fps
45 frame_rate = fs / seglen; 45 frame_rate = fs / seglen;
46 n_segs = ceil(n_samp / seglen); 46 n_segs = ceil(n_samp / seglen);
47 47
48 % Make the history buffers in the layers_array: 48 % Make the history buffers in the layers_array:
49 for layer = 1:n_layers 49 for layer = 1:n_layers
50 layer_array(layer).nap_buffer = zeros(layer_array(layer).buffer_width, n_ch); 50 layer_array(layer).nap_buffer = zeros(layer_array(layer).buffer_width, n_ch);
51 layer_array(layer).nap_fraction = 0; % leftover fraction to shift in. 51 layer_array(layer).nap_fraction = 0; % leftover fraction to shift in.
52 % The SAI frame is transposed to be image-like.
53 layer_array(layer).frame = zeros(n_ch, layer_array(layer).frame_width);
52 end 54 end
53 55
56 n_marginal_rows = 34;
57 marginals = [];
58
59 average_frame = 0;
54 for seg_num = 1:n_segs 60 for seg_num = 1:n_segs
55 % k_range is the range of input sample indices for this segment 61 % k_range is the range of input sample indices for this segment
56 if seg_num == n_segs 62 if seg_num == n_segs
57 % The last segment may be short of seglen, but do it anyway: 63 % The last segment may be short of seglen, but do it anyway:
58 k_range = (seglen*(seg_num - 1) + 1):n_samp; 64 k_range = (seglen*(seg_num - 1) + 1):n_samp;
73 79
74 80
75 for layer = n_layers:-1:1 % blend from coarse to fine 81 for layer = n_layers:-1:1 % blend from coarse to fine
76 update_interval = layer_array(layer).update_interval; 82 update_interval = layer_array(layer).update_interval;
77 if 0 == mod(seg_num, update_interval) 83 if 0 == mod(seg_num, update_interval)
78 nap_buffer = real(layer_array(layer).nap_buffer); 84 layer_array(layer) = SAI_StabilizeLayer(layer_array(layer));
79 n_buffer_times = size(nap_buffer, 1); 85 new_frame = layer_array(layer).frame;
80 width = layer_array(layer).frame_width; % To render linear SAI to. 86 composite_frame = SAI_BlendFrameIntoComposite( ...
81 new_frame = zeros(n_ch, width);
82
83 % Make the window to use for all the channels at this layer.
84 layer_factor = 1.5;
85 window_size = layer_array(layer).window_width;
86 after_samples = layer_array(layer).future_lags;
87
88 window_range = (1:window_size) + ...
89 (n_buffer_times - window_size) - after_samples;
90 window = sin((1:window_size)' * pi / window_size);
91 % This should not go negative!
92 offset_range = (1:width) + ...
93 (n_buffer_times - width - window_size);
94 % CHECK
95 if any(offset_range < 0)
96 error;
97 end
98
99 % smooth across channels; more in later layers
100 smoothed_buffer = smooth1d(nap_buffer', 0.25*(layer - 2))';
101
102 % For each buffer column (channel), pick a trigger and align into SAI_frame
103 for ch = 1:n_ch
104 smooth_wave = smoothed_buffer(:, ch); % for the trigger
105
106 [peak_val, trigger_time] = max(smooth_wave(window_range) .* window);
107 nap_wave = nap_buffer(:, ch); % for the waveform
108 if peak_val <= 0 % just use window center instead
109 [peak_val, trigger_time] = max(window);
110 end
111 if layer == n_layers % mark the trigger points to display as imaginary.
112 layer_array(layer).nap_buffer(trigger_time + window_range(1) - 1, ch) = ...
113 layer_array(layer).nap_buffer(trigger_time + window_range(1) - 1, ch) + 1i;
114 end
115 new_frame(ch, :) = nap_wave(trigger_time + offset_range)';
116 end
117 composite_frame = SAI_BlendFrameIntoComposite(new_frame, ...
118 layer_array(layer), composite_frame); 87 layer_array(layer), composite_frame);
119 end 88 end
120 end 89 end
121 90
122 91 if isempty(marginals)
92 composite_width = size(composite_frame, 2);
93 marginals = zeros(n_marginal_rows, composite_width);
94 end
95 for row = n_marginal_rows:-1:11
96 % smooth from row above (lower number)
97 marginals(row, :) = marginals(row, :) + ...
98 2^((10 - row)/2) * (1.06*marginals(row - 1, :) - marginals(row, :));
99 end
123 lag_marginal = mean(composite_frame, 1); % means max out near 1 or 2 100 lag_marginal = mean(composite_frame, 1); % means max out near 1 or 2
124 frame_bottom = zeros(size(composite_frame)); % will end up being 1/3 101 for row = 10:-1:1
125 n_bottom_rows = size(frame_bottom, 1); 102 marginals(row, :) = (lag_marginal - smooth1d(lag_marginal, 30)') - ...
126 for height = 1:n_bottom_rows 103 (10 - row) / 40;
127 big_ones = lag_marginal > 1*height/n_bottom_rows;
128 frame_bottom(n_bottom_rows - height + 1, big_ones) = 2; % 2 for black
129 end 104 end
130 105
131 if 0 == mod(seg_num, update_interval) || seg_num == 1 106 if 0 == mod(seg_num, update_interval) || seg_num == 1
132 coc_gram = layer_array(end).nap_buffer'; 107 coc_gram = layer_array(end).nap_buffer';
133 [n_ch, n_width] = size(composite_frame); 108 [n_ch, n_width] = size(composite_frame);
134 coc_gram = [coc_gram, zeros(n_ch, n_width - size(coc_gram, 2))]; 109 coc_gram = [coc_gram, zeros(n_ch, n_width - size(coc_gram, 2))];
135 trigger_gram = 2 * (imag(coc_gram) ~= 0);
136 coc_gram = real(coc_gram);
137 end 110 end
138 111
139 display_frame = [coc_gram; trigger_gram; ... 112 display_frame = [coc_gram; ...
140 composite_frame(floor(1:0.5:end), :); frame_bottom]; 113 composite_frame(floor(1:0.5:end), :); 20*max(0,marginals)];
141 114
142 cmap = jet; 115 cmap = jet;
143 cmap = 1 - gray; % jet 116 cmap = 1 - gray; % jet
144 figure(10) 117 figure(10)
145 image(32*display_frame); 118 image(32*display_frame);