From 4c0869841d9ee6f8cc567b3e9eb2249193fc9f83 Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Thu, 12 Mar 2015 16:43:49 -0400 Subject: Play a sound when you jump --- CMakeLists.txt | 6 ++- cmake/FindLibSndFile.cmake | 23 ++++++++++ cmake/FindPortaudio.cmake | 106 +++++++++++++++++++++++++++++++++++++++++++ res/Randomize87.wav | Bin 47368 -> 29620 bytes src/components.cpp | 3 ++ src/game.cpp | 2 +- src/main.cpp | 3 ++ src/muxer.cpp | 111 +++++++++++++++++++++++++++++++++++++++++++++ src/muxer.h | 8 ++++ 9 files changed, 260 insertions(+), 2 deletions(-) create mode 100644 cmake/FindLibSndFile.cmake create mode 100644 cmake/FindPortaudio.cmake create mode 100644 src/muxer.cpp create mode 100644 src/muxer.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 82ac3cb..0b28397 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,15 +25,19 @@ endif() find_package(OpenGL REQUIRED) find_package(GLEW REQUIRED) find_package(GLFW REQUIRED) +find_package(portaudio REQUIRED) +find_package(libsndfile REQUIRED) set(ALL_LIBS ${OPENGL_LIBRARY} ${GLEW_LIBRARY} ${GLFW_LIBRARY} + ${PORTAUDIO_LIBRARIES} + ${LIBSNDFILE_LIBRARY} ) # include_directories(${SDL2_INCLUDE_DIR}) set(CMAKE_BUILD_TYPE Debug) -add_executable(Aromatherapy src/main.cpp src/map.cpp src/renderer.cpp src/entity.cpp src/components.cpp src/game.cpp) +add_executable(Aromatherapy src/main.cpp src/map.cpp src/renderer.cpp src/entity.cpp src/components.cpp src/game.cpp src/muxer.cpp) target_link_libraries(Aromatherapy ${ALL_LIBS}) install(TARGETS Aromatherapy RUNTIME DESTINATION ${BIN_DIR}) diff --git a/cmake/FindLibSndFile.cmake b/cmake/FindLibSndFile.cmake new file mode 100644 index 0000000..a177bde --- /dev/null +++ b/cmake/FindLibSndFile.cmake @@ -0,0 +1,23 @@ +# Base Io build system +# Written by Jeremy Tregunna +# +# Find libsndfile. + +FIND_PATH(LIBSNDFILE_INCLUDE_DIR sndfile.h) + +SET(LIBSNDFILE_NAMES ${LIBSNDFILE_NAMES} sndfile libsndfile) +FIND_LIBRARY(LIBSNDFILE_LIBRARY NAMES ${LIBSNDFILE_NAMES} PATH) + +IF(LIBSNDFILE_INCLUDE_DIR AND LIBSNDFILE_LIBRARY) + SET(LIBSNDFILE_FOUND TRUE) +ENDIF(LIBSNDFILE_INCLUDE_DIR AND LIBSNDFILE_LIBRARY) + +IF(LIBSNDFILE_FOUND) + IF(NOT LibSndFile_FIND_QUIETLY) + MESSAGE(STATUS "Found LibSndFile: ${LIBSNDFILE_LIBRARY}") + ENDIF (NOT LibSndFile_FIND_QUIETLY) +ELSE(LIBSNDFILE_FOUND) + IF(LibSndFile_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find sndfile") + ENDIF(LibSndFile_FIND_REQUIRED) +ENDIF (LIBSNDFILE_FOUND) \ No newline at end of file diff --git a/cmake/FindPortaudio.cmake b/cmake/FindPortaudio.cmake new file mode 100644 index 0000000..aa46935 --- /dev/null +++ b/cmake/FindPortaudio.cmake @@ -0,0 +1,106 @@ +# - Try to find Portaudio +# Once done this will define +# +# PORTAUDIO_FOUND - system has Portaudio +# PORTAUDIO_INCLUDE_DIRS - the Portaudio include directory +# PORTAUDIO_LIBRARIES - Link these to use Portaudio +# PORTAUDIO_DEFINITIONS - Compiler switches required for using Portaudio +# PORTAUDIO_VERSION - Portaudio version +# +# Copyright (c) 2006 Andreas Schneider +# +# Redistribution and use is allowed according to the terms of the New BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. +# + + +if (PORTAUDIO_LIBRARIES AND PORTAUDIO_INCLUDE_DIRS) + # in cache already + set(PORTAUDIO_FOUND TRUE) +else (PORTAUDIO_LIBRARIES AND PORTAUDIO_INCLUDE_DIRS) + if (NOT WIN32) + include(FindPkgConfig) + pkg_check_modules(PORTAUDIO2 portaudio-2.0) + endif (NOT WIN32) + + if (PORTAUDIO2_FOUND) + set(PORTAUDIO_INCLUDE_DIRS + ${PORTAUDIO2_INCLUDE_DIRS} + ) + if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + set(PORTAUDIO_LIBRARIES "${PORTAUDIO2_LIBRARY_DIRS}/lib${PORTAUDIO2_LIBRARIES}.dylib") + else (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + set(PORTAUDIO_LIBRARIES + ${PORTAUDIO2_LIBRARIES} + ) + endif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + set(PORTAUDIO_VERSION + 19 + ) + set(PORTAUDIO_FOUND TRUE) + else (PORTAUDIO2_FOUND) + find_path(PORTAUDIO_INCLUDE_DIR + NAMES + portaudio.h + PATHS + /usr/include + /usr/local/include + /opt/local/include + /sw/include + ) + + find_library(PORTAUDIO_LIBRARY + NAMES + portaudio + PATHS + /usr/lib + /usr/local/lib + /opt/local/lib + /sw/lib + ) + + find_path(PORTAUDIO_LIBRARY_DIR + NAMES + portaudio + PATHS + /usr/lib + /usr/local/lib + /opt/local/lib + /sw/lib + ) + + set(PORTAUDIO_INCLUDE_DIRS + ${PORTAUDIO_INCLUDE_DIR} + ) + set(PORTAUDIO_LIBRARIES + ${PORTAUDIO_LIBRARY} + ) + + set(PORTAUDIO_LIBRARY_DIRS + ${PORTAUDIO_LIBRARY_DIR} + ) + + set(PORTAUDIO_VERSION + 18 + ) + + if (PORTAUDIO_INCLUDE_DIRS AND PORTAUDIO_LIBRARIES) + set(PORTAUDIO_FOUND TRUE) + endif (PORTAUDIO_INCLUDE_DIRS AND PORTAUDIO_LIBRARIES) + + if (PORTAUDIO_FOUND) + if (NOT Portaudio_FIND_QUIETLY) + message(STATUS "Found Portaudio: ${PORTAUDIO_LIBRARIES}") + endif (NOT Portaudio_FIND_QUIETLY) + else (PORTAUDIO_FOUND) + if (Portaudio_FIND_REQUIRED) + message(FATAL_ERROR "Could not find Portaudio") + endif (Portaudio_FIND_REQUIRED) + endif (PORTAUDIO_FOUND) + endif (PORTAUDIO2_FOUND) + + + # show the PORTAUDIO_INCLUDE_DIRS and PORTAUDIO_LIBRARIES variables only in the advanced view + mark_as_advanced(PORTAUDIO_INCLUDE_DIRS PORTAUDIO_LIBRARIES) + +endif (PORTAUDIO_LIBRARIES AND PORTAUDIO_INCLUDE_DIRS) diff --git a/res/Randomize87.wav b/res/Randomize87.wav index 6338faf..14cf907 100644 Binary files a/res/Randomize87.wav and b/res/Randomize87.wav differ diff --git a/src/components.cpp b/src/components.cpp index e2eb2ed..941d02e 100644 --- a/src/components.cpp +++ b/src/components.cpp @@ -1,5 +1,6 @@ #include "components.h" #include "game.h" +#include "muxer.h" // User movement component @@ -215,6 +216,8 @@ void PlayerPhysicsComponent::receive(Game&, Entity& entity, const Message& msg) velocity.second = 0.0; } else if (msg.type == Message::Type::jump) { + playSound("../res/Randomize87.wav"); + velocity.second = jump_velocity; accel.second = jump_gravity; } else if (msg.type == Message::Type::stopJump) diff --git a/src/game.cpp b/src/game.cpp index 043c82b..50c01f5 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -160,5 +160,5 @@ void Game::loadGame(const Map& curMap) void Game::schedule(int frames, std::function&& callback) { - scheduled.emplace(begin(scheduled), frames, callback); + scheduled.emplace_front(frames, callback); } diff --git a/src/main.cpp b/src/main.cpp index e37c2dd..96eb7da 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,12 +3,14 @@ #include "renderer.h" #include #include "game.h" +#include "muxer.h" int main() { srand(time(NULL)); GLFWwindow* window = initRenderer(); + initMuxer(); // Put this in a block so game goes out of scope before we destroy the renderer { @@ -16,6 +18,7 @@ int main() game.execute(window); } + destroyMuxer(); destroyRenderer(); return 0; diff --git a/src/muxer.cpp b/src/muxer.cpp new file mode 100644 index 0000000..0844faa --- /dev/null +++ b/src/muxer.cpp @@ -0,0 +1,111 @@ +#include "muxer.h" +#include +#include +#include +#include + +#define SAMPLE_RATE (44100) + +class Sound { + public: + Sound(const char* filename); + ~Sound(); + + float* ptr; + unsigned long pos; + unsigned long len; +}; + +struct Muxer { + std::list playing; + PaStream* stream; +}; + +inline void dealWithPaError(PaError err) +{ + if (err != paNoError) + { + printf("PortAudio error: %s\n", Pa_GetErrorText(err)); + exit(-1); + } +} + +int paMuxerCallback(const void*, void* outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags, void* userData) +{ + Muxer* muxer = (Muxer*) userData; + float* out = (float*) outputBuffer; + + for (unsigned long i = 0; iplaying) + { + if (sound.pos < sound.len) + { + *out *= curAmount++; + *out += sound.ptr[sound.pos++]; + *out /= (float) curAmount; + } + } + + out++; + } + + return 0; +} + +static Muxer* muxer; + +void initMuxer() +{ + muxer = new Muxer(); + + dealWithPaError(Pa_Initialize()); + dealWithPaError(Pa_OpenDefaultStream(&(muxer->stream), 0, 1, paFloat32, SAMPLE_RATE, paFramesPerBufferUnspecified, paMuxerCallback, muxer)); + dealWithPaError(Pa_StartStream(muxer->stream)); +} + +void destroyMuxer() +{ + dealWithPaError(Pa_AbortStream(muxer->stream)); + dealWithPaError(Pa_CloseStream(muxer->stream)); + dealWithPaError(Pa_Terminate()); + + delete muxer; + muxer = 0; +} + +void playSound(const char* filename) +{ + // First, clear out any sounds that have finished playing + muxer->playing.remove_if([] (Sound& value) { return value.pos >= value.len; }); + + // Then, add the new sound + muxer->playing.emplace_back(filename); +} + +Sound::Sound(const char* filename) +{ + SF_INFO info; + SNDFILE* file = sf_open(filename, SFM_READ, &info); + if (file == nullptr) + { + printf("LibSndFile error: %s\n", sf_strerror(file)); + exit(-1); + } + + ptr = (float*) malloc(info.frames * info.channels * sizeof(float)); + len = info.frames * info.channels; + pos = 0; + + sf_readf_float(file, ptr, info.frames); + + sf_close(file); +} + +Sound::~Sound() +{ + free(ptr); +} diff --git a/src/muxer.h b/src/muxer.h new file mode 100644 index 0000000..b0f5378 --- /dev/null +++ b/src/muxer.h @@ -0,0 +1,8 @@ +#ifndef MUXER_H +#define MUXER_H + +void initMuxer(); +void destroyMuxer(); +void playSound(const char* filename); + +#endif -- cgit 1.4.1