| 182 | } |
| 183 | |
| 184 | float BuildupDetector::calculateTrebleTrend() const { |
| 185 | if (mTrebleHistorySize < 4 || !mTrebleSG.full()) { |
| 186 | return 0.0f; // Not enough data |
| 187 | } |
| 188 | |
| 189 | // Use SG-smoothed current value vs oldest history entry for trend |
| 190 | float currentSmoothed = mTrebleSG.value(); |
| 191 | int oldestIdx = (mTrebleHistorySize < 16) ? 0 : mTrebleHistoryIndex; |
| 192 | float oldestValue = mTrebleHistory[oldestIdx]; |
| 193 | |
| 194 | if (oldestValue < 1e-6f) { |
| 195 | return 0.0f; |
| 196 | } |
| 197 | |
| 198 | float riseRate = (currentSmoothed - oldestValue) / oldestValue; |
| 199 | return fl::max(0.0f, fl::min(2.0f, riseRate)); // Clamp to [0, 2] |
| 200 | } |
| 201 | |
| 202 | float BuildupDetector::calculateBuildupIntensity(float energyTrend, float trebleTrend, float rms) const { |
| 203 | // Buildup intensity is a combination of: |