非職業的技師の覚え書き

JK1EJPの技術的検討事項を中心に記録を残します。

Teensy(16)Keiths' SDRのTx信号処理連鎖

Keiths' SDR(K7MDL局Mike OM版)の信号処理連鎖を学び中です。Rx信号処理連鎖の解読には一区切り付きました。Rx信号処理連鎖にもまだ不明確な点(サンプリング周波数とHilbertフィルタの帯域など)がありますが、Tx信号処理連鎖の解読に着手しました。

信号処理連鎖

ソースコードから読み取ったRx信号処理連鎖(青色の有向エッジ)とTx信号処理連鎖(赤色の有向エッジ)を下記に示します。前回までに詳説したRx信号処理連鎖は簡略化して示しています。前回調べたTwinPeakオブジェクトも省略しています。

Transmit signal processing chain (red edges).

赤色の有向エッジが今回調べたTx信号処理連鎖の経路です。黒色の有向エッジはRx/Tx共用の有向エッジです。

コーデック

ダイレクトコンバージョン方式のSDRでは、オーディオコーデック(ADC、DAC)が物理世界とのインターフェースになります。Keiths' SDRでは、NXP社のSGTL5000チップを搭載したPJRA社のAudio Adaptor Boardを採用しています。

最初に、RxとTxで切り変わるコーデックの入出力を整理しておきましょう。

Switching of audio codec input/output with switching between transmit and receive modes.

Rxモードでは、青字で示すように、ステレオLine入力からI/Q信号を入力して、Rx信号処理を適用し、ヘッドフォンに出力します。

Txモードでは、赤字で示すように、Mic入力からモノラル音声信号を入力して、Tx信号処理を適用し、ステレオLine出力からI/Q信号を出力します。

コーデックへの入力元およびコーデックからの出力先の切換えは、PTT信号をトリガーとしたRx/Txのモード切換え時に、codec1オブジェクトに入力/出力対象の指定メソッドを出すことで行います。

Rx信号処理連鎖の経路

Rx信号処理連鎖の調査で詳しくは言及しなかった2種類のスイッチオブジェクトが、Rx/Txモード切換え時に重要な役割を果たします。その観点から、Rx信号処理連鎖の経路を復習します。

Path of the Rx signal processing chain.

(1)Inputオブジェクト

Line入力のI/Q信号をコーデックがディジタルデータに変換し、InputオブジェクトにI2Sバス経由でDMA転送します。Inputオブジェクトは2つの出力ポート(0番、1番)を持ち、出力ポート0番からLチャネルのデータを受信Iデータとして出力し、出力ポート1番からRチャネルのデータを受信Qデータとして出力します。

(2)I_Switch/Q_Switchオブジェクト

Inputオブジェクトの出力であるI/Qデータを2つのスイッチオブジェクト(I_SwitchおよびQ_Switch)の入力ポート0番にそれぞれ入力します。I_SwitchおよびQ_Switchは、Mixerクラス(正式名はAudioMixer4_F32クラス)のオブジェクトです。Mixerクラスは本来、データストリームに対するゲイン係数を持つ加算器です。ゲイン係数を0/1で切換えることにより、何番の入力ポートのデータを出力するかを選択可能な入力ポート切換スイッチとして働きます。ここで使用しているMixerクラスは4つの入力ポート(0番~3番)を持ち、Rxモードではそれぞれ入力ポート0番の受信I/Qデータを選択して出力します。

(3)RxTx_InputSwitch_L/RxTx_InputSwitch_Rオブジェクト

I_Switch/Q_Switchオブジェクトの出力を後段の2つのスイッチオブジェクト(RxTx_InputSwitch_LおよびRxTx_InputSwitch_R)に入力します。RxTx_InputSwitch_LおよびRxTx_InputSwitch_Rは、Switchクラス(正式名はAudioSwitch4_OA_F32クラス)のオブジェクトです。Mixerクラスとは逆に、Switchクラスは入力データを何番の出力ポートから出力するかを選択可能な出力ポート切換スイッチとして働きます。ここで使用しているSwitchクラスは4つの出力ポート(0番~3番)を持ち、Rxモードではそれぞれ0番の出力ポートを選択して受信I/Qデータを出力します。

