From f76879c6b71c4c94a267ed5c91d0f17c5a54bd15 Mon Sep 17 00:00:00 2001 From: Bart van Strien Date: Sat, 2 Apr 2016 17:38:19 +0200 Subject: [PATCH] New audio playback API Instead of having three states, stopped, paused and playing, now there's only two states: paused and playing. This means resume() is gone, as is isStopped(), and isPaused() has become isPlaying(). stop() now pauses and rewinds, whereas pause() only pauses. rewind() has been removed, and should either be replaced with stop() or seek(0). The same has been applied to the functions in the love.audio module, except they get some extra magic: - love.audio.pause() now returns a table/list of Source objects, which contains only the sources it has just paused. This means you can then later restart only them, instead of everything (as before). - love.audio.play/pause/stop now have variants that take a list of Source objects, and it starts or stops them all at the same time, this means calling play(srcA, srcB) should mean srcA and srcB are much more (but possibly not exactly) synchronised than they were with play(srcA); play(srcB). --HG-- branch : minor --- src/modules/audio/Audio.h | 47 +++-- src/modules/audio/Source.h | 5 +- src/modules/audio/null/Audio.cpp | 26 ++- src/modules/audio/null/Audio.h | 9 +- src/modules/audio/null/Source.cpp | 15 +- src/modules/audio/null/Source.h | 5 +- src/modules/audio/openal/Audio.cpp | 39 ++-- src/modules/audio/openal/Audio.h | 10 +- src/modules/audio/openal/Pool.cpp | 140 ++++++++------ src/modules/audio/openal/Pool.h | 16 +- src/modules/audio/openal/Source.cpp | 290 +++++++++++++++------------- src/modules/audio/openal/Source.h | 19 +- src/modules/audio/wrap_Audio.cpp | 74 +++---- src/modules/audio/wrap_Source.cpp | 34 +--- src/modules/video/VideoStream.cpp | 2 +- 15 files changed, 356 insertions(+), 375 deletions(-) diff --git a/src/modules/audio/Audio.h b/src/modules/audio/Audio.h index 4cd59ced8..5a823338e 100644 --- a/src/modules/audio/Audio.h +++ b/src/modules/audio/Audio.h @@ -21,6 +21,10 @@ #ifndef LOVE_AUDIO_AUDIO_H #define LOVE_AUDIO_AUDIO_H +// STL +#include + +// LOVE #include "common/Module.h" #include "common/StringMap.h" #include "Source.h" @@ -90,12 +94,24 @@ public: **/ virtual bool play(Source *source) = 0; + /** + * Play the specified Sources. + * @param sources The Sources to play. + **/ + virtual bool play(const std::vector &sources) = 0; + /** * Stops playback on the specified source. * @param source The source on which to stop the playback. **/ virtual void stop(Source *source) = 0; + /** + * Stops playback on the specified sources. + * @param sources The sources on which to stop the playback. + **/ + virtual void stop(const std::vector &sources) = 0; + /** * Stops all playing audio. **/ @@ -107,33 +123,16 @@ public: **/ virtual void pause(Source *source) = 0; + /** + * Pauses playback on the specified sources. + * @param sources The sources on which to pause the playback. + **/ + virtual void pause(const std::vector &sources) = 0; + /** * Pauses all audio. **/ - virtual void pause() = 0; - - /** - * Resumes playback on the specified source. - * @param source The source on which to resume the playback. - **/ - virtual void resume(Source *source) = 0; - - /** - * Resumes all audio. - **/ - virtual void resume() = 0; - - /** - * Rewinds the specified source. Whatever is playing on this - * source gets rewound to the start. - * @param source The source to rewind. - **/ - virtual void rewind(Source *source) = 0; - - /** - * Rewinds all playing audio. - **/ - virtual void rewind() = 0; + virtual std::vector pause() = 0; /** * Sets the master volume, where 0.0f is min (off) and 1.0f is max. diff --git a/src/modules/audio/Source.h b/src/modules/audio/Source.h index a4c5d4d95..7530b91db 100644 --- a/src/modules/audio/Source.h +++ b/src/modules/audio/Source.h @@ -56,10 +56,7 @@ public: virtual bool play() = 0; virtual void stop() = 0; virtual void pause() = 0; - virtual void resume() = 0; - virtual void rewind() = 0; - virtual bool isStopped() const = 0; - virtual bool isPaused() const = 0; + virtual bool isPlaying() const = 0; virtual bool isFinished() const = 0; virtual bool update() = 0; diff --git a/src/modules/audio/null/Audio.cpp b/src/modules/audio/null/Audio.cpp index ea9ac5e05..376bfae00 100644 --- a/src/modules/audio/null/Audio.cpp +++ b/src/modules/audio/null/Audio.cpp @@ -66,10 +66,19 @@ bool Audio::play(love::audio::Source *) return false; } +bool Audio::play(const std::vector&) +{ + return false; +} + void Audio::stop(love::audio::Source *) { } +void Audio::stop(const std::vector&) +{ +} + void Audio::stop() { } @@ -78,24 +87,13 @@ void Audio::pause(love::audio::Source *) { } -void Audio::pause() +void Audio::pause(const std::vector&) { } -void Audio::resume(love::audio::Source *) -{ -} - -void Audio::resume() -{ -} - -void Audio::rewind(love::audio::Source *) -{ -} - -void Audio::rewind() +std::vector Audio::pause() { + return {}; } void Audio::setVolume(float volume) diff --git a/src/modules/audio/null/Audio.h b/src/modules/audio/null/Audio.h index 0be0ecc62..d186ccff2 100644 --- a/src/modules/audio/null/Audio.h +++ b/src/modules/audio/null/Audio.h @@ -49,14 +49,13 @@ public: int getSourceCount() const; int getMaxSources() const; bool play(love::audio::Source *source); + bool play(const std::vector &sources); void stop(love::audio::Source *source); + void stop(const std::vector &sources); void stop(); void pause(love::audio::Source *source); - void pause(); - void resume(love::audio::Source *source); - void resume(); - void rewind(love::audio::Source *source); - void rewind(); + void pause(const std::vector &sources); + std::vector pause(); void setVolume(float volume); float getVolume() const; diff --git a/src/modules/audio/null/Source.cpp b/src/modules/audio/null/Source.cpp index bf79968f0..1a6b205a9 100644 --- a/src/modules/audio/null/Source.cpp +++ b/src/modules/audio/null/Source.cpp @@ -55,20 +55,7 @@ void Source::pause() { } -void Source::resume() -{ -} - -void Source::rewind() -{ -} - -bool Source::isStopped() const -{ - return true; -} - -bool Source::isPaused() const +bool Source::isPlaying() const { return false; } diff --git a/src/modules/audio/null/Source.h b/src/modules/audio/null/Source.h index ec07d45aa..7feceee77 100644 --- a/src/modules/audio/null/Source.h +++ b/src/modules/audio/null/Source.h @@ -42,10 +42,7 @@ public: virtual bool play(); virtual void stop(); virtual void pause(); - virtual void resume(); - virtual void rewind(); - virtual bool isStopped() const; - virtual bool isPaused() const; + virtual bool isPlaying() const; virtual bool isFinished() const; virtual bool update(); virtual void setPitch(float pitch); diff --git a/src/modules/audio/openal/Audio.cpp b/src/modules/audio/openal/Audio.cpp index 7df930f05..9a7c00016 100644 --- a/src/modules/audio/openal/Audio.cpp +++ b/src/modules/audio/openal/Audio.cpp @@ -172,11 +172,21 @@ bool Audio::play(love::audio::Source *source) return source->play(); } +bool Audio::play(const std::vector &sources) +{ + return pool->play(sources); +} + void Audio::stop(love::audio::Source *source) { source->stop(); } +void Audio::stop(const std::vector &sources) +{ + return pool->stop(sources); +} + void Audio::stop() { pool->stop(); @@ -187,35 +197,14 @@ void Audio::pause(love::audio::Source *source) source->pause(); } -void Audio::pause() +void Audio::pause(const std::vector &sources) { - pool->pause(); -#ifdef LOVE_ANDROID - alcDevicePauseSOFT(device); -#endif + return pool->pause(sources); } -void Audio::resume(love::audio::Source *source) +std::vector Audio::pause() { - source->resume(); -} - -void Audio::resume() -{ -#ifdef LOVE_ANDROID - alcDeviceResumeSOFT(device); -#endif - pool->resume(); -} - -void Audio::rewind(love::audio::Source *source) -{ - source->rewind(); -} - -void Audio::rewind() -{ - pool->rewind(); + return pool->pause(); } void Audio::setVolume(float volume) diff --git a/src/modules/audio/openal/Audio.h b/src/modules/audio/openal/Audio.h index b33731e23..e7a246410 100644 --- a/src/modules/audio/openal/Audio.h +++ b/src/modules/audio/openal/Audio.h @@ -24,6 +24,7 @@ // STD #include #include +#include #include // LOVE @@ -73,14 +74,13 @@ public: int getSourceCount() const; int getMaxSources() const; bool play(love::audio::Source *source); + bool play(const std::vector &sources); void stop(love::audio::Source *source); + void stop(const std::vector &sources); void stop(); void pause(love::audio::Source *source); - void pause(); - void resume(love::audio::Source *source); - void resume(); - void rewind(love::audio::Source *source); - void rewind(); + void pause(const std::vector &sources); + std::vector pause(); void setVolume(float volume); float getVolume() const; diff --git a/src/modules/audio/openal/Pool.cpp b/src/modules/audio/openal/Pool.cpp index 1e662640e..6ccd325f4 100644 --- a/src/modules/audio/openal/Pool.cpp +++ b/src/modules/audio/openal/Pool.cpp @@ -110,7 +110,6 @@ void Pool::update() if (!i->first->update()) { i->first->stopAtomic(); - i->first->rewindAtomic(); i->first->release(); available.push(i->second); playing.erase(i++); @@ -130,44 +129,72 @@ int Pool::getMaxSources() const return totalSources; } -bool Pool::play(Source *source, ALuint &out) +bool Pool::assignSource(Source *source, ALuint &out, char *wasPlaying) +{ + out = 0; + + if (findSource(source, out)) + { + if (wasPlaying) + *wasPlaying = true; + return true; + } + + if (wasPlaying) + *wasPlaying = false; + + if (available.empty()) + return false; + + out = available.front(); + available.pop(); + + playing.insert(std::make_pair(source, out)); + source->retain(); + return true; +} + +bool Pool::play(Source *source) +{ + thread::Lock lock(mutex); + ALuint out; + + char wasPlaying; + if (!assignSource(source, out, &wasPlaying)) + return false; + + if (!wasPlaying) + return source->playAtomic(out); + else + { + source->resumeAtomic(); + return true; + } +} + +bool Pool::play(const std::vector &sources) { thread::Lock lock(mutex); - bool ok = true; - out = 0; + std::vector ids(sources.size()); + // NOTE: not bool, because std::vector is implemented as a bitvector + // which means no pointers can be created. + std::vector wasPlaying(sources.size()); - bool alreadyPlaying = findSource(source, out); - - if (!alreadyPlaying) + for (size_t i = 0; i < sources.size(); i++) { - // Try to play. - if (!available.empty()) + Source *source = (Source*) sources[i]; + if (!assignSource(source, ids[i], &wasPlaying[i])) { - // Get the first available source. - out = available.front(); - - // Remove it. - available.pop(); - - // Insert into map of playing sources. - playing.insert(std::pair(source, out)); - - source->retain(); - - ok = source->playAtomic(); - } - else - { - ok = false; + // Now we need to release the resources we had already allocated + for (size_t j = 0; j < sources.size(); j++) + if (!wasPlaying[j]) + release((Source*) sources[j]); + return false; } } - else - { - ok = true; - } - return ok; + return Source::playAtomic(sources, ids, wasPlaying); } void Pool::stop() @@ -176,7 +203,6 @@ void Pool::stop() for (const auto &i : playing) { i.first->stopAtomic(); - i.first->rewindAtomic(); i.first->release(); available.push(i.second); } @@ -190,11 +216,28 @@ void Pool::stop(Source *source) removeSource(source); } -void Pool::pause() +void Pool::stop(const std::vector &sources) { thread::Lock lock(mutex); + Source::stopAtomic(sources); +} + +std::vector Pool::pause() +{ + thread::Lock lock(mutex); + + std::vector werePlaying; + werePlaying.reserve(playing.size()); + for (const auto &i : playing) + { + if (!i.first->isPlaying()) + continue; + werePlaying.push_back(i.first); i.first->pauseAtomic(); + } + + return werePlaying; } void Pool::pause(Source *source) @@ -205,39 +248,10 @@ void Pool::pause(Source *source) source->pauseAtomic(); } -void Pool::resume() +void Pool::pause(const std::vector &sources) { thread::Lock lock(mutex); - for (const auto &i : playing) - i.first->resumeAtomic(); -} - -void Pool::resume(Source *source) -{ - thread::Lock lock(mutex); - ALuint out; - if (findSource(source, out)) - source->resumeAtomic(); -} - -void Pool::rewind() -{ - thread::Lock lock(mutex); - for (const auto &i : playing) - i.first->rewindAtomic(); -} - -// For those times we don't need it backed. -void Pool::softRewind(Source *source) -{ - thread::Lock lock(mutex); - source->rewindAtomic(); -} - -void Pool::rewind(Source *source) -{ - thread::Lock lock(mutex); - source->rewindAtomic(); + Source::pauseAtomic(sources); } void Pool::release(Source *source) diff --git a/src/modules/audio/openal/Pool.h b/src/modules/audio/openal/Pool.h index b4417b4d6..82b1272d6 100644 --- a/src/modules/audio/openal/Pool.h +++ b/src/modules/audio/openal/Pool.h @@ -24,12 +24,14 @@ // STD #include #include +#include #include // LOVE #include "common/config.h" #include "common/Exception.h" #include "thread/threads.h" +#include "audio/Source.h" // OpenAL #ifdef LOVE_APPLE_USE_FRAMEWORKS @@ -81,20 +83,19 @@ public: int getSourceCount() const; int getMaxSources() const; - bool play(Source *source, ALuint &out); + bool play(Source *source); void stop(); void stop(Source *source); - void pause(); + std::vector pause(); void pause(Source *source); - void resume(); - void resume(Source *source); - void rewind(); - void rewind(Source *source); - void softRewind(Source *source); void seek(Source *source, float offset, void *unit); float tell(Source *source, void *unit); double getDuration(Source *source, void *unit); + bool play(const std::vector &sources); + void stop(const std::vector &sources); + void pause(const std::vector &sources); + private: /** @@ -105,6 +106,7 @@ private: ALuint findi(const Source *source) const; + bool assignSource(Source *source, ALuint &out, char *wasPlaying = nullptr); bool findSource(Source *source, ALuint &out); bool removeSource(Source *source); diff --git a/src/modules/audio/openal/Source.cpp b/src/modules/audio/openal/Source.cpp index a58c1fe79..6ea77ffb9 100644 --- a/src/modules/audio/openal/Source.cpp +++ b/src/modules/audio/openal/Source.cpp @@ -85,7 +85,6 @@ Source::Source(Pool *pool, love::sound::SoundData *soundData) , volume(1.0f) , relative(false) , looping(false) - , paused(false) , minVolume(0.0f) , maxVolume(1.0f) , referenceDistance(1.0f) @@ -122,7 +121,6 @@ Source::Source(Pool *pool, love::sound::Decoder *decoder) , volume(1.0f) , relative(false) , looping(false) - , paused(false) , minVolume(0.0f) , maxVolume(1.0f) , referenceDistance(1.0f) @@ -158,7 +156,6 @@ Source::Source(const Source &s) , volume(s.volume) , relative(s.relative) , looping(s.looping) - , paused(false) , minVolume(s.minVolume) , maxVolume(s.maxVolume) , referenceDistance(s.referenceDistance) @@ -202,23 +199,14 @@ love::audio::Source *Source::clone() bool Source::play() { - if (valid && paused) - { - pool->resume(this); - return true; - } - - valid = pool->play(this, source); + valid = pool->play(this); return valid; } void Source::stop() { - if (!isStopped()) - { + if (valid) pool->stop(this); - pool->softRewind(this); - } } void Source::pause() @@ -226,43 +214,27 @@ void Source::pause() pool->pause(this); } -void Source::resume() +bool Source::isPlaying() const { - pool->resume(this); -} + if (!valid) + return false; -void Source::rewind() -{ - pool->rewind(this); -} - -bool Source::isStopped() const -{ - if (valid) - { - ALenum state; - alGetSourcei(source, AL_SOURCE_STATE, &state); - return (state == AL_STOPPED); - } - - return true; -} - -bool Source::isPaused() const -{ - if (valid) - { - ALenum state; - alGetSourcei(source, AL_SOURCE_STATE, &state); - return (state == AL_PAUSED); - } - - return false; + ALenum state; + alGetSourcei(source, AL_SOURCE_STATE, &state); + return state == AL_PLAYING; } bool Source::isFinished() const { - return type == TYPE_STATIC ? isStopped() : (isStopped() && !isLooping() && decoder->isFinished()); + if (!valid) + return false; + + if (type == TYPE_STREAM && (isLooping() || !decoder->isFinished())) + return false; + + ALenum state; + alGetSourcei(source, AL_SOURCE_STATE, &state); + return state == AL_STOPPED; } bool Source::update() @@ -274,7 +246,7 @@ bool Source::update() { // Looping mode could have changed. alSourcei(source, AL_LOOPING, isLooping() ? AL_TRUE : AL_FALSE); - return !isStopped(); + return !isFinished(); } else if (type == TYPE_STREAM && (isLooping() || !isFinished())) { @@ -362,45 +334,46 @@ float Source::getVolume() const void Source::seekAtomic(float offset, void *unit) { - if (valid) + if (!valid) + return; + + bool waspaused = !isPlaying(); + + // To drain all buffers + if (type == TYPE_STREAM) + stopAtomic(); + + switch (*((Source::Unit *) unit)) { - switch (*((Source::Unit *) unit)) - { - case Source::UNIT_SAMPLES: - if (type == TYPE_STREAM) - { - offsetSamples = offset; - offset /= decoder->getSampleRate(); - offsetSeconds = offset; - decoder->seek(offset); - } - else - alSourcef(source, AL_SAMPLE_OFFSET, offset); - break; - case Source::UNIT_SECONDS: - default: - if (type == TYPE_STREAM) - { - offsetSeconds = offset; - decoder->seek(offset); - offsetSamples = offset * decoder->getSampleRate(); - } - else - alSourcef(source, AL_SEC_OFFSET, offset); - break; - } + case Source::UNIT_SAMPLES: if (type == TYPE_STREAM) { - bool waspaused = paused; - // Because we still have old data - // from before the seek in the buffers - // let's empty them. - stopAtomic(); - playAtomic(); - if (waspaused) - pauseAtomic(); + offsetSamples = offset; + offset /= decoder->getSampleRate(); + offsetSeconds = offset; + decoder->seek(offset); } + else + alSourcef(source, AL_SAMPLE_OFFSET, offset); + break; + case Source::UNIT_SECONDS: + default: + if (type == TYPE_STREAM) + { + offsetSeconds = offset; + decoder->seek(offset); + offsetSamples = offset * decoder->getSampleRate(); + } + else + alSourcef(source, AL_SEC_OFFSET, offset); + break; } + + if (type == TYPE_STREAM) + playAtomic(source); + + if (waspaused) + pauseAtomic(); } void Source::seek(float offset, Source::Unit unit) @@ -593,7 +566,7 @@ bool Source::isLooping() const return looping; } -bool Source::playAtomic() +void Source::prepareAtomic() { if (type == TYPE_STATIC) { @@ -622,6 +595,38 @@ bool Source::playAtomic() // the properties of another love Source. Let's reset it to the settings // of the new one. reset(); +} + +void Source::teardownAtomic() +{ + if (type == TYPE_STATIC) + { + alSourcef(source, AL_SAMPLE_OFFSET, 0); + } + else if (type == TYPE_STREAM) + { + decoder->seek(0); + + int queued = 0; + alGetSourcei(source, AL_BUFFERS_QUEUED, &queued); + + while (queued--) + { + ALuint buffer; + alSourceUnqueueBuffers(source, 1, &buffer); + } + } + + alSourcei(source, AL_BUFFER, AL_NONE); + + toLoop = 0; + valid = false; +} + +bool Source::playAtomic(ALuint source) +{ + this->source = source; + prepareAtomic(); // Clear errors. alGetError(); @@ -640,76 +645,93 @@ bool Source::playAtomic() void Source::stopAtomic() { - if (valid) - { - if (type == TYPE_STATIC) - alSourceStop(source); - else if (type == TYPE_STREAM) - { - alSourceStop(source); - int queued = 0; - alGetSourcei(source, AL_BUFFERS_QUEUED, &queued); - - while (queued--) - { - ALuint buffer; - alSourceUnqueueBuffers(source, 1, &buffer); - } - } - - alSourcei(source, AL_BUFFER, AL_NONE); - } - - toLoop = 0; - valid = false; + if (!valid) + return; + alSourceStop(source); + teardownAtomic(); } void Source::pauseAtomic() { if (valid) - { alSourcePause(source); - paused = true; - } } void Source::resumeAtomic() { - if (valid && paused) - { + if (valid && !isPlaying()) alSourcePlay(source); - paused = false; +} + +bool Source::playAtomic(const std::vector &sources, const std::vector &ids, const std::vector &wasPlaying) +{ + if (sources.size() == 0) + return true; + + std::vector toPlay; + toPlay.reserve(sources.size()); + for (size_t i = 0; i < sources.size(); i++) + { + if (wasPlaying[i]) + continue; + Source *source = (Source*) sources[i]; + source->source = ids[i]; + source->prepareAtomic(); + toPlay.push_back(ids[i]); + } + + alGetError(); + alSourcePlayv(toPlay.size(), &toPlay[0]); + bool success = alGetError() == AL_NO_ERROR; + + for (auto &_source : sources) + { + Source *source = (Source*) _source; + source->valid = source->valid || success; + } + + return success; +} + +void Source::stopAtomic(const std::vector &sources) +{ + if (sources.size() == 0) + return; + + std::vector sourceIds; + sourceIds.reserve(sources.size()); + for (auto &_source : sources) + { + Source *source = (Source*) _source; + if (source->valid) + sourceIds.push_back(source->source); + } + + alSourceStopv(sources.size(), &sourceIds[0]); + + for (auto &_source : sources) + { + Source *source = (Source*) _source; + if (source->valid) + source->teardownAtomic(); } } -void Source::rewindAtomic() +void Source::pauseAtomic(const std::vector &sources) { - if (valid && type == TYPE_STATIC) + if (sources.size() == 0) + return; + + std::vector sourceIds; + sourceIds.reserve(sources.size()); + for (auto &_source : sources) { - alSourceRewind(source); - if (!paused) - alSourcePlay(source); - } - else if (valid && type == TYPE_STREAM) - { - bool waspaused = paused; - decoder->rewind(); - // Because we still have old data - // from before the seek in the buffers - // let's empty them. - stopAtomic(); - playAtomic(); - if (waspaused) - pauseAtomic(); - offsetSamples = 0; - offsetSeconds = 0; - } - else if (type == TYPE_STREAM) - { - decoder->rewind(); - offsetSamples = 0; - offsetSeconds = 0; + Source *source = (Source*) _source; + if (source->valid) + sourceIds.push_back(source->source); } + + alSourcePausev(sources.size(), &sourceIds[0]); } void Source::reset() diff --git a/src/modules/audio/openal/Source.h b/src/modules/audio/openal/Source.h index 555778a39..14fb6b1df 100644 --- a/src/modules/audio/openal/Source.h +++ b/src/modules/audio/openal/Source.h @@ -28,6 +28,9 @@ #include "sound/SoundData.h" #include "sound/Decoder.h" +// STL +#include + // OpenAL #ifdef LOVE_APPLE_USE_FRAMEWORKS #ifdef LOVE_IOS @@ -90,10 +93,7 @@ public: virtual bool play(); virtual void stop(); virtual void pause(); - virtual void resume(); - virtual void rewind(); - virtual bool isStopped() const; - virtual bool isPaused() const; + virtual bool isPlaying() const; virtual bool isFinished() const; virtual bool update(); virtual void setPitch(float pitch); @@ -130,11 +130,17 @@ public: virtual float getMaxDistance() const; virtual int getChannels() const; - bool playAtomic(); + void prepareAtomic(); + void teardownAtomic(); + + bool playAtomic(ALuint source); void stopAtomic(); void pauseAtomic(); void resumeAtomic(); - void rewindAtomic(); + + static bool playAtomic(const std::vector &sources, const std::vector &ids, const std::vector &wasPlaying); + static void stopAtomic(const std::vector &sources); + static void pauseAtomic(const std::vector &sources); private: @@ -169,7 +175,6 @@ private: float direction[3]; bool relative; bool looping; - bool paused; float minVolume; float maxVolume; float referenceDistance; diff --git a/src/modules/audio/wrap_Audio.cpp b/src/modules/audio/wrap_Audio.cpp index 52abf3110..32e77f251 100644 --- a/src/modules/audio/wrap_Audio.cpp +++ b/src/modules/audio/wrap_Audio.cpp @@ -75,8 +75,32 @@ int w_newSource(lua_State *L) return luax_typerror(L, 1, "Decoder or SoundData"); } +static std::vector readSourceList(lua_State *L, int n) +{ + if (n < 0) + n += lua_gettop(L) + 1; + + size_t items = lua_objlen(L, n); + std::vector sources(items); + + for (size_t i = 0; i < items; i++) + { + lua_rawgeti(L, n, i+1); + sources[i] = luax_checksource(L, -1); + lua_pop(L, 1); + } + + return sources; +} + int w_play(lua_State *L) { + if (lua_istable(L, 1)) + { + luax_pushboolean(L, instance()->play(readSourceList(L, 1))); + return 1; + } + Source *s = luax_checksource(L, 1); luax_pushboolean(L, instance()->play(s)); return 1; @@ -84,10 +108,10 @@ int w_play(lua_State *L) int w_stop(lua_State *L) { - if (lua_gettop(L) == 0) - { + if (lua_isnone(L, 1)) instance()->stop(); - } + else if (lua_istable(L, 1)) + instance()->stop(readSourceList(L, 1)); else { Source *s = luax_checksource(L, 1); @@ -98,10 +122,20 @@ int w_stop(lua_State *L) int w_pause(lua_State *L) { - if (lua_gettop(L) == 0) + if (lua_isnone(L, 1)) { - instance()->pause(); + auto sources = instance()->pause(); + + lua_createtable(L, sources.size(), 0); + for (size_t i = 0; i < sources.size(); i++) + { + luax_pushtype(L, AUDIO_SOURCE_ID, sources[i]); + lua_rawseti(L, -2, i+1); + } + return 1; } + else if (lua_istable(L, 1)) + instance()->pause(readSourceList(L, 1)); else { Source *s = luax_checksource(L, 1); @@ -111,34 +145,6 @@ int w_pause(lua_State *L) return 0; } -int w_resume(lua_State *L) -{ - if (lua_gettop(L) == 0) - { - instance()->resume(); - } - else - { - Source *s = luax_checksource(L, 1); - s->resume(); - } - return 0; -} - -int w_rewind(lua_State *L) -{ - if (lua_gettop(L) == 0) - { - instance()->rewind(); - } - else - { - Source *s = luax_checksource(L, 1); - s->rewind(); - } - return 0; -} - int w_setVolume(lua_State *L) { float v = (float)luaL_checknumber(L, 1); @@ -301,8 +307,6 @@ static const luaL_Reg functions[] = { "play", w_play }, { "stop", w_stop }, { "pause", w_pause }, - { "resume", w_resume }, - { "rewind", w_rewind }, { "setVolume", w_setVolume }, { "getVolume", w_getVolume }, { "setPosition", w_setPosition }, diff --git a/src/modules/audio/wrap_Source.cpp b/src/modules/audio/wrap_Source.cpp index f45a2358a..f4bdaa397 100644 --- a/src/modules/audio/wrap_Source.cpp +++ b/src/modules/audio/wrap_Source.cpp @@ -63,20 +63,6 @@ int w_Source_pause(lua_State *L) return 0; } -int w_Source_resume(lua_State *L) -{ - Source *t = luax_checksource(L, 1); - t->resume(); - return 0; -} - -int w_Source_rewind(lua_State *L) -{ - Source *t = luax_checksource(L, 1); - t->rewind(); - return 0; -} - int w_Source_setPitch(lua_State *L) { Source *t = luax_checksource(L, 1); @@ -268,24 +254,10 @@ int w_Source_isLooping(lua_State *L) return 1; } -int w_Source_isStopped(lua_State *L) -{ - Source *t = luax_checksource(L, 1); - luax_pushboolean(L, t->isStopped()); - return 1; -} - -int w_Source_isPaused(lua_State *L) -{ - Source *t = luax_checksource(L, 1); - luax_pushboolean(L, t->isPaused()); - return 1; -} - int w_Source_isPlaying(lua_State *L) { Source *t = luax_checksource(L, 1); - luax_pushboolean(L, !t->isStopped() && !t->isPaused()); + luax_pushboolean(L, t->isPlaying()); return 1; } @@ -377,8 +349,6 @@ static const luaL_Reg w_Source_functions[] = { "play", w_Source_play }, { "stop", w_Source_stop }, { "pause", w_Source_pause }, - { "resume", w_Source_resume }, - { "rewind", w_Source_rewind }, { "setPitch", w_Source_setPitch }, { "getPitch", w_Source_getPitch }, @@ -401,8 +371,6 @@ static const luaL_Reg w_Source_functions[] = { "setLooping", w_Source_setLooping }, { "isLooping", w_Source_isLooping }, - { "isStopped", w_Source_isStopped }, - { "isPaused", w_Source_isPaused }, { "isPlaying", w_Source_isPlaying }, { "setVolumeLimits", w_Source_setVolumeLimits }, diff --git a/src/modules/video/VideoStream.cpp b/src/modules/video/VideoStream.cpp index 8e976951a..b231fde7b 100644 --- a/src/modules/video/VideoStream.cpp +++ b/src/modules/video/VideoStream.cpp @@ -161,7 +161,7 @@ void VideoStream::SourceSync::seek(double time) bool VideoStream::SourceSync::isPlaying() const { - return !source->isStopped() && !source->isPaused(); + return source->isPlaying(); } } // video