MCPcopy Create free account
hub / github.com/FastLED/FastLED / makeSyntheticVowel

Function makeSyntheticVowel

tests/fl/audio/test_helpers.h:227–251  ·  view source on GitHub ↗

Generate a synthetic vowel using additive synthesis with Gaussian formant envelopes Simplest physically-motivated voice model: harmonic series with 1/h rolloff shaped by two resonance peaks

Source from the content-addressed store, hash-verified

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
227inline Sample makeSyntheticVowel(float f0, float f1Freq, float f2Freq,
228 u32 timestamp, float amplitude = 16000.0f,
229 int count = 512, float sampleRate = 44100.0f) {
230 fl::vector<fl::i16> data(count, 0);
231 const float f1Bw = 150.0f; // F1 bandwidth
232 const float f2Bw = 200.0f; // F2 bandwidth
233 const float maxFreq = fl::min(4000.0f, sampleRate / 2.0f);
234
235 for (int h = 1; h * f0 < maxFreq; ++h) {
236 float freq = f0 * h;
237 // Natural 1/h rolloff
238 float naturalAmp = 1.0f / static_cast<float>(h);
239 // Gaussian formant envelopes
240 float f1Gain = fl::expf(-0.5f * (freq - f1Freq) * (freq - f1Freq) / (f1Bw * f1Bw));
241 float f2Gain = fl::expf(-0.5f * (freq - f2Freq) * (freq - f2Freq) / (f2Bw * f2Bw));
242 float formantGain = fl::max(f1Gain, f2Gain);
243 float harmonicAmp = amplitude * naturalAmp * fl::max(0.05f, formantGain);
244
245 for (int i = 0; i < count; ++i) {
246 float phase = 2.0f * FL_M_PI * freq * i / sampleRate;
247 data[i] += static_cast<fl::i16>(harmonicAmp * fl::sinf(phase));
248 }
249 }
250 return Sample(data, timestamp);
251}
252
253/// Generate a jittered vowel: synthetic vowel with per-period amplitude and timing jitter
254/// Simulates real vocal cord irregularity — higher envelope jitter and lower autocorrelation

Callers 1

vocal.hppFile · 0.85

Calls 4

expfFunction · 0.85
maxFunction · 0.85
sinfFunction · 0.85
SampleClass · 0.50

Tested by

no test coverage detected