diff options
author | Alon Zakai <alonzakai@gmail.com> | 2012-03-27 11:59:12 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2012-03-27 11:59:12 -0700 |
commit | b4dcd8daa2d0ac559222139f2d797b3bfd0cb148 (patch) | |
tree | 75cdcbf19d4ffe3ef3b4be73f0994c84fbd77bc6 | |
parent | 84d65c025b4581202f0972be8f479978903d80e7 (diff) |
support for playing audio chunks through SDL mix
-rwxr-xr-x | emcc | 69 | ||||
-rw-r--r-- | src/library_sdl.js | 20 | ||||
-rw-r--r-- | src/preamble.js | 4 | ||||
-rwxr-xr-x | tests/runner.py | 7 |
4 files changed, 65 insertions, 35 deletions
@@ -329,6 +329,7 @@ ASSEMBLY_SUFFIXES = ('.ll',) LIB_PREFIXES = ('', 'lib') IMAGE_SUFFIXES = ('.jpg', '.png', '.bmp') +AUDIO_SUFFIXES = ('.ogg', '.wav', '.mp3') def suffix(name): return name.split('.')[:-1] @@ -833,6 +834,9 @@ try: code += 'var BlobBuilder = typeof MozBlobBuilder != "undefined" ? MozBlobBuilder : (typeof WebKitBlobBuilder != "undefined" ? WebKitBlobBuilder : console.log("warning: cannot build blobs"));\n' code += 'var URLObject = typeof window != "undefined" ? (window.URL ? window.URL : window.webkitURL) : console.log("warning: cannot create object URLs");\n' + code += 'var preloadedImages = {}; // maps url to image data\n' + code += 'var preloadedAudios = {}; // maps url to audio data\n' + # Expand directories into individual files def add(mode, dirname, names): for name in names: @@ -898,6 +902,49 @@ try: varname = 'filePreload%d' % counter counter += 1 image = filename.endswith(IMAGE_SUFFIXES) + audio = filename.endswith(AUDIO_SUFFIXES) + + if image: + finish = ''' + var bb = new BlobBuilder(); + bb.append(byteArray.buffer); + var b = bb.getBlob(); + var url = URLObject.createObjectURL(b); + var img = new Image(); + img.onload = function() { + assert(img.complete, 'Image %(filename)s could not be decoded'); + var canvas = document.createElement('canvas'); + canvas.width = img.width; + canvas.height = img.height; + var ctx = canvas.getContext('2d'); + ctx.drawImage(img, 0, 0); + preloadedImages['%(filename)s'] = canvas; + URLObject.revokeObjectURL(url); + removeRunDependency(); + }; + img.onerror = function(event) { + console.log('Image %(filename)s could not be decoded'); + }; + img.src = url; +''' % { 'filename': filename } + elif audio: + finish = ''' + var b = new Blob([byteArray.buffer], { type: 'audio/ogg' }); + var url = URLObject.createObjectURL(b); // XXX we never revoke this! + var audio = new Audio(); + audio.oncanplaythrough = function() { + audio.oncanplaythrough = null; + preloadedAudios['%(filename)s'] = audio; + removeRunDependency(); + }; + audio.onerror = function(event) { + console.log('Audio %(filename)s could not be decoded'); + }; + audio.src = url; +''' % { 'filename': filename } + else: + finish = 'removeRunDependency();\n' + code += ''' var %(varname)s = new %(request)s(); %(varname)s.open('GET', '%(netname)s', true); @@ -918,27 +965,7 @@ try: 'netname': file_['net_name'], 'dirname': os.path.dirname(filename), 'basename': os.path.basename(filename), - 'finish': 'removeRunDependency();' if not image else '''var bb = new BlobBuilder(); - bb.append(byteArray.buffer); - var b = bb.getBlob(); - var url = URLObject.createObjectURL(b); - var img = new Image(); - img.onload = function() { - assert(img.complete, 'Image %(filename)s could not be decoded'); - var canvas = document.createElement('canvas'); - canvas.width = img.width; - canvas.height = img.height; - var ctx = canvas.getContext('2d'); - ctx.drawImage(img, 0, 0); - preloadedImages['%(filename)s'] = canvas; - URLObject.revokeObjectURL(url); - removeRunDependency(); - }; - img.onerror = function(event) { - console.log('Image %(filename)s could not be decoded: ' + JSON.stringify(event)); - }; - img.src = url; -''' % { 'filename': filename } + 'finish': finish } else: assert 0 diff --git a/src/library_sdl.js b/src/library_sdl.js index 9d947cd4..db3771e9 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -717,12 +717,11 @@ mergeInto(LibraryManager.library, { SDL_CondWait: function() {}, SDL_DestroyCond: function() {}, -//SDL_CreateYUVOverlay -//SDL_CreateThread, SDL_WaitThread etc - // SDL Mixer - Mix_OpenAudio: function() { return 0 }, + Mix_OpenAudio: function(frequency, format, channels, chunksize) { + return 0; + }, Mix_HookMusicFinished: function(func) { SDL.hookMusicFinished = func; // TODO: use this @@ -734,22 +733,23 @@ mergeInto(LibraryManager.library, { Mix_LoadWAV_RW: function(filename, freesrc) { filename = FS.standardizePath(Pointer_stringify(filename)); + var raw = preloadedAudios[filename]; + assert(raw, 'Cannot find preloaded audio ' + filename); var id = SDL.audios.length; SDL.audios.push({ - audio: new Audio(filename) + audio: raw }); return id; }, Mix_FreeChunk: function(id) { - //SDL.audios[id].audio.pause(); - //SDL.audios[id] = null; - return 0; + SDL.audios[id].audio.pause(); + SDL.audios[id] = null; }, Mix_PlayChannel: function(channel, id, loops) { - //var audio = SDL.audios[id].audio; - //audio.play(); + var audio = SDL.audios[id].audio; + audio.play(); return 0; // XXX should return channel }, Mix_PlayChannelTimed: 'Mix_PlayChannel', // XXX ignore Timing diff --git a/src/preamble.js b/src/preamble.js index 0e43af12..33da1159 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -844,9 +844,5 @@ function removeRunDependency() { if (runDependencies == 0) run(); } -// Preloading - -var preloadedImages = {}; // maps url to image data - // === Body === diff --git a/tests/runner.py b/tests/runner.py index 09f7063f..1db6d3a7 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -6445,6 +6445,13 @@ f.close() Popen(['python', EMCC, os.path.join(self.get_dir(), 'sdl_mouse.c'), '-o', 'page.html', '--pre-js', 'pre.js']).communicate() self.run_browser('page.html', '', '/report_result?740') + def test_sdl_audio(self): + shutil.copyfile(path_from_root('tests', 'sounds', 'alarmvictory_1.ogg'), os.path.join(self.get_dir(), 'sound.ogg')) + open(os.path.join(self.get_dir(), 'sdl_audio.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_audio.c')).read())) + + Popen(['python', EMCC, os.path.join(self.get_dir(), 'sdl_audio.c'), '--preload-file', 'sound.ogg', '-o', 'page.html']).communicate() + self.run_browser('page.html', '', '/report_result?1') + def test_worker(self): # Test running in a web worker output = Popen(['python', EMCC, path_from_root('tests', 'hello_world_worker.cpp'), '-o', 'worker.js'], stdout=PIPE, stderr=PIPE).communicate() |