import java.io.IOException;
import java.util.Arrays;

import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException;

import net.beadsproject.beads.core.AudioContext;
import net.beadsproject.beads.core.Bead;
import net.beadsproject.beads.core.UGen;
import net.beadsproject.beads.data.Sample;
import net.beadsproject.beads.ugens.Clock;

public class BufferedSampleTestCompare {

	static class BufferedSamplePlayer extends UGen
	{
		Sample bs;
		int frame = 0;
		
		// read one frame at a time from sample? or a whole chunk?
		static final boolean PERFRAME = true; 
		
		public BufferedSamplePlayer(AudioContext ac, Sample bs)
		{
			super(ac,bs.getNumChannels());
			this.bs = bs;	
		}
		
		@Override
		public void calculateBuffer()
		{
			long nFrames = bs.getNumFrames();
			if (nFrames==AudioSystem.NOT_SPECIFIED)
			{
				System.out.println("dude it's an error");
				return;				
			}
			
			if (frame < nFrames)
			{
				if (PERFRAME)
				{
					int from = frame;
					int i = 0;
					int to = (int) Math.min(nFrames,frame+bufferSize);
					float[] data = new float[outs];
					for(;from<to;++from,++i)
					{
						bs.getFrame(from, data);
						for(int ch=0;ch<outs;ch++)
						{
							bufOut[ch][i] = data[ch];
						}
					}
				}
				else
				{				
					bs.getFrames(frame, bufOut);
				}
			}
			
			if ((nFrames - frame) < this.bufferSize)
			{
				for(int ch = 0;ch<this.outs;ch++)
					Arrays.fill(bufOut[ch], (int)(nFrames - frame), this.bufferSize, 0);					
				pause(true);
			}
			else
			{			
				frame += bufOut[0].length;
			}			
		}		
	
	}
	
	static Runtime rt;
	// returns the number of bytes used in the heap
	public static long heapSize()
	{
		return rt.totalMemory()-rt.freeMemory();
	}
	
	public static void printHeapSize(String s)
	{
		System.out.println("mem (" + s + ") = " + heapSize() + " bytes");
	}
	
	static Sample bs1;
	static Sample bs2;	
	
	/**
	 * @param args
	 * @throws UnsupportedAudioFileException 
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException, UnsupportedAudioFileException {
		
		System.out.println("*****************************************");
		System.out.println("This test can be use to compare some buffering params.");
		System.out.println("*****************************************");
		
		rt = Runtime.getRuntime();
		
		AudioContext ac = new AudioContext();
		printHeapSize("After new AC");

		// 
		String[] audiofiles = {"1234.aif","tada.wav","01 Leek.aif","gammaBrosTheme.mp3"};
		String file = audiofiles[3];
		
		bs1 = new Sample("audio/" + file, new Sample.TimedRegime(2000,5000,0,5000,Sample.TimedRegime.Order.ORDERED));	
				
		
		printHeapSize("After Buffered Sample Loaded");
				
		BufferedSamplePlayer bsp = new BufferedSamplePlayer(ac,bs1);
		ac.out.addInput(bsp);
		
		//BufferedSamplePlayer bsp2 = new BufferedSamplePlayer(ac,bs);
		//ac.out.addInput(bsp2);
				
		// gui
		
		printHeapSize("Just before ac.start()");
        Clock cl = new Clock(ac,1000.0f);
        
        cl.addMessageListener(new Bead(){
        	protected void messageReceived(Bead b)
        	{
        		if (((Clock)b).isBeat())
        		{
        			printHeapSize("tick");
        		}
        	}
        });
        
        ac.out.addDependent(cl);
        ac.start();				
	}

}
