00001 #include "afw.h" 00002 #include "flt.h" 00003 /** \file processdata.cpp 00004 * \brief オーディオコールバック関数 00005 * \author アナログ・デバイセズ株式会社 00006 * 00007 * このファイルは、オーディオ処理のコールバック関数を含む。 00008 */ 00009 namespace afw{ 00010 /** ステージ数 00011 * バイクワッドフィルタの段数を与える。バイクワッド1段辺り2次なので、 00012 * 6次のチェビシェフフィルタならステージ数は3 00013 */ 00014 const int stages = 1; 00015 /** IIRフィルタ系数列 00016 * IIRフィルタに与える係数の列。先頭から順位にA2/k, A1/k, B2/k, B1/k, B0/k。A0は指定 00017 * しないが、1で無ければならない。複数ステージのバイクワッドを直列実装する場合は、 00018 * 同じ順序で繰り返し係数を指定する。すなわち、 00019 * A02/k0, A01/k0, B02/k0, B01/k0, B00/k0, A12/k1, A11/k1, B12/k1, B11/k1, B10/k1, ... 00020 * kの値はステージ毎に指定できるkの指定は afw::scalefactorで指定する。 00021 * 00022 * サンプルで使っている係数は、「実践ディジタル・フィルタ設計入門」(ISBN4-7898-3400-X)158ページから引用した。 00023 */ 00024 // const shortfract coeff[stages*5] = { 0.196r, -0.370r, 0.391r, -0.783r, 0.391 }; // スケーリングしない場合 00025 const shortfract coeff[stages*5] = { 0.098r, -0.185r, 0.195r, -0.392r, 0.195 }; 00026 /** 係数のスケールを決める 00027 * バイクワッドのステージ毎にスケールファクターkを決める。kは次の式で求める。 00028 * k = 2^p 00029 * すなわち、k=1ならばp=0、k=4ならばp=2である。pの値は最初のステージから順に 00030 * 宣言する。p0, p1, p2... 00031 */ 00032 const short scalefactor[stages] = {1}; 00033 00034 /** フィルタ・オブジェクト 00035 * FIRフィルタを実装するためのオブジェクト。CFilter型は、他のフィルタ型の先祖に当たる。 00036 * 実際に生成されるフィルタ・オブジェクトは、CFilterの子孫のクラスに属する。 00037 */ 00038 flt::CFilter* filter; 00039 00040 /** コールバック関数の初期化 00041 * 00042 * フィルタ・オブジェクトを生成して実行の準備を行う。生成するオブジェクトのクラスは flt::CIIRFilterExである。 00043 * オブジェクト生成時に係数配列やタップ数を指定するため、実行時にこれらのパラメータを指定する必要はない。 00044 */ 00045 void initProcessData(void) 00046 { 00047 // iirフィルタを作る 00048 filter = new flt::CIIRFilterEx( coeff, scalefactor,stages ); 00049 // filter = new flt::CIIRFilter( coeff, stages ); // スケーリングしない場合 00050 } 00051 /** オーディオ・コールバック関数 00052 * 00053 * @param leftIn 左チャンネルの入力データバッファ 00054 * @param rightIn 右チャンネルの入力データバッファ 00055 * @param leftOut 左チャンネルの出力データバッファ 00056 * @param rightOut 右チャンネルの出力データバッファ 00057 * @param count 各バッファに格納されているオーディオデータの数 00058 * 00059 * 左チャンネルにFIRフィルタを施して出力する。同じ入力データを 00060 * 比較のため処理せずに右チャンネルにも出力する。 00061 * 00062 * 実行に当たって必要なfilterオブジェクトの生成は、 afw::initProcessDataで行っている。 00063 */ 00064 00065 void processData( 00066 const shortfract leftIn[], 00067 const shortfract rightIn[], 00068 shortfract leftOut[], 00069 shortfract rightOut[], 00070 int count 00071 ) 00072 { 00073 // 注意:左チャンネルしか処理していない 00074 filter->run( leftIn, leftOut, count ); 00075 00076 // 参照用に未処理の信号を右チャンネルに出力している 00077 for( int i=0; i<count; i++ ) 00078 rightOut[i] = leftIn[i]; 00079 } // processData 00080 00081 }; // namespace afw