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
30namespace dp_fx {
31
32using FXBuffer = SHCircularBuffer<float>;
33
34class ChannelBuffer {
35public:
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);
105private:
106    unsigned int mSamplingRate;
107    unsigned int mBlockSize;
108
109};
110
111using CBufferVector = std::vector<ChannelBuffer>;
112
113using GroupsMap = std::map<int32_t, IntVec>;
114
115class LinkedLimiters {
116public:
117    void reset();
118    void update(int32_t group, int index);
119    void remove(int index);
120    GroupsMap mGroupsMap;
121};
122
123class DPFrequency : public DPBase {
124public:
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
131private:
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