Mercurial > jmeCapture
view src/com/aurellem/capture/examples/AdvancedAudio.java @ 34:13d354e1184b
trying to track down very strange bug where a listener and aux listener at the same location hear different things
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sun, 30 Oct 2011 14:58:01 -0700 |
parents | c4bfbf5d090e |
children | c969b04fa0dc |
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.nio.ByteBuffer;8 import javax.sound.sampled.AudioFormat;10 import org.tritonus.share.sampled.FloatSampleTools;12 import com.aurellem.capture.Capture;13 import com.aurellem.capture.IsoTimer;14 import com.aurellem.capture.audio.CompositeSoundProcessor;15 import com.aurellem.capture.audio.MultiListener;16 import com.aurellem.capture.audio.SoundProcessor;17 import com.aurellem.capture.audio.WaveFileWriter;18 import com.jme3.app.SimpleApplication;19 import com.jme3.audio.AudioNode;20 import com.jme3.audio.AudioParam;21 import com.jme3.audio.Listener;22 import com.jme3.cinematic.MotionPath;23 import com.jme3.cinematic.events.MotionTrack;24 import com.jme3.input.controls.ActionListener;25 import com.jme3.input.controls.MouseButtonTrigger;26 import com.jme3.light.DirectionalLight;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.Spatial;35 import com.jme3.scene.shape.Box;36 import com.jme3.scene.shape.Sphere;37 import com.jme3.system.AppSettings;40 /**41 *42 * Demonstrates advanced use of the audio capture and recording features.43 * Multiple perspectives of the same scene are simultaneously rendered to44 * different sound files.45 *46 * A key limitation of the way multiple listeners are implemented is that47 * only 3D positioning effects are realized for listeners other than the48 * main LWJGL listener. This means that audio effects such as environment49 * settings will *not* be heard on any auxiliary listeners, though sound50 * attenuation will work correctly.51 *52 * Multiple listeners as realized here might be used to make AI entities53 * that can each hear the world from their own perspective.54 *55 * @author Robert McIntyre56 *57 */59 public class AdvancedAudio extends SimpleApplication {61 public static void main(String[] args) {63 AdvancedAudio app = new AdvancedAudio();64 AppSettings settings = new AppSettings(true);65 settings.setAudioRenderer("Send");66 app.setSettings(settings);67 app.setShowSettings(false);68 app.setPauseOnLostFocus(false);69 org.lwjgl.input.Mouse.setGrabbed(false);70 try {Capture.captureVideo(app, new File("/home/r/tmp/out.avi"));}71 catch (IOException e) {e.printStackTrace();}72 app.start();73 }75 private MotionTrack motionControl;78 private Spatial makeEar(Node root, Vector3f position){79 Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");80 Geometry ear = new Geometry("ear", new Box(1.0f, 1.0f, 1.0f));81 ear.setLocalTranslation(position);82 mat.setColor("Color", ColorRGBA.Green);83 ear.setMaterial(mat);84 root.attachChild(ear);85 return ear;86 }88 private Geometry bell;90 private Spatial ear1;91 //private Spatial ear2;92 //private Spatial ear3;93 //private Spatial ear4;96 private Vector3f[] path = new Vector3f[]{97 // loop 198 new Vector3f(0, 0, 0),99 new Vector3f(0, 0, -10),100 new Vector3f(-2, 0, -14),101 new Vector3f(-6, 0, -20),102 new Vector3f(0, 0, -26),103 new Vector3f(6, 0, -20),104 new Vector3f(0, 0, -14),105 new Vector3f(-6, 0, -20),106 new Vector3f(0, 0, -26),107 new Vector3f(6, 0, -20),108 // loop 2109 new Vector3f(5, 0, -5),110 new Vector3f(7, 0, 1.5f),111 new Vector3f(14, 0, 2),112 new Vector3f(20, 0, 6),113 new Vector3f(26, 0, 0),114 new Vector3f(20, 0, -6),115 new Vector3f(14, 0, 0),116 new Vector3f(20, 0, 6),117 new Vector3f(26, 0, 0),118 new Vector3f(20, 0, -6),119 new Vector3f(14, 0, 0),120 // loop 3121 new Vector3f(8, 0, 7.5f),122 new Vector3f(7, 0, 10.5f),123 new Vector3f(6, 0, 20),124 new Vector3f(0, 0, 26),125 new Vector3f(-6, 0, 20),126 new Vector3f(0, 0, 14),127 new Vector3f(6, 0, 20),128 new Vector3f(0, 0, 26),129 new Vector3f(-6, 0, 20),130 new Vector3f(0, 0, 14),131 // begin ellipse132 new Vector3f(16, 5, 20),133 new Vector3f(0, 0, 26),134 new Vector3f(-16, -10, 20),135 new Vector3f(0, 0, 14),136 new Vector3f(16, 20, 20),137 new Vector3f(0, 0, 26),138 new Vector3f(-10, -25, 10),139 new Vector3f(-10, 0, 0),140 // come at me bro!141 new Vector3f(-28.00242f, 48.005623f, -34.648228f),142 new Vector3f(0, 0 , -20),143 };147 private void createScene() {148 Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");149 bell = new Geometry( "sound-emitter" , new Sphere(15,15,1));150 mat.setColor("Color", ColorRGBA.Blue);151 bell.setMaterial(mat);152 rootNode.attachChild(bell);154 DirectionalLight light = new DirectionalLight();155 light.setDirection(new Vector3f(0, -1, 0).normalizeLocal());156 light.setColor(ColorRGBA.White.mult(1.5f));157 rootNode.addLight(light);159 ear1 = makeEar(rootNode, new Vector3f(0, 0 ,20));160 //ear2 = makeEar(rootNode, new Vector3f(0, 0 ,-20));161 //ear3 = makeEar(rootNode, new Vector3f(20, 0 ,0));162 //ear4 = makeEar(rootNode, new Vector3f(-20, 0 ,0));164 MotionPath track = new MotionPath();166 for (Vector3f v : path){167 track.addWayPoint(v);168 }171 track.setCurveTension(0.80f);174 motionControl = new MotionTrack(bell,track);175 motionControl.setTimer(new IsoTimer(60));176 motionControl.setDirectionType(MotionTrack.Direction.PathAndRotation);177 motionControl.setRotation(new Quaternion().fromAngleNormalAxis(-FastMath.HALF_PI, Vector3f.UNIT_Y));178 motionControl.setInitialDuration(20f);179 motionControl.setSpeed(1f);182 track.enableDebugShape(assetManager, rootNode);185 positionCamera();188 }191 private void positionCamera(){192 this.cam.setLocation(new Vector3f(-28.00242f, 48.005623f, -34.648228f));193 // cam.setLocation(new Vector3f(0,0,-20));194 this.cam.setRotation(new Quaternion(0.3359635f, 0.34280345f, -0.13281013f, 0.8671653f));195 }197 private AudioNode music;203 private void initAudio() {205 music = new AudioNode(assetManager, "Sound/Environment/pure.wav", false);207 rootNode.attachChild(music);208 audioRenderer.playSource(music);209 music.setPositional(true);210 music.setVolume(1f);211 music.setReverbEnabled(false);212 music.setMaxDistance(200.0f);213 music.setRefDistance(1f);214 music.setRolloffFactor(5f);215 audioRenderer.pauseSource(music);217 }222 private Listener auxListener = new Listener();223 //public File data1 = new File("/home/r/tmp/data1.wav");224 //public File data2 = new File("/home/r/tmp/data2.wav");225 //public File data3 = new File("/home/r/tmp/data3.wav");226 //public File data4 = new File("/home/r/tmp/data4.wav");227 //public File data5 = new File("/home/r/tmp/data5.wav");228 //public File data6 = new File("/home/r/tmp/data6.wav");231 public class Dancer implements SoundProcessor {233 Spatial entity;235 float scale = 2;236 String debug;237 public Dancer(Spatial entity, String debug){238 this.entity = entity;239 this.debug = debug;240 }242 /**243 * this method is irrelevant since there is no state to cleanup.244 */245 public void cleanup() {}248 /**249 * Dance to the beat! This is the brain of an AI entity that250 * hears it's surroundings and reacts to them.251 */252 public void process(ByteBuffer audioSamples, int numSamples, AudioFormat format) {253 audioSamples.clear();254 byte[] data = new byte[numSamples];255 float[] out = new float[numSamples];256 audioSamples.get(data);257 FloatSampleTools.byte2floatInterleaved(data, 0, out, 0,258 numSamples/format.getFrameSize(), format);260 float max = Float.NEGATIVE_INFINITY;261 for (float f : out){if (f > max) max = f;}262 audioSamples.clear();263 System.out.println(debug);264 System.out.println(max);268 //entity.scale(this.scale);269 //if (this.scale == 2f){this.scale = 0.5f;}270 //else {this.scale = 2;}271 }274 }279 public void simpleInitApp() {280 this.setTimer(new IsoTimer(60));281 initAudio();282 initKeys();283 createScene();284 if (this.audioRenderer instanceof MultiListener){285 MultiListener rf = (MultiListener)this.audioRenderer;288 listener.setLocation(ear1.getLocalTranslation());289 auxListener = new Listener(listener);291 rf.addListener(auxListener);292 WaveFileWriter aux = null;293 WaveFileWriter main = null;296 try {aux = new WaveFileWriter(new File("/home/r/tmp/aux.wav"));}297 catch (FileNotFoundException e) {e.printStackTrace();}299 try {main = new WaveFileWriter(new File("/home/r/tmp/main.wav"));}300 catch (FileNotFoundException e) {e.printStackTrace();}302 rf.registerSoundProcessor(auxListener,303 new CompositeSoundProcessor(new Dancer(ear1, "aux"), aux));305 rf.registerSoundProcessor(306 new CompositeSoundProcessor(new Dancer(ear1, "--------\nmain"), main));307 }309 motionControl.play();310 }316 private void initKeys() {317 inputManager.addMapping("Shoot", new MouseButtonTrigger(0));318 inputManager.addListener(actionListener, "Shoot");319 }321 /** Defining the "Shoot" action: Play a gun sound. */322 private ActionListener actionListener = new ActionListener() {323 @Override324 public void onAction(String name, boolean keyPressed, float tpf) {325 if (name.equals("Shoot") && !keyPressed) {326 System.out.println("I'm playing! <3");327 System.out.println(bell.getLocalTranslation().subtract(cam.getLocation()).length());328 bell.getMaterial().setColor("Color", ColorRGBA.randomColor());329 audioRenderer.playSource(music);330 System.out.println(music.getRefDistance());332 }333 }334 };336 /** Move the listener with the camera - for 3D audio. */339 private Vector3f prevBellPos = Vector3f.ZERO;342 public void simpleUpdate(float tpf) {343 //Vector3f loc = cam.getLocation();344 //Quaternion rot = cam.getRotation();345 //listener.setLocation(loc);346 //listener.setRotation(rot);349 //listener.setLocation(cam.getLocation());350 //listener.setRotation(cam.getRotation());351 //auxListener.setLocation(loc);352 //auxListener.setRotation(rot);353 if (music.getStatus() != AudioNode.Status.Playing){354 audioRenderer.playSource(music);355 bell.getMaterial().setColor("Color", ColorRGBA.randomColor());356 }357 //audioRenderer.updateSourceParam(music, AudioParam.Direction);359 Vector3f bellVelocity = bell.getLocalTranslation().subtract(prevBellPos).mult(1.0f/tpf);360 prevBellPos = bell.getLocalTranslation();362 music.setLocalTranslation(bell.getLocalTranslation());363 music.setVelocity(bellVelocity);365 //audioRenderer.updateSourceParam(music, AudioParam.Position);366 //audioRenderer.updateSourceParam(music, AudioParam.Velocity);369 //System.out.println("main:" + listener.getVolume());370 //System.out.println("aux:" + auxListener.getVolume());371 //org.lwjgl.openal.AL10.alSourcef(1, org.lwjgl.openal.AL10.AL_MIN_GAIN, 0f);372 //org.lwjgl.openal.AL10.alSourcef(1, org.lwjgl.openal.AL10.AL_ROLLOFF_FACTOR, 5f);374 }376 }