diff --git a/binding-mruby/audio-binding.cpp b/binding-mruby/audio-binding.cpp index 60cff27..5e1acbf 100644 --- a/binding-mruby/audio-binding.cpp +++ b/binding-mruby/audio-binding.cpp @@ -27,7 +27,7 @@ #define DEF_PLAY_STOP(entity) \ MRB_FUNCTION(audio_##entity##Play) \ { \ - return mrb_nil_value();char *filename; \ + char *filename; \ mrb_int volume = 100; \ mrb_int pitch = 100; \ mrb_get_args(mrb, "z|ii", &filename, &volume, &pitch); \ @@ -36,7 +36,7 @@ } \ MRB_FUNCTION(audio_##entity##Stop) \ { \ - return mrb_nil_value();MRB_FUN_UNUSED_PARAM; \ + MRB_FUN_UNUSED_PARAM; \ shState->audio().entity##Stop(); \ return mrb_nil_value(); \ } @@ -44,7 +44,7 @@ #define DEF_FADE(entity) \ MRB_FUNCTION(audio_##entity##Fade) \ { \ - return mrb_nil_value();mrb_int time; \ + mrb_int time; \ mrb_get_args(mrb, "i", &time); \ shState->audio().entity##Fade(time); \ return mrb_nil_value(); \ diff --git a/binding-mruby/graphics-binding.cpp b/binding-mruby/graphics-binding.cpp index 035da21..eeb0278 100644 --- a/binding-mruby/graphics-binding.cpp +++ b/binding-mruby/graphics-binding.cpp @@ -19,6 +19,10 @@ ** along with mkxp. If not, see . */ +#ifdef __EMSCRIPTEN__ +#include "audio.h" +#endif + #include "graphics.h" #include "sharedstate.h" #include "binding-util.h" @@ -30,6 +34,10 @@ MRB_FUNCTION(graphicsUpdate) shState->graphics().update(); +#ifdef __EMSCRIPTEN__ + shState->audio().update(); +#endif + return mrb_nil_value(); } diff --git a/src/alstream.cpp b/src/alstream.cpp index bb9a8ce..2eb74c9 100644 --- a/src/alstream.cpp +++ b/src/alstream.cpp @@ -302,8 +302,12 @@ void ALStream::startStream(float offset) startOffset = offset; procFrames = offset * source->sampleRate(); +#ifdef __EMSCRIPTEN__ + streamData(); +#else thread = createSDLThread (this, threadName); +#endif } void ALStream::pauseStream() @@ -362,7 +366,6 @@ void ALStream::streamData() { /* Fill up queue */ bool firstBuffer = true; - ALDataSource::Status status; if (threadTermReq) return; @@ -406,74 +409,82 @@ void ALStream::streamData() /* Wait for buffers to be consumed, then * refill and queue them up again */ +#ifndef __EMSCRIPTEN__ while (true) { - shState->rtData().syncPoint.passSecondarySync(); - - ALint procBufs = AL::Source::getProcBufferCount(alSrc); - - while (procBufs--) - { - if (threadTermReq) - break; - - AL::Buffer::ID buf = AL::Source::unqueueBuffer(alSrc); - - /* If something went wrong, try again later */ - if (buf == AL::Buffer::ID(0)) - break; - - if (buf == lastBuf) - { - /* Reset the processed sample count so - * querying the playback offset returns 0.0 again */ - procFrames = source->loopStartFrames(); - lastBuf = AL::Buffer::ID(0); - } - else - { - /* Add the frame count contained in this - * buffer to the total count */ - ALint bits = AL::Buffer::getBits(buf); - ALint size = AL::Buffer::getSize(buf); - ALint chan = AL::Buffer::getChannels(buf); - - if (bits != 0 && chan != 0) - procFrames += ((size / (bits / 8)) / chan); - } - - if (sourceExhausted) - continue; - - status = source->fillBuffer(buf); - - if (status == ALDataSource::Error) - { - sourceExhausted.set(); - return; - } - - AL::Source::queueBuffer(alSrc, buf); - - /* In case of buffer underrun, - * start playing again */ - if (AL::Source::getState(alSrc) == AL_STOPPED) - AL::Source::play(alSrc); - - /* If this was the last buffer before the data - * source loop wrapped around again, mark it as - * such so we can catch it and reset the processed - * sample count once it gets unqueued */ - if (status == ALDataSource::WrapAround) - lastBuf = buf; - - if (status == ALDataSource::EndOfStream) - sourceExhausted.set(); - } + streamDevice(); if (threadTermReq) break; - SDL_Delay(AUDIO_SLEEP); } +#endif +} + +void ALStream::update() { + if (threadTermReq) + return; + + shState->rtData().syncPoint.passSecondarySync(); + + ALint procBufs = AL::Source::getProcBufferCount(alSrc); + + while (procBufs--) + { + if (threadTermReq) + break; + + AL::Buffer::ID buf = AL::Source::unqueueBuffer(alSrc); + + /* If something went wrong, try again later */ + if (buf == AL::Buffer::ID(0)) + break; + + if (buf == lastBuf) + { + /* Reset the processed sample count so + * querying the playback offset returns 0.0 again */ + procFrames = source->loopStartFrames(); + lastBuf = AL::Buffer::ID(0); + } + else + { + /* Add the frame count contained in this + * buffer to the total count */ + ALint bits = AL::Buffer::getBits(buf); + ALint size = AL::Buffer::getSize(buf); + ALint chan = AL::Buffer::getChannels(buf); + + if (bits != 0 && chan != 0) + procFrames += ((size / (bits / 8)) / chan); + } + + if (sourceExhausted) + continue; + + status = source->fillBuffer(buf); + + if (status == ALDataSource::Error) + { + sourceExhausted.set(); + return; + } + + AL::Source::queueBuffer(alSrc, buf); + + /* In case of buffer underrun, + * start playing again */ + if (AL::Source::getState(alSrc) == AL_STOPPED) + AL::Source::play(alSrc); + + /* If this was the last buffer before the data + * source loop wrapped around again, mark it as + * such so we can catch it and reset the processed + * sample count once it gets unqueued */ + if (status == ALDataSource::WrapAround) + lastBuf = buf; + + if (status == ALDataSource::EndOfStream) + sourceExhausted.set(); + } } diff --git a/src/alstream.h b/src/alstream.h index e8c1606..3203452 100644 --- a/src/alstream.h +++ b/src/alstream.h @@ -23,13 +23,12 @@ #define ALSTREAM_H #include "al-util.h" +#include "aldatasource.h" #include "sdl-util.h" #include #include -struct ALDataSource; - #define STREAM_BUFS 3 /* State-machine like audio playback stream. @@ -104,6 +103,8 @@ struct ALStream float queryOffset(); bool queryNativePitch(); + void update(); + private: void closeSource(); void openSource(const std::string &filename); @@ -117,6 +118,8 @@ private: /* thread func */ void streamData(); + + ALDataSource::Status status; }; #endif // ALSTREAM_H diff --git a/src/audio.cpp b/src/audio.cpp index d536c70..756a304 100644 --- a/src/audio.cpp +++ b/src/audio.cpp @@ -71,22 +71,27 @@ struct AudioPrivate syncPoint(rtData.syncPoint) { meWatch.state = MeNotPlaying; +#ifndef __EMSCRIPTEN__ meWatch.thread = createSDLThread (this, "audio_mewatch"); +#endif } ~AudioPrivate() { meWatch.termReq.set(); +#ifndef __EMSCRIPTEN__ SDL_WaitThread(meWatch.thread, 0); +#endif } void meWatchFun() { const float fadeOutStep = 1.f / (200 / AUDIO_SLEEP); const float fadeInStep = 1.f / (1000 / AUDIO_SLEEP); - +#ifndef __EMSCRIPTEN__ while (true) +#endif { syncPoint.passSecondarySync(); @@ -231,8 +236,9 @@ struct AudioPrivate break; } } - +#ifndef __EMSCRIPTEN__ SDL_Delay(AUDIO_SLEEP); +#endif } } }; @@ -247,6 +253,7 @@ void Audio::bgmPlay(const char *filename, int pitch, float pos) { + printf("PLAYING BGM %s\n", filename); p->bgm.play(filename, volume, pitch, pos); } @@ -333,4 +340,14 @@ void Audio::reset() p->se.stop(); } +void Audio::update() +{ +#ifdef __EMSCRIPTEN__ + p->bgm.update(); + p->bgm.update(); + p->me.update(); + p->meWatchFun(); +#endif +} + Audio::~Audio() { delete p; } diff --git a/src/audio.h b/src/audio.h index b0aec26..903bb2b 100644 --- a/src/audio.h +++ b/src/audio.h @@ -69,6 +69,8 @@ public: void reset(); + void update(); + private: Audio(RGSSThreadData &rtData); ~Audio(); diff --git a/src/audiostream.cpp b/src/audiostream.cpp index 1d96553..71aadc2 100644 --- a/src/audiostream.cpp +++ b/src/audiostream.cpp @@ -203,12 +203,14 @@ void AudioStream::fadeOut(int duration) return; } +#ifdef __EMSCRIPTEN__ if (fade.thread) { fade.reqFini.set(); SDL_WaitThread(fade.thread, 0); fade.thread = 0; } +#endif fade.active.set(); fade.msStep = 1.0f / duration; @@ -216,8 +218,10 @@ void AudioStream::fadeOut(int duration) fade.reqTerm.clear(); fade.startTicks = SDL_GetTicks(); +#ifndef __EMSCRIPTEN__ fade.thread = createSDLThread (this, fade.threadName); +#endif unlockStream(); } @@ -280,24 +284,38 @@ void AudioStream::finiFadeOutInt() void AudioStream::startFadeIn() { +#ifdef __EMSCRIPTEN__ /* Previous fadein should always be terminated in play() */ assert(!fadeIn.thread); +#endif fadeIn.rqFini.clear(); fadeIn.rqTerm.clear(); fadeIn.startTicks = SDL_GetTicks(); +#ifdef __EMSCRIPTEN__ + fadeInThread(); +#else fadeIn.thread = createSDLThread (this, fadeIn.threadName); +#endif } void AudioStream::fadeOutThread() { +#ifndef __EMSCRIPTEN__ while (true) +#else + if (fade.active) +#endif { /* Just immediately terminate on request */ if (fade.reqTerm) +#ifdef __EMSCRIPTEN__ + return; +#else break; +#endif lockStream(); @@ -315,18 +333,26 @@ void AudioStream::fadeOutThread() setVolume(FadeOut, 1.0f); unlockStream(); - +#ifdef __EMSCRIPTEN__ + fade.active.clear(); + return; +#else break; +#endif + } setVolume(FadeOut, resVol); unlockStream(); - +#ifndef __EMSCRIPTEN__ SDL_Delay(AUDIO_SLEEP); +#endif } +#ifndef __EMSCRIPTEN__ fade.active.clear(); +#endif } void AudioStream::fadeInThread() @@ -363,3 +389,9 @@ void AudioStream::fadeInThread() SDL_Delay(AUDIO_SLEEP); } } + +void AudioStream::update() +{ + fadeOutThread(); + stream.update(); +} diff --git a/src/audiostream.h b/src/audiostream.h index 3f234a0..fa1d039 100644 --- a/src/audiostream.h +++ b/src/audiostream.h @@ -140,6 +140,8 @@ struct AudioStream float playingOffset(); + void update(); + private: float volumes[VolumeTypeCount]; void updateVolume(); diff --git a/src/sdlsoundsource.cpp b/src/sdlsoundsource.cpp index 8e1de83..cffdcd6 100644 --- a/src/sdlsoundsource.cpp +++ b/src/sdlsoundsource.cpp @@ -46,6 +46,7 @@ struct SDLSoundSource : ALDataSource if (!sample) { SDL_RWclose(&ops); + printf("ERROR SDL_sound: %s", Sound_GetError()); throw Exception(Exception::SDLError, "SDL_sound: %s", Sound_GetError()); }