1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 
18 #ifndef DPFREQUENCY_H_
19 #define DPFREQUENCY_H_
20 
21 #include <Eigen/Dense>
22 #include <unsupported/Eigen/FFT>
23 
24 #include "RDsp.h"
25 #include "SHCircularBuffer.h"
26 
27 #include "DPBase.h"
28 
29 
30 namespace dp_fx {
31 
32 using FXBuffer = SHCircularBuffer<float>;
33 
34 class ChannelBuffer {
35 public:
36     FXBuffer cBInput;   // Circular Buffer input
37     FXBuffer cBOutput;  // Circular Buffer output
38     FloatVec input;     // time domain temp vector for input
39     FloatVec output;    // time domain temp vector for output
40     FloatVec outTail;   // time domain temp vector for output tail (for overlap-add method)
41 
42     Eigen::VectorXcf complexTemp; // complex temp vector for frequency domain operations
43 
44     //Current parameters
45     float inputGainDb;
46     float outputGainDb;
47     struct BandParams {
48         bool enabled;
49         float freqCutoffHz;
50         size_t binStart;
51         size_t binStop;
52     };
53     struct EqBandParams : public BandParams {
54         float gainDb;
55     };
56     struct MbcBandParams : public BandParams {
57         float gainPreDb;
58         float gainPostDb;
59         float attackTimeMs;
60         float releaseTimeMs;
61         float ratio;
62         float thresholdDb;
63         float kneeWidthDb;
64         float noiseGateThresholdDb;
65         float expanderRatio;
66 
67         //Historic values
68         float previousEnvelope;
69     };
70     struct LimiterParams {
71         int32_t linkGroup;
72         float attackTimeMs;
73         float releaseTimeMs;
74         float ratio;
75         float thresholdDb;
76         float postGainDb;
77 
78         //Historic values
79         float previousEnvelope;
80         float newFactor;
81         float linkFactor;
82     };
83 
84     bool mPreEqInUse;
85     bool mPreEqEnabled;
86     std::vector<EqBandParams> mPreEqBands;
87 
88     bool mMbcInUse;
89     bool mMbcEnabled;
90     std::vector<MbcBandParams> mMbcBands;
91 
92     bool mPostEqInUse;
93     bool mPostEqEnabled;
94     std::vector<EqBandParams> mPostEqBands;
95 
96     bool mLimiterInUse;
97     bool mLimiterEnabled;
98     LimiterParams mLimiterParams;
99     FloatVec mPreEqFactorVector; // temp pre-computed vector to shape spectrum at preEQ stage
100     FloatVec mPostEqFactorVector; // temp pre-computed vector to shape spectrum at postEQ stage
101 
102     void initBuffers(unsigned int blockSize, unsigned int overlapSize, unsigned int halfFftSize,
103             unsigned int samplingRate, DPBase &dpBase);
104     void computeBinStartStop(BandParams &bp, size_t binStart);
105 private:
106     unsigned int mSamplingRate;
107     unsigned int mBlockSize;
108 
109 };
110 
111 using CBufferVector = std::vector<ChannelBuffer>;
112 
113 using GroupsMap = std::map<int32_t, IntVec>;
114 
115 class LinkedLimiters {
116 public:
117     void reset();
118     void update(int32_t group, int index);
119     void remove(int index);
120     GroupsMap mGroupsMap;
121 };
122 
123 class DPFrequency : public DPBase {
124 public:
125     virtual size_t processSamples(const float *in, float *out, size_t samples);
126     virtual void reset();
127     void configure(size_t blockSize, size_t overlapSize, size_t samplingRate);
128     static size_t getMinBockSize();
129     static size_t getMaxBockSize();
130 
131 private:
132     void updateParameters(ChannelBuffer &cb, int channelIndex);
133     size_t processMono(ChannelBuffer &cb);
134     size_t processOneVector(FloatVec &output, FloatVec &input, ChannelBuffer &cb);
135 
136     size_t processChannelBuffers(CBufferVector &channelBuffers);
137     size_t processFirstStages(ChannelBuffer &cb);
138     size_t processLastStages(ChannelBuffer &cb);
139     void processLinkedLimiters(CBufferVector &channelBuffers);
140 
141     size_t mBlockSize;
142     size_t mHalfFFTSize;
143     size_t mOverlapSize;
144     size_t mSamplingRate;
145 
146     float mBlocksPerSecond;
147 
148     CBufferVector mChannelBuffers;
149 
150     LinkedLimiters mLinkedLimiters;
151 
152     //dsp
153     FloatVec mVWindow;  //window class.
154     float mWindowRms;
155     Eigen::FFT<float> mFftServer;
156 };
157 
158 } //namespace dp_fx
159 
160 #endif  // DPFREQUENCY_H_
161