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: }