diff java/src/uk/ac/qmul/eecs/ccmi/speech/BeadsAudioPlayer.java @ 0:78b7fc5391a2

first import, outcome of NIME 2014 hackaton
author Fiore Martin <f.martin@qmul.ac.uk>
date Tue, 08 Jul 2014 16:28:59 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/java/src/uk/ac/qmul/eecs/ccmi/speech/BeadsAudioPlayer.java	Tue Jul 08 16:28:59 2014 +0100
@@ -0,0 +1,217 @@
+/*  
+ 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;
+
+}