From 38bdea0c2adb80101ed488d51a0a29f316f93030 Mon Sep 17 00:00:00 2001 From: KoyoNoguchi Date: Mon, 5 Oct 2026 15:50:03 +0900 Subject: [PATCH] =?UTF-8?q?=E7=B2=BE=E5=BA=A6=E5=AE=9F=E9=A8=93=E7=94=A8?= =?UTF-8?q?=E3=82=B9=E3=82=AF=E3=83=AA=E3=83=97=E3=83=88=E3=81=AB=E8=A7=92?= =?UTF-8?q?=E5=BA=A6=E7=9F=A5=E3=82=89=E3=81=9B=E6=A9=9F=E8=83=BD=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0=EF=BC=8E=20=E5=9B=9E=E9=A0=AD=E6=99=82?= =?UTF-8?q?=E9=96=93=E3=81=AE=E3=83=87=E3=83=95=E3=82=A9=E3=83=AB=E3=83=88?= =?UTF-8?q?=E3=82=92accuracy=5Freport.py=E3=81=AB=E5=8F=8D=E6=98=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/accuracy_report.py | 2 +- src/accuracy_session.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/accuracy_report.py b/src/accuracy_report.py index c6193d1..e48d99e 100644 --- a/src/accuracy_report.py +++ b/src/accuracy_report.py @@ -431,7 +431,7 @@ def main(argv: Sequence[str] | None = None, out=print) -> int: # type: ignore[n parser.add_argument("--out", type=Path, default=Path("data/analysis/accuracy/report")) parser.add_argument("--signal", choices=("yaw", "raw_yaw"), default="yaw") parser.add_argument("--flip-sign", action="store_true") - parser.add_argument("--settle", type=float, default=1.5, help="seconds after the cue ignored (turn in progress)") + parser.add_argument("--settle", type=float, default=3.0, help="seconds after the cue ignored (turn in progress)") parser.add_argument("--baseline-trim", type=float, default=0.5) parser.add_argument("--min-frames", type=int, default=10) parser.add_argument("--face-every", type=int, default=1, help="face.process_every_n_frames of the run") diff --git a/src/accuracy_session.py b/src/accuracy_session.py index a0d67eb..e13a2fa 100644 --- a/src/accuracy_session.py +++ b/src/accuracy_session.py @@ -44,6 +44,21 @@ INTERVAL_AUDIO = { "block": Path("assets/audio/block.wav"), "auto": Path("assets/audio/auto_interval.wav"), } +# One prepared announcement file per target yaw angle. +# Prepare these files under assets/audio/ using exactly these names. +ANGLE_AUDIO = { + 0.0: Path("assets/audio/yaw_0.wav"), + 5.0: Path("assets/audio/yaw_plus_5.wav"), + -5.0: Path("assets/audio/yaw_minus_5.wav"), + 10.0: Path("assets/audio/yaw_plus_10.wav"), + -10.0: Path("assets/audio/yaw_minus_10.wav"), + 15.0: Path("assets/audio/yaw_plus_15.wav"), + -15.0: Path("assets/audio/yaw_minus_15.wav"), + 20.0: Path("assets/audio/yaw_plus_20.wav"), + -20.0: Path("assets/audio/yaw_minus_20.wav"), + 30.0: Path("assets/audio/yaw_plus_30.wav"), + -30.0: Path("assets/audio/yaw_minus_30.wav"), +} LOGGER = logging.getLogger(__name__) DEFAULT_ANGLES = (0.0, 5.0, -5.0, 10.0, -10.0, 15.0, -15.0, 20.0, -20.0, 30.0, -30.0) PLAN_FIELDS = ["seq", "block", "condition_id", "distance_m", "true_yaw_deg", "pitch_deg", "repeat", "subject"] @@ -170,6 +185,14 @@ class IntervalAudioPlayer: self._sounds[kind] = mixer.Sound(str(path)) except Exception as exc: LOGGER.error("Failed to load interval audio %s: %s", path, exc) + for angle, path in ANGLE_AUDIO.items(): + if not path.is_file(): + LOGGER.warning("Angle announcement audio file does not exist (%+g deg): %s", angle, path) + continue + try: + self._sounds[f"angle:{angle:g}"] = mixer.Sound(str(path)) + except Exception as exc: + LOGGER.error("Failed to load angle announcement audio (%+g deg) %s: %s", angle, path, exc) except Exception as exc: LOGGER.error("Failed to initialize pygame mixer for interval audio: %s", exc) self._initialized = False @@ -186,6 +209,11 @@ class IntervalAudioPlayer: LOGGER.error("Failed to play interval audio %s: %s", kind, exc) return False + def play_angle(self, angle: float) -> bool: + """Announce the target yaw angle using the prepared per-angle WAV file.""" + key = f"angle:{angle:g}" + return self.play(key) + def close(self) -> None: if self._closed: return @@ -265,6 +293,7 @@ class SessionRunner: try: if self.auto_interval > 0 and not new_block: self.interval_audio.play("auto") + self.interval_audio.play_angle(row.true_yaw_deg) self._countdown(self.auto_interval) command = "" else: @@ -294,6 +323,7 @@ class SessionRunner: first_trial_move_pending = False elif block_change and self.block_interval > 0: self.interval_audio.play("block") + self.interval_audio.play_angle(row.true_yaw_deg) self._countdown(self.block_interval, label="moving to next block") try: stamps = self._execute(row)