comparison trunk/src/Modules/SSI/ModuleSSI.cc @ 397:7a573750b186

- First add of a lot of graphics code from the old version. Not working yet, not even compiling yet.
author tomwalters
date Fri, 15 Oct 2010 05:40:53 +0000
parents 0a8e7d0c70dc
children a908972d234e
comparison
equal deleted inserted replaced
396:06a26f5cdad7 397:7a573750b186
67 log_cycles_axis_ = parameters_->DefaultBool("ssi.log_cycles_axis", true); 67 log_cycles_axis_ = parameters_->DefaultBool("ssi.log_cycles_axis", true);
68 68
69 // The centre frequency of the channel which will just fill the complete 69 // The centre frequency of the channel which will just fill the complete
70 // width of the SSI buffer 70 // width of the SSI buffer
71 pivot_cf_ = parameters_->DefaultFloat("ssi.pivot_cf", 1000.0f); 71 pivot_cf_ = parameters_->DefaultFloat("ssi.pivot_cf", 1000.0f);
72
73 // Whether or not to do smooth offset when the pitch cutoff is active.
74 do_smooth_offset_ = parameters_->DefaultBool("ssi.do_smooth_offset", false);
75
76 // The number of cycles, centered on the pitch line, over which the SSI is taken
77 // to zero when doing the pitch cutoff.
78 smooth_offset_cycles_ = parameters_->DefaultFloat("ssi.smooth_offset_cycles", 3.0f);
72 } 79 }
73 80
74 ModuleSSI::~ModuleSSI() { 81 ModuleSSI::~ModuleSSI() {
75 } 82 }
76 83
144 151
145 int pitch_index = buffer_length_ - 1; 152 int pitch_index = buffer_length_ - 1;
146 if (do_pitch_cutoff_) { 153 if (do_pitch_cutoff_) {
147 pitch_index = ExtractPitchIndex(input); 154 pitch_index = ExtractPitchIndex(input);
148 } 155 }
156
157 float gamma_min = -1.0f;
158 float gamma_max = log2(ssi_width_cycles_);
149 159
150 for (int ch = 0; ch < channel_count_; ++ch) { 160 for (int ch = 0; ch < channel_count_; ++ch) {
151 float centre_frequency = input.centre_frequency(ch); 161 float centre_frequency = input.centre_frequency(ch);
162
163 float channel_weight = 1.0f;
164 int cutoff_index = buffer_length_ - 1;
165 if (do_pitch_cutoff_) {
166 if (pitch_index < cutoff_index) {
167 if (weight_by_cutoff_) {
168 channel_weight = static_cast<float>(buffer_length_)
169 / static_cast<float>(pitch_index);
170 }
171 cutoff_index = pitch_index;
172 }
173 }
174
175 // tanh(3) is about 0.995. Seems reasonable.
176 float smooth_pitch_constant = smooth_offset_cycles_ * 3.0f;
177 float pitch_h = 0.0f;
178 if (do_smooth_offset_) {
179 if (log_cycles_axis_) {
180 float gamma = gamma_min + (gamma_max - gamma_min)
181 * static_cast<float>(pitch_index)
182 / static_cast<float>(ssi_width_samples_);
183 pitch_h = pow(2.0f, gamma);
184 } else {
185 pitch_h = static_cast<float>(pitch_index) * ssi_width_cycles_
186 / static_cast<float>(ssi_width_samples_);
187 }
188 }
189
152 // Copy the buffer from input to output, addressing by h-value 190 // Copy the buffer from input to output, addressing by h-value
153 for (int i = 0; i < ssi_width_samples_; ++i) { 191 for (int i = 0; i < ssi_width_samples_; ++i) {
154 float h; 192 float h;
155 float cycle_samples = sample_rate_ / centre_frequency; 193 float cycle_samples = sample_rate_ / centre_frequency;
156 if (log_cycles_axis_) { 194 if (log_cycles_axis_) {
157 float gamma_min = -1.0f;
158 float gamma_max = log2(ssi_width_cycles_);
159 float gamma = gamma_min + (gamma_max - gamma_min) 195 float gamma = gamma_min + (gamma_max - gamma_min)
160 * static_cast<float>(i) 196 * static_cast<float>(i)
161 / static_cast<float>(ssi_width_samples_); 197 / static_cast<float>(ssi_width_samples_);
162 h = pow(2.0f, gamma); 198 h = pow(2.0f, gamma);
163 } else { 199 } else {
171 // between input samples to yield an output sample. 207 // between input samples to yield an output sample.
172 double whole_part; 208 double whole_part;
173 float frac_part = modf(h * cycle_samples, &whole_part); 209 float frac_part = modf(h * cycle_samples, &whole_part);
174 int sample = floor(whole_part); 210 int sample = floor(whole_part);
175 211
176 float weight = 1.0f; 212 float weight = channel_weight;
177 213
178 int cutoff_index = buffer_length_ - 1; 214 if (do_smooth_offset_ && do_pitch_cutoff_) {
179 if (do_pitch_cutoff_) { 215 // Smoothing around the pitch cutoff line.
180 if (pitch_index < cutoff_index) { 216 weight *= (1.0f + tanh(smooth_pitch_constant * (pitch_h - h))) / 2.0f;
181 if (weight_by_cutoff_) {
182 weight *= static_cast<float>(buffer_length_)
183 / static_cast<float>(pitch_index);
184 }
185 cutoff_index = pitch_index;
186 }
187 } 217 }
188 218
189 if (weight_by_scaling_) { 219 if (weight_by_scaling_) {
190 if (centre_frequency > pivot_cf_) { 220 if (centre_frequency > pivot_cf_) {
191 weight *= (centre_frequency / pivot_cf_); 221 weight *= (centre_frequency / pivot_cf_);
192 } 222 }
193 } 223 }
194 224
195 float val; 225 float val;
196 if (sample < cutoff_index) { 226 if (sample < cutoff_index || do_smooth_offset_) {
197 float curr_sample = input.sample(ch, sample); 227 float curr_sample = input.sample(ch, sample);
198 float next_sample = input.sample(ch, sample + 1); 228 float next_sample = input.sample(ch, sample + 1);
199 val = weight * (curr_sample 229 val = weight * (curr_sample
200 + frac_part * (next_sample - curr_sample)); 230 + frac_part * (next_sample - curr_sample));
201 } else { 231 } else {