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();
}
}
}