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

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

The newest version!
package be.tarsos.dsp.example;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.lang.reflect.InvocationTargetException;

import javax.sound.sampled.LineUnavailableException;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
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.AudioEvent;
import be.tarsos.dsp.AudioProcessor;
import be.tarsos.dsp.PitchShifter;
import be.tarsos.dsp.io.jvm.AudioDispatcherFactory;
import be.tarsos.dsp.io.jvm.AudioPlayer;
import be.tarsos.dsp.resample.Resampler;

public class TimeStrechingBasedOnPitchShifting extends JFrame implements TarsosDSPDemo {
	/**
	 * 
	 */
	private static final long serialVersionUID = -7188163235158960778L;
	private final JFileChooser fileChooser;
	private final JSlider factorSlider;
	private final JLabel factorLabel;
	
	private double currentFactor = 1.2;// pitch shift factor
	private AudioDispatcher dispatcher;
	private PitchShifter pitchShifter;
	
	private float[] buffer;
	
	private ChangeListener parameterSettingChangedListener = new ChangeListener(){
@Override
		public void stateChanged(ChangeEvent arg0) {
			currentFactor = factorSlider.getValue() / 100.0;
			factorLabel.setText("Factor " + Math.round(currentFactor * 100) + "%");
			if (TimeStrechingBasedOnPitchShifting.this.dispatcher != null) {				 
				pitchShifter.setPitchShiftFactor((float) currentFactor);
			}
		}}; 
	
	public TimeStrechingBasedOnPitchShifting(){
		this.setLayout(new BorderLayout());
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setTitle("Pitch shifting: change the tempo of your audio.");
		currentFactor = 1.;
		JPanel fileChooserPanel = new JPanel(new BorderLayout());
		fileChooserPanel.setBorder(new TitledBorder("1... Or choose your audio (wav mono)"));
		
		fileChooser = new JFileChooser();
		
		JButton chooseFileButton = new JButton("Choose a file...");
		chooseFileButton.addActionListener(new ActionListener(){
			@Override
			public void actionPerformed(ActionEvent arg0) {
				int returnVal = fileChooser.showOpenDialog(TimeStrechingBasedOnPitchShifting.this);
	            if (returnVal == JFileChooser.APPROVE_OPTION) {
	                File file = fileChooser.getSelectedFile();
	                startFile(file);
	            } else {
	                //canceled
	            }
			}

		
		});
		fileChooserPanel.add(chooseFileButton);
		fileChooser.setLayout(new BoxLayout(fileChooser, BoxLayout.PAGE_AXIS));
		this.add(fileChooserPanel,BorderLayout.NORTH);
		
		JPanel params = new JPanel(new BorderLayout());
		params.setBorder(new TitledBorder("2. Set the algorithm parameters"));
		
		factorSlider = new JSlider(20, 250);
		factorSlider.setValue((int) (currentFactor*100));
		factorSlider.setPaintLabels(true);
		factorSlider.addChangeListener(parameterSettingChangedListener);
		
		JLabel label = new JLabel("Factor 100%");
		label.setText("Factor " + Math.round(currentFactor * 100) + "%");
		label.setToolTipText("The tempo factor in % (100 is no change, 50 is double tempo, 200 half).");
		factorLabel = label;
		params.add(label,BorderLayout.NORTH);
		params.add(factorSlider,BorderLayout.CENTER);
		this.add(params,BorderLayout.CENTER);
	}
	
	private void startFile(File file) {
		final int size = 2048;
		final int overlap = 2048 - 128;
		int samplerate = 44100;
		final AudioDispatcher d = AudioDispatcherFactory.fromPipe(file.getAbsolutePath(), samplerate, size, overlap);
		pitchShifter = new PitchShifter(1.0/currentFactor, samplerate, size, overlap);
		
		d.addAudioProcessor(new AudioProcessor() {
			@Override
			public void processingFinished() {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public boolean process(AudioEvent audioEvent) {
				buffer = audioEvent.getFloatBuffer();
				return true;
			}
		});
		
		d.addAudioProcessor(pitchShifter);
		
		d.addAudioProcessor(new AudioProcessor() {
			Resampler r= new Resampler(false,0.1,4.0);
			@Override
			public void processingFinished() {
			}
			
			@Override
			public boolean process(AudioEvent audioEvent) {
				
				float factor = (float) (currentFactor);
				float[] src = audioEvent.getFloatBuffer();
				float[] out = new float[(int) ((size-overlap) * factor)];
				r.process(factor, src, overlap,size-overlap, false, out, 0, out.length);
				//The size of the output buffer changes (according to factor).
				d.setStepSizeAndOverlap(out.length, 0);
				
				audioEvent.setFloatBuffer(out);
				audioEvent.setOverlap(0);
		
				return true;
			}
		});
		//d.addAudioProcessor(rateTransposer);
		try {
			d.addAudioProcessor(new AudioPlayer(d.getFormat()));
		} catch (LineUnavailableException e) {
			e.printStackTrace();
		}
		d.addAudioProcessor(new AudioProcessor() {
			
			@Override
			public void processingFinished() {
			}
			
			@Override
			public boolean process(AudioEvent audioEvent) {
				d.setStepSizeAndOverlap(size, overlap);
				d.setAudioFloatBuffer(buffer);
				audioEvent.setFloatBuffer(buffer);
				audioEvent.setOverlap(overlap);
				return true;
			}
		});
		dispatcher = d ;
		new Thread(d).start();
		
	}		
	
	public static void main(String... args){
		new TimeStrechingBasedOnPitchShifting().start();
	}

	@Override
	public String name() {
		return "TimeStrechingBasedOnPitchShifting";
	}

	@Override
	public String description() {
		return "Shows how to do time stretching by pitch shifting and resampling";
	}

	@Override
	public void start() {
		try {
			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 TimeStrechingBasedOnPitchShifting();
					frame.pack();
					frame.setSize(400,450);
					frame.setVisible(true);
				}
			});
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy