手始めに1KHzの正弦波を生成してみましょう。簡単に実験できるようにMCMを使います。周波数は決めうちですから表引きで波形を生成できます。48Ksample/secのとき、1KHzは48サンプルが1周期になります。したがってコンストラクタで長さ48の配列に1周期分の正弦波波形を格納します。
#include "mcm2191.h" //************************************************************************** // // C1KHz 型クラスの導出 // // CWave型はEZ-KIT 2191用クラス fwEzKit2191 から派生させる。fwEzKit2191は // EZ-KIT 用のAD1815制御フレームワーク。handleBuffer内で送受信バッファ // 操作を行う // //************************************************************************** class C1KHz: public mcm::fwEzKit2191 { private: int wave[48]; public: C1KHz(); virtual void handleBuffer( struct mcm::sample * bufTx, struct mcm::sample * bufRx ); };
handleBuffer()メソッドではこのテーブルを出力バッファにコピーしています。ためしにここでコピーの代わりにsin()関数を実行したところ、実行時間が全体の65%も増えました。クロック周波数16MHzで48Ksample/secですから、1サンプルあたりのクロック数は3000ほどあるはずです。ということは、sin( 2.0 * 3.141592 * i / 48 ) に2000サイクルほどかけていることになり、かなりsin()関数の性能は悪いといえます。
なお、以下のコードはfwEzKit2191のbufSize変数のデフォルト値が48であることを利用しています。本来よくない書き方ですが試験コードなのでその辺は端折っています。
#include "wave.h" #include <math.h> //************************************************************************** // // C1KHz::C1KHzの定義 // // コンストラクタは正弦波テーブルを初期化する。48サンプルで // 1周期なので48Ksample/sのときに1KHzになる。 // //************************************************************************** C1KHz::C1KHz() { for ( int i=0; i<48; i++ ) wave[i] = 32767 * sin( 2.0 * 3.141592 * i / 48 ); } //************************************************************************** // // C1KHz::handleBufferの定義 // // handleBufferメンバー関数はDMA転送が終わるたびに受信バッファと送信 // バッファをパラメータに呼ばれる。受信バッファには直前のDMAで受信した // データが入っている。handleBufferから戻るときに送信バッファにデータを // おいておくと、次のDMA転送で送信される。 // //************************************************************************** void C1KHz::handleBuffer( struct mcm::sample * bufTx, struct mcm::sample * bufRx ) { for ( int i=0; i< this->bufSize; i++ ){ // bufSizeは送受信バッファの長さ bufTx[i].l = bufTx[i].r = wave[i]; // 正弦波をおく } }
次は⇒任意周波数の生成:DDS