From 775cbd152805324d2dbe69cc3b54427d81467ef5 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Fri, 13 Aug 2021 18:47:25 +1000 Subject: [PATCH] Get playback rate working through terrible hack --- src/Audio.c | 29 ++++++++++++++++++++++++++--- src/interop_web.js | 24 +++++++++++++++--------- 2 files changed, 41 insertions(+), 12 deletions(-) diff --git a/src/Audio.c b/src/Audio.c index b317e451b..a14f064a5 100644 --- a/src/Audio.c +++ b/src/Audio.c @@ -725,7 +725,7 @@ struct AudioContext { int contextID; }; extern int interop_InitAudio(void); extern int interop_AudioCreate(void); extern void interop_AudioClose(int contextID); -extern int interop_AudioPlay(int contextID, const void* name, int volume); +extern int interop_AudioPlay(int contextID, struct Sound* snd, int volume); extern int interop_AudioPoll(int contetID, int* inUse); extern int interop_AudioDescribe(int res, char* buffer, int bufferLen); @@ -764,7 +764,7 @@ cc_bool Audio_FastPlay(struct AudioContext* ctx, int channels, int sampleRate) { cc_result Audio_PlaySound(struct AudioContext* ctx, struct Sound* snd, int volume) { if (!ctx->contextID) ctx->contextID = interop_AudioCreate(); - return interop_AudioPlay(ctx->contextID, snd->data, volume); + return interop_AudioPlay(ctx->contextID, snd, volume); } cc_bool Audio_DescribeError(cc_result res, cc_string* dst) { @@ -1058,8 +1058,8 @@ static const struct SoundID { int group; const char* name; } sounds_list[] = { SOUND_STONE, "step_stone1" }, { SOUND_STONE, "step_stone2" }, { SOUND_STONE, "step_stone3" }, { SOUND_STONE, "step_stone4" }, { SOUND_WOOD, "step_wood1" }, { SOUND_WOOD, "step_wood2" }, { SOUND_WOOD, "step_wood3" }, { SOUND_WOOD, "step_wood4" }, { SOUND_NONE, NULL }, + { SOUND_CLOTH, "dig_cloth1" }, { SOUND_CLOTH, "dig_cloth2" }, { SOUND_CLOTH, "dig_cloth3" }, { SOUND_CLOTH, "dig_cloth4" }, - { SOUND_GRASS, "dig_grass1" }, { SOUND_GRASS, "dig_grass2" }, { SOUND_GRASS, "dig_grass3" }, { SOUND_GRASS, "dig_grass4" }, { SOUND_GLASS, "dig_glass1" }, { SOUND_GLASS, "dig_glass2" }, { SOUND_GLASS, "dig_glass3" }, { SOUND_GRAVEL, "dig_gravel1" }, { SOUND_GRAVEL, "dig_gravel2" }, { SOUND_GRAVEL, "dig_gravel3" }, { SOUND_GRAVEL, "dig_gravel4" }, @@ -1069,6 +1069,29 @@ static const struct SoundID { int group; const char* name; } sounds_list[] = { SOUND_WOOD, "dig_wood1" }, { SOUND_WOOD, "dig_wood2" }, { SOUND_WOOD, "dig_wood3" }, { SOUND_WOOD, "dig_wood4" }, }; +/* TODO this is a terrible solution */ +#include +EMSCRIPTEN_KEEPALIVE void Audio_SoundReady(const char* name, int channels, int sampleRate) { + struct Soundboard* board = name[0] == 's' ? &stepBoard : &digBoard; + struct SoundGroup* group; + cc_string str = String_FromReadonly(name); + int i, j; + /* This awful hack is because otherwise Sounds_Play tries to play the sound with samplerate of 0 */ + + for (i = 0; i < SOUND_COUNT; i++) { + group = &board->groups[i]; + + for (j = 0; j < group->count; j++) { + if (!String_CaselessEqualsConst(&str, group->sounds[j].data)) continue; + + group->sounds[j].channels = channels; + group->sounds[j].sampleRate = sampleRate; + return; + } + } + Platform_Log1("IDK %c", name); +} + static void InitWebSounds(void) { struct Soundboard* board = &stepBoard; struct SoundGroup* group; diff --git a/src/interop_web.js b/src/interop_web.js index 09bb77022..45be5fa6c 100644 --- a/src/interop_web.js +++ b/src/interop_web.js @@ -713,20 +713,22 @@ mergeInto(LibraryManager.library, { HEAP32[inUse >> 2] = src.playing; // only 1 buffer return 0; }, - interop_AudioPlay: function(ctxID, name, volume) { - var src = AUDIO.sources[ctxID - 1|0]; - var name_ = UTF8ToString(name); + interop_AudioPlay: function(ctxID, snd, volume) { + var nameAddr = HEAP32[(snd|0 + 8|0) >> 2]; + var src = AUDIO.sources[ctxID - 1|0]; + var name = UTF8ToString(nameAddr); // do we need to download this file? - if (!AUDIO.seen.hasOwnProperty(name_)) { - AUDIO.seen[name_] = true; - _interop_AudioDownload(name_); + if (!AUDIO.seen.hasOwnProperty(name)) { + AUDIO.seen[name] = true; + _interop_AudioDownload(name, nameAddr); return 0; } // still downloading or failed to download this file - var buffer = AUDIO.buffers[name_]; + var buffer = AUDIO.buffers[name]; if (!buffer) return 0; + var sampleRate = HEAP32[(snd|0 + 4|0) >> 2]; try { if (!src.gain) src.gain = AUDIO.context.createGain(); @@ -736,8 +738,10 @@ mergeInto(LibraryManager.library, { // MDN says that these nodes are very inexpensive to create though // https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode src.source = AUDIO.context.createBufferSource(); - src.source.buffer = buffer; + src.source.buffer = buffer; src.gain.gain.value = volume / 100; + // game adjusts samplerate to playback audio faster - undo that + src.source.playbackRate.value = sampleRate / buffer.sampleRate; // source -> gain -> output src.source.connect(src.gain); @@ -749,7 +753,7 @@ mergeInto(LibraryManager.library, { } }, interop_AudioPlay__deps: ['interop_AudioDownload'], - interop_AudioDownload: function(name) { + interop_AudioDownload: function(name, nameAddr) { var xhr = new XMLHttpRequest(); xhr.open('GET', 'static/' + name + '.wav', true); xhr.responseType = 'arraybuffer'; @@ -758,6 +762,8 @@ mergeInto(LibraryManager.library, { var data = xhr.response; AUDIO.context.decodeAudioData(data, function(buffer) { AUDIO.buffers[name] = buffer; + // TODO rethink this, this is a terrible solution + Module["_Audio_SoundReady"](nameAddr, buffer.channels, buffer.sampleRate); }); }; xhr.send();