diff --git a/binding-sandbox/audio-binding.h b/binding-sandbox/audio-binding.h index 336f2ffe..15fae86e 100644 --- a/binding-sandbox/audio-binding.h +++ b/binding-sandbox/audio-binding.h @@ -36,21 +36,37 @@ namespace mkxp_sandbox { wasm_ptr_t filename; int32_t volume; int32_t pitch; + double pos; + int32_t track; + bool have_track; VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) { BOOST_ASIO_CORO_REENTER (this) { volume = 100; pitch = 100; + pos = 0.0; + have_track = false; SANDBOX_AWAIT_AND_SET(filename, rb_string_value_cstr, (VALUE *)(**sb() + argv)); if (argc >= 2) { SANDBOX_AWAIT_AND_SET(volume, rb_num2int, ((VALUE *)(**sb() + argv))[1]); if (argc >= 3) { SANDBOX_AWAIT_AND_SET(pitch, rb_num2int, ((VALUE *)(**sb() + argv))[2]); + if (argc >= 4) { + SANDBOX_AWAIT_AND_SET(pos, rb_num2dbl, ((VALUE *)(**sb() + argv))[3]); + if (argc >= 5) { + SANDBOX_AWAIT_AND_SET(track, rb_num2int, ((VALUE *)(**sb() + argv))[4]); + have_track = true; + } + } } } - mkxp_retro::audio->bgmPlay((const char *)(**sb() + filename), volume, pitch); + if (have_track) { + mkxp_retro::audio->bgmPlay((const char *)(**sb() + filename), volume, pitch, pos, track); + } else { + mkxp_retro::audio->bgmPlay((const char *)(**sb() + filename), volume, pitch, pos); + } } return SANDBOX_NIL; @@ -65,6 +81,113 @@ namespace mkxp_sandbox { return SANDBOX_NIL; } + static VALUE bgs_play(int32_t argc, wasm_ptr_t argv, VALUE self) { + SANDBOX_COROUTINE(coro, + wasm_ptr_t filename; + int32_t volume; + int32_t pitch; + double pos; + + VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) { + BOOST_ASIO_CORO_REENTER (this) { + volume = 100; + pitch = 100; + pos = 0.0; + + SANDBOX_AWAIT_AND_SET(filename, rb_string_value_cstr, (VALUE *)(**sb() + argv)); + if (argc >= 2) { + SANDBOX_AWAIT_AND_SET(volume, rb_num2int, ((VALUE *)(**sb() + argv))[1]); + if (argc >= 3) { + SANDBOX_AWAIT_AND_SET(pitch, rb_num2int, ((VALUE *)(**sb() + argv))[2]); + if (argc >= 4) { + SANDBOX_AWAIT_AND_SET(pos, rb_num2dbl, ((VALUE *)(**sb() + argv))[3]); + } + } + } + + mkxp_retro::audio->bgsPlay((const char *)(**sb() + filename), volume, pitch, pos); + } + + return SANDBOX_NIL; + } + ) + + return sb()->bind()()(argc, argv, self); + } + + static VALUE bgs_stop(VALUE self) { + mkxp_retro::audio->bgsStop(); + return SANDBOX_NIL; + } + + static VALUE me_play(int32_t argc, wasm_ptr_t argv, VALUE self) { + SANDBOX_COROUTINE(coro, + wasm_ptr_t filename; + int32_t volume; + int32_t pitch; + + VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) { + BOOST_ASIO_CORO_REENTER (this) { + volume = 100; + pitch = 100; + + SANDBOX_AWAIT_AND_SET(filename, rb_string_value_cstr, (VALUE *)(**sb() + argv)); + if (argc >= 2) { + SANDBOX_AWAIT_AND_SET(volume, rb_num2int, ((VALUE *)(**sb() + argv))[1]); + if (argc >= 3) { + SANDBOX_AWAIT_AND_SET(pitch, rb_num2int, ((VALUE *)(**sb() + argv))[2]); + } + } + + mkxp_retro::audio->mePlay((const char *)(**sb() + filename), volume, pitch); + } + + return SANDBOX_NIL; + } + ) + + return sb()->bind()()(argc, argv, self); + } + + static VALUE me_stop(VALUE self) { + mkxp_retro::audio->meStop(); + return SANDBOX_NIL; + } + + static VALUE se_play(int32_t argc, wasm_ptr_t argv, VALUE self) { + SANDBOX_COROUTINE(coro, + wasm_ptr_t filename; + int32_t volume; + int32_t pitch; + + VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) { + BOOST_ASIO_CORO_REENTER (this) { + volume = 100; + pitch = 100; + + SANDBOX_AWAIT_AND_SET(filename, rb_string_value_cstr, (VALUE *)(**sb() + argv)); + if (argc >= 2) { + SANDBOX_AWAIT_AND_SET(volume, rb_num2int, ((VALUE *)(**sb() + argv))[1]); + if (argc >= 3) { + SANDBOX_AWAIT_AND_SET(pitch, rb_num2int, ((VALUE *)(**sb() + argv))[2]); + } + } + + mkxp_retro::audio->sePlay((const char *)(**sb() + filename), volume, pitch); + } + + return SANDBOX_NIL; + } + ) + + return sb()->bind()()(argc, argv, self); + } + + static VALUE se_stop(VALUE self) { + mkxp_retro::audio->seStop(); + return SANDBOX_NIL; + } + VALUE module; void operator()() { @@ -76,15 +199,15 @@ namespace mkxp_sandbox { SANDBOX_AWAIT(rb_define_module_function, module, "bgm_pos", (VALUE (*)(ANYARGS))todo, -1); SANDBOX_AWAIT(rb_define_module_function, module, "bgm_volume", (VALUE (*)(ANYARGS))todo, -1); SANDBOX_AWAIT(rb_define_module_function, module, "bgm_set_volume", (VALUE (*)(ANYARGS))todo, -1); - SANDBOX_AWAIT(rb_define_module_function, module, "bgs_play", (VALUE (*)(ANYARGS))todo, -1); - SANDBOX_AWAIT(rb_define_module_function, module, "bgs_stop", (VALUE (*)(ANYARGS))todo, -1); + SANDBOX_AWAIT(rb_define_module_function, module, "bgs_play", (VALUE (*)(ANYARGS))bgs_play, -1); + SANDBOX_AWAIT(rb_define_module_function, module, "bgs_stop", (VALUE (*)(ANYARGS))bgs_stop, 0); SANDBOX_AWAIT(rb_define_module_function, module, "bgs_fade", (VALUE (*)(ANYARGS))todo, -1); SANDBOX_AWAIT(rb_define_module_function, module, "bgs_pos", (VALUE (*)(ANYARGS))todo, -1); - SANDBOX_AWAIT(rb_define_module_function, module, "me_play", (VALUE (*)(ANYARGS))todo, -1); - SANDBOX_AWAIT(rb_define_module_function, module, "me_stop", (VALUE (*)(ANYARGS))todo, -1); + SANDBOX_AWAIT(rb_define_module_function, module, "me_play", (VALUE (*)(ANYARGS))me_play, -1); + SANDBOX_AWAIT(rb_define_module_function, module, "me_stop", (VALUE (*)(ANYARGS))me_stop, 0); SANDBOX_AWAIT(rb_define_module_function, module, "me_fade", (VALUE (*)(ANYARGS))todo, -1); - SANDBOX_AWAIT(rb_define_module_function, module, "se_play", (VALUE (*)(ANYARGS))todo, -1); - SANDBOX_AWAIT(rb_define_module_function, module, "se_stop", (VALUE (*)(ANYARGS))todo, -1); + SANDBOX_AWAIT(rb_define_module_function, module, "se_play", (VALUE (*)(ANYARGS))se_play, -1); + SANDBOX_AWAIT(rb_define_module_function, module, "se_stop", (VALUE (*)(ANYARGS))se_stop, 0); } } ) diff --git a/src/audio/audio.cpp b/src/audio/audio.cpp index 8e1b68fb..fa9cab39 100644 --- a/src/audio/audio.cpp +++ b/src/audio/audio.cpp @@ -44,9 +44,9 @@ struct AudioPrivate AudioStream bgs; AudioStream me; -#ifndef MKXPZ_RETRO SoundEmitter se; +#ifndef MKXPZ_RETRO SyncPoint &syncPoint; #endif // MKXPZ_RETRO @@ -429,16 +429,12 @@ void Audio::sePlay(const char *filename, int volume, int pitch) { -#ifndef MKXPZ_RETRO p->se.play(filename, volume, pitch); -#endif // MKXPZ_RETRO } void Audio::seStop() { -#ifndef MKXPZ_RETRO p->se.stop(); -#endif // MKXPZ_RETRO } void Audio::setupMidi() diff --git a/src/audio/sndfilesource.cpp b/src/audio/sndfilesource.cpp index 261573be..edc63bf4 100644 --- a/src/audio/sndfilesource.cpp +++ b/src/audio/sndfilesource.cpp @@ -26,7 +26,7 @@ #include #include -static SF_VIRTUAL_IO sfvirtual = { +SF_VIRTUAL_IO sfvirtual = { .get_filelen = [](void *handle) { #ifdef MKXPZ_RETRO PHYSFS_Stat stat; diff --git a/src/audio/soundemitter.cpp b/src/audio/soundemitter.cpp index 8d74ca90..beca0e63 100644 --- a/src/audio/soundemitter.cpp +++ b/src/audio/soundemitter.cpp @@ -28,7 +28,9 @@ #include "util.h" #include "debugwriter.h" -#ifndef MKXPZ_RETRO +#ifdef MKXPZ_RETRO +# include +#else # include #endif // MKXPZ_RETRO @@ -90,9 +92,17 @@ arrayPushBack(std::vector &array, size_t size, size_t index) array[size-1] = v; } +#ifdef MKXPZ_RETRO +SoundEmitter::SoundEmitter() +#else SoundEmitter::SoundEmitter(const Config &conf) +#endif // MKXPZ_RETRO : bufferBytes(0), +#ifdef MKXPZ_RETRO + srcCount(6), // TODO: get from config +#else srcCount(conf.SE.sourceCount), +#endif // MKXPZ_RETRO alSrcs(srcCount), atchBufs(srcCount), srcPrio(srcCount) @@ -202,29 +212,60 @@ struct SoundOpenHandler : FileSystem::OpenHandler #endif // MKXPZ_RETRO const char *ext ) { -#ifndef MKXPZ_RETRO +#ifdef MKXPZ_RETRO + extern SF_VIRTUAL_IO sfvirtual; + SndfileHandle handle(sfvirtual, ops.get()); +#else Sound_Sample *sample = Sound_NewSample(&ops, ext, 0, STREAM_BUF_SIZE); +#endif // MKXPZ_RETRO +#ifdef MKXPZ_RETRO + if (handle.error()) +#else if (!sample) +#endif // MKXPZ_RETRO { +#ifndef MKXPZ_RETRO SDL_RWclose(&ops); +#endif // MKXPZ_RETRO return false; } /* Do all of the decoding in the handler so we don't have * to keep the source ops around */ +#ifdef MKXPZ_RETRO + uint8_t sampleSize = 2; + uint32_t sampleCount = handle.frames(); +#else uint32_t decBytes = Sound_DecodeAll(sample); uint8_t sampleSize = formatSampleSize(sample->actual.format); uint32_t sampleCount = decBytes / sampleSize; +#endif // MKXPZ_RETRO buffer = new SoundBuffer; buffer->bytes = sampleSize * sampleCount; - ALenum alFormat = chooseALFormat(sampleSize, sample->actual.channels); + ALenum alFormat = chooseALFormat( + sampleSize, +#ifdef MKXPZ_RETRO + handle.channels() +#else + sample->actual.channels +#endif // MKXPZ_RETRO + ); +#ifdef MKXPZ_RETRO + int16_t *buf = (int16_t *)std::malloc(buffer->bytes); + if (buf == NULL) { + return false; + } + handle.read(buf, sampleCount); + AL::Buffer::uploadData(buffer->alBuffer, alFormat, buf, + buffer->bytes, handle.samplerate()); + std::free(buf); +#else AL::Buffer::uploadData(buffer->alBuffer, alFormat, sample->buffer, buffer->bytes, sample->actual.rate); - Sound_FreeSample(sample); #endif // MKXPZ_RETRO diff --git a/src/audio/soundemitter.h b/src/audio/soundemitter.h index 0a834231..dd6a64b3 100644 --- a/src/audio/soundemitter.h +++ b/src/audio/soundemitter.h @@ -49,7 +49,11 @@ struct SoundEmitter /* Indices of sources, sorted by priority (lowest first) */ std::vector srcPrio; +#ifdef MKXPZ_RETRO + SoundEmitter(); +#else SoundEmitter(const Config &conf); +#endif // MKXPZ_RETRO ~SoundEmitter(); void play(const std::string &filename,