Mercurial > boomslang
annotate pyntnclick/sound.py @ 631:8b78fc07a862 pyntnclick
Less buggy non-albow music support
author | Neil Muller <neil@dip.sun.ac.za> |
---|---|
date | Sat, 11 Feb 2012 22:24:24 +0200 |
parents | 660ef5793886 |
children | 4206da1f742d |
rev | line source |
---|---|
583
66c2e084b8b3
Remove unused import and fix comment.
Simon Cross <hodgestar+bzr@gmail.com>
parents:
577
diff
changeset
|
1 # sound management for pyntnclick |
107 | 2 |
3 # This re-implements some of the albow.resource code to | |
4 # a) work around an annoying bugs | |
5 # b) add some missing functionality (disable_sound) | |
6 | |
629 | 7 from random import randrange |
8 | |
9 | |
123 | 10 import pygame |
564 | 11 |
12 try: | |
13 from pygame.mixer import Sound as pygame_Sound | |
14 from pygame.mixer import music | |
15 pygame_import_error = None | |
16 except ImportError, e: | |
17 # Save error, so we don't crash and can do the right thing later | |
18 pygame_import_error = e | |
19 pygame_Sound = None | |
20 music = None | |
21 | |
22 from pyntnclick.resources import ResourceNotFound | |
629 | 23 from pyntnclick.engine import MUSIC_ENDED |
564 | 24 |
629 | 25 |
26 class PlayList(object): | |
27 """Hold a playlist of music filenames""" | |
28 | |
29 def __init__(self, pieces, random, repeat): | |
30 self._pieces = pieces | |
31 self._random = random | |
631
8b78fc07a862
Less buggy non-albow music support
Neil Muller <neil@dip.sun.ac.za>
parents:
629
diff
changeset
|
32 self._repeat = repeat |
629 | 33 |
34 def get_next(self): | |
35 # Get the next piece | |
631
8b78fc07a862
Less buggy non-albow music support
Neil Muller <neil@dip.sun.ac.za>
parents:
629
diff
changeset
|
36 if self._pieces: |
629 | 37 if self._random: |
631
8b78fc07a862
Less buggy non-albow music support
Neil Muller <neil@dip.sun.ac.za>
parents:
629
diff
changeset
|
38 if not self._repeat or len(self._pieces) < 3: |
8b78fc07a862
Less buggy non-albow music support
Neil Muller <neil@dip.sun.ac.za>
parents:
629
diff
changeset
|
39 i = randrange(0, len(self._pieces)) |
629 | 40 else: |
41 # Ignore the last entry, since we possibly just played it | |
631
8b78fc07a862
Less buggy non-albow music support
Neil Muller <neil@dip.sun.ac.za>
parents:
629
diff
changeset
|
42 i = randrange(0, len(self._pieces) - 1) |
629 | 43 else: |
44 i = 0 | |
631
8b78fc07a862
Less buggy non-albow music support
Neil Muller <neil@dip.sun.ac.za>
parents:
629
diff
changeset
|
45 result = self._pieces.pop(i) |
629 | 46 if self._repeat: |
631
8b78fc07a862
Less buggy non-albow music support
Neil Muller <neil@dip.sun.ac.za>
parents:
629
diff
changeset
|
47 self._pieces.append(result) |
629 | 48 return result |
49 return None | |
107 | 50 |
564 | 51 |
52 class DummySound(object): | |
53 """A dummy sound object. | |
54 | |
55 This is a placeholder object with the same API as | |
56 pygame.mixer.Sound which does nothing. Used when | |
57 sounds are disabled so scense don't need to worry | |
58 about the details. | |
59 | |
60 Inpsired by the same idea in Albow (by Greg Ewing)""" | |
61 | |
565 | 62 def play(self, *args): |
63 pass | |
564 | 64 |
565 | 65 def stop(self): |
66 pass | |
564 | 67 |
565 | 68 def get_length(self): |
69 return 0.0 | |
564 | 70 |
565 | 71 def get_num_channel(self): |
72 return 0 | |
564 | 73 |
565 | 74 def get_volume(self): |
75 return 0.0 | |
564 | 76 |
565 | 77 def fadeout(self, *args): |
78 pass | |
107 | 79 |
534 | 80 |
564 | 81 class Sound(object): |
82 """Global sound management and similiar useful things""" | |
83 | |
84 def __init__(self, resource_finder): | |
85 self.sound_enabled = False | |
86 self.sound_cache = {} | |
87 self._resource_finder = resource_finder | |
629 | 88 self._current_playlist = None |
564 | 89 |
576
1b1ab71535bd
Classify constants, which involves a whole bunch of XXX comments
Stefano Rivera <stefano@rivera.za.net>
parents:
572
diff
changeset
|
90 def enable_sound(self, constants): |
564 | 91 """Attempt to initialise the sound system""" |
92 if pygame_Sound is None: | |
93 self.disable_sound(pygame_import_error) | |
94 return | |
107 | 95 try: |
576
1b1ab71535bd
Classify constants, which involves a whole bunch of XXX comments
Stefano Rivera <stefano@rivera.za.net>
parents:
572
diff
changeset
|
96 pygame.mixer.init(constants.snd_freq, |
1b1ab71535bd
Classify constants, which involves a whole bunch of XXX comments
Stefano Rivera <stefano@rivera.za.net>
parents:
572
diff
changeset
|
97 constants.snd_bitsize, |
1b1ab71535bd
Classify constants, which involves a whole bunch of XXX comments
Stefano Rivera <stefano@rivera.za.net>
parents:
572
diff
changeset
|
98 constants.snd_channels, |
1b1ab71535bd
Classify constants, which involves a whole bunch of XXX comments
Stefano Rivera <stefano@rivera.za.net>
parents:
572
diff
changeset
|
99 constants.snd_buffer) |
564 | 100 self.sound_enabled = True |
629 | 101 music.set_endevent(MUSIC_ENDED) |
564 | 102 except pygame.error, exc: |
103 self.disable_sound(exc) | |
104 | |
105 def disable_sound(self, exc=None): | |
106 """Disable the sound system""" | |
107 self.sound_enabled = False | |
108 if exc is not None: | |
109 print 'Failed to initialise sound system' | |
110 print 'Error: %s' % exc | |
111 print 'Sound disabled' | |
112 | |
113 def get_sound(self, *names): | |
114 if not self.sound_enabled: | |
565 | 115 return DummySound() |
564 | 116 sound = None |
117 try: | |
577 | 118 path = self._resource_finder.get_resource_path("sounds", *names) |
565 | 119 sound = self.sound_cache.get(path, None) |
564 | 120 except ResourceNotFound: |
577 | 121 print "Sound file not found: %s" % names |
564 | 122 # Cache failed lookup |
123 sound = DummySound() | |
124 self.sound_cache[path] = sound | |
125 if sound is None: | |
126 try: | |
127 sound = pygame_Sound(path) | |
570
9c3528c2cbe5
Bug fixes for sound hook-up.
Simon Cross <hodgestar+bzr@gmail.com>
parents:
565
diff
changeset
|
128 except pygame.error: |
577 | 129 print "Sound file not found: %s" % names |
564 | 130 sound = DummySound() |
131 self.sound_cache[path] = sound | |
132 return sound | |
107 | 133 |
564 | 134 def get_playlist(self, pieces, random=False, repeat=False): |
629 | 135 return PlayList(pieces, random, repeat) |
534 | 136 |
629 | 137 def get_music(self, name): |
577 | 138 if self.sound_enabled: |
629 | 139 music_file = self._resource_finder.get_resource_path("sounds", |
140 name) | |
141 return music_file | |
142 return None | |
143 | |
144 def music_ended(self): | |
145 if self._current_playlist: | |
146 # Try start the next tune | |
147 self.start_next_music() | |
107 | 148 |
564 | 149 def change_playlist(self, new_playlist): |
577 | 150 if self.sound_enabled: |
631
8b78fc07a862
Less buggy non-albow music support
Neil Muller <neil@dip.sun.ac.za>
parents:
629
diff
changeset
|
151 music.stop() |
629 | 152 self._current_playlist = new_playlist |
153 self.start_next_music() | |
154 | |
155 def start_next_music(self): | |
156 if self._current_playlist: | |
157 tune = self._current_playlist.get_next() | |
158 if tune: | |
159 music.load(tune) | |
160 music.play() | |
154 | 161 |
577 | 162 def get_current_playlist(self): |
629 | 163 return self._current_playlist |