● (No.1201) HADES-SA CODEC2 音声スクランブル構造 (2026年10月13日)
----------------------------------------------------------------
[HADES-SA と HADES-L の共通点]
HADES-L は AX.25 ではなく、独自の "GENESIS形式 800 bps FSK" である。
AMSAT-EA が公開している HADES-L のデコーダーのソースコードを見ると、
HADES-L でも明確に、上記と同じ仕様である。さらに、HADES-L の main.c
は、genesis_crc.h と genesis_scrambler.h を直接インクルードしている。
つまり、これは単なる名称の類似ではなく、実際の HADES-Lデコーダーが
GENESIS方式を使っていることが確認できる。HADES-Lは、HADES-SAと同じ
GENESISフレーミング、スクランブル方式とデコード形式を採用している。
https://www.amsat-ea.org/proyectos/
HADES-SA
MSB-first
CRC-CCITT-FALSE
FSK GENESIS 800 bd
初期値: 0x2C350000
多項式: x^17 + x^12 + 1
1600 Hz tone separation
Multiplicative scrambler
HADES-L
GENESIS CRC
GENESIS scrambler
多項式: x^17 + x^12 + 1
Scrambler初期値: 0x2C350000
CRC初期値: 0xFFFF
[HADES-SA + Soundmodem]
60923hda.wav は、UZ7HO Soundmodem_for_HADES_SA_SpinnyONE.zip v0.05b 上に
HADES-SA の受信フレームが連続表示されていく。Soundmodem に連携する同梱の
KISSGENESIS.exe の Console画面には、SpinnyONE HADES-SA の packet type 13
packet type 11 (CODEC2 voice) などが表示されている。この 60923hda.wav は
GENESIS 800 baud FSK として正常にデコードできる実際のHADES-SA音源である。
HADES-SA, 60923hda.wav
#14185673, 2026-05-30 07:06:13
FSK 800 bps, 1600 Hz separation
Measured value Low:620 Hz, High:2220 Hz
参考SDM: E-Mail from UZ7HO, 11 Oct 2026
hs_soundmodem31.zip GFSK一般衛星用
erminaz.zip ERMINAZ衛星用
hadesl.zip HADES-L衛星用
unne1b.zip UNNE-1B衛星用
lilac2.zip ASRTU-1/LILACSAT2/BY70/JAMX01衛星用
LILACSAT2 uses FL114 mode, other sats FL223
HADES-SA CODEC2 スクランブル構造
[SoundModem と KISSGENESIS の出力の差異に関する質問]
From: Andrei, UZ7HO
Date: 29 Oct 2026
Hello, Mineo.
CODEC2 (type 11) are raw frames, there isn’t even a checksum check
and Soundmodem receives them in their original form. Since they lack
a checksum, these frames are received only by the main demodulator.
KISSGENESIS has "hadessa.dll" which contains some functions for
the post-processing of these frames. The different data is the result
of unscrambling.
You can find a source code there:
https://github.com/AMSAT-EA/HADES-SA_SpinnyONE/tree/main/byte_version
Look for "visualiza_codec2" etc.
On Thursday, October 29, 2026, 1:17:48 you wrote:
> Hello Andrei, UZ7HO
>
> I am currently working on decoding HADES-SA packets using SoundModem and KISSGENESIS.
>
> I noticed that the output data from SoundModem and KISSGENESIS appear to be different,
> even though the two programs work together and the data seems to
> correspond to the same frame and time.
> Source Audio is 60923hda.wav.
> For example, at approximately 22:45:00 on October 28, 2026,
> SoundModem displayed the following frame:
>
> ------------------------------------------------------
>
> soundmodem.exe for HADES-SA:
>
> [frm_type:11 len:37]
> B3 00 23 8A 55 29 A8 88 E9 A7 64 C3 91 6C 96 28
> EB 3A 1E 87 6A 7E BD A9 C3 DD 72 2C 5F CA 9E CE
> 99 A6 14 BC 0D
>
> At approximately the same time, KISSGENESIS.exe displayed:
>
> frame num : 0
> data :
> CE 9F 80 10 29 CF 80 90 5A 89 40 00 1B 73 C0 60
> CE EC 40 00 62 BF 80 00 CE BA 80 00 28 D4 C0 40
> CE C2 80 60 CE FF 80 00
>
> ------------------------------------------------------
>
> Could you please explain why these two outputs look different?
>
> Are these two data sequences representations of the same frame,
> with some conversion or processing performed by KISSGENESIS?
>
> If so, could you briefly explain the conversion process or point me
> to the relevant documentation or source code?
>
> I have attached the log containing the output from both programs for reference.
>
> Thank you very much for your help.
>
> Best regards. JE9PEL, Mineo Wakita
[続き: KISSGENESIS における CODEC2タイプ11デスクランブル]
From: Andrei, UZ7HO
Date: 29 Oct 2026
Hello, Mineo.
It's a bit of a complicated process.
Let's look at the structure of the "Type=11" frame:
B3 00 23 8A 55 29 A8 88 E9 A7 64 C3 91 6C 96 28 EB 3A 1E 87 6A 7E BD A9 C3 DD 72 2C 5F CA 9E CE 99 A6 14 BC 0D
"B3" contains SAT_ID=03 and PKT_TYPE=0B
"00" is serial number of CODEC2 packet.
Each packet contains 10 CODEC2 timeslots of 28 bits each, that gives us a total of 35 bytes (the rest part).
These 35 bytes are scrambled using the following XOR sequence:
uint8_t xor_codec2[35] = {
0xed, 0x15, 0xd5, 0x3b, 0x34, 0x70, 0xe0, 0xfd, 0xed, 0x83, 0x90, 0xdb,
0xaa, 0x2e, 0x25, 0xd6, 0x5e, 0x81, 0x41, 0x86, 0xbd, 0x67, 0x79, 0x5d,
0x70, 0xa1, 0x13, 0xce, 0x50, 0x0c, 0x19, 0xca, 0xfb, 0x44, 0x0d };
Since 28 bits are not a multiple of 8 bits, we need to align them to 32 bits sequence using padding bits.
Let's take first timeslot: "23 8A 55 2"
23 XOR ED = CE
8A XOR 15 = 9F
55 XOR D5 = 80
2 XOR 3 = 1
So we have the sequence "CE 9F 80 1", adding 4 padding bits to get a 32 bits word: "CE 9F 80 10".
In this way we perform all 10 iterations, which give us 40 bytes that you can see in KISSGENESIS output.
On Thursday, October 29, 2026, 9:08:35 you wrote:
> Hello Andrei,
>
> Thank you very much for your quick and helpful explanation.
> I would like to clarify two details about the descrambling of CODEC2 type 11 frames.
>
> 1. In the 37-byte SoundModem frame, which bytes are descrambled?
> Is the 3-byte header (B3 00 23) excluded, with descrambling
> applied only to the remaining payload?
> 2. Could you explain how the following SoundModem frame is
> transformed into the data displayed by KISSGENESIS?
> SoundModem input:
> B3 00 23 8A 55 29 A8 88 E9 A7 64 C3 91 6C 96 28
> EB 3A 1E 87 6A 7E BD A9 C3 DD 72 2C 5F CA 9E CE
> 99 A6 14 BC 0D
>
> KISSGENESIS output:
> CE 9F 80 10 29 CF 80 90 5A 89 40 00 1B 73 C0 60
> CE EC 40 00 62 BF 80 00 CE BA 80 00 28 D4 C0 40
> CE C2 80 60 CE FF 80 00
>
> If possible, could you point me to the specific function in the
> source code that performs this conversion,
> or provide a brief explanation of the algorithm?
>
> This will help me implement and verify the same processing in my GNU Radio HADES-SA decoder.
>
> Thank you again for your assistance.
>
> Best regards,
>
> JE9PEL, Mineo Wakita
--
Best regards, Andy
[SoundModem の37バイトのフレーム構造]
[最初の28ビットを実際に変換する]
項目 値
入力28ビット 23 8A 55 2
XOR系列の先頭 ED 15 D5 3
XOR後 CE 9F 80 1
32ビットに整列した出力 CE 9F 80 10
XORは、同じビット同士なら 0、異なるビット同士なら 1 になる演算である。
バイト単位で見ると、たとえば次のようになる。
23 XOR ED = CE
8A XOR 15 = 9F
55 XOR D5 = 80
最後は4ビットだけ処理し、残りの4ビットを整列用のパディングとして加える。
そのため、28ビットの入力が 32ビットの出力になる。
[XOR の基本原理]
XOR は “eXclusive OR” の略で、日本語では「排他的論理和(はいたてきろんりわ)」という。
OR:どちらか一方、または両方が 1 なら 1
Exclusive OR (XOR):どちらか一方だけが 1 なら 1, 両方同じなら 0
A B A XOR B
--- --- ---------
0 0 0
0 1 1
1 0 1
1 1 0
「Exclusive」は「排他的な、どちらか一方だけ」という意味である。
まず16進数を2進数に変換する。
16進数 2進数
23 0010 0011
ED 1110 1101
次に、1ビットずつ XOR 演算する。
0 0 1 0 0 0 1 1 ← 23
XOR 1 1 1 0 1 1 0 1 ← ED
-----------------
1 1 0 0 1 1 1 0 ← CE
結果を16進数に戻す。
1100 1110 ← CE
計算結果: 23 XOR ED = CE
今回の HADES-SA の例では、23 XOR ED = CE のように、各ビットにこの演算を適用している。
便利なのは、XOR は同じ値をもう一度 XOR すると元に戻る(解除)という性質である。
(A XOR B) XOR B = A
これが、今回の固定XOR系列を使ってデータをスクランブル解除できる基本原理である。
[XOR sequence (固定XOR系列) について]
xor_codec2[35] は、CODEC2データのスクランブル解除に使用する35バイトの固定XOR系列である。
受信データの280ビットと、この系列の280ビットを MSB-first で対応させて、28ビット単位の
10スロットに分けてXOR演算を行う。この配列の各数値は16進数で表されている。数値の並びに
単純な周期性や、直ちに判別できる規則性があるとは限らない。現時点では、配列の生成方法や
数値列の数学的な規則性は確認できていない。ここでは、公開ソースコードに示された固定系列
として扱う。
[なぜ37バイトから40バイトになるのか]
35バイトは280ビットである。
280ビット ÷ 28ビット = 10スロット
10スロット × 32ビット = 320ビット
320ビット ÷ 8 = 40バイト
つまり、KISSGENESISの40バイト出力は、10個の28ビットスロットをそれぞれ32ビットに整列させ
た結果である。37バイトのフレームと40バイトの出力は、形式が異なるため、長さは一致しない。
[GNU Radio実験への応用]
1. SoundModemで受信したフレームから B3 00 を除き、残り35バイトを取り出す。
2. UZ7HO局が示した35バイトの XOR系列を使い、28ビットずつデスクランブルする。
3. 各スロットを32ビットに整列し、40バイトの出力を生成する。
4. KISSGENESISの出力と比較し、全10スロットが一致するか確認する。
[SoundModem 37バイトから KISSGENESIS 40バイトへの変換検証]
UZ7HO局の説明に基づき、SoundModemが出力したCODEC2 (PKT_TYPE = 0B) の37バイトフレームから、
10個の28ビットスロットを復号し、40バイトのデータを計算した。
[変換方法]
先頭2バイト (B3 00) を除いた35バイトを280ビットの系列として扱う。
公開された固定XOR配列35バイトを同じく280ビットの系列として扱い、MSB-firstで28ビットずつ、
10スロットに分割してXORする。各28ビットスロットの末尾に4ビットの0000を追加し、4バイトに整列する。
[計算結果]
CE 9F 80 10 29 CF 80 90
5A 89 40 00 1B 73 C0 60
CE EC 40 00 62 BF 80 00
CE BA 80 00 28 D4 C0 40
CE C2 80 60 CE FF 80 00
この40バイトは、記録されていたKISSGENESISの同一フレームの出力と、全バイトで一致した。
[結論]
このサンプルフレームについて、SoundModemの生フレームからKISSGENESISの40バイト出力への変換を再現できた。
今後は、複数フレームでの再現性と、変換後のデータがCODEC2音声処理にどのように渡されるかを確認する。
[HADES-SA CODEC2 音声復元成功] (29-30 Oct 2026)
SoundModem.exe と KISSGENESIS.exe によって取得した HADES-SA の CODEC2(type 11)フレームから、実際に
音声を復元する実験に成功した。取得データのスクランブル構造の解析が大変難儀で、UZ7HO局の助言により、
この実験に取り組み始めて一ヶ月以上掛かって、ようやく音声の復元に成功した。以下にその手順を示す。
AMSAT-EA が公開している "HADES-SA SpinnyONE CODEC2 utilities" を使用する。
最初に入手していた4月3日版では、c2dec.exe の実行時に "libgcc_s_seh-1.dll" が見つからないという
エラーが発生した。そこで、AMSAT-EA の公開ページから4月4日版を再ダウンロードした。この版には不足
していた DLL が含まれており、c2dec.exe が正常に起動することを確認した。 AMSAT-EA Projects
[CODEC2 frameファイルの確認]
KISSGENESIS によって生成された CODEC2 frameファイル(.bin)は、satフォルダに保存されている。
各ファイルは 40バイトである。今回確認できたファイルは、全37フレーム中25フレームであった。
フレーム番号004~015 の12フレームは欠落していた。
[CODEC2 frameファイルの準備]
また、これらのファイルを結合するため、run_codec2.bat を修正し、satフォルダ内の CODEC2 frameファイル
を読み込むようにした。この修正済みのBATファイルは、ここからダウンロードできる。→ run_codec2.bat
(修正行) (for %%F in (sat\*codec2_frame_*.bin) do echo %%F) > codec2_file_list.txt
(BAT実行) C:\Program Files\hadesa\AMSAT-EA_HADES-SA_SpinnyONE_CODEC2_utilities>run_codec2.bat
[CODEC2ファイルの結合]
run_codec2.bat をコマンドラインから実行する。BATファイル内の処理により codec2-merge-windows-x86.exe
が自動起動され、codec2_file_list.txt に記載された25個の CODEC2 frameファイルが結合される。つまり、
codec2-merge-windows-x86 codec2_file_list.txt hades_sa.c2
hades_sa.c2 が自動生成される。続いて c2dec と ffmpeg が自動実行され、hades_sa.wav まで生成された。
欠落していた12フレームはゼロデータで補われ、正常終了した。
[c2dec.exe によるデコード]
utilityフォルダに hades_sa.c2 をコピーし、Windowsコマンドプロンプトから次のコマンドを実行した。
c2dec 700C hades_sa.c2 hades_sa.raw
700C は、CODEC2の 700 bit/s系の音声符号化モードを指定するものである。
実行結果: Detected Codec2 file version 1.2 in mode 8
エラーなく hades_sa.raw が生成された。
[FFmpeg による WAV変換]
続いて、RAW音声データを WAVファイルに変換した。
ffmpeg\bin\ffmpeg -f s16le -ar 8000 -ac 1 -i hades_sa.raw hades_sa.wav
生成された WAVファイル:
ファイル名: hades_sa.wav
形式: PCM signed 16 bits
サンプルレート: 8000 Hz
チャンネル: Mono
長さ: 14.80 seconds
[ついに音声を確認!]
生成された hades_sa.wav を Windows 上で再生したところ、ついに人の音声を聞くことができた。
61030cd2.wav (hades_sa.wav)
HADES-SA の受信データから CODEC2 フレームを結合し、デコード・音声WAV変換を経て、実際に音声を
再生することに成功した。今回は、37フレーム中12フレームが欠落しており、その部分はゼロデータで
補われているため、完全な音声ではない。しかし、受信したデジタルデータから人の音声を取り出せた
ことは、大きな成果である。
[追加実験: SoXによるRAW音声のWAV変換]
UZ7HO局から、FFmpegの代わりに SoX を使用して RAW音声をWAVに変換する別の方法のメールがあった。
From: Andrei, UZ7HO
Date: 1 Nov 2026
By the way, I used SoX instead of FFMPEG for RAW to WAV converting:
sox -t raw -b 16 -e signed-integer -r 8000 -c 1 -L hades_sa.raw hades_sa.wav
It takes less space on disk.
> On Sunday, November 1, 2026, 9:46:47 you wrote:
>
> Hello Andy.
>
> HADES-SA CODEC2 Audio Playback Successful.
> https://www.asahi-net.or.jp/~ei7m-wkt/numb1201.htm
> https://www.ne.jp/asahi/hamradio/je9pel/hadeslgr.htm
>
> Thank you.
> JE9PEL, Mineo Wakita
--
Best regards, Andy
そこで、Windows環境に SoX v14.4.2 を導入し、次のコマンドで変換を実行した。
sox -t raw -b 16 -e signed-integer -r 8000 -c 1 -L hades_sa.raw hades_sa.wav
変換は正常に完了し、作業フォルダー内に新しい hades_sa.wav が生成された。このファイルサイズは
以前 FFmpeg で作成した hades_sa_ffmpeg.wav より数十バイト小さくなった。新しい SoX版WAVを再生
し、FFmpeg版と耳で聞き比べると、どちらも人の音声が明瞭に再生され、聞き取れる違いはなかった。
今回の実験により、HADES-SA CODEC2音声の RAWからWAVへの変換に、SoXも問題なく使用できることを
確認した。
※比較は聴感によるもので、音声データのデジタル比較は行っていない。
SoXサイト: https://sourceforge.net/projects/sox/files/?utm_source=chatgpt.com
[今後の GNU Radio Companion (GRC)実験]
今回の実験では、CODEC2 utility を使用した手動処理によって、音声再生まで確認できた。今後は、
GNU Radio Companion (GRC) による受信・同期・フレーム抽出の自動処理を完成させ、今回確認した
CODEC2 音声処理につなげていく。最終目標は、HADES-SA だけでなく、同じ GENESIS形式を使用する
HADES-L についても、受信から音声再生までを実現することである。
[HADES-SA + GRC] (開発途中, 30 Oct 2026)
GNU Radio Companion (GRC) による HADES-SA の受信・デコード実験は、現在も継続中である。
今回、CODEC2 utility を使用して、受信データから人の音声を再生するところまで確認できた。
今後は、この処理を GRC のフローグラフに組み込み、受信から音声再生までの一連の自動処理を目指す。
https://www.ne.jp/asahi/hamradio/je9pel/HADES_SA_800bps_FSK_WAV_CHECK26_bits_inverted.grc (in progress)
トップ へ戻る.
前のページ へ戻る.
次のページ へ移る.(編集中)
ホームページ(目次) へ戻る.