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
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(); |
|
};
|
|
|