BI1ALF すでに、ある方がリンクを共有しているので、ここでは詳しく説明しません。簡単に言うと、その仕組みは以下の通りです。
APRSの物理層では、AFSK 1200を使用しています。具体的には、1200Hzと2200Hzがそれぞれ1と0を表します(または0と1ですが、これは重要ではありません。なぜなら、NRZI符号化によって反転で0を、非反転で1を表すからです)。各ビットの長さは1/1200秒、つまり1200Hzの周期です。このようなビット長と周波数の近い符号化方式は、フィルタで硬く除去して復調することはできません。なぜなら、フィルタの応答におけるグループ遅延がビット長のそれよりも大きいため、符号の変化に追いつけないからです。
一般、このような信号の復調にはIQ復調が用いられます。これは、例えばsin(2π×1200t)とcos(2π×1200t)という2つの直交信号を入力信号にかけ、高周波成分を除去した後、その和の平方根を計算することで、実際の符号列(つまり、どのタイミングで1が、どのタイミングで0になるか)を得る方法です。その後、符号列の長さ(例えば、完全な1と0がいつ出現するか、およびAPRSが開始される際に0x7Eが出現し、タイミングを合わせるために使用される)に基づいて、判別を開始するタイミングを判断します。

LibAPRSは、よりシンプルな方法を採用しています。前述で「sin(2π×1200t)」と「cos(2π×1200t)」を別々に掛ける必要がある理由ですが、入力信号の位相が不明な場合に、sinまたはcosのみで掛け算すると、位相差によって直流成分にずれが生じます。また、掛け算後の平方和はなくなります。LibAPRSでは、自身信号の遅延半周期と自身を掛けることで、入力信号の位相が何であっても、掛け算の結果の直流成分は常にコード系列を表します(0.5/1200周期の遅延の場合、1200×1200で得られる直流成分は1となり、12002200,22001200、2200×2200の直流成分がすべて0であるため、自己との積を計算した後でフィルタリングを行うことで、符号列を得ることができます。これは、上記のIQ復調と比較して、半分の乗算とフィルタリングの手間を削減し、単一プロセッサのリソースを節約します。
https://cloud.tsinghua.edu.cn/d/ad481bc84b9e43779395/ ここにいくつかのMATLABコードがあります。aprs\_iq.mは、直前に私が作成したIQ復調コードです。aprs1.mは、以前LibAPRSの原理に基づいて書かれたシミュレーションコードで、現在は自分でも理解できません。(残念)