processdata.cpp

説明を見る。
00001 /** \file processdata.cpp
00002  *  \brief オーディオコールバック関数
00003  *  \author アナログ・デバイセズ株式会社
00004  *
00005  * このファイルは、オーディオ処理のコールバック関数を含む。
00006  */
00007  
00008 #include "afw.h"
00009 #include "ad7998.h"
00010 #include "dline.h"
00011 #include "osc.h"
00012 
00013 namespace afw{
00014     /**
00015     * 周波数指定用定数
00016     *
00017     * osc::COscillator型に周波数を指定するときの単位として作用する定数。
00018     */
00019     const int mHz = (int)(65536.0*65536.0/48000.0/1000.0);
00020     /** 
00021     * LFO用バッファ
00022     *
00023     * afw::lfoの出力データを一時的に格納するために使う。
00024     */
00025     shortfract * lfotemp;
00026     /**
00027     * 低周波発振器
00028     *
00029     * トーンジェネレーターに変調をかけるための低周波発振用変数。
00030     */
00031     osc::COscillator * lfo ;
00032 
00033     /** 最大シフト量
00034     *
00035     * シフタのディレイラインの長さを与える
00036     */
00037     const unsigned int maxShift = 1024;
00038     /** シフタ 
00039     *
00040     * エフェクタが使う位相シフタ
00041     */
00042     dline::CShifter * shifter;
00043     
00044 /** コールバック関数の初期化
00045     * @param count afw::processDataが呼ばれる際、各バッファに格納されているオーディオデータの数
00046     * 
00047     * afw::processData()関数を呼ぶ前に初期化の必要がある場合は、この関数内部で行う。
00048 */
00049     
00050     void initProcessData(int count)
00051     {
00052         shifter = new dline::CShifter( maxShift );
00053         lfo = new osc::CTableLookup(1000*mHz);
00054     }
00055     
00056 /** オーディオ・コールバック関数
00057     *
00058     * @param leftIn 左チャンネルの入力データバッファ
00059     * @param rightIn 右チャンネルの入力データバッファ
00060     * @param leftOut 左チャンネルの出力データバッファ
00061     * @param rightOut 右チャンネルの出力データバッファ
00062     * @param count 各バッファに格納されているオーディオデータの数
00063     *
00064     * この関数はDMAが受信バッファをいっぱいにするたびに割り込み経由で呼ばれる。
00065     * 引数として渡されるのは受信データを含む入力バッファのほか、送信データを
00066     * 格納するために使う出力バッファとデータ個数である。
00067     * ユーザーは関数内部で入力バッファのデータを加工して、出力バッファに送信すべき
00068     * データをおく。呼び出しに先立って初期化が必要な場合は、 afw::initProcessData()
00069     * 関数で行う。
00070     *
00071     * 配列はshortfract型である。この16bit固定小数点型はshortと同じ大きさを
00072     * 持つが、四則は固定小数点領域で定義されている。
00073     * 
00074     * フランジャのアルゴリズムを実装する。ディレイライン afw::shifter を使い
00075     * 入力を遅延させる。遅延出力は再度入力と加算してディレイラインに入れる。
00076     * 遅延量は低周波発振器 afw::lfoの出力で決める。 lfoの振幅と周波数は外部から
00077     * 読んだボリューム値によって決定する。 lfoの振幅が大きくなると、フランジャ
00078     * の効果のゆれ幅も大きくなる。
00079     *
00080     * ブロック化による雑音混入を防ぐため、遅延量は1サンプルごとに更新している。
00081     * このため、 shifterは1サンプルごとに呼び出しており、効率は悪い。
00082     *
00083     * 割り込みソースのクリアなどは、この関数の呼び出し側で行うので、関数内で
00084     * 処理する必要はない。
00085     */
00086 
00087     void processData( 
00088                       const shortfract leftIn[], 
00089                       const shortfract rightIn[], 
00090                       shortfract leftOut[], 
00091                       shortfract rightOut[],
00092                       int count
00093                      )
00094     {    
00095         shortfract freq, span;
00096         static shortfract shifted;
00097         
00098         freq = ad7998::getValue(ad7998::Vin1);
00099         span = ad7998::getValue(ad7998::Vin2);
00100         
00101         lfo->setFreq( ( freq.v >> 5 ) * mHz ); // 周波数範囲は0 .. 1023 mHz 
00102         lfo->run( lfotemp, count );
00103       
00104         
00105         for ( int i=0; i<count; i++ ){      // 引数配列のすべてのデータを処理する。
00106                 // 左チャンネルしか処理していない
00107             shortfract input = leftIn[i]*(shortfract)0.5 + shifted * (shortfract)0.5;       // 入力データをあらかじめシフタ出力と混合する。
00108             shifter->run( &input, &shifted, 1, ((lfotemp[i]*(shortfract)0.5r+(shortfract)0.5r) * span ).v>>7  );    // シフト量は最大511
00109             leftOut[i] = rightOut[i] = shifted;
00110         }
00111 
00112     }   // processData
00113 
00114 };  // namespace afw
00115 
00116 

Flangerに対してWed Jul 25 11:10:16 2007に生成されました。  doxygen 1.5.2