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

記録の項目

アプリが書く frames.jsonl(生フレーム)と events.jsonl(通話)の、すべてのキーの意味です。1 行が 1 件の JSON です。メイン画面のログ欄と、TCP で送る行も、同じ形です。

ファイルの置き場所と名前は出力ファイルにあります。

共通のキー​

frames.jsonl と events.jsonl の両方の行が持つキーです。

キー型内容
ts文字列時刻(ISO 8601、ローカル時刻とオフセット)。枠の時刻を、チャンクが届いた時刻から逆算した近似です。順序は si で見てください
radio文字列受けた無線機の ID。同じチャンネルを 2 台で受けたときも 1 ファイルに書き、これで区別します
ch文字列チャンネルの ID(プリセットの channels[].id。例 t102_399131250、t61t_399068750、t61c_399062500)
standard文字列方式。t102(T102 強化秘話, AMBE+2)か t61(ARIB STD-T61 EL-CELP)
si整数受信を始めてからの絶対位置。T102 はシンボル番号(2400 シンボル/秒)、T61 はビット位置(9600 bit/秒)。無線機を開き直すと 0 に戻ります
kind文字列行の種別。方式とファイルごとに下の表のとおりです

frames.jsonl(T102)​

同期した枠を 1 行ずつ書きます。同期語の誤りが 0 の枠が、直近 4 秒の窓に 2 枚以上ある間だけ書きます(雑音から行を作らないためです)。1 枠は 80 ms です。

