aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-03-27 11:59:12 -0700
committerAlon Zakai <alonzakai@gmail.com>2012-03-27 11:59:12 -0700
commitb4dcd8daa2d0ac559222139f2d797b3bfd0cb148 (patch)
tree75cdcbf19d4ffe3ef3b4be73f0994c84fbd77bc6
parent84d65c025b4581202f0972be8f479978903d80e7 (diff)
support for playing audio chunks through SDL mix
-rwxr-xr-xemcc69
-rw-r--r--src/library_sdl.js20
-rw-r--r--src/preamble.js4
-rwxr-xr-xtests/runner.py7
4 files changed, 65 insertions, 35 deletions
diff --git a/emcc b/emcc
index aa877fd5..72895065 100755
--- a/emcc
+++ b/emcc
@@ -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()