diff options
author | kcr <kcr@28c7f869-5b4e-e670-f602-82bfaf57f300> | 2004-06-09 03:28:13 +0000 |
---|---|---|
committer | kcr <kcr@28c7f869-5b4e-e670-f602-82bfaf57f300> | 2004-06-09 03:28:13 +0000 |
commit | 53ebfcc5ad5554b67d2287f8b02c22ec8405af0f (patch) | |
tree | 70c8fabf4cbef5a9d2a50735c4e502d56ce156da /src/Sound | |
parent | 4dead457a59220406dd9fcd40997d7a7b27571b0 (diff) |
Initial creation of j3d-examples sources in CVS repository
Diffstat (limited to 'src/Sound')
-rw-r--r-- | src/Sound/AudioBehaviorMoveOne.java | 104 | ||||
-rw-r--r-- | src/Sound/AudioReverberate.java | 169 | ||||
-rw-r--r-- | src/Sound/MoveAppBoundingLeaf.html | 15 | ||||
-rw-r--r-- | src/Sound/MoveAppBoundingLeaf.java | 387 | ||||
-rw-r--r-- | src/Sound/MoveAppBoundingLeaf_plugin.html | 39 | ||||
-rw-r--r-- | src/Sound/README.release | 226 | ||||
-rw-r--r-- | src/Sound/ReverberateSound.html | 15 | ||||
-rw-r--r-- | src/Sound/ReverberateSound.java | 220 | ||||
-rw-r--r-- | src/Sound/ReverberateSound_plugin.html | 39 | ||||
-rw-r--r-- | src/Sound/SimpleSounds.html | 15 | ||||
-rw-r--r-- | src/Sound/SimpleSounds.java | 292 | ||||
-rw-r--r-- | src/Sound/SimpleSoundsBehavior.java | 177 | ||||
-rw-r--r-- | src/Sound/SimpleSounds_plugin.html | 39 | ||||
-rw-r--r-- | src/Sound/build.xml | 66 | ||||
-rw-r--r-- | src/Sound/hello_universe.au | bin | 0 -> 10743 bytes | |||
-rw-r--r-- | src/Sound/roar.au | bin | 0 -> 18935 bytes | |||
-rw-r--r-- | src/Sound/techno_machine.au | bin | 0 -> 49347 bytes |
17 files changed, 1803 insertions, 0 deletions
diff --git a/src/Sound/AudioBehaviorMoveOne.java b/src/Sound/AudioBehaviorMoveOne.java new file mode 100644 index 0000000..440158e --- /dev/null +++ b/src/Sound/AudioBehaviorMoveOne.java @@ -0,0 +1,104 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +import javax.media.j3d.*; +import javax.vecmath.*; +import java.util.Enumeration; + +// User defined audio behavior class +public class AudioBehaviorMoveOne extends Behavior { + WakeupOnElapsedTime wt; + WakeupOnBehaviorPost wp; + PointSound psound = new PointSound(); + static int WAKEUP_SOUND = 0; + long dur; + // long time; + // long lastTime = -1; + boolean first_loop = true; + String fileName; + + // Override Behavior's initialize method to setup wakeup criteria + public void initialize() { + MediaContainer sample = new MediaContainer(); + sample.setCapability(MediaContainer.ALLOW_URL_WRITE); + sample.setCapability(MediaContainer.ALLOW_URL_READ); + sample.setURLString(fileName); + psound.setSoundData(sample); + // exaggerate the sound position now that viewPlatform + // tranform is taken into account + Point3f soundPos = new Point3f(-20.0f, 0.0f, 0.0f); + psound.setPosition(soundPos); + WakeupOnElapsedTime wp = new WakeupOnElapsedTime(5000); + wakeupOn(wp); + } + + // Override Behavior's stimulus method to handle the event + public void processStimulus(Enumeration criteria) { + // time = System.currentTimeMillis(); + if (first_loop) { + first_loop = false; + dur = psound.getDuration(); + if (dur == Sound.DURATION_UNKNOWN) + dur = 2000; // Force iterations every 2 seconds + // System.out.println(" sound duration time " + dur); + wt = new WakeupOnElapsedTime(dur); + } + else { + // System.out.println(" time between setEnables calls "+ + // (time - lastTime)); + psound.setEnable(false) ; + } + psound.setEnable(true); + // lastTime = time; + wakeupOn(wt); + } + + // + // Constructor for rotation behavior. Parameter: front and back Sound nodes + // + public AudioBehaviorMoveOne(PointSound psound, String filename) { + this.psound = psound; + this.fileName = filename; + } +} diff --git a/src/Sound/AudioReverberate.java b/src/Sound/AudioReverberate.java new file mode 100644 index 0000000..7befc2c --- /dev/null +++ b/src/Sound/AudioReverberate.java @@ -0,0 +1,169 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +import javax.media.j3d.*; +import javax.vecmath.*; +import java.util.Enumeration; + +/* + * Pick the JavaSound reverb type that matches the input parameters + * as best as possible. + * + * Hae Reverb Types Size Persistance Delay + * ================ ----------- ------------ ----------- + * 1 None (dry) + * 2 "Closet" very small very short <.5 fast smooth + * 3 "Garage" med. large medium 1.0 medium + * 4 "Acoustic Lab" med. small short .5 med. fast + * 5 "Cavern" large long >2.0 very slow + * 6 "Dungeon" medium med. long 1.5 med. slow + * + * + * Order is NOT controllable, nor does it have a natural parallel. + * For this reason Order and Reflection are tied together as to + * affect 'Decay Speed'. This speed paired with the size of the + * space implied by the Delay parameter determine the JavaSound + * Reverb type that is set: + * + * | Short: Long: + * Speed | Coeff <= 0.9 Coeff > 0.9 + * Size | Order <= 8 Order > 8 + * --------------------------------------------------------------- + * small (<100ms) | 2 "Closet" 4 "Acoustic Lab" + * medium (<500ms) | 3 "Garage" 6 "Dungeon" + * large (>500ms) | 6 "Dungeon" 5 "Cavern" + */ +// User defined audio behavior class +public class AudioReverberate extends Behavior { + WakeupOnElapsedTime wt; + WakeupOnBehaviorPost wp; + PointSound psound = new PointSound(); + AuralAttributes sScape = null; + static int WAKEUP_SOUND = 0; + long dur; + long time; + boolean firstTime = true; + String fileName; + int lCount = 0; + int loopCount = 0; + + // Override Behavior's initialize method to setup wakeup criteria + public void initialize() { + MediaContainer sample = new MediaContainer(); + sample.setCacheEnable(true); + sample.setURLString(fileName); + psound.setSoundData(sample); + Point3f soundPos = new Point3f(-23.0f, 0.0f, 0.0f); + psound.setPosition(soundPos); + psound.setLoop(3); + firstTime = true; + System.out.println("Reverb Name Size Reflect Order Delay "); + System.out.println("----------- ---- ------- ----- ----- "); + WakeupOnElapsedTime wp = new WakeupOnElapsedTime(5000); + wakeupOn(wp); + } + + // Override Behavior's stimulus method to handle the event + public void processStimulus(Enumeration criteria) { + // time = System.currentTimeMillis(); + if (firstTime) { + wt = new WakeupOnElapsedTime(10000); + firstTime = false; + } + else + psound.setEnable(false) ; + + if (++lCount > 6) + lCount = 1; + + if (lCount == 1) { + sScape.setReverbDelay(10.0f) ; + sScape.setReflectionCoefficient(0.5f) ; + sScape.setReverbOrder(5) ; + System.out.println("Closet sm 0.5 5 10.0 "); + } + else if (lCount == 2) { + sScape.setReverbDelay(10.0f) ; + sScape.setReflectionCoefficient(0.999f) ; + sScape.setReverbOrder(9) ; + System.out.println("Acoustic Lab sm 0.999 9 10.0 "); + } + else if (lCount == 3) { + sScape.setReverbDelay(200.0f) ; + sScape.setReflectionCoefficient(0.4f) ; + sScape.setReverbOrder(3) ; + System.out.println("Garage med 0.4 3 200.0 "); + } + else if (lCount == 4) { + sScape.setReverbDelay(200.0f) ; + sScape.setReflectionCoefficient(0.99f) ; + sScape.setReverbOrder(10) ; + System.out.println("Dungeon med 0.99 10 200.0 "); + } + else if (lCount == 5) { + sScape.setReverbDelay(600.0f) ; + sScape.setReflectionCoefficient(0.33f) ; + sScape.setReverbOrder(7) ; + System.out.println("Dungeon lrg 0.33 7 600.0 "); + } + else if (lCount == 6) { + sScape.setReverbDelay(600.0f) ; + sScape.setReflectionCoefficient(1.0f) ; + sScape.setReverbOrder(20) ; + System.out.println("Cavern lrg 1.0 20 600.0 "); + } + psound.setEnable(true); + wakeupOn(wt); + } + + // + // Constructor for rotation behavior. Parameter: front and back Sound nodes + // + public AudioReverberate(PointSound psound, String filename, + AuralAttributes sscape) { + this.psound = psound; + this.fileName = filename; + this.sScape = sscape; + } +} diff --git a/src/Sound/MoveAppBoundingLeaf.html b/src/Sound/MoveAppBoundingLeaf.html new file mode 100644 index 0000000..885cc03 --- /dev/null +++ b/src/Sound/MoveAppBoundingLeaf.html @@ -0,0 +1,15 @@ +<HTML> +<HEAD> +<TITLE>MoveAppBoundingLeaf</TITLE> +</HEAD> +<BODY BGCOLOR="#000000"> +<applet align=middle code="MoveAppBoundingLeaf.class" width=256 height=256> +<blockquote> +<hr> +If you were using a Java-capable browser, +you would see Hello Universe! instead of this paragraph. +<hr> +</blockquote> +</applet> +</BODY> +</HTML> diff --git a/src/Sound/MoveAppBoundingLeaf.java b/src/Sound/MoveAppBoundingLeaf.java new file mode 100644 index 0000000..35d99e5 --- /dev/null +++ b/src/Sound/MoveAppBoundingLeaf.java @@ -0,0 +1,387 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +/* + * This Java3D program: + * Creates an instance of the JavaSoundMixer AudioDevice, initializing it + * and attaching it to the PhysicalEnvironment with a special version + * of UniverseBuilder (UniverseBuildJS). + * Creates one Point sound sources. + * Creates two Soundscapes with their own aural attributes. Each + * of these Soundscapes defines its own bounding leaf region. + * Creates and executes a custom behavior (AudioBehaviorMoveOne) that + * starts sound playing and transforms the AuralAttribute positions + * by modifying the TransformGroup that contains both soundscape + * nodes. + * Usage: java MoveAppBoundingLeaf [ URLpath [ name ]] + * + * The first optional command line parameter is the URL path to directory + * containing: + * (1) the files that will be named on the command line, or + * (2) the javaone/data/sounds directory that contains the default files + * If not given the default path is: + * file:/net/java3d/export/java3d/javaone/data/sounds + * NOTE: This default path is only valid on Solaris Eng Menlo Park network. + * A path must be supplied if sound files to be used are in a different + * directory location. + * NOTE: When running on Java3D Menlo Park Test WinTel platform path should + * be set to + * file:/java3d/export/java3d/javaone/data/sounds + * + * The second thru fourth optional command line parameters are sound file names + * If not given the default file name is: + * unicycle_close.au + */ + +import java.applet.Applet; +import java.net.URL; +import java.awt.*; +import java.awt.event.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.geometry.ColorCube; +import com.sun.j3d.utils.geometry.Sphere; +import com.sun.j3d.utils.universe.*; +import java.io.File; +import javax.media.j3d.*; +import javax.vecmath.*; + +public class MoveAppBoundingLeaf extends Applet { + + // File name of sound sample + private static int filenamesGiven = 0; + private static URL[] url = new URL[1]; + private static String[] filename = new String[1]; + private static String path = null; + private static boolean filenamesSet = false; + + private SimpleUniverse u = null; + + public BranchGroup createSceneGraph() { + // Create the root of the subgraph + BranchGroup objRoot = new BranchGroup(); + + // Create the transform group node and initialize it to the identity. + // Enable the TRANSFORM_WRITE capability so that our behavior code + // can modify it at runtime. Add it to the root of the subgraph. + TransformGroup objTrans = new TransformGroup(); + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objRoot.addChild(objTrans); + + // Create a simple shape leaf node and add it into the scene graph. + objTrans.addChild(new ColorCube(0.7)); + + // Create a new Behavior object that will perform the desired + // operation on the specified transform object and add it into the + // scene graph. + Transform3D yAxis = new Transform3D(); + Alpha rotation = new Alpha(-1, Alpha.INCREASING_ENABLE, + 0, 0, + 20000, 0, 0, + 0, 0, 0); + RotationInterpolator rotator = + new RotationInterpolator(rotation, + objTrans, yAxis, + 0.0f, (float) Math.PI*2.0f); + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + rotator.setSchedulingBounds(bounds); + objTrans.addChild(rotator); + // + // Create a sound node and add it to the scene graph + // + PointSound sound = new PointSound(); + sound.setCapability(PointSound.ALLOW_ENABLE_WRITE); + sound.setCapability(PointSound.ALLOW_INITIAL_GAIN_WRITE); + sound.setCapability(PointSound.ALLOW_SOUND_DATA_WRITE); + sound.setCapability(PointSound.ALLOW_SCHEDULING_BOUNDS_WRITE); + sound.setCapability(PointSound.ALLOW_CONT_PLAY_WRITE); + sound.setCapability(PointSound.ALLOW_RELEASE_WRITE); + sound.setCapability(PointSound.ALLOW_DURATION_READ); + sound.setCapability(PointSound.ALLOW_IS_PLAYING_READ); + sound.setCapability(PointSound.ALLOW_POSITION_WRITE); + sound.setCapability(PointSound.ALLOW_LOOP_WRITE); + + BoundingSphere soundBounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + sound.setSchedulingBounds(soundBounds); + objTrans.addChild(sound); + + /* + * Spheres denoting aural attribute regions + */ + TransformGroup objTransChild1 = new TransformGroup(); + TransformGroup objTransChild2 = new TransformGroup(); + objTransChild1.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objTransChild2.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + Transform3D translate1 = new Transform3D(); + Transform3D translate2 = new Transform3D(); + Vector3f vector1 = new Vector3f( 2.0f, 0.0f, 0.0f); + Vector3f vector2 = new Vector3f(-2.0f, 0.0f, 0.0f); + translate1.setTranslation(vector1); + translate2.setTranslation(vector2); + objTransChild1.setTransform(translate1); + objTransChild2.setTransform(translate2); + Sphere sphere1 = new Sphere(0.42f); + Sphere sphere2 = new Sphere(0.38f); + + Appearance app = new Appearance(); + app.setCapability( Appearance.ALLOW_POLYGON_ATTRIBUTES_WRITE ); + sphere1.setAppearance( app ); + sphere2.setAppearance( app ); + objTransChild1.addChild(sphere1); + objTransChild2.addChild(sphere2); + + objTrans.addChild(objTransChild1); + objTrans.addChild(objTransChild2); + /** + * Define Soundscapes/AuralAttributes + */ + // First Aural Attributes + Point2f[] distanceFilter = new Point2f[2]; + distanceFilter[0] = new Point2f(6.0f, 6000f); + distanceFilter[1] = new Point2f(17.0f, 700f); + AuralAttributes attributes = new AuralAttributes(1.0f, 2.0f, 0.3f, + 4.0f, 5, distanceFilter, 0.8f, 0.0f); + attributes.setReverbDelay(90.0f) ; + attributes.setReflectionCoefficient(0.999f) ; + attributes.setReverbOrder(9) ; + + // SoundScape + BoundingSphere bounds1 = + new BoundingSphere(new Point3d(2.0,0.0,0.0), 3.5); + + BoundingLeaf sScapeBounds1 = new BoundingLeaf(bounds1); + Soundscape soundScape = new Soundscape(null, attributes); + soundScape.setApplicationBoundingLeaf(sScapeBounds1); + /** addChild of BoundingLeaf as well**/ + objTrans.addChild(sScapeBounds1); + + AuralAttributes queryAttribs = new AuralAttributes(); + if (queryAttribs == null) + System.out.println(" new AuralAttributes returned NULL"); + // else + // System.out.println(" new AuralAttributes returned " + queryAttribs); + queryAttribs = soundScape.getAuralAttributes(); + if (queryAttribs == null) + System.out.println("getAuralAttributes returned NULL"); + // else + // System.out.println("AuralAttributes for Soundscape 1:"); + float tmpFloat = queryAttribs.getAttributeGain(); + // System.out.println(" Gain = " + tmpFloat); + tmpFloat = queryAttribs.getRolloff(); + // System.out.println(" Rolloff = " + tmpFloat); + tmpFloat = queryAttribs.getReflectionCoefficient(); + // System.out.println(" Reflection Coeff = " + tmpFloat); + tmpFloat = queryAttribs.getReverbDelay(); + // System.out.println(" Delay = " + tmpFloat); + int tmpInt = queryAttribs.getReverbOrder(); + // System.out.println(" Order = " + tmpInt); + int length = queryAttribs.getDistanceFilterLength(); + // System.out.println(" Filter length = " + length); + Point2f[] tmpPoint = new Point2f[length]; + tmpPoint = new Point2f[length]; + for (int i=0; i< length; i++) + tmpPoint[i] = new Point2f(); + queryAttribs.getDistanceFilter(tmpPoint); + // for (int i=0; i< length; i++) + // System.out.println(" Distance Filter = (" + tmpPoint[i].x + + // ", " + tmpPoint[i].y + ")" ); + tmpFloat = queryAttribs.getFrequencyScaleFactor(); + // System.out.println(" Freq scalefactor = " + tmpFloat); + tmpFloat = queryAttribs.getVelocityScaleFactor(); + // System.out.println(" Velocity scalefactor= " + tmpFloat); + objTrans.addChild(soundScape); + + // System.out.println("SoundScape2**********************************"); + Soundscape soundScape2 = new Soundscape(); + distanceFilter = new Point2f[2]; + distanceFilter[0] = new Point2f(2.0f, 20000.0f); + distanceFilter[1] = new Point2f(20.0f, 2000.0f); + AuralAttributes attributes2 = new AuralAttributes(); + attributes2.setAttributeGain(1.2f); + attributes2.setRolloff(2.2f); + attributes2.setReverbDelay(1313.0f) ; + attributes2.setReflectionCoefficient(1.0f) ; + attributes2.setReverbOrder(15) ; + distanceFilter[0] = new Point2f(5.0f, 15000.0f); + distanceFilter[1] = new Point2f(15.0f, 500.0f); + attributes2.setDistanceFilter(distanceFilter); + attributes2.setFrequencyScaleFactor(0.8f); + attributes2.setVelocityScaleFactor(0.0f); + BoundingSphere bounds2 = + new BoundingSphere(new Point3d(-2.0,0.0,0.0), 0.38); + BoundingLeaf sScapeBounds2 = new BoundingLeaf(bounds2); + soundScape2.setApplicationBoundingLeaf(sScapeBounds2); + // set BoundingLeaf as a child of transform node + objTrans.addChild(sScapeBounds2); + soundScape2.setAuralAttributes(attributes2); + + queryAttribs = soundScape2.getAuralAttributes(); + if (queryAttribs == null) + System.out.println(" new AuralAttributes returned NULL"); + // else + // System.out.println(" new AuralAttributes returned " + queryAttribs); + // System.out.println("AuralAttributes for Soundscape 2:"); + tmpFloat = queryAttribs.getAttributeGain(); + // System.out.println(" Gain = " + tmpFloat); + tmpFloat = queryAttribs.getRolloff(); + // System.out.println(" Rolloff = " + tmpFloat); + tmpFloat = queryAttribs.getReflectionCoefficient(); + // System.out.println(" Reflection Coeff = " + tmpFloat); + tmpFloat = queryAttribs.getReverbDelay(); + // System.out.println(" Delay = " + tmpFloat); + tmpInt = queryAttribs.getReverbOrder(); + // System.out.println(" Order = " + tmpInt); + length = queryAttribs.getDistanceFilterLength(); + // System.out.println(" Filter length = " + length); + tmpPoint = new Point2f[length]; + for (int i=0; i< length; i++) + tmpPoint[i] = new Point2f(); + queryAttribs.getDistanceFilter(tmpPoint); + // for (int i=0; i< length; i++) + // System.out.println(" Distance Filter = (" + tmpPoint[i].x + + // ", " + tmpPoint[i].y + ")" ); + tmpFloat = queryAttribs.getFrequencyScaleFactor(); + // System.out.println(" Freq scalefactor = " + tmpFloat); + tmpFloat = queryAttribs.getVelocityScaleFactor(); + // System.out.println(" Velocity scalefactor= " + tmpFloat); + objTrans.addChild(soundScape2); + + // + // Create a new Behavior object that will play the sound + // + AudioBehaviorMoveOne player = new AudioBehaviorMoveOne(sound, + filename[0]); + player.setSchedulingBounds(soundBounds); + objTrans.addChild(player); + + return objRoot; + } + + public MoveAppBoundingLeaf() { + } + + public void init() { + if (!filenamesSet) { + // path is null if started from applet + if (path == null) { + path = getCodeBase().toString(); + } + + /* + * append given file name to given URL path + */ + if (filenamesGiven > 0) { + filename[0] = new String(path + "/" + filename[0]); + } + else { + // fill in default file names if all three not given + filename[0] = new String(path + "/techno_machine.au"); + } + filenamesSet = true; + } + + setLayout(new BorderLayout()); + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + Canvas3D c = new Canvas3D(config); + add("Center", c); + + /* + * Change filenames into URLs + */ + String substr = filename[0].substring(0,4); + try { + url[0] = new URL(filename[0]); + } + catch (Exception e) { + return; + } + /* + * Create a simple scene and attach it to the virtual universe + */ + u = new SimpleUniverse(c); + AudioDevice audioDev = u.getViewer().createAudioDevice(); + BranchGroup scene = createSceneGraph(); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + u.getViewingPlatform().setNominalViewingTransform(); + + u.addBranchGraph(scene); + } + + public void destroy() { + u.cleanup(); + } + + // + // The following allows AuralAttributes to be run as an application + // as well as an applet + // + public static void main(String[] args) { + if (args.length > 0) { + if ( (args[0].startsWith("file"+File.pathSeparator)) || + (args[0].startsWith("http"+File.pathSeparator)) ) { + path = args[0]; + } + else { + path = "file:" + args[0]; + } + } + else { + path = "file:."; + } + + if (args.length > 1) { + filename[0] = args[1]; + if (filename[0] != null) { + filenamesGiven++ ; + } + } + + new MainFrame(new MoveAppBoundingLeaf(), 256, 256); + } +} diff --git a/src/Sound/MoveAppBoundingLeaf_plugin.html b/src/Sound/MoveAppBoundingLeaf_plugin.html new file mode 100644 index 0000000..0681917 --- /dev/null +++ b/src/Sound/MoveAppBoundingLeaf_plugin.html @@ -0,0 +1,39 @@ +<HTML> +<HEAD> +<TITLE>MoveAppBoundingLeaf</TITLE> +</HEAD> +<BODY BGCOLOR="#000000"> +<!--"CONVERTED_APPLET"--> +<!-- CONVERTER VERSION 1.3 --> +<OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" +WIDTH = 256 HEIGHT = 256 ALIGN = middle codebase="http://java.sun.com/products/plugin/1.3/jinstall-13-win32.cab#Version=1,3,0,0"> +<PARAM NAME = CODE VALUE = "MoveAppBoundingLeaf.class" > + +<PARAM NAME="type" VALUE="application/x-java-applet;version=1.2.2"> +<PARAM NAME="scriptable" VALUE="false"> +<COMMENT> +<EMBED type="application/x-java-applet;version=1.2.2" CODE = "MoveAppBoundingLeaf.class" WIDTH = 256 HEIGHT = 256 ALIGN = middle scriptable=false pluginspage="http://java.sun.com/products/plugin/1.3/plugin-install.html"><NOEMBED></COMMENT> +<blockquote> +<hr> +If you were using a Java-capable browser, +you would see Hello Universe! instead of this paragraph. +<hr> +</blockquote> +</NOEMBED></EMBED> +</OBJECT> + +<!-- +<APPLET CODE = "MoveAppBoundingLeaf.class" WIDTH = 256 HEIGHT = 256 ALIGN = middle> +<blockquote> +<hr> +If you were using a Java-capable browser, +you would see Hello Universe! instead of this paragraph. +<hr> +</blockquote> + +</APPLET> +--> +<!--"END_CONVERTED_APPLET"--> + +</BODY> +</HTML> diff --git a/src/Sound/README.release b/src/Sound/README.release new file mode 100644 index 0000000..25a8045 --- /dev/null +++ b/src/Sound/README.release @@ -0,0 +1,226 @@ +/* + * @(#)README.release 1.7 01/10/14 09:42:38 + * + * Copyright (c) 1996-2001 Sun Microsystems, Inc. All Rights Reserved. + */ + +========================================================================== +Java 3D(TM) Sound 1.3 Beta 1 +========================================================================== + +Java 3D sound is rendered via the use of a specific implementation +of the AudioDevice3D interface. This release includes two AudioDevice3DL2 +implementations. + += = = = = = = = = = = = = = = = = = = = = = = +HeadspaceMixer AudioDevice3DL2 Implememtation += = = = = = = = = = = = = = = = = = = = = = = + + The HeadspaceMixer implementation is part of the Sun Java 3D + com.sun.j3d.audioengines.headspace package. This implementation + uses a version of the Headspace Audio Engine licensed from Beatnik + which does all rendering in software and pipes the stereo audio image + to the platform's audio device. + + The implemention that was called JavaSoundMixer in previous Sun + releases of Java 3D has been renamed to HeadspaceMixer. + It was renamed in enticipation of the release of a new AudioDevice + implementation that uses JavaSound API which will be called JavaSoundMixer + (described below). + + The HeadspaceMixer audio device will be created and initialized when the + utility SimpleUniverse.Viewer.createAudioDevice() method is called. + If your application uses this utility, no change will be required to + use the recommended HeadspaceMixer implementation. + + If your application explicitly used the older JavaSoundMixer audio device + implemention from the package com.sun.j3d.audioengines.javasound, you should + change the reference to JavaSoundMixer, at least for this Beta 1 release, + to HeadspaceMixer: + + import com.sun.j3d.audioengines.headspace.HeadspaceMixer; + : + HeadspaceMixer mixer = new HeadspaceMixer(physicalEnvironment); + + Most of the Java 3D Audio features have been implemented but there are + a few exceptions. Additionally, some Java 3D Audio features are only + only partially implemented. + + Hang under JDK 1.3 on Windows platforms + --------------------------------------- + Occationally, some applications when run under JDK 1.3 on Windows + experienced window manager hangs. This problem could not be produced + under JDK 1.4. It is recommended that if this problem arrises with + your application that JDK 1.4 be used. + + Audio Features Not Supported with this release: + ----------------------------------------------- + - Cross-talk cancellation is not performed when rendered audio output + on speakers. + - Spatialization of positional and directional sound is very rudimentary. + Point and Cone sound will simply be panned (approximating interaural + intensity difference) and left-right output signals delayed + (approximating interaural delay difference) applying gain attenuation. + - The filtering of sound source (that would aid in Elevation or Front/ + Back differentiation cues) is not implemented with this AudioDevice. + - For this release, distance and angular low-pass filtering of sound + sources is implemented with a very simple algorithm (that choose speed + over accuracy). + - For this release, Sound.POSITIVE_INFINITY is mapped to 2^15. + + Supported MediaContainers data + ------------------------------ + This engine supports 8- and 16- bit linear, and u-law and A-law formatted + files in mono and stereo AU, AIFF, WAV, and PCM file formats. + Compressed formats such as DVI, GSM, and MOD are not supported at this + time. Encoded format such as MP3 are not supported. + + MIDI and RMF files are supported but not fully spatialized. + MIDI file playback as BackgroundSound and attenuated Point/ConeSounds + is at least partially supported with the following limitations: + - For this release MIDI data is automatically cached. + - Point/ConeSound nodes that use MIDI MediaContainers can not be + panned or delayed to simulate Interaural Intensity or Time + Differences due to the limitiation of the underlying technology + used in this implementation. + + InputStreams as MediaContainers are not supported for Point or + ConeSounds in this implementation. + + Reverberation + ------------- + The Headspace engine supports these 5 reverberation environments: + "Closet" very small area, very absorptive surfaces + "Acoustic Lab" med. small area, equally absorptive/reflective + "Garage" med. large area, somewhat reflective surfaces + "Dungeon" medium area, reflective surfaces + "Cavern" large area, highly reflective surfaces + + The AuralAttributes parameters dealing with reverb - + early and late reflection coefficient and delay time, reverb decay + time - are compared to choose one of these five software aural + environments offered as part of the Headspace engine. + Decay speed, paired with the explicit or implicit size of the space, + determine the Headspace Reverb type that is set: + + | Short: Long: + Size Delay Time | Decay <= 1500ms Decay > 1500ms + --------------------------------------------------------------- + small (< 100ms) | 2 "Closet" 4 "Acoustic Lab" + medium (<=500ms) | 3 "Garage" 6 "Dungeon" + large (> 500ms) | 6 "Dungeon" 5 "Cavern" + + A "feature" of this engines 'Dungeon' reverb type is that the + reverberation is added to the opposite pan position from the + sound's position. This creates an aural effect that sounds + like the reverberation is bouncing off the opposite wall of + the 'Dungeon'. + += = = = = = = = = = = = = = = = = = = = = = = +JavaSoundMixer AudioDevice3DL2 Implememtation += = = = = = = = = = = = = = = = = = = = = = = + + The JavaSoundMixer implementation is part of the Sun Java 3D + com.sun.j3d.audioengines.javasound package. This implementation uses + the Java Sound API. All low-level access to the platforms audio device + are dependent on the Java Sound mixer implementation(s) installed on + the machine you're running on. + + The JavaSoundMixer Java 3D audio device implementation uses Java Sound + SourceDataLine streams for non-cached data and Java Sound Clips for + cached data. Support for specific sound cards, the exact input formats + that can be passed as data to Java 3D MediaContainers, and which feature + are rendered in software verses accelleration hardware is dependent on + the Java Sound implementation installed on your machine. + There is guarenteed to be at least one Java Sound mixer implementation + available with all J2SE releases (such as Sun's JDK 1.3 and above). + + Audio Features Not Supported with this release: + ----------------------------------------------- + The JavaSoundMixer is a brand new implementation as of 1.3 Beta 1 + release. While much of the Java 3D Audio API has been implemented + but there are known problems and limitations. Additionally, some Java + 3D Audio features are only partially implemented. + + - Non-linear file formats (A-law and u-law) are not converted. + - MIDI files for all sound types are not implemented. + - There are several timing and channel synchronization problems + encountered when Point and Cone Sounds are rendered. + - Distance and angular low-pass filtering of sound source is not + implemented. + - Spatialization of positional and directional sound is very rudimentary. + See notes above under HeadspaceMixer. + - Cross-talk cancellation for speaker playback is not performed. + + Until these isues are fixed in next Beta 2 release it is recommended + that you use the the HeadspaceMixer implementation. + + Supported MediaContainers data + ------------------------------ + The intent is that all MediaContainer input data types supported by + Java Sound will also be supported by the JavaSoundMixer implementation. + This implementation will not have the restrictions on InputStreams as + the HeadspaceMixer implementation has. + + Reverberation + ------------- + Java 3D reverberation parameters map to a corresponding set + reverb control parameters available thru JavaSound API for Clips + (cached MediaContainers). The exact auralization rendering based + on these parameters is dependent on the Java Sound mixer implementation + choosen. + += = = = = = = = = = = = = = = = = = = = = = = +Use += = = = = = = = = = = = = = = = = = = = = = = +Any Java 3D program that wants to render sounds must create and initialize +an instance of either HeadspaceMixer or JavaSoundMixer directly or indirectly +(using SimpleUniverse utilities). + +All of the sound example programs included in this release use the +com.sun.j3d.utils.universe.SimpleUniverse class to create and initialize +an instance of the HeadspaceMixer with the following code: + + Canvas3D c = new Canvas3D(null); + SimpleUniverse u = new SimpleUniverse(c); + AudioDevice audioDev = u.getViewer().createAudioDevice(); + +As application can initialize the HeadspaceMixer implementation directly +with code like following: + + import com.sun.j3d.audioengines.headspace.HeadspaceMixer; + : + Canvas3D canvas = new Canvas3D(null); + SimpleUniverse univ = new SimpleUniverse(canvas); + univ.getViewingPlatform().setNominalViewingTransform(); + PhysicalEnvironment physicalEnv = + univ.getViewer().getPhysicalEnvironment(); + if (physicalEnv != null) { + HeadspaceMixer mixer = new HeadspaceMixer(physicalEnv); + if (mixer == null) + System.out.println("creation of audio device failed"); + mixer.initialize(); + } + +NOTE: Sun JDK has an implementation of the javax.sound.sampled.Mixer +interface named 'HeadspaceMixer'. If your application also imports the +javax.sound.sampled package you'll need to explicitly differentiate by +specifying the full Java 3D package when referencing HeadspaceMixer: + : + com.sun.j3d.audioengines.headspace.HeadspaceMixer mixer = + new com.sun.j3d.audioengines.headspace.HeadspaceMixer(physicalEnv); + : + + +========================================================================== +General Installation Notes: +========================================================================== + If your Java 3D application has trouble acquiring the AudioDevice + ("Audio Device unavailable" exception occurs) you may need to exit + other applications that use sound. NOTE: If this occurs we would + appreciate being informed as to which sound application Java 3D had + problems running simultaneously with. + + Combining calls to JMF 1.0 methods in your Java 3D sound application + is still dangerous. The engines used by both APIs may not yet be + robust enough to handle supporting both of these concurrently. diff --git a/src/Sound/ReverberateSound.html b/src/Sound/ReverberateSound.html new file mode 100644 index 0000000..7bdee49 --- /dev/null +++ b/src/Sound/ReverberateSound.html @@ -0,0 +1,15 @@ +<HTML> +<HEAD> +<TITLE>ReverberateSound</TITLE> +</HEAD> +<BODY BGCOLOR="#000000"> +<applet align=middle code="ReverberateSound.class" width=256 height=256> +<blockquote> +<hr> +If you were using a Java-capable browser, +you would see Hello Universe! instead of this paragraph. +<hr> +</blockquote> +</applet> +</BODY> +</HTML> diff --git a/src/Sound/ReverberateSound.java b/src/Sound/ReverberateSound.java new file mode 100644 index 0000000..2404a39 --- /dev/null +++ b/src/Sound/ReverberateSound.java @@ -0,0 +1,220 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +/* + * ReverberateSound + * + * Same as MoveSound except this calls UniverseBuilderJS to use the + * JavaSoundMixer AudioDevice rather than the HolosketchMixer device. + * + * NOTE: To run this anywhere but the Solaris Eng Menlo Park network + * the URL path must be set to the java3d/javaone directory. + */ + +import java.applet.Applet; +import java.awt.*; +import java.awt.event.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.geometry.ColorCube; +import com.sun.j3d.utils.universe.*; +import java.io.File; +import javax.media.j3d.*; +import javax.vecmath.*; + +public class ReverberateSound extends Applet { + + // File name of sound sample + private static String[] filename = new String[1]; + private static String path = null; + private static int filenamesGiven = 0; + private static boolean filenamesSet = false; + + private SimpleUniverse u = null; + + public BranchGroup createSceneGraph() { + // Create the root of the subgraph + BranchGroup objRoot = new BranchGroup(); + + // Create the transform group node and initialize it to the identity. + // Enable the TRANSFORM_WRITE capability so that our behavior code + // can modify it at runtime. Add it to the root of the subgraph. + TransformGroup objTrans = new TransformGroup(); + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objRoot.addChild(objTrans); + + // Create a simple shape leaf node and add it into the scene graph. + objTrans.addChild(new ColorCube(0.4)); + + // Create a new Behavior object that will perform the desired + // operation on the specified transform object and add it into the + // scene graph. + Transform3D yAxis = new Transform3D(); + Alpha rotation = new Alpha(-1, Alpha.INCREASING_ENABLE, + 0, 0, + 20000, 0, 0, + 0, 0, 0); + RotationInterpolator rotator = + new RotationInterpolator(rotation, + objTrans, yAxis, + 0.0f, (float) Math.PI*2.0f); + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + rotator.setSchedulingBounds(bounds); + objTrans.addChild(rotator); + + // + // Create an AuralAttribute with reverb params set + // + Soundscape soundScape2 = new Soundscape(); + AuralAttributes attributes2 = new AuralAttributes(); + attributes2.setReverbOrder(6); + attributes2.setCapability(AuralAttributes.ALLOW_REVERB_ORDER_WRITE); + attributes2.setCapability(AuralAttributes.ALLOW_REVERB_DELAY_WRITE); + attributes2.setCapability(AuralAttributes.ALLOW_REFLECTION_COEFFICIENT_WRITE); + soundScape2.setApplicationBounds(bounds); + soundScape2.setAuralAttributes(attributes2); + objRoot.addChild(soundScape2); + + // + // Create a sound node and add it to the scene graph + // + PointSound sound = new PointSound(); + sound.setCapability(PointSound.ALLOW_ENABLE_WRITE); + sound.setCapability(PointSound.ALLOW_INITIAL_GAIN_WRITE); + sound.setCapability(PointSound.ALLOW_SOUND_DATA_WRITE); + sound.setCapability(PointSound.ALLOW_DURATION_READ); + sound.setCapability(PointSound.ALLOW_POSITION_WRITE); + sound.setCapability(PointSound.ALLOW_LOOP_WRITE); + sound.setSchedulingBounds(bounds); + + objTrans.addChild(sound); + // + // Create a new Behavior object that will play the sound + // + AudioReverberate player = new AudioReverberate(sound, filename[0], + attributes2); + player.setSchedulingBounds(bounds); + objTrans.addChild(player); + + + return objRoot; + } + + public ReverberateSound() { + } + + public void init() { + if (!filenamesSet) { + // path is null if started from applet + if (path == null) { + // the path for an applet + path = getCodeBase().toString(); + } + + /* + * append given file name to given URL path + */ + if (filenamesGiven > 0) { + filename[0] = new String(path + "/" + filename[0]); + } + else { + // fill in default file names if all three not given + filename[0] = new String(path + "/hello_universe.au"); + } + filenamesSet = true; + } + + setLayout(new BorderLayout()); + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + Canvas3D c = new Canvas3D(config); + add("Center", c); + + /* + * Create a simple scene and attach it to the virtual universe + */ + u = new SimpleUniverse(c); + AudioDevice audioDev = u.getViewer().createAudioDevice(); + BranchGroup scene = createSceneGraph(); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + u.getViewingPlatform().setNominalViewingTransform(); + + u.addBranchGraph(scene); + } + + public void destroy() { + u.cleanup(); + } + + // + // The following allows ReverberateSound to be run as an application + // as well as an applet + // + public static void main(String[] args) { + if (args.length > 0) { + if ( (args[0].startsWith("file"+File.pathSeparator)) || + (args[0].startsWith("http"+File.pathSeparator)) ) { + path = args[0]; + } + else { + path = "file:" + args[0]; + } + } + else { + path = "file:."; + } + + if (args.length > 1) { + filename[0] = args[1]; + if (filename[0] != null) { + filenamesGiven++ ; + } + } + + new MainFrame(new ReverberateSound(), 256, 256); + } +} diff --git a/src/Sound/ReverberateSound_plugin.html b/src/Sound/ReverberateSound_plugin.html new file mode 100644 index 0000000..a3cd545 --- /dev/null +++ b/src/Sound/ReverberateSound_plugin.html @@ -0,0 +1,39 @@ +<HTML> +<HEAD> +<TITLE>ReverberateSound</TITLE> +</HEAD> +<BODY BGCOLOR="#000000"> +<!--"CONVERTED_APPLET"--> +<!-- CONVERTER VERSION 1.3 --> +<OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" +WIDTH = 256 HEIGHT = 256 ALIGN = middle codebase="http://java.sun.com/products/plugin/1.3/jinstall-13-win32.cab#Version=1,3,0,0"> +<PARAM NAME = CODE VALUE = "ReverberateSound.class" > + +<PARAM NAME="type" VALUE="application/x-java-applet;version=1.2.2"> +<PARAM NAME="scriptable" VALUE="false"> +<COMMENT> +<EMBED type="application/x-java-applet;version=1.2.2" CODE = "ReverberateSound.class" WIDTH = 256 HEIGHT = 256 ALIGN = middle scriptable=false pluginspage="http://java.sun.com/products/plugin/1.3/plugin-install.html"><NOEMBED></COMMENT> +<blockquote> +<hr> +If you were using a Java-capable browser, +you would see Hello Universe! instead of this paragraph. +<hr> +</blockquote> +</NOEMBED></EMBED> +</OBJECT> + +<!-- +<APPLET CODE = "ReverberateSound.class" WIDTH = 256 HEIGHT = 256 ALIGN = middle> +<blockquote> +<hr> +If you were using a Java-capable browser, +you would see Hello Universe! instead of this paragraph. +<hr> +</blockquote> + +</APPLET> +--> +<!--"END_CONVERTED_APPLET"--> + +</BODY> +</HTML> diff --git a/src/Sound/SimpleSounds.html b/src/Sound/SimpleSounds.html new file mode 100644 index 0000000..1330e5f --- /dev/null +++ b/src/Sound/SimpleSounds.html @@ -0,0 +1,15 @@ +<HTML> +<HEAD> +<TITLE>Simple Sound test</TITLE> +</HEAD> +<BODY BGCOLOR="#000000"> +<applet align=middle code="SimpleSounds.class" width=256 height=256> +<blockquote> +<hr> +If you were using a Java-capable browser, +you would see Simple Sound test instead of this paragraph. +<hr> +</blockquote> +</applet> +</BODY> +</HTML> diff --git a/src/Sound/SimpleSounds.java b/src/Sound/SimpleSounds.java new file mode 100644 index 0000000..e40c58c --- /dev/null +++ b/src/Sound/SimpleSounds.java @@ -0,0 +1,292 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +import java.applet.Applet; +import java.net.URL; +import java.awt.*; +import java.awt.event.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.geometry.ColorCube; +import com.sun.j3d.utils.universe.*; +import java.io.File; +import java.security.*; +import javax.media.j3d.*; +import javax.vecmath.*; + +/* + * This Java3D program: + * Creates an instance of the JavaSoundMixer AudioDevice, initializing it + * and attaching it to the PhysicalEnvironment by using + * SimpleUniverse. + * Creates one cached Background and two cached Point sound sources. + * Creates and executes a custom behavior (SimpleSoundsBehavior) that + * starts the sound playing and transforms the PointSound source + * by modifying the TransformGroup that contains the Sound nodes. + * + * Usage: + * java SimpleSounds [URLpath [name1 [name2 [name2]]]] + * + * The first optional command line parameter is the URL path to directory + * containing "file:" or "http:" and then directory path string. + * If you are using the suppled default sound files in the same directory + * as this test program then only the URLpath need be supplied on the + * command line. + * If this parameter is not included then the current path to the directory + * this program is running in is used for an application + * and the codebase is used for an applet. + * The second thru fourth optional command line parameters are sound file names + * If not given, the default file names are: + * techno_machine.au + * hello_universe.au + * roar.au + * that correspond to the 3 'voice' quality, 8-bit, u-law, 8-kHz samples + * included in the same directory as this test program. + * + * Java Sound engine has been advertised to support the following 8- and 16- + * bit, linear and u-law, mono and stereo sound sample file formats: AU, + * AIFF, WAV, and PCM. Non-cached MIDI and RMF files are also supported. + * Neither compressed formats (DVI, GSM, MOD) nor A-law formated files are + * supported at this time, but they will be converted. + */ + +public class SimpleSounds extends Applet { + + // File name of sound sample + private static int filenamesGiven = 0; + private static URL[] url = new URL[3]; + private static String[] filename = new String[3]; + private static String path = null; + private static boolean filenamesSet = false; + + private SimpleUniverse u = null; + + public BranchGroup createSceneGraph() { + // Create the root of the subgraph + BranchGroup objRoot = new BranchGroup(); + + // Create the transform group node and initialize it to the identity. + // Enable the TRANSFORM_WRITE capability so that our behavior code + // can modify it at runtime. Add it to the root of the subgraph. + TransformGroup objTrans = new TransformGroup(); + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objRoot.addChild(objTrans); + + // Create a simple shape leaf node and add it into the scene graph. + objTrans.addChild(new ColorCube(0.4)); + + // Create a new Behavior object that will perform the desired + // operation on the specified transform object and add it into the + // scene graph. + Transform3D yAxis = new Transform3D(); + Alpha rotation = new Alpha(-1, Alpha.INCREASING_ENABLE, + 0, 0, + 20000, 0, 0, + 0, 0, 0); + RotationInterpolator rotator = + new RotationInterpolator(rotation, + objTrans, yAxis, + 0.0f, (float) Math.PI*2.0f); + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + rotator.setSchedulingBounds(bounds); + objTrans.addChild(rotator); + /* + * Create a sound node and add it to the scene graph + */ + BackgroundSound sound1 = new BackgroundSound(); + PointSound sound2 = new PointSound(); + PointSound sound3 = new PointSound(); + sound1.setCapability(PointSound.ALLOW_ENABLE_WRITE); + sound1.setCapability(PointSound.ALLOW_INITIAL_GAIN_WRITE); + sound1.setCapability(PointSound.ALLOW_SOUND_DATA_WRITE); + sound1.setCapability(PointSound.ALLOW_SCHEDULING_BOUNDS_WRITE); + sound1.setCapability(PointSound.ALLOW_CONT_PLAY_WRITE); + sound1.setCapability(PointSound.ALLOW_RELEASE_WRITE); + sound1.setCapability(PointSound.ALLOW_DURATION_READ); + sound1.setCapability(PointSound.ALLOW_IS_PLAYING_READ); + sound1.setCapability(PointSound.ALLOW_LOOP_WRITE); + sound2.setCapability(PointSound.ALLOW_ENABLE_WRITE); + sound2.setCapability(PointSound.ALLOW_INITIAL_GAIN_WRITE); + sound2.setCapability(PointSound.ALLOW_SOUND_DATA_WRITE); + sound2.setCapability(PointSound.ALLOW_SCHEDULING_BOUNDS_WRITE); + sound2.setCapability(PointSound.ALLOW_CONT_PLAY_WRITE); + sound2.setCapability(PointSound.ALLOW_RELEASE_WRITE); + sound2.setCapability(PointSound.ALLOW_DURATION_READ); + sound2.setCapability(PointSound.ALLOW_IS_PLAYING_READ); + sound2.setCapability(PointSound.ALLOW_POSITION_WRITE); + sound2.setCapability(PointSound.ALLOW_LOOP_WRITE); + sound3.setCapability(PointSound.ALLOW_ENABLE_WRITE); + sound3.setCapability(PointSound.ALLOW_INITIAL_GAIN_WRITE); + sound3.setCapability(PointSound.ALLOW_SOUND_DATA_WRITE); + sound3.setCapability(PointSound.ALLOW_SCHEDULING_BOUNDS_WRITE); + sound3.setCapability(PointSound.ALLOW_CONT_PLAY_WRITE); + sound3.setCapability(PointSound.ALLOW_RELEASE_WRITE); + sound3.setCapability(PointSound.ALLOW_DURATION_READ); + sound3.setCapability(PointSound.ALLOW_IS_PLAYING_READ); + sound3.setCapability(PointSound.ALLOW_POSITION_WRITE); + + BoundingSphere soundBounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + sound1.setSchedulingBounds(soundBounds); + sound2.setSchedulingBounds(soundBounds); + sound3.setSchedulingBounds(soundBounds); + objTrans.addChild(sound1); + objTrans.addChild(sound2); + objTrans.addChild(sound3); + + + /* + * Create a new Behavior object that will play the sound + */ + SimpleSoundsBehavior player = new SimpleSoundsBehavior( + sound1, sound2, sound3, + url[0], url[1], url[2], soundBounds); + player.setSchedulingBounds(soundBounds); + objTrans.addChild(player); + + // Let Java 3D perform optimizations on this scene graph. + objRoot.compile(); + + return objRoot; + } + + public SimpleSounds() { + } + + public void init() { + if (!filenamesSet) { + // path is null if started from appletviewer/browser + if (path == null) { + // the path for an applet + path = getCodeBase().toString(); + } + int j; + /* + * append given file name to given URL path + */ + for (j=0; j<filenamesGiven; j++) + filename[j] = new String(path + "/" + filename[j]); + /* + * fill in default file names if all three not given + */ + for (int i=j; i<3; i++) { + if (i == 0) + filename[0] = new String(path + "/techno_machine.au"); + if (i == 1) + filename[1] = new String(path + "/hello_universe.au"); + if (i == 2) + filename[2] = new String(path + "/roar.au"); + } + filenamesSet = true; + } + + setLayout(new BorderLayout()); + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + Canvas3D c = new Canvas3D(config); + add("Center", c); + + /* + * Change filenames into URLs + */ + for (int i=0; i<3; i++) { + try { + url[i] = new URL(filename[i]); + } + catch (Exception e) { + System.out.println(e.getMessage()); + return; + } + } + + /* + * Create a simple scene and attach it to the virtual universe + */ + u = new SimpleUniverse(c); + AudioDevice audioDev = u.getViewer().createAudioDevice(); + BranchGroup scene = createSceneGraph(); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + u.getViewingPlatform().setNominalViewingTransform(); + + u.addBranchGraph(scene); + } + + public void destroy() { + u.cleanup(); + } + + /* + * The following allows SimpleSounds to be run as an application + * as well as an applet + */ + public static void main(String[] args) { + if (args.length > 0) { + if ( (args[0].startsWith("file"+File.pathSeparator)) || + (args[0].startsWith("http"+File.pathSeparator)) ) { + path = args[0]; + } + else { + path = "file:" + args[0]; + } + } + else { + path = "file:."; + } + + for (int i=0; i<3; i++) { + if (args.length > (i+1)) { + filename[i] = args[i+1]; + if (filename[i] != null) { + filenamesGiven++ ; + } + } + else + break; + } + new MainFrame(new SimpleSounds(), args, 256, 256); + } +} diff --git a/src/Sound/SimpleSoundsBehavior.java b/src/Sound/SimpleSoundsBehavior.java new file mode 100644 index 0000000..6293d3d --- /dev/null +++ b/src/Sound/SimpleSoundsBehavior.java @@ -0,0 +1,177 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +import javax.media.j3d.*; +import javax.vecmath.*; +import java.net.URL; +import java.util.Enumeration; + +// User defined audio behavior class +public class SimpleSoundsBehavior extends Behavior { + WakeupOnElapsedTime wt; + WakeupOnBehaviorPost wp; + BackgroundSound sound1 = new BackgroundSound(); + PointSound sound2 = new PointSound(); + PointSound sound3 = new PointSound(); + static int WAKEUP_SOUND = 0; + int soundIndex = 0; + URL URLName1; + URL URLName2; + URL URLName3; + BoundingSphere bounds; + + // Override Behavior's initialize method to setup wakeup criteria + public void initialize() { + MediaContainer sample1 = new MediaContainer(); + MediaContainer sample2 = new MediaContainer(); + MediaContainer sample3 = new MediaContainer(); + sample1.setCapability(MediaContainer.ALLOW_URL_WRITE); + sample1.setCapability(MediaContainer.ALLOW_URL_READ); + sample1.setURLObject(URLName1); + //sample1.setCacheEnable(false); + sound1.setLoop(0); + sound1.setContinuousEnable(false); + sound1.setReleaseEnable(false); + sound1.setSoundData(sample1); + sound1.setInitialGain(0.7f); + sample2.setCapability(MediaContainer.ALLOW_URL_WRITE); + sample2.setCapability(MediaContainer.ALLOW_URL_READ); + sample2.setURLObject(URLName2); + sound2.setLoop(Sound.INFINITE_LOOPS); + sound2.setContinuousEnable(false); + sound2.setReleaseEnable(false); + sound2.setSoundData(sample2); + sound2.setInitialGain(2.0f); + Point3f sound2Pos = new Point3f(-30.0f, 0.0f, 0.0f); + sound2.setPosition(sound2Pos); + sample3.setCapability(MediaContainer.ALLOW_URL_WRITE); + sample3.setCapability(MediaContainer.ALLOW_URL_READ); + sample3.setURLObject(URLName3); + sound3.setContinuousEnable(false); + sound3.setReleaseEnable(false); + sound3.setSoundData(sample3); + sound3.setInitialGain(4.0f); + Point3f sound3Pos = new Point3f(30.0f, 0.0f, 0.0f); + sound3.setPosition(sound3Pos); + + wt = new WakeupOnElapsedTime(2000); + WakeupOnElapsedTime wp = new WakeupOnElapsedTime(5000); + wakeupOn(wp); + } + + // Override Behavior's stimulus method to handle the event + public void processStimulus(Enumeration criteria) { + + switch (soundIndex) + { + // Active + case 0: + // System.out.println("****Enable First Sound"); + sound1.setEnable(true); + wakeupOn(wt); + break; + case 1: + // System.out.println("********Enable Second Sound"); + sound2.setEnable(true); + wakeupOn(wt); + break; + case 2: + case 4: + case 6: + case 8: + case 10: + // System.out.println("************Enable Third Sound"); + sound3.setEnable(true); + wakeupOn(wt); + break; + case 3: + case 5: + case 7: + case 9: + // System.out.println("************Disable Third Sound"); + sound3.setEnable(false); + wakeupOn(wt); + break; + + case 11: + // System.out.println("********Disable Second Sound"); + sound2.setEnable(false) ; + wakeupOn(wt); + break; + case 12: + // System.out.println("****Disable First Sound"); + sound1.setEnable(false) ; + System.out.println("SimpleSounds: test complete"); + wt = new WakeupOnElapsedTime(400000); + wakeupOn(wt); + break; + + default: + break; + } + soundIndex++; + } + + // + // Constructor for rotation behavior. + // Parameters: sound node + // sample file name + // sound node's bounds + // + public SimpleSoundsBehavior(BackgroundSound sound1, + PointSound sound2, + PointSound sound3, + URL urlName1, + URL urlName2, + URL urlName3, + BoundingSphere soundBounds) { + this.sound1 = sound1; + this.sound2 = sound2; + this.sound3 = sound3; + this.URLName1 = urlName1; + this.URLName2 = urlName2; + this.URLName3 = urlName3; + this.bounds = (BoundingSphere)soundBounds.clone(); + } +} diff --git a/src/Sound/SimpleSounds_plugin.html b/src/Sound/SimpleSounds_plugin.html new file mode 100644 index 0000000..55d834e --- /dev/null +++ b/src/Sound/SimpleSounds_plugin.html @@ -0,0 +1,39 @@ +<HTML> +<HEAD> +<TITLE>Simple Sound test</TITLE> +</HEAD> +<BODY BGCOLOR="#000000"> +<!--"CONVERTED_APPLET"--> +<!-- CONVERTER VERSION 1.3 --> +<OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" +WIDTH = 256 HEIGHT = 256 ALIGN = middle codebase="http://java.sun.com/products/plugin/1.3/jinstall-13-win32.cab#Version=1,3,0,0"> +<PARAM NAME = CODE VALUE = "SimpleSounds.class" > + +<PARAM NAME="type" VALUE="application/x-java-applet;version=1.2.2"> +<PARAM NAME="scriptable" VALUE="false"> +<COMMENT> +<EMBED type="application/x-java-applet;version=1.2.2" CODE = "SimpleSounds.class" WIDTH = 256 HEIGHT = 256 ALIGN = middle scriptable=false pluginspage="http://java.sun.com/products/plugin/1.3/plugin-install.html"><NOEMBED></COMMENT> +<blockquote> +<hr> +If you were using a Java-capable browser, +you would see Simple Sound test instead of this paragraph. +<hr> +</blockquote> +</NOEMBED></EMBED> +</OBJECT> + +<!-- +<APPLET CODE = "SimpleSounds.class" WIDTH = 256 HEIGHT = 256 ALIGN = middle> +<blockquote> +<hr> +If you were using a Java-capable browser, +you would see Simple Sound test instead of this paragraph. +<hr> +</blockquote> + +</APPLET> +--> +<!--"END_CONVERTED_APPLET"--> + +</BODY> +</HTML> diff --git a/src/Sound/build.xml b/src/Sound/build.xml new file mode 100644 index 0000000..cbf53a8 --- /dev/null +++ b/src/Sound/build.xml @@ -0,0 +1,66 @@ +<?xml version="1.0"?> + +<!-- +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + --> + +<project basedir="." default="compile"> + <target name="compile"> + <javac debug="true" deprecation="true" destdir="." srcdir="."> + </javac> + </target> + + <target name="all" depends="compile"> + </target> + + <target description="Clean all build products." name="clean"> + <delete> + <fileset dir="."> + <include name="**/*.class"/> + </fileset> + </delete> + </target> + +</project> diff --git a/src/Sound/hello_universe.au b/src/Sound/hello_universe.au Binary files differnew file mode 100644 index 0000000..08d7456 --- /dev/null +++ b/src/Sound/hello_universe.au diff --git a/src/Sound/roar.au b/src/Sound/roar.au Binary files differnew file mode 100644 index 0000000..202b628 --- /dev/null +++ b/src/Sound/roar.au diff --git a/src/Sound/techno_machine.au b/src/Sound/techno_machine.au Binary files differnew file mode 100644 index 0000000..12e47ea --- /dev/null +++ b/src/Sound/techno_machine.au |