Generate a guitar string decay: harmonic series with 1/h^2 rolloff and exponential decay Very periodic waveform — low envelope jitter, high autocorrelation, low ZC CV
| 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 |
| 299 | inline Sample makeGuitarStringDecay(float f0, u32 timestamp, |
| 300 | float amplitude = 16000.0f, |
| 301 | int count = 512, float sampleRate = 44100.0f) { |
| 302 | fl::vector<fl::i16> data(count, 0); |
| 303 | const float maxFreq = fl::min(8000.0f, sampleRate / 2.0f); |
| 304 | const float decayTime = 0.5f; // 500ms decay |
| 305 | |
| 306 | for (int h = 1; h * f0 < maxFreq; ++h) { |
| 307 | float freq = f0 * h; |
| 308 | float harmonicAmp = amplitude / static_cast<float>(h * h); |
| 309 | float harmonicDecay = decayTime / static_cast<float>(h); // Higher harmonics decay faster |
| 310 | |
| 311 | for (int i = 0; i < count; ++i) { |
| 312 | float t = static_cast<float>(i) / sampleRate; |
| 313 | float decay = fl::expf(-t / harmonicDecay); |
| 314 | float phase = 2.0f * FL_M_PI * freq * t; |
| 315 | float sample = harmonicAmp * decay * fl::sinf(phase); |
| 316 | data[i] += static_cast<fl::i16>(fl::clamp(sample, -32768.0f, 32767.0f)); |
| 317 | } |
| 318 | } |
| 319 | return Sample(data, timestamp); |
| 320 | } |
| 321 | |
| 322 | /// Generate deterministic white noise using fl::fl_random with fixed seed |
| 323 | inline Sample makeWhiteNoise(u32 timestamp, float amplitude = 16000.0f, |