ANCcontroller.h 4.38 KB
Newer Older
杉下大河's avatar
杉下大河 committed
1
2
3
4
5
6
#pragma once

//#include <Arduino.h>
#include <deque>
#include <numeric>
#include <math.h>
7
8
//#include <stdlib.h>
#include <Arduino.h>
杉下大河's avatar
杉下大河 committed
9
10
11
12
13
14

#include "array.h"

class WaveGenerator
{
  private:
15
16


杉下大河's avatar
杉下大河 committed
17
    const int16_t AS_16BIT_MAX_NUM = 32767;
18
    const int16_t AS_12BIT_MAX_NUM = 4095;
杉下大河's avatar
杉下大河 committed
19
20
21
    const float FREQ = 120;
    const float GAIN = 0.8;

22
23
    float SAMPLE_RATE;
    int AS_nBIT_MAX_NUM; //量子化ビット数から算出した最大値(dex)
杉下大河's avatar
杉下大河 committed
24
25
26
27
28
29
    //charp信号用_Juceから移植したのでリファクタリング推奨
    const float fMin = 50;
    const float fMax = 700;
    const float tLength = 0.15;

    std::deque<int16_t> wave_sin;
30
31
    std::deque<int16_t> waveIntChirp;
    std::deque<int16_t> waveUnsingedIntChirp;
杉下大河's avatar
杉下大河 committed
32
33
34
35
36

    void CreateSinWave();
    void CreateChirpWave();

  public:
37
38
39
    static const char INT_WAVE = 0;
    static const char UNSINGED_INT_WAVE = 1;
    static const char FLOAT_WAVE = 2;
杉下大河's avatar
杉下大河 committed
40

41
    uint32_t sound_cnt = 0;
杉下大河's avatar
杉下大河 committed
42

43
    WaveGenerator(int sp_rate,int quantifying_bit_number);
杉下大河's avatar
杉下大河 committed
44
45


46
47
    int16_t playWaveSin(char mode);
    int16_t playWaveCharp(char mode);
杉下大河's avatar
杉下大河 committed
48
49
50
51
52
53
54
55
56
57
58
59
60

};

//model
class ANC_DataBase {
  public:
    ANC_DataBase();

    const float samplerate = 48000;
    static const int16_t WaveBufLen = 2000;

    //WaveBufLen >= CoefLenであること
    static const int16_t CoefWLen = (882 + 2400) ;
61
    static const int16_t CoefCLen = 300 ;//900
杉下大河's avatar
杉下大河 committed
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
    static const int16_t CoefHLen = 3800;

    inoArray<float, CoefCLen> coefC;//主経路
    inoArray<float, CoefWLen> coefW;//二次経路
    inoArray<float, CoefHLen> coefH;//ハウリング経路

    const float StepSizeW = 0.1;
    const float StepSizeC = 0.95;
    const float StepSizeH = 0.95;

    //LMS用バッファー
    std::deque<float> squaredXBuf;
    std::deque<float> inputXBuf;
    std::deque<float> filteredXBuf;
    std::deque<float> outputYBuf;

    float y = 0;
    float yc = 0;


    template <class T>
    void shiftBuffer(T inValue, std::deque<T>& ioBuffer);

    template<class T, class U, size_t FilterSize >
    float calcFIR(const std::deque<T>& inDataBuf, inoArray<U, FilterSize>& filter_ary);

    template <class T>
    void InitFilter(T &Filter);


    //クラス内部で適応フィルタを計算する
    //使い勝手を意識して引数多めにしているが、減らしてもいい
    //アルゴリズムを変更する場合はオーバーロードが妥当
    template<class T, size_t FilterSize >
    void calcAptiveFilter(float inErrValue, inoArray<T, FilterSize> &ioW, float inStepSize, const std::deque<T>& inXBuf, const std::deque<T>& xAvaHelp );

    template<class T, size_t FilterSize >
    void IdentTransferFunction(float errGain, float TrainingWave, inoArray<T, FilterSize>& TF, float inStepSize);

    //ANC用の波形を算出する(2マイク) CoefH CoefC 必須 TODO:未実装
    void calcANCwave_FF(float errGain , float refGain);
    
    //ANC用の波形を算出する(2マイク) CoefH CoefC いらないTODO:未実装
    void calcANCwave_Nopass(float errGain , float refGain);

    //ANC用の波形を算出する(1マイク) CoefC 必須
    void calcANCwave_IMC(float errGain);

    //ANC用の波形を算出する(H∞フィルタ)CoefH CoefC 必須 TODO:未実装
    void calcANCwave_HI(float errGain);


};

#define AS_IMC 1 //1マイク運用
#define AS_FF 2  //2マイク運用
#define AS_HI 3  //H∞フィルタ
class ANC_Controller {



  public:
	  //ANC構成情報
	  ANC_DataBase DB;

    //システム状態管理用の変数
    static const char IDENTIFICAT_COEFC = 0;
    static const char ACTIVATION_ANC = 1;
    //static const int16_t IDENTIFICAT_coefH

    ANC_Controller();

    //TrainingWaveと比較しながら経路の伝達関数を算出する。2ndとEchoで共通のプロパティを使っており、同時に実行することは想定していない。
    //同時に動かすと地獄みたいに重くなるので1つずつ測定し、終了時にDB.IdentTransferFunction()すること
    void calc2ndPassTF(float errGain, float TrainingWave) ;
    void calcEchoPassTF(float errGain, float TrainingWave) ;

    /* ANCの出力波形を計算して波形を出力
      AS_IMC 1 //1マイク運用
      AS_FF 2  //2マイク運用
      AS_HI 3  //H∞フィルタ */
    float calcANCwave(const char methodNum , float errGain , float refGain);

    //算出後の波形データを吐き出す
    float playANCwave() {return DB.y;}

148
149
150
    void printCoefH();
    void printCoefC();
    
杉下大河's avatar
杉下大河 committed
151
152
153
  private:

};