| Home | Trees | Indices | Help |
|---|
|
|
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 """
25 Sound Manager
26 ==================================
27
28 This is a simple implementation of a sound manager that was originaly
29 intended for the shooter demo. It was functional enough that we decided
30 to include it in the FIFE extensions. This is by no means a fully featured
31 implementation for several reasons. It doesnt limit how many sounds can
32 play at once or allow the positioning of sounds. It does however provide
33 a good starting point for a more advanced version of a sound manager.
34
35 Usage::
36 soundmanager = SoundManager(my_fife_engine)
37
38 emitter = soundmanager.createSoundEmitter("path/filename.ogg")
39 emitter.gain = 128
40 emitter.play()
41
42 """
43
44 from fife import fife
45
46 import fife.extensions.fife_timer as fife_timer
47 from fife.extensions.pychan.tools import callbackWithArguments as cbwa
48
50 """
51 Wraps the L{fife.SoundEmitter} class.
52
53 This class wraps an instance of a L{fife.SoundEmitter} class along
54 with some information about a sound clip (like gain and if its
55 looping). All instances of SoundEmitter should be created by SoundManager.
56
57 @todo: At some point this class will store positional information
58 and also be responsible for updating the L{fife.SoundEmitter} position.
59 """
61 """
62 @param soundmanager: A reference to the SoundManager
63 @type soundmanager: L{SoundManager}
64 @param clipid: The FIFE sound clip ID from the sound clip pool
65 @type clipid: C{int}
66 @param soundname: The filename of the sound
67 @type soundname: C{string}
68 @param emitter: A reference to the L{fife.SoundEmitter} associated with this clip
69 @type emitter: L{fife.SoundEmitter}
70
71 """
72 self._soundmanager = soundmanager
73 self._name = soundname
74
75 #The FIFE SoundEmitter associated with this SoundEmitter.
76 #Note that we do NOT own the emitter.
77 self._fifeemitter = emitter
78 self._fifeemitter.thisown = 0
79 self._fifeclip = clip
80
81 #0 = mute, 255 = normal volume
82 self._gain = 255.0
83 self._looping = False
84
85 #if you set the callback it will be executed after the sound
86 #has finished playing.
87 self._callback = None
88
89 #length of the sound
90 self._duration = 0
91
92 self._timer = None
93
94 self._position = None
95 self._rolloff = 0
96
98 self._soundmanager.unregisterClip(self)
99
101 self._soundmanager.playClip(self)
102
104 self._soundmanager.stopClip(self)
105
108
111
113 """
114 Sets the volume of the L{SoundEmitter}.
115
116 @param gain: Value should be from 0-255. 0 being mute and 255 being the normal
117 volume of the clip.
118 @type gain: C{int}
119 """
120 self._gain = float(gain)
121
124
126 self._looping = looping
127
130
135
138
141
144
147
150
153
155 self._timer = timer
156
158 self._position = position
159
162
164 self._rolloff = rolloff
165
168
169 rolloff = property(_getRolloff, _setRolloff)
170 position = property(_getPosition, _setPosition)
171 timer = property(_getTimer, _setTimer)
172 clip = property(_getClip)
173 gain = property(_getGain, _setGain)
174 looping = property(_getLooping, _setLooping)
175 fifeemitter = property(_getFifeEmitter, _setFifeEmitter)
176 name = property(_getName)
177 callback = property(_getCallback, _setCallback)
178 duration = property(_getDuration, _setDuration)
179
181 """
182 A simple sound manager class.
183
184 This class manages and plays all the sounds of the game.
185 It creates SoundEmitters and ensures that there is only one
186 L{fife.SoundEmitter} per unique sound.
187 """
189 """
190 @param engine: A reference to the FIFE engine
191 @type engine: L{fife.Engine}
192 """
193
194 self._engine = engine
195
196 self._fifesoundclipmanager = self._engine.getSoundClipManager()
197
198 self._fifesoundmanager = self._engine.getSoundManager()
199 self._fifesoundmanager.init()
200
201 self._fifesoundmanager.setListenerOrientation(0,1,0)
202
203 # basic rolloff used for positional sounds
204 self._rolloff = 1
205
206 #A dict of fife emitters
207 self._loadedclips = {}
208
209 #A list of created clips
210 self._soundclips = []
211
212 #A tuple representing the listener position (x,y)
213 self._listenerposition = None
214
216 """
217 Returns a valid SoundEmitter instance.
218
219 @param filename: The relative path and filename of the sound file
220 @type clip: C{string}
221 @param forceUnique: This forces a new L{fife.SoundEmitter} to be created.
222 This is useful if you want more than one instance of the same sound
223 to be played at the same time.
224 @type forceUnique: C{boolean}
225 @param position: The position on the map that the sound emitter
226 is to be created at.
227 @type position: L{tuple}
228
229 @return: Returns a new L{SoundEmitter} instance.
230 @rtype: L{SoundEmitter}
231 """
232 if not self._loadedclips.has_key(filename):
233 soundclipptr = self._fifesoundclipmanager.get(filename)
234 fifeemitter = self._fifesoundmanager.createEmitter()
235 fifeemitter.thisown = 0
236 fifeemitter.setSoundClip(soundclipptr)
237 self._loadedclips[filename] = [fifeemitter]
238 clip = SoundEmitter(self, soundclipptr, filename, fifeemitter)
239 clip.duration = fifeemitter.getDuration()
240 else:
241 if forceUnique:
242 soundclipptr = self._fifesoundclipmanager.get(filename)
243 fifeemitter = self._fifesoundmanager.createEmitter()
244 fifeemitter.thisown = 0
245 fifeemitter.setSoundClip(soundclipptr)
246 self._loadedclips[filename].append(fifeemitter)
247 else:
248 fifeemitter = self._loadedclips[filename][0]
249
250 clip = SoundEmitter(self, fifeemitter.getSoundClip(), filename, fifeemitter)
251 clip.duration = fifeemitter.getDuration()
252
253 if position is not None:
254 clip.position = position
255 clip.rolloff = self.rolloff
256
257 self._soundclips.append(clip)
258
259 return clip
260
262 """
263 Plays a sound clip.
264
265 This function does not use the L{fife.SoundEmitter}
266 "looping" property to loop a sound. Instead it registers
267 a new timer and uses the duration of the clip as the timer length.
268
269 If the SoundEmitter is invalid (no fifeemitter) then it attempts
270 to load it before playing it.
271
272 @note: This will stop any clips that use the same L{fife.SoundEmitter}.
273 You cannot play the same sound more than once at a time unless you create
274 the SoundEmitter with the forceUnique paramater set to True.
275
276 @param clip: The L{SoundEmitter} to be played
277 @type clip: L{SoundEmitter}
278 """
279 if clip.fifeemitter:
280 if clip.callback:
281 if clip.timer:
282 clip.timer.stop()
283 timer = None
284
285 if clip.looping:
286 repeat = 0
287 def real_callback(clip):
288 clip.fifeemitter.stop()
289 clip.fifeemitter.setGain(float(clip.gain)/255.0)
290 if self.listenerposition and clip.position:
291 # Use 1 as z coordinate, no need to specify it
292 clip.fifeemitter.setPosition(clip.position[0], clip.position[1], 1)
293 clip.fifeemitter.setRolloff(clip.rolloff)
294 elif self.listenerposition and not clip.position:
295 clip.fifeemitter.setPosition(self._listenerposition[0], self._listenerposition[1], 1)
296 clip.fifeemitter.setRolloff(self.rolloff)
297
298 clip.fifeemitter.play()
299
300 clip.callback = cbwa(real_callback, clip)
301
302 else:
303 repeat = 1
304
305 clip.timer = fife_timer.Timer(clip.duration, clip.callback, repeat)
306
307 else:
308 if clip.looping:
309 def real_callback(clip):
310 clip.fifeemitter.stop()
311 clip.fifeemitter.setGain(float(clip.gain)/255.0)
312 if self.listenerposition and clip.position:
313 # Use 1 as z coordinate, no need to specify it
314 clip.fifeemitter.setPosition(clip.position[0], clip.position[1], 1)
315 clip.fifeemitter.setRolloff(clip.rolloff)
316 elif self.listenerposition and not clip.position:
317 clip.fifeemitter.setPosition(self._listenerposition[0], self._listenerposition[1], 1)
318 clip.fifeemitter.setRolloff(self.rolloff)
319
320 clip.fifeemitter.play()
321
322 clip.callback = cbwa(real_callback, clip)
323 clip.timer = fife_timer.Timer(clip.duration, clip.callback, 0)
324
325 clip.fifeemitter.setGain(float(clip.gain)/255.0)
326
327 if self.listenerposition and clip.position:
328 # Use 1 as z coordinate, no need to specify it
329 clip.fifeemitter.setPosition(clip.position[0], clip.position[1], 1)
330 clip.fifeemitter.setRolloff(clip.rolloff)
331 elif self.listenerposition and not clip.position:
332 clip.fifeemitter.setPosition(self._listenerposition[0], self._listenerposition[1], 1)
333 clip.fifeemitter.setRolloff(self.rolloff)
334
335 clip.fifeemitter.play()
336 if clip.timer:
337 clip.timer.start()
338
339 else:
340 clip = self.createSoundEmitter(clip.name)
341 self.playClip(clip)
342
348
350 """
351 Stops playing the sound clip. Note that this will stop all clips that
352 use the same FIFE emitter.
353
354 @param clip: The SoundEmitter to stop.
355 @type clip: L{SoundEmitter}
356 """
357 if clip.fifeemitter:
358 clip.fifeemitter.stop()
359
360 if clip.timer:
361 clip.timer.stop()
362 clip.timer = None
363
367
369 """
370 Releases all instances of L{fife.SoundEmitter}.
371
372 @note: This does not free the resources from the FIFE sound clip pool.
373 """
374 self.stopAllSounds()
375
376 for emitterlist in self._loadedclips.values():
377 for emitter in emitterlist:
378 self._fifesoundmanager.releaseEmitter(emitter.getId())
379 emitter = None
380
381 self._loadedclips.clear()
382
def _getRolloff(self):
383 return self._rolloff
384
386 self._rolloff = rolloff
387
390
392 self._listenerposition = position
393 self._fifesoundmanager.setListenerPosition(self._listenerposition[0], self._listenerposition[1], 10)
394
395 rolloff = property(_getRolloff, _setRolloff)
396 listenerposition = property(_getListenerPosition, _setListenerPosition)
397
398 __all__ = ['SoundEmitter','SoundManager']
399
| Home | Trees | Indices | Help |
|---|
| Generated by Epydoc 3.0.1 on Tue May 22 00:00:40 2012 | http://epydoc.sourceforge.net |