#!/usr/bin/env python3 """Extract the audio of a Blu-ray window as mono PCM at an MSM6258 sample rate. The video side of this window is tools/encoder/extract.py; the arguments mean the same things and are meant to be given the same values, because an audio stream that is not the same seconds as the frames is not this project's audio. The disc is AC-3 5.1 at 48 kHz. The arcade original is MONO, so this downmixes -- ffmpeg's default matrix, dialogue from the centre channel included -- and resamples to the chip's rate. Nothing here shapes, gates or normalises the level: what the ADPCM encoder is handed is what the disc has, so that the SNR it reports is the codec's and not a gain stage's. """ import getpass, os, subprocess, sys BDROM = os.environ.get("DLX_BDROM") or f"/media/{getpass.getuser()}/BDROM" STREAM_DIR = f"{BDROM}/BDMV/STREAM" # 8 MHz / {512, 768, 1024}. The chip has no other rates and 15,625 is the one # every budget in this project is written against (FINDINGS 52). RATES = {15625: 512, 10417: 768, 7813: 1024} def extract(stream, out, rate=15625, start=None, dur=None): if rate not in RATES: raise SystemExit(f"{rate} is not an MSM6258 rate: {sorted(RATES)}") src = f"{STREAM_DIR}/{stream}.m2ts" cmd = ["ffmpeg", "-v", "error"] if start is not None: cmd += ["-ss", str(start)] if dur is not None: cmd += ["-t", str(dur)] cmd += ["-i", src, "-vn", "-ac", "1", "-ar", str(rate), "-f", "s16le", "-acodec", "pcm_s16le", out, "-y"] subprocess.check_call(cmd) n = os.path.getsize(out) // 2 print(f"{stream}: {n} samples @ {rate} Hz mono = {n/rate:.3f} s -> {out}") return n if __name__ == "__main__": # extract_audio.py [rate] [start_s] [dur_s] stream, out = sys.argv[1], sys.argv[2] rate = int(sys.argv[3]) if len(sys.argv) > 3 else 15625 start = float(sys.argv[4]) if len(sys.argv) > 4 else None dur = float(sys.argv[5]) if len(sys.argv) > 5 else None extract(stream, out, rate, start, dur)