(4)Rx信号処理ブロック

RxTx_InputSwitch_L/RxTx_InputSwitch_Rオブジェクトの出力をRx信号処理ブロックに入力します。Rx信号処理ブロックの内容は前回までに調査し報告しました。Rx信号処理ブロックは、受信I/Qデータにディジタル信号処理を適用して復調した受信オーディオデータを出力します。

(5)OutputSwitch_I/OutputSwitch_Qオブジェクト

Rx信号処理ブロックの出力を2つのスイッチオブジェクト(OutputSwitch_IおよびOutputSwitch_Q)に入力します。OutputSwitch_IおよびOutputSwitch_Qは、再びMixerクラス(正式名はAudioMixer4_F32クラス)のオブジェクトです。ここで使用しているMixerクラスも4つの入力ポート(0番~3番)を持ち、Rxモードではそれぞれ0番の入力ポートの受信オーディオデータを出力します。

(6)Amp1_L/Amp1_Rオブジェクト

OutputSwitch_I/OutputSwitch_Qオブジェクトの出力をオーディオ増幅器オブジェクト(Amp1_LおよびAmp1_R)に入力します。Amp1_LおよびAmp1_Rは、AudioEffectGain _F32クラスのオブジェクトです。オーディオ増幅ゲインの操作を行い、受信オーディオデータを出力します。モノラル信号ですが、左右の音量は独立に調整可能です。

(7)Outputオブジェクト

Amp1_L/Amp1_Rオブジェクトの出力をOutputオブジェクトに入力します。Outputオブジェクトは2つの入力ポート(0番、1番)を持ち、入力ポート0番にLチャネルのデータを入力し、入力ポート1番にRチャネルのデータを入力します。受信オーディオデータをOutputオブジェクトからコーデックにI2Sバス経由でDMA転送し、コーデックがアナログデータに変換し、Headphoneに出力します。

Tx信号処理連鎖の経路

受信ではスイッチオブジェクトの0番のポートを選択して、Rx信号処理連鎖の経路を実現していました。送信ではスイッチオブジェクトの1番のポートを選択して、Tx信号処理連鎖の経路を実現します。

Path of the Tx signal processing chain.

(0)codec1オブジェクト

codec1オブジェクトによるADCの対象入力信号を受信と送信で交互に切り換えます。受信時は、QSD(直交検波器)からのI/Q信号が入力されるLine-INがADCの対象に選択されています。送信時は、音声信号が入力されるMicをADCの対象にするように、codec1オブジェクトに入力切換の指示を出します。

(1)Inputオブジェクト

Mic入力のモノラル音声信号をコーデックがディジタルデータに変換し、InputオブジェクトにI2Sバス経由でDMA転送します。Inputオブジェクトは2つの出力ポート(0番、1番)を持ちますが、モノラル信号のため両者は同じデータになります。Tx信号処理経路では、出力ポート0番を利用しています。

(2)TX_Sourceオブジェクト

TX_Sourceは、Mixerクラス(正式名はAudioMixer4_F32クラス)のオブジェクトであり、送信用入力ソースを切り換えるスイッチの役割を果たします。

TX_Sourceは4つの入力ポートを持ち、Inputオブジェクトからの音声データ出力は入力ポート0番にプログラム上で結線されています。音声データ以外に、USB_Inオブジェクトからのデータが1番に、TxTestTone_Aオブジェクトからのトーン信号データが2番に、TxTestTone_Bオブジェクトからのトーン信号データが3番に、それぞれプログラム上で結線されています。

2つのトーンジェネレータは、2トーンテストのために準備されているものと思われます。2つのトーンジェネレータでクラスが異なり、AudioSynthSineCosine_F32とAudioSynthWaveformSine_F32に分かれますが、使い分けている理由は不明です。最初に存在した後者に対して、スペクトル純度を上げるために前者を作成し、その成果に基づき後者も更新している経緯が読み取れます。集合知で発展してきたソースコードの歴史的経緯の痕跡として、2つが残っているのかもしれません。

