Mercurial > hg > aimc
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 { |