{"record":{"id":"ab9e99db8181c91f","repo":"3b1b/manim","slug":"adding-sound-at-timestamp-0","errorCode":null,"errorMessage":"Adding sound at timestamp < 0","messagePattern":"Adding sound at timestamp < 0","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"manimlib/scene/scene_file_writer.py","lineNumber":154,"sourceCode":"\n    def create_audio_segment(self) -> None:\n        self.audio_segment = AudioSegment.silent()\n\n    def add_audio_segment(\n        self,\n        new_segment: AudioSegment,\n        time: float | None = None,\n        gain_to_background: float | None = None\n    ) -> None:\n        if not self.includes_sound:\n            self.includes_sound = True\n            self.create_audio_segment()\n        segment = self.audio_segment\n        curr_end = segment.duration_seconds\n        if time is None:\n            time = curr_end\n        if time < 0:\n            raise Exception(\"Adding sound at timestamp < 0\")\n\n        new_end = time + new_segment.duration_seconds\n        diff = new_end - curr_end\n        if diff > 0:\n            segment = segment.append(\n                AudioSegment.silent(int(np.ceil(diff * 1000))),\n                crossfade=0,\n            )\n        self.audio_segment = segment.overlay(\n            new_segment,\n            position=int(1000 * time),\n            gain_during_overlay=gain_to_background,\n        )\n\n    def add_sound(\n        self,\n        sound_file: str,\n        time: float | None = None,","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/3b1b/manim/blob/dee01804d47b9f94402d71472674710dcac125b8/manimlib/scene/scene_file_writer.py#L136-L172","documentation":"SceneFileWriter.add_audio_segment overlays a new AudioSegment onto the growing soundtrack at a given timestamp. If the requested time is negative, overlay position would be meaningless, so the writer raises an Exception. This is the plumbing behind scene.add_sound(..., time=...).","triggerScenarios":"Calling self.add_sound('clip.mp3', time=-1) or any negative timestamp; computing a timestamp from an animation start time that evaluates negative (e.g. subtracting wrong run_time, or a time_offset variable that went below zero).","commonSituations":"Synchronizing sounds to animations where the offset is computed as start_time - accumulated_time and underflows; passing a time earlier than the clip start; refactoring code that used seconds vs frames inconsistently.","solutions":["Pass time=None to append the sound at the current end of the audio track","Clamp the computed timestamp: max(0, t)","Fix the timestamp arithmetic (usually a wrong subtraction order when computing when a sound should start)"],"exampleFix":"# before\nself.add_sound(\"chime.wav\", time=start - delay)  # start - delay < 0\n# after\nself.add_sound(\"chime.wav\", time=max(0, start - delay))","handlingStrategy":"validation","validationCode":"t = max(0.0, float(computed_time)) if computed_time is not None else None\nself.add_sound(\"clip.wav\", time=t)","typeGuard":null,"tryCatchPattern":"try:\n    self.add_sound(sound, time=t)\nexcept Exception as e:\n    if \"timestamp\" in str(e):\n        self.add_sound(sound, time=None)  # append at end\n    else:\n        raise","preventionTips":["Compute sound offsets from scene.time or self.renderer.time, never hand-subtracted constants","Assert offsets are non-negative right after computing them in your scene helpers"],"tags":["audio","scene","file-writer","validation"],"backgroundTag":null,"analyzedSha":"dee01804d47b9f94402d71472674710dcac125b8","analyzedAt":"2026-08-14T19:53:44.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}