Deluge Firmware 1.3.0
Build date: 2025.06.05
Loading...
Searching...
No Matches
filter.h
1/*
2 * Copyright © 2015-2023 Synthstrom Audible Limited
3 *
4 * This file is part of The Synthstrom Audible Deluge Firmware.
5 *
6 * The Synthstrom Audible Deluge Firmware is free software: you can redistribute it and/or modify it under the
7 * terms of the GNU General Public License as published by the Free Software Foundation,
8 * either version 3 of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
11 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with this program.
15 * If not, see <https://www.gnu.org/licenses/>.
16 */
17
18#pragma once
19
20#include "dsp/stereo_sample.h"
21#include "model/mod_controllable/filters/filter_config.h"
22#include "util/fixedpoint.h"
23#include "util/functions.h"
24#include <cstdint>
25#include <ranges>
26#include <span>
27
28namespace deluge::dsp::filter {
29constexpr int32_t ONE_Q16 = 134217728;
30
31extern std::array<StereoSample, SSI_TX_BUFFER_NUM_SAMPLES> blendBuffer;
45template <typename T>
46class [[gnu::hot]] Filter {
47public:
48 Filter() = default;
49 // returns a gain compensation value
50 q31_t configure(q31_t frequency, q31_t resonance, FilterMode lpfMode, q31_t lpfMorph, q31_t filterGain) {
51
52 // lpfmorph comes in q28 but we want q31
53 return static_cast<T*>(this)->setConfig(frequency, resonance, lpfMode, lshiftAndSaturate<2>(lpfMorph),
54 filterGain);
55 }
63 [[gnu::hot]] void filterMono(std::span<q31_t> buffer) {
64 if (dryFade < 0.001) {
65 static_cast<T*>(this)->doFilter(buffer);
66 return;
67 }
68
69 memcpy(blendBuffer.data(), buffer.data(), buffer.size_bytes());
70 static_cast<T*>(this)->doFilter(buffer);
71
72 std::span mono_blend_buffer{reinterpret_cast<q31_t*>(blendBuffer.data()), buffer.size()};
73
74 for (auto [dry, wet] : std::views::zip(mono_blend_buffer, buffer)) {
75 wet = multiply_32x32_rshift32(wet, wetLevel);
76 wet = multiply_accumulate_32x32_rshift32_rounded(wet, dry, ONE_Q31 - wetLevel) << 1;
77 updateBlend(); // will go to one over 512 samples
78 }
79 }
80
87 [[gnu::hot]] void filterStereo(std::span<StereoSample> buffer) {
88 if (dryFade < 0.001) {
89 static_cast<T*>(this)->doFilterStereo(buffer);
90 return;
91 }
92 memcpy(blendBuffer.data(), buffer.data(), buffer.size_bytes());
93 static_cast<T*>(this)->doFilterStereo(buffer);
94
95 for (auto [dry, wet] : std::views::zip(blendBuffer, buffer)) {
96 wet.l = multiply_32x32_rshift32(wet.l, wetLevel);
97 wet.l = multiply_accumulate_32x32_rshift32_rounded(wet.l, dry.l, ONE_Q31 - wetLevel) << 1;
98 wet.r = multiply_32x32_rshift32(wet.r, wetLevel);
99 wet.r = multiply_accumulate_32x32_rshift32_rounded(wet.r, dry.r, ONE_Q31 - wetLevel) << 1;
100 updateBlend();
101 }
102 }
103
107 void reset(bool fade = false) {
108 static_cast<T*>(this)->resetFilter();
109 if (fade) {
110 dryFade = 1;
111 wetLevel = 0;
112 }
113 }
114
115 void updateBlend() {
116 // fades over around 500 samples
117 dryFade = dryFade * 0.99;
118 wetLevel = (q31_t)(ONE_Q31 * (1 - dryFade));
119 }
120
125 void curveFrequency(q31_t frequency) {
126 // Between 0 and 8, by my making. 1 represented by 268435456
127 tannedFrequency = instantTan(lshiftAndSaturate<5>(frequency));
128
129 // this is 1q31*1q16/(1q16+tan(f)/2)
130 // tan(f) is q17
131 divideBy1PlusTannedFrequency = (q31_t)(288230376151711744.0 / (double)(ONE_Q16 + (tannedFrequency >> 1)));
132 fc = multiply_32x32_rshift32_rounded(tannedFrequency, divideBy1PlusTannedFrequency) << 4;
133 }
134 q31_t fc;
135 float dryFade = 1;
136 q31_t wetLevel = ONE_Q31;
137 q31_t tannedFrequency;
138 q31_t divideBy1PlusTannedFrequency;
139};
140
141} // namespace deluge::dsp::filter
void reset(bool fade=false)
Definition filter.h:107
void filterStereo(std::span< StereoSample > buffer)
Definition filter.h:87
void filterMono(std::span< q31_t > buffer)
Definition filter.h:63
void curveFrequency(q31_t frequency)
Definition filter.h:125