view java/src/uk/ac/qmul/eecs/ccmi/speech/BeadsAudioPlayer.java @ 1:e3935c01cde2 tip

moved license of PdPersistenceManager to the beginning of the file
author Fiore Martin <f.martin@qmul.ac.uk>
date Tue, 08 Jul 2014 19:52:03 +0100
parents 78b7fc5391a2
children
line wrap: on
line source
/*  
 CCmI Editor - A Collaborative Cross-Modal Diagram Editing Tool
  
 Copyright (C) 2011  Queen Mary University of London (http://ccmi.eecs.qmul.ac.uk/)

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/ 

package uk.ac.qmul.eecs.ccmi.speech;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException;


import net.beadsproject.beads.core.AudioContext;
import net.beadsproject.beads.core.Bead;
import net.beadsproject.beads.data.Sample;
import net.beadsproject.beads.ugens.Gain;
import net.beadsproject.beads.ugens.Panner;
import net.beadsproject.beads.ugens.SamplePlayer;

import com.sun.speech.freetts.audio.AudioPlayer;

/**
 * An implementation of {@code AudioPlayer} using the {@code Beads} 
 * library.
 */
public class BeadsAudioPlayer implements AudioPlayer {
	public BeadsAudioPlayer(){
		format = new AudioFormat(8000f, 16, 1, true, true);
		ac = new AudioContext(format);
		volume = 1.0f;
		monitor = new Object();
	}
	
	public BeadsAudioPlayer(float vol, float pan){
		this();
		volume = vol;
		this.pan = pan;
	}
	
	
	@Override
	public void begin(int size) {
		buffer = new byte[size];
		bufferPosition = 0;
		ac = new AudioContext();
	}

	@Override
	public void cancel() {
		
	}

	@Override
	public void close() {
		ac.stop();
	}

	@Override
	public boolean drain() {
		synchronized(monitor){
			if(!finished)
				try {
					monitor.wait();
				} catch (InterruptedException e) {
					throw new RuntimeException(e);
				}
			finished = false;	
		}
		return false;
	}

	@Override
	public boolean end() {
		ByteArrayInputStream stream = new ByteArrayInputStream(buffer);
		AudioInputStream audioStream = new AudioInputStream(stream, format, bufferPosition/format.getFrameSize());
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		Sample sample = null;
		try {
			AudioSystem.write(audioStream, AudioFileFormat.Type.WAVE,out);
			sample = new Sample(new ByteArrayInputStream(out.toByteArray()));
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		} catch (UnsupportedAudioFileException e) {
			e.printStackTrace();
			return false;
		}
		
		SamplePlayer player = new SamplePlayer(ac,sample);
		player.setKillOnEnd(true);
		Gain g = new Gain(ac,1,volume); 
		g.addInput(player);
		final Panner panner = new Panner(ac,pan);
		panner.addInput(g);
		player.setKillListener(new Bead(){
			@Override
			protected void messageReceived(Bead message){
				panner.kill();
				synchronized(monitor){
					finished = true;
					monitor.notify();
				}
			}
		});
		
		/* starts playing the sample */
		ac.out.addInput(panner);
		ac.start();
		return true;
	}

	@Override
	public AudioFormat getAudioFormat() {
		return format;
	}

	@Override
	public long getTime() {
		return -1L;
	}

	@Override
	public float getVolume() {
		return volume;
	}

	@Override
	public void pause() {
		
	}

	@Override
	public void reset() {
		
	}

	@Override
	public void resetTime() {
		
	}

	@Override
	public void resume() {
		
	}

	@Override
	public void setAudioFormat(AudioFormat format) {
		this.format = format;
		ac.setInputAudioFormat(format);
	}

	@Override
	public void setVolume(float vol) {
		volume = vol;
	}
	
	public void setPan(float pan){
		this.pan = pan;
	}
	
	public float getPan(){
		return pan;
	}

	@Override
	public void showMetrics() {
		
	}

	@Override
	public void startFirstSampleTimer() {
		
	}

	@Override
	public boolean write(byte[] audioData) {
		return write(audioData,0,audioData.length);
	}

	@Override
	public boolean write(byte[] audioData, int offset, int size) {
		System.arraycopy(audioData, offset, buffer, bufferPosition, size);
		bufferPosition += size;
		return true;
	}
	
	private byte[] buffer;
	private int bufferPosition;
	private AudioFormat format;
	private float volume;
	private float pan;
	private Object monitor;
	private boolean finished;
	private AudioContext ac;

}