Mercurial > hg > aimc
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); |