fiore@0: /*
fiore@0: CCmI Editor - A Collaborative Cross-Modal Diagram Editing Tool
fiore@0:
fiore@0: Copyright (C) 2011 Queen Mary University of London (http://ccmi.eecs.qmul.ac.uk/)
fiore@0:
fiore@0: This program is free software: you can redistribute it and/or modify
fiore@0: it under the terms of the GNU General Public License as published by
fiore@0: the Free Software Foundation, either version 3 of the License, or
fiore@0: (at your option) any later version.
fiore@0:
fiore@0: This program is distributed in the hope that it will be useful,
fiore@0: but WITHOUT ANY WARRANTY; without even the implied warranty of
fiore@0: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
fiore@0: GNU General Public License for more details.
fiore@0:
fiore@0: You should have received a copy of the GNU General Public License
fiore@0: along with this program. If not, see .
fiore@0: */
fiore@0:
fiore@0: package uk.ac.qmul.eecs.ccmi.sound;
fiore@0:
fiore@0: import java.io.InputStream;
fiore@6: import java.util.EnumMap;
fiore@0: import java.util.Map;
fiore@0:
fiore@0: import net.beadsproject.beads.core.AudioContext;
fiore@0: import net.beadsproject.beads.core.Bead;
fiore@0: import net.beadsproject.beads.core.UGen;
fiore@0: import net.beadsproject.beads.data.Sample;
fiore@0: import net.beadsproject.beads.data.SampleManager;
fiore@0: import net.beadsproject.beads.ugens.Gain;
fiore@0: import net.beadsproject.beads.ugens.SamplePlayer;
fiore@0: import net.beadsproject.beads.ugens.SamplePlayer.LoopType;
fiore@0:
fiore@0: /**
fiore@0: * The Sound interface implementation using the Beads library.
fiore@6: * For more info about the library see http://www.beadsproject.net/.
fiore@0: */
fiore@0: class BeadsSound implements Sound {
fiore@0:
fiore@0: public BeadsSound(){
fiore@0: ac = new AudioContext();
fiore@6: playerListeners = new EnumMap(SoundEvent.class);
fiore@6: loopPlayers = new EnumMap(SoundEvent.class);
fiore@0:
fiore@0: /* pre load all the sample to avoid future overhead */
fiore@0: for(SoundEvent key : AudioResourcesService.eventTypes()){
fiore@0: SampleManager.sample(AudioResourcesService.getAudiofile(key));
fiore@0: }
fiore@0: ac.start();
fiore@0: }
fiore@0:
fiore@0:
fiore@0: public void play(InputStream sound, final PlayerListener playerListener) {
fiore@0: if(mute)
fiore@0: return;
fiore@0: SamplePlayer player;
fiore@0: Sample sample = null;
fiore@0: if(sound != null)
fiore@0: sample = SampleManager.sample(sound);
fiore@0: if(sample == null){
fiore@0: /* we got problems retrieving the sample to play
fiore@0: * call the playerListener method and return */
fiore@0: if(playerListener != null)
fiore@0: playerListener.playEnded();
fiore@0: return;
fiore@0: }
fiore@0: player = new SamplePlayer(ac,sample);
fiore@0: player.setKillOnEnd(true);
fiore@0: final Gain g = new Gain(ac,1,MASTER_VOLUME);
fiore@0: g.addInput(player);
fiore@0:
fiore@0: Bead killBill;
fiore@0: if(playerListener != null){
fiore@0: killBill = new Bead(){
fiore@0: @Override
fiore@0: protected void messageReceived(Bead message){
fiore@0: playerListener.playEnded();
fiore@0: g.kill();
fiore@0: playingBead = null;
fiore@0: }
fiore@0: };
fiore@0: }else{
fiore@0: killBill = new Bead(){
fiore@0: @Override
fiore@0: protected void messageReceived(Bead message){
fiore@0: g.kill();
fiore@0: playingBead = null;
fiore@0: }
fiore@0: };
fiore@0: }
fiore@0:
fiore@0: player.setKillListener(killBill);
fiore@0: playingBead = g;
fiore@0: ac.out.addInput(g);
fiore@0: }
fiore@0:
fiore@0: public void play(InputStream sound){
fiore@0: play(sound, null);
fiore@0: }
fiore@0:
fiore@0: @Override
fiore@0: public void play(final SoundEvent evt ){
fiore@0: if(evt == null){
fiore@0: InputStream s = null;
fiore@0: play(s);
fiore@0: }else
fiore@0: play(evt,playerListeners.get(evt));
fiore@0: }
fiore@0:
fiore@0: public void play(SoundEvent evt, PlayerListener playerListener){
fiore@0: if(evt == null){
fiore@0: InputStream s = null;
fiore@0: play(s,playerListener);
fiore@0: }else
fiore@0: play(AudioResourcesService.getAudiofile(evt),playerListener);
fiore@0: }
fiore@0:
fiore@0: public void stop(){
fiore@0: if(mute)
fiore@0: return;
fiore@0: if(playingBead != null){
fiore@0: playingBead.setKillListener(null);
fiore@0: playingBead.kill();
fiore@0: }
fiore@0: }
fiore@0:
fiore@0: public void loadSound(InputStream sound){
fiore@0: SampleManager.sample(sound);
fiore@0: }
fiore@0:
fiore@0: @Override
fiore@0: public void startLoop(SoundEvent action) {
fiore@0: if(mute)
fiore@0: return;
fiore@0: Sample sample = null;
fiore@0: if(action != null){
fiore@0: InputStream samplePath = AudioResourcesService.getAudiofile(action);
fiore@0: if(samplePath != null)
fiore@0: sample = SampleManager.sample(samplePath);
fiore@0: }
fiore@0: if(sample == null)
fiore@0: return;
fiore@0: SamplePlayer player = new SamplePlayer(ac,sample);
fiore@0: player.setLoopType(LoopType.LOOP_FORWARDS);
fiore@0: Gain g = new Gain(ac,1,MASTER_VOLUME);
fiore@0: g.addInput(player);
fiore@0: ac.out.addInput(g);
fiore@0: loopPlayers.put(action, g);
fiore@0: }
fiore@0:
fiore@0: @Override
fiore@0: public void stopLoop(SoundEvent action) {
fiore@0: UGen g = loopPlayers.get(action);
fiore@0: if(g != null){
fiore@0: g.kill();
fiore@0: loopPlayers.remove(action);
fiore@0: }
fiore@0: }
fiore@0:
fiore@0: @Override
fiore@3: public void setDefaultPlayerListener(PlayerListener listener, SoundEvent type){
fiore@0: playerListeners.put(type, listener);
fiore@0: }
fiore@0:
fiore@0: @Override
fiore@0: public void setMuted(boolean mute){
fiore@0: this.mute = mute;
fiore@0: }
fiore@0:
fiore@0: @Override
fiore@0: public void dispose(){
fiore@0: ac.stop();
fiore@0: }
fiore@0:
fiore@0: private AudioContext ac;
fiore@0: private Bead playingBead;
fiore@0: private Map playerListeners;
fiore@0: private Map loopPlayers;
fiore@0: private static final float MASTER_VOLUME = 0.35f;
fiore@0: private boolean mute;
fiore@0: }