mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-01-23 17:43:08 -05:00
Get WebAudio context creation working, including error handling
This commit is contained in:
parent
cfb4917c92
commit
288fe4b2ce
3 changed files with 153 additions and 2 deletions
71
src/Audio.c
71
src/Audio.c
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
},
|
||||
});
|
Loading…
Add table
Reference in a new issue