私は(?あなたがやって終わるんでした何を)これはおそらくあなたを助けるには遅すぎであると仮定し、それは隣の男を助けるかもしれません。私はあなたを説得するために、最初にこの小さなgolfedバージョンを提示
main(a,b){for(;;)a+=((b+=16+a/1024)&256?1:-1)*getchar()-a/512,putchar(b);}
:
はここであなたと一緒に歌います私はCの1行で書いたソフトウェアの位相ロックループのgolfed例ですソフトウェアのフェーズロックループは実際にはかなりシンプルなものですが、ソフトウェアは複雑になりがちですが、
stdinで8ビットの線形サンプルをフィードすると、標準出力で1オクターブ上をトラッキングしようとするノコギリ波のサンプルが8ビット生成されます。毎秒8000サンプルでは、250Hz付近の周波数を、中間のCよりわずかに上の周波数でトラッキングします.Linuxでは、arecord | ./pll | aplay
と入力します。 b
の下位9ビットは、入力波形(getchar()
)を乗算して位相の出力を生成する方形波(1または-1)を生成するオシレータ(ハードウェア実装ではVCOとなる可能性があります)検出器。その出力は次にa
にローパスフィルタされ、平滑化された位相誤差信号が生成され、b
の周波数を0に向けてa
にプッシュします。a == 0
の場合、固有周波数はb
16サンプル毎に512(フルサイクル)ずつインクリメントする。毎秒8000サンプルで32サンプルが1/250秒であるため、固有周波数は250Hzです。
次にputchar()
は、500Hz程度でのこぎり波を構成するb
の下位8ビットを取り、それらを出力オーディオストリームとして吐き出します。
この単純な例から欠落しているいくつかのものがあります。
それはロックを検出するためには良い方法がありません。無音、ノイズ、純粋な250Hz入力トーンがある場合、aはおおよそゼロになり、bはデフォルト周波数で振動します。アプリケーションによっては、信号を検出したかどうかを知りたい場合があります。 Designing Analog Chipsの第12章のCamenzindの示唆は、第2の「位相検出器」を実際の位相検出器から90°位相をずらして供給することである。その平滑化された出力は、あなたが理論的にロックしている信号の振幅を与えます。
発振器の固有周波数は固定されており、はスイープしません。 PLLの捕捉範囲のは、現在ロックされていないと振動に気付く頻度の間隔がかなり狭いです。そのロック範囲は、一度ロックされると信号に従うために範囲が広がりますが、これははるかに大きくなります。このため、ロックを取得してからスイープを停止するまでは、PLLの周波数を信号を検出したい範囲でスイープするのが一般的です。
ロック検出をするのかが、スイープしません上記の私が今日書いたmuch more readable example of a software phase-locked loop in Cから減少しgolfedバージョン、。私のネットブックのAtom CPUには、PLLあたりの入力サンプルあたり約100 CPUサイクルが必要です。
私があなたの状況にあったとすれば、私は信号処理についてもっと知っている人を探してテストデータを生成するような明白なことを除いて、次のことを行うと思います。私はおそらく、そのような低周波数に既にあるので、フロントエンドで信号をフィルタリングしたりダウンコンバートしたりしないでしょう。 200Hz~400Hzの帯域へのダウンコンバートはほとんど必要ありません。私は、信号が突然位相が90°以上シフトすると、位相ロックを失うので、PSKがいくつかの新しい問題を引き起こすと思われます。しかし、私はこれらの問題が解決しやすいと思っています。
http://dsp.stackexchange.com/questions/8456/how-to-perform-carrier-phase-recovery-in-software – Keith