diff --git a/cmakeaudioplayer/include/AudioPlayer.hpp b/cmakeaudioplayer/include/AudioPlayer.hpp index c8e2d12..b1d23f1 100644 --- a/cmakeaudioplayer/include/AudioPlayer.hpp +++ b/cmakeaudioplayer/include/AudioPlayer.hpp @@ -12,18 +12,26 @@ public: AudioPlayer(); ~AudioPlayer(); - bool playFromSoundsDir(const std::string& filename); + // Для музыки с зацикливанием (если filename пустой - продолжает играть текущую) + bool playMusic(const std::string& filename = ""); + + // Для одноразовых звуковых эффектов + bool playSound(const std::string& filename); + void stop(); bool isPlaying() const; private: ALCdevice* device; ALCcontext* context; - ALuint source; - ALuint buffer; + ALuint musicSource; // Источник для музыки + ALuint soundSource; // Источник для звуков + ALuint musicBuffer; // Буфер для музыки + ALuint soundBuffer; // Буфер для звуков bool playing; + std::string currentMusic; // Хранит имя текущего музыкального файла - std::vector loadOgg(const std::string& filename); + std::vector loadOgg(const std::string& filename, ALuint buffer); std::string findFileInSounds(const std::string& filename); bool isOggFile(const std::string& filename) const; }; diff --git a/cmakeaudioplayer/src/AudioPlayer.cpp b/cmakeaudioplayer/src/AudioPlayer.cpp index 4d37c27..e650ea9 100644 --- a/cmakeaudioplayer/src/AudioPlayer.cpp +++ b/cmakeaudioplayer/src/AudioPlayer.cpp @@ -6,7 +6,8 @@ #include #include -AudioPlayer::AudioPlayer() : device(nullptr), context(nullptr), source(0), buffer(0), playing(false) { +AudioPlayer::AudioPlayer() : device(nullptr), context(nullptr), + musicSource(0), soundSource(0), musicBuffer(0), soundBuffer(0), playing(false) { device = alcOpenDevice(nullptr); if (!device) { throw std::runtime_error("Failed to open audio device"); @@ -19,15 +20,21 @@ AudioPlayer::AudioPlayer() : device(nullptr), context(nullptr), source(0), buffe } alcMakeContextCurrent(context); - alGenSources(1, &source); - alGenBuffers(1, &buffer); + alGenSources(1, &musicSource); + alGenSources(1, &soundSource); + alGenBuffers(1, &musicBuffer); + alGenBuffers(1, &soundBuffer); } AudioPlayer::~AudioPlayer() { - if (source) - alDeleteSources(1, &source); - if (buffer) - alDeleteBuffers(1, &buffer); + if (musicSource) + alDeleteSources(1, &musicSource); + if (soundSource) + alDeleteSources(1, &soundSource); + if (musicBuffer) + alDeleteBuffers(1, &musicBuffer); + if (soundBuffer) + alDeleteBuffers(1, &soundBuffer); if (context) { alcMakeContextCurrent(nullptr); @@ -72,7 +79,7 @@ std::string AudioPlayer::findFileInSounds(const std::string& filename) { throw std::runtime_error("❌ File not found: " + filename); } -std::vector AudioPlayer::loadOgg(const std::string& filename) { +std::vector AudioPlayer::loadOgg(const std::string& filename, ALuint buffer) { FILE* file = fopen(filename.c_str(), "rb"); if (!file) { throw std::runtime_error("Cannot open file: " + filename); @@ -108,45 +115,79 @@ std::vector AudioPlayer::loadOgg(const std::string& filename) { return audioData; } -bool AudioPlayer::playFromSoundsDir(const std::string& filename) { +bool AudioPlayer::playMusic(const std::string& filename) { try { + // Если filename пустой, просто проверяем играет ли музыка + if (filename.empty()) { + if (!isPlaying()) { + alSourcei(musicSource, AL_LOOPING, AL_TRUE); // Включаем зацикливание + alSourcePlay(musicSource); + } + return true; + } + + // Если filename не пустой, загружаем новую музыку if (!isOggFile(filename)) { - std::cerr << "❌ Error: File must be an .ogg file\n"; + std::cerr << "❌ Error: Music file must be an .ogg file\n"; return false; } std::string fullPath = findFileInSounds(filename); - std::cout << "✅ Found file: " << fullPath << "\n"; + std::cout << "✅ Found music file: " << fullPath << "\n"; - auto audioData = loadOgg(fullPath); - alSourcei(source, AL_BUFFER, buffer); + // Останавливаем текущую музыку + alSourceStop(musicSource); - alGetError(); // Clear any previous errors + // Загружаем и настраиваем новую музыку + loadOgg(fullPath, musicBuffer); + alSourcei(musicSource, AL_BUFFER, musicBuffer); + alSourcei(musicSource, AL_LOOPING, AL_TRUE); // Включаем зацикливание - std::cout << "▶️ Starting playback...\n"; - alSourcePlay(source); - - ALenum error = alGetError(); - if (error != AL_NO_ERROR) { - std::cerr << "❌ OpenAL error: " << error << std::endl; - return false; - } + std::cout << "▶️ Starting music playback...\n"; + alSourcePlay(musicSource); + currentMusic = filename; playing = true; return true; } catch (const std::exception& e) { - std::cerr << "❌ Error: " << e.what() << std::endl; + std::cerr << "❌ Error playing music: " << e.what() << std::endl; + return false; + } +} + +bool AudioPlayer::playSound(const std::string& filename) { + try { + if (!isOggFile(filename)) { + std::cerr << "❌ Error: Sound file must be an .ogg file\n"; + return false; + } + + std::string fullPath = findFileInSounds(filename); + std::cout << "✅ Found sound file: " << fullPath << "\n"; + + // Загружаем и настраиваем звук + loadOgg(fullPath, soundBuffer); + alSourcei(soundSource, AL_BUFFER, soundBuffer); + alSourcei(soundSource, AL_LOOPING, AL_FALSE); // Выключаем зацикливание + + std::cout << "▶️ Playing sound effect...\n"; + alSourcePlay(soundSource); + + return true; + } catch (const std::exception& e) { + std::cerr << "❌ Error playing sound: " << e.what() << std::endl; return false; } } void AudioPlayer::stop() { - alSourceStop(source); + alSourceStop(musicSource); + alSourceStop(soundSource); playing = false; } bool AudioPlayer::isPlaying() const { ALint state; - alGetSourcei(source, AL_SOURCE_STATE, &state); + alGetSourcei(musicSource, AL_SOURCE_STATE, &state); return state == AL_PLAYING; } diff --git a/main.cpp b/main.cpp index d2013ff..33f4340 100755 --- a/main.cpp +++ b/main.cpp @@ -402,8 +402,11 @@ namespace ZL std::cout << "\nAfter removal:\n"; ZL::PrintInventory(); - // Initialize audio player + // Initialize audio player and start background music GameObjects::audioPlayer = std::make_unique(); + if (GameObjects::audioPlayer) { + GameObjects::audioPlayer->playMusic("Symphony No.6 (1st movement).ogg"); + } /// } @@ -457,25 +460,37 @@ namespace ZL case SDLK_LEFT: case SDLK_a: Env::leftPressed = true; + if (GameObjects::audioPlayer) { + GameObjects::audioPlayer->playSound("Звук-Идут-по-земле.ogg"); + } break; case SDLK_RIGHT: case SDLK_d: Env::rightPressed = true; + if (GameObjects::audioPlayer) { + GameObjects::audioPlayer->playSound("Звук-Идут-по-земле.ogg"); + } break; case SDLK_UP: case SDLK_w: Env::upPressed = true; + if (GameObjects::audioPlayer) { + GameObjects::audioPlayer->playSound("Звук-Идут-по-земле.ogg"); + } break; case SDLK_DOWN: case SDLK_s: Env::downPressed = true; + if (GameObjects::audioPlayer) { + GameObjects::audioPlayer->playSound("Звук-Идут-по-земле.ogg"); + } break; case SDLK_SPACE: // Play the symphony when space is pressed if (GameObjects::audioPlayer) { - GameObjects::audioPlayer->playFromSoundsDir("Symphony No.6 (1st movement).ogg"); - } - break; + GameObjects::audioPlayer->playMusic("Symphony No.6 (1st movement).ogg"); + } + break; } } diff --git a/sounds/Звук-Идут-по-земле.ogg b/sounds/Звук-Идут-по-земле.ogg new file mode 100644 index 0000000..fca9763 Binary files /dev/null and b/sounds/Звук-Идут-по-земле.ogg differ