xref: /aosp_15_r20/external/oboe/src/flowgraph/Limiter.h (revision 05767d913155b055644481607e6fa1e35e2fe72c)
1*05767d91SRobert Wu /*
2*05767d91SRobert Wu  * Copyright 2022 The Android Open Source Project
3*05767d91SRobert Wu  *
4*05767d91SRobert Wu  * Licensed under the Apache License, Version 2.0 (the "License");
5*05767d91SRobert Wu  * you may not use this file except in compliance with the License.
6*05767d91SRobert Wu  * You may obtain a copy of the License at
7*05767d91SRobert Wu  *
8*05767d91SRobert Wu  *      http://www.apache.org/licenses/LICENSE-2.0
9*05767d91SRobert Wu  *
10*05767d91SRobert Wu  * Unless required by applicable law or agreed to in writing, software
11*05767d91SRobert Wu  * distributed under the License is distributed on an "AS IS" BASIS,
12*05767d91SRobert Wu  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*05767d91SRobert Wu  * See the License for the specific language governing permissions and
14*05767d91SRobert Wu  * limitations under the License.
15*05767d91SRobert Wu  */
16*05767d91SRobert Wu 
17*05767d91SRobert Wu #ifndef FLOWGRAPH_LIMITER_H
18*05767d91SRobert Wu #define FLOWGRAPH_LIMITER_H
19*05767d91SRobert Wu 
20*05767d91SRobert Wu #include <atomic>
21*05767d91SRobert Wu #include <unistd.h>
22*05767d91SRobert Wu #include <sys/types.h>
23*05767d91SRobert Wu 
24*05767d91SRobert Wu #include "FlowGraphNode.h"
25*05767d91SRobert Wu 
26*05767d91SRobert Wu namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph {
27*05767d91SRobert Wu 
28*05767d91SRobert Wu class Limiter : public FlowGraphFilter {
29*05767d91SRobert Wu public:
30*05767d91SRobert Wu     explicit Limiter(int32_t channelCount);
31*05767d91SRobert Wu 
32*05767d91SRobert Wu     int32_t onProcess(int32_t numFrames) override;
33*05767d91SRobert Wu 
getName()34*05767d91SRobert Wu     const char *getName() override {
35*05767d91SRobert Wu         return "Limiter";
36*05767d91SRobert Wu     }
37*05767d91SRobert Wu 
38*05767d91SRobert Wu private:
39*05767d91SRobert Wu     // These numbers are based on a polynomial spline for a quadratic solution Ax^2 + Bx + C
40*05767d91SRobert Wu     // The range is up to 3 dB, (10^(3/20)), to match AudioTrack for float data.
41*05767d91SRobert Wu     static constexpr float kPolynomialSplineA = -0.6035533905; // -(1+sqrt(2))/4
42*05767d91SRobert Wu     static constexpr float kPolynomialSplineB = 2.2071067811; // (3+sqrt(2))/2
43*05767d91SRobert Wu     static constexpr float kPolynomialSplineC = -0.6035533905; // -(1+sqrt(2))/4
44*05767d91SRobert Wu     static constexpr float kXWhenYis3Decibels = 1.8284271247; // -1+2sqrt(2)
45*05767d91SRobert Wu 
46*05767d91SRobert Wu     /**
47*05767d91SRobert Wu      * Process an input based on the following:
48*05767d91SRobert Wu      * If between -1 and 1, return the input value.
49*05767d91SRobert Wu      * If above kXWhenYis3Decibels, return sqrt(2).
50*05767d91SRobert Wu      * If below -kXWhenYis3Decibels, return -sqrt(2).
51*05767d91SRobert Wu      * If between 1 and kXWhenYis3Decibels, use a quadratic spline (Ax^2 + Bx + C).
52*05767d91SRobert Wu      * If between -kXWhenYis3Decibels and -1, use the absolute value for the spline and flip it.
53*05767d91SRobert Wu      * The derivative of the spline is 1 at 1 and 0 at kXWhenYis3Decibels.
54*05767d91SRobert Wu      * This way, the graph is both continuous and differentiable.
55*05767d91SRobert Wu      */
56*05767d91SRobert Wu     float processFloat(float in);
57*05767d91SRobert Wu 
58*05767d91SRobert Wu     // Use the previous valid output for NaN inputs
59*05767d91SRobert Wu     float mLastValidOutput = 0.0f;
60*05767d91SRobert Wu };
61*05767d91SRobert Wu 
62*05767d91SRobert Wu } /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */
63*05767d91SRobert Wu 
64*05767d91SRobert Wu #endif //FLOWGRAPH_LIMITER_H
65