Merge branch 'mixer'

This commit is contained in:
Dmitry Marakasov 2015-09-07 00:52:27 +03:00
commit 2d9787c63e
21 changed files with 2035 additions and 5 deletions

View File

@ -10,7 +10,7 @@ before_install:
- sudo add-apt-repository --yes ppa:ubuntu-toolchain-r/test - sudo add-apt-repository --yes ppa:ubuntu-toolchain-r/test
- sudo add-apt-repository --yes ppa:libreoffice/libreoffice-4-2 - sudo add-apt-repository --yes ppa:libreoffice/libreoffice-4-2
- sudo apt-get update -qq - sudo apt-get update -qq
- sudo apt-get install -qq cmake libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev g++-4.8 cppcheck doxygen - sudo apt-get install -qq cmake libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev libsdl2-mixer-dev g++-4.8 cppcheck doxygen
- sudo sed -i -e 's|friend class hash|friend struct hash|' /usr/include/c++/4.8/bits/stl_bvector.h - sudo sed -i -e 's|friend class hash|friend struct hash|' /usr/include/c++/4.8/bits/stl_bvector.h
- if [ "$CXX" = "g++" ]; then export CXX="g++-4.8" CC="gcc-4.8"; fi - if [ "$CXX" = "g++" ]; then export CXX="g++-4.8" CC="gcc-4.8"; fi
script: script:

View File

