Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Juan-Carlos-Cruz/robotaxi-zoox/llms.txt

Use this file to discover all available pages before exploring further.

The AudioManager class in application/audio.py wraps pygame.mixer to provide a layered audio experience: a looping background ambient track plays from the moment the application starts, a separate looping engine sound plays only while the taxi is animating its route, and a set of discrete event effects fire in response to specific gameplay moments. All three layers are mixed in real time across dedicated channels, and the ambient volume automatically ducks when the drive loop is active to prevent the tracks from competing for prominence.

Audio assets

All audio files live in the audio/ directory at the project root. Each file is loaded at startup by _load_assets and registered under a string key in AudioManager.sounds.
FileKeyRole
lofi_ambient.wav(music channel)Background ambient music that loops continuously throughout the session. Loaded via pygame.mixer.music rather than a sound channel so it can be faded and toggled independently.
road_loop.wavroad_loopEngine/driving sound that loops on a dedicated channel while the taxi is animating its route. Starts with a 250 ms fade-in and stops with a 250 ms fade-out.
pickup_horn.wavpickup_hornShort horn effect that fires once each time the taxi enters a cell that contains a passenger.
traffic_horn.wavtraffic_hornDistinct horn effect triggered when the taxi enters a FLUJO_ALTO (high-traffic) cell.
ui_click.wavui_clickSubtle click sound played on every button press throughout the interface.
finish_jingle.wavfinish_jingleShort celebratory melody that plays when the animation completes and the results modal opens.

Volume levels

AudioManager sets each sound’s volume at load time using the module-level constants defined in audio.py. Volumes are expressed as floats between 0.0 (silence) and 1.0 (full).
ConstantValueApplied to
AMBIENT_VOLUME0.24Background ambient music at rest (not driving).
DRIVE_VOLUME0.28road_loop channel during taxi animation.
PICKUP_HORN_VOLUME0.28pickup_horn effect.
TRAFFIC_HORN_VOLUME0.24traffic_horn effect.
UI_CLICK_VOLUME0.22ui_click effect.
FINISH_JINGLE_VOLUME0.3finish_jingle effect.
DUCKED_AMBIENT_VOLUME0.16Ambient music level while the drive loop is active — lower than AMBIENT_VOLUME to prevent both tracks from clashing.
The ambient volume switches automatically between AMBIENT_VOLUME and DUCKED_AMBIENT_VOLUME via _ambient_volume_target, which is called whenever start_drive_loop or stop_drive_loop adjusts the music channel.

Ambient music toggle

The Ambiente On/Off button in the header bar lets users enable or disable the background ambient track at any time without affecting the drive loop or any event effects. The button label reflects the current state:
  • Ambiente On — ambient music is currently playing (button highlighted).
  • Ambiente Off — ambient music has been muted by the user.
  • Ambiente N/D — displayed when AudioManager.enabled is False, meaning the mixer could not be initialised. The button is still rendered but clicking it has no effect.
Toggling the button calls set_ambient_enabled, which either fades out the music over 250 ms and sets ambient_started = False, or restarts it via play_ambient with a 900 ms fade-in. The drive loop and event effects are unaffected by this toggle.

Graceful fallback

AudioManager.__init__ calls _init_mixer, which wraps the entire pygame.mixer initialisation in a try/except pygame.error block. If the mixer cannot start — for example on a headless server without an audio device — the exception is caught, a message is printed to standard output, and self.enabled is set to False.
try:
    if pygame.mixer.get_init() is None:
        pygame.mixer.init(frequency=22050, size=-16, channels=2, buffer=512)
    pygame.mixer.set_num_channels(8)
    self.drive_channel = pygame.mixer.Channel(1)
    self.effect_channels = [pygame.mixer.Channel(2), pygame.mixer.Channel(3)]
    self.enabled = True
except pygame.error as exc:
    print(f"Audio deshabilitado: {exc}")
    self.enabled = False
Every public method (play_ambient, start_drive_loop, stop_drive_loop, play_pickup_horn, play_traffic_horn, play_ui_click, play_finish_jingle, shutdown) checks self.enabled as its first action and returns immediately if it is False. The rest of the application never needs to check audio availability — it simply calls the AudioManager methods unconditionally and they become silent no-ops when audio is unavailable.

Regenerating audio assets

The WAV files are generated programmatically by a helper script:
python3 scripts/generate_audio_assets.py
Running this script recreates all files in the audio/ directory using synthetic waveforms.
The audio assets are committed to the repository alongside the source code. Regeneration is only necessary if the files in audio/ have been deleted or become corrupted. Under normal circumstances you do not need to run this script.

Build docs developers (and LLMs) love