Skip to content

Commit

Permalink
Ft sound manager (#18)
Browse files Browse the repository at this point in the history
* Add sound effects and theme

* Create Sound manager

* Update root cmakelist

* Update git lfs
  • Loading branch information
bilalkah authored Dec 18, 2024
1 parent 4da74d4 commit 72cdfdb
Show file tree
Hide file tree
Showing 11 changed files with 181 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
**/*.png filter=lfs diff=lfs merge=lfs -text
**/*.ttf filter=lfs diff=lfs merge=lfs -text
**/*.wav filter=lfs diff=lfs merge=lfs -text
**/*.mp3 filter=lfs diff=lfs merge=lfs -text
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Set the output directory for the build executables and libraries
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_THREAD_LIBS_INIT "-lpthread")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
set(CMAKE_HAVE_THREADS_LIBRARY 1)
set(CMAKE_USE_WIN32_THREADS_INIT 0)
set(CMAKE_USE_PTHREADS_INIT 1)
set(THREADS_PREFER_PTHREAD_FLAG ON)

# Set the executable name
set(EXECUTABLE wolfenstein)
Expand Down Expand Up @@ -62,6 +68,7 @@ add_subdirectory(src/NavigationManager)
add_subdirectory(src/ShootingManager)
add_subdirectory(src/Strike)
add_subdirectory(src/State)
add_subdirectory(src/SoundManager)
add_subdirectory(src/TextureManager)
add_subdirectory(src/TimeManager)
add_subdirectory(src/Utility)
Expand Down
Binary file added assets/sounds/npc_attack.wav
Binary file not shown.
Binary file added assets/sounds/npc_death.wav
Binary file not shown.
Binary file added assets/sounds/npc_pain.wav
Binary file not shown.
Binary file added assets/sounds/player_pain.wav
Binary file not shown.
Binary file added assets/sounds/shotgun.wav
Binary file not shown.
Binary file added assets/sounds/theme.mp3
Binary file not shown.
14 changes: 14 additions & 0 deletions src/SoundManager/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
add_library(
sound_manager
STATIC
src/sound_manager.cpp
)
target_include_directories(sound_manager PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include
)
target_link_libraries(
sound_manager
PUBLIC
SDL2
SDL2_mixer
)
53 changes: 53 additions & 0 deletions src/SoundManager/include/SoundManager/sound_manager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/**
* @file sound_manager.h
* @author Bilal Kahraman ([email protected])
* @brief
* @version 0.1
* @date 2024-12-12
*
* @copyright Copyright (c) 2024
*
*/

#ifndef SOUND_MANAGER_INCLUDE_SOUND_MANAGER_H
#define SOUND_MANAGER_INCLUDE_SOUND_MANAGER_H

#include <SDL2/SDL.h>
#include <SDL2/SDL_mixer.h>
#include <cstddef>
#include <string>
#include <unordered_map>
#include <vector>

namespace wolfenstein {

class SoundManager
{

public:
static SoundManager& GetInstance();

SoundManager(const SoundManager&) = delete;
SoundManager& operator=(const SoundManager&) = delete;
~SoundManager();

void InitManager();
void PlayEffect(std::string requester_id, std::string sound_effect);

private:
SoundManager() = default;
void LoadSound(const std::string sound_name, const std::string& sound_path);
void PlaySound(Mix_Chunk* sound, int channel = -1, int loops = 0);
Mix_Chunk* GetSound(std::string sound_name);

static SoundManager* instance_;
bool initialized_{false};
int channel_counter;
std::unordered_map<std::string, Mix_Chunk*> chunks_;
std::unordered_map<std::string, int> id_to_channel_;
Mix_Music* main_theme;
};

} // namespace wolfenstein

#endif // SOUND_MANAGER_INCLUDE_SOUND_MANAGER_H
105 changes: 105 additions & 0 deletions src/SoundManager/src/sound_manager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#include "SoundManager/sound_manager.h"
#include <SDL2/SDL_image.h>
#include <iostream>
#include <string>

namespace wolfenstein {

SoundManager* SoundManager::instance_ = nullptr;

SoundManager& SoundManager::GetInstance() {
if (instance_ == nullptr) {
instance_ = new SoundManager();
}
return *instance_;
}

SoundManager::~SoundManager() {
for (auto chunk : chunks_) {
Mix_FreeChunk(chunk.second);
}
Mix_FreeMusic(main_theme);
Mix_CloseAudio();
delete instance_;
}

void SoundManager::InitManager() {
if (initialized_) {
return;
}
if (SDL_Init(SDL_INIT_AUDIO) != 0) {
SDL_Log("Unable to initialize SDL: %s", SDL_GetError());
exit(EXIT_FAILURE);
}

if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0) {
std::cerr << "Failed to initialize SDL_mixer: " << Mix_GetError()
<< std::endl;
exit(EXIT_FAILURE);
}

// Allocate channels (default is 8; increase if necessary)
Mix_AllocateChannels(16);

std::string sound_path = std::string(RESOURCE_DIR) + "sounds/";
LoadSound("npc_attack", sound_path + "npc_attack.wav");
LoadSound("npc_pain", sound_path + "npc_pain.wav");
LoadSound("npc_death", sound_path + "npc_death.wav");
LoadSound("player_pain", sound_path + "player_pain.wav");
LoadSound("shotgun", sound_path + "shotgun.wav");

Mix_VolumeChunk(GetSound("npc_attack"), 32);
Mix_VolumeChunk(GetSound("npc_pain"), 32);
Mix_VolumeChunk(GetSound("npc_death"), 64);
Mix_VolumeChunk(GetSound("player_pain"), 64);
Mix_VolumeChunk(GetSound("shotgun"), 64);

std::string main_music = sound_path + "theme.mp3";
main_theme = Mix_LoadMUS(main_music.c_str());
Mix_VolumeMusic(64);

// Play the MP3 file
if (Mix_PlayMusic(main_theme, -1) == -1) {
std::cerr << "Failed to play MP3 file: " << Mix_GetError() << std::endl;
exit(EXIT_FAILURE);
}
channel_counter = 0;
initialized_ = true;
}

// keep track of the ids
void SoundManager::PlayEffect(std::string requester_id,
std::string sound_effect) {
auto channel = id_to_channel_.find(requester_id);
if (channel == id_to_channel_.end()) {
id_to_channel_.insert({requester_id, channel_counter++});
PlaySound(GetSound(sound_effect), id_to_channel_[requester_id]);
}
else {
Mix_HaltChannel(channel->second);
PlaySound(GetSound(sound_effect), id_to_channel_[requester_id]);
}
}

void SoundManager::LoadSound(const std::string sound_name,
const std::string& sound_path) {
Mix_Chunk* sound = Mix_LoadWAV(sound_path.c_str());
if (!sound) {
std::cerr << "Failed to load WAV file: " << Mix_GetError() << std::endl;
return exit(EXIT_FAILURE);
}
chunks_.insert({sound_name, sound});
}

Mix_Chunk* SoundManager::GetSound(std::string sound_name) {
return chunks_[sound_name];
}

void SoundManager::PlaySound(Mix_Chunk* sound, int channel, int loops) {
// Play the sound on the specified channel with the specified number of loops
if (Mix_PlayChannel(channel, sound, loops) == -1) {
std::cerr << "Failed to play sound: " << Mix_GetError() << std::endl;
}
}

} // namespace wolfenstein

0 comments on commit 72cdfdb

Please sign in to comment.