<DFTと位相>

1.DFT 離散フーリエ変換

AD変換して求めた入力信号の周波数特性を求めるための離散フーリエ変換をC++で記述したサンプルプログラムを参考に下記に示す。
ここでは、入力信号の波形は音声のピッチに同期した周期信号と仮定しているため、あえて窓を掛けることなく、計算している。


#include <math.h>

void   TCDFT::dft(short  *in_wave,  int kosuu)
{
   int i,j;
     double y0,y1,x0,xx;

      m_N = kosuu;    //m_N  はDFTの計算の次数。 入力のデータ数。
     
      m_wave=(double *)malloc( m_N * sizeof(double));
      for(i=0;i<m_N;++i)  *(m_wave+i) = (double) *(in_wave+i);
      // AD変換された m_N個の 16ビットの整数short s_waveデータを、
      //  実数double m_waveに変換する。
   
      m_x =(double *)malloc( m_N * 2 * sizeof(double));
     // DFTの計算結果を格納するためにメモリーを確保する。
     // 複素数なので、実数部、虚数部、と言う順に格納するのでメモリーが2倍になる。

     xx= 2.0 * M_PI / (double)m_N;  
     // サンプリング周波数fs[Hz]が2πに相当する。
     //  周波数は fs/m_N   [Hz]の ごとに計算される。
     //  つまり、    0 x  fs/m_N[Hz] は   m_x[0] +  i  m_x[1]
     //                  1 x  fs/m_N[Hz] は   m_x[2] +  i  m_x[3]
     //                  2 x  fs/m_N[Hz] は   m_x[4] +  i  m_x[5]
     // ここで i は虚数単位を示す。
                                            
     for(i=0;i<m_N;++i)    
     {
       y0=y1=0.0;
       for(j=0;j<m_N;++j)   
       {
          x0= xx * (double)i * (double) j;
          y0 += cos(x0) * *(m_wave+j);  
          y1 -= sin(x0) * *(m_wave+j);
       }
       *(m_x + 2 * i) = y0;     // 複素数の実数部分
       *(m_x + 2 * i + 1 ) =y1; // 複素数の虚数部分
     }
     ・・・
}
 
class TCDFT
{
public:   
                   void      dft(short  *in_wave,  int kosuu);
                   ・・・
private:
                  int       m_N;
                  double *m_wave;
                  double *m_x;
};

このサンプルを実際に動作させるためには、おそらく、
ご使用されるプログラミング環境に合わせて修正・変更・追加などが必要です。
万一、このサンプルを動作させる場合は、あなたの責任においておこなってください。



付録:


   
2.位相
 オーディオ用のスピーカー・ボックス(箱)の設計者は耳が良いと言われる。実際、彼らは位相の違いを聞き分けながら仕事をしている。スピーカー・ユニッ トから出る音の位相 を調整して楽器の音や人の声が上手く鳴るようにするのもスピーカー・ボックス(箱)の設計者の腕の見せ所である。
特に、低い周波数(低音)には、周波数特性や歪み特 性では理解できない、音源に姿を与えるような秘密が隠されているのかもしれない。昔、オーディオ機器がアナログ再生からデジタル再生に変化したさい (CDやMP3しか知らないデジタル再生の世 代の方にはわからない話で申し訳ない)、音源の姿が弱くなってしまったのだ。もちろん、アナログ再生よりデジタル再生の方が周波数特性や歪みは優れてい るのだが、人が音を聞くときに感じる何かを失ってしまったのかもしれない。

周波数分析においては、位相情報は省略してしまい、更に、人の聴覚の強度感覚に真似て、dB(デシベル)というLOG尺度に変換した振幅値をつかうことが ある。DFTやFFTを使った周波数特性の値は、普通、複素数の値をもつ。複素数の絶対値をとり(ここで位相情報が失われる)、10のLOG値を計算し、 20を乗じるとdB(デシベル)の尺度になる。振幅で20dBは10倍を意味する。(注:もちろんスピーカー・ボックス(箱)の設計者は振幅特性だけでは なく位相特性もチェックしている。)

2つの音があった場合、人はどの位の音の強さの違いを聞き分けることができるのだろうか?仮に、60dB(デシベル)までの音の強さの違いを聞き分けるこ とができたと仮定しよう。60dBと言うと1000倍の違いまで聞き分けることができる。逆に、例えば66dBの違いがあると、大きい音の方に埋もれても 小 さい方の音は聞き分けることができないわけだ。この特徴は、コンピューターで計算する計算量を減らし情報量を減らすことに役立つことができる。つまり、 一番大きな音から60dBより更に小さい音ならば、情報として省略できたり、また、あらかじめ60dBより小さいと予想されるある周波数以上は割り 切って計算からも除外することで、計算量を減らしメモリーを節約し、より高速にすることができるかもしれないのである。



No.9b   2006年1月9日