diff --git a/Makefile.emscripten b/Makefile.emscripten index b1ca76f..f736d67 100644 --- a/Makefile.emscripten +++ b/Makefile.emscripten @@ -9,7 +9,7 @@ EMFLAGS += -O2 EMFLAGS += -s EMTERPRETIFY=1 -s EMTERPRETIFY_ASYNC=1 LFLAGS := $(EMFLAGS) -LFLAGS += -s EXPORTED_FUNCTIONS="['_main','_musfade_setvolval_all','_ags_setAntialiasedStringMode','_sdl_rightButton']" +LFLAGS += -s EXPORTED_FUNCTIONS="['_main','_musfade_setvolval_all','_ags_setAntialiasedStringMode','_sdl_rightButton', '_ald_getdata', '_ald_freedata']" docs/xsystem35.js: emterpretify_whitelist src/xsystem35 $(CC) xsystem35.bc $(LFLAGS) @emterpretify_whitelist -o $@ diff --git a/src/pcm.emscripten.c b/src/pcm.emscripten.c index 93e7aed..4a15b5d 100644 --- a/src/pcm.emscripten.c +++ b/src/pcm.emscripten.c @@ -23,8 +23,6 @@ #include "portab.h" #include "system.h" -#include "ald_manager.h" -#include "dri.h" #include "music_pcm.h" #include "music_private.h" #include "nact.h" @@ -41,49 +39,19 @@ int muspcm_exit() { // 番号指定のPCMファイル読み込み int muspcm_load_no(int slot, int no) { - dridata *dfile = ald_getdata(DRIFILE_WAVE, no -1); - if (dfile == NULL) { - WARNING("DRIFILE_WAVE fail to open %d\n", no -1); - return NG; - } - - EM_ASM_({ - xsystem35.waitPromise(function(){ - return xsystem35.audio.pcm_load($0, $1, $2); - }); - }, slot, dfile->data, dfile->size); + EM_ASM_({ xsystem35.audio.pcm_load($0, $1); }, slot, no); #ifdef EMTERPRETIFY_ADVISE emscripten_sleep(0); #endif - - ald_freedata(dfile); return OK; } int muspcm_load_mixlr(int slot, int noL, int noR) { - dridata *dfileL = ald_getdata(DRIFILE_WAVE, noL -1); - if (dfileL == NULL) { - WARNING("DRIFILE_WAVE fail to open %d\n", noL -1); - return NG; - } - dridata *dfileR = ald_getdata(DRIFILE_WAVE, noR -1); - if (dfileR == NULL) { - ald_freedata(dfileL); - WARNING("DRIFILE_WAVE fail to open %d\n", noR -1); - return NG; - } - EM_ASM_({ - xsystem35.waitPromise(function() { - return xsystem35.audio.pcm_load_mixlr($0, $1, $2, $3, $4); - }); - }, slot, dfileL->data, dfileL->size, dfileR->data, dfileR->size); + EM_ASM_({ xsystem35.audio.pcm_load_mixlr($0, $1, $2); }, slot, noL, noR); #ifdef EMTERPRETIFY_ADVISE emscripten_sleep(0); #endif - - ald_freedata(dfileL); - ald_freedata(dfileR); return OK; } @@ -152,4 +120,5 @@ boolean muspcm_isplaying(int slot) { int musfade_setvolval_all(int val) { EM_ASM_(xsystem35.audio.setVolume($0), val); + return OK; } diff --git a/web/shell/shell.ts b/web/shell/shell.ts index 2ea7775..7a321f2 100644 --- a/web/shell/shell.ts +++ b/web/shell/shell.ts @@ -4,6 +4,8 @@ var $: (selector:string)=>HTMLElement = document.querySelector.bind(document); declare function _musfade_setvolval_all(vol: number): void; declare function _ags_setAntialiasedStringMode(on: number): void; declare function _sdl_rightButton(down: number): void; +declare function _ald_getdata(type: number, no: number): number; +declare function _ald_freedata(data: number): void; declare namespace Module { var noInitialRun: boolean; @@ -409,6 +411,7 @@ class AudioManager { private context: AudioContext; private masterGain: GainNode; private slots: PCMSound[]; + private buffers: AudioBuffer[]; private isSafari: boolean; constructor() { @@ -422,6 +425,7 @@ class AudioManager { this.masterGain = this.context.createGain(); this.masterGain.connect(this.context.destination); this.slots = []; + this.buffers = []; } private unlockAudioContextForiOS() { @@ -436,31 +440,64 @@ class AudioManager { window.addEventListener('touchend', hanlder); } - private load(ptr: number, size: number): Promise { - var buf = Module.HEAPU8.buffer.slice(ptr, ptr + size); + private load(no: number): Promise { + var buf = this.getWave(no); + if (!buf) + return Promise.reject('Failed to open wave ' + no); + + var decoded: Promise; if (this.isSafari) { - return new Promise((resolve, reject) => { + decoded = new Promise((resolve, reject) => { this.context.decodeAudioData(buf, resolve, reject); }); + } else { + decoded = this.context.decodeAudioData(buf); } - return this.context.decodeAudioData(buf); - } - - pcm_load(slot: number, ptr: number, size: number): Promise { - this.pcm_stop(slot); - var start = performance.now(); - return this.load(ptr, size).then((audioBuf) => { - console.log('pcm_load: ' + (performance.now() - start) + ' ms'); - this.slots[slot] = new PCMSoundSimple(this.masterGain, audioBuf); + return decoded.then((audioBuf) => { + this.buffers[no] = audioBuf; + return audioBuf; }); } - pcm_load_mixlr(slot: number, lptr: number, lsize: number, rptr: number, rsize: number): Promise { - this.pcm_stop(slot); - var start = performance.now(); - return Promise.all([this.load(lptr, lsize), this.load(rptr, rsize)]).then((bufs) => { - console.log('pcm_load_mixlr: ' + (performance.now() - start) + ' ms'); - this.slots[slot] = new PCMSoundMixLR(this.masterGain, bufs[0], bufs[1]); + private getWave(no: number): ArrayBuffer { + var dfile = _ald_getdata(2 /* DRIFILE_WAVE */, no-1); + if (!dfile) + return null; + var ptr = Module.getValue(dfile + 8, '*'); + var size = Module.getValue(dfile, 'i32'); + var buf = Module.HEAPU8.buffer.slice(ptr, ptr + size); + _ald_freedata(dfile); + return buf; + } + + pcm_load(slot: number, no: number) { + EmterpreterAsync.handle((resume) => { + this.pcm_stop(slot); + if (this.buffers[no]) { + this.slots[slot] = new PCMSoundSimple(this.masterGain, this.buffers[no]); + return resume(); + } + this.load(no).then((audioBuf) => { + this.slots[slot] = new PCMSoundSimple(this.masterGain, audioBuf); + resume(); + }); + }); + } + + pcm_load_mixlr(slot: number, noL: number, noR: number) { + EmterpreterAsync.handle((resume) => { + this.pcm_stop(slot); + if (this.buffers[noL] && this.buffers[noR]) { + this.slots[slot] = new PCMSoundMixLR(this.masterGain, this.buffers[noL], this.buffers[noR]); + return resume(); + } + var ps = []; + if (!this.buffers[noL]) ps.push(this.load(noL)); + if (!this.buffers[noR]) ps.push(this.load(noR)); + Promise.all(ps).then(() => { + this.slots[slot] = new PCMSoundMixLR(this.masterGain, this.buffers[noL], this.buffers[noR]); + resume(); + }); }); }