#pragma once #include #include #include #include #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. };