more advanced build script, refactor eqprocessor.cpps functions: process and recomputeBiquad, which were not nice to read. now nicer to read. no need to compile, compile at more major change

This commit is contained in:
2026-06-08 12:36:13 +02:00
parent 1960bf5e1d
commit 3c274b5cf8
5 changed files with 108 additions and 46 deletions
+45 -6
View File
@@ -1,6 +1,45 @@
rm -rf build #!/usr/bin/env bash
mkdir build set -e
cd build
cmake .. clean() {
make -j$(nproc) echo "cleaning build dir"
./SubWave rm -rf build
}
incremental_build() {
mkdir -p ../build
cd build
cmake ..
make -j"$(nproc)"
}
clean_build() {
clean
mkdir build
cd build
cmake ..
make -j"$(nproc)"
}
run_executable() {
./build/SubWave
}
case "${1:-build}" in
clean|c)
clean
;;
build|incremental|ib)
incremental_build
;;
cleanbuild|cb)
clean_build
;;
run|exec|r)
run_executable
;;
*)
echo "Usage: $0 {build|clean|cleanbuild|cb}"
exit 1
;;
esac
-1
View File
@@ -1,6 +1,5 @@
#pragma once #pragma once
#include <vector> #include <vector>
#include <cstdint>
namespace engine { namespace engine {
-2
View File
@@ -3,8 +3,6 @@
#include "engine/EqProcessor.h" #include "engine/EqProcessor.h"
#include "engine/SpectrumAnalyzer.h" #include "engine/SpectrumAnalyzer.h"
#include <cmath>
#include <numbers>
#include <algorithm> #include <algorithm>
#include <QThread> #include <QThread>
#include <QMediaDevices> #include <QMediaDevices>
+48 -34
View File
@@ -1,7 +1,6 @@
#include "EqProcessor.h" #include "EqProcessor.h"
#include <cmath> #include <cmath>
#include <numbers> #include <numbers>
#include <algorithm>
#include <cstring> #include <cstring>
namespace engine { namespace engine {
@@ -33,51 +32,66 @@ void EqProcessor::reset() {
std::memset(m_state, 0, sizeof(m_state)); std::memset(m_state, 0, sizeof(m_state));
} }
void EqProcessor::process(AudioBuffer &buf) {
const int channels = buf.channels; void EqProcessor::process(AudioBuffer &a_buf) {
const int count = buf.sampleCount(); const int channels = a_buf.channels;
float *samples = buf.samples.data(); const int count = a_buf.sampleCount();
float *samples = a_buf.samples.data();
for (int band = 0; band < BANDS; ++band) { for (int band = 0; band < BANDS; ++band) {
if (std::abs(m_gainDb[band]) < 0.01f) continue; if (std::abs(m_gainDb[band]) < 0.01f) {continue;}
const float b0 = m_coeff[band][0], b1 = m_coeff[band][1], b2 = m_coeff[band][2]; const auto& c = m_coeff[band];
const float a1 = m_coeff[band][3], a2 = m_coeff[band][4];
for (int i = 0; i < count; ++i) { for (int idx = 0; idx < count; ++idx) {
const int ch = i % channels; const int ch = idx % channels;
float &z1 = m_state[band][ch][0];
float &z2 = m_state[band][ch][1];
float x = samples[i]; auto &s = m_state[band][ch];
float y = b0 * x + z1;
z1 = b1 * x - a1 * y + z2; const float x = samples[idx];
z2 = b2 * x - a2 * y; const float y = c.b0 * x + s.z1;
samples[i] = y;
s.z1 = c.b1 * x - c.a1 * y + s.z2;
s.z2 = c.b2 * x - c.a2 * y;
samples[idx] = y;
} }
} }
} }
void EqProcessor::recomputeBiquad(int band) { void EqProcessor::recomputeBiquad(int band) {
const float sr = static_cast<float>(m_sampleRate); const double sampleRate = static_cast<double>(m_sampleRate);
const float f0 = FREQS[band]; const double frequency = FREQS[band];
const float dBg = m_gainDb[band]; const double gainDb = m_gainDb[band];
const float Q = 1.41421356f; // sqrt(2) , Butterworth Q constexpr double Q = std::numbers::sqrt2;
const float A = std::pow(10.f, dBg / 40.f);
const double w0 = 2.0 * std::numbers::pi * f0 / sr;
const double cW = std::cos(w0);
const double sW = std::sin(w0);
const double alp = sW / (2.0 * Q);
// Peaking EQ biquad // RBJ peaking EQ gain factor
const double b0 = 1 + alp * A, b1 = -2 * cW, b2 = 1 - alp * A; const double A = std::pow(10.0, gainDb / 40.0);
const double a0 = 1 + alp / A, a1 = -2 * cW, a2 = 1 - alp / A; const double omega = 2.0 * std::numbers::pi * frequency / sampleRate;
const double sinW = std::sin(omega);
const double cosW = std::cos(omega);
m_coeff[band][0] = float(b0 / a0); const double alpha = sinW / (2.0 * Q);
m_coeff[band][1] = float(b1 / a0);
m_coeff[band][2] = float(b2 / a0); // rbj audio eq cookbook
m_coeff[band][3] = float(a1 / a0); const double b0 = 1.0 + alpha * A;
m_coeff[band][4] = float(a2 / a0); const double b1 = -2.0 * cosW;
const double b2 = 1.0 - alpha * A;
const double a0 = 1.0 + alpha / A;
const double a1 = -2.0 * cosW;
const double a2 = 1.0 - alpha / A;
const double invA0 = 1.0 / a0;
auto &c = m_coeff[band];
c.b0 = static_cast<float>(b0 * invA0);
c.b1 = static_cast<float>(b1 * invA0);
c.b2 = static_cast<float>(b2 * invA0);
c.a1 = static_cast<float>(a1 * invA0);
c.a2 = static_cast<float>(a2 * invA0);
} }
} // namespace engine } // namespace engine
+15 -3
View File
@@ -1,5 +1,4 @@
#pragma once #pragma once
#include <array>
#include "AudioBuffer.h" #include "AudioBuffer.h"
namespace engine { namespace engine {
@@ -28,10 +27,23 @@ private:
int m_sampleRate { 44100 }; int m_sampleRate { 44100 };
float m_gainDb[BANDS] {}; float m_gainDb[BANDS] {};
float m_coeff[BANDS][5] {}; struct BiquadCoefficients {
float b0 {};
float b1 {};
float b2 {};
float a1 {};
float a2 {};
};
BiquadCoefficients m_coeff[BANDS];
struct BiquadState {
float z1;
float z2;
};
static constexpr int MAX_CH = 8; static constexpr int MAX_CH = 8;
float m_state[BANDS][MAX_CH][2] {}; BiquadState m_state[BANDS][MAX_CH] {};
}; };
} // namespace engine } // namespace engine