Source code for src.FMOD.Banks.EnvironmentBank

# Copyright (c) 2026 Kai Braun, Ozan Miguel Gündogdu, Yeri Jikong, Sven Winkelmann
#
# SPDX-License-Identifier: MIT
#
# Licensed under the MIT License. 
# See LICENSE file in the project root for full license information.
# Also consult our README to comply with Third-Party Licenses.

import os
import time
import logging
from .config import *

os.environ["PYFMODEX_DLL_PATH"] = FMOD_CORE_DLL
os.environ["PYFMODEX_STUDIO_DLL_PATH"] = FMOD_STUDIO_DLL

import pyfmodex
from pyfmodex.studio import StudioSystem 
from pyfmodex.studio.enums import PLAYBACK_STATE
from pyfmodex.exceptions import FmodError

[docs] class EnvironmentBank: """ Interface for environmental audio assets and FMOD Studio banks. This class manages the lifecycle of environmental sound banks, including loading the 'Master' and 'Environment' banks. It instantiates and maintains persistent event instances for ambient sounds like rain and wind, allowing them to be modulated in real-time by the :class:`EnvironmentAdapter`. Attributes: studio_system (StudioSystem): The active FMOD Studio playback engine. rain_inst (EventInstance): Persistent instance for the rain audio loop. wind_inst (EventInstance): Persistent instance for the wind audio loop. """ DEFAULT_BANK_PATH = ENVIRONMENT_BANK_PATH """DEFAULT_BANK_PATH (str): The default filesystem directory containing the .bank files, sourced from the global configuration."""
[docs] def __init__(self): """ Initializes the FMOD system, loads the environment banks, and immediately starts the ambient sound instances. """ self.studio_system = None self.rain_inst = None self.wind_inst = None self.__init_studio_system() self.__init_events() self.__start_events()
def __init_studio_system(self): """ Initializes the FMOD Studio API and ensures core system drivers are properly bootstrapped. """ core_system = pyfmodex.System() core_system.init() core_system.release() self.studio_system = StudioSystem() self.studio_system.initialize(max_channels=512) def __init_events(self, bank_path=DEFAULT_BANK_PATH): """ Higher-level sequence to load bank files and prepare event instances. Args: bank_path (str, optional): The directory containing bank files. Defaults to ENVIRONMENT_BANK_PATH. """ self._load(bank_path) self._prepare_events() def _load(self, bank_path=DEFAULT_BANK_PATH): """ Loads the Master, Master.strings, and Environment banks into memory. Args: bank_path (str): The normalized path to the bank directory. Raises: FileNotFoundError: If the directory or any of the required bank files are missing. """ if bank_path is None: bank_path = self.DEFAULT_BANK_PATH bank_path = os.path.normpath(bank_path) print(f"[{self.__class__.__name__}] Resolved bank path: {bank_path}") if not os.path.isdir(bank_path): logging.error(f"Bank directory not found: {bank_path}") raise FileNotFoundError(f"Bank directory not found: {bank_path}") expected_files = [ "Master.bank", "Master.strings.bank", "Environment.bank" ] for f in expected_files: full_path = os.path.join(bank_path, f) if not os.path.exists(full_path): print(f"[{self.__class__.__name__}] Expected bank file missing: {full_path}") raise FileNotFoundError(f"Bank directory not found: {bank_path}") else: self.studio_system.load_bank_file(full_path) def _prepare_events(self): """ Retrieves event descriptions and creates instances for rain and wind. """ rain_event_desc = self.studio_system.get_event(RAIN_EVENT_PATH) self.rain_inst = rain_event_desc.create_instance() wind_event_desc = self.studio_system.get_event(WIND_EVENT_PATH) self.wind_inst = wind_event_desc.create_instance() def __start_events(self): """ Begins playback of ambient loops. """ self.rain_inst.start() self.wind_inst.start()
[docs] def update_studio_system(self): """ Synchronizes the FMOD Studio system. Must be called in main loop to apply parameter changes (intensity) to the running instances. """ self.studio_system.update()
[docs] def get_events(self): """ Provides access to the active event instances for external adapters. Returns: dict: A dictionary mapping "rain" and "wind" to their respective FMOD EventInstances. """ events = { "rain": self.rain_inst, "wind": self.wind_inst } return events
[docs] def shutdown(self): """ Releases the FMOD Studio System and stops all environmental audio. """ try: print(f'Releasing Studio System') self.studio_system.release() except AttributeError as e: e.add_note(f"Fehlerquelle: Die Instanz existiert nicht mehr") print(f"Fehler abgefangen {e}") else: print(f"Fahre herunter")