Mercurial > jmeCapture
diff src/com/aurellem/capture/examples/Advanced.java @ 41:58386a64d019
renamed stuff
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Thu, 03 Nov 2011 16:55:43 -0700 |
parents | |
children | b1bc965a38d2 |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/com/aurellem/capture/examples/Advanced.java Thu Nov 03 16:55:43 2011 -0700 1.3 @@ -0,0 +1,277 @@ 1.4 +package com.aurellem.capture.examples; 1.5 + 1.6 +import java.io.File; 1.7 +import java.io.FileNotFoundException; 1.8 +import java.io.IOException; 1.9 +import java.nio.ByteBuffer; 1.10 +import java.util.logging.Level; 1.11 +import java.util.logging.Logger; 1.12 + 1.13 +import javax.sound.sampled.AudioFormat; 1.14 + 1.15 +import org.tritonus.share.sampled.FloatSampleTools; 1.16 + 1.17 +import com.aurellem.capture.Capture; 1.18 +import com.aurellem.capture.IsoTimer; 1.19 +import com.aurellem.capture.audio.CompositeSoundProcessor; 1.20 +import com.aurellem.capture.audio.MultiListener; 1.21 +import com.aurellem.capture.audio.SoundProcessor; 1.22 +import com.aurellem.capture.audio.WaveFileWriter; 1.23 +import com.jme3.app.SimpleApplication; 1.24 +import com.jme3.audio.AudioNode; 1.25 +import com.jme3.audio.Listener; 1.26 +import com.jme3.cinematic.MotionPath; 1.27 +import com.jme3.cinematic.events.MotionTrack; 1.28 +import com.jme3.material.Material; 1.29 +import com.jme3.math.ColorRGBA; 1.30 +import com.jme3.math.FastMath; 1.31 +import com.jme3.math.Quaternion; 1.32 +import com.jme3.math.Vector3f; 1.33 +import com.jme3.scene.Geometry; 1.34 +import com.jme3.scene.Node; 1.35 +import com.jme3.scene.shape.Box; 1.36 +import com.jme3.scene.shape.Sphere; 1.37 +import com.jme3.system.AppSettings; 1.38 + 1.39 + 1.40 +/** 1.41 + * 1.42 + * Demonstrates advanced use of the audio capture and recording features. 1.43 + * Multiple perspectives of the same scene are simultaneously rendered to 1.44 + * different sound files. 1.45 + * 1.46 + * A key limitation of the way multiple listeners are implemented is that 1.47 + * only 3D positioning effects are realized for listeners other than the 1.48 + * main LWJGL listener. This means that audio effects such as environment 1.49 + * settings will *not* be heard on any auxiliary listeners, though sound 1.50 + * attenuation will work correctly. 1.51 + * 1.52 + * Multiple listeners as realized here might be used to make AI entities 1.53 + * that can each hear the world from their own perspective. 1.54 + * 1.55 + * @author Robert McIntyre 1.56 + * 1.57 + */ 1.58 + 1.59 +public class Advanced extends SimpleApplication { 1.60 + 1.61 + 1.62 + private Geometry bell; 1.63 + private Geometry ear1; 1.64 + private Geometry ear2; 1.65 + private Geometry ear3; 1.66 + private AudioNode music; 1.67 + private MotionTrack motionControl; 1.68 + 1.69 + public static void main(String[] args) { 1.70 + Logger.getLogger("com.jme3").setLevel(Level.OFF); 1.71 + Advanced app = new Advanced(); 1.72 + AppSettings settings = new AppSettings(true); 1.73 + settings.setAudioRenderer("Send"); 1.74 + app.setSettings(settings); 1.75 + app.setShowSettings(false); 1.76 + app.setPauseOnLostFocus(false); 1.77 + 1.78 + try { 1.79 + Capture.captureVideo(app, File.createTempFile("advanced",".avi")); 1.80 + Capture.captureAudio(app, File.createTempFile("advanced", ".wav")); 1.81 + } 1.82 + catch (IOException e) {e.printStackTrace();} 1.83 + app.start(); 1.84 + } 1.85 + 1.86 + private Geometry makeEar(Node root, Vector3f position){ 1.87 + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); 1.88 + Geometry ear = new Geometry("ear", new Box(1.0f, 1.0f, 1.0f)); 1.89 + ear.setLocalTranslation(position); 1.90 + mat.setColor("Color", ColorRGBA.Green); 1.91 + ear.setMaterial(mat); 1.92 + root.attachChild(ear); 1.93 + return ear; 1.94 + } 1.95 + 1.96 + private Vector3f[] path = new Vector3f[]{ 1.97 + // loop 1 1.98 + new Vector3f(0, 0, 0), 1.99 + new Vector3f(0, 0, -10), 1.100 + new Vector3f(-2, 0, -14), 1.101 + new Vector3f(-6, 0, -20), 1.102 + new Vector3f(0, 0, -26), 1.103 + new Vector3f(6, 0, -20), 1.104 + new Vector3f(0, 0, -14), 1.105 + new Vector3f(-6, 0, -20), 1.106 + new Vector3f(0, 0, -26), 1.107 + new Vector3f(6, 0, -20), 1.108 + // loop 2 1.109 + new Vector3f(5, 0, -5), 1.110 + new Vector3f(7, 0, 1.5f), 1.111 + new Vector3f(14, 0, 2), 1.112 + new Vector3f(20, 0, 6), 1.113 + new Vector3f(26, 0, 0), 1.114 + new Vector3f(20, 0, -6), 1.115 + new Vector3f(14, 0, 0), 1.116 + new Vector3f(20, 0, 6), 1.117 + new Vector3f(26, 0, 0), 1.118 + new Vector3f(20, 0, -6), 1.119 + new Vector3f(14, 0, 0), 1.120 + // loop 3 1.121 + new Vector3f(8, 0, 7.5f), 1.122 + new Vector3f(7, 0, 10.5f), 1.123 + new Vector3f(6, 0, 20), 1.124 + new Vector3f(0, 0, 26), 1.125 + new Vector3f(-6, 0, 20), 1.126 + new Vector3f(0, 0, 14), 1.127 + new Vector3f(6, 0, 20), 1.128 + new Vector3f(0, 0, 26), 1.129 + new Vector3f(-6, 0, 20), 1.130 + new Vector3f(0, 0, 14), 1.131 + // begin ellipse 1.132 + new Vector3f(16, 5, 20), 1.133 + new Vector3f(0, 0, 26), 1.134 + new Vector3f(-16, -10, 20), 1.135 + new Vector3f(0, 0, 14), 1.136 + new Vector3f(16, 20, 20), 1.137 + new Vector3f(0, 0, 26), 1.138 + new Vector3f(-10, -25, 10), 1.139 + new Vector3f(-10, 0, 0), 1.140 + // come at me! 1.141 + new Vector3f(-28.00242f, 48.005623f, -34.648228f), 1.142 + new Vector3f(0, 0 , -20), 1.143 + }; 1.144 + 1.145 + private void createScene() { 1.146 + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); 1.147 + bell = new Geometry( "sound-emitter" , new Sphere(15,15,1)); 1.148 + mat.setColor("Color", ColorRGBA.Blue); 1.149 + bell.setMaterial(mat); 1.150 + rootNode.attachChild(bell); 1.151 + 1.152 + ear1 = makeEar(rootNode, new Vector3f(0, 0 ,-20)); 1.153 + ear2 = makeEar(rootNode, new Vector3f(0, 0 ,20)); 1.154 + ear3 = makeEar(rootNode, new Vector3f(20, 0 ,0)); 1.155 + 1.156 + MotionPath track = new MotionPath(); 1.157 + 1.158 + for (Vector3f v : path){ 1.159 + track.addWayPoint(v); 1.160 + } 1.161 + track.setCurveTension(0.80f); 1.162 + 1.163 + motionControl = new MotionTrack(bell,track); 1.164 + motionControl.setTimer(new IsoTimer(60)); 1.165 + motionControl.setDirectionType(MotionTrack.Direction.PathAndRotation); 1.166 + motionControl.setRotation(new Quaternion().fromAngleNormalAxis(-FastMath.HALF_PI, Vector3f.UNIT_Y)); 1.167 + motionControl.setInitialDuration(20f); 1.168 + motionControl.setSpeed(1f); 1.169 + 1.170 + track.enableDebugShape(assetManager, rootNode); 1.171 + positionCamera(); 1.172 + } 1.173 + 1.174 + 1.175 + private void positionCamera(){ 1.176 + this.cam.setLocation(new Vector3f(-28.00242f, 48.005623f, -34.648228f)); 1.177 + this.cam.setRotation(new Quaternion(0.3359635f, 0.34280345f, -0.13281013f, 0.8671653f)); 1.178 + } 1.179 + 1.180 + private void initAudio() { 1.181 + org.lwjgl.input.Mouse.setGrabbed(false); 1.182 + music = new AudioNode(assetManager, "Sound/Effects/Beep.ogg", false); 1.183 + 1.184 + rootNode.attachChild(music); 1.185 + audioRenderer.playSource(music); 1.186 + music.setPositional(true); 1.187 + music.setVolume(1f); 1.188 + music.setReverbEnabled(false); 1.189 + music.setDirectional(false); 1.190 + music.setMaxDistance(200.0f); 1.191 + music.setRefDistance(1f); 1.192 + music.setRolloffFactor(1f); 1.193 + music.setLooping(false); 1.194 + audioRenderer.pauseSource(music); 1.195 + } 1.196 + 1.197 + 1.198 + 1.199 + 1.200 + 1.201 + 1.202 + public class Dancer implements SoundProcessor { 1.203 + Geometry entity; 1.204 + float scale = 2; 1.205 + public Dancer(Geometry entity){ 1.206 + this.entity = entity; 1.207 + } 1.208 + 1.209 + /** 1.210 + * this method is irrelevant since there is no state to cleanup. 1.211 + */ 1.212 + public void cleanup() {} 1.213 + 1.214 + 1.215 + /** 1.216 + * Respond to sound! This is the brain of an AI entity that 1.217 + * hears it's surroundings and reacts to them. 1.218 + */ 1.219 + public void process(ByteBuffer audioSamples, int numSamples, AudioFormat format) { 1.220 + audioSamples.clear(); 1.221 + byte[] data = new byte[numSamples]; 1.222 + float[] out = new float[numSamples]; 1.223 + audioSamples.get(data); 1.224 + FloatSampleTools.byte2floatInterleaved(data, 0, out, 0, 1.225 + numSamples/format.getFrameSize(), format); 1.226 + 1.227 + float max = Float.NEGATIVE_INFINITY; 1.228 + for (float f : out){if (f > max) max = f;} 1.229 + audioSamples.clear(); 1.230 + 1.231 + if (max > 0.1){entity.getMaterial().setColor("Color", ColorRGBA.Green);} 1.232 + else {entity.getMaterial().setColor("Color", ColorRGBA.Gray);} 1.233 + } 1.234 + } 1.235 + 1.236 + private void prepareEar(Geometry ear, int n){ 1.237 + if (this.audioRenderer instanceof MultiListener){ 1.238 + MultiListener rf = (MultiListener)this.audioRenderer; 1.239 + 1.240 + Listener auxListener = new Listener(); 1.241 + auxListener.setLocation(ear.getLocalTranslation()); 1.242 + 1.243 + rf.addListener(auxListener); 1.244 + WaveFileWriter aux = null; 1.245 + 1.246 + try {aux = new WaveFileWriter(new File("/home/r/tmp/ear"+n+".wav"));} 1.247 + catch (FileNotFoundException e) {e.printStackTrace();} 1.248 + 1.249 + rf.registerSoundProcessor(auxListener, 1.250 + new CompositeSoundProcessor(new Dancer(ear), aux)); 1.251 + 1.252 + } 1.253 + } 1.254 + 1.255 + 1.256 + public void simpleInitApp() { 1.257 + this.setTimer(new IsoTimer(60)); 1.258 + initAudio(); 1.259 + 1.260 + createScene(); 1.261 + 1.262 + prepareEar(ear1, 1); 1.263 + prepareEar(ear2, 1); 1.264 + prepareEar(ear3, 1); 1.265 + 1.266 + motionControl.play(); 1.267 + } 1.268 + 1.269 + public void simpleUpdate(float tpf) { 1.270 + if (music.getStatus() != AudioNode.Status.Playing){ 1.271 + music.play(); 1.272 + } 1.273 + Vector3f loc = cam.getLocation(); 1.274 + Quaternion rot = cam.getRotation(); 1.275 + listener.setLocation(loc); 1.276 + listener.setRotation(rot); 1.277 + music.setLocalTranslation(bell.getLocalTranslation()); 1.278 + } 1.279 + 1.280 +}