# HG changeset patch # User Robert McIntyre # Date 1322961927 21600 # Node ID afc437f637bd121dd2f8ff8e41f2c4c7d0a538b0 # Parent b05f629fc29658e7e24a01b4bef6ee549c8cd4b6 improved formating diff -r b05f629fc296 -r afc437f637bd src/com/aurellem/capture/Capture.java --- a/src/com/aurellem/capture/Capture.java Sat Dec 03 19:18:38 2011 -0600 +++ b/src/com/aurellem/capture/Capture.java Sat Dec 03 19:25:27 2011 -0600 @@ -18,122 +18,135 @@ import com.jme3.system.JmeSystem; /** - * Use the methods in this class for capturing consistent, high quality video and audio from a - * jMonkeyEngine3 application. To capture audio or video do the following: + * Use the methods in this class for capturing consistent, high quality video + * and audio from a jMonkeyEngine3 application. To capture audio or video do + * the following: * - * 1.) Set your application's timer to an IsoTimer. Create the IsoTimer with the desired video - * frames-per-second. - * 2.) Call captureAudio and/or captureVideo on the Application as desired before starting the Application. + * 1.) Set your application's timer to an IsoTimer. Create the IsoTimer with the + * desired video frames-per-second. + * + * 2.) Call captureAudio and/or captureVideo on the Application as desired + * before starting the Application. * - * See the Basic and Advanced demos in the examples section for more information. If you have any trouble, - * please PM me on the jMonkeyEngine forums. My username is bortreb. + * See the Basic and Advanced demos in the examples section for more + * information. If you have any trouble, please PM me on the jMonkeyEngine + * forums. My username is bortreb. * * @author Robert McIntyre */ public class Capture { - /** - * Use this function to capture video from your application. You specify the framerate at which - * the video will be recording by setting the Application's timer to an IsoTimer created with the - * desired frames-per-second. - * - * There are three ways to record and they are selected by the properties of the file that you - * specify. - * - * 1.) (Preferred) - * If you supply an empty directory as the file, then the video will - * be saved as a sequence of .png files, one file per frame. The files start at - * 0000000.png and increment from there. You can then combine the frames into your - * preferred container/codec. If the directory is not empty, then writing video frames - * to it will fail, and nothing will be written. - * - * 2.) If the filename ends in ".avi" then the frames will be encoded as a RAW stream - * inside an AVI 1.0 container. The resulting file will be quite large and you will - * probably want to re-encode it to your preferred container/codec format. Be advised - * that some video payers cannot process AVI with a RAW stream, and that AVI 1.0 files - * generated by this method that exceed 2.0GB are invalid according to the AVI 1.0 spec - * (but many programs can still deal with them.) Thanks to Werner Randelshofer for his - * excellent work which made AVI file writer option possible. - * - * 3.) Any non-directory file ending in anything other than ".avi" will be processed through - * Xuggle. Xuggle provides the option to use many codecs/containers, but you will have to - * install it on your system yourself in order to use this option. Please visit - * http://www.xuggle.com/ to learn how to do this. - * - * @param app The Application from which you wish to record Video. - * @param file The file to which the video will be captured. - * @throws IOException - */ + /** + * Use this function to capture video from your application. You + * specify the framerate at which the video will be recording by setting + * the Application's timer to an IsoTimer created with the desired + * frames-per-second. + * + * There are three ways to record and they are selected by the + * properties of the file that you specify. + * + * 1.) (Preferred) If you supply an empty directory as the file, then + * the video will be saved as a sequence of .png files, one file per + * frame. The files start at 0000000.png and increment from there. + * You can then combine the frames into your preferred + * container/codec. If the directory is not empty, then writing + * video frames to it will fail, and nothing will be written. + * + * 2.) If the filename ends in ".avi" then the frames will be encoded as + * a RAW stream inside an AVI 1.0 container. The resulting file + * will be quite large and you will probably want to re-encode it to + * your preferred container/codec format. Be advised that some + * video payers cannot process AVI with a RAW stream, and that AVI + * 1.0 files generated by this method that exceed 2.0GB are invalid + * according to the AVI 1.0 spec (but many programs can still deal + * with them.) Thanks to Werner Randelshofer for his excellent work + * which made AVI file writer option possible. + * + * 3.) Any non-directory file ending in anything other than ".avi" will + * be processed through Xuggle. Xuggle provides the option to use + * many codecs/containers, but you will have to install it on your + * system yourself in order to use this option. Please visit + * http://www.xuggle.com/ to learn how to do this. + * + * @param app The Application from which you wish to record Video. + * @param file The file to which the video will be captured. + * @throws IOException + */ - public static void captureVideo(final Application app, final File file) throws IOException{ - final AbstractVideoRecorder videoRecorder; + public static void captureVideo(final Application app, final File file) throws IOException{ + final AbstractVideoRecorder videoRecorder; - if (file.getCanonicalPath().endsWith(".avi")){ - videoRecorder = new AVIVideoRecorder(file);} - else if (file.isDirectory()){ - videoRecorder = new FileVideoRecorder(file);} - else { videoRecorder = new XuggleVideoRecorder(file);} + if (file.getCanonicalPath().endsWith(".avi")){ + videoRecorder = new AVIVideoRecorder(file);} + else if (file.isDirectory()){ + videoRecorder = new FileVideoRecorder(file);} + else { videoRecorder = new XuggleVideoRecorder(file);} - Callable thunk = new Callable(){ - public Object call(){ + Callable thunk = new Callable(){ + public Object call(){ - ViewPort viewPort = - app.getRenderManager() - .createPostView("aurellem video record", app.getCamera()); + ViewPort viewPort = + app.getRenderManager() + .createPostView("aurellem video record", app.getCamera()); - viewPort.setClearFlags(false, false, false); + viewPort.setClearFlags(false, false, false); - // get GUI node stuff - for (Spatial s : app.getGuiViewPort().getScenes()){ - viewPort.attachScene(s); - } + // get GUI node stuff + for (Spatial s : app.getGuiViewPort().getScenes()){ + viewPort.attachScene(s); + } - app.getStateManager().attach(videoRecorder); - viewPort.addProcessor(videoRecorder); - return null; - } - }; - app.enqueue(thunk); - } + app.getStateManager().attach(videoRecorder); + viewPort.addProcessor(videoRecorder); + return null; + } + }; + app.enqueue(thunk); + } - /** - * Use this function to capture audio from your application. Audio data will be saved in linear - * PCM format at 44,100 hertz in the wav container format to the file that you specify. - * - * Note that you *have* to use an IsoTimer for your Application's timer while recording audio or - * the recording will fail. Also ensure that your IsoTimer obeys the following constraints: - * - * - The frames-per-second value of the IsoTimer cannot be lower than 10 frames-per-second. - * - The frames-per-second value of the IsoTimer must evenly divide 44,100. - * - * @param app The Application from which you wish to record Audio. - * @param file the target file to which you want to record audio data. - * @throws IOException - */ + /** + * Use this function to capture audio from your application. Audio data + * will be saved in linear PCM format at 44,100 hertz in the wav container + * format to the file that you specify. + * + * Note that you *have* to use an IsoTimer for your Application's timer + * while recording audio or the recording will fail. Also ensure that your + * IsoTimer obeys the following constraints: + * + * 1.) The frames-per-second value of the IsoTimer cannot be lower than 10 + * frames-per-second. + * + * 2.) The frames-per-second value of the IsoTimer must evenly divide + * 44,100. + * + * @param app The Application from which you wish to record Audio. + * @param file the target file to which you want to record audio data. + * @throws IOException + */ - public static void captureAudio(final Application app, final File file) throws IOException{ - AppSettings settings = null; - if (app.getContext() != null){settings = app.getContext().getSettings();} - if (settings == null){settings = new AppSettings(true);} - settings.setAudioRenderer("Send"); - app.setSettings(settings); + public static void captureAudio(final Application app, final File file) throws IOException{ + AppSettings settings = null; + if (app.getContext() != null){settings = app.getContext().getSettings();} + if (settings == null){settings = new AppSettings(true);} + settings.setAudioRenderer("Send"); + app.setSettings(settings); - JmeSystem.setSystemDelegate(new AurellemSystemDelegate()); + JmeSystem.setSystemDelegate(new AurellemSystemDelegate()); - final WaveFileWriter writer = new WaveFileWriter(file); + final WaveFileWriter writer = new WaveFileWriter(file); - Callable thunk = new Callable(){ - public Object call(){ - AudioRenderer ar = app.getAudioRenderer(); - if (ar instanceof MultiListener){ - MultiListener ml = (MultiListener)ar; - ml.registerSoundProcessor(writer); - } - return null; - } - }; - app.enqueue(thunk); - } + Callable thunk = new Callable(){ + public Object call(){ + AudioRenderer ar = app.getAudioRenderer(); + if (ar instanceof MultiListener){ + MultiListener ml = (MultiListener)ar; + ml.registerSoundProcessor(writer); + } + return null; + } + }; + app.enqueue(thunk); + } } diff -r b05f629fc296 -r afc437f637bd src/com/aurellem/capture/IsoTimer.java --- a/src/com/aurellem/capture/IsoTimer.java Sat Dec 03 19:18:38 2011 -0600 +++ b/src/com/aurellem/capture/IsoTimer.java Sat Dec 03 19:25:27 2011 -0600 @@ -12,9 +12,9 @@ * throttles its physics engine and graphics display. If the * computations involved in running the game are too intense, then the * game will first skip frames, then sacrifice physics accuracy. If - * there are particularly demanding computations, then you may only get - * 1 fps, and the ball may tunnel through the floor or obstacles due - * to inaccurate physics simulation, but after the end of one + * there are particularly demanding computations, then you may only + * get 1 fps, and the ball may tunnel through the floor or obstacles + * due to inaccurate physics simulation, but after the end of one * user-hour, that ball will have traveled one game-mile. * * When we're recording video or audio, we don't care if the game-time @@ -36,32 +36,32 @@ public class IsoTimer extends Timer { - private float framerate; - private int ticks; + private float framerate; + private int ticks; - public IsoTimer(float framerate){ - this.framerate = framerate; - this.ticks = 0; - } + public IsoTimer(float framerate){ + this.framerate = framerate; + this.ticks = 0; + } - public long getTime() { - return (long) (this.ticks / this.framerate); - } + public long getTime() { + return (long) (this.ticks / this.framerate); + } - public long getResolution() { - return 1000000000L; - } + public long getResolution() { + return 1000000000L; + } - public float getFrameRate() { - return this.framerate; - } + public float getFrameRate() { + return this.framerate; + } - public float getTimePerFrame() { - return (float) (1.0f / this.framerate); - } + public float getTimePerFrame() { + return (float) (1.0f / this.framerate); + } - public void update() {this.ticks++;} + public void update() {this.ticks++;} - public void reset() {this.ticks = 0;} + public void reset() {this.ticks = 0;} } diff -r b05f629fc296 -r afc437f637bd src/com/aurellem/capture/examples/Advanced.java --- a/src/com/aurellem/capture/examples/Advanced.java Sat Dec 03 19:18:38 2011 -0600 +++ b/src/com/aurellem/capture/examples/Advanced.java Sat Dec 03 19:25:27 2011 -0600 @@ -37,266 +37,266 @@ /** * - * Demonstrates advanced use of the audio capture and recording features. - * Multiple perspectives of the same scene are simultaneously rendered to - * different sound files. + * Demonstrates advanced use of the audio capture and recording + * features. Multiple perspectives of the same scene are + * simultaneously rendered to different sound files. * - * A key limitation of the way multiple listeners are implemented is that - * only 3D positioning effects are realized for listeners other than the - * main LWJGL listener. This means that audio effects such as environment - * settings will *not* be heard on any auxiliary listeners, though sound - * attenuation will work correctly. + * A key limitation of the way multiple listeners are implemented is + * that only 3D positioning effects are realized for listeners other + * than the main LWJGL listener. This means that audio effects such + * as environment settings will *not* be heard on any auxiliary + * listeners, though sound attenuation will work correctly. * - * Multiple listeners as realized here might be used to make AI entities - * that can each hear the world from their own perspective. + * Multiple listeners as realized here might be used to make AI + * entities that can each hear the world from their own perspective. * * @author Robert McIntyre */ public class Advanced extends SimpleApplication { - /** - * You will see three grey cubes, a blue sphere, and a path - * which circles each cube. The blue sphere is generating a - * constant monotone sound as it moves along the track. Each - * cube is listening for sound; when a cube hears sound whose - * intensity is greater than a certain threshold, it changes - * its color from grey to green. - * - * Each cube is also saving whatever it hears to a file. The - * scene from the perspective of the viewer is also saved to - * a video file. When you listen to each of the sound files - * alongside the video, the sound will get louder when the - * sphere approaches the cube that generated that sound file. - * This shows that each listener is hearing the world from - * its own perspective. - * - */ - public static void main(String[] args) { - Advanced app = new Advanced(); - AppSettings settings = new AppSettings(true); - settings.setAudioRenderer(AurellemSystemDelegate.SEND); - JmeSystem.setSystemDelegate(new AurellemSystemDelegate()); - app.setSettings(settings); - app.setShowSettings(false); - app.setPauseOnLostFocus(false); + /** + * You will see three grey cubes, a blue sphere, and a path which + * circles each cube. The blue sphere is generating a constant + * monotone sound as it moves along the track. Each cube is + * listening for sound; when a cube hears sound whose intensity is + * greater than a certain threshold, it changes its color from + * grey to green. + * + * Each cube is also saving whatever it hears to a file. The + * scene from the perspective of the viewer is also saved to a + * video file. When you listen to each of the sound files + * alongside the video, the sound will get louder when the sphere + * approaches the cube that generated that sound file. This + * shows that each listener is hearing the world from its own + * perspective. + * + */ + public static void main(String[] args) { + Advanced app = new Advanced(); + AppSettings settings = new AppSettings(true); + settings.setAudioRenderer(AurellemSystemDelegate.SEND); + JmeSystem.setSystemDelegate(new AurellemSystemDelegate()); + app.setSettings(settings); + app.setShowSettings(false); + app.setPauseOnLostFocus(false); - try { - Capture.captureVideo(app, File.createTempFile("advanced",".avi")); - Capture.captureAudio(app, File.createTempFile("advanced", ".wav")); - } - catch (IOException e) {e.printStackTrace();} + try { + Capture.captureVideo(app, File.createTempFile("advanced",".avi")); + Capture.captureAudio(app, File.createTempFile("advanced", ".wav")); + } + catch (IOException e) {e.printStackTrace();} - app.start(); + app.start(); + } + + + private Geometry bell; + private Geometry ear1; + private Geometry ear2; + private Geometry ear3; + private AudioNode music; + private MotionTrack motionControl; + + private Geometry makeEar(Node root, Vector3f position){ + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + Geometry ear = new Geometry("ear", new Box(1.0f, 1.0f, 1.0f)); + ear.setLocalTranslation(position); + mat.setColor("Color", ColorRGBA.Green); + ear.setMaterial(mat); + root.attachChild(ear); + return ear; + } + + private Vector3f[] path = new Vector3f[]{ + // loop 1 + new Vector3f(0, 0, 0), + new Vector3f(0, 0, -10), + new Vector3f(-2, 0, -14), + new Vector3f(-6, 0, -20), + new Vector3f(0, 0, -26), + new Vector3f(6, 0, -20), + new Vector3f(0, 0, -14), + new Vector3f(-6, 0, -20), + new Vector3f(0, 0, -26), + new Vector3f(6, 0, -20), + // loop 2 + new Vector3f(5, 0, -5), + new Vector3f(7, 0, 1.5f), + new Vector3f(14, 0, 2), + new Vector3f(20, 0, 6), + new Vector3f(26, 0, 0), + new Vector3f(20, 0, -6), + new Vector3f(14, 0, 0), + new Vector3f(20, 0, 6), + new Vector3f(26, 0, 0), + new Vector3f(20, 0, -6), + new Vector3f(14, 0, 0), + // loop 3 + new Vector3f(8, 0, 7.5f), + new Vector3f(7, 0, 10.5f), + new Vector3f(6, 0, 20), + new Vector3f(0, 0, 26), + new Vector3f(-6, 0, 20), + new Vector3f(0, 0, 14), + new Vector3f(6, 0, 20), + new Vector3f(0, 0, 26), + new Vector3f(-6, 0, 20), + new Vector3f(0, 0, 14), + // begin ellipse + new Vector3f(16, 5, 20), + new Vector3f(0, 0, 26), + new Vector3f(-16, -10, 20), + new Vector3f(0, 0, 14), + new Vector3f(16, 20, 20), + new Vector3f(0, 0, 26), + new Vector3f(-10, -25, 10), + new Vector3f(-10, 0, 0), + // come at me! + new Vector3f(-28.00242f, 48.005623f, -34.648228f), + new Vector3f(0, 0 , -20), + }; + + private void createScene() { + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + bell = new Geometry( "sound-emitter" , new Sphere(15,15,1)); + mat.setColor("Color", ColorRGBA.Blue); + bell.setMaterial(mat); + rootNode.attachChild(bell); + + ear1 = makeEar(rootNode, new Vector3f(0, 0 ,-20)); + ear2 = makeEar(rootNode, new Vector3f(0, 0 ,20)); + ear3 = makeEar(rootNode, new Vector3f(20, 0 ,0)); + + MotionPath track = new MotionPath(); + + for (Vector3f v : path){ + track.addWayPoint(v); + } + track.setCurveTension(0.80f); + + motionControl = new MotionTrack(bell,track); + + // for now, use reflection to change the timer... + // motionControl.setTimer(new IsoTimer(60)); + try { + Field timerField; + timerField = AbstractCinematicEvent.class.getDeclaredField("timer"); + timerField.setAccessible(true); + try {timerField.set(motionControl, new IsoTimer(60));} + catch (IllegalArgumentException e) {e.printStackTrace();} + catch (IllegalAccessException e) {e.printStackTrace();} + } + catch (SecurityException e) {e.printStackTrace();} + catch (NoSuchFieldException e) {e.printStackTrace();} + + motionControl.setDirectionType(MotionTrack.Direction.PathAndRotation); + motionControl.setRotation(new Quaternion().fromAngleNormalAxis(-FastMath.HALF_PI, Vector3f.UNIT_Y)); + motionControl.setInitialDuration(20f); + motionControl.setSpeed(1f); + + track.enableDebugShape(assetManager, rootNode); + positionCamera(); + } + + + private void positionCamera(){ + this.cam.setLocation(new Vector3f(-28.00242f, 48.005623f, -34.648228f)); + this.cam.setRotation(new Quaternion(0.3359635f, 0.34280345f, -0.13281013f, 0.8671653f)); + } + + private void initAudio() { + org.lwjgl.input.Mouse.setGrabbed(false); + music = new AudioNode(assetManager, "Sound/Effects/Beep.ogg", false); + + rootNode.attachChild(music); + audioRenderer.playSource(music); + music.setPositional(true); + music.setVolume(1f); + music.setReverbEnabled(false); + music.setDirectional(false); + music.setMaxDistance(200.0f); + music.setRefDistance(1f); + //music.setRolloffFactor(1f); + music.setLooping(false); + audioRenderer.pauseSource(music); + } + + public class Dancer implements SoundProcessor { + Geometry entity; + float scale = 2; + public Dancer(Geometry entity){ + this.entity = entity; } - - private Geometry bell; - private Geometry ear1; - private Geometry ear2; - private Geometry ear3; - private AudioNode music; - private MotionTrack motionControl; + /** + * this method is irrelevant since there is no state to cleanup. + */ + public void cleanup() {} + + + /** + * Respond to sound! This is the brain of an AI entity that + * hears it's surroundings and reacts to them. + */ + public void process(ByteBuffer audioSamples, int numSamples, AudioFormat format) { + audioSamples.clear(); + byte[] data = new byte[numSamples]; + float[] out = new float[numSamples]; + audioSamples.get(data); + FloatSampleTools.byte2floatInterleaved(data, 0, out, 0, + numSamples/format.getFrameSize(), format); + + float max = Float.NEGATIVE_INFINITY; + for (float f : out){if (f > max) max = f;} + audioSamples.clear(); + + if (max > 0.1){entity.getMaterial().setColor("Color", ColorRGBA.Green);} + else {entity.getMaterial().setColor("Color", ColorRGBA.Gray);} + } + } + + private void prepareEar(Geometry ear, int n){ + if (this.audioRenderer instanceof MultiListener){ + MultiListener rf = (MultiListener)this.audioRenderer; + + Listener auxListener = new Listener(); + auxListener.setLocation(ear.getLocalTranslation()); + + rf.addListener(auxListener); + WaveFileWriter aux = null; + + try {aux = new WaveFileWriter(new File("/home/r/tmp/ear"+n+".wav"));} + catch (FileNotFoundException e) {e.printStackTrace();} + + rf.registerSoundProcessor(auxListener, + new CompositeSoundProcessor(new Dancer(ear), aux)); + } + } + + + public void simpleInitApp() { + this.setTimer(new IsoTimer(60)); + initAudio(); - private Geometry makeEar(Node root, Vector3f position){ - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - Geometry ear = new Geometry("ear", new Box(1.0f, 1.0f, 1.0f)); - ear.setLocalTranslation(position); - mat.setColor("Color", ColorRGBA.Green); - ear.setMaterial(mat); - root.attachChild(ear); - return ear; - } + createScene(); - private Vector3f[] path = new Vector3f[]{ - // loop 1 - new Vector3f(0, 0, 0), - new Vector3f(0, 0, -10), - new Vector3f(-2, 0, -14), - new Vector3f(-6, 0, -20), - new Vector3f(0, 0, -26), - new Vector3f(6, 0, -20), - new Vector3f(0, 0, -14), - new Vector3f(-6, 0, -20), - new Vector3f(0, 0, -26), - new Vector3f(6, 0, -20), - // loop 2 - new Vector3f(5, 0, -5), - new Vector3f(7, 0, 1.5f), - new Vector3f(14, 0, 2), - new Vector3f(20, 0, 6), - new Vector3f(26, 0, 0), - new Vector3f(20, 0, -6), - new Vector3f(14, 0, 0), - new Vector3f(20, 0, 6), - new Vector3f(26, 0, 0), - new Vector3f(20, 0, -6), - new Vector3f(14, 0, 0), - // loop 3 - new Vector3f(8, 0, 7.5f), - new Vector3f(7, 0, 10.5f), - new Vector3f(6, 0, 20), - new Vector3f(0, 0, 26), - new Vector3f(-6, 0, 20), - new Vector3f(0, 0, 14), - new Vector3f(6, 0, 20), - new Vector3f(0, 0, 26), - new Vector3f(-6, 0, 20), - new Vector3f(0, 0, 14), - // begin ellipse - new Vector3f(16, 5, 20), - new Vector3f(0, 0, 26), - new Vector3f(-16, -10, 20), - new Vector3f(0, 0, 14), - new Vector3f(16, 20, 20), - new Vector3f(0, 0, 26), - new Vector3f(-10, -25, 10), - new Vector3f(-10, 0, 0), - // come at me! - new Vector3f(-28.00242f, 48.005623f, -34.648228f), - new Vector3f(0, 0 , -20), - }; + prepareEar(ear1, 1); + prepareEar(ear2, 1); + prepareEar(ear3, 1); - private void createScene() { - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - bell = new Geometry( "sound-emitter" , new Sphere(15,15,1)); - mat.setColor("Color", ColorRGBA.Blue); - bell.setMaterial(mat); - rootNode.attachChild(bell); + motionControl.play(); + } - ear1 = makeEar(rootNode, new Vector3f(0, 0 ,-20)); - ear2 = makeEar(rootNode, new Vector3f(0, 0 ,20)); - ear3 = makeEar(rootNode, new Vector3f(20, 0 ,0)); - - MotionPath track = new MotionPath(); - - for (Vector3f v : path){ - track.addWayPoint(v); - } - track.setCurveTension(0.80f); - - motionControl = new MotionTrack(bell,track); - - // for now, use reflection to change the timer... - // motionControl.setTimer(new IsoTimer(60)); - try { - Field timerField; - timerField = AbstractCinematicEvent.class.getDeclaredField("timer"); - timerField.setAccessible(true); - try {timerField.set(motionControl, new IsoTimer(60));} - catch (IllegalArgumentException e) {e.printStackTrace();} - catch (IllegalAccessException e) {e.printStackTrace();} - } - catch (SecurityException e) {e.printStackTrace();} - catch (NoSuchFieldException e) {e.printStackTrace();} - - motionControl.setDirectionType(MotionTrack.Direction.PathAndRotation); - motionControl.setRotation(new Quaternion().fromAngleNormalAxis(-FastMath.HALF_PI, Vector3f.UNIT_Y)); - motionControl.setInitialDuration(20f); - motionControl.setSpeed(1f); - - track.enableDebugShape(assetManager, rootNode); - positionCamera(); + public void simpleUpdate(float tpf) { + if (music.getStatus() != AudioNode.Status.Playing){ + music.play(); } - - - private void positionCamera(){ - this.cam.setLocation(new Vector3f(-28.00242f, 48.005623f, -34.648228f)); - this.cam.setRotation(new Quaternion(0.3359635f, 0.34280345f, -0.13281013f, 0.8671653f)); - } - - private void initAudio() { - org.lwjgl.input.Mouse.setGrabbed(false); - music = new AudioNode(assetManager, "Sound/Effects/Beep.ogg", false); - - rootNode.attachChild(music); - audioRenderer.playSource(music); - music.setPositional(true); - music.setVolume(1f); - music.setReverbEnabled(false); - music.setDirectional(false); - music.setMaxDistance(200.0f); - music.setRefDistance(1f); - //music.setRolloffFactor(1f); - music.setLooping(false); - audioRenderer.pauseSource(music); - } - - public class Dancer implements SoundProcessor { - Geometry entity; - float scale = 2; - public Dancer(Geometry entity){ - this.entity = entity; - } - - /** - * this method is irrelevant since there is no state to cleanup. - */ - public void cleanup() {} - - - /** - * Respond to sound! This is the brain of an AI entity that - * hears it's surroundings and reacts to them. - */ - public void process(ByteBuffer audioSamples, int numSamples, AudioFormat format) { - audioSamples.clear(); - byte[] data = new byte[numSamples]; - float[] out = new float[numSamples]; - audioSamples.get(data); - FloatSampleTools.byte2floatInterleaved(data, 0, out, 0, - numSamples/format.getFrameSize(), format); - - float max = Float.NEGATIVE_INFINITY; - for (float f : out){if (f > max) max = f;} - audioSamples.clear(); - - if (max > 0.1){entity.getMaterial().setColor("Color", ColorRGBA.Green);} - else {entity.getMaterial().setColor("Color", ColorRGBA.Gray);} - } - } - - private void prepareEar(Geometry ear, int n){ - if (this.audioRenderer instanceof MultiListener){ - MultiListener rf = (MultiListener)this.audioRenderer; - - Listener auxListener = new Listener(); - auxListener.setLocation(ear.getLocalTranslation()); - - rf.addListener(auxListener); - WaveFileWriter aux = null; - - try {aux = new WaveFileWriter(new File("/home/r/tmp/ear"+n+".wav"));} - catch (FileNotFoundException e) {e.printStackTrace();} - - rf.registerSoundProcessor(auxListener, - new CompositeSoundProcessor(new Dancer(ear), aux)); - } - } - - - public void simpleInitApp() { - this.setTimer(new IsoTimer(60)); - initAudio(); - - createScene(); - - prepareEar(ear1, 1); - prepareEar(ear2, 1); - prepareEar(ear3, 1); - - motionControl.play(); - } - - public void simpleUpdate(float tpf) { - if (music.getStatus() != AudioNode.Status.Playing){ - music.play(); - } - Vector3f loc = cam.getLocation(); - Quaternion rot = cam.getRotation(); - listener.setLocation(loc); - listener.setRotation(rot); - music.setLocalTranslation(bell.getLocalTranslation()); - } + Vector3f loc = cam.getLocation(); + Quaternion rot = cam.getRotation(); + listener.setLocation(loc); + listener.setRotation(rot); + music.setLocalTranslation(bell.getLocalTranslation()); + } } diff -r b05f629fc296 -r afc437f637bd src/com/aurellem/capture/examples/Basic.java --- a/src/com/aurellem/capture/examples/Basic.java Sat Dec 03 19:18:38 2011 -0600 +++ b/src/com/aurellem/capture/examples/Basic.java Sat Dec 03 19:25:27 2011 -0600 @@ -11,30 +11,29 @@ /** - * - * Demonstrates how to use basic Audio/Video capture with a jMonkeyEngine - * application. You can use these techniques to make high quality cutscenes - * or demo videos, even on very slow laptops. + * Demonstrates how to use basic Audio/Video capture with a + * jMonkeyEngine application. You can use these techniques to make + * high quality cutscenes or demo videos, even on very slow laptops. * * @author Robert McIntyre */ public class Basic { - public static void main(String[] ignore) throws IOException{ - File video = File.createTempFile("JME-water-video", ".avi"); - File audio = File.createTempFile("JME-water-audio", ".wav"); + public static void main(String[] ignore) throws IOException{ + File video = File.createTempFile("JME-water-video", ".avi"); + File audio = File.createTempFile("JME-water-audio", ".wav"); - SimpleApplication app = new TestPostWater(); - app.setTimer(new IsoTimer(60)); - app.setShowSettings(false); + SimpleApplication app = new TestPostWater(); + app.setTimer(new IsoTimer(60)); + app.setShowSettings(false); - Capture.captureVideo(app, video); - Capture.captureAudio(app, audio); + Capture.captureVideo(app, video); + Capture.captureAudio(app, audio); - app.start(); + app.start(); - System.out.println(video.getCanonicalPath()); - System.out.println(audio.getCanonicalPath()); - } + System.out.println(video.getCanonicalPath()); + System.out.println(audio.getCanonicalPath()); + } } diff -r b05f629fc296 -r afc437f637bd src/com/aurellem/capture/examples/HelloAudioRecording.java --- a/src/com/aurellem/capture/examples/HelloAudioRecording.java Sat Dec 03 19:18:38 2011 -0600 +++ b/src/com/aurellem/capture/examples/HelloAudioRecording.java Sat Dec 03 19:25:27 2011 -0600 @@ -9,12 +9,12 @@ import com.aurellem.capture.IsoTimer; import com.jme3.app.Application; -/** Recording audio from your Application is simple. If all you - * want to do is record Audio, then follow the following steps. +/** Recording audio from your Application is simple. If all you want + * to do is record Audio, then follow the following steps. * * 1.) Set the Application's timer to an IsoTimer. The framerate is - * irrelevant for sound, but must evenly divide 44,100Hz, which is the - * frequency at which sound will be recorded. For example + * irrelevant for sound, but must evenly divide 44,100Hz, which is + * the frequency at which sound will be recorded. For example * IsoTimer(60) is ok, but IsoTimer(61) is not. * * 2.) Call Capture.captureAudio(yourApplication, target-file) before @@ -27,12 +27,12 @@ */ public class HelloAudioRecording { - public static void main(String[] ignore) throws IOException{ - Application app = new HelloAudio(); - File audio = File.createTempFile("JME-simple-audio", ".wav"); - app.setTimer(new IsoTimer(60)); - Capture.captureAudio(app, audio); - app.start(); - System.out.println(audio.getCanonicalPath()); - } + public static void main(String[] ignore) throws IOException{ + Application app = new HelloAudio(); + File audio = File.createTempFile("JME-simple-audio", ".wav"); + app.setTimer(new IsoTimer(60)); + Capture.captureAudio(app, audio); + app.start(); + System.out.println(audio.getCanonicalPath()); + } } diff -r b05f629fc296 -r afc437f637bd src/com/aurellem/capture/examples/HelloVideoRecording.java --- a/src/com/aurellem/capture/examples/HelloVideoRecording.java Sat Dec 03 19:18:38 2011 -0600 +++ b/src/com/aurellem/capture/examples/HelloVideoRecording.java Sat Dec 03 19:25:27 2011 -0600 @@ -9,8 +9,8 @@ import com.aurellem.capture.IsoTimer; import com.jme3.app.Application; -/** Recording Video from your Application is simple. If all you - * want to do is record Video, then follow the following steps. +/** Recording Video from your Application is simple. If all you want + * to do is record Video, then follow the following steps. * * 1.) Set the Application's timer to an IsoTimer. The framerate of * the IsoTimer will determine the framerate of the resulting video. @@ -27,12 +27,12 @@ */ public class HelloVideoRecording { - public static void main(String[] ignore) throws IOException { - Application app = new HelloLoop(); - File video = File.createTempFile("JME-simple-video", ".avi"); - app.setTimer(new IsoTimer(60)); - Capture.captureVideo(app, video); - app.start(); - System.out.println(video.getCanonicalPath()); - } + public static void main(String[] ignore) throws IOException { + Application app = new HelloLoop(); + File video = File.createTempFile("JME-simple-video", ".avi"); + app.setTimer(new IsoTimer(60)); + Capture.captureVideo(app, video); + app.start(); + System.out.println(video.getCanonicalPath()); + } }