import java.io.IOException;
import javax.sound.sampled.UnsupportedAudioFileException;
import net.beadsproject.beads.analysis.FeatureTrack;
import net.beadsproject.beads.core.AudioContext;
import net.beadsproject.beads.core.Bead;
import net.beadsproject.beads.data.Sample;
import net.beadsproject.beads.ugens.Clock;
import net.beadsproject.beads.ugens.Recorder;
import net.beadsproject.beads.ugens.SamplePlayer;

public class LargeFileAccessUseCase {

	public static void main(String[] args) throws Exception {
		
		/**
		 * Demo use case by Ollie for Ben. Buffering Sample object must handle requests for random playback points.
		 */
		
		String filename = "audio/1234.aif";
		//open a sample
		final Sample s = null;
		
		/*
		s = new Sample(); //we no longer need to specify the file at instantiation, otherwise it would just load completely
		s.setBufferingRegime(Sample.BufferingRegime.TIMED); 	//alternatives are TIMED and TOTAL (default)
		s.setLookAhead(100); //set how many milliseconds from last loaded point to look ahead
		s.setLookBack(10); //set how many milliseconds  from last loaded  point to look back
		s.setMemory(10000f); //set the memory in milliseconds
		s.setBufferMax(10); //set the max space used in MB
		//bear in mind that if we used BufferingRegime.TOTAL, then Sample would behave as it used to -- none of these new settings would mean anything
		s.setFile(filename); //now we set the file
		*/
		final FeatureTrack ft = null;
		/*
		ft = new FeatureTrack(filename, "myTrack"); //feature track works out what file to load given the filename
		//for the moment assume that the feature data is low-res enough that you can load it all up
		//this is a reasonable assumption, but it may be that FeatureTrack needs to do clever buffering like Sample does.
		*/
		
		//now play around - the code below just starts a SamplePlayer running and then occasionally (about every 10s)
		//hops to a new position in the SamplePlayer. The Sample object will not know what is coming next, so it
		//should not crash because the data isn't loaded but instead do something reasonable like return zeros until the
		//it has the data.
		AudioContext ac = new AudioContext();
		final SamplePlayer sp = new SamplePlayer(ac, s);
		ac.out.addInput(sp);
		Clock c = new Clock(ac, 1000f);
		ac.out.addDependent(c);
		c.addMessageListener(new Bead() {
			public void messageReceived(Bead message) {
				if(((Clock)message).isBeat()) {
					if(Math.random() < 0.1f) {
						sp.setPosition(s.getLength() * Math.random()); //occasionally change the position of sp
					}
				}
				System.out.println(ft.getFrameAt(sp.getPosition())); //regularly grab the feature data of the audio at the current pos
			}
		});
		ac.start();
		
		//bonus points... recording
		Sample recording = null;
		Recorder r = null;
		/*
		recording = new Sample();
		recording.setBufferingRegime(Sample.BufferingRegime.TIMED); 	//alternatives are TIMED and TOTAL (default)
		recording.setMemory(0f); //set the memory in milliseconds
		r = new Recorder(ac, recording);
		r.setRecordFile("myRecording.aif"); //Recorder forces sample to keep writing to disk
		*/
		//Alternatively
		/*
		 * r = new Recorder(ac, "myRecording.aif"); //Recorder implicitly sets up the Sample as above.
		 */
		r.addInput(ac.out);
		ac.out.addDependent(r);
		
		
	}
}
