ICT290 / src / engine / audio.h
audio.h
Raw
#pragma once
#include <irrKlang.h>
#include <glm/glm.hpp>
#include <string>
#include <utility>

#define AUDIO_RES_PATH "../res/audio/"

/**
 * @struct Sound
 * @brief A struct with constructors to create single sound objects that can be
 * played by the audio manager class.
 *
 * @author Chase Percy
 *
 */
struct Sound {
    std::string filename{};  /// The file name with extension of the audio file.
    bool loop{false};        /// If the sound should repeat.
    float volume{100};       /// The volume of the sound.
    bool is3D{false};        /// If a sound is 3D.
    glm::vec3 position{};    /// The location of a sound if 3D.
    float soundRadius{10};   /// The loudness of the sound in 3D

    /**
     * Create a 3D sound struct to be played later.
     * @param filename_ the name of the file to play (no pathing)
     *     is moved, so string will be empty after calling this fn
     * @param loop_ true to loop sound, false otherwise.
     * @param volume_ how loud the sound is 0 - 100.
     * @param is3D_ true if the sound is 3D else false for 2D.
     * @param position_ The location of the sound if it's 3D.
     * @param soundRadius_ The loudness of the sound
     */
    Sound(std::string filename_,
          bool loop_,
          float volume_,
          bool is3D_,
          glm::vec3 position_,
          float soundRadius_)
        : filename(std::move(filename_)),
          loop(loop_),
          volume(volume_),
          is3D(is3D_),
          position(position_),
          soundRadius(soundRadius_) {}

    /**
     * Create a 2D sound struct to be played later.
     * @param filename_ the name of the file to play (no pathing)
     *     is moved, so string will be empty after calling this fn
     * @param loop_ true to loop sound, false otherwise.
     * @param volume_ how loud the sound is 0 - 100.
     */
    Sound(std::string filename_, bool loop_, float volume_)
        : filename(std::move(filename_)),
          loop(loop_),
          volume(volume_) {}
};

/**
 * @class AudioManager
 * @brief Wraps the irrKlang audio library with a class to make using easier and
 * reduce code overhead in the scenes.
 *
 * @author Chase Percy
 *
 */
class AudioManager {
   public:
    AudioManager();
    ~AudioManager();

    /**
     * Plays a sound
     * @param sound the sound struct with the sound data to play
     */
    void playSound(const Sound& sound);

    /**
     * Sets the listener position (usually the camera).
     * @param location the location of the listener.
     * @param lookDirection the direction the listener is looking.
     * @warning internally will set lookDirection to a negative value, if your
     * sound is the wrong way around just pass a negative vec in.
     */
    void setListener(const glm::vec3& location, const glm::vec3& lookDirection);

    /**
     * Stops all sounds playing immediately.
     */
    void stopAllSounds();

    /**
     * Sets the master volume from which all sounds are multiplied by.
     * Takes values between 0 - 100 anything higher or less will be set to 100
     * or 0 respectively.
     * @param volume the volume to set between 0 - 100
     */
    void setMasterVolume(float volume);

    /**
     * Returns the current master volume.
     * @return the current master volume.
     */
    float getMasterVolume() const;

    /**
     * Pauses or unpauses all currently played sounds.
     * @param pause the bool to pause or unpause the sounds.
     */
    void pauseSounds(bool pause);

    /**
     * Returns if the audio engine is paused.
     * @return true if paused, false if not.
     */
    bool isPaused() const;

    /**
     * Mutes or unmute all current sound, but doesn't stop it from playing.
     * Retains master volume from before mute.
     */
    void toggleMute();

    /**
     * Returns if the audio engine is muted.
     * @return true if muted, else false if not.
     */
    bool isMuted() const;

    /**
     * Sets the audio manager to equal the mute bool.
     * @param mute the mute option
     */
    void setMute(bool mute);

   private:
    irrklang::ISoundEngine* m_audio;  /// The audio engine
    float m_masterVolume{
        80.f};  /// The master volume, all sounds are multiplied by this value.
    bool m_paused{false};  /// True if the audioManager is paused, else false.
    bool m_muted{false};   /// true if the audioManager is muted, else false.
};