You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

59 lines
1.4 KiB

#pragma once
#include <vector>
#include <deque>
#include <cstdint>
class AudioCompressor {
public:
struct Config {
int sampleRate = 48000;
int channels = 1;
int blockDurationMs = 20;
int lookbackMs = 200;
int lookaheadMs = 100;
float maxGainDb = 30.0f;
float riseRatePer500ms = 2.0f;
float targetLevel = 0.25f;
};
void configure(const Config& cfg);
void reset();
void setEnabled(bool enabled) { m_enabled = enabled; }
bool isEnabled() const { return m_enabled; }
void push(const int16_t* samples, size_t count);
const std::vector<int16_t>& outputBuffer() const { return m_output; }
bool hasPending() const { return !m_pending.empty() || !m_accumulator.empty(); }
void flush();
private:
Config m_cfg;
bool m_enabled = true;
struct BlockLevel {
float level;
};
std::deque<BlockLevel> m_blockLevels;
struct PendingBlock {
std::vector<int16_t> samples;
size_t levelIndex;
};
std::deque<PendingBlock> m_pending;
std::vector<int16_t> m_accumulator;
std::vector<int16_t> m_output;
int m_blockSamples = 960;
int m_lookbackBlocks = 10;
int m_lookaheadBlocks = 5;
float m_riseFactorPerBlock = 1.0f;
float m_maxGain = 31.62f;
float m_gainSmoothed = 1.0f;
int m_dbgCounter = 0;
float computeBlockLevel(const int16_t* samples, size_t count) const;
void processPendingBlock();
};