メインコンテンツまでスキップ

出力ファイル

チャンネルごとに JSONL を、保存先フォルダに追記します。T102 の波は frames.jsonl と events.jsonl の 2 本、T61 の通話波は frames.jsonl の 1 本です。T61 の制御波は記録しません。T102 の通話は、同じフォルダに通話ごとの WAV で録音します。

<出力先>/2026-10-26_T102_399.13125.frames.jsonl # 生フレーム(T102)
<出力先>/2026-10-26_T102_399.13125.events.jsonl # 通話(T102)
<出力先>/2026-10-26_T102_399.13125_voice_090215_c20002-d11.wav # 音声(T102)
<出力先>/2026-10-26_T61_通話_399.06875.frames.jsonl # 生フレーム(T61)
<出力先>/2026-10-26_stats.jsonl # 統計
<出力先>/iq/2026-10-26_090215_受信1_399243750_1024000.cu8 # IQ の録音
未認証の間は記録しません

ライセンスが未認証の間は、JSONL と WAV を記録せず、TCP でも送りません(IQ の録音はできます)。画面の通話の欄には、通話の開始・終了の行がコールサイン名と発信者・宛先の番号だけを残して出ます。認証の手順はライセンス認証にあります。

ファイルの分かれ方​

  • ファイル名は <営業日>_<チャンネルの名前> です。名前の空白は _ に置き換えます(「T61 通話 399.06875」→ T61_通話_399.06875)。チャンネルの名前はプリセットの name です(プリセット)。
  • 営業日は、ローカル時刻を日付の境界時刻(既定 3 時)で区切った日付です。
  • ファイルはチャンネルごとに分かれます。同じチャンネルを 2 台で受けた場合も 1 つのファイルに書き、行の radio で区別します。
  • frames が生フレーム、events が通話です。
  • WAV は、チャンネルごと、通話ごとに 1 ファイルです。
  • cu8 ファイルを再生したときの記録は、<出力先>/replay/ に入ります。録音した日に受信したときの記録と二重にならないためです。録音した時刻が分かる cu8 では、ts とファイル名の日付が録音した時刻になります(録音ファイルの再生)。

保存先フォルダ、日付の境界時刻、書き出す種類は、設定画面の「出力」欄で決めます。記録しているかどうかは、メイン画面のツールバーの「記録」に「ON」「OFF」で出ます。

生フレーム(*.frames.jsonl)​

1 行が、同期した 1 つの枠です。

T102 の生フレームの 1 行
{"ts":"2026-10-26T09:02:17.312+09:00","radio":"r1","ch":"t102_399131250","standard":"t102","freq_hz":399131250,"si":1234567,"kind":"voice","sync_errors":0,"sacch":{"info":33554437,"crc_ok":true,"s":2,"user":0},"voice_errors":[3,0,1,2],"uncorrectable":0}
T61 の生フレームの 1 行
{"ts":"2026-10-26T09:02:17.312+09:00","radio":"r1","ch":"t61t_399068750","standard":"t61","freq_hz":399068750,"si":1234567,"kind":"traffic","sw_hd":0,"rich":{"mode":1,"crc_ok":true,"raw_hex":"<14 桁>"},"tch_hex":"<64 桁>","elcelp":{"ok":true,"hex":"<35 桁>","corrected":3}}

kind は次のとおりです。

方式kind意味
T102voice音声の枠です
T102facch制御の枠です
T102idle空きの制御の枠です。通話が無いあいだも送られ続けます
T102unknown種別を読めなかった枠です
T61trafficRICH の CRC が通った枠です
T61unknown同期したものの、RICH の CRC が通らなかった枠です
  • si は受信を始めてからの位置(T102 はシンボル、T61 はビット)です。ts は枠が届いた時刻から逆算した近似なので、順序は si で見てください。
  • T61 の枠には、後で音にし直せるよう、EL-CELP の 137 bit(elcelp.hex)を残します。

すべてのキーの意味は記録の項目にあります。

通話(*.events.jsonl)​

T102 の通話の始まりと終わり、コールサイン名、制御メッセージを、1 行 1 件で書きます。T61 は events.jsonl を書きません。

通話の行
{"ts":"2026-10-26T09:02:15.040+09:00","radio":"r1","ch":"t102_399131250","standard":"t102","si":1229000,"kind":"call_start","summary":"移動162 → 宛先11(平文)","detail":{"caller":20002,"caller_name":"移動162","caller_tag":"a1b2c3d4","destination":11,"cipher_mode":0,"key_number":null,"key_known":true}}
{"ts":"2026-10-26T09:02:27.360+09:00","radio":"r1","ch":"t102_399131250","standard":"t102","si":1258568,"kind":"call_end","summary":"通話終了 発信者20002 12.3 秒","detail":{"caller":20002,"caller_name":"移動162","caller_tag":"a1b2c3d4","destination":11,"duration_s":12.32,"voice_words":614,"gap_words":2,"inferred_phase_words":0,"mean_errors":1.8,"uncorrectable_words":0,"wav":"2026-10-26_T102_399.13125_voice_090215_c20002-d11.wav"}}
kind内容
call_start通話の始まりです
call_end通話の終わりです。detail.wav に、その通話の WAV のファイル名が入ります
unit_name発信者とコールサイン名を初めて結び付けた行です
controlそのほかの制御メッセージです

summary はメイン画面の通話の欄に出る 1 行の要約、detail は詳細の欄に出る中身です。detail のキーの意味は記録の項目にあります。

音声(*.wav)​

T102 の通話を、通話ごとに 1 ファイルの WAV に録音します。形式は 8 kHz、モノラル、16 bit です。T61 の音声は録音できません。

