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