MMTTYのデジタル信号処理 初版 2000.07.18 JE3HHT 森 誠 改定 2000.10.19 JE3HHT 森 誠  MMTTYで使っている各信号処理について簡単に解説します。 ◎FIRフィルタ ~~~~~~~~~~~~~ FIR(Finite Impulse Response)フィルタはデジタル信号処理の最も基本となるフィルタで、一定間隔でサンプリングされた過去のデータと、ある計算から得られた係数をそれぞれ掛け合わせ、すべての総和を得る事により実現できます。 In --> Z-1 --> Z-1 --> Z-1 --- ・・・・ Z-1 -- | | | | H0 H1 H2 ・・・・ Hn | | | | ------> + ----> + ---------------------> + ----> Out 「Z-1」は遅延器を表し、これが連続してトコロテンのように並んでいます。「H0」〜「Hn」はそれぞれの掛け合わせる係数を表します。  このような計算をたたみ込み演算(MAC演算)と呼びます。  例えば過去10点のサンプリングデータに、すべて同じ係数0.1を掛け合わせそれを合計すれば、それは10点における平均値を求めていることになり、結果としてスムージングされたLPFとして働くことになります。  この係数H0〜Hnのそれぞれに、ある特性から割り出される値(希望する周波数特性のインパルス応答)を与えると、任意のフィルタとして働かせる事ができます。  FIRフィルタはその名前の通りインパルス応答が有限時間で終了しますので発振に悩まされる心配がありません。また係数を対象性にする(H0=Hn, H1=Hn-1,・・・)ことにより、直線位相特性になり、それがこのフィルタの最大の特長でもあります。一方鋭い特性を得ようとすると次数を大きくする必要があり、応答が遅延するという欠点を持ち合わせています。  デジタル信号処理のフィルタと言えば、まずこのFIRフィルタの事を指すと思っても間違いないぐらいに良く使われています。 ◎IIRフィルタ ~~~~~~~~~~~~~  IIR(Infinite Impulse Response)フィルタは以下に示すように帰還回路があり、その名前の通りインパルス応答が無限に続きます。その動作はアナログ回路のLCフィルタやアクティブフィルタなどと同じですので、こちらのほうがOMさんには馴染みやすいかも知れません。 In -----+---------------> b0 --+------ Out | | | + <- a1 <- Z-1 -> b1 ->+ | | | + <- a2 <- Z-2 -> b2 ->+  IIRフィルタの設計は、まず希望する周波数特性のアナログフィルタを設計し、それをデジタルフィルタの係数に変換する方法が良く取られます。この方法ではアナログフィルタと同様、バターワース特性やチェビシフ特性を持たせることができます。  IIRフィルタの最大の特長は少ない次数で鋭い特性のフィルタを作成できる点です。また応答遅れが少ない(最小位相)システムを構成することができます。  一方位相特性は平坦ではなく、アナログフィルタと同様の群遅延歪みがあり、また係数量子化誤差(計算機の語長制限による丸め誤差)や演算誤差(乗算の際の語長制限による丸め誤差)の影響を受けやすいという欠点を持ち合わせていますので、固定小数点演算のデジタル信号処理では、IIRフィルタはあまり使われません。 ◎IIR型共振器 ~~~~~~~~~~~~~  IIRフィルタの一種として下記のような共振器を構成できます。MMTTYの周波数弁別器の1つはこれを使用しています。 In --- b --+---------------------- Out | | + <- a1 <- Z-1 | | + <- a2 <- Z-2  それぞれの係数は、 a1 = 2exp(-πBT)・cos(2πFT) a2 = -exp(-2πBT) b = A・sin(2πFT) F:共振周波数(Hz) B:周波数帯域幅(Hz) T:サンプリング間隔(s) = 1/fs A:ゲイン で簡単に求めることができ、IIRフィルタを設計する場合のようなややこしい計算も不要です。 Bを0にすると共振回路のQが無限大になり、完全無損失になりますので、Z-1に初期値を与えておけば、そのまま発振器として使うこともできます。 ◎検波器 ~~~~~~~~  ハードウエアではダイオードを使いますが、デジタル信号処理の場合はマイナスの値だけを0にするか、そのままプラスにする(絶対値を得る)だけでOKです。 ◎積分器 ~~~~~~~~  いろいろな方法で実現できると思いますが、MMTTYの場合は過去の信号を一定期間について平均するFIRフィルタ、またはバターワース特性(N*6dB/Oct)を持つIIRフィルタのいずれかを選択できます。  いずれの方式を選択しても劇的には変化しないようですが、受信する信号の質によっては微妙に異なるようです。  設定するスムージング周波数は、FIRフィルタの場合は平均する周期期間の逆数で与え、IIRフィルタの場合はそのカットオフ周波数で与えますが、FIRフィルタで設定するスムージング周波数よりは、IIRフィルタのカットオフ周波数は低く設定する必要があります(積分器の場合のFIRフィルタに与えるスムージング周波数はそのLPF特性のカットオフ周波数ではなく単に平均周期の逆数であることに留意して下さい)。  デフォルトではFIRフィルタになっていますが、IIRフィルタのほうが遥かに処理が軽いですので、こちらのほうを選択されるほうがFBかも知れません。低次の場合のカットオフ周波数は5次の場合は40Hzぐらい、3次の場合は30Hzあたりが良さそうですが、これに関する私の実験のサンプル数は少ないです。 ◎VCO ~~~~~ VCOはRTTY信号の変調器や、PLL方式のデモジュレータで使います。デジタル信号処理でのVCOは下記のような構成になります。 C2 | In --> C1 --+---+-----> sin --> Out | | -- Z-1 <- C1:VCOゲイン C2:フリーランニング周波数を決定する値  このままプログラムするとZ-1はどんどん大きな値になっていきますので、それを0〜2πまでの範囲で循環するようにしておきます(具体的には2πで割って余りを求めるか、または2π以上になった時に2πを引けばOKです)。  また1サンプリング毎に「sin」を計算するのは処理に時間がかかり過ぎますので、あらかじめ「sin」を計算した大きなテーブルを作っておき、それを参照する方法で処理速度を得る事ができます。  デジタル信号処理でのVCOは周波数が安定していますので、そのままFSKの変調器として利用してもまったく問題ありません。 ◎PLL ~~~~~ PLLは下記に示すような構成でこれはアナログ回路とまったく同じです。デジタル信号処理での位相検波器(Phase Det.)は、単に両者の値を掛け合わせるだけで良く、とても簡単に実現できます。 In - Phase Det. -> LoopLPF ---> OutLPF --> Out | | | | +---- VCO <-------+  この位相検波器の出力には両者の周波数の和と差の成分が現れ、欲しいのは差の成分なので、それを取り出すためにIIR型のLPFで作ったループフィルタ(LoopLPF)を通します。しかしこのフィルタはループ内にあるためにPLLの応答特性に大きく影響し、あまり鋭い特性を持たせることができません。通常は1次フィルタが良く使われます(ハードウエアで構成するPLLとまったく同じです)。 したがってこれだけでは阻止域の減衰量が不足し、完全には和の成分を除去できないので、出力部にもう1つLPF(OutLPF)を入れてそれを取り除きます。 RTTYのデモジュレータとして使う場合、ループフィルタのカットオフ周波数はシフト幅よりも大きくしておかなければなりません。  PLL方式のデモジュレータは高速デコードが要求される場合に適していますが、RTTY信号のように、そのボーレートが遅い場合は、周波数弁別器方式の方が向いているように思います。  しかし処理はとても軽くて済みますので、OutLPFの次数を大きくし、その後の積分器をIIR型にすれば、遅いCPUでも動作します。 ◎適応フィルタ ~~~~~~~~~~~~~~ 適応フィルタはデジタル信号処理の花形です。以下に単純化した構成例を示します。 In ------ 遅延器 -->トランスバーサルフィルタ ---> Out | | | - (誤差×2μ)---------> 係数更新(γ) | | | -------------------------------------------  (参照信号)  まずInからの信号を適当な遅延器を通して、トランスバーサルフィルタ(FIRフィルタ)に入力します。次にトランスバーサルフィルタを経た信号を入力信号と減算してその誤差を求め、それを元にフィルタの係数を更新します。  一般に雑音などのランダムな信号の自己相関関数は遅延が大きくなるにつれて急激に減少します。これにより入力点と出力点の雑音成分の相関は非常に小さな値になります。一方目標とする周期的な成分の相関はある程度大きな値になります。この図では係数更新により、入力と出力(参照信号)の二乗誤差が小さくなるように作用しますので、出力点では相関の大きな成分は強調され、逆に相関の小さな成分は抑制されていきます。  最終的には「Out」から信号を取り出せば、周期的な信号を強調したノイズスムーサ的な(スペクトル強調器)動作になり、また誤差信号を出力にすると周期的な信号を取り除いたオートノッチフィルタとして動作します。 MMTTYで設定できるパラメータは以下の通りです。 Tap トランスバーサルフィルタの次数 Delay 相関遅延器の個数 2μ この値を大きくすると応答が速くなります。 γ この値を小さくすると減衰応答が速くなります。 Inv これにチェックを付けると誤差信号を出力します。 AGC 係数の値が小さい時に出力を大きくします。 BPF デフォルトでBPF特性を持たせます。 μを大きくすると応答が早まりますが、収束しにくくなります。 γを小さくすると、入力信号が無くなった時の各係数の下がり具合が早まりますが、あまり小さくしすぎると逆に収束しなくなったり発振したりします。このγの働きを見るには、十分に収束した状態で入力信号を突然切ってみるとよいでしょう。普通は1.0より少しだけ小さな値を設定します。 AGCとBPFは本来のLMSアルゴリズムにはありませんが、RTTY用に実験的に付けてみたものです。AGCは弱い信号の時にもある程度のフィルタゲインを確保するように働き、BPFはデフォルトでBPF特性を軽く持たせるように働きます。 適応フィルタの動作具合はμとγだけではなく、DelayとTapの数も密接に関係しますので、これらすべてを適当に調整して自分好みの適応動作に仕上げて使って下さい。 少しLMSの調整をしてみましたが、弱い信号ではあまり旨く働かない事が多く、動作は面白いですが、実際には役には立たないかも知れません。Hi 皆さんも色々と試して実験してみて下さい。良いパラメータが見つかった時にはぜひ教えてね! ◎デモジュレータの構成 ~~~~~~~~~~~~~~~~~~~~~~  以下にそれぞれの構成図を示します。 [周波数弁別器方式] (Mark) +-> 共振器 -> 検波 -> 積分器 - ATC -+ | | Sound -> リミッタ -+ cmp -> 0 or 1 | (Space) | +-> 共振器 -> 検波 -> 積分器 - ATC -+ [PLL方式] Sound -> リミッタ - Phase Det. > LoopLPF -+-> OutLPF --> 積分器 --> | | | | +---- VCO <------+ 周波数弁別器方式は、IIR型共振器またはFIR型BPFのいずれかを選択することができます。この両者の特性の違いはXY-Scope表示をすると顕著に表れますので面白いと思います。IIR型共振器はLC共振回路に近い特性で、一方FIR型BPFは直線位相特性が保証されます。 いずれの場合もこの2つの共振器(またはBPF)の出力を検波した後、それぞれ平均型(FIR型)またはIIR型LPFで構成した積分器を通し、その出力の大小を比較しています。 Ver1.19までは検波器のあとにAGCを入れていましたが、あまり効果がなかったので、結局オーソドックスなリミッタアンプを前置するように戻しました。またVer1.58からはATCを追加してあります。  PLL方式も教科書通りの構成です。XY-Scopeを表示させるために、IIR型共振器にも信号をパラで入れてありますが、この共振器の出力はデコードには関係しません。 いずれの場合も各パラメータを調整する際、表示メニューの「オシロスコープ」を選択するとオシロスコープ画面を表示しますので、「Trig」ボタンを押して各信号の状態を観測することができます。 このオシロスコープは4現象で、上からマーク周波数信号、スペース周波数信号、コンパレータの出力信号、デコード同期パルス信号の4つを表示します。 マーク周波数信号およびスペース周波数信号は、「信号源」を切り替えることにより観測プローブの位置が以下のように切り替わります。 [周波数弁別器方式の場合] 1.IIR型共振器またはFIR型BPF出力後の波形 2.検波後の波形 3.積分器通過後の波形 [PLL方式の場合] 1.IIR共振器出力後の波形(デコードには関係しません) 2.上がLoopLPFの出力、下がOutLPFの出力 3.積分器通過後の波形 デコード同期パルスは、以下のような色分けがされています。 黄色 スタートビット検出位置 白黄 データ取りこみ位置 青色 ストップビット予想位置 ストップビットが正しく検出された時は、青色パルスは2個連続表示され、正しく検出されなかった時(フレーミングエラー時)は、1個しか表示されません。 この2個目の青色パルスはストップビットの終了予想位置のほんの少し手前に設定してあり、デコーダーはこの位置から次のスタートビットの検出動作に入ります。同期パルスは常にデータの真中付近に位置していなければなりません。 オプションメニューの設定画面のデコードページで、「多数決論理デコード」にチェックを付けている場合、同期パルスはデータの変化点に位置するようになります。この場合スタートビットを表す黄色の同期パルスは検出位置とデータ開始位置に2本表示されます。デコーダーは1ビット期間あたりのマークとスペースのサンプル数を調べ、その数の多いほうをデータとして取りこみます。この場合、RxStopビットを1ビットにしている場合、青色パルスは常に1つしか表示されません。 また設定画面のデコードページで「フレーミングエラーの無視」にチェックを付けている場合、フレーミングエラーは無視され、ストップビットの状態に関わらずデータは取りこまれるようになります。 フレーミングエラーを無視すると、ストップビットだけが落ちた場合も正しく文字として表示されますが、無信号時にも文字が表示される確立は高くなります。 オプションメニューの設定画面のデコードページで、ボーレート,ビット長,ストップビット,パリティ等のデコードパラメータも変更できますが、アマチュアのRTTYの場合はデフォルト(BaudRate=45.45, BitLength=5, RxStop=1 or 1.42, Parity=NONE)から変更しないで下さい。 *RxStop=1 または 1.42を選択しても、送信する符号のストップビットは1.5bitです。 ◎オーバーサンプリング ~~~~~~~~~~~~~~~~~~~~~~  サンプリング周波数を内部で変更するオーバーサンプリング(マルチレートシステム)という技術が、処理速度を稼ぐためにデジタル信号処理ではごく常識的に使われています。MMTTYのデモジュレータ部もオーバーサンプリングされています。以下にオーバーサンプリングシステムの構成図を示します。 A/D --> LPF --> ↓M --> アプリケーション --> ↑L --> LPF --> D/A サンプリング周波数を下げる部分をデジメータ(↓M)と呼び、例えば1/2にする場合には、サンプリングデータを2回に1回と間引けば良いわけですから話は簡単です。  ただこのままだと入力部の物理的なサンプリング周波数を下げるのとまったく同じことになり、低い周波数で折り返し歪みが発生してしまいますので、この部分の前にデジタルフィルタによるLPFを入れておきます。  サンプリング周波数を上げる部分はインターポーレータ(↑L)と呼び、例えば2倍にする場合には、1サンプリングの途中の点を作らなければならないので、少し難しそうに思えますが、これはとりあえずその途中の点をエイヤッと0にしてしまい、サンプリング周波数を無理やり上げておいてから、そのあとデジタルフィルタによるLPFでスムージングして補完します。  2倍のオーバーサンプリングを行うことにより、例えばFIR型フィルタではその次数が半分で同じ特性のフィルタを得る事ができるようになります。また1サンプリング期間が2倍になりますので、処理にも余裕が生まれます。  ただしアプリケーション部でのナイキスト周波数(処理可能な周波数=サンプリング周波数の1/2)は半分になりますので、この倍率にはおのずと限界があることになります。 ○リミッターの処理周波数 ~~~~~~~~~~~~~~~~~~~~~~~~ デフォルトではリミッターはサンプリング周波数11025Hzで動作しており、この部分で位相歪みが発生します。これはデコード動作には大きく影響しないようですが、XYScopeの表示に歪みとなって現れます。 オプションメニューの設定画面でリミッターの「Over Sampling」のチェックを付けると、MMTTYは以下のようにリミッターだけを4倍のサンプリング周波数(44100Hz)で動作させこの歪みを緩和させます。 Sound --> ↑L(4) -> LPF --> Limiter --> LPF -> ↓M(1/4) --> LimitOut 11025Hz 44100Hz 11025Hz CPUパワーに余裕がある場合は、「Over Sampling」のチェックを入れておいたほうがXYScopeの表示が少し綺麗になると思います。 またこれとは別に表示メニューのXYScopeの処理品質を高くすると、MMTTYは以下のようにXYScopeに与える信号のサンプリング周波数だけを高くします。 Mark ---> ↑L(N) -> LPF --> X Space ---> ↑L(N) -> LPF --> Y この処理はリミッタでの位相歪みに対しては効果はありませんが、表示分解能が高まりXYScopeが見やすくなります。 ◎FFT ~~~~~ FFTは参考文献も多く、ここでは詳しく触れませんが、時間領域の信号を周波数領域(またはその逆)に変換するのに使われ、MMTTYでは周波数スペクトル表示およびWaterFall表示の際に使っています。  普通の素直なDFT(離散的フーリエ変換)では、例えばN点の解析を行う場合にN×N回の計算が必要ですが、FFTの場合はNを2のべき乗に選ぶことによりN×log2(N)回に減らすことができます。  以下の書籍にサンプルプログラムが載っています。他にも判り易く解説された書籍が多くありますのでそれらを参照されると良いでしょう。 Basicの例  三谷 政昭「デジタルフィルタデザイン」(株)昭晃堂 平成6年4月 Pascalの例  三上 直樹「デジタル信号処理プログラミング入門」CQ出版(株)1993  なお、MMTTYのFIRフィルタの周波数特性表示はFFTではなくDFTなので、処理がとても重いです。Hi ◎サウンドカードのベースサンプリング周波数 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ MMTTYはサウンドカードに対してデフォルトでサンプリング周波数11025Hzを指定します。これは全てのサウンドカードが標準でサポートする最も安全な周波数です。  しかしあなたのサウンドカードが対応するならば、MMTTYのClock値を変更して、6000Hz,8000Hzまたは12000Hzベースのサンプリング周波数でサウンドカードを動作させることもできます。  Clockベース値とClock範囲、各動作周波数は以下のようになります。 ベース値 6000 8000 11025 12000 ----------Clock範囲---------------------------------- Clock下限 5000 7000 10000 11600 Clock上限 6999 9999 11599 12500 ----------Demodulator-------------------------------- オーバーサンプリング なし なし 1/2 1/2 ナイキスト周波数 3000 4000 2756 3000 ----------Modulator---------------------------------- ナイキスト周波数 3000 4000 5513 6000 ----------FFT---------------------------------------- FFT点数 1024 1024 2048 2048 ナイキスト周波数 3000 4000 5513 6000 収集時間[ms] 171 128 186 171 ----------XY Scope----------------------------------- データ点数 512 512 512 512 ナイキスト周波数 3000 4000 2756 3000 収集時間[ms] 85 128 93 85 *ナイキスト周波数=論理サンプリング周波数の1/2の周波数(デジタル信号処理で元の信号に復元可能な論理限界周波数)  例えば6000Hzベースを選択する場合、オプションメニューの設定画面「その他」ページで、サウンドカードClock値に6000を選択した後、一旦MMTTYを終了して再起動して下さい。以後MMTTYは6000Hzでサウンドカードを動作させます。 既にあたなが11025ベースでクロック補正を行っている場合、次のようにClockに設定する正確な値を計算で求めることもできます(端数は四捨五入して下さい)。 Clock = 従来の補正Clock値 x 希望するベース値 / 11025  サウンドカードのベース周波数を下げるとCPUへの負荷は著しく軽減されます。特に6000Hzを選択した場合その効果は顕著です。 ただしデフォルトのパラメータは11025Hzで調整されているため、あなた自身で動作パラメータを若干調整しなければならない場合があります。 6000Hzベースの場合 ~~~~~~~~~~~~~~~~~~  ほとんどのパラメータは変更しなくてもそのまま使用できます。サウンドカードのバッファサイズはデフォルトよりも減少させた方が操作性は改善します。  前置フィルタとTxBPFの特性は11025Hzベースと比較して鋭くなりますので、お好みの状態に調整して下さい。Tap数を半分にするとデフォルトとほぼ同じ特性を得ることができます。特にTxBPFはそのままでは狭過ぎますのでTap数を減少させたほうが良いかも知れません。 8000Hzベースの場合 ~~~~~~~~~~~~~~~~~~  この周波数はほとんどのサウンドカードで使用可能のようですが、デモジュレータの処理周波数が高くなり過ぎるため、6000Hzベースと比較してCPU負荷に対するメリットはあまり大きくありません。 周波数弁別器にFIR型BPFを選択する場合、Tap数を約1.4倍(96次ぐらい)に増加させる必要があるかも知れません。しかしIIR型共振器の特性はほとんど変化せずそのままのパラメータで使用できます。  この場合もサウンドカードのバッファサイズはデフォルトよりも減少させたほうが操作性は改善します。  前置フィルタとTxBPFの特性は11025Hzベースと比較して鋭くなりますので、お好みの状態に調整して下さい。Tap数を約0.7倍に減少させるとデフォルトとほぼ同じ特性を得ることができます。特にTxBPFはそのままでは少し狭過ぎますのでTap数を減少させたほうが良いかも知れません。 12000Hzベースの場合 ~~~~~~~~~~~~~~~~~~~  すべてのパラメータを変更せずにほぼ同等の特性が得られます。この場合11025Hzと比較してCPUの負荷は若干上昇します。  以下に各サンプリングベースでのMMTTYの動作構成を整理しておきます。 [受信- 11025/12000] ---> BPF -> Notch/LMS -> Limitter -> M(1/2) -> Demodulator ~~~~~~~~~~ 11025/12000 ~~~~~~~~~~~|~~~~~~~ 5513/6000 [受信- 6000/8000] ---> BPF -> Notch/LMS -> Limitter -> Demodulator ~~~~~~~~~~~~~~~~ 6000/8000 ~~~~~~~~~~~~~~~~ [送信] TxLPF ----> VCO ----> TxBPF ~~ 6000/8000/11025/12000 ~~  前置フィルタ、リミッター、TxLPF、TxBPF、FFT等はデモジュレータのオーバーサンプリングとは無関係です。これらは常に物理サンプリング周波数で動作します。  オーバーサンプリングの項で解説したように、サンプリング周波数を下げると同じ次数でも鋭い特性のフィルタが得られることを思い出して下さい。物理サンプリング周波数を下げることはCPU負荷に対して以下の点で効果的です ・サンプリング間隔が長くなるのでそれだけ処理のマージンが増える ・少ない次数で同じ特性のFIRフィルタが構成できる ・デモジュレータのオーバーサンプリング処理の必要がなくなる  ベース周波数に6000Hzまたは12000Hzを選択した場合、デモジュレータのナイキスト周波数(3000Hz)は最も適した状態になります。しかしサウンドカードによっては、これらの周波数をサポートしていない場合があり、更にMMTTYにエラーを通知しない場合がありますので、必ず送受信に異常がないか確認して下さい。  異なるベース周波数で録音したMMVファイルは正しく再生できません。またベース周波数を下げると録音されるMMVファイルの容量は同じ録音時間でも小さくなります。  6000Hzベースを選択した場合、ナイキスト周波数近辺では、D/Aコンバータの零次ホールド特性(アパーチャ効果)により出力レベルが最大4dB程度低下する可能性があります。高い周波数で広いシフト幅を設定すると、マーク周波数とスペース周波数でレベル差が発生する可能性があることに留意して下さい(アマチュア無線のRTTYではこのような使い方はしないので問題はないと思います)。 ◎最後に ~~~~~~~~ 何と言ってもデジタル信号処理は、インピーダンスを考慮しなくて良い点が楽だと思います。データは元の状態を損なわずに何度でもコピーできますので、これは出力インピーダンス0Ωに、入力インピーダンス∞Ωを接続しているのと同じです。  また今回のように浮動小数点演算を使うと、固定小数点演算では苦労する係数量子化誤差や演算誤差による特性劣化をあまり気にしなくてすみますので、ほぼ計算通りの結果を比較的簡単に得る事ができると思います。