#ifndef MIXER_H_6DF82000 #define MIXER_H_6DF82000 #include #include #include #include #include #include class mix_error : public std::logic_error { public: mix_error() : std::logic_error(Mix_GetError()) { } }; class mix_wrapper { public: mix_wrapper() { if (Mix_Init(0) != 0) { mix_error ex; Mix_Quit(); throw ex; } if (Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 1024) != 0) { mix_error ex; Mix_Quit(); throw ex; } } ~mix_wrapper() { Mix_CloseAudio(); Mix_Quit(); } }; class chunk_deleter { public: void operator()(Mix_Chunk* chunk) { Mix_FreeChunk(chunk); } }; using chunk_ptr = std::unique_ptr; class music_deleter { public: void operator()(Mix_Music* music) { Mix_FreeMusic(music); } }; using music_ptr = std::unique_ptr; // MUST create the Renderer first! class Mixer { public: void playSound(std::string_view filename); int loopSound(std::string_view filename); void stopChannel(int channel); void pauseSounds(); void unpauseSounds(); int getSoundVolume() const { return std::round(static_cast(soundVolume_) / MIX_MAX_VOLUME * 10); } void setSoundVolume(int vol); // name is the name of the file, not containing the extension // ms is the time in milliseconds to fade in void playMusic(std::string_view name, int ms = 0); bool isPlayingMusic() const { return !playingTrack_.empty(); } const std::string& getPlayingTrack() const { return playingTrack_; } void fadeoutMusic(int ms); void muteMusic(); void unmuteMusic(); bool isMusicMuted() const { return musicMuted_; } int getMusicVolume() const { return std::round(static_cast(musicVolume_) / MIX_MAX_VOLUME * 10); } void setMusicVolume(int vol); void pauseMusic(); void unpauseMusic(); private: Mix_Chunk* getChunkByFilename(std::string filename); Mix_Music* getMusicByName(std::string_view name); mix_wrapper mix_; std::map sounds_; std::map music_; std::string playingTrack_; int musicVolume_ = MIX_MAX_VOLUME; bool musicMuted_ = false; int soundVolume_ = MIX_MAX_VOLUME; }; #endif /* end of include guard: MIXER_H_6DF82000 */