examples.be.tarsos.dsp.example.constantq.Player 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.constantq;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.File;
import java.io.IOException;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import be.tarsos.dsp.AudioDispatcher;
import be.tarsos.dsp.AudioEvent;
import be.tarsos.dsp.AudioProcessor;
import be.tarsos.dsp.GainProcessor;
import be.tarsos.dsp.io.jvm.AudioDispatcherFactory;
import be.tarsos.dsp.io.jvm.AudioPlayer;
public class Player implements AudioProcessor {
private PropertyChangeSupport support = new PropertyChangeSupport(this);
private PlayerState state;
private File loadedFile;
private GainProcessor gainProcessor;
private AudioPlayer audioPlayer;
private AudioDispatcher dispatcher;
private double durationInSeconds;
private double currentTime;
private double pauzedAt;
private final AudioProcessor processor;
private final int stepSize;
private final int overlap;
private double gain;
public Player(AudioProcessor processor,int stepSize,int overlap){
state = PlayerState.NO_FILE_LOADED;
gain = 1.0;
this.processor = processor;
this.stepSize =stepSize;
this.overlap = overlap;
}
public void setStepSizeAndOverlap(int audioBufferSize,int bufferOverlap){
dispatcher.setStepSizeAndOverlap(audioBufferSize, bufferOverlap);
}
public void load(File file) {
if(state != PlayerState.NO_FILE_LOADED){
eject();
}
loadedFile = file;
AudioFileFormat fileFormat;
try {
fileFormat = AudioSystem.getAudioFileFormat(loadedFile);
} catch (UnsupportedAudioFileException e) {
throw new Error(e);
} catch (IOException e) {
throw new Error(e);
}
AudioFormat format = fileFormat.getFormat();
durationInSeconds = fileFormat.getFrameLength() / format.getFrameRate();
pauzedAt = 0;
currentTime = 0;
setState(PlayerState.FILE_LOADED);
}
public void eject(){
loadedFile = null;
stop();
setState(PlayerState.NO_FILE_LOADED);
}
public void play(){
if(state == PlayerState.NO_FILE_LOADED){
throw new IllegalStateException("Can not play when no file is loaded");
} else if(state == PlayerState.PAUZED) {
play(pauzedAt);
} else {
play(0);
}
}
public void play(double startTime) {
if(state == PlayerState.NO_FILE_LOADED){
throw new IllegalStateException("Can not play when no file is loaded");
} else {
try {
AudioFileFormat fileFormat = AudioSystem.getAudioFileFormat(loadedFile);
AudioFormat format = fileFormat.getFormat();
gainProcessor = new GainProcessor(gain);
audioPlayer = new AudioPlayer(format);
dispatcher = AudioDispatcherFactory.fromFile(loadedFile,stepSize,overlap);
dispatcher.skip(startTime);
dispatcher.addAudioProcessor(this);
dispatcher.addAudioProcessor(processor);
dispatcher.addAudioProcessor(gainProcessor);
dispatcher.addAudioProcessor(audioPlayer);
Thread t = new Thread(dispatcher,"Audio Player Thread");
t.start();
setState(PlayerState.PLAYING);
} catch (UnsupportedAudioFileException e) {
throw new Error(e);
} catch (IOException e) {
throw new Error(e);
} catch (LineUnavailableException e) {
throw new Error(e);
}
}
}
public void pauze(){
pauze(currentTime);
}
public void pauze(double pauzeAt) {
if(state == PlayerState.PLAYING || state == PlayerState.PAUZED){
setState(PlayerState.PAUZED);
dispatcher.stop();
pauzedAt = pauzeAt;
} else {
throw new IllegalStateException("Can not pauze when nothing is playing");
}
}
public void stop(){
if(state == PlayerState.PLAYING || state == PlayerState.PAUZED){
setState(PlayerState.STOPPED);
dispatcher.stop();
} else if(state != PlayerState.STOPPED){
throw new IllegalStateException("Can not stop when nothing is playing");
}
}
public void setGain(double newGain){
gain = newGain;
if(state == PlayerState.PLAYING ){
gainProcessor.setGain(gain);
}
}
public double getDurationInSeconds() {
if(state == PlayerState.NO_FILE_LOADED){
throw new IllegalStateException("No file loaded, unable to determine the duration in seconds");
}
return durationInSeconds;
}
private void setState(PlayerState newState){
PlayerState oldState = state;
state = newState;
support.firePropertyChange("state", oldState, newState);
}
public PlayerState getState() {
return state;
}
public void addPropertyChangeListener(PropertyChangeListener l) {
support.addPropertyChangeListener(l);
}
public void removePropertyChangeListener(PropertyChangeListener l) {
support.removePropertyChangeListener(l);
}
@Override
public boolean process(AudioEvent audioEvent) {
currentTime = audioEvent.getTimeStamp();
return true;
}
@Override
public void processingFinished() {
if(state==PlayerState.PLAYING){
setState(PlayerState.STOPPED);
}
}
public File getLoadedFile(){
return loadedFile;
}
/**
* Defines the state of the audio player.
* @author Joren Six
*/
public static enum PlayerState{
/**
* No file is loaded.
*/
NO_FILE_LOADED,
/**
* A file is loaded and ready to be played.
*/
FILE_LOADED,
/**
* The file is playing
*/
PLAYING,
/**
* Audio play back is paused.
*/
PAUZED,
/**
* Audio play back is stopped.
*/
STOPPED
}
}