SSB変復調

ADSP-2191に実装したSSB複素変復調を、Blackfinにも実装してみました。実行環境はTOPPERS/JSPで、AD1836A用のTalkthroughをもとに信号処理系のみ使っています。なお、STKも使用しています。

処理の方式は2191版とまったく同じで、PSNを複素フィルタで実装したものです。キャリア周波数は12KHzで、サンプル周波数はオーディオと同じ48KHzです。

必要MIPSはADSP-BF533 Rev 0.2用のビルドで73MIPS、Rev 0.4用のビルドで48MIPSです( VisualDSP++ 4.0 September Update )。

ダウロード(616KB) : ssb_complex.zip

#include "t_services.h"
#include "kernel_id.h"
#include "complex_ssb.h"
#include "ad1836a.h"
#include "stk.h"

#define TAPS 256

static short sound[SAMPLE_PER_INTR], signal[SAMPLE_PER_INTR], sp[SAMPLE_PER_INTR];
static short temp_r[SAMPLE_PER_INTR], temp_i[SAMPLE_PER_INTR];
static short temp2_r[SAMPLE_PER_INTR], temp2_i[SAMPLE_PER_INTR];
static short lo_r[SAMPLE_PER_INTR], lo_i[SAMPLE_PER_INTR];


static short re_coeff[TAPS]={
        #include "relpf.txt"
};
static short im_coeff[TAPS]={
        #include "imlpf.txt"
};
static struct CODEC_BUFFER tx_buf;


void modem_task(VP_INT extinf)
{
    struct CODEC_BUFFER * rx_buf;
        
                // 変調器の複素フィルタ
    stk::CFilter * mod_re_fir = new stk::CFirFilter( re_coeff, TAPS );
    stk::CFilter * mod_im_fir = new stk::CFirFilter( im_coeff, TAPS );
                // 復調器の複素フィルタ
    stk::CFilter * demod_re_fir = new stk::CFirFilter( re_coeff, TAPS );
    stk::CFilter * demod_im_fir = new stk::CFirFilter( im_coeff, TAPS );
                // 12KHzの局発
    stk::CDDS * lo = new stk::CDDS( 0x40000000 ); // 48KHz/4 = 12KHz
                // 11KHzの妨害波
    stk::CDDS * spurious = new stk::CDDS( 984263339 ); // 2^32 / 48 * 11 = 11 KHz
                

    act_tsk( CODEC_TASK );
    while( 1 )
    {
        int sample, slot;
                
        rcv_dtq( CODEC_RX_DTQ, (VP_INT*)& rx_buf );

                // 入力データからLとRを取り出して加算する。
                // SLOT 0 : Internal L
                // SLOT 4 : Internal R
                // 24 bit データを加算後, 16bitに
                // 丸めるために9bitシフトする
        for ( sample = 0; sample < SAMPLE_PER_INTR; sample++ )
            sound[sample] = ( rx_buf->data[sample][0] + rx_buf->data[sample][4] ) >> 17;
                // sound にはモノラルデータが入っている。               


                // ---------- USB 変調 -------------
                // 複素フィルタを適用
        mod_re_fir->run( temp_r, sound, SAMPLE_PER_INTR );
        mod_im_fir->run( temp_i, sound, SAMPLE_PER_INTR );

                // 複素局発(解析信号)を生成
        lo->run( lo_r, lo_i, SAMPLE_PER_INTR );
                
                // +12KHzのアップコンバート
        stk::mul( temp_r, temp_r, lo_r, SAMPLE_PER_INTR );
        stk::mul( temp_i, temp_i, lo_i, SAMPLE_PER_INTR );
        stk::sub( signal, temp_r, temp_i, SAMPLE_PER_INTR );    
        
                // 複素局発(+12KHz 解析信号)を生成
        lo->run( lo_r, lo_i, SAMPLE_PER_INTR );
                // ---------- 妨害波 -------------
                // 妨害信号(11KHz cos波)を生成
        spurious->run( sp, SAMPLE_PER_INTR );
        stk::mul( sp, sp, 0x4000, SAMPLE_PER_INTR ); // 0.5倍
                        
                // 妨害信号の混入
        stk::add( signal, signal, sp, SAMPLE_PER_INTR );
                
                // ---------- USB 復調 -------------
                // -12KHzでダウンコンバート
        stk::mul( temp_r, lo_i, signal, SAMPLE_PER_INTR );    // -12Khzにするために
        stk::mul( temp_i, lo_r, signal, SAMPLE_PER_INTR );    // sin/cosを入れ替える
 
        demod_re_fir->run( temp2_r, temp_r, SAMPLE_PER_INTR ); // 実部
        demod_im_fir->run( temp2_i, temp_i, SAMPLE_PER_INTR ); // 虚部
 
        stk::sub( sound, temp2_r, temp2_i, SAMPLE_PER_INTR );    // USB復調
//      stk::add( sound, temp2_r, temp2_i, SAMPLE_PER_INTR );    // LSB復調

        for ( sample = 0; sample < SAMPLE_PER_INTR; sample++ )
        {
            tx_buf.data[sample][0] = sound[sample] << 16;//rx_buf->data[sample][0];
            tx_buf.data[sample][4] = sound[sample] << 16;//rx_buf->data[sample][4];
        }
              // ---------- 出力バッファにコピー -------------
        snd_dtq( CODEC_TX_DTQ, (VP_INT) & tx_buf ); 
    }
}
Blackfin空挺団 | プログラム | EZ-KIT | コア&ペリフェラル | TOPPERS/JSP | こぼれ話 | DSP掲示板