package com.haxademic.core.media.audio.playback;

import java.util.ArrayList;
import java.util.HashMap;

import com.haxademic.core.app.P;
import com.haxademic.core.file.FileUtil;
import com.haxademic.core.math.MathUtil;
import com.haxademic.core.media.audio.interphase.Scales;

public class DroneSampler {
	
	protected String audioDir;
	protected String[] audioFiles;
	protected WavPlayer activePlayer;
	protected HashMap<String, DroneSamplerLoop> droneLoops = new HashMap<String, DroneSamplerLoop>();
	protected int soundIndex = -1;
	protected int loopInterval = 15000;
	protected int loopLastStartTime = -loopInterval;
	
	
	public DroneSampler(String audioDir, float loopIntervalSeconds) {
		this.audioDir = audioDir;
		this.loopInterval = P.round(loopIntervalSeconds * 1000); // ms
		P.out("DroneSampler loading sounds from:", this.audioDir);
		loadSounds();
	}
	
	protected void loadSounds() {
		// load audio directory
		ArrayList<String> sounds = FileUtil.getFilesInDirOfTypes(FileUtil.getPath(audioDir), "wav,aif");
		audioFiles = new String[sounds.size()];
		for (int i = 0; i < sounds.size(); i++) {
			audioFiles[i] = sounds.get(i);
			P.out("Loading...", audioFiles[i]);
		}
	}
	
	protected void startNextSound() {
		// go to next index & play next sound!
		soundIndex = (soundIndex < audioFiles.length - 1) ? soundIndex + 1 : 0;	
		String nextSoundId = audioFiles[soundIndex];
		startPlayer(nextSoundId);
	}
	
	protected void releaseOldPlayers() {
		for (HashMap.Entry<String, DroneSamplerLoop> entry : droneLoops.entrySet()) {
			// ramp down old players halfway through interval
			DroneSamplerLoop synthLoop = entry.getValue();
			if(synthLoop.active() && P.p.millis() - synthLoop.startTime() > loopInterval/2) {
				synthLoop.release();
			}
		}
	}
	
	protected void startPlayer(String id) {
		// lazy-init DroneSampler
		if(droneLoops.containsKey(id) == false) {
			droneLoops.put(id, new DroneSamplerLoop(id));
		}
		// get random pitch and play
		int newPitch = Scales.SCALES[0][MathUtil.randRange(0, Scales.SCALES[0].length - 1)];
		droneLoops.get(id).start(newPitch);
	}
	
	protected void checkNextSoundInterval() {
		if(P.p.millis() > loopLastStartTime + loopInterval) {
			loopLastStartTime = P.p.millis();
			startNextSound();
		}
	}
	
	protected void updateLoops() {
		for (HashMap.Entry<String, DroneSamplerLoop> entry : droneLoops.entrySet()) {
			DroneSamplerLoop droneLoop = entry.getValue();
			droneLoop.update();
		}
	}
	
	public void update() {
		releaseOldPlayers();
		checkNextSoundInterval();
		updateLoops();
	}
}
@@ -558,16 +558,8 @@
 rval
- = 15000
 ;%0A%09p
@@ -592,24 +592,8 @@
 Time
- = -loopInterval
 ;%0A%09%0A
@@ -760,66 +760,63 @@
 s%0A%09%09
-P.out(%22DroneSampler loading sounds from:%22, this.audioDir);
+loopLastStartTime = -loopInterval; // start immediately
 %0A%09%09l
@@ -890,16 +890,77 @@
 rectory%0A
+%09%09P.out(%22DroneSampler loading sounds from:%22, this.audioDir);%0A
 %09%09ArrayL
@@ -1210,32 +1210,359 @@
 s%5Bi%5D);%0A%09%09%7D%0A%09%7D%0A%09%0A
+%09protected void startPlayer(String id) %7B%0A%09%09// lazy-init DroneSampler%0A%09%09if(droneLoops.containsKey(id) == false) %7B%0A%09%09%09droneLoops.put(id, new DroneSamplerLoop(id));%0A%09%09%7D%0A%09%09// get random pitch and play%0A%09%09int newPitch = Scales.SCALES%5B0%5D%5BMathUtil.randRange(0, Scales.SCALES%5B0%5D.length - 1)%5D;%0A%09%09droneLoops.get(id).start(newPitch);%0A%09%7D%0A%09%0A
 %09protected void 
@@ -1810,24 +1810,76 @@
 Players() %7B%0A
+%09%09// ramp down old players halfway through interval%0A
 %09%09for (HashM
@@ -1950,61 +1950,8 @@
 ) %7B%0A
-%09%09%09// ramp down old players halfway through interval%0A
 %09%09%09D
@@ -2124,335 +2124,8 @@
 %7D%0A%09%0A
-%09protected void startPlayer(String id) %7B%0A%09%09// lazy-init DroneSampler%0A%09%09if(droneLoops.containsKey(id) == false) %7B%0A%09%09%09droneLoops.put(id, new DroneSamplerLoop(id));%0A%09%09%7D%0A%09%09// get random pitch and play%0A%09%09int newPitch = Scales.SCALES%5B0%5D%5BMathUtil.randRange(0, Scales.SCALES%5B0%5D.length - 1)%5D;%0A%09%09droneLoops.get(id).start(newPitch);%0A%09%7D%0A%09%0A
 %09pro
@@ -2163,16 +2163,53 @@
 val() %7B%0A
+%09%09// is it time to start a new loop?%0A
 %09%09if(P.p
@@ -2315,32 +2315,32 @@
 und();%0A%09%09%7D%0A%09%7D%0A%09%0A
-
 %09protected void 
@@ -2355,16 +2355,43 @@
 ops() %7B%0A
+%09%09// update volume lerping%0A
 %09%09for (H

Update DroneSampler.java