<出力先>/2026-10-26_T102_399.13125_voice_090215_c20002-d11.wav

ファイル名は <営業日>_<チャンネルの名前>_voice_<開始時刻 HHMMSS>_c<発信者 ID>-d<宛先 ID>.wav です。

  • 発信者や宛先が分からない通話は、_c<発信者 ID> や -d<宛先 ID> を省きます。
  • 通話の始まりで開き、通話の終わりで閉じます。音声が 2 秒途切れるか、発信者が変わると、通話が終わったとみなします。
  • 日付の境界時刻が既定の 3 時のとき、0:00〜2:59 の録音はファイル名の日付が前日になります。
  • 同じ秒に同じチャンネルで 2 つ目のファイルを開くときは、末尾に _2 のような連番が付きます。

録音するかどうかは、設定画面の「出力」欄の「音声を WAV に録音する」で切り替えます。既定はオンです。再生の操作は音声を聞くにあります。

統計(*_stats.jsonl)​

1 分ごとの受信の統計を、同じ保存先フォルダの <営業日>_stats.jsonl(例: 2026-10-26_stats.jsonl)に追記します。1 分ごとに、監視中のチャンネルごとの行と、無線機ごとの行を書きます。

統計の行
{"ts":"2026-10-26T09:02:00.000+09:00","radio":"r1","ch":"t102_399131250","frames":750,"received":742,"events":2}
{"ts":"2026-10-26T09:02:00.000+09:00","radio":"r1","queue_fill_max":0.6,"dropped":3,"overflow":1}

チャンネルの行のキーは次のとおりです。枠の届かなかったチャンネルの行は書きません。

キー内容
tsその 1 分の始まりの時刻です。ファイル名の営業日も、この時刻で決めます
radio受信した無線機を表す ID です
chチャンネル ID です
framesその 1 分に届いた枠の数です
receivedそのうち、受信率に数える枠(T102 は unknown 以外、T61 は traffic)の数です。received ÷ frames が、画面の受信率にあたります
eventsその 1 分の通話の行の数です

無線機の行のキーは次のとおりです。

キー内容
tsその 1 分の始まりの時刻です
radio無線機を表す ID です
queue_fill_maxその 1 分のキュー滞留率の最大(0〜1)です
droppedその 1 分に増えた取りこぼしの数です
overflowその 1 分に増えた overflow の数です

2 台の無線機の行は同じファイルに書き、radio で区別します。ライセンスが未認証の間は、統計も書きません。設定画面の「出力」欄で、生フレーム・通話・音声の書き出しをどれも切っているときも書きません(どれか 1 つでも入っていれば書きます)。書けなかったときは、その 1 分の行を捨て、次の 1 分にまた書きます。ヘッドレス版も同じです。

IQ の録音(iq/)​

受信の不調を後から調べるために、受信した IQ をそのままファイルに録音できます。

  • 手動: メイン画面の無線機の欄の「● IQ 録音」を押すと始まり、もう一度押すと止まります。録音中は経過秒とサイズを表示します。
  • 自動: 設定画面の「出力」欄の「音声が出ているあいだ IQ を録音する」をオンにすると、T102 の音声の枠を受ける 5 秒前から、途切れて 5 秒後までを録音します(既定はオフ)。未認証の間は音は出ませんが、同じように録音します。
  • 1 本は 10 分で閉じます。手動の録音はそこで止まります。自動の録音は、音声が続いていれば次のファイルへ続きます。
  • 容量は 1.024 Msps で 1 分あたり約 123 MB です(サンプルレート × 2 バイト)。古いファイルは自動では消しません。

ファイルは出力先の iq/ に、cu8(I, Q の順の符号なし 8 bit)と同名の .json(中心周波数、サンプルレート、ゲイン、録音を始めた時刻など)の組で作ります。

<出力先>/iq/2026-10-26_090215_受信1_399243750_1024000.cu8
<出力先>/iq/2026-10-26_090215_受信1_399243750_1024000.json

ファイル名は <開始日時>_<無線機のラベル>_<中心周波数 Hz>_<サンプルレート>.cu8 です。録音した cu8 は、録音ファイルの再生の手順でそのまま再生できます。

TCP で送る​

JSONL と同じ行を、TCP でも送れます。設定画面の「出力」欄の「TCP で送る」を入れて、送り先のホストとポート(既定は 127.0.0.1 の 35263)を決めます。「生フレーム」「通話」で、どちらの行を送るかを選べます。

アプリの側から送り先へつなぎに行くので、受ける側を先に待ち受けにしておきます。たとえば次のようにします。

nc -lk 35263
  • 送る行は、生フレームと通話の JSONL のファイルと同じです。1 行が 1 件の JSON で、生フレームの行には freq_hz があり、通話の行にはありません。これで見分けます。
  • ファイルに書かない設定でも送れます。「生フレーム JSONL」「通話 JSONL」を切っていても、「TCP で送る」を入れていれば送ります。
  • cu8 を再生している無線機の行も、同じように送ります。行に再生だと分かる印はありません。録音した時刻(started_utc)が分かる cu8 なら ts は録音した時刻です(録音ファイルの再生)。実時間の行と区別したいときは、ts か radio で見分けます。
  • つながっていない間の行は捨てます。溜めておいて、つながったときにまとめて送ることはしません。設定画面に、接続中か再接続待ちかと、捨てた行の数を出します。
  • ライセンスが未認証の間は送りません。
  • ヘッドレス版は、config.json の output.tcp で同じように動きます。キーは enabled、host、port、frames、events です。ヘッドレス版を同じ機械で動かしているときは、ヘッドレス版の待ち受け(既定 35263)と重ならないポートにしてください。