DirectX EmptyProjectを使う その23(ああっ!、もったいない)

 
                              S9(40dBuEMF)入力信号の、filter通過後のオーディオ出力(cutoff 2900Hz、 Prodigy7.1XT使用)

 1.ああっ!もったいない....

     サウンドカードの EDIROL FA-66 使用時に、CPU使用率が、60〜90% にまで、上がってしまう原因は、

     何と! DirectXの描くスピードが、速すぎたのが、原因です。

     DirectXには、定数フレーム時間を設定するvoid DXUTSetConstantFrameTime( bool bEnabled, float fTimePerFrame ) が、存在しますが

     実は、この関数は、作動しません。

    MicrosoftのMSDNを、調べると

            HRESULT DXUTSetConstantFrameTime(BOOL bEnabled,FLOAT fTimePerFrame);
 
      と、書いてありますが、 
 
     第一、この関数の返す値が 一方は void型なのに、MSDNでは HRESULT型です.....?
     
          では、如何するか?

     描画をつかさどる部分は、DirectXのフレーム内の

       void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext ) 

     です。

     時間を遅らせるのは、簡単です。     

     この関数内に、スリープ関数を、入れてやればよいのです。 ::Sleep(40); 40ms もっ!

     ああっ! もったいない....

     こうすると、 FA-66使用時も、CPU使用率は20〜35%位に、落ち着きます.......

     FPS (frames per second) は、18くらいに、落ちます。 

     でも、watch している限りは、これくらいの速度でも、CW時の画面の動きは、出力音声と、ほぼ一致していますから、許容できます。

     何たる贅沢や....
 
2.ピーク値を使うと、出力が一定しない件

     今では、ピーク値を使っても、出力が一定するように、なりました、ホッ (^_^;;

     理論的には、私のプログラムは、間違ってなかったので、不思議に思ってました。

     不具合は、filterの切れに、あったようです。 (96KHz sampling時)

    
           改良前 音声出力(入力 S9 40dBuEMF)                              改良後 音声出力(同)

     プログラム的には

        入力信号のFFT結果 * filterのFFT結果 = result3[]

     の、後に、続けて

          for(i=span;i<4096;i++)
            DATA->result3[2*i]=DATA->result3[2*i+1]=0;

     と、手動 notch と、同じ手法を使いました。

     この後、逆FFTして、時間信号に戻してやると、安定した音声出力を得る事が、できました。

     やれやれ、安堵いたしました、ホッ。

 
3.filterの 0Hz 付近での、不具合の件

     先ず、言っておかないと、あかん事は、

     私は、50Hz とか、8Hz とかの、低周波の復元に、こだわっているわけでは、ありません。

     ただ、filterの0Hz付近に、希望以外の信号が来た時、(シグナルが、かぶさった時)

     問題に、なるからです。

       

      一応の解決策は、 LPF(Low pass filter)を止めて、 BPF(Band pass filter)に、変えた事です。

      窓関数法のBPFは、こんな風に、定義しました。

void CFir:: get_BPFir_coeff(int samples_per_sec,double* dest,int size,int low_f,int high_f)
        {
   int i;
   double fc_low ;     //cut off lower frequency
   double fc_high;  //        higher frequency
   double delta_frequency_current;//遷移周波数
  
   //フィルターサイズを指定して、遷移周波数は、計算で求める

            // use window
            switch (func_no)
            {
                case 0: delta_frequency_current = 0.9/size; break;
                case 1: delta_frequency_current = 3.1/size; break;
                case 2: delta_frequency_current = 3.3/size; break;
                case 3: delta_frequency_current = 5.5/size; break;
                case 4:
                case 5:
                default: delta_frequency_current = 3.3/size; break;
            }

            delta_frequency_current *= samples_per_sec;       //de_normalize

            fc_low = low_f  - delta_frequency_current / 2.0;    // not normalize
       fc_high= high_f + delta_frequency_current / 2.0;

   if(fc_low<0)
    fc_low=delta_frequency_current /2.0;

            //normalize
            fc_low  /= samples_per_sec;
   fc_high /= samples_per_sec;

   int k = 0;
            for ( i = (int)(-size/2); i <(int)(size/2); i++)//LPFirの係数をずらす。
            {              //両側にimpulse応答を出す為
                if (i == 0)
                    dest[k] = 2.0 * (fc_high-fc_low);
                else
                {
                    dest[k] = fc_high*sin(2*pi*fc_high*i)/(pi*fc_high*i) - fc_low*sin(2*pi*fc_low*i)/(pi*fc_low*i);
                }

                k++;
            }
}
        (参考: ディジタルサウンド処理入門 青木先生 CQ出版 p.69 )  
 
    これで、一応、正常に、動いてくれています。

    しかし、 入力信号が、大きすぎると、雑音が、やはり、目立ちます......

    decimationも、やってみましたが、

    私のプログラムでは、向いてないのです。(filterも、まだ、96KHzが、sampling周波数です)

    なんとか、しのげた気が、します。

       H.19.12.16