- メインページ
- ネームスペース
- クラス
- ファイル

- ファイル一覧
- ファイルメンバ

# 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