ANCcontroller.h 4.21 KB
Newer Older
杉下大河's avatar
杉下大河 committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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
148
149
150
151
#pragma once

//#include <Arduino.h>
#include <deque>
#include <numeric>
#include <math.h>

#include "array.h"

class WaveGenerator
{
  private:
    const int16_t AS_16BIT_MAX_NUM = 32767;
    const float FREQ = 120;
    const float SAMPLE_RATE = 48000;
    const float GAIN = 0.8;

    //charp信号用_Juceから移植したのでリファクタリング推奨
    const float fMin = 50;
    const float fMax = 700;
    const float tLength = 0.15;

    std::deque<int16_t> wave_sin;
    std::deque<int16_t> waveChirp;

    void CreateSinWave();
    void CreateChirpWave();

  public:
    uint32_t sound_cnt = 0;

    WaveGenerator();

    int16_t playWaveSin();
    int16_t playWaveCharp();

    void dumpWaveDat() {

#if 0 //チャープ信号の内容をCSVで出力できます
      std::string outFileName = "Charpwave.csv";
      std::ofstream wavedat(outFileName);
      for (auto &w : waveChirpSignal )
        wavedat << w << ",";
#endif

    }



};

//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) ;
    static const int16_t CoefCLen = 900 ;
    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;}

  private:

};