{"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}
{"ts":"2026-10-26T09:02:17.392+09:00","radio":"r1","ch":"t102_399131250","standard":"t102","freq_hz":399131250,"si":1234759,"kind":"facch","sync_errors":0,"sacch":{"info":0,"crc_ok":false,"s":0,"user":0},"facch_hex":"e10500004e22000b5800e10500004e22000b5800"}
キー型内容
freq_hz整数チャンネルの周波数(Hz)
kind文字列voice(音声枠)、facch(制御の枠)、idle(空きの制御の枠。CRC が通った片がどれも 00 05 で始まる)、unknown(RICH のパリティが合わない枠、または種別を読めない枠)
sync_errors整数同期語(10 シンボル)の誤りビット数
sacchオブジェクト枠ごとの SACCH の 1 片。下の表
facch_hex文字列facch と idle の枠だけ。CRC が通った FACCH の片(1 片 10 バイト = 20 桁)を、枠の中の順に連ねた hex。1 片なら 20 桁、2 片なら 40 桁。CRC が通った片が無ければキーごと無い
voice_errors整数 4 つの配列voice の枠だけ。4 語(1 語 20 ms)それぞれの、情報ビットの訂正数
uncorrectable整数voice の枠だけ。訂正できなかった語の数(0〜4)

sacch:

キー型内容
info整数SACCH の 1 片の 26 bit(上位から S 2 bit、ユーザー 6 bit、本体 18 bit)
crc_ok真偽SACCH の片の CRC が通ったか
s整数info の上位 2 bit。4 片で 1 通の制御メッセージになるときの片の番号(3 → 0 の順に送られる)
user整数info の次の 6 bit

SACCH の制御メッセージ(72 bit)は 4 片をつないで作ります。受信中は 4 片を組み立て、結果を events.jsonl の control 行(detail.channel が sacch)に書きます。

frames.jsonl(T61)​

通話波で同期した枠を 1 行ずつ書きます。同期語の硬判定の誤りが 3 bit 以上の枠は書きません。1 枠は 40 ms です。制御波の枠は書きません(信号だけを出します)。

{"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}}
キー型内容
freq_hz整数チャンネルの周波数(Hz)
kind文字列traffic(RICH の CRC が通った枠)、unknown(同期したが RICH の CRC が通らなかった枠)
sw_hd整数同期語の硬判定の誤りビット数(0〜2)
richオブジェクトRICH(56 bit)。下の表
tch_hex文字列TCH の 256 bit(PN9 を剥がしたもの)。64 桁の hex
elcelpオブジェクトEL-CELP の伝送路符号を復号した結果。下の表。次の枠(40 ms 後)がそろった枠だけに付くので、行は 1 枠遅れて書かれます。次の枠が来なかった枠にはキーごと無い

rich:

キー型内容
mode整数か null通信モード M。CRC が通らなければ null
crc_ok真偽RICH の CRC が通ったか
raw_hex文字列RICH の 56 bit。14 桁の hex

elcelp:

キー型内容
ok真偽FEC が合格したか。入力 116 bit の末尾 3 bit の従属検査(u113 = u110⊕u112、u114 = u110⊕u111、u115 = u111⊕u112)が成り立ち、corrected が 12 以下なら合格
hex文字列音声ビット 137 bit。35 桁の hex(末尾 3 bit は 0 詰め)
corrected整数復号結果を符号化し直したものと、受けた硬判定との不一致ビット数

hex はどれも、ビットの並びの先頭を上位にして 4 bit ずつ小文字の 16 進にしたものです。

EL-CELP の符号語と 137 bit の並び​

  • 符号語(256 bit)は、枠 n の TCH の偶数位置と、枠 n+1 の TCH の奇数位置から作ります。結果は枠 n の行に付きます。
  • 符号語は、14 列のブロックインタリーブを戻してから、テイルバイティングの畳み込み符号(レート 1/2、拘束長 7、生成多項式 (133,171)₈)を軟判定の Viterbi で復号し、入力 116 bit を得ます。
  • hex の 137 bit は、入力の u0〜u112(113 bit)の後に、無保護の 24 bit を並べたものです。
  • 無保護の 24 bit は、符号語の中の位置 [16,17,34,35,36,53,54,71,72,73,90,91,108,109,128,145,146,165,182,183,218,219,254,255] にあります。hex での並びは、この昇順ではありません。研究側のビット地図(codec137.npz の unp)と同じ順です。誤りのない実データ 6,093 語で、この順なら全語が研究側のビット列と一致することを確かめています。
  • コーデック側の欄の配置と符号帳は分かっていないので、この版では音にしません。

events.jsonl(T102)​

T102 の通話の始まりと終わりと、制御メッセージを書きます。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(秘話 鍵24)","detail":{"caller":20002,"caller_name":"移動162","caller_tag":"a1b2c3d4","destination":11,"cipher_mode":1,"key_number":24,"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"}}
{"ts":"2026-10-26T09:02:27.360+09:00","radio":"r1","ch":"t102_399131250","standard":"t102","si":1258568,"kind":"unit_name","summary":"ユニット名 20002 = 移動162","detail":{"caller":20002,"name":"移動162","tag":"a1b2c3d4"}}
{"ts":"2026-10-26T09:02:30.000+09:00","radio":"r1","ch":"t102_399131250","standard":"t102","si":1265000,"kind":"control","summary":"制御 e3 05 …","detail":{"channel":"facch","raw_hex":"e3050000000000000000"}}
キー型内容
kind文字列call_start(通話の始まり)、call_end(通話の終わり)、unit_name(発信者とコールサイン名を初めて結び付けた)、control(そのほかの制御メッセージ)
summary文字列画面の通話の欄に出す 1 行の要約
detailオブジェクト種別ごとの中身。下の表

ts と si は、call_start は通話の始まり、call_end は通話の終わり、unit_name はそれを出した通話の始まりか終わり、control はそのメッセージを運んだ枠の時刻です。

通話の区切り方​

通話は、音声の語の流れで区切ります。制御メッセージの通話開始(0xE1)が運ぶ発信者・宛先・秘話の値を、その後の音声に当てます。音声が 2 秒途切れたときと、語の発信者が変わったときに閉じます(通話終了 0xE8 を受けると発信者が分からなくなるので、次の語で閉じます)。音声の語が 50 に満たない通話は捨てます(call_start も出しません)。call_start は語が 50 に達したときに出すので、行が出るのは通話が始まって 1 秒ほど後です。ts と si は通話の始まりの時刻です。

call_start​

キー型内容
caller整数か null発信者の ID。通話開始のメッセージを受けていなければ null
caller_name文字列か null発信者のコールサイン名(例「移動162」「基地11」)。まだ結び付いていなければ null
caller_tag文字列か null発信者の 4 バイトの固有タグ(8 桁の hex)。意味は分かっておらず、見分けるための値です
destination整数か null宛先の ID
cipher_mode整数か null暗号モード。0 は秘話なし
key_number整数か null秘話の鍵番号
key_known真偽秘話を外して合成できる鍵か。鍵番号が分かっていて、アプリが持つ鍵と違えば false(暗号モードは見ないので、平文の通話でも鍵番号で決まります)。false で秘話が掛かっている通話は、秘話が掛かったまま合成するので聞き取れません

summary は、発信者の名前(無ければ 発信者<ID>)と宛先(宛先<ID>)を「→」でつなぎ、秘話の括弧((平文)、(秘話 鍵<n>)、鍵が分からなければ (秘話 鍵<n> 未知))を付けたものです。値が無いところは 不明 と書きます。

call_end​

caller、caller_name、caller_tag、destination は call_start と同じです。コールサイン名は通話の途中で結び付くことが多いので、call_start では null でも call_end では埋まっていることがあります。

キー型内容
duration_s数通話の長さ(秒)
voice_words整数受けた音声の語の数(1 語 20 ms)
gap_words整数取れなかった語の数。合成では前の語からの補間か無音で埋めます
inferred_phase_words整数SACCH の CRC が通らず、語の位相を前後から推定した数
mean_errors数訂正できた語の、情報ビットの訂正数の平均(訂正できなかった語は除く)
uncorrectable_words整数訂正できなかった語の数
wav文字列この通話を録音した WAV のファイル名。WAV を書かなかった通話(WAV の録音を切っているときなど)ではキーが無い

summary は 通話終了 発信者<ID> <秒数> 秒 です(名前があっても ID で書きます)。

unit_name​

コールサイン名の制御メッセージ(0xE7)は、自分の発信者 ID を持ちません。アプリは直近の通話開始の発信者に結び付け、何度か受けた値の多数決で名前とタグを決めます。(発信者, 名前) の組を初めて決めたときに 1 行出します。

キー型内容
caller整数発信者の ID
name文字列コールサイン名(Shift-JIS を読んだもの)
tag文字列か null4 バイトの固有タグ(8 桁の hex)

control​

通話開始(0xE1)、通話終了(0xE8)、コールサイン名(0xE7)以外の制御メッセージで、CRC が通ったものです。FACCH の空き(00 05 で始まる片)は書きません。画面の通話の欄では、最初は表示から外してあります。

キー型内容
channel文字列運んだチャネル。facch か sacch
raw_hex文字列メッセージのバイト列の hex。FACCH は 10 バイト(20 桁)、SACCH は 4 片をつないだ 9 バイト(18 桁)

ライセンスが未認証のとき​

未認証の間は、frames.jsonl と events.jsonl を書かず、TCP でも送りません。画面に出す行では、次の値を伏せます。

行見せるもの伏せるもの
call_start・call_enddetail の caller、caller_name、destinationdetail のほかの値(caller_tag、cipher_mode、key_number、key_known、duration_s、wav など)は ***。null は null のまま、無いキーは足しません
unit_namesummary と detail の全部なし
controlなしsummary と detail の値は ***
T102 の枠受信品質の値(sync_errors、sacch、voice_errors、uncorrectable)facch_hex は同じ文字数の *
T61 の枠受信品質の値(sw_hd、rich.mode、rich.crc_ok、elcelp.ok、elcelp.corrected)rich.raw_hex・tch_hex・elcelp.hex は同じ文字数の *

未認証の summary は、秘話の括弧と通話の長さを含みません。call_start は <名前> → 宛先<ID>、call_end は 通話終了 <名前> です。名前は caller_name があればそれ、無ければ 発信者<ID> で、値が無いところは 不明 と書きます(例「移動162 → 宛先11」「通話終了 発信者20002」)。音声は流さず、WAV も作りません。