69 static constexpr float max_sample = 32768.0f;
70 static constexpr float min_value = -32768.0f;
71 static constexpr float max_value = 32767.0f;
72 static constexpr int fixed_shift = 0;
77 static constexpr float max_sample = 8388608.0f;
78 static constexpr float min_value = -8388608.0f;
79 static constexpr float max_value = 8388607.0f;
80 static constexpr int fixed_shift = 8;
85 static constexpr float max_sample = 2147483648.0f;
86 static constexpr float min_value = -2147483648.0f;
87 static constexpr float max_value = 2147483647.0f;
88 static constexpr int fixed_shift = 16;
196 if (data ==
nullptr ||
p_in ==
nullptr) {
210 size_t write(
const uint8_t* data,
size_t len)
override {
211 if (data ==
nullptr ||
p_out ==
nullptr) {
246 static float dbToLinear(
float db) {
return powf(10.0f, db / 20.0f); }
249 if (value <= 0.0000001f) {
253 return 20.0f * log10f(value);
264 if (seconds <= 0.0f) {
272 float block_seconds =
static_cast<float>(samples) /
275 return 1.0f - expf(-block_seconds / seconds);
287 template <
typename T>
288 void analyze(
const T* data,
size_t samples,
float& rms,
float& peak) {
294 int32_t peak_raw = 0;
296 for (
size_t i = 0; i < samples; ++i) {
300 int32_t value =
static_cast<int32_t
>(sample) >> shift;
301 int32_t abs_value = value < 0 ? -value : value;
303 if (abs_value > peak_raw) {
304 peak_raw = abs_value;
307 sum_sq +=
static_cast<int64_t
>(value) * value;
310 float scaled_max = max_sample /
static_cast<float>(1 << shift);
312 rms = samples == 0 ? 0.0f
313 : sqrtf(
static_cast<float>(sum_sq) /
314 static_cast<float>(samples)) /
316 peak =
static_cast<float>(peak_raw) / scaled_max;
323 for (
size_t i = 0; i < samples; ++i) {
327 float value =
static_cast<float>(sample) / max_sample;
329 float abs_value = fabsf(value);
331 sum += value * value;
333 if (abs_value > peak) {
338 rms = samples == 0 ? 0.0f : sqrtf(sum /
static_cast<float>(samples));
345 bool analyze(
const uint8_t* buffer,
size_t bytes,
float& rms,
float& peak) {
352 analyze(
reinterpret_cast<const int16_t*
>(buffer),
353 bytes /
sizeof(int16_t), rms, peak);
358 bytes /
sizeof(
int24_t), rms, peak);
362 analyze(
reinterpret_cast<const int32_t*
>(buffer),
363 bytes /
sizeof(int32_t), rms, peak);
415 float peak_after_gain = peak_db + desired;
420 if (peak_limited_gain < desired) {
421 desired = peak_limited_gain;
483 template <
typename T>
484 void apply(T* data,
size_t samples,
float gain) {
488 for (
size_t i = 0; i < samples; ++i) {
489 data[i] = fixed_gain.
scale(data[i]);
496 const float dgain =
static_cast<float>(gain);
498 for (
size_t i = 0; i < samples; ++i) {
499 float value =
static_cast<float>(data[i]) * dgain;
501 if (value > max_value) {
505 if (value < min_value) {
509 data[i] =
static_cast<T
>(value);
517 void apply(uint8_t* buffer,
size_t bytes,
float gain) {
520 apply(
reinterpret_cast<int16_t*
>(buffer), bytes /
sizeof(int16_t),
530 apply(
reinterpret_cast<int32_t*
>(buffer), bytes /
sizeof(int32_t),
539 void process(
const uint8_t* input,
size_t bytes) {
540 if (input ==
nullptr || bytes == 0 ||
channels == 0) {
549 uint8_t* buffer =
const_cast<uint8_t*
>(input);
560 if (!
analyze(buffer, bytes, rms, peak)) {
567 float rms_db =
linearToDb(
static_cast<float>(rms));
569 float peak_db =
linearToDb(
static_cast<float>(peak));
576 if (sample_size == 0) {
580 size_t samples = bytes / sample_size;
601 apply(buffer, bytes, gain);
virtual int availableForWrite()
Definition Arduino.h:128
virtual size_t write(const uint8_t *data, size_t len)
Definition Arduino.h:120
virtual void flush()
Definition Arduino.h:130
virtual size_t readBytes(uint8_t *data, size_t len)
Definition Arduino.h:140
virtual int available()
Definition Arduino.h:139