fiore@0
|
1 /*
|
fiore@0
|
2 CCmI Editor - A Collaborative Cross-Modal Diagram Editing Tool
|
fiore@0
|
3
|
fiore@0
|
4 Copyright (C) 2011 Queen Mary University of London (http://ccmi.eecs.qmul.ac.uk/)
|
fiore@0
|
5
|
fiore@0
|
6 This program is free software: you can redistribute it and/or modify
|
fiore@0
|
7 it under the terms of the GNU General Public License as published by
|
fiore@0
|
8 the Free Software Foundation, either version 3 of the License, or
|
fiore@0
|
9 (at your option) any later version.
|
fiore@0
|
10
|
fiore@0
|
11 This program is distributed in the hope that it will be useful,
|
fiore@0
|
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
fiore@0
|
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
fiore@0
|
14 GNU General Public License for more details.
|
fiore@0
|
15
|
fiore@0
|
16 You should have received a copy of the GNU General Public License
|
fiore@0
|
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
|
fiore@0
|
18 */
|
fiore@0
|
19
|
fiore@0
|
20 package uk.ac.qmul.eecs.ccmi.sound;
|
fiore@0
|
21
|
fiore@0
|
22 import java.io.InputStream;
|
fiore@6
|
23 import java.util.EnumMap;
|
fiore@0
|
24 import java.util.Map;
|
fiore@0
|
25
|
fiore@0
|
26 import net.beadsproject.beads.core.AudioContext;
|
fiore@0
|
27 import net.beadsproject.beads.core.Bead;
|
fiore@0
|
28 import net.beadsproject.beads.core.UGen;
|
fiore@0
|
29 import net.beadsproject.beads.data.Sample;
|
fiore@0
|
30 import net.beadsproject.beads.data.SampleManager;
|
fiore@0
|
31 import net.beadsproject.beads.ugens.Gain;
|
fiore@0
|
32 import net.beadsproject.beads.ugens.SamplePlayer;
|
fiore@0
|
33 import net.beadsproject.beads.ugens.SamplePlayer.LoopType;
|
fiore@0
|
34
|
fiore@0
|
35 /**
|
fiore@0
|
36 * The Sound interface implementation using the Beads library.
|
fiore@6
|
37 * For more info about the library see http://www.beadsproject.net/.
|
fiore@0
|
38 */
|
fiore@0
|
39 class BeadsSound implements Sound {
|
fiore@0
|
40
|
fiore@0
|
41 public BeadsSound(){
|
fiore@0
|
42 ac = new AudioContext();
|
fiore@6
|
43 playerListeners = new EnumMap<SoundEvent,PlayerListener>(SoundEvent.class);
|
fiore@6
|
44 loopPlayers = new EnumMap<SoundEvent,UGen>(SoundEvent.class);
|
fiore@0
|
45
|
fiore@0
|
46 /* pre load all the sample to avoid future overhead */
|
fiore@0
|
47 for(SoundEvent key : AudioResourcesService.eventTypes()){
|
fiore@0
|
48 SampleManager.sample(AudioResourcesService.getAudiofile(key));
|
fiore@0
|
49 }
|
fiore@0
|
50 ac.start();
|
fiore@0
|
51 }
|
fiore@0
|
52
|
fiore@0
|
53
|
fiore@0
|
54 public void play(InputStream sound, final PlayerListener playerListener) {
|
fiore@0
|
55 if(mute)
|
fiore@0
|
56 return;
|
fiore@0
|
57 SamplePlayer player;
|
fiore@0
|
58 Sample sample = null;
|
fiore@0
|
59 if(sound != null)
|
fiore@0
|
60 sample = SampleManager.sample(sound);
|
fiore@0
|
61 if(sample == null){
|
fiore@0
|
62 /* we got problems retrieving the sample to play
|
fiore@0
|
63 * call the playerListener method and return */
|
fiore@0
|
64 if(playerListener != null)
|
fiore@0
|
65 playerListener.playEnded();
|
fiore@0
|
66 return;
|
fiore@0
|
67 }
|
fiore@0
|
68 player = new SamplePlayer(ac,sample);
|
fiore@0
|
69 player.setKillOnEnd(true);
|
fiore@0
|
70 final Gain g = new Gain(ac,1,MASTER_VOLUME);
|
fiore@0
|
71 g.addInput(player);
|
fiore@0
|
72
|
fiore@0
|
73 Bead killBill;
|
fiore@0
|
74 if(playerListener != null){
|
fiore@0
|
75 killBill = new Bead(){
|
fiore@0
|
76 @Override
|
fiore@0
|
77 protected void messageReceived(Bead message){
|
fiore@0
|
78 playerListener.playEnded();
|
fiore@0
|
79 g.kill();
|
fiore@0
|
80 playingBead = null;
|
fiore@0
|
81 }
|
fiore@0
|
82 };
|
fiore@0
|
83 }else{
|
fiore@0
|
84 killBill = new Bead(){
|
fiore@0
|
85 @Override
|
fiore@0
|
86 protected void messageReceived(Bead message){
|
fiore@0
|
87 g.kill();
|
fiore@0
|
88 playingBead = null;
|
fiore@0
|
89 }
|
fiore@0
|
90 };
|
fiore@0
|
91 }
|
fiore@0
|
92
|
fiore@0
|
93 player.setKillListener(killBill);
|
fiore@0
|
94 playingBead = g;
|
fiore@0
|
95 ac.out.addInput(g);
|
fiore@0
|
96 }
|
fiore@0
|
97
|
fiore@0
|
98 public void play(InputStream sound){
|
fiore@0
|
99 play(sound, null);
|
fiore@0
|
100 }
|
fiore@0
|
101
|
fiore@0
|
102 @Override
|
fiore@0
|
103 public void play(final SoundEvent evt ){
|
fiore@0
|
104 if(evt == null){
|
fiore@0
|
105 InputStream s = null;
|
fiore@0
|
106 play(s);
|
fiore@0
|
107 }else
|
fiore@0
|
108 play(evt,playerListeners.get(evt));
|
fiore@0
|
109 }
|
fiore@0
|
110
|
fiore@0
|
111 public void play(SoundEvent evt, PlayerListener playerListener){
|
fiore@0
|
112 if(evt == null){
|
fiore@0
|
113 InputStream s = null;
|
fiore@0
|
114 play(s,playerListener);
|
fiore@0
|
115 }else
|
fiore@0
|
116 play(AudioResourcesService.getAudiofile(evt),playerListener);
|
fiore@0
|
117 }
|
fiore@0
|
118
|
fiore@0
|
119 public void stop(){
|
fiore@0
|
120 if(mute)
|
fiore@0
|
121 return;
|
fiore@0
|
122 if(playingBead != null){
|
fiore@0
|
123 playingBead.setKillListener(null);
|
fiore@0
|
124 playingBead.kill();
|
fiore@0
|
125 }
|
fiore@0
|
126 }
|
fiore@0
|
127
|
fiore@0
|
128 public void loadSound(InputStream sound){
|
fiore@0
|
129 SampleManager.sample(sound);
|
fiore@0
|
130 }
|
fiore@0
|
131
|
fiore@0
|
132 @Override
|
fiore@0
|
133 public void startLoop(SoundEvent action) {
|
fiore@0
|
134 if(mute)
|
fiore@0
|
135 return;
|
fiore@0
|
136 Sample sample = null;
|
fiore@0
|
137 if(action != null){
|
fiore@0
|
138 InputStream samplePath = AudioResourcesService.getAudiofile(action);
|
fiore@0
|
139 if(samplePath != null)
|
fiore@0
|
140 sample = SampleManager.sample(samplePath);
|
fiore@0
|
141 }
|
fiore@0
|
142 if(sample == null)
|
fiore@0
|
143 return;
|
fiore@0
|
144 SamplePlayer player = new SamplePlayer(ac,sample);
|
fiore@0
|
145 player.setLoopType(LoopType.LOOP_FORWARDS);
|
fiore@0
|
146 Gain g = new Gain(ac,1,MASTER_VOLUME);
|
fiore@0
|
147 g.addInput(player);
|
fiore@0
|
148 ac.out.addInput(g);
|
fiore@0
|
149 loopPlayers.put(action, g);
|
fiore@0
|
150 }
|
fiore@0
|
151
|
fiore@0
|
152 @Override
|
fiore@0
|
153 public void stopLoop(SoundEvent action) {
|
fiore@0
|
154 UGen g = loopPlayers.get(action);
|
fiore@0
|
155 if(g != null){
|
fiore@0
|
156 g.kill();
|
fiore@0
|
157 loopPlayers.remove(action);
|
fiore@0
|
158 }
|
fiore@0
|
159 }
|
fiore@0
|
160
|
fiore@0
|
161 @Override
|
fiore@3
|
162 public void setDefaultPlayerListener(PlayerListener listener, SoundEvent type){
|
fiore@0
|
163 playerListeners.put(type, listener);
|
fiore@0
|
164 }
|
fiore@0
|
165
|
fiore@0
|
166 @Override
|
fiore@0
|
167 public void setMuted(boolean mute){
|
fiore@0
|
168 this.mute = mute;
|
fiore@0
|
169 }
|
fiore@0
|
170
|
fiore@0
|
171 @Override
|
fiore@0
|
172 public void dispose(){
|
fiore@0
|
173 ac.stop();
|
fiore@0
|
174 }
|
fiore@0
|
175
|
fiore@0
|
176 private AudioContext ac;
|
fiore@0
|
177 private Bead playingBead;
|
fiore@0
|
178 private Map<SoundEvent,PlayerListener> playerListeners;
|
fiore@0
|
179 private Map<SoundEvent,UGen> loopPlayers;
|
fiore@0
|
180 private static final float MASTER_VOLUME = 0.35f;
|
fiore@0
|
181 private boolean mute;
|
fiore@0
|
182 }
|