From 329bedd5230cf7102825e60e6e44274d482ab3af Mon Sep 17 00:00:00 2001 From: Charlie Groves Date: Fri, 22 Aug 2008 02:02:54 +0000 Subject: [PATCH] Choose a random sound from multi-option sounds in the SoundLoader when told to play a particular key. Set the gain on streams before returning them in addition to during each update. git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@644 ed5b42cb-e716-0410-a449-f6a68f950b19 --- .../threerings/media/sound/SoundLoader.java | 33 ++++++++--- .../threerings/openal/OpenALSoundPlayer.java | 58 +++++++++++++++++-- 2 files changed, 77 insertions(+), 14 deletions(-) diff --git a/src/java/com/threerings/media/sound/SoundLoader.java b/src/java/com/threerings/media/sound/SoundLoader.java index 6459244a..edf93277 100644 --- a/src/java/com/threerings/media/sound/SoundLoader.java +++ b/src/java/com/threerings/media/sound/SoundLoader.java @@ -12,7 +12,6 @@ import org.apache.commons.io.IOUtils; import com.samskivert.util.Config; import com.samskivert.util.ConfigUtil; import com.samskivert.util.LRUHashMap; - import com.threerings.resource.ResourceManager; /** @@ -34,22 +33,38 @@ public class SoundLoader public byte[][] load (String packagePath, String key) throws IOException { - // otherwise, randomize between all available sounds - Config c = getConfig(packagePath); - String[] names = c.getValue(key, (String[])null); - if (names == null) { + String[] paths = getPaths(packagePath, key); + if (paths == null) { log.warning("No such sound", "key", key); return null; } - byte[][] data = new byte[names.length][]; - String bundle = c.getValue("bundle", (String)null); - for (int ii = 0; ii < names.length; ii++) { - data[ii] = loadClipData(bundle, names[ii]); + byte[][] data = new byte[paths.length][]; + String bundle = getBundle(packagePath); + for (int ii = 0; ii < paths.length; ii++) { + data[ii] = loadClipData(bundle, paths[ii]); } return data; } + /** + * Returns the paths to sounds for key in the given package. Returns null if no + * sounds are found. + */ + public String[] getPaths (String packagePath, String key) + { + return getConfig(packagePath).getValue(key, (String[])null); + } + + + /** + * Returns the bundle for sounds in the given package. Returns null if the bundle isn't found. + */ + public String getBundle (String packagePath) + { + return getConfig(packagePath).getValue("bundle", (String)null); + } + /** * Attempts to load a sound stream from the given path from the given bundle and from the * classpath. If nothing is found, a FileNotFoundException is thrown. diff --git a/src/java/com/threerings/openal/OpenALSoundPlayer.java b/src/java/com/threerings/openal/OpenALSoundPlayer.java index fd5e7584..59b7ef8d 100644 --- a/src/java/com/threerings/openal/OpenALSoundPlayer.java +++ b/src/java/com/threerings/openal/OpenALSoundPlayer.java @@ -6,20 +6,29 @@ package com.threerings.openal; import static com.threerings.media.Log.log; import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; import java.util.Map; +import javax.sound.sampled.AudioFileFormat; +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; + import org.lwjgl.openal.AL10; import org.lwjgl.util.WaveData; +import com.google.common.base.Preconditions; import com.google.common.collect.Maps; import com.samskivert.util.BasicRunQueue; +import com.samskivert.util.RandomUtil; import com.samskivert.util.RunQueue; import com.threerings.media.FrameManager; +import com.threerings.media.sound.JavaSoundPlayer; import com.threerings.media.sound.SoundLoader; import com.threerings.media.sound.SoundPlayer; import com.threerings.media.timer.MediaTimer; @@ -42,9 +51,41 @@ public class OpenALSoundPlayer extends SoundPlayer public Clip loadClip (String path) throws IOException { - int pkgEnd = path.lastIndexOf("/") + 1; - byte[] data = _loader.load(path.substring(0, pkgEnd), path.substring(pkgEnd))[0]; - return new Clip(WaveData.create(new ByteArrayInputStream(data))); + int bundleEnd = path.lastIndexOf(":"); + InputStream sound = _loader.getSound(path.substring(0, bundleEnd), + path.substring(bundleEnd + 1)); + if (path.endsWith(".ogg")) { + try { + AudioInputStream instream = JavaSoundPlayer.setupAudioStream(sound); + ByteArrayOutputStream outstream = new ByteArrayOutputStream(); + + byte[] buf = new byte[16 * 1024]; + int read; + do { + read = instream.read(buf, 0, buf.length); + if (read >= 0) { + outstream.write(buf, 0, read); + } + } while (read >= 0); + + byte[] audio = outstream.toByteArray(); + AudioFormat format = instream.getFormat(); + long length = audio.length / format.getFrameSize(); + + instream = new AudioInputStream(new ByteArrayInputStream(audio), format, length); + + outstream = new ByteArrayOutputStream(); + + AudioSystem.write(instream, AudioFileFormat.Type.WAVE, outstream); + + sound = new ByteArrayInputStream(outstream.toByteArray()); + + } catch (Exception e) { + log.warning("Error decompressing audio clip", "path", path, e); + return new Clip(); + } + } + return new Clip(WaveData.create(sound)); } @Override @@ -113,7 +154,7 @@ public class OpenALSoundPlayer extends SoundPlayer InputStream rsrc = _loader.getSound(bundle, path); final StreamDecoder dec = new OggStreamDecoder(); dec.init(rsrc); - return new Stream(_alSoundManager) { + Stream s = new Stream(_alSoundManager) { @Override protected void update (float time) { @@ -144,6 +185,8 @@ public class OpenALSoundPlayer extends SoundPlayer } return read; }}; + s.setGain(_clipVol); + return s; } @Override @@ -267,7 +310,12 @@ public class OpenALSoundPlayer extends SoundPlayer public SoundGrabber (String pkgPath, String key) { - path = pkgPath + key; + String bundle = _loader.getBundle(pkgPath); + Preconditions.checkNotNull(bundle, + "Unable to find the bundle name for a package [package=%s, key=%s]", pkgPath, key); + String[] names = _loader.getPaths(pkgPath, key); + Preconditions.checkNotNull(bundle, "No such sound [package=%s, key=%s]", pkgPath, key); + path = bundle + ":" + names[RandomUtil.getInt(names.length)]; } public void run ()