6502tinymachines

コムフィルタ、RGB 符号化器、そして速度

M2 の報告。作業の後に書かれた。

走行スタンプ: 2026-09-01、このリポジトリの三つ目のコミット、rustc 1.97.1、cargo test --workspace は 45 テストが緑、clippy はきれい、MUTATE=1 は 27 テストを赤にする。処理速度は AMD Ryzen 5 5600X (6 コア、1 スレッドだけ使用) で測り、wasm の行は node v24.0.1。以下の数値はすべて、ここで述べた走行から貼ったものだ。M5 がそれらを check-self-counts のスキャンの下に置く。

一次資料、ついに手元に

SMPTE 自身のリポジトリが ST 170M-2004 (2010 年に安定化) を配っている: https://pub.smpte.org/latest/st170/st170-20041130-pub.zip、zip の sha256 は dc9a1f0487385b697de0caca0a8371d61d84bffe7352bcf707818cc9bd8df2bd。M1 の宿題は閉じた: 条項 6.1 は基礎行列の桁を桁どおりに述べており (「precise values; i.e., 0.587 G = 587/1000 G」)、条項 6.2 の I/Q の式は、転記した縮小係数と 33 度の回転から、印字された小数 4 桁すべてまで再導出できる。data/yuv-matrix.toml がその確認を記録する。data/broadcast-timing.toml は表 1 (水準)、表 2 (水平タイミング)、そして条項 5.1、7、8、10、11 の新しい転記だ。条項 11 自身の有理数は M0 のものにぴったり着地する: f_sc = 5 MHz x 63/88 = 315/88 MHz、f_V = 59.94005994 Hz = 60,000/1,001。

計画を作り直させた発見が二つ、どちらも一次資料から出た:

  • 等帯域の U/V が標準であり、妥協ではない。 条項 7.2 の主たる仕様は B-Y と R-Y を同じように帯域制限する (1.3 MHz で 2 dB 未満の低下、3.6 MHz で 20 dB 以上の低下)。I/Q で帯域幅を分けるほうは、その NTSC-1953 継続の註だ。仕様書の 4.2 節の手順 2 (「Y は 4.2 MHz へ、I は 1.3 へ、Q は 0.4 へ」) は、v0.3 でこれを引くべきだ: Y は明示的に制限されておらず (7.1)、I/Q の分割は任意の歴史だ。
  • 条項 10 はデコーダにとって自己正規化する。 基礎の式はルミナンスとクロマを同じ 0.925 で拡縮し、7.5 IRE のセットアップを足す。だから黒 7.5 / 白 100 IRE を基準にしたデコーダは、ちょうど 0.492 (B-Y) と 0.877 (R-Y) を復元する: 転記した逆行列が期待している、縮小係数どおりの U と V であり、余分な定数はどこにも要らない。

RGB 符号化器と、カラーバーのゲート

ntsc-source-rgb: 映像水準の G'B'R' (あるいは sRGB のバイトを sRGB の EOTF と条項 5.1 のカメラ OETF に通したもの)、条項 6.1 の行列、有効領域の 2271 標本への線形リサンプル、色差のローパス (Blackman 窓の sinc。カットオフは 7.2 のテンプレートに対して余裕が最大になるところまで走査した: 2.60 MHz、1.3 MHz で -0.00 dB、3.6 MHz で -51.8 dB と実測、data/filters/rgb-encoder.toml に記録)、条項 10 の基礎の式、そして表 1 と表 2 の同期、消去、バースト。1 フィールドあたり 9 本のバースト無し行も守っている。単純化したところ (矩形の包絡、垂直同期は行の粒度、SC-H は未調整) はモジュールのヘッダに記録されていて、M2 のオラクルには見えない。

既知解のゲート (tests/bars.rs)、すべて表 1 の +/-1 IRE の内側だ:

  • 75% の各バーの波形の平均が、条項 10 の導出と、公表された波形モニタの欄 (76.9 / 69.0 / 56.1 / 48.2 / 36.1 / 28.2 / 15.4 IRE) の両方に着地する。この二つは互いに比べられるので、行列が間違っていてもセットアップが間違っていても、一致が壊れる。
  • バーストの peak-to-peak は 40 IRE (許容は 12 標本の格子の最悪のピーク標本化オフセット、cos 15 度から正当化した)、同期は -40、消去は 0。
  • 各バーのクロマ振幅は、条項 10 自身の拡縮の 3% 以内。
  • 復号の往復は、どのバーの中心も入力の映像水準から 0.02 以内で返す。

