ダイオードによる包絡線検波のプログラムを組んでみます。
MCMを使っていったん12KHzのAM信号を作り、それの絶対値を求める(実際には0と比較して大きいほうを取り出し)ことでダイオード検波を行います。最後の平滑化はLPFを使います。伝送する音声の帯域は3KHzです。図1にブロックダイアグラムを示します。ダイオード検波の部分はstk::max()関数を使いました。信号と0の間で比較を行い、大きなほうを選ぶことで負の値をきります。
図1 AM変調と包絡線復調
復調結果にはDC成分がのっていますが、そのままにしています。
#include "modem.h" #include <stdlib.h> #include <def2191.h> // ファイルの先頭に置く #include <sysreg.h> short tlpfCoeff[127]={ #include "tlpf.txt" }; short rlpfCoeff[31]={ #include "rlpf.txt" }; //************************************************************************** // // CModem::CModemの定義 // // //************************************************************************** CModem::CModem():mcm::fwEzKit2191() { osc = new stk::CSinCosDDS(16384,0); // 12KHz rlpf = new stk::CFirFilter(31, rlpfCoeff ); tlpf = new stk::CFirFilter(127, tlpfCoeff ); temp = new short[bufSize]; carrier = new short[bufSize]; } //************************************************************************** // // CModem::~CModemの定義 // // //************************************************************************** CModem::~CModem() { delete osc; delete tlpf; delete rlpf; delete[] temp; delete[] carrier; } //************************************************************************** // // CModem::handleBufferの定義 // // handleBufferメソッドはDMA転送が終わるたびに受信バッファと送信 // バッファをパラメータに呼ばれる。受信バッファには直前のDMAで受信した // データが入っている。handleBufferから戻るときに送信バッファにデータを // おいておくと、次のDMA転送で送信される。 // //************************************************************************** void CModem::handleBuffer( struct mcm::sample * bufTx, struct mcm::sample * bufRx ) { stk::copy( temp, &bufRx[0].r, bufSize, 1, sizeof( mcm::sample ) ); tlpf->run( temp, temp, bufSize ); stk::mul( temp, temp, (int)(0.5*32767), bufSize ); // 飽和回避のためのスケーリング stk::add( temp, temp, (int)(0.5*32767), bufSize ); // DCオフセットを付加 osc->run( carrier, bufSize ); // 搬送波生成 stk::mul( temp, temp, carrier, bufSize ); // 振幅変調 stk::max( temp, temp, (short)0, (short)bufSize ); // ダイオード検波 rlpf->run( temp, temp, bufSize ); // 可聴領域だけ取り出す stk::copy( &bufTx[0].r, temp, bufSize, sizeof( mcm::sample ) ); stk::copy( &bufTx[0].l, temp, bufSize, sizeof( mcm::sample ) ); }
3KHzともなるとかなりこもった音になります。それでも「天使の歌声」オリビア・ニュートンジョンがちゃんと聞けるあたりはご立派。
次は⇒プロダクト検波