mirror of
https://github.com/mkxp-z/mkxp-z.git
synced 2025-08-29 18:23:03 +02:00
Implement playing sound effects in libretro builds
This commit is contained in:
parent
1c4d65e02e
commit
8ed8c5c984
5 changed files with 181 additions and 17 deletions
|
@ -36,21 +36,37 @@ namespace mkxp_sandbox {
|
||||||
wasm_ptr_t filename;
|
wasm_ptr_t filename;
|
||||||
int32_t volume;
|
int32_t volume;
|
||||||
int32_t pitch;
|
int32_t pitch;
|
||||||
|
double pos;
|
||||||
|
int32_t track;
|
||||||
|
bool have_track;
|
||||||
|
|
||||||
VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) {
|
VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) {
|
||||||
BOOST_ASIO_CORO_REENTER (this) {
|
BOOST_ASIO_CORO_REENTER (this) {
|
||||||
volume = 100;
|
volume = 100;
|
||||||
pitch = 100;
|
pitch = 100;
|
||||||
|
pos = 0.0;
|
||||||
|
have_track = false;
|
||||||
|
|
||||||
SANDBOX_AWAIT_AND_SET(filename, rb_string_value_cstr, (VALUE *)(**sb() + argv));
|
SANDBOX_AWAIT_AND_SET(filename, rb_string_value_cstr, (VALUE *)(**sb() + argv));
|
||||||
if (argc >= 2) {
|
if (argc >= 2) {
|
||||||
SANDBOX_AWAIT_AND_SET(volume, rb_num2int, ((VALUE *)(**sb() + argv))[1]);
|
SANDBOX_AWAIT_AND_SET(volume, rb_num2int, ((VALUE *)(**sb() + argv))[1]);
|
||||||
if (argc >= 3) {
|
if (argc >= 3) {
|
||||||
SANDBOX_AWAIT_AND_SET(pitch, rb_num2int, ((VALUE *)(**sb() + argv))[2]);
|
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;
|
return SANDBOX_NIL;
|
||||||
|
@ -65,6 +81,113 @@ namespace mkxp_sandbox {
|
||||||
return SANDBOX_NIL;
|
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<struct coro>()()(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<struct coro>()()(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<struct coro>()()(argc, argv, self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE se_stop(VALUE self) {
|
||||||
|
mkxp_retro::audio->seStop();
|
||||||
|
return SANDBOX_NIL;
|
||||||
|
}
|
||||||
|
|
||||||
VALUE module;
|
VALUE module;
|
||||||
|
|
||||||
void operator()() {
|
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_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_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, "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_play", (VALUE (*)(ANYARGS))bgs_play, -1);
|
||||||
SANDBOX_AWAIT(rb_define_module_function, module, "bgs_stop", (VALUE (*)(ANYARGS))todo, -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_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, "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_play", (VALUE (*)(ANYARGS))me_play, -1);
|
||||||
SANDBOX_AWAIT(rb_define_module_function, module, "me_stop", (VALUE (*)(ANYARGS))todo, -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, "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_play", (VALUE (*)(ANYARGS))se_play, -1);
|
||||||
SANDBOX_AWAIT(rb_define_module_function, module, "se_stop", (VALUE (*)(ANYARGS))todo, -1);
|
SANDBOX_AWAIT(rb_define_module_function, module, "se_stop", (VALUE (*)(ANYARGS))se_stop, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -44,9 +44,9 @@ struct AudioPrivate
|
||||||
AudioStream bgs;
|
AudioStream bgs;
|
||||||
AudioStream me;
|
AudioStream me;
|
||||||
|
|
||||||
#ifndef MKXPZ_RETRO
|
|
||||||
SoundEmitter se;
|
SoundEmitter se;
|
||||||
|
|
||||||
|
#ifndef MKXPZ_RETRO
|
||||||
SyncPoint &syncPoint;
|
SyncPoint &syncPoint;
|
||||||
#endif // MKXPZ_RETRO
|
#endif // MKXPZ_RETRO
|
||||||
|
|
||||||
|
@ -429,16 +429,12 @@ void Audio::sePlay(const char *filename,
|
||||||
int volume,
|
int volume,
|
||||||
int pitch)
|
int pitch)
|
||||||
{
|
{
|
||||||
#ifndef MKXPZ_RETRO
|
|
||||||
p->se.play(filename, volume, pitch);
|
p->se.play(filename, volume, pitch);
|
||||||
#endif // MKXPZ_RETRO
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::seStop()
|
void Audio::seStop()
|
||||||
{
|
{
|
||||||
#ifndef MKXPZ_RETRO
|
|
||||||
p->se.stop();
|
p->se.stop();
|
||||||
#endif // MKXPZ_RETRO
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::setupMidi()
|
void Audio::setupMidi()
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <sndfile.hh>
|
#include <sndfile.hh>
|
||||||
|
|
||||||
static SF_VIRTUAL_IO sfvirtual = {
|
SF_VIRTUAL_IO sfvirtual = {
|
||||||
.get_filelen = [](void *handle) {
|
.get_filelen = [](void *handle) {
|
||||||
#ifdef MKXPZ_RETRO
|
#ifdef MKXPZ_RETRO
|
||||||
PHYSFS_Stat stat;
|
PHYSFS_Stat stat;
|
||||||
|
|
|
@ -28,7 +28,9 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "debugwriter.h"
|
#include "debugwriter.h"
|
||||||
|
|
||||||
#ifndef MKXPZ_RETRO
|
#ifdef MKXPZ_RETRO
|
||||||
|
# include <sndfile.hh>
|
||||||
|
#else
|
||||||
# include <SDL_sound.h>
|
# include <SDL_sound.h>
|
||||||
#endif // MKXPZ_RETRO
|
#endif // MKXPZ_RETRO
|
||||||
|
|
||||||
|
@ -90,9 +92,17 @@ arrayPushBack(std::vector<size_t> &array, size_t size, size_t index)
|
||||||
array[size-1] = v;
|
array[size-1] = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MKXPZ_RETRO
|
||||||
|
SoundEmitter::SoundEmitter()
|
||||||
|
#else
|
||||||
SoundEmitter::SoundEmitter(const Config &conf)
|
SoundEmitter::SoundEmitter(const Config &conf)
|
||||||
|
#endif // MKXPZ_RETRO
|
||||||
: bufferBytes(0),
|
: bufferBytes(0),
|
||||||
|
#ifdef MKXPZ_RETRO
|
||||||
|
srcCount(6), // TODO: get from config
|
||||||
|
#else
|
||||||
srcCount(conf.SE.sourceCount),
|
srcCount(conf.SE.sourceCount),
|
||||||
|
#endif // MKXPZ_RETRO
|
||||||
alSrcs(srcCount),
|
alSrcs(srcCount),
|
||||||
atchBufs(srcCount),
|
atchBufs(srcCount),
|
||||||
srcPrio(srcCount)
|
srcPrio(srcCount)
|
||||||
|
@ -202,29 +212,60 @@ struct SoundOpenHandler : FileSystem::OpenHandler
|
||||||
#endif // MKXPZ_RETRO
|
#endif // MKXPZ_RETRO
|
||||||
const char *ext
|
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);
|
Sound_Sample *sample = Sound_NewSample(&ops, ext, 0, STREAM_BUF_SIZE);
|
||||||
|
#endif // MKXPZ_RETRO
|
||||||
|
|
||||||
|
#ifdef MKXPZ_RETRO
|
||||||
|
if (handle.error())
|
||||||
|
#else
|
||||||
if (!sample)
|
if (!sample)
|
||||||
|
#endif // MKXPZ_RETRO
|
||||||
{
|
{
|
||||||
|
#ifndef MKXPZ_RETRO
|
||||||
SDL_RWclose(&ops);
|
SDL_RWclose(&ops);
|
||||||
|
#endif // MKXPZ_RETRO
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do all of the decoding in the handler so we don't have
|
/* Do all of the decoding in the handler so we don't have
|
||||||
* to keep the source ops around */
|
* 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);
|
uint32_t decBytes = Sound_DecodeAll(sample);
|
||||||
uint8_t sampleSize = formatSampleSize(sample->actual.format);
|
uint8_t sampleSize = formatSampleSize(sample->actual.format);
|
||||||
uint32_t sampleCount = decBytes / sampleSize;
|
uint32_t sampleCount = decBytes / sampleSize;
|
||||||
|
#endif // MKXPZ_RETRO
|
||||||
|
|
||||||
buffer = new SoundBuffer;
|
buffer = new SoundBuffer;
|
||||||
buffer->bytes = sampleSize * sampleCount;
|
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,
|
AL::Buffer::uploadData(buffer->alBuffer, alFormat, sample->buffer,
|
||||||
buffer->bytes, sample->actual.rate);
|
buffer->bytes, sample->actual.rate);
|
||||||
|
|
||||||
Sound_FreeSample(sample);
|
Sound_FreeSample(sample);
|
||||||
#endif // MKXPZ_RETRO
|
#endif // MKXPZ_RETRO
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,11 @@ struct SoundEmitter
|
||||||
/* Indices of sources, sorted by priority (lowest first) */
|
/* Indices of sources, sorted by priority (lowest first) */
|
||||||
std::vector<size_t> srcPrio;
|
std::vector<size_t> srcPrio;
|
||||||
|
|
||||||
|
#ifdef MKXPZ_RETRO
|
||||||
|
SoundEmitter();
|
||||||
|
#else
|
||||||
SoundEmitter(const Config &conf);
|
SoundEmitter(const Config &conf);
|
||||||
|
#endif // MKXPZ_RETRO
|
||||||
~SoundEmitter();
|
~SoundEmitter();
|
||||||
|
|
||||||
void play(const std::string &filename,
|
void play(const std::string &filename,
|
||||||
|
|
Loading…
Add table
Reference in a new issue