Skip to content

Commit

Permalink
Add music loading and playing, with storage in unique_ptrs and a mini…
Browse files Browse the repository at this point in the history
… test to GLRenderTest that'll move eventually
  • Loading branch information
SgtCoDFish committed Jul 6, 2015
1 parent dc59cf1 commit 103676b
Show file tree
Hide file tree
Showing 11 changed files with 90 additions and 35 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,6 @@ build/

/Debug-sanitize/
/Debug-GL/

assets/test_music.ogg

4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ add_library(APG-d ${APG_SOURCES})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_BASE} ${APG_RELEASE_FLAGS}")
add_library(APG ${APG_SOURCES})

if ( EXISTS "assets/test_music.ogg" )
add_definitions(-DAPG_GL_TEST_AUDIO)
endif ( EXISTS "assets/test_music.ogg" )

if ( (NOT EXCLUDE_SDL_TEST) OR (NOT EXCLUDE_GL_TEST) )
file(MAKE_DIRECTORY assets)
file(COPY ${APG_TEST_ASSETS} DESTINATION assets)
Expand Down
14 changes: 6 additions & 8 deletions include/APG/Audio.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@

namespace APG {

class SoundClip {

};

/**
* Handles everything audio related in the engine. Loaded music and sounds will persist until the manager is destroyed;
* if you're running into memory issues, you can delete sooner however.
Expand All @@ -54,8 +50,8 @@ class SoundClip {
*/
class AudioManager {
public:
using music_handle = uint32_t;
using sound_handle = uint32_t;
using music_handle = int32_t;
using sound_handle = int32_t;

static_assert(std::is_copy_constructible<music_handle>(), "Music handle type must be copy constructible.");
static_assert(std::is_copy_constructible<sound_handle>(), "Sound handle type must be copy constructible.");
Expand All @@ -76,8 +72,10 @@ class AudioManager {
virtual music_handle loadMusicFile(const std::string &filename) = 0;
virtual sound_handle loadSoundFile(const std::string &filename) = 0;

virtual void freeMusic(const music_handle &handle) = 0;
virtual void freeSound(const sound_handle &handle) = 0;
virtual void freeMusic(music_handle &handle) = 0;
virtual void freeSound(sound_handle &handle) = 0;

virtual void playMusic(const music_handle &handle) = 0;
};

}
Expand Down
13 changes: 11 additions & 2 deletions include/APG/SDLAudioManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,31 @@
#ifndef INCLUDE_APG_SDLAUDIOMANAGER_HPP_
#define INCLUDE_APG_SDLAUDIOMANAGER_HPP_

#include <unordered_map>

#include <SDL2/SDL_mixer.h>

#include "APG/SXXDL.hpp"
#include "APG/Audio.hpp"

namespace APG {

class SDLAudioManager: public AudioManager {
private:
std::unordered_map<music_handle, SXXDL::mixer::music_ptr> loadedMusic;
std::unordered_map<sound_handle, SXXDL::mixer::sound_ptr> loadedSounds;

public:
explicit SDLAudioManager(int frequency = MIX_DEFAULT_FREQUENCY, uint16_t format = MIX_DEFAULT_FORMAT);
virtual ~SDLAudioManager();

virtual music_handle loadMusicFile(const std::string &filename) override;
virtual sound_handle loadSoundFile(const std::string &filename) override;

virtual void freeMusic(const music_handle &handle) override;
virtual void freeSound(const sound_handle &handle) override;
virtual void freeMusic(music_handle &handle) override;
virtual void freeSound(sound_handle &handle) override;

virtual void playMusic(const music_handle &handle) override;
};

}
Expand Down
9 changes: 5 additions & 4 deletions include/APG/SXXDL.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SXXDL_HPP_
#define SXXDL_HPP_
#ifndef SXXDL_INCLUDE_HPP_
#define SXXDL_INCLUDE_HPP_

#include <memory>

Expand All @@ -46,11 +46,12 @@ renderer_ptr make_renderer_ptr(SDL_Renderer *renderer);

namespace mixer {

using sound_ptr = std::unique_ptr<Mix_Chunk, void (*)(Mix_Chunk *)>;

using music_ptr = std::unique_ptr<Mix_Music, void(*)(Mix_Music *)>;
using sound_ptr = std::unique_ptr<Mix_Chunk, void (*)(Mix_Chunk *)>;

sound_ptr make_sound_ptr(Mix_Chunk *chunk);
music_ptr make_music_ptr(Mix_Music *music);
sound_ptr make_sound_ptr(Mix_Chunk *chunk);

}

Expand Down
4 changes: 4 additions & 0 deletions include/test/APGGLRenderTest.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ class APGGLRenderTest final : public APG::SDLGame {
std::vector<Sprite> playerFrames;
std::unique_ptr<AnimatedSprite> playerAnimation;

#ifdef APG_GL_TEST_AUDIO
AudioManager::music_handle testHandle = -1;
#endif

public:
explicit APGGLRenderTest(const std::string &windowTitle, uint32_t windowWidth, uint32_t windowHeight,
uint32_t glContextMajor = 3, uint32_t glContextMinor = 2, uint32_t windowX = SDL_WINDOWPOS_CENTERED, uint32_t windowY = SDL_WINDOWPOS_CENTERED) :
Expand Down
6 changes: 3 additions & 3 deletions src/Audio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,15 @@ APG::AudioManager::music_handle APG::AudioManager::getNextMusicHandle() {
APG::AudioManager::sound_handle APG::AudioManager::getNextSoundHandle() {
const auto retval = availableSoundHandles.front();
availableSoundHandles.pop_front();
return retval;;
return retval;
}

void APG::AudioManager::fillDefaultQueues() {
for(music_handle i = 0u; i < 256u; ++i) {
for(music_handle i = 0; i < 256; ++i) {
availableMusicHandles.push_back(i);
}

for(sound_handle i = 0u; i < 256u; ++i) {
for(sound_handle i = 0; i < 256; ++i) {
availableSoundHandles.push_back(i);
}
}
30 changes: 23 additions & 7 deletions src/SDLAudioManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,21 @@ APG::AudioManager::music_handle APG::SDLAudioManager::loadMusicFile(const std::s
const auto logger = el::Loggers::getLogger("default");
logger->info("Loading music file \"%v\".", filename);

const auto handle = getNextMusicHandle();
auto sdlMusic = SXXDL::mixer::make_music_ptr(Mix_LoadMUS(filename.c_str()));

// LOAD
if (sdlMusic == nullptr) {
logger->fatal("Couldn't load \"%v\", error: %v.", filename, Mix_GetError());
return -1;
} else {
const auto handle = getNextMusicHandle();
logger->info("Loaded \"%v\" at handle %v.", filename, handle);

return handle;
loadedMusic.emplace(handle, std::move(sdlMusic));

logger->verbose(9, "Total loaded music files: %v", loadedMusic.size());

return handle;
}
}

APG::AudioManager::sound_handle APG::SDLAudioManager::loadSoundFile(const std::string &filename) {
Expand All @@ -65,10 +75,16 @@ APG::AudioManager::sound_handle APG::SDLAudioManager::loadSoundFile(const std::s
return handle;
}

void APG::SDLAudioManager::freeMusic(const music_handle &handle) {
// FREE
void APG::SDLAudioManager::freeMusic(music_handle &handle) {
loadedMusic.erase(handle);
handle = -1;
}

void APG::SDLAudioManager::freeSound(sound_handle &handle) {
handle = -1;
}

void APG::SDLAudioManager::freeSound(const sound_handle &handle) {
// FREE
void APG::SDLAudioManager::playMusic(const music_handle &handle) {
const auto &song = loadedMusic.find(handle);
Mix_PlayMusic((*song).second.get(), 0);
}
13 changes: 4 additions & 9 deletions src/SDLGame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,8 @@ APG::SDLGame::SDLGame(const std::string &windowTitle, uint32_t windowWidth, uint
inputManager = std::make_unique<SDLInputManager>();
audioManager = std::make_unique<SDLAudioManager>();

const auto sdlWindow = SDL_CreateWindow(windowTitle.c_str(), windowX, windowY, windowWidth, windowHeight,
SDL_WINDOW_FLAGS);

if (sdlWindow == nullptr) {
logger->fatal("Couldn't create window: %v", SDL_GetError());
}

window = SXXDL::make_window_ptr(sdlWindow);
window = SXXDL::make_window_ptr(
SDL_CreateWindow(windowTitle.c_str(), windowX, windowY, windowWidth, windowHeight, SDL_WINDOW_FLAGS));

if (window == nullptr) {
logger->fatal("Couldn't create SDL window: %v", SDL_GetError());
Expand All @@ -98,12 +92,13 @@ APG::SDLGame::SDLGame(const std::string &windowTitle, uint32_t windowWidth, uint
glewExperimental = GL_TRUE;
glewInit();

logger->verbose(9, "OpenGL errors have been reset (probably as a workaround for any bugs with glew)");
// reset all errors because some are caused by glew even upon successful setup.
auto error = glGetError();
while (error != GL_NO_ERROR) {
error = glGetError();
}

logger->verbose(9, "OpenGL errors have been reset (probably as a workaround for any bugs with glew)");
}

APG::SDLGame::~SDLGame() {
Expand Down
9 changes: 8 additions & 1 deletion src/SXXDL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <SDL2/SDL.h>
#include <SDL2/SDL_mixer.h>

#include "easylogging++.h"

#include "APG/SXXDL.hpp"

SXXDL::window_ptr SXXDL::make_window_ptr(SDL_Window *window) {
Expand All @@ -48,6 +53,8 @@ SXXDL::mixer::sound_ptr SXXDL::mixer::make_sound_ptr(Mix_Chunk *chunk) {
}

SXXDL::mixer::music_ptr SXXDL::mixer::make_music_ptr(Mix_Music *music) {
// el::Loggers::getLogger("default")->info("Creating music_ptr!");
// return music_ptr(music,
// [](Mix_Music *music) {el::Loggers::getLogger("default")->info("Freeing music_ptr!"); Mix_FreeMusic(music);});
return music_ptr(music, Mix_FreeMusic);
}

20 changes: 19 additions & 1 deletion test/APGGLRenderTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ bool APG::APGGLRenderTest::init() {
return false;
}

#ifdef APG_GL_TEST_AUDIO
logger->info("Note: audio test enabled. Use P and SPACE to test.");
#endif

return true;
}

Expand Down Expand Up @@ -120,6 +124,20 @@ void APG::APGGLRenderTest::render(float deltaTime) {
playerX += 32.0f;
}

#ifdef APG_GL_TEST_AUDIO
if(inputManager->isKeyJustPressed(SDL_SCANCODE_P)) {
if(testHandle == -1) {
testHandle = audioManager->loadMusicFile("assets/test_music.ogg");
} else {
audioManager->freeMusic(testHandle);
}
}

if (inputManager->isKeyJustPressed(SDL_SCANCODE_SPACE) && testHandle != -1) {
audioManager->playMusic(testHandle);
}
#endif

spriteBatch->begin();
spriteBatch->draw(playerAnimation.get(), playerX, playerY);
spriteBatch->end();
Expand Down Expand Up @@ -159,7 +177,7 @@ int main(int argc, char *argv[]) {

const float fps = 1 / (sum / timesTaken.size());

el::Loggers::getLogger("default")->info("FPS: ", fps);
el::Loggers::getLogger("default")->info("FPS: %v", fps);

timesTaken.clear();
}
Expand Down

0 comments on commit 103676b

Please sign in to comment.