Implement mixer playback

This commit is contained in:
Dmitry Marakasov 2015-08-28 23:23:47 +03:00
parent a25c84932c
commit c5dc35574d
3 changed files with 338 additions and 5 deletions

View File

@ -20,6 +20,7 @@
*/
#include <SDL2pp/Mixer.hh>
#include <SDL2pp/Chunk.hh>
#include <SDL2pp/Exception.hh>
namespace SDL2pp {
@ -48,4 +49,80 @@ Mixer& Mixer::operator=(Mixer&& other) noexcept {
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::Pause(int channel) {
Mix_Pause(channel);
}
void Mixer::Resume(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_ExpireChannel(channel, ms);
}
int Mixer::Playing(int channel) const {
return Mix_Playing(channel);
}
int Mixer::Paused(int channel) const {
return Mix_Paused(channel);
}
int Mixer::FadingChannel(int which) const {
return Mix_FadingChannel(which);
}
}

View File

@ -22,13 +22,11 @@
#ifndef SDL2PP_MIXER_HH
#define SDL2PP_MIXER_HH
#include <string>
#include <SDL2/SDL_mixer.h>
namespace SDL2pp {
class RWops;
class Chunk;
////////////////////////////////////////////////////////////
/// \brief SDL_mixer's audio mixer
@ -108,6 +106,249 @@ public:
///
////////////////////////////////////////////////////////////
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 Pause(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 Resume(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);
////////////////////////////////////////////////////////////
/// \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);
// TODO: ChannelFinished
////////////////////////////////////////////////////////////
/// \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 Playing(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 Paused(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
///
////////////////////////////////////////////////////////////
int FadingChannel(int which) const;
// TODO: Groups
// TODO: Music
// TODO: Effects
};
}

View File

@ -36,9 +36,24 @@ int main() try {
SDLMixer mixerlib(MIX_INIT_OGG);
Mixer mixer(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 4096);
// currently fails as audio device hasn't been opened
Chunk chunk(TESTDATA_DIR "/test.ogg");
chunk.Volume(128);
int chan;
chan = mixer.PlayChannel(-1, chunk);
std::cerr << "Playing sound on channel " << chan << "\n";
SDL_Delay(500);
chan = mixer.PlayChannel(-1, chunk);
std::cerr << "Playing sound on channel " << chan << "\n";
SDL_Delay(1000);
chan = mixer.PlayChannel(-1, chunk);
std::cerr << "Playing sound on channel " << chan << "\n";
SDL_Delay(4500);
return 0;
} catch (std::exception& e) {