包絡線復調器

ダイオードによる包絡線検波のプログラムを組んでみます。

プログラム

MCMを使っていったん12KHzのAM信号を作り、それの絶対値を求める(実際には0と比較して大きいほうを取り出し)ことでダイオード検波を行います。最後の平滑化はLPFを使います。伝送する音声の帯域は3KHzです。図1にブロックダイアグラムを示します。ダイオード検波の部分はstk::max()関数を使いました。信号と0の間で比較を行い、大きなほうを選ぶことで負の値をきります。

AM変調と包絡線復調

図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ともなるとかなりこもった音になります。それでも「天使の歌声」オリビア・ニュートンジョンがちゃんと聞けるあたりはご立派。

次は⇒プロダクト検波

2191空挺団 | プログラム | EZ-KIT | こぼれ話 | アーキテクチャー | 命令 | レジスタ | DSP掲示板 | FAQ |