Get WebAudio context creation working, including error handling

This commit is contained in:
UnknownShadow200 2021-08-13 09:05:09 +10:00
parent cfb4917c92
commit 288fe4b2ce
3 changed files with 153 additions and 2 deletions

View file

@ -717,6 +717,67 @@ cc_bool Audio_DescribeError(cc_result res, cc_string* dst) {
if (err) String_AppendConst(dst, err);
return err != NULL;
}
#elif defined CC_BUILD_WEBAUDIO
/*########################################################################################################################*
*-----------------------------------------------------WebAudio backend----------------------------------------------------*
*#########################################################################################################################*/
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 char* name);
extern int interop_AudioDescribe(int res, char* buffer, int bufferLen);
static cc_bool AudioBackend_Init(void) {
cc_result res = interop_InitAudio();
if (res) { AudioWarn(res, "initing WebAudio context"); return false; }
InitFakeSounds();
return true;
}
void Audio_Init(struct AudioContext* ctx, int buffers) {
}
void Audio_Close(struct AudioContext* ctx) {
if (ctx->contextID) interop_AudioClose(ctx->contextID);
ctx->contextID = 0;
}
cc_result Audio_SetFormat(struct AudioContext* ctx, int channels, int sampleRate) {
return ERR_NOT_SUPPORTED;
}
cc_result Audio_QueueData(struct AudioContext* ctx, void* data, cc_uint32 size) {
return ERR_NOT_SUPPORTED;
}
cc_result Audio_Play(struct AudioContext* ctx) {
return ERR_NOT_SUPPORTED;
}
cc_result Audio_Poll(struct AudioContext* ctx, int* inUse) {
return ERR_NOT_SUPPORTED;
}
cc_bool Audio_FastPlay(struct AudioContext* ctx, int channels, int sampleRate) {
/* Channels/Sample rate is per buffer, not a per source property */
return true;
}
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);
}
cc_bool Audio_DescribeError(cc_result res, cc_string* dst) {
char buffer[NATIVE_STR_LEN];
int len = interop_AudioDescribe(res, buffer, NATIVE_STR_LEN);
String_AppendUtf8(dst, buffer, len);
return len > 0;
}
#endif
/*########################################################################################################################*
@ -989,6 +1050,12 @@ static void Sounds_LoadFile(const cc_string* path, void* obj) {
Soundboard_Load(&stepBoard, &step, path);
}
/* TODO this is a pretty terrible solution */
#ifdef CC_BUILD_WEBAUDIO
static void InitWebSounds(void) {
}
#endif
static cc_bool sounds_loaded;
static void Sounds_Start(void) {
int i;
@ -1004,7 +1071,11 @@ static void Sounds_Start(void) {
if (sounds_loaded) return;
sounds_loaded = true;
#ifdef CC_BUILD_WEBAUDIO
InitWebSounds();
#else
Directory_Enum(&audio_dir, NULL, Sounds_LoadFile);
#endif
}
static void Sounds_Stop(void) {

View file

@ -239,7 +239,7 @@ Thus it is **NOT SAFE** to allocate a string on the stack. */
#define CC_BUILD_GLMODERN
#define CC_BUILD_GLES
#define CC_BUILD_TOUCH
#define CC_BUILD_NOSOUNDS
#define CC_BUILD_WEBAUDIO
#define CC_BUILD_NOMUSIC
#define CC_BUILD_MINFILES
#endif

View file

@ -660,5 +660,85 @@ mergeInto(LibraryManager.library, {
var dbg = GLctx.getExtension('WEBGL_debug_renderer_info');
var str = dbg ? GLctx.getParameter(dbg.UNMASKED_RENDERER_WEBGL) : "";
stringToUTF8(str, buffer, len);
}
},
//########################################################################################################################
//---------------------------------------------------------Sockets--------------------------------------------------------
//########################################################################################################################
interop_AudioLog: function(err) {
console.log(err);
window.AUDIO.errors.push(''+err);
return window.AUDIO.errors.length|0;
},
interop_InitAudio: function() {
window.AUDIO = window.AUDIO || {
context: null,
sources: [],
buffers: {},
errors: [],
seen: {},
};
if (window.AUDIO.context) return 0;
// TODO error handling everywhere
try {
if (window.AudioContext) {
AUDIO.context = new window.AudioContext();
} else {
AUDIO.context = new window.webkitAudioContext();
}
} catch (err) {
return _interop_AudioLog(err)
}
return 0;
},
interop_InitAudio__deps: ['interop_AudioLog'],
interop_AudioCreate: function() {
var source = AUDIO.context.createBufferSource();
AUDIO.sources.push(source);
return AUDIO.sources.length|0;
// NOTE: 0 is used by Audio.c for "no source"
},
interop_AudioClose: function(ctxID) {
var source = AUDIO.sources[ctxID - 1|0];
source.stop();
AUDIO.sources[ctxID - 1|0] = null;
},
interop_AudioPlay: function(ctxID, name) {
var source = AUDIO.sources[ctxID - 1|0];
var name_ = UTF8ToString(name);
// have we already downloaded or are downloading this file?
if (!AUDIO.seen.hasOwnProperty(name_)) {
Audio.seen[name_] = true;
_interop_AudioDownload(name_);
return 0;
}
source.buffer = AUDIO.buffers[name_];
source.connect(audioCtx.destination);
source.start();
return 0;
},
interop_AudioPlay__deps: ['interop_AudioDownload'],
interop_AudioDownload: function(name) {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'static/' + name + '.wav', true);
xhr.responseType = 'arraybuffer';
xhr.onload = function() {
var data = xhr.response;
AUDIO.context.decodeAudioData(data, function(buffer) {
AUDIO.buffers[name] = buffer;
});
};
xhr.send();
},
interop_AudioDescribe: function(errCode, buffer, bufferLen) {
if (errCode > AUDIO.errors.length) return 0;
var str = AUDIO.errors[errCode - 1];
return stringToUTF8(str, buffer, bufferLen);
},
});