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

Function makeJitteredVowel

tests/fl/audio/test_helpers.h:256–295  ·  view source on GitHub ↗

Generate a jittered vowel: synthetic vowel with per-period amplitude and timing jitter Simulates real vocal cord irregularity — higher envelope jitter and lower autocorrelation than clean synthetic vowels

Source from the content-addressed store, hash-verified

254/// Simulates real vocal cord irregularity — higher envelope jitter and lower autocorrelation
255/// than clean synthetic vowels
256inline Sample makeJitteredVowel(float f0, float f1Freq, float f2Freq,
257 u32 timestamp, float amplitude = 16000.0f,
258 int count = 512, float sampleRate = 44100.0f) {
259 fl::vector<fl::i16> data(count, 0);
260 fl::fl_random rng(123);
261 const float f1Bw = 150.0f;
262 const float f2Bw = 200.0f;
263 const float maxFreq = fl::min(4000.0f, sampleRate / 2.0f);
264
265 // Generate clean vowel base
266 for (int h = 1; h * f0 < maxFreq; ++h) {
267 float freq = f0 * h;
268 float naturalAmp = 1.0f / static_cast<float>(h);
269 float f1Gain = fl::expf(-0.5f * (freq - f1Freq) * (freq - f1Freq) / (f1Bw * f1Bw));
270 float f2Gain = fl::expf(-0.5f * (freq - f2Freq) * (freq - f2Freq) / (f2Bw * f2Bw));
271 float formantGain = fl::max(f1Gain, f2Gain);
272 float harmonicAmp = amplitude * naturalAmp * fl::max(0.05f, formantGain);
273
274 for (int i = 0; i < count; ++i) {
275 float phase = 2.0f * FL_M_PI * freq * i / sampleRate;
276 data[i] += static_cast<fl::i16>(harmonicAmp * fl::sinf(phase));
277 }
278 }
279
280 // Apply per-period amplitude jitter (simulates vocal cord irregularity)
281 float periodSamples = sampleRate / f0;
282 float pos = 0.0f;
283 float currentJitter = 1.0f;
284 for (int i = 0; i < count; ++i) {
285 pos += 1.0f;
286 if (pos >= periodSamples) {
287 pos -= periodSamples;
288 // Random amplitude jitter: +/- 20%
289 currentJitter = 0.80f + 0.40f * (static_cast<float>(rng.random16()) / 65535.0f);
290 }
291 float sample = static_cast<float>(data[i]) * currentJitter;
292 data[i] = static_cast<fl::i16>(fl::clamp(sample, -32768.0f, 32767.0f));
293 }
294 return Sample(data, timestamp);
295}
296
297/// Generate a guitar string decay: harmonic series with 1/h^2 rolloff and exponential decay
298/// Very periodic waveform — low envelope jitter, high autocorrelation, low ZC CV

Callers 3

makeFullBandMixFunction · 0.85
vocal.hppFile · 0.85
makeVocalInFullMixFunction · 0.85

Calls 6

expfFunction · 0.85
maxFunction · 0.85
sinfFunction · 0.85
clampFunction · 0.85
random16Method · 0.80
SampleClass · 0.50

Tested by

no test coverage detected