mirror of
https://codeberg.org/armin/ambivalence.git
synced 2026-09-01 04:10:48 +02:00
init
This commit is contained in:
parent
29c860587e
commit
42cf8432bf
57 changed files with 5782 additions and 0 deletions
104
Source/DSP/AcousticMetrics.h
Normal file
104
Source/DSP/AcousticMetrics.h
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
#pragma once
|
||||
#include "DSPConstants.h"
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <vector> // <- 1 row added
|
||||
|
||||
namespace FDNReverb {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// AcousticMetrics class
|
||||
// -----------------------------------------------------------------------------
|
||||
// Computes real-time acoustic metrics (D50, C50, C80, EDT).
|
||||
//
|
||||
// Principle:
|
||||
// Accumulate the squared energy of the input signal in a ring buffer,
|
||||
// then compare it against the energy from 50 ms / 80 ms ago,
|
||||
// and compute the D50 / C50 / C80 values.
|
||||
//
|
||||
// Sample-rate support:
|
||||
// times (ms) are converted to sample counts,
|
||||
// so 44.1 kHz through 192 kHz are supported automatically.
|
||||
//
|
||||
// CPU:
|
||||
// O(1) per-sample computation (energy accumulation)
|
||||
// CPU overhead: below ~0.5%
|
||||
// -----------------------------------------------------------------------------
|
||||
class AcousticMetrics {
|
||||
public:
|
||||
AcousticMetrics() = default;
|
||||
|
||||
// -- initialize --
|
||||
// sampleRate: sample rate (Hz)
|
||||
// analysisWindowMs: analysis window (ms). 2000 ms (2 s)
|
||||
void prepare(double sampleRate, float analysisWindowMs = 2000.0f);
|
||||
|
||||
// -- per-sample state update --
|
||||
// sample: current Wet signal sample (mono)
|
||||
void processSample(float sample) noexcept;
|
||||
|
||||
// -- value getters --
|
||||
// ranges:
|
||||
// D50: 0.0 ~ 1.0 ( 0.3~0.9)
|
||||
// C50: -10 ~ +30 dB
|
||||
// C80: -10 ~ +30 dB
|
||||
// EDT: 0.0 ~ 5.0 (s)
|
||||
float getD50() const noexcept { return d50.load(std::memory_order_relaxed); }
|
||||
float getC50() const noexcept { return c50.load(std::memory_order_relaxed); }
|
||||
float getC80() const noexcept { return c80.load(std::memory_order_relaxed); }
|
||||
float getEDT() const noexcept { return edt.load(std::memory_order_relaxed); }
|
||||
|
||||
// --- added: expose energy history for drawing ---
|
||||
// get the instantaneous energy (squared) at a time offset in the past
|
||||
float getEnergyAtTimeOffset(float secondsAgo) const noexcept;
|
||||
|
||||
// input activity detection (energy over the last 50 ms)
|
||||
bool isActive() const noexcept;
|
||||
|
||||
// -- reset --
|
||||
void reset() noexcept;
|
||||
|
||||
private:
|
||||
// -- compute --
|
||||
void updateMetrics() noexcept;
|
||||
|
||||
// -- parameter --
|
||||
double sampleRate{ 48000.0 };
|
||||
float analysisWindowMs{ 2000.0f };
|
||||
|
||||
// 50ms / 80ms sample count ( sample rate depends on )
|
||||
int samples50ms{ 2400 }; // @ 48kHz
|
||||
int samples80ms{ 3840 }; // @ 48kHz
|
||||
int analysisWindowSamples{ 96000 }; // 2000ms @ 48kHz
|
||||
|
||||
// -- buffer --
|
||||
// energy history ( squared value )
|
||||
std::vector<float> energyHistory;
|
||||
int historyWritePos{ 0 };
|
||||
|
||||
// -- cumulative energy value --
|
||||
// 50ms cumulative energy ( time )
|
||||
double recent50msEnergy{ 0.0 };
|
||||
// 80ms cumulative energy ( time )
|
||||
double recent80msEnergy{ 0.0 };
|
||||
// entire cumulative energy
|
||||
double totalEnergy{ 0.0 };
|
||||
|
||||
// EDT : energy decay tracking
|
||||
float energyPeak{ 0.0f };
|
||||
int energyPeakPos{ 0 };
|
||||
|
||||
// -- output value (atomic for thread safety) --
|
||||
std::atomic<float> d50{ 0.0f };
|
||||
std::atomic<float> c50{ 0.0f };
|
||||
std::atomic<float> c80{ 0.0f };
|
||||
std::atomic<float> edt{ 0.0f };
|
||||
|
||||
// -- update --
|
||||
// sample compute ,
|
||||
// sample interval update
|
||||
int updateCounter{ 0 };
|
||||
static constexpr int kUpdateInterval = 1024; // about 21ms @ 48kHz
|
||||
};
|
||||
|
||||
} // namespace FDNReverb
|
||||
Loading…
Add table
Add a link
Reference in a new issue