| 38 | BuildupDetector::~BuildupDetector() FL_NOEXCEPT = default; |
| 39 | |
| 40 | void BuildupDetector::update(shared_ptr<Context> context) { |
| 41 | if (!context) { |
| 42 | FL_WARN("BuildupDetector::update: null context"); |
| 43 | return; |
| 44 | } |
| 45 | |
| 46 | mRetainedFFT = context->getFFT(32); |
| 47 | const fft::Bins& fft = *mRetainedFFT; |
| 48 | float rms = context->getRMS(); |
| 49 | float treble = getTrebleEnergy(fft); |
| 50 | u32 timestamp = context->getTimestamp(); |
| 51 | |
| 52 | // Update history and SG filters |
| 53 | updateEnergyHistory(rms); |
| 54 | updateTrebleHistory(treble); |
| 55 | mEnergySG.update(rms); |
| 56 | mTrebleSG.update(treble); |
| 57 | |
| 58 | // Calculate trends |
| 59 | float energyTrend = calculateEnergyTrend(); |
| 60 | float trebleTrend = calculateTrebleTrend(); |
| 61 | |
| 62 | // Calculate buildup intensity |
| 63 | float intensity = calculateBuildupIntensity(energyTrend, trebleTrend, rms); |
| 64 | |
| 65 | if (!mBuildupActive) { |
| 66 | // Check if we should start a buildup |
| 67 | if (shouldStartBuildup(intensity)) { |
| 68 | mBuildupActive = true; |
| 69 | mPeakFired = false; |
| 70 | mCurrentBuildup.timestamp = timestamp; |
| 71 | mCurrentBuildup.intensity = intensity; |
| 72 | mCurrentBuildup.progress = 0.0f; |
| 73 | mCurrentBuildup.duration = 0; |
| 74 | mCurrentBuildup.active = true; |
| 75 | |
| 76 | FL_DBG("BuildupDetector: Buildup started (intensity=" << intensity << ")"); |
| 77 | |
| 78 | mFireBuildupStart = true; |
| 79 | } |
| 80 | } else { |
| 81 | // Update existing buildup |
| 82 | mCurrentBuildup.duration = timestamp - mCurrentBuildup.timestamp; |
| 83 | mCurrentBuildup.intensity = intensity; |
| 84 | |
| 85 | // Calculate progress (0.0 to 1.0) |
| 86 | float normalizedDuration = static_cast<float>(mCurrentBuildup.duration) / static_cast<float>(mMaxDuration); |
| 87 | mCurrentBuildup.progress = fl::min(1.0f, normalizedDuration); |
| 88 | |
| 89 | // Check if we've reached peak (just before drop) |
| 90 | if (!mPeakFired && shouldPeak()) { |
| 91 | mPeakFired = true; |
| 92 | FL_DBG("BuildupDetector: Peak reached"); |
| 93 | |
| 94 | mFireBuildupPeak = true; |
| 95 | } |
| 96 | |
| 97 | // Set progress callback flag |
nothing calls this directly
no test coverage detected