changeset 4:ed256a687dfe

removed very old crufty java program
author Robert McIntyre <rlm@mit.edu>
date Tue, 25 Oct 2011 13:17:37 -0700
parents 96298d83959c
children ff36dfa1addb
files RecordAudioRenderer.java cleanup-message.txt org/cleanup-message.txt
diffstat 3 files changed, 100 insertions(+), 1283 deletions(-) [+]
line wrap: on
line diff
     1.1 --- a/RecordAudioRenderer.java	Tue Oct 25 13:16:27 2011 -0700
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,1183 +0,0 @@
     1.4 -package com.jme3.capture;
     1.5 -
     1.6 -import static org.lwjgl.openal.AL10.AL_BUFFER;
     1.7 -import static org.lwjgl.openal.AL10.AL_BUFFERS_PROCESSED;
     1.8 -import static org.lwjgl.openal.AL10.AL_CONE_INNER_ANGLE;
     1.9 -import static org.lwjgl.openal.AL10.AL_CONE_OUTER_ANGLE;
    1.10 -import static org.lwjgl.openal.AL10.AL_CONE_OUTER_GAIN;
    1.11 -import static org.lwjgl.openal.AL10.AL_DIRECTION;
    1.12 -import static org.lwjgl.openal.AL10.AL_FALSE;
    1.13 -import static org.lwjgl.openal.AL10.AL_FORMAT_MONO16;
    1.14 -import static org.lwjgl.openal.AL10.AL_FORMAT_MONO8;
    1.15 -import static org.lwjgl.openal.AL10.AL_FORMAT_STEREO16;
    1.16 -import static org.lwjgl.openal.AL10.AL_FORMAT_STEREO8;
    1.17 -import static org.lwjgl.openal.AL10.AL_GAIN;
    1.18 -import static org.lwjgl.openal.AL10.AL_LOOPING;
    1.19 -import static org.lwjgl.openal.AL10.AL_MAX_DISTANCE;
    1.20 -import static org.lwjgl.openal.AL10.AL_ORIENTATION;
    1.21 -import static org.lwjgl.openal.AL10.AL_PAUSED;
    1.22 -import static org.lwjgl.openal.AL10.AL_PITCH;
    1.23 -import static org.lwjgl.openal.AL10.AL_POSITION;
    1.24 -import static org.lwjgl.openal.AL10.AL_REFERENCE_DISTANCE;
    1.25 -import static org.lwjgl.openal.AL10.AL_RENDERER;
    1.26 -import static org.lwjgl.openal.AL10.AL_SOURCE_RELATIVE;
    1.27 -import static org.lwjgl.openal.AL10.AL_SOURCE_STATE;
    1.28 -import static org.lwjgl.openal.AL10.AL_STOPPED;
    1.29 -import static org.lwjgl.openal.AL10.AL_TRUE;
    1.30 -import static org.lwjgl.openal.AL10.AL_VELOCITY;
    1.31 -import static org.lwjgl.openal.AL10.AL_VENDOR;
    1.32 -import static org.lwjgl.openal.AL10.AL_VERSION;
    1.33 -import static org.lwjgl.openal.AL10.alBufferData;
    1.34 -import static org.lwjgl.openal.AL10.alDeleteBuffers;
    1.35 -import static org.lwjgl.openal.AL10.alDeleteSources;
    1.36 -import static org.lwjgl.openal.AL10.alGenBuffers;
    1.37 -import static org.lwjgl.openal.AL10.alGenSources;
    1.38 -import static org.lwjgl.openal.AL10.alGetError;
    1.39 -import static org.lwjgl.openal.AL10.alGetSourcei;
    1.40 -import static org.lwjgl.openal.AL10.alGetString;
    1.41 -import static org.lwjgl.openal.AL10.alListener;
    1.42 -import static org.lwjgl.openal.AL10.alListener3f;
    1.43 -import static org.lwjgl.openal.AL10.alListenerf;
    1.44 -import static org.lwjgl.openal.AL10.alSource3f;
    1.45 -import static org.lwjgl.openal.AL10.alSourcePause;
    1.46 -import static org.lwjgl.openal.AL10.alSourcePlay;
    1.47 -import static org.lwjgl.openal.AL10.alSourceQueueBuffers;
    1.48 -import static org.lwjgl.openal.AL10.alSourceStop;
    1.49 -import static org.lwjgl.openal.AL10.alSourceUnqueueBuffers;
    1.50 -import static org.lwjgl.openal.AL10.alSourcef;
    1.51 -import static org.lwjgl.openal.AL10.alSourcei;
    1.52 -
    1.53 -import java.lang.reflect.Field;
    1.54 -import java.nio.ByteBuffer;
    1.55 -import java.nio.FloatBuffer;
    1.56 -import java.nio.IntBuffer;
    1.57 -import java.util.ArrayList;
    1.58 -import java.util.Vector;
    1.59 -import java.util.concurrent.atomic.AtomicBoolean;
    1.60 -import java.util.logging.Level;
    1.61 -import java.util.logging.Logger;
    1.62 -
    1.63 -import org.lwjgl.LWJGLException;
    1.64 -import org.lwjgl.openal.AL;
    1.65 -import org.lwjgl.openal.AL11;
    1.66 -import org.lwjgl.openal.ALC10;
    1.67 -import org.lwjgl.openal.ALCdevice;
    1.68 -import org.lwjgl.openal.EFX10;
    1.69 -import org.lwjgl.openal.OpenALException;
    1.70 -
    1.71 -import com.jme3.audio.AudioBuffer;
    1.72 -import com.jme3.audio.AudioData;
    1.73 -import com.jme3.audio.AudioNode;
    1.74 -import com.jme3.audio.AudioNode.Status;
    1.75 -import com.jme3.audio.AudioParam;
    1.76 -import com.jme3.audio.AudioRenderer;
    1.77 -import com.jme3.audio.AudioStream;
    1.78 -import com.jme3.audio.Environment;
    1.79 -import com.jme3.audio.Filter;
    1.80 -import com.jme3.audio.Listener;
    1.81 -import com.jme3.audio.ListenerParam;
    1.82 -import com.jme3.audio.LowPassFilter;
    1.83 -import com.jme3.math.Vector3f;
    1.84 -import com.jme3.util.BufferUtils;
    1.85 -
    1.86 -
    1.87 -
    1.88 -public class RecordAudioRenderer implements AudioRenderer, Runnable {
    1.89 -
    1.90 -	
    1.91 -	
    1.92 -	public static void getMainSamples(){
    1.93 -		
    1.94 -	}
    1.95 -	
    1.96 -	
    1.97 -   private static final Logger logger = Logger.getLogger(RecordAudioRenderer.class.getName());
    1.98 -
    1.99 -   // When multiplied by STREAMING_BUFFER_COUNT, will equal 44100 * 2 * 2
   1.100 -   // which is exactly 1 second of audio.
   1.101 -   private static final int BUFFER_SIZE = 35280;
   1.102 -   private static final int STREAMING_BUFFER_COUNT = 5;
   1.103 -
   1.104 -   private final static int MAX_NUM_CHANNELS = 2;
   1.105 -   private IntBuffer ib = BufferUtils.createIntBuffer(1);
   1.106 -   private final FloatBuffer fb = BufferUtils.createVector3Buffer(2);
   1.107 -   private final ByteBuffer nativeBuf = BufferUtils.createByteBuffer(BUFFER_SIZE);
   1.108 -   private final byte[] arrayBuf = new byte[BUFFER_SIZE];
   1.109 -
   1.110 -   private int[] channels;
   1.111 -   private AudioNode[] chanSrcs;
   1.112 -   private int nextChan = 0;
   1.113 -   private ArrayList<Integer> freeChans = new ArrayList<Integer>();
   1.114 -
   1.115 -   private Listener listener;
   1.116 -   private boolean audioDisabled = false;
   1.117 -
   1.118 -   private boolean supportEfx = false;
   1.119 -   private int auxSends = 0;
   1.120 -   private int reverbFx = -1;
   1.121 -   private int reverbFxSlot = -1;
   1.122 -
   1.123 -   // RLM: this is to call the native methods which require the OpenAL device ID.
   1.124 -   // currently it is obtained through reflection.
   1.125 -   private long deviceID;
   1.126 -   
   1.127 -   // Update audio 20 times per second
   1.128 -   private static final float UPDATE_RATE = 0.05f;
   1.129 -
   1.130 -   private final Thread audioThread = new Thread(this, "jME3 Audio Thread");
   1.131 -   private final AtomicBoolean threadLock = new AtomicBoolean(false);
   1.132 -
   1.133 -   public RecordAudioRenderer(){
   1.134 -   }
   1.135 -
   1.136 -   public static native void helloEveryone();
   1.137 -   
   1.138 -   
   1.139 -   public static native void nstep(long device);
   1.140 -   public void step(){
   1.141 -	   nstep(this.deviceID);
   1.142 -   }
   1.143 -	
   1.144 -	
   1.145 -	
   1.146 -	public void getMainSamples(ByteBuffer buffer){
   1.147 -		ngetMainSamples(this.deviceID, buffer, buffer.position());
   1.148 -	}
   1.149 -	public static native void ngetMainSamples(long device, ByteBuffer buffer, int position);
   1.150 -	
   1.151 -	
   1.152 -	public void getAuxSamples(ByteBuffer buffer){
   1.153 -		ngetAuxSamples(this.deviceID, buffer, buffer.position());
   1.154 -	}
   1.155 -	public static native void ngetAuxSamples(long device, ByteBuffer buffer, int position);
   1.156 -
   1.157 -   
   1.158 -   
   1.159 -   public void initialize(){
   1.160 -       if (!audioThread.isAlive()){
   1.161 -           audioThread.setDaemon(true);
   1.162 -           audioThread.setPriority(Thread.NORM_PRIORITY+1);
   1.163 -           audioThread.start();
   1.164 -       }else{
   1.165 -           throw new IllegalStateException("Initialize already called");
   1.166 -       }
   1.167 -   }
   1.168 -
   1.169 -   private void checkDead(){
   1.170 -       if (audioThread.getState() == Thread.State.TERMINATED)
   1.171 -           throw new IllegalStateException("Audio thread is terminated");
   1.172 -   }
   1.173 -
   1.174 -   public void run(){
   1.175 -       initInThread();
   1.176 -       synchronized (threadLock){
   1.177 -           threadLock.set(true);
   1.178 -           threadLock.notifyAll();
   1.179 -       }
   1.180 -       
   1.181 -       
   1.182 -       helloEveryone();
   1.183 -       System.out.println("AudioRecorder: Trying to call native methods.");
   1.184 -	   System.out.println("our device ID is : " + this.deviceID);
   1.185 -
   1.186 -	   
   1.187 -	   
   1.188 -	   
   1.189 -       long updateRateNanos = (long) (UPDATE_RATE * 1000000000);
   1.190 -       mainloop: while (true){
   1.191 -           long startTime = System.nanoTime();
   1.192 -
   1.193 -           if (Thread.interrupted())
   1.194 -               break;
   1.195 -
   1.196 -           synchronized (threadLock){
   1.197 -               updateInThread(UPDATE_RATE);
   1.198 -           }
   1.199 -
   1.200 -           long endTime = System.nanoTime();
   1.201 -           long diffTime = endTime - startTime;
   1.202 -
   1.203 -           if (diffTime < updateRateNanos){
   1.204 -               long desiredEndTime = startTime + updateRateNanos;
   1.205 -               while (System.nanoTime() < desiredEndTime){
   1.206 -                   try{
   1.207 -                       Thread.sleep(1);
   1.208 -                   }catch (InterruptedException ex){
   1.209 -                       break mainloop;
   1.210 -                   }
   1.211 -               }
   1.212 -           }
   1.213 -       }
   1.214 -
   1.215 -       synchronized (threadLock){
   1.216 -           cleanupInThread();
   1.217 -       }
   1.218 -   }
   1.219 -
   1.220 -   public void initInThread(){
   1.221 -       try{
   1.222 -           if (!AL.isCreated()){
   1.223 -        	   AL.create("Aurellem", 44100, 15, false);	
   1.224 -           }
   1.225 -       }catch (OpenALException ex){
   1.226 -           logger.log(Level.SEVERE, "Failed to load audio library", ex);
   1.227 -           audioDisabled = true;
   1.228 -           return;
   1.229 -       }catch (LWJGLException ex){
   1.230 -           logger.log(Level.SEVERE, "Failed to load audio library", ex);
   1.231 -           audioDisabled = true;
   1.232 -           return;
   1.233 -       }
   1.234 -
   1.235 -       ALCdevice device = AL.getDevice();
   1.236 -       
   1.237 -       // RLM: use reflection to grab the ID of our device for use later.
   1.238 -       try {
   1.239 -    	   Field deviceIDField;
   1.240 -    	   deviceIDField = ALCdevice.class.getDeclaredField("device");
   1.241 -    	   deviceIDField.setAccessible(true);
   1.242 -    	   try {deviceID = (Long)deviceIDField.get(device);} 
   1.243 -    	   catch (IllegalArgumentException e) {e.printStackTrace();} 
   1.244 -    	   catch (IllegalAccessException e) {e.printStackTrace();}
   1.245 -    	   deviceIDField.setAccessible(false);} 
   1.246 -       catch (SecurityException e) {e.printStackTrace();} 
   1.247 -       catch (NoSuchFieldException e) {e.printStackTrace();}
   1.248 -       
   1.249 -       
   1.250 -       
   1.251 -       String deviceName = ALC10.alcGetString(device, ALC10.ALC_DEVICE_SPECIFIER);
   1.252 -
   1.253 -       logger.log(Level.FINER, "Audio Device: {0}", deviceName);
   1.254 -       logger.log(Level.FINER, "Audio Vendor: {0}", alGetString(AL_VENDOR));
   1.255 -       logger.log(Level.FINER, "Audio Renderer: {0}", alGetString(AL_RENDERER));
   1.256 -       logger.log(Level.FINER, "Audio Version: {0}", alGetString(AL_VERSION));
   1.257 -
   1.258 -       // Find maximum # of sources supported by this implementation
   1.259 -       // RLM: this may not be wise -- exceeding the number of available channels 
   1.260 -       //      can crash some versions of OpenAL
   1.261 -       ArrayList<Integer> channelList = new ArrayList<Integer>();
   1.262 -       for (int i = 0; i < MAX_NUM_CHANNELS; i++){
   1.263 -           int chan = alGenSources();
   1.264 -           if (alGetError() != 0){
   1.265 -               break;
   1.266 -           }else{
   1.267 -               channelList.add(chan);
   1.268 -           }
   1.269 -       }
   1.270 -
   1.271 -       channels = new int[channelList.size()];
   1.272 -       for (int i = 0; i < channels.length; i++){
   1.273 -           channels[i] = channelList.get(i);
   1.274 -       }
   1.275 -
   1.276 -       ib = BufferUtils.createIntBuffer(channels.length);
   1.277 -       chanSrcs = new AudioNode[channels.length];
   1.278 -
   1.279 -       logger.log(Level.INFO, "AudioRenderer supports {0} channels", channels.length);
   1.280 -
   1.281 -       supportEfx = ALC10.alcIsExtensionPresent(device, "ALC_EXT_EFX");
   1.282 -       // RLM: disable this for now.
   1.283 -       supportEfx = false;
   1.284 -       logger.log(Level.FINER, "Audio EFX support: {0}", supportEfx);
   1.285 -
   1.286 -       if (supportEfx){
   1.287 -           ib.position(0).limit(1);
   1.288 -           ALC10.alcGetInteger(device, EFX10.ALC_EFX_MAJOR_VERSION, ib);
   1.289 -           int major = ib.get(0);
   1.290 -           ib.position(0).limit(1);
   1.291 -           ALC10.alcGetInteger(device, EFX10.ALC_EFX_MINOR_VERSION, ib);
   1.292 -           int minor = ib.get(0);
   1.293 -           logger.log(Level.INFO, "Audio effect extension version: {0}.{1}", new Object[]{major, minor});
   1.294 -
   1.295 -           ALC10.alcGetInteger(device, EFX10.ALC_MAX_AUXILIARY_SENDS, ib);
   1.296 -           auxSends = ib.get(0);
   1.297 -           logger.log(Level.INFO, "Audio max auxilary sends: {0}", auxSends);
   1.298 -
   1.299 -           // create slot
   1.300 -           ib.position(0).limit(1);
   1.301 -           EFX10.alGenAuxiliaryEffectSlots(ib);
   1.302 -           reverbFxSlot = ib.get(0);
   1.303 -
   1.304 -           // create effect
   1.305 -           ib.position(0).limit(1);
   1.306 -           EFX10.alGenEffects(ib);
   1.307 -           reverbFx = ib.get(0);
   1.308 -           EFX10.alEffecti(reverbFx, EFX10.AL_EFFECT_TYPE, EFX10.AL_EFFECT_REVERB);
   1.309 -
   1.310 -           // attach reverb effect to effect slot
   1.311 -//           EFX10.alAuxiliaryEffectSloti(reverbFxSlot, EFX10.AL_EFFECTSLOT_EFFECT, reverbFx);
   1.312 -       }
   1.313 -   }
   1.314 -
   1.315 -   public void cleanupInThread(){
   1.316 -
   1.317 -
   1.318 -	   if (audioDisabled){
   1.319 -           AL.destroy();
   1.320 -           return;
   1.321 -       }
   1.322 -
   1.323 -       // delete channel-based sources
   1.324 -       ib.clear();
   1.325 -       ib.put(channels);
   1.326 -       ib.flip();
   1.327 -       alDeleteSources(ib);
   1.328 -
   1.329 -       if (supportEfx){
   1.330 -           ib.position(0).limit(1);
   1.331 -           ib.put(0, reverbFx);
   1.332 -           EFX10.alDeleteEffects(ib);
   1.333 -
   1.334 -           ib.position(0).limit(1);
   1.335 -           ib.put(0, reverbFxSlot);
   1.336 -           EFX10.alDeleteAuxiliaryEffectSlots(ib);
   1.337 -       }
   1.338 -
   1.339 -       // XXX: Delete other buffers/sources
   1.340 -       AL.destroy();
   1.341 -   }
   1.342 -
   1.343 -   public void cleanup(){
   1.344 -       // kill audio thread
   1.345 -	   
   1.346 -       if (audioThread.isAlive()){
   1.347 -           audioThread.interrupt();
   1.348 -       }
   1.349 -       
   1.350 -       Byte[] data1 = new Byte[this.fullWaveData1.size()];
   1.351 -	   data1 = this.fullWaveData1.toArray(data1);
   1.352 -
   1.353 -	   Byte[] data2 = new Byte[this.fullWaveData2.size()];
   1.354 -	   data2 = this.fullWaveData2.toArray(data2);
   1.355 -	   System.out.println(this.fullWaveData1.size());
   1.356 -	   System.out.println("Saving WAVE data!");
   1.357 -	   /*for (int i = 0; i < data1.length;i++){
   1.358 -		   System.out.print(data1[i]+",");
   1.359 -		   if (i%32 ==0){System.out.println();}
   1.360 -	   }
   1.361 -	   */
   1.362 -	   
   1.363 -	   
   1.364 -	   StdAudio.save("/home/r/wave-output/data2.wav", data2);
   1.365 -	   StdAudio.save("/home/r/wave-output/data1.wav", data1);
   1.366 -   }
   1.367 -
   1.368 -   private void updateFilter(Filter f){
   1.369 -       int id = f.getId();
   1.370 -       if (id == -1){
   1.371 -           ib.position(0).limit(1);
   1.372 -           EFX10.alGenFilters(ib);
   1.373 -           id = ib.get(0);
   1.374 -           f.setId(id);
   1.375 -       }
   1.376 -
   1.377 -       if (f instanceof LowPassFilter){
   1.378 -           LowPassFilter lpf = (LowPassFilter) f;
   1.379 -           EFX10.alFilteri(id, EFX10.AL_FILTER_TYPE,    EFX10.AL_FILTER_LOWPASS);
   1.380 -           EFX10.alFilterf(id, EFX10.AL_LOWPASS_GAIN,   lpf.getVolume());
   1.381 -           EFX10.alFilterf(id, EFX10.AL_LOWPASS_GAINHF, lpf.getHighFreqVolume());
   1.382 -       }else{
   1.383 -           throw new UnsupportedOperationException("Filter type unsupported: "+
   1.384 -                                                   f.getClass().getName());
   1.385 -       }
   1.386 -
   1.387 -       f.clearUpdateNeeded();
   1.388 -   }
   1.389 -
   1.390 -   public void updateSourceParam(AudioNode src, AudioParam param){
   1.391 -       checkDead();
   1.392 -       synchronized (threadLock){
   1.393 -           while (!threadLock.get()){
   1.394 -               try {
   1.395 -                   threadLock.wait();
   1.396 -               } catch (InterruptedException ex) {
   1.397 -               }
   1.398 -           }
   1.399 -           if (audioDisabled)
   1.400 -               return;
   1.401 -
   1.402 -           // There is a race condition in AudioNode that can
   1.403 -           // cause this to be called for a node that has been
   1.404 -           // detached from its channel.  For example, setVolume()
   1.405 -           // called from the render thread may see that that AudioNode
   1.406 -           // still has a channel value but the audio thread may
   1.407 -           // clear that channel before setVolume() gets to call
   1.408 -           // updateSourceParam() (because the audio stopped playing
   1.409 -           // on its own right as the volume was set).  In this case, 
   1.410 -           // it should be safe to just ignore the update
   1.411 -           if (src.getChannel() < 0) 
   1.412 -               return;
   1.413 -          
   1.414 -           assert src.getChannel() >= 0;
   1.415 -
   1.416 -           int id = channels[src.getChannel()];
   1.417 -           switch (param){
   1.418 -               case Position:
   1.419 -                   if (!src.isPositional())
   1.420 -                       return;
   1.421 -
   1.422 -                   Vector3f pos = src.getWorldTranslation();
   1.423 -                   alSource3f(id, AL_POSITION, pos.x, pos.y, pos.z);
   1.424 -                   break;
   1.425 -               case Velocity:
   1.426 -                   if (!src.isPositional())
   1.427 -                       return;
   1.428 -
   1.429 -                   Vector3f vel = src.getVelocity();
   1.430 -                   alSource3f(id, AL_VELOCITY, vel.x, vel.y, vel.z);
   1.431 -                   break;
   1.432 -               case MaxDistance:
   1.433 -                   if (!src.isPositional())
   1.434 -                       return;
   1.435 -
   1.436 -                   alSourcef(id, AL_MAX_DISTANCE, src.getMaxDistance());
   1.437 -                   break;
   1.438 -               case RefDistance:
   1.439 -                   if (!src.isPositional())
   1.440 -                       return;
   1.441 -
   1.442 -                   alSourcef(id, AL_REFERENCE_DISTANCE, src.getRefDistance());
   1.443 -                   break;
   1.444 -               case ReverbFilter:
   1.445 -                   if (!src.isPositional() || !src.isReverbEnabled())
   1.446 -                       return;
   1.447 -
   1.448 -                   int filter = EFX10.AL_FILTER_NULL;
   1.449 -                   if (src.getReverbFilter() != null){
   1.450 -                       Filter f = src.getReverbFilter();
   1.451 -                       if (f.isUpdateNeeded()){
   1.452 -                           updateFilter(f);
   1.453 -                       }
   1.454 -                       filter = f.getId();
   1.455 -                   }
   1.456 -                   AL11.alSource3i(id, EFX10.AL_AUXILIARY_SEND_FILTER, reverbFxSlot, 0, filter);
   1.457 -                   break;
   1.458 -               case ReverbEnabled:
   1.459 -                   if (!src.isPositional())
   1.460 -                       return;
   1.461 -
   1.462 -                   if (src.isReverbEnabled()){
   1.463 -                       updateSourceParam(src, AudioParam.ReverbFilter);
   1.464 -                   }else{
   1.465 -                       AL11.alSource3i(id, EFX10.AL_AUXILIARY_SEND_FILTER, 0, 0, EFX10.AL_FILTER_NULL);
   1.466 -                   }
   1.467 -                   break;
   1.468 -               case IsPositional:
   1.469 -                   if (!src.isPositional()){
   1.470 -                       // play in headspace
   1.471 -                       alSourcei(id, AL_SOURCE_RELATIVE, AL_TRUE);
   1.472 -                       alSource3f(id, AL_POSITION, 0,0,0);
   1.473 -                       alSource3f(id, AL_VELOCITY, 0,0,0);
   1.474 -                   }else{
   1.475 -                       alSourcei(id, AL_SOURCE_RELATIVE, AL_FALSE);
   1.476 -                       updateSourceParam(src, AudioParam.Position);
   1.477 -                       updateSourceParam(src, AudioParam.Velocity);
   1.478 -                       updateSourceParam(src, AudioParam.MaxDistance);
   1.479 -                       updateSourceParam(src, AudioParam.RefDistance);
   1.480 -                       updateSourceParam(src, AudioParam.ReverbEnabled);
   1.481 -                   }
   1.482 -                   break;
   1.483 -               case Direction:
   1.484 -                   if (!src.isDirectional())
   1.485 -                       return;
   1.486 -
   1.487 -                   Vector3f dir = src.getDirection();
   1.488 -                   alSource3f(id, AL_DIRECTION, dir.x, dir.y, dir.z);
   1.489 -                   break;
   1.490 -               case InnerAngle:
   1.491 -                   if (!src.isDirectional())
   1.492 -                       return;
   1.493 -
   1.494 -                   alSourcef(id, AL_CONE_INNER_ANGLE, src.getInnerAngle());
   1.495 -                   break;
   1.496 -               case OuterAngle:
   1.497 -                   if (!src.isDirectional())
   1.498 -                       return;
   1.499 -
   1.500 -                   alSourcef(id, AL_CONE_OUTER_ANGLE, src.getOuterAngle());
   1.501 -                   break;
   1.502 -               case IsDirectional:
   1.503 -                   if (src.isDirectional()){
   1.504 -                       updateSourceParam(src, AudioParam.Direction);
   1.505 -                       updateSourceParam(src, AudioParam.InnerAngle);
   1.506 -                       updateSourceParam(src, AudioParam.OuterAngle);
   1.507 -                       alSourcef(id, AL_CONE_OUTER_GAIN, 0);
   1.508 -                   }else{
   1.509 -                       alSourcef(id, AL_CONE_INNER_ANGLE, 360);
   1.510 -                       alSourcef(id, AL_CONE_OUTER_ANGLE, 360);
   1.511 -                       alSourcef(id, AL_CONE_OUTER_GAIN, 1f);
   1.512 -                   }
   1.513 -                   break;
   1.514 -               case DryFilter:
   1.515 -                   if (src.getDryFilter() != null){
   1.516 -                       Filter f = src.getDryFilter();
   1.517 -                       if (f.isUpdateNeeded()){
   1.518 -                           updateFilter(f);
   1.519 -
   1.520 -                           // NOTE: must re-attach filter for changes to apply.
   1.521 -                           alSourcei(id, EFX10.AL_DIRECT_FILTER, f.getId());
   1.522 -                       }
   1.523 -                   }else{
   1.524 -                       alSourcei(id, EFX10.AL_DIRECT_FILTER, EFX10.AL_FILTER_NULL);
   1.525 -                   }
   1.526 -                   break;
   1.527 -               case Looping:
   1.528 -                   if (src.isLooping()){
   1.529 -                       if (!(src.getAudioData() instanceof AudioStream)){
   1.530 -                           alSourcei(id, AL_LOOPING, AL_TRUE);
   1.531 -                       }
   1.532 -                   }else{
   1.533 -                       alSourcei(id, AL_LOOPING, AL_FALSE);
   1.534 -                   }
   1.535 -                   break;
   1.536 -               case Volume:
   1.537 -                   alSourcef(id, AL_GAIN, src.getVolume());
   1.538 -                   break;
   1.539 -               case Pitch:
   1.540 -                   alSourcef(id, AL_PITCH, src.getPitch());
   1.541 -                   break;
   1.542 -           }
   1.543 -       }
   1.544 -   }
   1.545 -
   1.546 -   private void setSourceParams(int id, AudioNode src, boolean forceNonLoop){
   1.547 -       if (src.isPositional()){
   1.548 -           Vector3f pos = src.getWorldTranslation();
   1.549 -           Vector3f vel = src.getVelocity();
   1.550 -           alSource3f(id, AL_POSITION, pos.x, pos.y, pos.z);
   1.551 -           alSource3f(id, AL_VELOCITY, vel.x, vel.y, vel.z);
   1.552 -           alSourcef(id, AL_MAX_DISTANCE, src.getMaxDistance());
   1.553 -           alSourcef(id, AL_REFERENCE_DISTANCE, src.getRefDistance());
   1.554 -           alSourcei(id, AL_SOURCE_RELATIVE, AL_FALSE);
   1.555 -
   1.556 -           if (src.isReverbEnabled()){
   1.557 -               int filter = EFX10.AL_FILTER_NULL;
   1.558 -               if (src.getReverbFilter() != null){
   1.559 -                   Filter f = src.getReverbFilter();
   1.560 -                   if (f.isUpdateNeeded()){
   1.561 -                       updateFilter(f);
   1.562 -                   }
   1.563 -                   filter = f.getId();
   1.564 -               }
   1.565 -               AL11.alSource3i(id, EFX10.AL_AUXILIARY_SEND_FILTER, reverbFxSlot, 0, filter);
   1.566 -           }
   1.567 -       }else{
   1.568 -           // play in headspace
   1.569 -           alSourcei(id, AL_SOURCE_RELATIVE, AL_TRUE);
   1.570 -           alSource3f(id, AL_POSITION, 0,0,0);
   1.571 -           alSource3f(id, AL_VELOCITY, 0,0,0);
   1.572 -       }
   1.573 -
   1.574 -       if (src.getDryFilter() != null){
   1.575 -           Filter f = src.getDryFilter();
   1.576 -           if (f.isUpdateNeeded()){
   1.577 -               updateFilter(f);
   1.578 -               
   1.579 -               // NOTE: must re-attach filter for changes to apply.
   1.580 -               alSourcei(id, EFX10.AL_DIRECT_FILTER, f.getId());
   1.581 -           }
   1.582 -       }
   1.583 -
   1.584 -       if (forceNonLoop){
   1.585 -           alSourcei(id,  AL_LOOPING, AL_FALSE);
   1.586 -       }else{
   1.587 -           alSourcei(id,  AL_LOOPING, src.isLooping() ? AL_TRUE : AL_FALSE);
   1.588 -       }
   1.589 -       alSourcef(id,  AL_GAIN, src.getVolume());
   1.590 -       alSourcef(id,  AL_PITCH, src.getPitch());
   1.591 -       alSourcef(id,  AL11.AL_SEC_OFFSET, src.getTimeOffset());
   1.592 -
   1.593 -       if (src.isDirectional()){
   1.594 -           Vector3f dir = src.getDirection();
   1.595 -           alSource3f(id, AL_DIRECTION, dir.x, dir.y, dir.z);
   1.596 -           alSourcef(id, AL_CONE_INNER_ANGLE, src.getInnerAngle());
   1.597 -           alSourcef(id, AL_CONE_OUTER_ANGLE, src.getOuterAngle());
   1.598 -           alSourcef(id, AL_CONE_OUTER_GAIN,  0);
   1.599 -       }else{
   1.600 -           alSourcef(id, AL_CONE_INNER_ANGLE, 360);
   1.601 -           alSourcef(id, AL_CONE_OUTER_ANGLE, 360);
   1.602 -           alSourcef(id, AL_CONE_OUTER_GAIN, 1f);
   1.603 -       }
   1.604 -   }
   1.605 -
   1.606 -   public void updateListenerParam(Listener listener, ListenerParam param){
   1.607 -       checkDead();
   1.608 -       synchronized (threadLock){
   1.609 -           while (!threadLock.get()){
   1.610 -               try {
   1.611 -                   threadLock.wait();
   1.612 -               } catch (InterruptedException ex) {
   1.613 -               }
   1.614 -           }
   1.615 -           if (audioDisabled)
   1.616 -               return;
   1.617 -           
   1.618 -           switch (param){
   1.619 -               case Position:
   1.620 -                   Vector3f pos = listener.getLocation();
   1.621 -                   alListener3f(AL_POSITION, pos.x, pos.y, pos.z);
   1.622 -                   break;
   1.623 -               case Rotation:
   1.624 -                   Vector3f dir = listener.getDirection();
   1.625 -                   Vector3f up  = listener.getUp();
   1.626 -                   fb.rewind();
   1.627 -                   fb.put(dir.x).put(dir.y).put(dir.z);
   1.628 -                   fb.put(up.x).put(up.y).put(up.z);
   1.629 -                   fb.flip();
   1.630 -                   alListener(AL_ORIENTATION, fb);
   1.631 -                   break;
   1.632 -               case Velocity:
   1.633 -                   Vector3f vel = listener.getVelocity();
   1.634 -                   alListener3f(AL_VELOCITY, vel.x, vel.y, vel.z);
   1.635 -                   break;
   1.636 -               case Volume:
   1.637 -                   alListenerf(AL_GAIN, listener.getVolume());
   1.638 -                   break;
   1.639 -           }
   1.640 -       }
   1.641 -   }
   1.642 -
   1.643 -   private void setListenerParams(Listener listener){
   1.644 -       Vector3f pos = listener.getLocation();
   1.645 -       Vector3f vel = listener.getVelocity();
   1.646 -       Vector3f dir = listener.getDirection();
   1.647 -       Vector3f up  = listener.getUp();
   1.648 -
   1.649 -       alListener3f(AL_POSITION, pos.x, pos.y, pos.z);
   1.650 -       alListener3f(AL_VELOCITY, vel.x, vel.y, vel.z);
   1.651 -       fb.rewind();
   1.652 -       fb.put(dir.x).put(dir.y).put(dir.z);
   1.653 -       fb.put(up.x).put(up.y).put(up.z);
   1.654 -       fb.flip();
   1.655 -       alListener(AL_ORIENTATION, fb);
   1.656 -       alListenerf(AL_GAIN, listener.getVolume());
   1.657 -   }
   1.658 -
   1.659 -   private int newChannel(){
   1.660 -       if (freeChans.size() > 0)
   1.661 -           return freeChans.remove(0);
   1.662 -       else if (nextChan < channels.length){
   1.663 -           return nextChan++;
   1.664 -       }else{
   1.665 -           return -1;
   1.666 -       }
   1.667 -   }
   1.668 -
   1.669 -   private void freeChannel(int index){
   1.670 -       if (index == nextChan-1){
   1.671 -           nextChan--;
   1.672 -       } else{
   1.673 -           freeChans.add(index);
   1.674 -       }
   1.675 -   }
   1.676 -
   1.677 -   public void setEnvironment(Environment env){
   1.678 -       checkDead();
   1.679 -       synchronized (threadLock){
   1.680 -           while (!threadLock.get()){
   1.681 -               try {
   1.682 -                   threadLock.wait();
   1.683 -               } catch (InterruptedException ex) {
   1.684 -               }
   1.685 -           }
   1.686 -           if (audioDisabled)
   1.687 -               return;
   1.688 -           
   1.689 -           EFX10.alEffectf(reverbFx, EFX10.AL_REVERB_DENSITY,             env.getDensity());
   1.690 -           EFX10.alEffectf(reverbFx, EFX10.AL_REVERB_DIFFUSION,           env.getDiffusion());
   1.691 -           EFX10.alEffectf(reverbFx, EFX10.AL_REVERB_GAIN,                env.getGain());
   1.692 -           EFX10.alEffectf(reverbFx, EFX10.AL_REVERB_GAINHF,              env.getGainHf());
   1.693 -           EFX10.alEffectf(reverbFx, EFX10.AL_REVERB_DECAY_TIME,          env.getDecayTime());
   1.694 -           EFX10.alEffectf(reverbFx, EFX10.AL_REVERB_DECAY_HFRATIO,       env.getDecayHFRatio());
   1.695 -           EFX10.alEffectf(reverbFx, EFX10.AL_REVERB_REFLECTIONS_GAIN,    env.getReflectGain());
   1.696 -           EFX10.alEffectf(reverbFx, EFX10.AL_REVERB_REFLECTIONS_DELAY,   env.getReflectDelay());
   1.697 -           EFX10.alEffectf(reverbFx, EFX10.AL_REVERB_LATE_REVERB_GAIN,    env.getLateReverbGain());
   1.698 -           EFX10.alEffectf(reverbFx, EFX10.AL_REVERB_LATE_REVERB_DELAY,   env.getLateReverbDelay());
   1.699 -           EFX10.alEffectf(reverbFx, EFX10.AL_REVERB_AIR_ABSORPTION_GAINHF, env.getAirAbsorbGainHf());
   1.700 -           EFX10.alEffectf(reverbFx, EFX10.AL_REVERB_ROOM_ROLLOFF_FACTOR, env.getRoomRolloffFactor());
   1.701 -
   1.702 -           // attach effect to slot
   1.703 -           EFX10.alAuxiliaryEffectSloti(reverbFxSlot, EFX10.AL_EFFECTSLOT_EFFECT, reverbFx);
   1.704 -       }
   1.705 -   }
   1.706 -
   1.707 -   private boolean fillBuffer(AudioStream stream, int id){
   1.708 -       int size = 0;
   1.709 -       int result;
   1.710 -
   1.711 -       while (size < arrayBuf.length){
   1.712 -           result = stream.readSamples(arrayBuf, size, arrayBuf.length - size);
   1.713 -
   1.714 -           if(result > 0){
   1.715 -               size += result;
   1.716 -           }else{
   1.717 -               break;
   1.718 -           }
   1.719 -       }
   1.720 -
   1.721 -       if(size == 0)
   1.722 -           return false;
   1.723 -
   1.724 -       nativeBuf.clear();
   1.725 -       nativeBuf.put(arrayBuf, 0, size);
   1.726 -       nativeBuf.flip();
   1.727 -
   1.728 -       alBufferData(id, convertFormat(stream), nativeBuf, stream.getSampleRate());
   1.729 -
   1.730 -       return true;
   1.731 -   }
   1.732 -
   1.733 -   private boolean fillStreamingSource(int sourceId, AudioStream stream){
   1.734 -       if (!stream.isOpen())
   1.735 -           return false;
   1.736 -
   1.737 -       boolean active = true;
   1.738 -       int processed = alGetSourcei(sourceId, AL_BUFFERS_PROCESSED);
   1.739 -
   1.740 -//       while((processed--) != 0){
   1.741 -       if (processed > 0){
   1.742 -           int buffer;
   1.743 -
   1.744 -           ib.position(0).limit(1);
   1.745 -           alSourceUnqueueBuffers(sourceId, ib);
   1.746 -           buffer = ib.get(0);
   1.747 -
   1.748 -           active = fillBuffer(stream, buffer);
   1.749 -
   1.750 -           ib.position(0).limit(1);
   1.751 -           ib.put(0, buffer);
   1.752 -           alSourceQueueBuffers(sourceId, ib);
   1.753 -       }
   1.754 -
   1.755 -       if (!active && stream.isOpen())
   1.756 -           stream.close();
   1.757 -       
   1.758 -       return active;
   1.759 -   }
   1.760 -
   1.761 -   private boolean attachStreamToSource(int sourceId, AudioStream stream){
   1.762 -       boolean active = true;
   1.763 -       for (int id : stream.getIds()){
   1.764 -           active = fillBuffer(stream, id);
   1.765 -           ib.position(0).limit(1);
   1.766 -           ib.put(id).flip();
   1.767 -           alSourceQueueBuffers(sourceId, ib);
   1.768 -       }
   1.769 -       return active;
   1.770 -   }
   1.771 -
   1.772 -   private boolean attachBufferToSource(int sourceId, AudioBuffer buffer){
   1.773 -       alSourcei(sourceId, AL_BUFFER, buffer.getId());
   1.774 -       return true;
   1.775 -   }
   1.776 -
   1.777 -   private boolean attachAudioToSource(int sourceId, AudioData data){
   1.778 -       if (data instanceof AudioBuffer){
   1.779 -           return attachBufferToSource(sourceId, (AudioBuffer) data);
   1.780 -       }else if (data instanceof AudioStream){
   1.781 -           return attachStreamToSource(sourceId, (AudioStream) data);
   1.782 -       }
   1.783 -       throw new UnsupportedOperationException();
   1.784 -   }
   1.785 -
   1.786 -   private void clearChannel(int index){
   1.787 -       // make room at this channel
   1.788 -       if (chanSrcs[index] != null){
   1.789 -           AudioNode src = chanSrcs[index];
   1.790 -
   1.791 -           int sourceId = channels[index];
   1.792 -           alSourceStop(sourceId);
   1.793 -
   1.794 -           if (src.getAudioData() instanceof AudioStream){
   1.795 -               AudioStream str = (AudioStream) src.getAudioData();
   1.796 -               ib.position(0).limit(STREAMING_BUFFER_COUNT);
   1.797 -               ib.put(str.getIds()).flip();
   1.798 -               alSourceUnqueueBuffers(sourceId, ib);
   1.799 -           }else if (src.getAudioData() instanceof AudioBuffer){
   1.800 -               alSourcei(sourceId, AL_BUFFER, 0);
   1.801 -           }
   1.802 -
   1.803 -           if (src.getDryFilter() != null){
   1.804 -               // detach filter
   1.805 -               alSourcei(sourceId, EFX10.AL_DIRECT_FILTER, EFX10.AL_FILTER_NULL);
   1.806 -           }
   1.807 -           if (src.isPositional()){
   1.808 -               AudioNode pas = (AudioNode) src;
   1.809 -               if (pas.isReverbEnabled()) {
   1.810 -                   AL11.alSource3i(sourceId, EFX10.AL_AUXILIARY_SEND_FILTER, 0, 0, EFX10.AL_FILTER_NULL);
   1.811 -               }
   1.812 -           }
   1.813 -
   1.814 -           chanSrcs[index] = null;
   1.815 -       }
   1.816 -   }
   1.817 -
   1.818 -   public void update(float tpf){
   1.819 -	   //ByteBuffer test = BufferUtils.createByteBuffer(1);
   1.820 -	   //AurellemTransport.getAuxSamples(AL.getDevice(), test);
   1.821 -   }
   1.822 -
   1.823 -   Vector<Byte> fullWaveData1 = new Vector<Byte>();
   1.824 -   Vector<Byte> fullWaveData2 = new Vector<Byte>();
   1.825 -  
   1.826 -   public void updateInThread(float tpf){
   1.827 -       if (audioDisabled)
   1.828 -           return;
   1.829 -       
   1.830 -       step();
   1.831 -       ByteBuffer test = BufferUtils.createByteBuffer(4096);
   1.832 -	   test.clear();
   1.833 -       this.getMainSamples(test);
   1.834 -       byte[] waveData = new byte[4096];
   1.835 -       test.get(waveData, 0, 4096);
   1.836 -       //System.out.println("J DATA:");
   1.837 -       /*for (int j = 0; j < 1; j++){
   1.838 -    	   for(int i = 64 * j; i < (64*j) + 64; i++){
   1.839 -    		   System.out.print(waveData[i]);
   1.840 -    	   }
   1.841 -    	   System.out.println();
   1.842 -       }*/
   1.843 -       
   1.844 -       ByteBuffer test2 = BufferUtils.createByteBuffer(4096);
   1.845 -	   test2.clear();
   1.846 -       this.getAuxSamples(test2);
   1.847 -       byte[] waveData2 = new byte[4096];
   1.848 -       test2.get(waveData2, 0, 4096);
   1.849 -       //System.out.print("wave1:");
   1.850 -       //for (int j = 0; j< 32; j++){
   1.851 -    //	   System.out.print(waveData[j]+",");
   1.852 -      // }
   1.853 -       //System.out.println();
   1.854 -       //System.out.print("wave2:");
   1.855 -      // for (int j = 0; j< 4096; j++){
   1.856 -    	//   if (waveData2[j] != 0){
   1.857 -    	//	   System.out.println("fucked at : " + j);
   1.858 -    	 //  }
   1.859 -    	
   1.860 -    	  /* System.out.print(waveData2[j]+",");
   1.861 -    	   if (0 == (j % 64)){System.out.println();}*/
   1.862 -       //}
   1.863 -       //System.out.println();
   1.864 -       
   1.865 -       for (byte b : waveData){
   1.866 -    	   this.fullWaveData1.add(b);
   1.867 -       }
   1.868 -       
   1.869 -       for (byte b : waveData2){
   1.870 -    	   this.fullWaveData2.add(b);
   1.871 -       }
   1.872 -       
   1.873 -       
   1.874 -       for (int i = 0; i < channels.length; i++){
   1.875 -           AudioNode src = chanSrcs[i];
   1.876 -           if (src == null)
   1.877 -               continue;
   1.878 -
   1.879 -           int sourceId = channels[i];
   1.880 -
   1.881 -           // is the source bound to this channel
   1.882 -           // if false, it's an instanced playback
   1.883 -           boolean boundSource = i == src.getChannel();
   1.884 -
   1.885 -           // source's data is streaming
   1.886 -           boolean streaming = src.getAudioData() instanceof AudioStream;
   1.887 -
   1.888 -           // only buffered sources can be bound
   1.889 -           assert (boundSource && streaming) || (!streaming);
   1.890 -
   1.891 -           int state = alGetSourcei(sourceId, AL_SOURCE_STATE);
   1.892 -           boolean wantPlaying = src.getStatus() == Status.Playing;
   1.893 -           boolean stopped = state == AL_STOPPED;
   1.894 -
   1.895 -           if (streaming && wantPlaying){
   1.896 -               AudioStream stream = (AudioStream) src.getAudioData();
   1.897 -               if (stream.isOpen()){
   1.898 -                   fillStreamingSource(sourceId, stream);
   1.899 -                   if (stopped)
   1.900 -                       alSourcePlay(sourceId);
   1.901 -                   
   1.902 -               }else{
   1.903 -                   if (stopped){
   1.904 -                       // became inactive
   1.905 -                       src.setStatus(Status.Stopped);
   1.906 -                       src.setChannel(-1);
   1.907 -                       clearChannel(i);
   1.908 -                       freeChannel(i);
   1.909 -
   1.910 -                       // And free the audio since it cannot be
   1.911 -                       // played again anyway.
   1.912 -                       deleteAudioData(stream);
   1.913 -                   }
   1.914 -               }
   1.915 -           }else if (!streaming){
   1.916 -               boolean paused = state == AL_PAUSED;
   1.917 -
   1.918 -               // make sure OAL pause state & source state coincide
   1.919 -               assert (src.getStatus() == Status.Paused && paused) || (!paused);
   1.920 -
   1.921 -               if (stopped){
   1.922 -                   if (boundSource){
   1.923 -                       src.setStatus(Status.Stopped);
   1.924 -                       src.setChannel(-1);
   1.925 -                   }
   1.926 -                   clearChannel(i);
   1.927 -                   freeChannel(i);  
   1.928 -               }
   1.929 -           }
   1.930 -       }
   1.931 -   }
   1.932 -
   1.933 -   public void setListener(Listener listener) {
   1.934 -       checkDead();
   1.935 -       synchronized (threadLock){
   1.936 -           while (!threadLock.get()){
   1.937 -               try {
   1.938 -                   threadLock.wait();
   1.939 -               } catch (InterruptedException ex) {
   1.940 -               }
   1.941 -           }
   1.942 -           if (audioDisabled)
   1.943 -               return;
   1.944 -
   1.945 -           if (this.listener != null){
   1.946 -               // previous listener no longer associated with current
   1.947 -               // renderer
   1.948 -               this.listener.setRenderer(null);
   1.949 -           }
   1.950 -           
   1.951 -           this.listener = listener;
   1.952 -           this.listener.setRenderer(this);
   1.953 -           setListenerParams(listener);
   1.954 -       }
   1.955 -   }
   1.956 -
   1.957 -   public void playSourceInstance(AudioNode src){
   1.958 -       checkDead();
   1.959 -       synchronized (threadLock){
   1.960 -           while (!threadLock.get()){
   1.961 -               try {
   1.962 -                   threadLock.wait();
   1.963 -               } catch (InterruptedException ex) {
   1.964 -               }
   1.965 -           }
   1.966 -           if (audioDisabled)
   1.967 -               return;
   1.968 -           
   1.969 -           if (src.getAudioData() instanceof AudioStream)
   1.970 -               throw new UnsupportedOperationException(
   1.971 -                       "Cannot play instances " +
   1.972 -                       "of audio streams. Use playSource() instead.");
   1.973 -
   1.974 -           if (src.getAudioData().isUpdateNeeded()){
   1.975 -               updateAudioData(src.getAudioData());
   1.976 -           }
   1.977 -
   1.978 -           // create a new index for an audio-channel
   1.979 -           int index = newChannel();
   1.980 -           if (index == -1)
   1.981 -               return;
   1.982 -
   1.983 -           int sourceId = channels[index];
   1.984 -
   1.985 -           clearChannel(index);
   1.986 -
   1.987 -           // set parameters, like position and max distance
   1.988 -           setSourceParams(sourceId, src, true);
   1.989 -           attachAudioToSource(sourceId, src.getAudioData());
   1.990 -           chanSrcs[index] = src;
   1.991 -
   1.992 -           // play the channel
   1.993 -           alSourcePlay(sourceId);
   1.994 -       }
   1.995 -   }
   1.996 -
   1.997 -   
   1.998 -   public void playSource(AudioNode src) {
   1.999 -       checkDead();
  1.1000 -       synchronized (threadLock){
  1.1001 -           while (!threadLock.get()){
  1.1002 -               try {
  1.1003 -                   threadLock.wait();
  1.1004 -               } catch (InterruptedException ex) {
  1.1005 -               }
  1.1006 -           }
  1.1007 -           if (audioDisabled)
  1.1008 -               return;
  1.1009 -
  1.1010 -           //assert src.getStatus() == Status.Stopped || src.getChannel() == -1;
  1.1011 -
  1.1012 -           if (src.getStatus() == Status.Playing){
  1.1013 -               return;
  1.1014 -           }else if (src.getStatus() == Status.Stopped){
  1.1015 -
  1.1016 -               // allocate channel to this source
  1.1017 -               int index = newChannel();
  1.1018 -               if (index == -1) {
  1.1019 -                   logger.log(Level.WARNING, "No channel available to play {0}", src);
  1.1020 -                   return;
  1.1021 -               }
  1.1022 -               clearChannel(index);
  1.1023 -               src.setChannel(index);
  1.1024 -
  1.1025 -               AudioData data = src.getAudioData();
  1.1026 -               if (data.isUpdateNeeded())
  1.1027 -                   updateAudioData(data);
  1.1028 -
  1.1029 -               chanSrcs[index] = src;
  1.1030 -               setSourceParams(channels[index], src, false);
  1.1031 -               attachAudioToSource(channels[index], data);
  1.1032 -           }
  1.1033 -
  1.1034 -           alSourcePlay(channels[src.getChannel()]);
  1.1035 -           src.setStatus(Status.Playing);
  1.1036 -       }
  1.1037 -   }
  1.1038 -
  1.1039 -   
  1.1040 -   public void pauseSource(AudioNode src) {
  1.1041 -       checkDead();
  1.1042 -       synchronized (threadLock){
  1.1043 -           while (!threadLock.get()){
  1.1044 -               try {
  1.1045 -                   threadLock.wait();
  1.1046 -               } catch (InterruptedException ex) {
  1.1047 -               }
  1.1048 -           }
  1.1049 -           if (audioDisabled)
  1.1050 -               return;
  1.1051 -           
  1.1052 -           if (src.getStatus() == Status.Playing){
  1.1053 -               assert src.getChannel() != -1;
  1.1054 -
  1.1055 -               alSourcePause(channels[src.getChannel()]);
  1.1056 -               src.setStatus(Status.Paused);
  1.1057 -           }
  1.1058 -       }
  1.1059 -   }
  1.1060 -
  1.1061 -   
  1.1062 -   public void stopSource(AudioNode src) {
  1.1063 -       synchronized (threadLock){
  1.1064 -           while (!threadLock.get()){
  1.1065 -               try {
  1.1066 -                   threadLock.wait();
  1.1067 -               } catch (InterruptedException ex) {
  1.1068 -               }
  1.1069 -           }
  1.1070 -           if (audioDisabled)
  1.1071 -               return;
  1.1072 -           
  1.1073 -           if (src.getStatus() != Status.Stopped){
  1.1074 -               int chan = src.getChannel();
  1.1075 -               assert chan != -1; // if it's not stopped, must have id
  1.1076 -
  1.1077 -               src.setStatus(Status.Stopped);
  1.1078 -               src.setChannel(-1);
  1.1079 -               clearChannel(chan);
  1.1080 -               freeChannel(chan);
  1.1081 -               
  1.1082 -               if (src.getAudioData() instanceof AudioStream) {
  1.1083 -                   
  1.1084 -                   AudioStream stream = (AudioStream)src.getAudioData();
  1.1085 -                   if (stream.isOpen()) {
  1.1086 -                       stream.close();
  1.1087 -                   }
  1.1088 -               
  1.1089 -                   // And free the audio since it cannot be
  1.1090 -                   // played again anyway.
  1.1091 -                   deleteAudioData(src.getAudioData());
  1.1092 -               }                    
  1.1093 -           }
  1.1094 -       }
  1.1095 -   }
  1.1096 -
  1.1097 -   private int convertFormat(AudioData ad){
  1.1098 -       switch (ad.getBitsPerSample()){
  1.1099 -           case 8:
  1.1100 -               if (ad.getChannels() == 1)
  1.1101 -                   return AL_FORMAT_MONO8;
  1.1102 -               else if (ad.getChannels() == 2)
  1.1103 -                   return AL_FORMAT_STEREO8;
  1.1104 -
  1.1105 -               break;
  1.1106 -           case 16:
  1.1107 -               if (ad.getChannels() == 1)
  1.1108 -                   return AL_FORMAT_MONO16;
  1.1109 -               else
  1.1110 -                   return AL_FORMAT_STEREO16;
  1.1111 -       }
  1.1112 -       throw new UnsupportedOperationException("Unsupported channels/bits combination: "+
  1.1113 -                                               "bits="+ad.getBitsPerSample()+", channels="+ad.getChannels());
  1.1114 -   }
  1.1115 -
  1.1116 -   private void updateAudioBuffer(AudioBuffer ab){
  1.1117 -       int id = ab.getId();
  1.1118 -       if (ab.getId() == -1){
  1.1119 -           ib.position(0).limit(1);
  1.1120 -           alGenBuffers(ib);
  1.1121 -           id = ib.get(0);
  1.1122 -           ab.setId(id);
  1.1123 -       }
  1.1124 -
  1.1125 -       ab.getData().clear();
  1.1126 -       alBufferData(id, convertFormat(ab), ab.getData(), ab.getSampleRate());
  1.1127 -       ab.clearUpdateNeeded();
  1.1128 -   }
  1.1129 -
  1.1130 -   private void updateAudioStream(AudioStream as){
  1.1131 -       if (as.getIds() != null){
  1.1132 -           deleteAudioData(as);
  1.1133 -       }
  1.1134 -
  1.1135 -       int[] ids = new int[STREAMING_BUFFER_COUNT];
  1.1136 -       ib.position(0).limit(STREAMING_BUFFER_COUNT);
  1.1137 -       alGenBuffers(ib);
  1.1138 -       ib.position(0).limit(STREAMING_BUFFER_COUNT);        
  1.1139 -       ib.get(ids);
  1.1140 -       
  1.1141 -       as.setIds(ids);
  1.1142 -       as.clearUpdateNeeded();
  1.1143 -   }
  1.1144 -
  1.1145 -   private void updateAudioData(AudioData ad){
  1.1146 -       if (ad instanceof AudioBuffer){
  1.1147 -           updateAudioBuffer((AudioBuffer) ad);
  1.1148 -       }else if (ad instanceof AudioStream){
  1.1149 -           updateAudioStream((AudioStream) ad);
  1.1150 -       }
  1.1151 -   }
  1.1152 -
  1.1153 -   public void deleteAudioData(AudioData ad){
  1.1154 -       synchronized (threadLock){
  1.1155 -           while (!threadLock.get()){
  1.1156 -               try {
  1.1157 -                   threadLock.wait();
  1.1158 -               } catch (InterruptedException ex) {
  1.1159 -               }
  1.1160 -           }
  1.1161 -           if (audioDisabled)
  1.1162 -               return;
  1.1163 -       
  1.1164 -           if (ad instanceof AudioBuffer){
  1.1165 -               AudioBuffer ab = (AudioBuffer) ad;
  1.1166 -               int id = ab.getId();
  1.1167 -               if (id != -1){
  1.1168 -                   ib.put(0,id);
  1.1169 -                   ib.position(0).limit(1);
  1.1170 -                   alDeleteBuffers(ib);
  1.1171 -                   ab.resetObject();
  1.1172 -               }
  1.1173 -           }else if (ad instanceof AudioStream){
  1.1174 -               AudioStream as = (AudioStream) ad;
  1.1175 -               int[] ids = as.getIds();
  1.1176 -               if (ids != null){
  1.1177 -                   ib.clear();
  1.1178 -                   ib.put(ids).flip();
  1.1179 -                   alDeleteBuffers(ib);
  1.1180 -                   as.resetObject();
  1.1181 -               }
  1.1182 -           }
  1.1183 -       }            
  1.1184 -   }
  1.1185 -
  1.1186 -}
     2.1 --- a/cleanup-message.txt	Tue Oct 25 13:16:27 2011 -0700
     2.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.3 @@ -1,100 +0,0 @@
     2.4 -My name is Robert McIntyre. I am seeking help packaging some changes
     2.5 -I've made to open-al.
     2.6 -
     2.7 -* tl;dr how do I distribute changes to open-al which involve adding a
     2.8 -  new device?
     2.9 -
    2.10 -* Background / Motivation
    2.11 -
    2.12 -I'm working on an AI simulation involving multiple listeners, where
    2.13 -each listener is a separate AI entity.  Since each AI entity can move
    2.14 -independently, I needed to add multiple listener functionality to
    2.15 -open-al. Furthermore, my entire simulation allows time to dilate
    2.16 -depending on how hard the entities are collectively "thinking," so
    2.17 -that the entities can keep up with the simulation.  Therefore, I
    2.18 -needed to have a system that renders sound on-demand instead of trying
    2.19 -to render in real time as open-al does. 
    2.20 -
    2.21 -I don't need any of the more advanced effects, just 3D positioning,
    2.22 -and I'm only using open-al from jMonkeyEngine3 that uses the LWJGL
    2.23 -bindings that importantly only allow access to one and only one
    2.24 -context.
    2.25 -
    2.26 -Under these constraints, I made a new device which renders sound in
    2.27 -small, user-defined increments.  It must be explicitly told to render
    2.28 -sound or it won't do anything.  It maintains a separate "auxiliary
    2.29 -context" for every additional listener, and syncs the sources from the
    2.30 -LWJGL context whenever it is about to render samples.  I've tested it
    2.31 -and it works quite well for my purposes.  So far, I've gotten 1,000
    2.32 -separate listeners to work in a single simulation easily.
    2.33 -
    2.34 -The code is here: 
    2.35 -http://aurellem.localhost/audio-send/html/send.html
    2.36 -No criticism is too harsh! 
    2.37 -
    2.38 -Note that the java JNI bindings that are part of the device code right
    2.39 -now would be moved to a separate file the the same way that LWJGL does
    2.40 -it. I left them there for now to show how the device might be used.
    2.41 -
    2.42 -Although I made this for my own AI work, it's ideal for recording
    2.43 -perfect audio from a video game to create trailers/demos, since the
    2.44 -computer doesn't have to try to record the sound in real time.  This
    2.45 -device could be used to record audio in any system that wraps open-al
    2.46 -and only exposes one context, which is what many wrappers do.
    2.47 -
    2.48 -
    2.49 -* Actual Question
    2.50 -
    2.51 -My question is about packaging --- how do you recommend I distribute
    2.52 -my new device?  I got it to work by just grafting it on the open-al's
    2.53 -primitive object system, but this requires quite a few changes to main
    2.54 -open-al source files, and as far as I can tell requires me to
    2.55 -recompile open-al against my new device. 
    2.56 -
    2.57 -I also don't want the user to be able to hide my devices presence
    2.58 -using their ~/.alsoftrc file, since that gets in the way of easy
    2.59 -recording when the system is wrapped several layers deep, and they've
    2.60 -already implicitly requested my device anyway by using my code in the
    2.61 -first place.
    2.62 -
    2.63 -The options I have thought of so far are:
    2.64 -
    2.65 -1.) Create my own C-artifact, compiled against open-al, which somehow
    2.66 -"hooks in" my device to open-al and forces open-al to use it to the
    2.67 -exclusion of all other devices.  This new artifact would have bindings
    2.68 -for java, etc.  I don't know how to do this, since there doesn't seem
    2.69 -to be any way to access the list of devices in Alc/ALc.c for example.
    2.70 -In order to add a new device to open-al I had to modify 5 separate
    2.71 -files, documented here:
    2.72 -
    2.73 -http://aurellem.localhost/audio-send/html/add-new-device.html
    2.74 -
    2.75 -and there doesn't seem to be a way to get the same effect
    2.76 -programmatically.
    2.77 -
    2.78 -2.) Strip down open-al to a minimal version that only has my device
    2.79 -and deal with selecting the right open-al library at a higher level,
    2.80 -depending on whether the user wants to record sound or actually hear
    2.81 -it.  I don't like this because I can't easily benefit from
    2.82 -improvements in the main open-al distribution. It also would involve
    2.83 -more significant modification to jMonkeyEngine3's logic which selects
    2.84 -the appropriate C-artifact at runtime.
    2.85 -
    2.86 -3.) Get this new device added to open-al, and provide a java wrapper
    2.87 -for it in a separate artifact. Problem here is that this device does
    2.88 -not have the same semantics as the other devices --- it must be told
    2.89 -to render sound, doesn't support multiple user-created contexts, and
    2.90 -it exposes extra functions for retrieving the rendered sounds. It also
    2.91 -might be too "niche" for open-al proper.
    2.92 -
    2.93 -4.) Maybe abandon the device metaphor and use something better suited
    2.94 -to my problem that /can/ be done as in (1)?
    2.95 -
    2.96 -
    2.97 -I'm sure someone here knows enough about open-al's devices to give me
    2.98 -a better solution than these 4!  All help would be most appreciated.
    2.99 -
   2.100 -sincerely,
   2.101 ---Robert McIntyre
   2.102 -
   2.103 -
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/org/cleanup-message.txt	Tue Oct 25 13:17:37 2011 -0700
     3.3 @@ -0,0 +1,100 @@
     3.4 +My name is Robert McIntyre. I am seeking help packaging some changes
     3.5 +I've made to open-al.
     3.6 +
     3.7 +* tl;dr how do I distribute changes to open-al which involve adding a
     3.8 +  new device?
     3.9 +
    3.10 +* Background / Motivation
    3.11 +
    3.12 +I'm working on an AI simulation involving multiple listeners, where
    3.13 +each listener is a separate AI entity.  Since each AI entity can move
    3.14 +independently, I needed to add multiple listener functionality to
    3.15 +open-al. Furthermore, my entire simulation allows time to dilate
    3.16 +depending on how hard the entities are collectively "thinking," so
    3.17 +that the entities can keep up with the simulation.  Therefore, I
    3.18 +needed to have a system that renders sound on-demand instead of trying
    3.19 +to render in real time as open-al does. 
    3.20 +
    3.21 +I don't need any of the more advanced effects, just 3D positioning,
    3.22 +and I'm only using open-al from jMonkeyEngine3 that uses the LWJGL
    3.23 +bindings that importantly only allow access to one and only one
    3.24 +context.
    3.25 +
    3.26 +Under these constraints, I made a new device which renders sound in
    3.27 +small, user-defined increments.  It must be explicitly told to render
    3.28 +sound or it won't do anything.  It maintains a separate "auxiliary
    3.29 +context" for every additional listener, and syncs the sources from the
    3.30 +LWJGL context whenever it is about to render samples.  I've tested it
    3.31 +and it works quite well for my purposes.  So far, I've gotten 1,000
    3.32 +separate listeners to work in a single simulation easily.
    3.33 +
    3.34 +The code is here: 
    3.35 +http://aurellem.localhost/audio-send/html/send.html
    3.36 +No criticism is too harsh! 
    3.37 +
    3.38 +Note that the java JNI bindings that are part of the device code right
    3.39 +now would be moved to a separate file the the same way that LWJGL does
    3.40 +it. I left them there for now to show how the device might be used.
    3.41 +
    3.42 +Although I made this for my own AI work, it's ideal for recording
    3.43 +perfect audio from a video game to create trailers/demos, since the
    3.44 +computer doesn't have to try to record the sound in real time.  This
    3.45 +device could be used to record audio in any system that wraps open-al
    3.46 +and only exposes one context, which is what many wrappers do.
    3.47 +
    3.48 +
    3.49 +* Actual Question
    3.50 +
    3.51 +My question is about packaging --- how do you recommend I distribute
    3.52 +my new device?  I got it to work by just grafting it on the open-al's
    3.53 +primitive object system, but this requires quite a few changes to main
    3.54 +open-al source files, and as far as I can tell requires me to
    3.55 +recompile open-al against my new device. 
    3.56 +
    3.57 +I also don't want the user to be able to hide my devices presence
    3.58 +using their ~/.alsoftrc file, since that gets in the way of easy
    3.59 +recording when the system is wrapped several layers deep, and they've
    3.60 +already implicitly requested my device anyway by using my code in the
    3.61 +first place.
    3.62 +
    3.63 +The options I have thought of so far are:
    3.64 +
    3.65 +1.) Create my own C-artifact, compiled against open-al, which somehow
    3.66 +"hooks in" my device to open-al and forces open-al to use it to the
    3.67 +exclusion of all other devices.  This new artifact would have bindings
    3.68 +for java, etc.  I don't know how to do this, since there doesn't seem
    3.69 +to be any way to access the list of devices in Alc/ALc.c for example.
    3.70 +In order to add a new device to open-al I had to modify 5 separate
    3.71 +files, documented here:
    3.72 +
    3.73 +http://aurellem.localhost/audio-send/html/add-new-device.html
    3.74 +
    3.75 +and there doesn't seem to be a way to get the same effect
    3.76 +programmatically.
    3.77 +
    3.78 +2.) Strip down open-al to a minimal version that only has my device
    3.79 +and deal with selecting the right open-al library at a higher level,
    3.80 +depending on whether the user wants to record sound or actually hear
    3.81 +it.  I don't like this because I can't easily benefit from
    3.82 +improvements in the main open-al distribution. It also would involve
    3.83 +more significant modification to jMonkeyEngine3's logic which selects
    3.84 +the appropriate C-artifact at runtime.
    3.85 +
    3.86 +3.) Get this new device added to open-al, and provide a java wrapper
    3.87 +for it in a separate artifact. Problem here is that this device does
    3.88 +not have the same semantics as the other devices --- it must be told
    3.89 +to render sound, doesn't support multiple user-created contexts, and
    3.90 +it exposes extra functions for retrieving the rendered sounds. It also
    3.91 +might be too "niche" for open-al proper.
    3.92 +
    3.93 +4.) Maybe abandon the device metaphor and use something better suited
    3.94 +to my problem that /can/ be done as in (1)?
    3.95 +
    3.96 +
    3.97 +I'm sure someone here knows enough about open-al's devices to give me
    3.98 +a better solution than these 4!  All help would be most appreciated.
    3.99 +
   3.100 +sincerely,
   3.101 +--Robert McIntyre
   3.102 +
   3.103 +