All Downloads are FREE. Search and download functionalities are using the official Maven repository.

examples.be.tarsos.dsp.example.OnsetDetector Maven / Gradle / Ivy

The newest version!
/*
*      _______                       _____   _____ _____  
*     |__   __|                     |  __ \ / ____|  __ \ 
*        | | __ _ _ __ ___  ___  ___| |  | | (___ | |__) |
*        | |/ _` | '__/ __|/ _ \/ __| |  | |\___ \|  ___/ 
*        | | (_| | |  \__ \ (_) \__ \ |__| |____) | |     
*        |_|\__,_|_|  |___/\___/|___/_____/|_____/|_|     
*                                                         
* -------------------------------------------------------------
*
* TarsosDSP is developed by Joren Six at IPEM, University Ghent
*  
* -------------------------------------------------------------
*
*  Info: http://0110.be/tag/TarsosDSP
*  Github: https://github.com/JorenSix/TarsosDSP
*  Releases: http://0110.be/releases/TarsosDSP/
*  
*  TarsosDSP includes modified source code by various authors,
*  for credits and info, see README.
* 
*/


package be.tarsos.dsp.example;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collections;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.Mixer;
import javax.sound.sampled.TargetDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import be.tarsos.dsp.AudioDispatcher;
import be.tarsos.dsp.io.jvm.JVMAudioInputStream;
import be.tarsos.dsp.onsets.ComplexOnsetDetector;
import be.tarsos.dsp.onsets.OnsetHandler;


public class OnsetDetector extends JFrame implements OnsetHandler {

	/**
	 * 
	 */
	private static final long serialVersionUID = 3501426880288136245L;

	private final JTextArea textArea;
	ArrayList clipList;
	int counter;
	double threshold = 0.4;

	public OnsetDetector() {
		this.setLayout(new BorderLayout());
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setTitle("Percussion Detector");
			
		JPanel inputPanel = new InputPanel();
		inputPanel.addPropertyChangeListener("mixer",
				new PropertyChangeListener() {
					@Override
					public void propertyChange(PropertyChangeEvent arg0) {
						try {
							setNewMixer((Mixer) arg0.getNewValue());
						} catch (LineUnavailableException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (UnsupportedAudioFileException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				});
		
			
		JSlider thresholdSlider = initialzeThresholdSlider();		
		JPanel params = new JPanel(new GridLayout(0,1));
		params.setBorder(new TitledBorder("2. Set the algorithm parameters"));
		
		JLabel label = new JLabel("Threshold");
		label.setToolTipText("Peak picking threshold.");
		params.add(label);
		params.add(thresholdSlider);
		
		JPanel paramsAndInputPanel = new JPanel(new GridLayout(1,0));
		paramsAndInputPanel.add(inputPanel);
		paramsAndInputPanel.add(params);
		
		
		textArea = new JTextArea();
		textArea.setEditable(false);
		
		this.add(paramsAndInputPanel,BorderLayout.NORTH);
		this.add(new JScrollPane(textArea),BorderLayout.CENTER);
		
		clipList = new ArrayList();
	
		addClips();
	}
	
	private JSlider initialzeThresholdSlider() {
		JSlider thresholdSlider = new JSlider(0,100);
		thresholdSlider.setValue((int)threshold);
		thresholdSlider.setPaintLabels(true);
		thresholdSlider.setPaintTicks(true);
		thresholdSlider.setMajorTickSpacing(20);
		thresholdSlider.setMinorTickSpacing(10);
		thresholdSlider.setValue(25);
		thresholdSlider.addChangeListener(new ChangeListener(){
			@Override
			public void stateChanged(ChangeEvent e) {
				JSlider source = (JSlider) e.getSource();
			    if (!source.getValueIsAdjusting()) {
			       threshold = source.getValue()/100.0;
			       if(onsetDetector!=null){
			    	   onsetDetector.setThreshold(threshold);
			       }
			    }
			}
		});
		return thresholdSlider;
	}
	
	private void addClips(){
		String[] clips = {"50863__chipfork__Echopop.wav","50771__Digital_System__BOOM_reverb.wav","30667__HardPCM__HardBassDrum001.wav","30669__HardPCM__HardKick002.wav","33637__HerbertBoland__CinematicBoomNorm.wav"};
		for(String clipName : clips){
		
			try {
				final InputStream inputStream = this.getClass().getResourceAsStream("resources/" + clipName);
				AudioInputStream sound;
				sound = AudioSystem.getAudioInputStream(inputStream);
				  // load the sound into memory (a Clip)
			    DataLine.Info info = new DataLine.Info(Clip.class, sound.getFormat());
			    Clip clip = (Clip) AudioSystem.getLine(info);
			    clip.open(sound);
			    clipList.add(clip);
			} catch (UnsupportedAudioFileException e) {
				System.out.println(clipName);
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (LineUnavailableException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}	

		}
	}

	ComplexOnsetDetector onsetDetector;
	AudioDispatcher dispatcher;
	Mixer currentMixer;
	private void setNewMixer(Mixer mixer) throws LineUnavailableException,
			UnsupportedAudioFileException {
		
		if(dispatcher!= null){
			dispatcher.stop();
		}
		currentMixer = mixer;
		
		float sampleRate = 44100;
		int bufferSize = 512;
		int overlap = 0;
		
		textArea.append("Started listening with " + Shared.toLocalString(mixer.getMixerInfo().getName()) + "\n\tparams: " + threshold + "dB\n");

		final AudioFormat format = new AudioFormat(sampleRate, 16, 1, true,
				true);
		final DataLine.Info dataLineInfo = new DataLine.Info(
				TargetDataLine.class, format);
		TargetDataLine line;
		line = (TargetDataLine) mixer.getLine(dataLineInfo);
		final int numberOfSamples = bufferSize;
		line.open(format, numberOfSamples);
		line.start();
		final AudioInputStream stream = new AudioInputStream(line);
		JVMAudioInputStream audioStream = new JVMAudioInputStream(stream);
		// create a new dispatcher
		dispatcher = new AudioDispatcher(audioStream, bufferSize,
				overlap);

		onsetDetector = new ComplexOnsetDetector(bufferSize, threshold,0.07,-60);
		onsetDetector.setHandler(this);
		// add a processor, handle percussion event.
		dispatcher.addAudioProcessor(onsetDetector);

		// run the dispatcher (on a new thread).
		new Thread(dispatcher,"Audio dispatching").start();
	}

	public static void main(String... strings) throws InterruptedException,
			InvocationTargetException {
		SwingUtilities.invokeAndWait(new Runnable() {
			@Override
			public void run() {
				try {
					UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
				} catch (Exception e) {
					//ignore failure to set default look en feel;
				}
				JFrame frame = new OnsetDetector();
				frame.pack();
				frame.setSize(640, 480);
				frame.setVisible(true);
			}
		});
	}

	@Override
	public void handleOnset(double time, double salience) {
		textArea.append("Percussion at:" + time + "\n");
		textArea.setCaretPosition(textArea.getDocument().getLength());
		Clip clip = clipList.get(counter % clipList.size());
		clip.setFramePosition(0);
		clip.start();
		counter++;
		if(counter == clipList.size()){
			Collections.shuffle(clipList);
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy