Audio Manager - UQcsse3200/2024-studio-2 GitHub Wiki

Overview/Description

The AudioManager class is a centralized service responsible for handling all the audio-related functionality in the game, including managing background music, sound effects, and global mute/unmute functionality. This class interacts with the ServiceLocator to retrieve the appropriate audio resources and manage their playback. It ensures that both music and sound effects are played according to the user’s settings (e.g., volume, mute).

Features

Global Audio Control:

The AudioManager provides a single point to control all game-related audio (music and sound effects) through methods like play, stop, mute, and volume adjustment.

Persistent Volume Settings:

The audio manager saves user-specified volumes for both music and sound, even when muted, allowing audio to resume with the same levels when unmuted.

Music and Sound Effects:

It can handle playing background music and sound effects in parallel, ensuring that they are managed independently. Global Mute Functionality: A convenient method to globally mute all music and sound effects and restore them to their previous volume levels when unmuted.

Key Features (In-Depth Explanation)

Music and Sound Management:

The AudioManager provides methods to play, stop, and control the volume of background music and sound effects. Both are managed independently, so sound effects can continue even if music is stopped or vice versa.

For example, to play background music:

public static void playMusic(String musicPath, boolean looping) {
    Music music = ServiceLocator.getResourceService().getAsset(musicPath, Music.class);
    if (music != null) {
        music.setVolume(musicVolume);
        music.setLooping(looping);
        music.play();
        currentMusic = music;
    }
}

This method retrieves the music asset from the ResourceService, sets the volume and looping state, and starts playback. The current music is stored in the currentMusic variable to manage it later (e.g., stop or change volume).

public static void playSound(String soundPath) {
    Sound sound = ServiceLocator.getResourceService().getAsset(soundPath, Sound.class);
    if (sound != null) {
        long id = sound.play(soundVolume);
        soundInstances.put(sound, id); // Track sound instance for further control (e.g., stop)
    }
}

The playSound() method follows a similar process, playing sound effects at the current soundVolume.

Mute and Unmute Functionality

The AudioManager includes global mute functionality, which allows you to mute all audio (both music and sound) with a single command. The previous volume levels are preserved when muting so that they can be restored upon unmuting.

Design Decisions

Modular Approach for Audio Control

The AudioManager centralizes all audio-related tasks, making it easy to control and modify audio behavior throughout the game. By separating the management of music and sound effects, the AudioManager provides flexibility in controlling background music and game sounds independently.

Persistent Volume Management

The decision to store user-specified volume levels even when the audio is muted ensures that users experience a smooth transition when toggling mute. This is done by keeping track of both desiredMusicVolume and desiredSoundVolume.

Separation of Music and Sound

Rather than treating music and sound effects as the same, they are handled independently. This allows for background music to continue playing during gameplay, while individual sound effects (e.g., footsteps, attack sounds) can be played and stopped without affecting the background music.

Example Usage

Playing background music

AudioManager.playMusic("path/to/music.ogg", true); // Play and loop background music

Playing a sound effect

AudioManager.playSound("path/to/sound.wav"); // Play a sound effect

Muting all audio

AudioManager.muteAudio(); // Mute all game audio

Unmute all audio

AudioManager.unmuteAudio(); // Unmute all game audio and restore volume

Setting music volume

AudioManager.setMusicVolume(0.5f); // Set music volume to 50%

Stopping background music

AudioManager.stopMusic(); // Stop currently playing music

Testing:

jUnit testing is conducted through the AudioMangerTest in the game, as mentioned in the following page:

AudioManager Testing

Sequence Diagrams: AudioManager Interaction

Basic AudioManager Interaction

The following sequence diagram demonstrates the basic interactions between the AudioManager, ServiceLocator, ResourceService, and the assets for both sound effects and music. It illustrates how sounds and music are played, stopped, and managed independently.

Basic Sequence Diagram: Playing and Stopping Music and Sound Effects

image

Explanation

This basic sequence diagram showcases the fundamental audio operations: playing and stopping sounds and music using the AudioManager.

Key Interactions:

  1. Playing Sound:

    • The AudioManager requests the ResourceService to load the sound asset.
    • Once the asset is retrieved, the AudioManager plays the sound at the current soundVolume.
    • The sound instance ID is saved, allowing it to be referenced later (for stopping or adjusting the sound).
  2. Stopping Sound:

    • The AudioManager retrieves the sound asset again using the ResourceService.
    • The sound is stopped using the saved instance ID, ensuring only the specific sound is halted.
  3. Playing Music:

    • Similar to sound, the AudioManager retrieves the music asset via ResourceService.
    • The music volume and looping settings are configured based on user settings before the playback starts.
  4. Stopping Music:

    • The currently playing music is stopped through the stop() method on the Music instance.

Advanced Sequence: Playing Music, Applying Settings, and Muting

Sequence Diagram

image (Replace with a link to the image of the diagram)

Explanation

This advanced sequence diagram delves deeper into how the AudioManager handles background music, audio settings, and mute/unmute functionality.

Key Interactions:

  1. Playing Music in a Game Area:

    • The game area (e.g., ForestGameArea) requests the UserSettings to retrieve the selected music track.
    • The AudioManager then plays the chosen track by retrieving it through the ServiceLocator and ResourceService.
    • The music is set to loop, and the volume is set according to the user's settings.
  2. Pausing Music:

    • The game area calls the AudioManager.stopMusic() method, which directly stops the current Music instance.
  3. Applying Audio Settings:

    • The game area retrieves user settings, such as audio and sound scales.
    • If the game is muted, both music and sound volumes are set to 0.
    • If unmuted, the last saved volumes for both music and sound are restored, ensuring a seamless transition.
  4. Muting and Unmuting Audio:

    • The AudioManager stores the current music and sound volumes before muting.
    • When unmuting, these saved volumes are restored to provide a consistent audio experience.

Why a Sequence Diagram?

The sequence diagrams serve as a visual representation of how the AudioManager interacts with various game systems and assets during common operations. They clarify the flow of information and methods between components like ServiceLocator, ResourceService, UserSettings, and audio assets (e.g., Music and Sound).

By breaking down these operations into simple and advanced flows, the diagrams demonstrate how the AudioManager efficiently manages audio playback and settings, ensuring smooth transitions between different states (e.g., playing, muting, stopping).

  • Basic Sequence: Covers essential audio functionality (play, stop).
  • Advanced Sequence: Includes more complex scenarios involving settings and mute/unmute behavior.