Generate a multi-harmonic signal (fundamental + overtones with geometric decay) Useful for testing harmonic-rich signals that aren't voice (e.g., instruments)
| 207 | /// Generate a multi-harmonic signal (fundamental + overtones with geometric decay) |
| 208 | /// Useful for testing harmonic-rich signals that aren't voice (e.g., instruments) |
| 209 | inline Sample makeMultiHarmonic(float f0, int numHarmonics, float decay, |
| 210 | u32 timestamp, float amplitude = 16000.0f, |
| 211 | int count = 512, float sampleRate = 44100.0f) { |
| 212 | fl::vector<fl::i16> data(count, 0); |
| 213 | for (int h = 1; h <= numHarmonics; ++h) { |
| 214 | float harmonicAmp = amplitude * fl::powf(decay, static_cast<float>(h - 1)); |
| 215 | float freq = f0 * h; |
| 216 | if (freq >= sampleRate / 2.0f) break; // Nyquist |
| 217 | for (int i = 0; i < count; ++i) { |
| 218 | float phase = 2.0f * FL_M_PI * freq * i / sampleRate; |
| 219 | data[i] += static_cast<fl::i16>(harmonicAmp * fl::sinf(phase)); |
| 220 | } |
| 221 | } |
| 222 | return Sample(data, timestamp); |
| 223 | } |
| 224 | |
| 225 | /// Generate a synthetic vowel using additive synthesis with Gaussian formant envelopes |
| 226 | /// Simplest physically-motivated voice model: harmonic series with 1/h rolloff shaped by two resonance peaks |