Mercurial > jmeCapture
view src/com/aurellem/capture/examples/Advanced.java @ 42:b1bc965a38d2
use reflection to set timer for MotionTrack for now
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Thu, 03 Nov 2011 18:47:21 -0700 |
parents | 58386a64d019 |
children | 2f129118e2d6 |
line wrap: on
line source
1 package com.aurellem.capture.examples;3 import java.io.File;4 import java.io.FileNotFoundException;5 import java.io.IOException;6 import java.lang.reflect.Field;7 import java.nio.ByteBuffer;8 import java.util.logging.Level;9 import java.util.logging.Logger;11 import javax.sound.sampled.AudioFormat;13 import org.tritonus.share.sampled.FloatSampleTools;15 import com.aurellem.capture.Capture;16 import com.aurellem.capture.IsoTimer;17 import com.aurellem.capture.audio.CompositeSoundProcessor;18 import com.aurellem.capture.audio.MultiListener;19 import com.aurellem.capture.audio.SoundProcessor;20 import com.aurellem.capture.audio.WaveFileWriter;21 import com.jme3.app.SimpleApplication;22 import com.jme3.audio.AudioNode;23 import com.jme3.audio.Listener;24 import com.jme3.cinematic.MotionPath;25 import com.jme3.cinematic.events.AbstractCinematicEvent;26 import com.jme3.cinematic.events.MotionTrack;27 import com.jme3.material.Material;28 import com.jme3.math.ColorRGBA;29 import com.jme3.math.FastMath;30 import com.jme3.math.Quaternion;31 import com.jme3.math.Vector3f;32 import com.jme3.scene.Geometry;33 import com.jme3.scene.Node;34 import com.jme3.scene.shape.Box;35 import com.jme3.scene.shape.Sphere;36 import com.jme3.system.AppSettings;39 /**40 *41 * Demonstrates advanced use of the audio capture and recording features.42 * Multiple perspectives of the same scene are simultaneously rendered to43 * different sound files.44 *45 * A key limitation of the way multiple listeners are implemented is that46 * only 3D positioning effects are realized for listeners other than the47 * main LWJGL listener. This means that audio effects such as environment48 * settings will *not* be heard on any auxiliary listeners, though sound49 * attenuation will work correctly.50 *51 * Multiple listeners as realized here might be used to make AI entities52 * that can each hear the world from their own perspective.53 *54 * @author Robert McIntyre55 *56 */58 public class Advanced extends SimpleApplication {61 private Geometry bell;62 private Geometry ear1;63 private Geometry ear2;64 private Geometry ear3;65 private AudioNode music;66 private MotionTrack motionControl;68 public static void main(String[] args) {69 Logger.getLogger("com.jme3").setLevel(Level.OFF);70 Advanced app = new Advanced();71 AppSettings settings = new AppSettings(true);72 settings.setAudioRenderer("Send");73 app.setSettings(settings);74 app.setShowSettings(false);75 app.setPauseOnLostFocus(false);77 try {78 Capture.captureVideo(app, File.createTempFile("advanced",".avi"));79 Capture.captureAudio(app, File.createTempFile("advanced", ".wav"));80 }81 catch (IOException e) {e.printStackTrace();}82 app.start();83 }85 private Geometry makeEar(Node root, Vector3f position){86 Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");87 Geometry ear = new Geometry("ear", new Box(1.0f, 1.0f, 1.0f));88 ear.setLocalTranslation(position);89 mat.setColor("Color", ColorRGBA.Green);90 ear.setMaterial(mat);91 root.attachChild(ear);92 return ear;93 }95 private Vector3f[] path = new Vector3f[]{96 // loop 197 new Vector3f(0, 0, 0),98 new Vector3f(0, 0, -10),99 new Vector3f(-2, 0, -14),100 new Vector3f(-6, 0, -20),101 new Vector3f(0, 0, -26),102 new Vector3f(6, 0, -20),103 new Vector3f(0, 0, -14),104 new Vector3f(-6, 0, -20),105 new Vector3f(0, 0, -26),106 new Vector3f(6, 0, -20),107 // loop 2108 new Vector3f(5, 0, -5),109 new Vector3f(7, 0, 1.5f),110 new Vector3f(14, 0, 2),111 new Vector3f(20, 0, 6),112 new Vector3f(26, 0, 0),113 new Vector3f(20, 0, -6),114 new Vector3f(14, 0, 0),115 new Vector3f(20, 0, 6),116 new Vector3f(26, 0, 0),117 new Vector3f(20, 0, -6),118 new Vector3f(14, 0, 0),119 // loop 3120 new Vector3f(8, 0, 7.5f),121 new Vector3f(7, 0, 10.5f),122 new Vector3f(6, 0, 20),123 new Vector3f(0, 0, 26),124 new Vector3f(-6, 0, 20),125 new Vector3f(0, 0, 14),126 new Vector3f(6, 0, 20),127 new Vector3f(0, 0, 26),128 new Vector3f(-6, 0, 20),129 new Vector3f(0, 0, 14),130 // begin ellipse131 new Vector3f(16, 5, 20),132 new Vector3f(0, 0, 26),133 new Vector3f(-16, -10, 20),134 new Vector3f(0, 0, 14),135 new Vector3f(16, 20, 20),136 new Vector3f(0, 0, 26),137 new Vector3f(-10, -25, 10),138 new Vector3f(-10, 0, 0),139 // come at me!140 new Vector3f(-28.00242f, 48.005623f, -34.648228f),141 new Vector3f(0, 0 , -20),142 };144 private void createScene() {145 Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");146 bell = new Geometry( "sound-emitter" , new Sphere(15,15,1));147 mat.setColor("Color", ColorRGBA.Blue);148 bell.setMaterial(mat);149 rootNode.attachChild(bell);151 ear1 = makeEar(rootNode, new Vector3f(0, 0 ,-20));152 ear2 = makeEar(rootNode, new Vector3f(0, 0 ,20));153 ear3 = makeEar(rootNode, new Vector3f(20, 0 ,0));155 MotionPath track = new MotionPath();157 for (Vector3f v : path){158 track.addWayPoint(v);159 }160 track.setCurveTension(0.80f);162 motionControl = new MotionTrack(bell,track);164 // for now, use reflection to change the timer...165 //motionControl.setTimer(new IsoTimer(60));166 try {167 Field timerField;168 timerField = AbstractCinematicEvent.class.getDeclaredField("timer");169 timerField.setAccessible(true);170 try {timerField.set(motionControl, new IsoTimer(60));}171 catch (IllegalArgumentException e) {e.printStackTrace();}172 catch (IllegalAccessException e) {e.printStackTrace();}173 }174 catch (SecurityException e) {e.printStackTrace();}175 catch (NoSuchFieldException e) {e.printStackTrace();}177 motionControl.setDirectionType(MotionTrack.Direction.PathAndRotation);178 motionControl.setRotation(new Quaternion().fromAngleNormalAxis(-FastMath.HALF_PI, Vector3f.UNIT_Y));179 motionControl.setInitialDuration(20f);180 motionControl.setSpeed(1f);182 track.enableDebugShape(assetManager, rootNode);183 positionCamera();184 }187 private void positionCamera(){188 this.cam.setLocation(new Vector3f(-28.00242f, 48.005623f, -34.648228f));189 this.cam.setRotation(new Quaternion(0.3359635f, 0.34280345f, -0.13281013f, 0.8671653f));190 }192 private void initAudio() {193 org.lwjgl.input.Mouse.setGrabbed(false);194 music = new AudioNode(assetManager, "Sound/Effects/Beep.ogg", false);196 rootNode.attachChild(music);197 audioRenderer.playSource(music);198 music.setPositional(true);199 music.setVolume(1f);200 music.setReverbEnabled(false);201 music.setDirectional(false);202 music.setMaxDistance(200.0f);203 music.setRefDistance(1f);204 music.setRolloffFactor(1f);205 music.setLooping(false);206 audioRenderer.pauseSource(music);207 }214 public class Dancer implements SoundProcessor {215 Geometry entity;216 float scale = 2;217 public Dancer(Geometry entity){218 this.entity = entity;219 }221 /**222 * this method is irrelevant since there is no state to cleanup.223 */224 public void cleanup() {}227 /**228 * Respond to sound! This is the brain of an AI entity that229 * hears it's surroundings and reacts to them.230 */231 public void process(ByteBuffer audioSamples, int numSamples, AudioFormat format) {232 audioSamples.clear();233 byte[] data = new byte[numSamples];234 float[] out = new float[numSamples];235 audioSamples.get(data);236 FloatSampleTools.byte2floatInterleaved(data, 0, out, 0,237 numSamples/format.getFrameSize(), format);239 float max = Float.NEGATIVE_INFINITY;240 for (float f : out){if (f > max) max = f;}241 audioSamples.clear();243 if (max > 0.1){entity.getMaterial().setColor("Color", ColorRGBA.Green);}244 else {entity.getMaterial().setColor("Color", ColorRGBA.Gray);}245 }246 }248 private void prepareEar(Geometry ear, int n){249 if (this.audioRenderer instanceof MultiListener){250 MultiListener rf = (MultiListener)this.audioRenderer;252 Listener auxListener = new Listener();253 auxListener.setLocation(ear.getLocalTranslation());255 rf.addListener(auxListener);256 WaveFileWriter aux = null;258 try {aux = new WaveFileWriter(new File("/home/r/tmp/ear"+n+".wav"));}259 catch (FileNotFoundException e) {e.printStackTrace();}261 rf.registerSoundProcessor(auxListener,262 new CompositeSoundProcessor(new Dancer(ear), aux));264 }265 }268 public void simpleInitApp() {269 this.setTimer(new IsoTimer(60));270 initAudio();272 createScene();274 prepareEar(ear1, 1);275 prepareEar(ear2, 1);276 prepareEar(ear3, 1);278 motionControl.play();279 }281 public void simpleUpdate(float tpf) {282 if (music.getStatus() != AudioNode.Status.Playing){283 music.play();284 }285 Vector3f loc = cam.getLocation();286 Quaternion rot = cam.getRotation();287 listener.setLocation(loc);288 listener.setRotation(rot);289 music.setLocalTranslation(bell.getLocalTranslation());290 }292 }