コムのラング

  • ラング B は NES プロファイルでは構築時に名指しで拒まれる。仕様のとおり: 120 度の行の残差が意味するのは、隣り合う二行が打ち消せないということだ。そこで二行コムが与える減衰は、クロマ経路で 0.866 で、クロマの半分がルミナンスに残る (時間コムのテストが直接測っているフェーザの算術)。放送では機能する: カラーバーの行でのコムのルミナンスのクロマ帯域エネルギーは、生の行の 2% 未満まで潰れる。
  • ラング C は NES プロファイルでは生来のコムであり、M2 のゲートが示すとおりだ: 縞のフレームでは三行の平均の副搬送波に同期したクロマが生の行の 1% 未満になり、その一方でクロマ経路はまだ、ノッチのラング自身の彩度で縞のアーティファクト色を復調する。一様なフレームでは、コムは基本波を 1e-3 未満まで取り去るのに対し、ノッチは (1 - 0.907) の残差を残す。
  • ラング D、仕様の主張に対して実測。 仕様 v0.2 の第 5 節は、描画が有効なフレームは交互に 180 度離れており、二フレームの平均がクロマを打ち消すと言う。同じ仕様の 3.2 節の残差は 4 標本と 8 標本、つまり 120 度と 240 度で、180 度には決してならない。実測 (tests/combs.rs): Even/OddShort の模様での二フレームのコムは、クロマ経路を一フレームの 0.866 倍に減衰させ (|1 - e^(-i120)| / 2)、基本波の半分をルミナンスに残す。打ち消せない。三つの完全なフレーム (描画を無効にした模様、それぞれ残差 4: Battletoads の場合) はちょうど打ち消す: ルミナンスの基本波は 2e-3 未満、彩度は 1.000 まで保たれる。v0.3 へ: 仕様どおりのラング D は存在しない。正直な時間コムは、全フレームの模様に対する三フレームのものだ。 OddShort の経路はどちらにしても復号を通して運動させられ、それがこのラングを置いた仕様の述べた理由だった。

計器についてのさらに三つの教訓、直したところで記録

  1. 帯域のエネルギーはクロマではない。 縞のフレームのドットレートのルミナンスの方形波 (2.685 MHz) はクロマ帯域の内側に住んでいる。コムはそれを正しく残すのに、帯域 RMS の計器は完璧に打ち消していたコムを有罪にした (一様なフレームのプローブは生の 5e-4 と測っていた)。計器はいま、副搬送波に同期した主張には同期復調を使い、帯域 RMS は基本波がその帯域の唯一の住人であるところだけで使う。
  2. 借りてきたデコーダは自分の利得を連れてくる。 時間コムをノッチのデコーダに通したら、その 0.907 のクロマ利得の除数を継いで彩度 1.103 と測れた: ちょうど 1/0.907 だ。コムは今その利得を 1 に上書きし、理由を述べる。
  3. 切り捨てられたティックが、遅い表示をでっち上げた。 放送の歩調合わせのテストの dt、1,001e9/30,000 ns は切り下がる。直し方は、ちょうど三周期に足し合わさる 3 ティックの模様だ。

処理速度、実測 (見積りの置き換え)

Ryzen 5 5600X、1 スレッド、--release、3 回の最良、全経路 = 2048 x 240 出力での符号化 + 復号:

経路フレーム/s註
NES ノッチ、ネイティブ7.54復号 3.7 M 標本/s
NES コム 3、ネイティブ8.49
NES 時間コム 3 の復号、ネイティブ12.41復調の尾だけ、符号化は共有
放送ノッチの復号、ネイティブ8.212271 標本の 240 行
放送コム 2 の復号、ネイティブ9.97
NES ノッチ、wasm (node v24)4.87
NES コム 3、wasm5.20
NES ノッチ、wasm +simd1284.97雑音の内側
NES コム 3、wasm +simd1285.18雑音の内側

仕様の書き下ろしの見積りは、ラング A が 42.95 M 標本/s で「SIMD 付きなら 1 スレッドに余裕で収まるはず」と言っていた。実測はそうではないと言う: 素朴な標本ごとの FIR は 1 標本あたり約 253 回の積和 (51 タップのクロマ帯域通過と 101 タップの U/V ローパス二つ) を要し、実時間から一桁離れている。そして simd128 のフラグだけでは何も変わらない。ベクトル化されるように書かれたものが何も無いからだ。名指しできて、まだ作っていないてこ: クロマは復調の後で 0.6 MHz 幅なので、U/V のローパスより前で間引けば支配的な費用が間引き率ぶん下がる。そして行の畳み込みは、明示的な SIMD の自然な置き場所だ。M3 はこの数値のままで走れる (CRT の各段は標本ごとではなく画素ごとだ)。実時間の表示は最適化のマイルストーンであって、正しさのマイルストーンではない。

歩調合わせの方針 (仕様の第 7 節) は実装されていて、打ち直しではなく導出した期待値でテストされている: 60 Hz の表示を NES の描画有効レートに当てると、ちょうどうなり周波数のぶんだけ落ちる (10 秒に約 1 フレーム)。120 Hz の表示は一つ飛ばしにコールバックを重複させ、ちょうど 30,000/1,001 Hz の表示は決してドリフトしない。

持ち越し

  • M3: CRT の各段、解析的なテスト、そしてシェルのゲート。
  • 実時間の復号 (間引き、明示的な SIMD)。表示の消費者が現れたときに。wasm のブリッジと統計はその準備ができている。
  • このマイルストーンから出た仕様 v0.3 への註: ラング D の訂正、条項 7.2 の等帯域の引用、そして M1 のフィールドレートの訂正。

ビルド時に ntsc-crt/docs/m2-report.md から取り込まれる。写しはリポジトリの一つだけだ。報告は独自の作業用の言葉をいくつか使う: 報告書で使われる言葉。