所有する初代PlayStationの512 KiB BIOSを、アナログステレオ音声からブラウザへ転送する。目標は180秒以内。BIOSデータはサーバーへ送信せず、全ブロックCRC32とイメージCRC32が一致した場合だけ保存する。
PS1側はFPUを使わず固定小数点で処理する。SPU ADPCMとダブルバッファDMAで音声を生成する。転送本体は44.1 kHzステレオOFDM、512ポイントFFT、64サンプルCP、96搬送波、QPSK、32データ+4パリティshard FEC。1 OFDMパケットは同期1シンボル+データ4シンボルで、シンボル周期は576サンプル(約76.56 OFDMシンボル/秒)。ステレオの生ビットレートは約21.56 kbit/s、FEC・CRC・同期を含む実効値は実機条件で変動する。
本体の前に、三角波ADPCMで短音「ぴー、ぴー」、休符、長音「ぷーーー」を送る。短音440 ms、休符360 ms、長音1400 ms。ブラウザAudioWorkletは 高音→休符→高音→休符→低音 のステートを検出し、2・1をカットイン表示する。低音の立ち上がりでGO!を表示し、そこから受信タイマーを開始する。
このスタートSE自体もPS1側で生成・再生する。実機で音量を確認でき、従来のFSKでいうキャリアのレベル調整(入力ゲイン合わせ)の基準として利用できる。FSKは実データ転送には使用せず、実データはOFDMのみで送る。
ブラウザはステレオ入力専用(モノラル入力不可)。AudioWorkletが入力を専用Workerへ渡し、OFDM復調、CRC、FEC訂正を実行する。CD起動イメージは Pages のCUE+BIN ZIPリンクから取得できる。
- 32データ+4パリティshardのリード・ソロモンFECで、最大4パケット欠損をグループ内で復元する。
- パケットCRC不一致時は、受信シンボルの信頼度を使った候補探索とCRC-guided単一ビット補正を行い、訂正不能時だけ停止する。
- PS1のSPU ADPCMは4-bit量子化、16サンプル単位のブロック履歴、ブロック終端フラグを持つため、無音境界や急峻な波形で誤差が増える。そこで波形振幅を抑え、フェードイン/アウトを入れ、DMAバッファをOFDM本体と分離した。
- FSKヘッダの再利用音が実機で混ざる問題を避け、OFDM領域とスタート音領域を分離した。スタート音は三角波ADPCMで、AudioWorkletのステートマシンが2・1・GO!を順序保証する。
各グループは最大32個のデータshardと4個のパリティshardで構成する。パリティはGF(256)、既約多項式0x11d上のCauchy行列係数 1/(r XOR (4+c)) で生成する。受信側はCRC不一致パケットを消失(erasure)として扱い、既知データをパリティから引いて不足shardだけの線形方程式を作る。受信したパリティ行を不足数だけ選び、GF(256)ガウス消去で逆行列を求め、各バイト位置を同じ係数で復元する。復元後はパケットCRC32、ブロックCRC32、最終イメージCRC32を順に検証する。
OFDMのFFT・同期・復調の重い処理はC/C++系の固定小数点コードをWebAssembly(ofdm-decoder.wasm)へコンパイルしている。専用WorkerからWASMを呼び出してUIスレッドを塞がず、ロードできない場合は同じプロトコルのJavaScript実装へフォールバックする。
AGENTS.mdにプロトコル、ビルド、実機検証の境界を先に固定し、Codexには小さな変更単位で実装させた。各変更で make test、Node構文チェック、git diff --check を実行した。開発用MacはMacBook Neo(メモリ8GB)しかないため、Dockerを動かさずPS1のビルドをMac Studioへ同期して実行した。合成WAVループバック、DuckStation、実機録音を別々の証拠として扱い、最後に生成CUE/BINをZIP化してPagesへ公開した。
仮想環境(DuckStation)で動作確認した後、CUE/BINをCD-Rへ焼いて実機PlayStationで検証した。構成はPS1のアナログ音声L/R → EP-136オーディオインターフェースのステレオ入力 → ブラウザAudioWorklet(44.1 kHz、AGC/ノイズ抑制/エコーキャンセルOFF)。EP-136のゲイン、入力レベル、ケーブル、左右チャンネル設定が復調安定性に影響する。
This project backs up a 512 KiB BIOS from an owned original PlayStation over analog stereo audio, targeting completion within 180 seconds. The browser never uploads BIOS data; it saves only after per-block and whole-image CRC32 verification.
The PS1 implementation avoids floating point and uses fixed-point arithmetic, SPU ADPCM, and double-buffered DMA. The payload uses 44.1 kHz stereo OFDM with a 512-point FFT, 64-sample cyclic prefix, 96 carriers, QPSK, and 32+4 shard FEC. Each packet has one sync and four data symbols; each symbol is 576 samples, about 76.56 OFDM symbols/s. Raw stereo payload capacity is about 21.56 kbit/s before FEC and protocol overhead.
Before OFDM, a triangle-wave ADPCM race start sequence sends two short beeps, rests, then one long beep. The browser state machine displays 2, 1, and GO!, starting the timer at the long-beep onset. Stereo capture is required; mono input is rejected.
After validating DuckStation, the CUE/BIN image was burned to CD-R and tested on a physical PlayStation. The path used an EP-136 stereo audio interface: PS1 analog L/R → EP-136 stereo input → browser AudioWorklet at 44.1 kHz with AGC, noise suppression, and echo cancellation disabled.
The start sound is generated and played on the PS1 itself. It provides an audible level reference for setting capture gain, analogous to the carrier-level adjustment used by an FSK modem. FSK is not used for payload transfer; actual data is OFDM only.
The 32+4 shard Reed–Solomon layer recovers up to four missing packets per group. CRC failures trigger confidence-guided candidate search and a CRC-guided single-bit repair before the receiver stops. SPU ADPCM is block-history based 4-bit quantization, so sharp edges and block boundaries amplify error; the transmitter uses conservative amplitude, short fades, explicit end flags, and a separate SPU region for the start signal. Codex work was kept reproducible with AGENTS.md constraints, codec/loopback tests, Node checks, remote Mac Studio builds, emulator checks, and separately recorded physical-console evidence.
Each group contains up to 32 data shards and 4 parity shards. Parity uses a Cauchy matrix over GF(256) with irreducible polynomial 0x11d and coefficient 1/(r XOR (4+c)). The receiver treats CRC-failing packets as erasures, subtracts known shards from selected parity rows, solves the remaining linear system with GF(256) Gaussian elimination, and reconstructs only the missing shards byte-by-byte. Packet CRC32, block CRC32, and whole-image CRC32 are checked after recovery.
The CPU-heavy OFDM FFT, synchronization, and demodulation path is implemented in C/C++-style fixed-point code and compiled to WebAssembly (ofdm-decoder.wasm). A dedicated browser Worker invokes the WASM so the UI thread remains responsive; a JavaScript implementation of the same protocol is used as fallback when WASM is unavailable.
本项目通过模拟立体声音频,从用户拥有的初代PlayStation备份512 KiB BIOS,目标是在180秒内完成。浏览器不会上传BIOS数据,只有每个区块和整幅镜像CRC32验证通过后才允许保存。
PS1端不使用浮点运算,采用定点处理、SPU ADPCM和双缓冲DMA。数据使用44.1 kHz立体声OFDM:512点FFT、64采样循环前缀、96个载波、QPSK以及32+4分片FEC。每个数据包包含1个同步符号和4个数据符号,每符号576采样,约76.56 OFDM符号/秒;FEC和协议开销前的立体声原始容量约21.56 kbit/s。
OFDM之前发送三角波ADPCM起步信号:两个短音、休止、一个长音。浏览器状态机依次显示2、1、GO!,在长音开始时启动计时。必须使用立体声输入,单声道输入会被拒绝。
在DuckStation中确认运行后,将CUE/BIN镜像刻录到CD-R并在真实PlayStation上测试。连接使用EP-136立体声音频接口:PS1模拟L/R → EP-136立体声输入 → 浏览器44.1 kHz AudioWorklet,并关闭AGC、降噪和回声消除。
起步音由PS1端生成并播放,可作为调节输入增益的可听电平基准,作用类似FSK调制解调器中的载波电平校准。实际数据传输不使用FSK,仅使用OFDM。
使用32+4分片里德-所罗门FEC,每组最多恢复4个丢失数据包。CRC失败时先按置信度搜索候选并进行CRC引导的单比特修复,只有无法纠正时才停止。SPU ADPCM采用带块历史的4位量化,陡峭边沿和块边界更容易产生误差,因此发送端降低振幅、加入淡入淡出、明确块结束标志,并将起步信号放入独立SPU区域。Codex开发通过AGENTS.md固定约束,逐步执行编解码测试、合成回环、Node检查、Mac Studio远程构建、模拟器检查,并把真实主机证据单独记录。
每组最多包含32个数据分片和4个校验分片。校验在GF(256)上计算,使用不可约多项式0x11d和Cauchy矩阵系数 1/(r XOR (4+c))。接收端把CRC失败的数据包当作擦除,先从校验行中扣除已知分片,再用GF(256)高斯消元求解缺失分片的线性方程,并逐字节重建。恢复后依次检查数据包CRC32、区块CRC32和整幅镜像CRC32。
OFDM的FFT、同步和解调等高负载部分使用C/C++风格的定点代码,并编译为WebAssembly(ofdm-decoder.wasm)。浏览器专用Worker调用WASM以避免阻塞界面线程;WASM不可用时回退到相同协议的JavaScript实现。
-
日本語: メルカリでPlayStation 2台(SCPH-3500、SCPH-7500)、ビデオキャプチャ、オーディオケーブルを購入。総額は約1万円。CD-Rメディアはあきばおー、CD-RライタのApple USB SuperDriveはメルカリで購入した。
-
English: Two PlayStation consoles (SCPH-3500 and SCPH-7500), a video capture device, and audio cables were bought through Mercari for about ¥10,000 total. CD-R media came from Akibaoo; the Apple USB SuperDrive CD-R writer was bought through Mercari.
-
简体中文:通过Mercari购买两台PlayStation(SCPH-3500、SCPH-7500)、视频采集设备和音频线,总计约10,000日元。CD-R介质购自秋叶原的Akibaoo,Apple USB SuperDrive刻录机购自Mercari。
-
WebアプリとPlayStation側アプリはCodexで制作。掲載画像・イメージ素材はChatGPTで生成。
-
開発用MacはMacBook Neo(メモリ8GB)しかない。PS1アプリのビルドはMac Studio(512GB)で実行した。
-
The web application and PlayStation application were built with Codex. Images and visual assets were generated with ChatGPT.
-
The only development Mac was a MacBook Neo with 8 GB of memory; PS1 builds ran on a 512 GB Mac Studio.
-
Web应用和PlayStation端应用均使用Codex制作;所用图片和视觉素材由ChatGPT生成。
-
唯一的开发Mac是内存8GB的MacBook Neo;PS1构建在512GB Mac Studio上完成。
-
Concept and visual direction: はむ(@Imaha486).
-
Project: ps1-bios-audio-ripper-sx-burst-edition.
