Skip to content

Commit 9736565

Browse files
committed
More restructure
1 parent eb1a9fc commit 9736565

File tree

5 files changed

+292
-76
lines changed

5 files changed

+292
-76
lines changed
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
/*
2+
==============================================================================
3+
4+
This file is part of the YUP library.
5+
Copyright (c) 2025 - [email protected]
6+
7+
YUP is an open source library subject to open-source licensing.
8+
9+
The code included in this file is provided under the terms of the ISC license
10+
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
11+
to use, copy, modify, and/or distribute this software for any purpose with or
12+
without fee is hereby granted provided that the above copyright notice and
13+
this permission notice appear in all copies.
14+
15+
YUP IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
16+
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
17+
DISCLAIMED.
18+
19+
==============================================================================
20+
*/
21+
22+
#pragma once
23+
24+
namespace yup
25+
{
26+
27+
//==============================================================================
28+
/**
29+
First-order IIR filter implementation.
30+
31+
The filter implements the difference equation:
32+
y[n] = b0*x[n] + b1*x[n-1] - a1*y[n-1]
33+
34+
@see FilterBase, FirstOrderCoefficients, FirstOrderState
35+
*/
36+
template <typename SampleType, typename CoeffType = double>
37+
class FirstOrder : public FilterBase<SampleType, CoeffType>
38+
{
39+
public:
40+
//==============================================================================
41+
/** Default constructor */
42+
FirstOrder() = default;
43+
44+
//==============================================================================
45+
/**
46+
Sets the filter coefficients.
47+
48+
@param newCoefficients The new first-order coefficients
49+
*/
50+
void setCoefficients (const FirstOrderCoefficients<CoeffType>& newCoefficients) noexcept
51+
{
52+
coefficients = newCoefficients;
53+
}
54+
55+
/**
56+
Gets the current filter coefficients.
57+
58+
@returns The current first-order coefficients
59+
*/
60+
const FirstOrderCoefficients<CoeffType>& getCoefficients() const noexcept
61+
{
62+
return coefficients;
63+
}
64+
65+
//==============================================================================
66+
/** @internal */
67+
void reset() noexcept override
68+
{
69+
state.reset();
70+
}
71+
72+
/** @internal */
73+
void prepare (double sampleRate, int maximumBlockSize) noexcept override
74+
{
75+
this->sampleRate = sampleRate;
76+
this->maximumBlockSize = maximumBlockSize;
77+
reset();
78+
}
79+
80+
/** @internal */
81+
SampleType processSample (SampleType inputSample) noexcept override
82+
{
83+
const auto inputCoeff = static_cast<CoeffType> (inputSample);
84+
const auto outputCoeff = coefficients.b0 * inputCoeff + coefficients.b1 * state.x1 - coefficients.a1 * state.y1;
85+
86+
state.x1 = inputCoeff;
87+
state.y1 = outputCoeff;
88+
89+
return static_cast<SampleType> (outputCoeff);
90+
}
91+
92+
/** @internal */
93+
void processBlock (const SampleType* inputBuffer, SampleType* outputBuffer, int numSamples) noexcept override
94+
{
95+
auto x1 = state.x1;
96+
auto y1 = state.y1;
97+
const auto b0 = coefficients.b0;
98+
const auto b1 = coefficients.b1;
99+
const auto a1 = coefficients.a1;
100+
101+
for (int i = 0; i < numSamples; ++i)
102+
{
103+
const auto input = inputBuffer[i];
104+
const auto output = b0 * input + b1 * x1 - a1 * y1;
105+
106+
x1 = input;
107+
y1 = output;
108+
outputBuffer[i] = output;
109+
}
110+
111+
state.x1 = x1;
112+
state.y1 = y1;
113+
}
114+
115+
/** @internal */
116+
DspMath::Complex<CoeffType> getComplexResponse (CoeffType frequency) const noexcept override
117+
{
118+
return coefficients.getComplexResponse (frequency, this->sampleRate);
119+
}
120+
121+
/** @internal */
122+
void getPolesZeros (
123+
DspMath::ComplexVector<CoeffType>& poles,
124+
DspMath::ComplexVector<CoeffType>& zeros) const override
125+
{
126+
poles.reserve (1);
127+
zeros.reserve (1);
128+
129+
DspMath::extractPolesZerosFromFirstOrder (coefficients.b0, coefficients.b1, coefficients.a1, poles, zeros);
130+
}
131+
132+
private:
133+
//==============================================================================
134+
struct FirstOrderState
135+
{
136+
CoeffType x1 = 0; // Input delay
137+
CoeffType y1 = 0; // Output delay
138+
139+
/** Resets all state variables to zero */
140+
void reset() noexcept
141+
{
142+
x1 = y1 = static_cast<CoeffType> (0.0);
143+
}
144+
};
145+
146+
//==============================================================================
147+
FirstOrderCoefficients<CoeffType> coefficients;
148+
FirstOrderState state;
149+
150+
//==============================================================================
151+
YUP_LEAK_DETECTOR (FirstOrder)
152+
};
153+
154+
//==============================================================================
155+
/** Type aliases for convenience */
156+
using FirstOrderFloat = FirstOrder<float>; // float samples, double coefficients (default)
157+
using FirstOrderDouble = FirstOrder<double>; // double samples, double coefficients (default)
158+
159+
} // namespace yup

0 commit comments

Comments
 (0)