1番ポートに入力されるUSBデータはFT8等のデータ通信用ですが、CWのトーン信号の入力ソースとしても計画されているようです。CWの送信系は、クリック防止のためのエンベロープ制御も含めて、まだ完成を見ていないようです。QSE(直交変調器)とは別系統でCW送信系を準備するとなるとRFフロントエンドの改造が発生してしまうため、CWのトーン信号をTX_Sourceに入力してVFOをその分オフセットさせる変調CW方式に落ち着きそうです。FT8のGaussian filterに例があるように、CWのエンベロープ制御もソフトウェアによって処理され得ると思います。

(3)bpf1オブジェクト

音声信号に対するBPFです。このオブジェクトだけ命名規則(小文字のみ使用)が他と異なるため、実験的に挿入されている可能性があります。

BPFの機能は後段のHilbertフィルタと重複しますが、Rx信号処理連鎖と同様に、位相シフトとBPFの機能を分割したのではないかと思われます。機能分割しておけば、将来イコライザに進化させることも可能と思われます。

bpf1は、AudioFilterFIR_F32クラスのオブジェクトであることから、FIRフィルタであることが分かります。fir1係数配列を引数として初期化をしています。fir1係数配列の定義ファイルに下記のフィルタ仕様に関するコメントがありました。

FIR filter designed with http://t-filter.appspot.com
sampling frequency: 48000 Hz

// 0 Hz - 400 Hz   attenuation = -91.3 dB
// 900 Hz - 3200 Hz  ripple = 3.5 dB
// 4000 Hz - 22050 Hz  attenuation = -91.3 dB

サンプリング周波数が98kHzなのか48kHzなのか判然としていませんでしたが、コメントから推察するとbpf1は48kHzで設計されています。やはり、ソースコード上のサンプリング周波数98kHzはコーディック1チャンネル分の仕様であって、2チャンネル分では48kHzになるのではないかと推定されます。

bpf1のフィルタ特性を係数から調べた結果を下記に示します。400Hz~4,000HzのBPFになっていますが、attenuation = -91.3 dB を達成しているバンド幅はもう少しブロードになります。後段のHilbertフィルタのBPF特性よりも、DCを含めた低周波帯域と高周波帯域の減衰に優れているようですが、それを狙って追加したのかどうかは不明です。

Bandpass characteristics of the FIR filter examined from the coefficients of bpf1.

(4)Hilbertオブジェクト

Rx信号処理連鎖と同様に、±45度の位相シフトを行う二つのHilbertフィルタが準備されています。2.8kHzの通過域を名前に持つHilbert_Plus45_28K係数配列およびHilbert_Minus45_28K係数配列を引数として、それぞれのオブジェクトの初期化をしています。Rx信号処理連鎖で調べたフィルタ特性を下記に再録します。

Hilbert FIR filter with a cutoff frequency of 2.8 kHz.

以上の(2)から(4)までのブロックが、Tx専用の信号処理連鎖になります。

(5)(6)(7)スイッチオブジェクト

Hilbertオブジェクトの出力は、(5)I_SwitchおよびQ_Switchオブジェクトの入力ポート1番にプログラム上で結線されています。送信時には入力ポートを0番から1番に切り換えます。

同時に、(6)RxTx_InputSwitch_L/RxTx_InputSwitch_Rオブジェクトの出力を0番から1番に切り換え、Rx信号処理ブロックをバイパスして、(7)OutputSwitch_IおよびOutputSwitch_Qオブジェクトの入力ポート1番に直結します。

(8)(9)QSEへの出力オブジェクト

(7)OutputSwitch_IおよびOutputSwitch_Qオブジェクトの出力は、Rx信号処理連鎖と同じく、オーディオ増幅器オブジェクト(8)Amp1_LおよびAmp1_Rにプログラム上で結線されています。IQバランス等の用途でゲインは調整可能ですが、初期値1.0のまま使われているようです。

送信IQデータを(8)OutputオブジェクトからコーデックにI2Sバス経由でDMA転送します。送信時には、コーデックの出力先をHeadphoneからLine-OUTに切り換えておきます。コーデックが送信IQデータをアナログデータに変換し、Line-OUTからQSEに出力します。

以上が主にSSBを対象にしたTx信号処理連鎖になります。Rx信号処理連鎖よりも簡易な連鎖になっています。FT8等のデータ通信や、PCからKeyingする変調CWを深掘りするためには、USB_In/Outオブジェクトをさらに調べる必要がありそうです。