Mercurial > fife-parpg
comparison engine/python/fife/extensions/soundmanager.py @ 492:16ceb3228324
Moved the SoundManager and the 2D math function (helpers) from the shooter demo to the fife extensions.
Fixed fife_timer as it didn't work in the first place. Modified the SoundManager to use the now working fife_timer and removed the Timer class from the shooter demo entirely
author | prock@33b003aa-7bff-0310-803a-e67f0ece8222 |
---|---|
date | Fri, 07 May 2010 21:07:27 +0000 |
parents | |
children | e29853880e87 |
comparison
equal
deleted
inserted
replaced
491:c4168eb47a44 | 492:16ceb3228324 |
---|---|
1 # -*- coding: utf-8 -*- | |
2 | |
3 # #################################################################### | |
4 # Copyright (C) 2005-2010 by the FIFE team | |
5 # http://www.fifengine.net | |
6 # This file is part of FIFE. | |
7 # | |
8 # FIFE is free software; you can redistribute it and/or | |
9 # modify it under the terms of the GNU Lesser General Public | |
10 # License as published by the Free Software Foundation; either | |
11 # version 2.1 of the License, or (at your option) any later version. | |
12 # | |
13 # This library is distributed in the hope that it will be useful, | |
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 # Lesser General Public License for more details. | |
17 # | |
18 # You should have received a copy of the GNU Lesser General Public | |
19 # License along with this library; if not, write to the | |
20 # Free Software Foundation, Inc., | |
21 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
22 # #################################################################### | |
23 | |
24 from fife import fife | |
25 | |
26 import fife.extensions.fife_timer as fife_timer | |
27 from fife.extensions.pychan.tools import callbackWithArguments as cbwa | |
28 | |
29 """ | |
30 Sound Manager | |
31 ================================== | |
32 | |
33 This is a simple implementation of a sound manager that was originaly | |
34 intended for the shooter demo. It was functional enough that we decided | |
35 to include it in the FIFE extensions. This is by no means a fully featured | |
36 implementation for several reasons. It doesnt limit how many sounds can | |
37 play at once or allow the positioning of sounds. It does however provide | |
38 a good starting point for a more advanced version of a sound manager. | |
39 | |
40 """ | |
41 | |
42 class SoundEmitter(object): | |
43 """ | |
44 SoundEmitter | |
45 | |
46 This class wraps an instance of a L{fife.SoundEmitter} class along | |
47 with some information about a sound clip (like gain and if its | |
48 looping). All instances of SoundEmitter should be created by SoundManager. | |
49 | |
50 @todo At some point this class will store positional information | |
51 and also be responsible for updating the L{fife.SoundEmitter} position. | |
52 """ | |
53 def __init__(self, soundmanager, clipid, soundname, emitter): | |
54 """ | |
55 @param soundmanager A reference to the SoundManager | |
56 @param clipid The FIFE sound clip ID from the sound clip pool | |
57 @param soundname The filename of the sound | |
58 @param emitter A reference to the L{fife.SoundEmitter} associated with this clip | |
59 | |
60 """ | |
61 self._soundmanager = soundmanager | |
62 self._name = soundname | |
63 | |
64 #The FIFE SoundEmitter associated with this SoundEmitter. | |
65 #Note that we do NOT own the emitter. | |
66 self._fifeemitter = emitter | |
67 self._fifeemitter.thisown = 0 | |
68 self._fifeclipid = clipid | |
69 | |
70 #0 = mute, 255 = normal volume | |
71 self._gain = 255.0 | |
72 self._looping = False | |
73 | |
74 #if you set the callback it will be executed after the sound | |
75 #has finished playing. | |
76 self._callback = None | |
77 | |
78 #length of the sound | |
79 self._duration = 0 | |
80 | |
81 self._timer = None | |
82 | |
83 def play(self): | |
84 self._soundmanager.playClip(self) | |
85 | |
86 def stop(self): | |
87 self._soundmanager.stopClip(self) | |
88 | |
89 def _getClipID(self): | |
90 return self._fifeclipid | |
91 | |
92 def _getGain(self): | |
93 return self._gain | |
94 | |
95 def _setGain(self, gain): | |
96 self._gain = float(gain) | |
97 | |
98 def _getLooping(self): | |
99 return self._looping | |
100 | |
101 def _setLooping(self, looping): | |
102 self._looping = looping | |
103 | |
104 def _getFifeEmitter(self): | |
105 return self._fifeemitter | |
106 | |
107 def _setFifeEmitter(self, emitter): | |
108 self._fifeemitter = emitter | |
109 if self._fifeemitter: | |
110 self._fifeemitter.thisown = 0 | |
111 | |
112 def _getName(self): | |
113 return self._name | |
114 | |
115 def _getCallback(self): | |
116 return self._callback | |
117 | |
118 def _setCallback(self, cb): | |
119 self._callback = cb | |
120 | |
121 def _getDuration(self): | |
122 return self._duration | |
123 | |
124 def _setDuration(self, millliseconds): | |
125 self._duration = millliseconds | |
126 | |
127 def _getTimer(self): | |
128 return self._timer | |
129 | |
130 def _setTimer(self, timer): | |
131 self._timer = timer | |
132 | |
133 timer = property(_getTimer, _setTimer) | |
134 clipid = property(_getClipID) | |
135 gain = property(_getGain, _setGain) | |
136 looping = property(_getLooping, _setLooping) | |
137 fifeemitter = property(_getFifeEmitter, _setFifeEmitter) | |
138 name = property(_getName) | |
139 callback = property(_getCallback, _setCallback) | |
140 duration = property(_getDuration, _setDuration) | |
141 | |
142 class SoundManager(object): | |
143 """ | |
144 SoundManger | |
145 | |
146 This class manages and plays all the sounds of the game. | |
147 It creates SoundEmitters and ensures that there is only one | |
148 L{fife.SoundEmitter} per unique sound. | |
149 """ | |
150 def __init__(self, engine): | |
151 """ | |
152 @param engine A reference to the FIFE engine | |
153 """ | |
154 | |
155 self._engine = engine | |
156 | |
157 self._fifesoundmanager = self._engine.getSoundManager() | |
158 self._fifesoundmanager.init() | |
159 | |
160 #A dict of fife emitters | |
161 self._loadedclips = {} | |
162 | |
163 def createSoundEmitter(self, filename, forceUnique=False): | |
164 """ | |
165 Returns a valid SoundEmitter instance. | |
166 | |
167 @param filename The relative path and filename of the sound file | |
168 @parm forceUnique This forces a new L{fife.SoundEmitter} to be created. | |
169 This is useful if you want more than one instance of the same sound | |
170 to be played at the same time. | |
171 | |
172 @return Returns a new SoundEmitter instance. | |
173 """ | |
174 if not self._loadedclips.has_key(filename): | |
175 clipid = self._engine.getSoundClipPool().addResourceFromFile(filename) | |
176 fifeemitter = self._fifesoundmanager.createEmitter() | |
177 fifeemitter.thisown = 0 | |
178 fifeemitter.setSoundClip(clipid) | |
179 | |
180 self._loadedclips[filename] = [fifeemitter] | |
181 clip = SoundEmitter(self, clipid, filename, fifeemitter) | |
182 clip.duration = fifeemitter.getDuration() | |
183 else: | |
184 if forceUnique: | |
185 clipid = self._engine.getSoundClipPool().addResourceFromFile(filename) | |
186 fifeemitter = self._fifesoundmanager.createEmitter() | |
187 fifeemitter.thisown = 0 | |
188 fifeemitter.setSoundClip(clipid) | |
189 self._loadedclips[filename].append(fifeemitter) | |
190 else: | |
191 fifeemitter = self._loadedclips[filename][0] | |
192 | |
193 clip = SoundEmitter(self, fifeemitter.getID(), filename, fifeemitter) | |
194 clip.duration = fifeemitter.getDuration() | |
195 | |
196 return clip | |
197 | |
198 def playClip(self, clip): | |
199 """ | |
200 Plays a sound clip. | |
201 | |
202 This function does not use the L{fife.SoundEmitter} | |
203 "looping" property to loop a sound. Instead it registers | |
204 a new timer and uses the duration of the clip as the timer length. | |
205 | |
206 If the SoundEmitter is invalid (no fifeemitter) then it attempts | |
207 to load it before playing it. | |
208 | |
209 @note This will stop any clips that use the same L{fife.SoundEmitter}. | |
210 You cannot play the same sound more than once at a time unless you create | |
211 the SoundEmitter with the forceUnique paramater set to True. | |
212 | |
213 @param clip The SoundEmitter to be played | |
214 """ | |
215 | |
216 if clip.fifeemitter: | |
217 if clip.callback: | |
218 if clip.timer: | |
219 clip.timer.stop() | |
220 timer = None | |
221 | |
222 if clip.looping: | |
223 repeat = 0 | |
224 def real_callback(c, e, g): | |
225 c() | |
226 e.stop() | |
227 e.setGain(g) | |
228 e.play() | |
229 | |
230 clip.callback = cbwa(real_callback, clip.callback, clip.fifeemitter, clip.gain) | |
231 | |
232 else: | |
233 repeat = 1 | |
234 | |
235 clip.timer = fife_timer.delayCall(clip.duration, clip.callback) | |
236 #clip.timer.start() | |
237 | |
238 clip.fifeemitter.setGain(clip.gain) | |
239 clip.fifeemitter.play() | |
240 else: | |
241 clip = self.createSoundEmitter(clip.name) | |
242 self.playClip(clip) | |
243 | |
244 def stopClip(self, clip): | |
245 """ | |
246 Stops playing the sound clip. Note that this will stop all clips that | |
247 use the same FIFE emitter. | |
248 | |
249 @parm clip The SoundEmitter to stop. | |
250 """ | |
251 if clip.fifeemitter: | |
252 clip.fifeemitter.stop() | |
253 | |
254 if clip.timer: | |
255 clip.timer.stop() | |
256 clip.timer = None | |
257 | |
258 def stopAllSounds(self): | |
259 for emitterlist in self._loadedclips.values(): | |
260 for emitter in emitterlist: | |
261 emitter.stop() | |
262 | |
263 def destroy(self): | |
264 """ | |
265 Releases all instances of L{fife.SoundEmitter}. This does not free | |
266 the resources from the FIFE sound clip pool. | |
267 """ | |
268 self.stopAllSounds() | |
269 | |
270 for emitterlist in self._loadedclips.values(): | |
271 for emitter in emitterlist: | |
272 self._fifesoundmanager.releaseEmitter(emitter.getID()) | |
273 emitter = None | |
274 | |
275 self._loadedclips.clear() | |
276 | |
277 __all__ = ['SoundEmitter','SoundManager'] |