@ -21,8 +21,9 @@ SET(SDL2PP_CXXSTD "c++11" CACHE STRING "Used c++ standard")
IF(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) IF(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
OPTION(SDL2PP_WITH_IMAGE "Enable SDL2_image support" ON) OPTION(SDL2PP_WITH_IMAGE "Enable SDL2_image support" ON)
OPTION(SDL2PP_WITH_TTF "Enable SDL2_ttf support" ON) OPTION(SDL2PP_WITH_TTF "Enable SDL2_ttf support" ON)
OPTION(SDL2PP_WITH_MIXER "Enable SDL2_mixer support" ON)
ELSE(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) ELSE(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
# please set SDL2PP_WITH_IMAGE, SDL2PP_WITH_TTF in parent project as needed # please set SDL2PP_WITH_IMAGE, SDL2PP_WITH_TTF, SDL2PP_WITH_MIXER in parent project as needed
ENDIF(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) ENDIF(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
# depends # depends
@ -43,6 +44,13 @@ IF(SDL2PP_WITH_TTF)
ELSE(SDL2PP_WITH_TTF) ELSE(SDL2PP_WITH_TTF)
MESSAGE(STATUS "SDL2_ttf support disabled") MESSAGE(STATUS "SDL2_ttf support disabled")
ENDIF(SDL2PP_WITH_TTF) ENDIF(SDL2PP_WITH_TTF)
IF(SDL2PP_WITH_MIXER)
FIND_PACKAGE(SDL2_mixer REQUIRED)
SET(SDL2_ALL_INCLUDE_DIRS ${SDL2_ALL_INCLUDE_DIRS} ${SDL2_MIXER_INCLUDE_DIR})
SET(SDL2_ALL_LIBRARIES ${SDL2_ALL_LIBRARIES} ${SDL2_MIXER_LIBRARY})
ELSE(SDL2PP_WITH_MIXER)
MESSAGE(STATUS "SDL2_mixer support disabled")
ENDIF(SDL2PP_WITH_MIXER)
FIND_PACKAGE(Doxygen) FIND_PACKAGE(Doxygen)
@ -100,12 +108,16 @@ SET(LIBRARY_SOURCES
SDL2pp/AudioDevice.cc SDL2pp/AudioDevice.cc
SDL2pp/AudioLock.cc SDL2pp/AudioLock.cc
SDL2pp/AudioSpec.cc SDL2pp/AudioSpec.cc
SDL2pp/Chunk.cc
SDL2pp/Exception.cc SDL2pp/Exception.cc
SDL2pp/Mixer.cc
SDL2pp/Music.cc
SDL2pp/Point.cc SDL2pp/Point.cc
SDL2pp/RWops.cc SDL2pp/RWops.cc
SDL2pp/Rect.cc SDL2pp/Rect.cc
SDL2pp/Renderer.cc SDL2pp/Renderer.cc
SDL2pp/SDL.cc SDL2pp/SDL.cc
SDL2pp/SDLMixer.cc
SDL2pp/Surface.cc SDL2pp/Surface.cc
SDL2pp/SurfaceLock.cc SDL2pp/SurfaceLock.cc
SDL2pp/Texture.cc SDL2pp/Texture.cc
@ -117,8 +129,11 @@ SET(LIBRARY_SOURCES
SET(LIBRARY_HEADERS SET(LIBRARY_HEADERS
SDL2pp/AudioDevice.hh SDL2pp/AudioDevice.hh
SDL2pp/AudioSpec.hh SDL2pp/AudioSpec.hh
SDL2pp/Chunk.hh
SDL2pp/ContainerRWops.hh SDL2pp/ContainerRWops.hh
SDL2pp/Exception.hh SDL2pp/Exception.hh
SDL2pp/Mixer.hh
SDL2pp/Music.hh
SDL2pp/Optional.hh SDL2pp/Optional.hh
SDL2pp/Point.hh SDL2pp/Point.hh
SDL2pp/RWops.hh SDL2pp/RWops.hh
@ -126,6 +141,7 @@ SET(LIBRARY_HEADERS
SDL2pp/Renderer.hh SDL2pp/Renderer.hh
SDL2pp/SDL.hh SDL2pp/SDL.hh
SDL2pp/SDL2pp.hh SDL2pp/SDL2pp.hh
SDL2pp/SDLMixer.hh
SDL2pp/StreamRWops.hh SDL2pp/StreamRWops.hh
SDL2pp/Surface.hh SDL2pp/Surface.hh
SDL2pp/Texture.hh SDL2pp/Texture.hh
@ -162,6 +178,15 @@ IF(SDL2PP_WITH_IMAGE)
) )
ENDIF(SDL2PP_WITH_IMAGE) ENDIF(SDL2PP_WITH_IMAGE)
IF(SDL2PP_WITH_MIXER)
SET(LIBRARY_SOURCES
${LIBRARY_SOURCES}
)
SET(LIBRARY_HEADERS
${LIBRARY_HEADERS}
)
ENDIF(SDL2PP_WITH_MIXER)
# targets # targets
IF(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) IF(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
MESSAGE(STATUS "libSDL2pp ${SDL2PP_VERSION} standalone build") MESSAGE(STATUS "libSDL2pp ${SDL2PP_VERSION} standalone build")

View File

@ -12,7 +12,7 @@ try {
using namespace SDL2pp; using namespace SDL2pp;
// Init SDL; will be automatically deinitialized when the object is destroyed // Init SDL; will be automatically deinitialized when the object is destroyed
SDL sdl(SDL_INIT_VIDEO); SDL sdl(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
// Likewise, init SDL_ttf library // Likewise, init SDL_ttf library
SDLTTF sdl_ttf; SDLTTF sdl_ttf;
@ -29,6 +29,11 @@ try {
Font font("Vera.ttf", 20); // SDL_ttf font Font font("Vera.ttf", 20); // SDL_ttf font
// Initialize audio mixer
Mixer mixer(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, MIX_DEFAULT_CHANNELS, 4096);
Chunk sound("effect.ogg"); // OGG sound file
// Create texture from surface containing text rendered by SDL_ttf // Create texture from surface containing text rendered by SDL_ttf
Texture text(renderer, font.RenderText_Solid("Hello, world!", Texture text(renderer, font.RenderText_Solid("Hello, world!",
SDL_Color{255, 255, 255, 255})); SDL_Color{255, 255, 255, 255}));
@ -53,6 +58,9 @@ try {
renderer.Present(); renderer.Present();
// Play our sound one time on a first available mixer channel
mixer.PlayChannel(-1, sound);
// You can still access wrapped C SDL types // You can still access wrapped C SDL types
SDL_Renderer* sdl_renderer = renderer.Get(); SDL_Renderer* sdl_renderer = renderer.Get();
@ -94,6 +102,11 @@ Currently, the library provides wrapper classes for
* SDL_image * SDL_image
* Library initialization/deinitialization * Library initialization/deinitialization
* Loading functions integrated into Texture and Surface * Loading functions integrated into Texture and Surface
* SDL_mixer
* Library initialization/deinitialization
* Sound sample handling (Mix_Chunk)
* Music handling (Mix_Music)
* Mixer class which encapsulates device handling and all playback functions
* SDL_ttf * SDL_ttf
* Library initialization/deinitialization * Library initialization/deinitialization
* TTF_Font (all functions covered) * TTF_Font (all functions covered)
@ -122,8 +135,9 @@ example clang 3.4+ or gcc 4.8+.
Dependencies: Dependencies:
* cmake * cmake
* SDL2 * SDL2
* SDL_image2 (optional) * SDL2_image (optional)
* SDL_ttf2 (optional) * SDL2_mixer (optional)
* SDL2_ttf (optional)
To build standalone version: To build standalone version:
@ -132,6 +146,7 @@ To build standalone version:
Following variables may be supplied to CMake to affect build: Following variables may be supplied to CMake to affect build:
* ```SDL2PP_WITH_IMAGE``` - enable SDL_image support (default ON) * ```SDL2PP_WITH_IMAGE``` - enable SDL_image support (default ON)
* ```SDL2PP_WITH_MIXER``` - enable SDL_mixer support (default ON)
* ```SDL2PP_WITH_TTF``` - enable SDL_ttf support (default ON) * ```SDL2PP_WITH_TTF``` - enable SDL_ttf support (default ON)
* ```SDL2PP_WITH_WERROR``` - treat warnings as errors, useful for CI (default OFF) * ```SDL2PP_WITH_WERROR``` - treat warnings as errors, useful for CI (default OFF)
* ```SDL2PP_CXXSTD``` - override C++ standard (default C++11). With C++1y some additional features are enabled such as usage of [[deprecated]] attribute and using stock experimental/optional from C++ standard library * ```SDL2PP_CXXSTD``` - override C++ standard (default C++11). With C++1y some additional features are enabled such as usage of [[deprecated]] attribute and using stock experimental/optional from C++ standard library
@ -183,6 +198,7 @@ Just place the library into dedicated directory in your project
```cmake ```cmake
SET(SDL2PP_WITH_IMAGE ON) # if you need SDL_image support SET(SDL2PP_WITH_IMAGE ON) # if you need SDL_image support
SET(SDL2PP_WITH_MIXER ON) # if you need SDL_mixer support
SET(SDL2PP_WITH_TTF ON) # if you need SDL_ttf support SET(SDL2PP_WITH_TTF ON) # if you need SDL_ttf support
ADD_SUBDIRECTORY(extlib/libSDL2pp) ADD_SUBDIRECTORY(extlib/libSDL2pp)
``` ```

68
SDL2pp/Chunk.cc Normal file
View File

@ -0,0 +1,68 @@
/*
libSDL2pp - C++11 bindings/wrapper for SDL2
Copyright (C) 2015 Dmitry Marakasov <amdmi3@amdmi3.ru>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include <SDL2pp/Chunk.hh>
#include <SDL2pp/RWops.hh>
#include <SDL2pp/Exception.hh>
namespace SDL2pp {
Chunk::Chunk(Mix_Chunk* chunk) : chunk_(chunk) {
}
Chunk::Chunk(const std::string& file) {
if ((chunk_ = Mix_LoadWAV(file.c_str())) == nullptr)
throw Exception("Mix_LoadWAV");
}
Chunk::Chunk(RWops& rwops) {
if ((chunk_ = Mix_LoadWAV_RW(rwops.Get(), 0)) == nullptr)
throw Exception("Mix_LoadWAV_RW");
}
Chunk::~Chunk() {
if (chunk_ != nullptr)
Mix_FreeChunk(chunk_);
}
Chunk::Chunk(Chunk&& other) noexcept : chunk_(other.chunk_) {
other.chunk_ = nullptr;
}
Chunk& Chunk::operator=(Chunk&& other) noexcept {
if (&other == this)
return *this;
if (chunk_ != nullptr)
Mix_FreeChunk(chunk_);
chunk_ = other.chunk_;
other.chunk_ = nullptr;
return *this;
}
Mix_Chunk* Chunk::Get() const {
return chunk_;
}
int Chunk::Volume(int volume) {
return Mix_VolumeChunk(chunk_, volume);
}
}

150
SDL2pp/Chunk.hh Normal file
View File

@ -0,0 +1,150 @@
/*
libSDL2pp - C++11 bindings/wrapper for SDL2
Copyright (C) 2015 Dmitry Marakasov <amdmi3@amdmi3.ru>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL2PP_CHUNK_HH
#define SDL2PP_CHUNK_HH
#include <string>
#include <SDL2/SDL_mixer.h>
namespace SDL2pp {
class RWops;
////////////////////////////////////////////////////////////
/// \brief Chunk of SDL_mixer audio data
///
/// \ingroup mixer
///
/// \headerfile SDL2pp/Chunk.hh
///
////////////////////////////////////////////////////////////
class Chunk {
private:
Mix_Chunk* chunk_; ///< Managed Mix_Chunk object
public:
////////////////////////////////////////////////////////////
/// \brief Construct from existing Mix_Chunk structure
///
/// \param[in] chunk Existing Mix_Chunk to manage
///
////////////////////////////////////////////////////////////
Chunk(Mix_Chunk* chunk);
////////////////////////////////////////////////////////////
/// \brief Load file for use as a sample
///
/// \param[in] file File name to load sample from
///
/// \throws SDL2pp::Exception
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC19
///
////////////////////////////////////////////////////////////
Chunk(const std::string& file);
////////////////////////////////////////////////////////////
/// \brief Load sample using RWops
///
/// \param[in] rwops SDL2pp::RWops used to access sample data
///
/// \throws SDL2pp::Exception
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC20
///
////////////////////////////////////////////////////////////
Chunk(RWops& rwops);
////////////////////////////////////////////////////////////
/// \brief Destructor
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC24
///
/// \note Despite what Mix_FreeChunk() documentation (and even
/// comment in function implementation) says, right after
/// the named comment there's a code which stops playback
/// of any channel which plays the chunk being freed.
/// Thus, it is safe to destroy Chunk before destroying
/// Mixer, even if it still plays the chunk.
///
////////////////////////////////////////////////////////////
~Chunk();
////////////////////////////////////////////////////////////
/// \brief Move constructor
///
/// \param[in] other SDL2pp::Chunk object to move data from
///
////////////////////////////////////////////////////////////
Chunk(Chunk&& other) noexcept;
////////////////////////////////////////////////////////////
/// \brief Move assignment operator
///
/// \param[in] other SDL2pp::Chunk object to move data from
///
/// \returns Reference to self
///
////////////////////////////////////////////////////////////
Chunk& operator=(Chunk&& other) noexcept;
////////////////////////////////////////////////////////////
/// \brief Deleted copy constructor
///
/// This class is not copyable
///
////////////////////////////////////////////////////////////
Chunk(const Chunk& other) = delete;
////////////////////////////////////////////////////////////
/// \brief Deleted assignment operator
///
/// This class is not copyable
///
////////////////////////////////////////////////////////////
Chunk& operator=(const Chunk& other) = delete;
////////////////////////////////////////////////////////////
/// \brief Get pointer to managed Mix_Chunk structure
///
/// \returns Pointer to managed Mix_Chunk structure
///
////////////////////////////////////////////////////////////
Mix_Chunk* Get() const;
////////////////////////////////////////////////////////////
/// \brief Set volume of a chunk
///
/// \param[in] volume The volume to use from 0 to MIX_MAX_VOLUME(128)
///
/// \returns Previous volume setting
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC23
///
////////////////////////////////////////////////////////////
int Volume(int volume);
};
}
#endif

View File

@ -30,6 +30,7 @@
#cmakedefine SDL2PP_WITH_IMAGE #cmakedefine SDL2PP_WITH_IMAGE
#cmakedefine SDL2PP_WITH_TTF #cmakedefine SDL2PP_WITH_TTF
#cmakedefine SDL2PP_WITH_MIXER
#cmakedefine SDL2PP_WITH_2_0_4 #cmakedefine SDL2PP_WITH_2_0_4
#cmakedefine SDL2PP_WITH_EXPERIMENTAL_OPTIONAL #cmakedefine SDL2PP_WITH_EXPERIMENTAL_OPTIONAL
#cmakedefine SDL2PP_WITH_DEPRECATED #cmakedefine SDL2PP_WITH_DEPRECATED

285
SDL2pp/Mixer.cc Normal file
View File

@ -0,0 +1,285 @@
/*
libSDL2pp - C++11 bindings/wrapper for SDL2
Copyright (C) 2015 Dmitry Marakasov <amdmi3@amdmi3.ru>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include <SDL2pp/Mixer.hh>
#include <SDL2pp/Chunk.hh>
#include <SDL2pp/Music.hh>
#include <SDL2pp/Exception.hh>
namespace SDL2pp {
Mixer::Mixer(int frequency, Uint16 format, int channels, int chunksize) : open_(true) {
if (Mix_OpenAudio(frequency, format, channels, chunksize) != 0)
throw Exception("Mix_OpenAudio");
}
Mixer::~Mixer() {
if (open_)
Mix_CloseAudio();
}
Mixer::Mixer(Mixer&& other) noexcept : open_(other.open_), current_music_hook_(std::move(other.current_music_hook_)) {
other.open_ = false;
}
Mixer& Mixer::operator=(Mixer&& other) noexcept {
if (&other == this)
return *this;
if (open_)
Mix_CloseAudio();
open_ = other.open_;
current_music_hook_ = std::move(other.current_music_hook_);
other.open_ = false;
return *this;
}
int Mixer::AllocateChannels(int numchans) {
return Mix_AllocateChannels(numchans);
}
int Mixer::GetNumChannels() const {
return Mix_AllocateChannels(-1);
}
int Mixer::SetVolume(int channel, int volume) {
return Mix_Volume(channel, volume);
}
int Mixer::GetVolume(int channel) const {
return Mix_Volume(channel, -1);
}
int Mixer::PlayChannel(int channel, const Chunk& chunk, int loops) {
int chan;
if ((chan = Mix_PlayChannel(channel, chunk.Get(), loops)) == -1)
throw Exception("Mix_PlayChannel");
return chan;
}
int Mixer::PlayChannel(int channel, const Chunk& chunk, int loops, int ticks) {
int chan;
if ((chan = Mix_PlayChannelTimed(channel, chunk.Get(), loops, ticks)) == -1)
throw Exception("Mix_PlayChannelTimed");
return chan;
}
int Mixer::FadeInChannel(int channel, const Chunk& chunk, int loops, int ms) {
int chan;
if ((chan = Mix_FadeInChannel(channel, chunk.Get(), loops, ms)) == -1)
throw Exception("Mix_FadeInChannel");
return chan;
}
int Mixer::FadeInChannel(int channel, const Chunk& chunk, int loops, int ms, int ticks) {
int chan;
if ((chan = Mix_FadeInChannelTimed(channel, chunk.Get(), loops, ms, ticks)) == -1)
throw Exception("Mix_FadeInChannelTimed");
return chan;
}
void Mixer::PauseChannel(int channel) {
Mix_Pause(channel);
}
void Mixer::ResumeChannel(int channel) {
Mix_Resume(channel);
}
void Mixer::HaltChannel(int channel) {
Mix_HaltChannel(channel);
}
int Mixer::ExpireChannel(int channel, int ticks) {
return Mix_ExpireChannel(channel, ticks);
}
int Mixer::FadeOutChannel(int channel, int ms) {
return Mix_FadeOutChannel(channel, ms);
}
void Mixer::SetChannelFinishedHandler(ChannelFinishedHandler channel_finished) {
Mix_ChannelFinished(channel_finished);
}
int Mixer::IsChannelPlaying(int channel) const {
return Mix_Playing(channel);
}
int Mixer::IsChannelPaused(int channel) const {
return Mix_Paused(channel);
}
Mix_Fading Mixer::GetChannelFading(int which) const {
return Mix_FadingChannel(which);
}
int Mixer::ReserveChannels(int num) {
return Mix_ReserveChannels(num);
}
void Mixer::GroupChannel(int which, int tag) {
if (Mix_GroupChannel(which, tag) != 1)
throw Exception("Mix_GroupChannel");
}
void Mixer::GroupChannels(int from, int to, int tag) {
if (Mix_GroupChannels(from, to, tag) != to - from + 1)
throw Exception("Mix_GroupChannels");
}
int Mixer::GetGroupNumChannels(int tag) const {
return Mix_GroupCount(tag);
}
int Mixer::GetGroupAvailableChannel(int tag) const {
return Mix_GroupAvailable(tag);
}
int Mixer::GetGroupOldestChannel(int tag) const {
return Mix_GroupOldest(tag);
}
int Mixer::GetGroupNewestChannel(int tag) const {
return Mix_GroupNewer(tag);
}
int Mixer::FadeOutGroup(int tag, int ms) {
return Mix_FadeOutGroup(tag, ms);
}
void Mixer::HaltGroup(int tag) {
Mix_HaltGroup(tag);
}
void Mixer::PlayMusic(const Music& music, int loops) {
if (Mix_PlayMusic(music.Get(), loops) == -1)
throw Exception("Mix_PlayMusic");
}
void Mixer::FadeInMusic(const Music& music, int loops, int ms) {
if (Mix_FadeInMusic(music.Get(), loops, ms) == -1)
throw Exception("Mix_FadeInMusic");
}
int Mixer::SetMusicVolume(int volume) {
return Mix_VolumeMusic(volume);
}
int Mixer::GetMusicVolume() const {
return Mix_VolumeMusic(-1);
}
void Mixer::PauseMusic() {
Mix_PauseMusic();
}
void Mixer::ResumeMusic() {
Mix_ResumeMusic();
}
void Mixer::RewindMusic() {
Mix_RewindMusic();
}
void Mixer::SetMusicPosition(double position) {
if (Mix_SetMusicPosition(position) == -1)
throw Exception("Mix_SetMusicPosition");
}
void Mixer::HaltMusic() {
Mix_HaltMusic();
}
bool Mixer::FadeOutMusic(int ms) {
return Mix_FadeOutMusic(ms);
}
bool Mixer::IsMusicPlaying() const {
return Mix_PlayingMusic();
}
bool Mixer::IsMusicPaused() const {
return Mix_PausedMusic();
}
Mix_Fading Mixer::GetMusicFading() const {
return Mix_FadingMusic();
}
void Mixer::SetMusicFinishedHandler(MusicFinishedHandler music_finished) {
Mix_HookMusicFinished(music_finished);
}
void Mixer::SetMusicHook(MusicHook&& hook) {
if (!hook) {
Mix_HookMusic(nullptr, nullptr);
current_music_hook_.reset(nullptr);
return;
}
current_music_hook_.reset(new MusicHook(std::move(hook)));
Mix_HookMusic([](void *udata, Uint8 *stream, int len) {
static_cast<std::function<void(Uint8 *stream, int len)>*>(udata)->operator()(stream, len);
}, current_music_hook_.get());
}
void Mixer::SetPanning(int channel, int left, int right) {
if (Mix_SetPanning(channel, left, right) == 0)
throw Exception("Mix_SetPanning");
}
void Mixer::UnsetPanning(int channel) {
if (Mix_SetPanning(channel, 255, 255) == 0)
throw Exception("Mix_SetPanning");
}
void Mixer::SetDistance(int channel, int distance) {
if (Mix_SetDistance(channel, distance) == 0)
throw Exception("Mix_SetDistance");
}
void Mixer::UnsetDistance(int channel) {
if (Mix_SetDistance(channel, 0) == 0)
throw Exception("Mix_SetDistance");
}
void Mixer::SetPosition(int channel, int angle, int distance) {
if (Mix_SetPosition(channel, angle, distance) == 0)
throw Exception("Mix_SetPosition");
}
void Mixer::UnsetPosition(int channel) {
if (Mix_SetPosition(channel, 0, 0) == 0)
throw Exception("Mix_SetPosition");
}
void Mixer::SetReverseStereo(int channel) {
if (Mix_SetReverseStereo(channel, 1) == 0)
throw Exception("Mix_SetReverseStereo");
}
void Mixer::UnsetReverseStereo(int channel) {
if (Mix_SetReverseStereo(channel, 0) == 0)
throw Exception("Mix_SetReverseStereo");
}
}

776
SDL2pp/Mixer.hh Normal file
View File

@ -0,0 +1,776 @@
/*
libSDL2pp - C++11 bindings/wrapper for SDL2
Copyright (C) 2015 Dmitry Marakasov <amdmi3@amdmi3.ru>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL2PP_MIXER_HH
#define SDL2PP_MIXER_HH
#include <functional>
#include <memory>
#include <SDL2/SDL_stdinc.h>
#include <SDL2/SDL_mixer.h>
namespace SDL2pp {
class Chunk;
class Music;
////////////////////////////////////////////////////////////
/// \brief SDL_mixer's audio mixer
///
/// \ingroup mixer
///
/// \headerfile SDL2pp/Mixer.hh
///
/// This class represents open SDL_mixer audio device. Object
/// of this class must be constructed before creating any
/// SDL2pp:Chunk's.
///
////////////////////////////////////////////////////////////
class Mixer {
public:
typedef void (*ChannelFinishedHandler)(int); ///< Function type for channel finished callback
typedef void (*MusicFinishedHandler)(); ///< Function type for music finished callback
typedef std::function<void(Uint8 *stream, int len)> MusicHook; ///< Custom music hook
private:
bool open_;
std::unique_ptr<MusicHook> current_music_hook_;
public:
////////////////////////////////////////////////////////////
/// \brief Construct a mixer and open an audio device
///
/// \param[in] frequency Output sampling frequency in samples
/// per second (Hz). You might use
/// MIX_DEFAULT_FREQUENCY(22050) since that
/// is a good value for most games
/// \param[in] format Output sample format
/// \param[in] channels Number of sound channels in output. Set
/// to 2 for stereo, 1 for mono. This has
/// nothing to do with mixing channels
/// \param[in] chunksize Bytes used per output sample
///
/// \throws SDL2pp::Exception
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC11
///
////////////////////////////////////////////////////////////
Mixer(int frequency, Uint16 format, int channels, int chunksize);
////////////////////////////////////////////////////////////
/// \brief Destructor
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC12
///
////////////////////////////////////////////////////////////
~Mixer();
////////////////////////////////////////////////////////////
/// \brief Move constructor
///
/// \param[in] other SDL2pp::Mixer object to move data from
///
////////////////////////////////////////////////////////////
Mixer(Mixer&& other) noexcept;
////////////////////////////////////////////////////////////
/// \brief Move assignment operator
///
/// \param[in] other SDL2pp::Mixer object to move data from
///
/// \returns Reference to self
///
////////////////////////////////////////////////////////////
Mixer& operator=(Mixer&& other) noexcept;
////////////////////////////////////////////////////////////
/// \brief Deleted copy constructor
///
/// This class is not copyable
///
////////////////////////////////////////////////////////////
Mixer(const Mixer& other) = delete;
////////////////////////////////////////////////////////////
/// \brief Deleted assignment operator
///
/// This class is not copyable
///
////////////////////////////////////////////////////////////
Mixer& operator=(const Mixer& other) = delete;
////////////////////////////////////////////////////////////
/// \brief Set the number of channels to mix
///
/// \param[in] numchans Number of channels to allocate for mixing
///
/// \returns The number of channels allocated
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC26
///
////////////////////////////////////////////////////////////
int AllocateChannels(int numchans);
////////////////////////////////////////////////////////////
/// \brief Get the number of channels being mixed
///
/// \returns The number of channels allocated
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC26
///
////////////////////////////////////////////////////////////
int GetNumChannels() const;
////////////////////////////////////////////////////////////
/// \brief Set the mix volume of a channel
///
/// \param[in] channel Channel to set mix volume for.
/// -1 will set the volume for all allocated
/// channels.
/// \param[in] volume The volume to use from 0 to MIX_MAX_VOLUME(128)
///
/// \returns Current volume of the channel. If channel is -1,
/// the average volume is returned
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC27
///
////////////////////////////////////////////////////////////
int SetVolume(int channel, int volume);
////////////////////////////////////////////////////////////
/// \brief Get the mix volume of a channel
///
/// \param[in] channel Channel to set mix volume for.
/// -1 will return the average volume.
///
/// \returns Current volume of the channel. If channel is -1,
/// the average volume is returned
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC27
///
////////////////////////////////////////////////////////////
int GetVolume(int channel) const;
////////////////////////////////////////////////////////////
/// \brief Play loop
///
/// \param[in] channel Channel to play on, or -1 for the first
/// free unreserved channel
/// \param[in] chunk Sample to play
/// \param[in] loops Number of loops, -1 is infinite loops.
/// Passing one here plays the sample twice (1 loop).
///
/// \returns The channel the sample is played on
///
/// \throws SDL2pp::Exception
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC28
///
////////////////////////////////////////////////////////////
int PlayChannel(int channel, const Chunk& chunk, int loops = 0);
////////////////////////////////////////////////////////////
/// \brief Play loop and limit by time
///
/// \param[in] channel Channel to play on, or -1 for the first
/// free unreserved channel
/// \param[in] chunk Sample to play
/// \param[in] loops Number of loops, -1 is infinite loops.
/// Passing one here plays the sample twice (1 loop).
/// \param[in] ticks Millisecond limit to play sample, at most.
/// If not enough loops or the sample chunk is not
/// long enough, then the sample may stop before
/// this timeout occurs. -1 means play forever
///
/// \returns The channel the sample is played on
///
/// \throws SDL2pp::Exception
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC29
///
////////////////////////////////////////////////////////////
int PlayChannel(int channel, const Chunk& chunk, int loops, int ticks);
////////////////////////////////////////////////////////////
/// \brief Play loop with fade in
///
/// \param[in] channel Channel to play on, or -1 for the first
/// free unreserved channel
/// \param[in] chunk Sample to play
/// \param[in] loops Number of loops, -1 is infinite loops.
/// Passing one here plays the sample twice (1 loop).
/// \param[in] ms Milliseconds of time that the fade-in effect
/// should take to go from silence to full volume
///
/// \returns The channel the sample is played on
///
/// \throws SDL2pp::Exception
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC30
///
////////////////////////////////////////////////////////////
int FadeInChannel(int channel, const Chunk& chunk, int loops, int ms);
////////////////////////////////////////////////////////////
/// \brief loop with fade in and limit by time
///
/// \param[in] channel Channel to play on, or -1 for the first
/// free unreserved channel
/// \param[in] chunk Sample to play
/// \param[in] loops Number of loops, -1 is infinite loops.
/// Passing one here plays the sample twice (1 loop).
/// \param[in] ms Milliseconds of time that the fade-in effect
/// should take to go from silence to full volume
/// \param[in] ticks Millisecond limit to play sample, at most.
/// If not enough loops or the sample chunk is not
/// long enough, then the sample may stop before
/// this timeout occurs. -1 means play forever
///
/// \returns The channel the sample is played on
///
/// \throws SDL2pp::Exception
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC31
///
////////////////////////////////////////////////////////////
int FadeInChannel(int channel, const Chunk& chunk, int loops, int ms, int ticks);
////////////////////////////////////////////////////////////
/// \brief Pause a channel
///
/// \param[in] channel Channel to pause on, or -1 for all channels
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC32
///
////////////////////////////////////////////////////////////
void PauseChannel(int channel = -1);
////////////////////////////////////////////////////////////
/// \brief Resume a paused channel
///
/// \param[in] channel Channel to resume playing, or -1 for all channels
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC33
///
////////////////////////////////////////////////////////////
void ResumeChannel(int channel = -1);
////////////////////////////////////////////////////////////
/// \brief Stop playing on a channel
///
/// \param[in] channel Channel to stop playing, or -1 for all channels
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC34
///
////////////////////////////////////////////////////////////
void HaltChannel(int channel = -1);
////////////////////////////////////////////////////////////
/// \brief Change the timed stoppage of a channel
///
/// \param[in] channel Channel to stop playing, or -1 for all channels
/// \param[in] ticks Millisecons until channel(s) halt playback
///
/// \returns Number of channels set to expire. Whether or not they are active
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC35
///
////////////////////////////////////////////////////////////
int ExpireChannel(int channel, int ticks);
////////////////////////////////////////////////////////////
/// \brief Stop playing channel after timed fade out
///
/// \param[in] channel Channel to fade out, or -1 to fade all channels out
/// \param[in] ms Milliseconds of time that the fade-out effect should
/// take to go to silence, starting now
///
/// \returns The number of channels set to fade out
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC36
///
////////////////////////////////////////////////////////////
int FadeOutChannel(int channel, int ms);
////////////////////////////////////////////////////////////
/// \brief Set callback for when channel finishes playing
///
/// \param[in] channel_finished Function to call when any channel
/// finishes playback
///
/// \note Since Mix_ChannelFinished doesn't take any custom data
/// pointer, unfortunately there's no safe way of using
/// std::function here.
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC37
///
////////////////////////////////////////////////////////////
void SetChannelFinishedHandler(ChannelFinishedHandler channel_finished);
////////////////////////////////////////////////////////////
/// \brief Get the active playing status of a channel
///
/// \param[in] channel Channel to test whether it is playing or not.
/// -1 will tell you how many channels are playing
///
/// \returns Zero if the channel is not playing. Otherwise if you passed
/// in -1, the number of channels playing is returned. If you
/// passed in a specific channel, then 1 is returned if it is
/// playing.
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC38
///
////////////////////////////////////////////////////////////
int IsChannelPlaying(int channel) const;
////////////////////////////////////////////////////////////
/// \brief Get the pause status of a channel
///
/// \param[in] channel Channel to test whether it is paused or not.
/// -1 will tell you how many channels are playing
///
/// \returns Zero if the channel is not paused. Otherwise if you passed
/// in -1, the number of paused channels is returned. If you
/// passed in a specific channel, then 1 is returned if it is
/// paused.
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC39
///
////////////////////////////////////////////////////////////
int IsChannelPaused(int channel) const;
////////////////////////////////////////////////////////////
/// \brief Get the fade status of a channel
///
/// \param[in] which Channel to get the fade activity status from
///
/// \returns The fading status
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC40
///
////////////////////////////////////////////////////////////
Mix_Fading GetChannelFading(int which) const;
////////////////////////////////////////////////////////////
/// \brief Prevent channels from being used in default group
///
/// \param[in] num Number of channels to reserve from default mixing.
/// Zero removes all reservations
///
/// \returns The number of channels reserved. Never fails,
/// but may return less channels than you ask for,
/// depending on the number of channels previously
/// allocated
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC43
///
////////////////////////////////////////////////////////////
int ReserveChannels(int num);
////////////////////////////////////////////////////////////
/// \brief Add/remove channel to/from group
///
/// \param[in] which Channel number to assign tag to.
/// \param[in] tag A group number. Any positive numbers
/// (including zero). -1 is the default group.
/// Use -1 to remove a group tag essentially.
///
/// \throws SDL2pp::Exception
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC44
///
////////////////////////////////////////////////////////////
void GroupChannel(int which, int tag);
////////////////////////////////////////////////////////////
/// \brief Add/remove segment of channels to/from group
///
/// \param[in] from First Channel number of channels to assign tag to.
/// \param[in] to Last Channel number of channels to assign tag to
/// \param[in] tag A group number. Any positive numbers (including zero).
/// -1 is the default group. Use -1 to remove a group tag
/// essentially.
///
/// \throws SDL2pp::Exception
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC45
///
////////////////////////////////////////////////////////////
void GroupChannels(int from, int to, int tag);
////////////////////////////////////////////////////////////
/// \brief Get number of channels in group
///
/// \param[in] tag A group number
///
/// \returns The number of channels found in the group
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC46
///
////////////////////////////////////////////////////////////
int GetGroupNumChannels(int tag) const;
////////////////////////////////////////////////////////////
/// \brief Get first inactive channel in group
///
/// \param[in] tag A group number
///
/// \returns The channel found on success. -1 is returned when
/// no channels in the group are available
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC47
///
////////////////////////////////////////////////////////////
int GetGroupAvailableChannel(int tag) const;
////////////////////////////////////////////////////////////
/// \brief Get oldest busy channel in group
///
/// \param[in] tag A group number
///
/// \returns The channel found on success. -1 is returned when
/// no channels in the group are available
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC48
///
////////////////////////////////////////////////////////////
int GetGroupOldestChannel(int tag) const;
////////////////////////////////////////////////////////////
/// \brief Get youngest busy channel in group
///
/// \param[in] tag A group number
///
/// \returns The channel found on success. -1 is returned when
/// no channels in the group are available
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC49
///
////////////////////////////////////////////////////////////
int GetGroupNewestChannel(int tag) const;
////////////////////////////////////////////////////////////
/// \brief Fade out a group over time
///
/// \param[in] tag Group to fade out
/// \param[in] ms Milliseconds of time that the fade-out effect
/// should take to go to silence, starting now
///
/// \returns The number of channels set to fade out
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC50
///
////////////////////////////////////////////////////////////
int FadeOutGroup(int tag, int ms);
////////////////////////////////////////////////////////////
/// \brief Stop a group
///
/// \param[in] tag Group to fade out
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC51
///
////////////////////////////////////////////////////////////
void HaltGroup(int tag);
////////////////////////////////////////////////////////////
/// \brief Play music
///
/// \param[in] music Music to play
/// \param[in] loops number of times to play through the music.
/// 0 plays the music zero times...
/// -1 plays the music forever
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC57
///
////////////////////////////////////////////////////////////
void PlayMusic(const Music& music, int loops = -1);
////////////////////////////////////////////////////////////
/// \brief Play music, with looping, and fade in
///
/// \param[in] music Music to play
/// \param[in] loops number of times to play through the music.
/// 0 plays the music zero times...
/// -1 plays the music forever
/// \param[in] ms Milliseconds for the fade-in effect to complete
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC57
///
////////////////////////////////////////////////////////////
void FadeInMusic(const Music& music, int loops = -1, int ms = 0);
////////////////////////////////////////////////////////////
/// \brief Set music volume
///
/// \param[in] volume The volume to use from 0 to MIX_MAX_VOLUME(128)
///
/// \returns The previous volume setting
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC61
///
////////////////////////////////////////////////////////////
int SetMusicVolume(int volume);
////////////////////////////////////////////////////////////
/// \brief Get music volume
///
/// \returns Current volume setting
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC61
///
////////////////////////////////////////////////////////////
int GetMusicVolume() const;
////////////////////////////////////////////////////////////
/// \brief Pause music
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC62
///
////////////////////////////////////////////////////////////
void PauseMusic();
////////////////////////////////////////////////////////////
/// \brief Resume paused music
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC63
///
////////////////////////////////////////////////////////////
void ResumeMusic();
////////////////////////////////////////////////////////////
/// \brief Rewind music to beginning
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC64
///
////////////////////////////////////////////////////////////
void RewindMusic();
////////////////////////////////////////////////////////////
/// \brief Set position of playback in stream
///
/// \param[in] position Posistion to play from
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC65
///
////////////////////////////////////////////////////////////
void SetMusicPosition(double position);
////////////////////////////////////////////////////////////
/// \brief Stop music playback
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC67
///
////////////////////////////////////////////////////////////
void HaltMusic();
////////////////////////////////////////////////////////////
/// \brief Stop music, with fade out
///
/// \param[in] ms Milliseconds of time that the fade-out effect
/// should take to go to silence, starting now.
///
/// \returns True in success, false on failure
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC68
///
////////////////////////////////////////////////////////////
bool FadeOutMusic(int ms);
////////////////////////////////////////////////////////////
/// \brief Test whether music is playing
///
/// \returns True if music is actively playing
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC71
///
////////////////////////////////////////////////////////////
bool IsMusicPlaying() const;
////////////////////////////////////////////////////////////
/// \brief Test whether music is paused
///
/// \returns True if music is paused
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC72
///
////////////////////////////////////////////////////////////
bool IsMusicPaused() const;
////////////////////////////////////////////////////////////
/// \brief Get status of current music fade activity
///
/// \returns The fading status
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC73
///
////////////////////////////////////////////////////////////
Mix_Fading GetMusicFading() const;
////////////////////////////////////////////////////////////
/// \brief Set a callback for when music stops
///
/// \param[in] music_finished Function to call when music stops
///
/// \note Since Mix_HookMusicFinished doesn't take any custom data
/// pointer, unfortunately there's no safe way of using
/// std::function here.
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC69
///
////////////////////////////////////////////////////////////
void SetMusicFinishedHandler(MusicFinishedHandler music_finished);
////////////////////////////////////////////////////////////
/// \brief Hook for a custom music player
///
/// \param[in] hook Music player mixer function
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC60
///
////////////////////////////////////////////////////////////
void SetMusicHook(MusicHook&& hook);
// TODO: custom effects
////////////////////////////////////////////////////////////
/// \brief Stereo panning
///
/// \param[in] channel Channel number to register this effect on or
/// MIX_CHANNEL_POST to process the postmix stream
/// \param[in] left Volume for the left channel, range is 0 (silence)
/// to 255 (loud)
/// \param[in] right Volume for the right channel, range is 0 (silence)
/// to 255 (loud)
///
/// \throws SDL2pp::Exception
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC80
///
////////////////////////////////////////////////////////////
void SetPanning(int channel, int left, int right);
////////////////////////////////////////////////////////////
/// \brief Disable stereo panning
///
/// \param[in] channel Channel number to unregister this effect from or
/// MIX_CHANNEL_POST to unregister from the postmix stream
///
/// \throws SDL2pp::Exception
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC80
///
////////////////////////////////////////////////////////////
void UnsetPanning(int channel);
////////////////////////////////////////////////////////////
/// \brief Distance attenuation (volume)
///
/// \param[in] channel Channel number to register this effect on or
/// MIX_CHANNEL_POST to process the postmix stream
/// \param[in] distance Specify the distance from the listener,
/// from 0 (close/loud) to 255 (far/quiet)
///
/// \throws SDL2pp::Exception
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC81
///
////////////////////////////////////////////////////////////
void SetDistance(int channel, int distance);
////////////////////////////////////////////////////////////
/// \brief Disable distance attenuation
///
/// \param[in] channel Channel number to unregister this effect from or
/// MIX_CHANNEL_POST to unregister from the postmix stream
///
/// \throws SDL2pp::Exception
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC81
///
////////////////////////////////////////////////////////////
void UnsetDistance(int channel);
////////////////////////////////////////////////////////////
/// \brief Panning (angular) and distance
///
/// \param[in] channel Channel number to register this effect on or
/// MIX_CHANNEL_POST to process the postmix stream
/// \param[in] angle Direction in relation to forward from 0 to 360 degrees.
/// Larger angles will be reduced to this range using angles
/// % 360. 0 = directly in front, 90 = directly to the right
/// etc.
/// \param[in] distance Specify the distance from the listener,
/// from 0 (close/loud) to 255 (far/quiet)
///
/// \throws SDL2pp::Exception
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC82
///
////////////////////////////////////////////////////////////
void SetPosition(int channel, int angle, int distance);
////////////////////////////////////////////////////////////
/// \brief Disable panning and distance
///
/// \param[in] channel Channel number to unregister this effect from or
/// MIX_CHANNEL_POST to unregister from the postmix stream
///
/// \throws SDL2pp::Exception
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC82
///
////////////////////////////////////////////////////////////
void UnsetPosition(int channel);
////////////////////////////////////////////////////////////
/// \brief Swap stereo left and right
///
/// \param[in] channel Channel number to register this effect on or
/// MIX_CHANNEL_POST to process the postmix stream
///
/// \throws SDL2pp::Exception
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC83
///
////////////////////////////////////////////////////////////
void SetReverseStereo(int channel);
////////////////////////////////////////////////////////////
/// \brief Disable stereo swapping
///
/// \param[in] channel Channel number to unregister this effect from or
/// MIX_CHANNEL_POST to unregister from the postmix stream
///
/// \throws SDL2pp::Exception
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC83
///
////////////////////////////////////////////////////////////
void UnsetReverseStereo(int channel);
};
}
#endif

62
SDL2pp/Music.cc Normal file
View File

@ -0,0 +1,62 @@
/*
libSDL2pp - C++11 bindings/wrapper for SDL2
Copyright (C) 2015 Dmitry Marakasov <amdmi3@amdmi3.ru>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include <SDL2pp/Music.hh>
#include <SDL2pp/Exception.hh>
namespace SDL2pp {
Music::Music(Mix_Music* music) : music_(music) {
}
Music::Music(const std::string& file) {
if ((music_ = Mix_LoadMUS(file.c_str())) == nullptr)
throw Exception("Mix_LoadMUS");
}
Music::~Music() {
if (music_ != nullptr)
Mix_FreeMusic(music_);
}
Music::Music(Music&& other) noexcept : music_(other.music_) {
other.music_ = nullptr;
}
Music& Music::operator=(Music&& other) noexcept {
if (&other == this)
return *this;
if (music_ != nullptr)
Mix_FreeMusic(music_);
music_ = other.music_;
other.music_ = nullptr;
return *this;
}
Mix_Music* Music::Get() const {
return music_;
}
Mix_MusicType Music::GetType() const {
return Mix_GetMusicType(music_);
}
}

125
SDL2pp/Music.hh Normal file
View File

@ -0,0 +1,125 @@
/*
libSDL2pp - C++11 bindings/wrapper for SDL2
Copyright (C) 2015 Dmitry Marakasov <amdmi3@amdmi3.ru>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL2PP_MUSIC_HH
#define SDL2PP_MUSIC_HH
#include <string>
#include <SDL2/SDL_mixer.h>
namespace SDL2pp {
////////////////////////////////////////////////////////////
/// \brief SDL_mixer music data
///
/// \ingroup mixer
///
/// \headerfile SDL2pp/Music.hh
///
////////////////////////////////////////////////////////////
class Music {
private:
Mix_Music* music_; ///< Managed Mix_Music object
public:
////////////////////////////////////////////////////////////
/// \brief Construct from existing Mix_Music pointer
///
/// \param[in] music Existing Mix_Music to manage
///
////////////////////////////////////////////////////////////
Music(Mix_Music* music);
////////////////////////////////////////////////////////////
/// \brief Load music file
///
/// \param[in] file Name of music file to use
///
/// \throws SDL2pp::Exception
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC55
///
////////////////////////////////////////////////////////////
Music(const std::string& file);
////////////////////////////////////////////////////////////
/// \brief Destructor
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC56
///
////////////////////////////////////////////////////////////
~Music();
////////////////////////////////////////////////////////////
/// \brief Move constructor
///
/// \param[in] other SDL2pp::Music object to move data from
///
////////////////////////////////////////////////////////////
Music(Music&& other) noexcept;
////////////////////////////////////////////////////////////
/// \brief Move assignment operator
///
/// \param[in] other SDL2pp::Music object to move data from
///
/// \returns Reference to self
///
////////////////////////////////////////////////////////////
Music& operator=(Music&& other) noexcept;
////////////////////////////////////////////////////////////
/// \brief Deleted copy constructor
///
/// This class is not copyable
///
////////////////////////////////////////////////////////////
Music(const Music& other) = delete;
////////////////////////////////////////////////////////////
/// \brief Deleted assignment operator
///
/// This class is not copyable
///
////////////////////////////////////////////////////////////
Music& operator=(const Music& other) = delete;
////////////////////////////////////////////////////////////
/// \brief Get pointer to managed Mix_Music
///
/// \returns Pointer to managed Mix_Music
///
////////////////////////////////////////////////////////////
Mix_Music* Get() const;
////////////////////////////////////////////////////////////
/// \brief Get the music encoding type
///
/// \returns The type of music
///
////////////////////////////////////////////////////////////
Mix_MusicType GetType() const;
};
}
#endif

View File

@ -116,4 +116,17 @@
# include <SDL2pp/SDLImage.hh> # include <SDL2pp/SDLImage.hh>
#endif #endif
////////////////////////////////////////////////////////////
/// \defgroup mixer SDL_mixer
///
/// \brief Functions that are specific to SDL_mixer library
///
////////////////////////////////////////////////////////////
#ifdef SDL2PP_WITH_MIXER
# include <SDL2pp/Chunk.hh>
# include <SDL2pp/Mixer.hh>
# include <SDL2pp/Music.hh>
# include <SDL2pp/SDLMixer.hh>
#endif
#endif #endif

51
SDL2pp/SDLMixer.cc Normal file
View File

@ -0,0 +1,51 @@
/*
libSDL2pp - C++11 bindings/wrapper for SDL2
Copyright (C) 2014-2015 Dmitry Marakasov <amdmi3@amdmi3.ru>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include <SDL2/SDL_mixer.h>
#include <SDL2pp/SDLMixer.hh>
#include <SDL2pp/Exception.hh>
namespace SDL2pp {
SDLMixer::SDLMixer(int flags) {
if ((Mix_Init(flags) & flags) != flags)
throw Exception("Mix_Init");
}
SDLMixer::~SDLMixer() {
// see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC10
while (Mix_Init(0))
Mix_Quit();
}
int SDLMixer::InitMore(int flags) {
int ret;
if (((ret = Mix_Init(flags)) & flags) != flags)
throw Exception("Mix_Init");
return ret;
}
int SDLMixer::GetInitFlags() {
return Mix_Init(0);
}
}

123
SDL2pp/SDLMixer.hh Normal file
View File

@ -0,0 +1,123 @@
/*
libSDL2pp - C++11 bindings/wrapper for SDL2
Copyright (C) 2014-2015 Dmitry Marakasov <amdmi3@amdmi3.ru>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL2PP_SDLMIXER_HH
#define SDL2PP_SDLMIXER_HH
namespace SDL2pp {
////////////////////////////////////////////////////////////
/// \brief Object taking care of SDL_mixer library initialization and deinitialization
///
/// \ingroup mixer
///
/// \headerfile SDL2pp/SDLMixer.hh
///
/// Usage example:
/// \code
/// int main() {
/// SDL2pp::SDL sdl(SDL_INIT_VIDEO);
/// SDL2pp::SDLMixer mixer(MIX_INIT_OGG);
///
/// // SDL_mixer library is automatically deinitialized before exit
/// return 0;
/// }
/// \endcode
///
////////////////////////////////////////////////////////////
class SDLMixer {
public:
////////////////////////////////////////////////////////////
/// \brief Initializes SDL_mixer library
///
/// \param[in] flags Flags to pass to Mix_Init()
///
/// \throws SDL2pp::Exception
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC9
///
////////////////////////////////////////////////////////////
SDLMixer(int flags = 0);
////////////////////////////////////////////////////////////
/// \brief Destructor, deinitializes SDL_mixer library
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC10
///
////////////////////////////////////////////////////////////
virtual ~SDLMixer();
////////////////////////////////////////////////////////////
/// \brief Try to init more SDL_mixer formats
///
/// \param[in] flags Flags to pass to Mix_Init()
///
/// \throws SDL2pp::Exception
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC9
///
////////////////////////////////////////////////////////////
int InitMore(int flags);
////////////////////////////////////////////////////////////
/// \brief Get mask of initialized SDL_mixer formats
///
/// \see https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC9
///
////////////////////////////////////////////////////////////
int GetInitFlags();
////////////////////////////////////////////////////////////
/// \brief Deleted copy constructor
///
/// This class is not copyable
///
////////////////////////////////////////////////////////////
SDLMixer(const SDLMixer& other) = delete;
////////////////////////////////////////////////////////////
/// \brief Deleted assignment operator
///
/// This class is not copyable
///
////////////////////////////////////////////////////////////
SDLMixer& operator=(const SDLMixer& other) = delete;
////////////////////////////////////////////////////////////
/// \brief Deleted move constructor
///
/// This class is not movable
///
////////////////////////////////////////////////////////////
SDLMixer(SDLMixer&& other) = delete;
////////////////////////////////////////////////////////////
/// \brief Deleted move assignment operator
///
/// This class is not movable
///
////////////////////////////////////////////////////////////
SDLMixer& operator=(SDLMixer&& other) = delete;
};
}
#endif

View File

@ -0,0 +1,17 @@
# - Try to locate SDL2_mixer
# This module defines:
#
# SDL2_MIXER_INCLUDE_DIR
# SDL2_MIXER_LIBRARY
# SDL2_MIXER_FOUND
#
FIND_PATH(SDL2_MIXER_INCLUDE_DIR NAMES SDL2/SDL_mixer.h)
FIND_LIBRARY(SDL2_MIXER_LIBRARY NAMES SDL2_mixer)
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2_mixer REQUIRED_VARS SDL2_MIXER_INCLUDE_DIR SDL2_MIXER_LIBRARY)
MARK_AS_ADVANCED(SDL2_MIXER_INCLUDE_DIR SDL2_MIXER_LIBRARY)

View File

@ -27,3 +27,17 @@ IF(SDL2PP_WITH_TTF)
ADD_EXECUTABLE(ttf ttf.cc) ADD_EXECUTABLE(ttf ttf.cc)
TARGET_LINK_LIBRARIES(ttf SDL2pp) TARGET_LINK_LIBRARIES(ttf SDL2pp)
ENDIF(SDL2PP_WITH_TTF) ENDIF(SDL2PP_WITH_TTF)
IF(SDL2PP_WITH_MIXER)
ADD_EXECUTABLE(mixer mixer.cc)
TARGET_LINK_LIBRARIES(mixer SDL2pp)
ADD_EXECUTABLE(mixer_music mixer_music.cc)
TARGET_LINK_LIBRARIES(mixer_music SDL2pp)
ADD_EXECUTABLE(mixer_music_sine mixer_music_sine.cc)
TARGET_LINK_LIBRARIES(mixer_music_sine SDL2pp)
ADD_EXECUTABLE(mixer_effects mixer_effects.cc)
TARGET_LINK_LIBRARIES(mixer_effects SDL2pp)
ENDIF(SDL2PP_WITH_MIXER)

80
examples/mixer.cc Normal file
View File

@ -0,0 +1,80 @@
/*
libSDL2pp - C++11 bindings/wrapper for SDL2
Copyright (C) 2015 Dmitry Marakasov <amdmi3@amdmi3.ru>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include <iostream>
#include <SDL2/SDL.h>
#include <SDL2/SDL_mixer.h>
#include <SDL2pp/SDL.hh>
#include <SDL2pp/SDLMixer.hh>
#include <SDL2pp/Mixer.hh>
#include <SDL2pp/Chunk.hh>
using namespace SDL2pp;
int main() try {
SDL sdl(SDL_INIT_AUDIO);
SDLMixer mixerlib(MIX_INIT_OGG);
Mixer mixer(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, MIX_DEFAULT_CHANNELS, 4096);
Chunk sound(TESTDATA_DIR "/test.ogg");
mixer.SetChannelFinishedHandler([](int channel){
std::cerr << "Channel " << channel << " finished playback" << std::endl;
});
int chan;
// Fade in
chan = mixer.FadeInChannel(-1, sound, 0, 1000);
std::cerr << "Fading sound in on channel " << chan << "\n";
SDL_Delay(2000);
// Mix 3 sounds
chan = mixer.PlayChannel(-1, sound);
std::cerr << "Playing sound on channel " << chan << "\n";
SDL_Delay(250);
chan = mixer.PlayChannel(-1, sound);
std::cerr << "Playing sound on channel " << chan << "\n";
SDL_Delay(250);
chan = mixer.PlayChannel(-1, sound);
std::cerr << "Playing sound on channel " << chan << "\n";
SDL_Delay(2000);
// Fade out
chan = mixer.PlayChannel(-1, sound);
std::cerr << "Fading out sound on channel " << chan << "\n";
mixer.FadeOutChannel(chan, 2000);
SDL_Delay(2000);
return 0;
} catch (std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
return 1;
}

118
examples/mixer_effects.cc Normal file
View File

@ -0,0 +1,118 @@
/*
libSDL2pp - C++11 bindings/wrapper for SDL2
Copyright (C) 2015 Dmitry Marakasov <amdmi3@amdmi3.ru>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include <iostream>
#include <SDL2/SDL.h>
#include <SDL2/SDL_mixer.h>
#include <SDL2pp/SDL.hh>
#include <SDL2pp/SDLMixer.hh>
#include <SDL2pp/Mixer.hh>
#include <SDL2pp/Chunk.hh>
using namespace SDL2pp;
int main() try {
SDL sdl(SDL_INIT_AUDIO);
SDLMixer mixerlib(MIX_INIT_OGG);
Mixer mixer(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, MIX_DEFAULT_CHANNELS, 4096);
Chunk sound(TESTDATA_DIR "/test.ogg");
// Panning
std::cerr << "Panning: left" << std::endl;
mixer.SetPanning(MIX_CHANNEL_POST, 255, 0);
mixer.PlayChannel(-1, sound);
SDL_Delay(2000);
mixer.HaltChannel(-1);
std::cerr << "Panning: right" << std::endl;
mixer.SetPanning(MIX_CHANNEL_POST, 0, 255);
mixer.PlayChannel(-1, sound);
SDL_Delay(2000);
mixer.HaltChannel(-1);
mixer.UnsetPanning(MIX_CHANNEL_POST);
// Distance
std::cerr << "Distance: somewhat far" << std::endl;
mixer.SetDistance(MIX_CHANNEL_POST, 128);
mixer.PlayChannel(-1, sound);
SDL_Delay(2000);
mixer.HaltChannel(-1);
std::cerr << "Distance: further" << std::endl;
mixer.SetDistance(MIX_CHANNEL_POST, 192);
mixer.PlayChannel(-1, sound);
SDL_Delay(2000);
mixer.HaltChannel(-1);
std::cerr << "Distance: even further" << std::endl;
mixer.SetDistance(MIX_CHANNEL_POST, 224);
mixer.PlayChannel(-1, sound);
SDL_Delay(2000);
mixer.HaltChannel(-1);
mixer.UnsetDistance(MIX_CHANNEL_POST);
// Position
std::cerr << "Position: closest left" << std::endl;
mixer.SetPosition(MIX_CHANNEL_POST, 270, 0);
mixer.PlayChannel(-1, sound);
SDL_Delay(2000);
mixer.HaltChannel(-1);
std::cerr << "Position: somewhat far front" << std::endl;
mixer.SetPosition(MIX_CHANNEL_POST, 0, 128);
mixer.PlayChannel(-1, sound);
SDL_Delay(2000);
mixer.HaltChannel(-1);
std::cerr << "Position: further right" << std::endl;
mixer.SetPosition(MIX_CHANNEL_POST, 90, 192);
mixer.PlayChannel(-1, sound);
SDL_Delay(2000);
mixer.HaltChannel(-1);
std::cerr << "Position: even further back" << std::endl;
mixer.SetPosition(MIX_CHANNEL_POST, 180, 224);
mixer.PlayChannel(-1, sound);
SDL_Delay(2000);
mixer.HaltChannel(-1);
mixer.UnsetPosition(MIX_CHANNEL_POST);
// Position
std::cerr << "Reverse stereo" << std::endl;
mixer.SetReverseStereo(MIX_CHANNEL_POST);
mixer.PlayChannel(-1, sound);
SDL_Delay(2000);
mixer.HaltChannel(-1);
mixer.UnsetReverseStereo(MIX_CHANNEL_POST);
return 0;
} catch (std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
return 1;
}

49
examples/mixer_music.cc Normal file
View File

@ -0,0 +1,49 @@
/*
libSDL2pp - C++11 bindings/wrapper for SDL2
Copyright (C) 2015 Dmitry Marakasov <amdmi3@amdmi3.ru>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include <iostream>
#include <SDL2/SDL.h>
#include <SDL2/SDL_mixer.h>
#include <SDL2pp/SDL.hh>
#include <SDL2pp/SDLMixer.hh>
#include <SDL2pp/Mixer.hh>
#include <SDL2pp/Music.hh>
using namespace SDL2pp;
int main() try {
SDL sdl(SDL_INIT_AUDIO);
SDLMixer mixerlib(MIX_INIT_OGG);
Mixer mixer(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, MIX_DEFAULT_CHANNELS, 4096);
Music music(TESTDATA_DIR "/test.ogg");
mixer.FadeInMusic(music, -1, 2000);
SDL_Delay(5000);
return 0;
} catch (std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
return 1;
}

View File

@ -0,0 +1,53 @@
/*
libSDL2pp - C++11 bindings/wrapper for SDL2
Copyright (C) 2013-2015 Dmitry Marakasov <amdmi3@amdmi3.ru>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include <iostream>
#include <SDL2/SDL.h>
#include <SDL2pp/SDL.hh>
#include <SDL2pp/Mixer.hh>
using namespace SDL2pp;
int main() try {
SDL sdl(SDL_INIT_AUDIO);
Mixer mixer(MIX_DEFAULT_FREQUENCY, AUDIO_S16SYS, 1, 4096);
float frequency = 2093.00f; // C7 tone
int64_t nsample = 0;
// Set custom music hook which generates a sine wave
mixer.SetMusicHook([&nsample, frequency](Uint8* stream, int len) {
// fill provided buffer with sine wave
for (Uint8* ptr = stream; ptr < stream + len; ptr += 2)
*(Uint16*)ptr = (Uint16)(32766.0f * sin(nsample++ / (float)MIX_DEFAULT_FREQUENCY * frequency));
}
);
// Play for 1 second, after which everything is stopped and closed
SDL_Delay(1000);
return 0;
} catch (std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
return 1;
}

4
testdata/README.md vendored
View File

@ -4,6 +4,10 @@ Some test data was taken from third party sources:
* https://www.freesound.org/people/junggle/sounds/30341/ * https://www.freesound.org/people/junggle/sounds/30341/
* http://profiles.google.com/jun66le * http://profiles.google.com/jun66le
* ```test.ogg``` is (0) CC0 by fins from www.freesound.org
* http://www.freesound.org/people/fins/sounds/171671/
* http://www.freesound.org/people/fins/
* ```Vera.ttf``` is (c) 2003 by Bitstream, Inc. All Rights Reserved. * ```Vera.ttf``` is (c) 2003 by Bitstream, Inc. All Rights Reserved.
Bitstream Vera is a trademark of Bitstream, Inc. Bitstream Vera is a trademark of Bitstream, Inc.
See Bitstream-Vera-COPYRIGHT.TXT for details See Bitstream-Vera-COPYRIGHT.TXT for details

BIN
testdata/test.ogg vendored Normal file

Binary file not shown.