

import java.io.IOException;

import net.beadsproject.beads.analysis.featureextractors.FFT;
import net.beadsproject.beads.analysis.featureextractors.PeakDetector;
import net.beadsproject.beads.analysis.featureextractors.PowerSpectrum;
import net.beadsproject.beads.analysis.featureextractors.SpectralDifference;
import net.beadsproject.beads.analysis.segmenters.ShortFrameSegmenter;
import net.beadsproject.beads.core.AudioContext;
import net.beadsproject.beads.core.Bead;
import net.beadsproject.beads.data.Sample;
import net.beadsproject.beads.data.SampleManager;
import net.beadsproject.beads.data.buffers.RampBuffer;
import net.beadsproject.beads.ugens.Clicker;
import net.beadsproject.beads.ugens.Gain;
import net.beadsproject.beads.ugens.Recorder;
import net.beadsproject.beads.ugens.SamplePlayer;


public class OnsetDetectionTestTwo {

	public static void main(String[] args) {
		
		String audioDir = "audio";
		final String outputDir = "output/osdt2";
		SampleManager.group("audio", audioDir);
		
		// for(int i = 0; i < SampleManager.getGroup("audio").size(); i++) {
		for(int i = 0; i < 1; i++) {
			//set up audio
			final AudioContext ac = new AudioContext();
			//set up playback
			final Sample samp = SampleManager.fromGroup("audio", i);
			SamplePlayer player = new SamplePlayer(ac, samp);
			Gain sampleTrack = new Gain(ac, samp.getNumChannels());
			sampleTrack.addInput(player);
			ac.out.addInput(sampleTrack);
			
			// more complex onset detection 
			
			//set up the chopper upper
			ShortFrameSegmenter sfs = new ShortFrameSegmenter(ac);
			sfs.addInput(ac.out);
			ac.out.addDependent(sfs);
			int chunkSize = 512;
			sfs.setChunkSize(chunkSize);
			sfs.setHopSize(chunkSize/2);			
			FFT fft = new FFT();
			sfs.addListener(fft);
			PowerSpectrum ps = new PowerSpectrum();
			fft.addListener(ps);
			SpectralDifference sd = new SpectralDifference(ac.getSampleRate());			
			ps.addListener(sd);
			PeakDetector od = new PeakDetector();
			od.setThreshold(0.1f);
			od.setFilter(new RampBuffer().generateBuffer(16));			
			sd.addListener(od);
			
			//set up a listener and click track
			final Gain simpleClickTrack = new Gain(ac, samp.getNumChannels());
			ac.out.addInput(simpleClickTrack);
			od.addMessageListener(new Bead() {
				public void messageReceived(Bead message) {
					simpleClickTrack.addInput(new Clicker(ac, 1f));
					System.out.println("click");
				}
			});			
			//set up recording on the click track
			final Sample clickRecording = new Sample(ac.getAudioFormat(), (long)ac.msToSamples(samp.getLength()));
			Recorder rec = null;
			try {
				rec = new Recorder(ac, clickRecording);
			} catch (Exception e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			rec.addInput(ac.out);
//			rec.addInput(clickTrack);
			ac.out.addDependent(rec);
			rec.setKillListener(new Bead() {
				public void messageReceived(Bead message) {
					try {
						System.out.println("done");
						clickRecording.write(outputDir + "/clicks_for_" + samp.getSimpleFileName() + ".aif");
						ac.stop();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			});
			//start
			ac.runNonRealTime();
		}
	}
	
}
