Generate a synthetic hi-hat: high-pass shaped white noise @param open If true, use 80ms decay (open hi-hat); if false, use 5ms decay (closed)
| 418 | /// Generate a synthetic hi-hat: high-pass shaped white noise |
| 419 | /// @param open If true, use 80ms decay (open hi-hat); if false, use 5ms decay (closed) |
| 420 | inline Sample makeHiHat(fl::u32 timestamp, bool open = false, float amplitude = 16000.0f, |
| 421 | int count = 512, float sampleRate = 44100.0f) { |
| 422 | fl::fl_random rng(99); // Deterministic seed |
| 423 | float decayTime = open ? 0.080f : 0.005f; |
| 424 | fl::vector<fl::i16> data(count, 0); |
| 425 | float prevSample = 0.0f; |
| 426 | for (int i = 0; i < count; ++i) { |
| 427 | float t = static_cast<float>(i) / sampleRate; |
| 428 | float decay = fl::expf(-t / decayTime); |
| 429 | // White noise |
| 430 | float noiseVal = (static_cast<float>(rng.random16()) / 32767.5f) - 1.0f; |
| 431 | // Simple high-pass: subtract previous sample (first-order difference) |
| 432 | float raw = amplitude * decay * noiseVal; |
| 433 | float highPassed = raw - prevSample * 0.85f; |
| 434 | prevSample = raw; |
| 435 | if (highPassed > 32767.0f) highPassed = 32767.0f; |
| 436 | if (highPassed < -32768.0f) highPassed = -32768.0f; |
| 437 | data[i] = static_cast<fl::i16>(highPassed); |
| 438 | } |
| 439 | return Sample(data, timestamp); |
| 440 | } |
| 441 | |
| 442 | /// Generate a synthetic tom drum: single sine at tuning frequency, 60ms decay, NO click |
| 443 | /// Discriminated from kick by absence of click transient |
no test coverage detected