フーリエ変換 をするCLASSを作ろうとインターネットを探したのですが、参考になるHPが意外に少なかったので、私の作ったCLASSをここに置いておきます。これから作ろうとされる方は参考にしてみてください。
↓のDft.javaは離散フーリエ変換を行うクラスです。詳しくはソースをよくお読みください。
クラス、TextFileとBynaryFileはファイルを読み書きする自作クラスです。
| package tomolib.wave;
import tomolib.wave.*; import tomolib.util.*;
/** 離散フーリエ変換(DFT) 実行Class<BR> 2004/1/4作成 */ public class Dft {
/** * メソッド:public void dft( int[] data ,int samp ) <BR> * 引数:data:音声DATA<BR> * 引数:samp:サンプリング周波数(回/秒)<BR> * 引数:interbal:解析する間隔(1/samp*iterbal秒)<BR> * 引数:stop :解析終了周波数<BR> * 機能:音声DATAをdftする<BR> * 返り値:周波数ごとの強度<BR> */ public double[][] dft( int[] datatmp ,int samp ,int interbal , int stop ) { int[] data = null; //data数が2のべき乗であるように多ければカットする。 int datanos=1; while( datanos = datatmp.length ){ datanos = datanos * 2;} if( datanos == datatmp.length ) { data = datatmp; } else { datanos = (int)( datanos / 2. ); data = new int[ datanos ]; for(int I=0;I datanos;I++) {data[I] = datatmp[I]; } }
//解析結果data数の設定 int sampn = (int)((double)( stop )/((double)interbal)); double[][] kekka = new double[sampn][2]; double tmpx,tmpy; for ( int I=0; I sampn ; I++) { tmpx = 0; tmpy = 0; for ( int j=0 ; j data.length ; j++) { tmpx = tmpx + data[j] * Math.cos( 2. * Math.PI * ( interbal * I) * j / (double)samp ); tmpy = tmpy - data[j] * Math.sin( 2. * Math.PI * ( interbal * I) * j / (double)samp );
} kekka[I][1] = Math.sqrt( tmpx * tmpx + tmpy * tmpy ) * 2. / (double)samp ; kekka[I][0] = (double)( interbal * I); }
return kekka; }
/** * アプリケーション:main()<BR> * 機能:このclassの動作確認用<BR> */ public static void main(String args[]) { Wav wav = new Wav(); wav.readWav( test.wav ); Dft dft = new Dft(); double kekka[][] = dft.dft( wav.DATA , wav.SAMP , 10 , 2500 );
TextFile t = new TextFile(); t.OutOpen( test.csv ); for(int I=0;I kekka.length ;I++) { System.out.println( kekka[I][0]+ +kekka[I][1] ); t.Write( kekka[I][0] + , + kekka[I][1] ); } t.OutClose(); }
}
|
↓はwav形式のファイルの中身を読み込むWav.java
| package tomolib.wave;
import tomolib.util.*; import tomolib.wave.*; import java.util.*;
/** .wav形式の音声ファイルの処理を行う<BR> 条件で名称変更する<BR> 2004/1/4作成 伊藤智行<BR> */ public class Wav { /**1秒間あたりのサンプリング数*/ public int SAMP; /**1サンプルのバイト数*/ public int BYTE; /**サンプルDATA数*/ public int DATA[]=null;
/** * メソッド:public void readWav( String wavfile ) <BR> * 引数:<BR> * 機能:Wav形式のデータファイルを開いてこのClassに格納する<BR> 読み込むのはDATAと、サンプリング周期、DATAバイト数。 * 返り値:なし<BR> */ public void readWav( String wavfile ) { BynaryFile b = new BynaryFile(); b.InOpen( wavfile ); b.readStringN( 24 ); SAMP = b.ReadInt( 1 ); SAMP = SAMP + 256 * b.ReadInt( 1 ); SAMP = SAMP + 256 * 256 * b.ReadInt( 1 ); SAMP = SAMP + 256 * 256 * 256 * b.ReadInt( 1 ); b.readStringN( 4 ); BYTE = b.ReadInt( 1 ); BYTE = BYTE + 256 * b.ReadInt( 1 ); b.readStringN( 16 ); b.readStringN( 4 ) ; //ここには data が入る Vector vect = new Vector(); int tmpi=b.ReadInt( 1 ); int tmpii =0; while( tmpii==0 ) { vect.addElement( new Integer(tmpi) ); tmpi=b.ReadInt( 1 ); if( tmpi == -1 ){tmpii=1;} } b.InClose(); DATA = new int[vect.size()]; for( int I =0;I vect.size(); I++) { DATA[I] = ((Integer)vect.get( I )).intValue(); }
return; }
/** * メソッド:public void writeData() <BR> * 引数:<BR> * 機能:格納されたDATAをテキストファイルに出力(試験用)<BR> * 返り値:なし<BR> */ public void writeData() { TextFile t = new TextFile(); t.OutOpen( wav-txt.txt ); t.Write( + SAMP ); for( int I =0;I DATA.length ; I++) { t.Write( + DATA[I] ); } t.OutClose();
}
/** * アプリケーション:main()<BR> * 機能:このclassの動作確認用<BR> */ public static void main(String args[]) { Wav wav = new Wav(); wav.readWav( test__.wav ); wav.writeData(); }
} |
私の声をwavファイルに記録し、Wavクラスを用いてグラフにしたものが下のグラフ。60Hzと600Hzくらいの波が重なっているのがわかります。
このwavファイルをDft.classに通してフーリエ変換したのがしたのグラフ。正常に変換されているようです。

作成日: 2004-05-07 07:39:00
このページは「ともさん」が個人的に運営しています。