Mercurial > boomslang
changeset 564:2f7aa3cad77c pyntnclick
Sound hackery
author | Neil Muller <neil@dip.sun.ac.za> |
---|---|
date | Sat, 11 Feb 2012 15:35:06 +0200 |
parents | 18396b937647 |
children | 88cffe418201 |
files | pyntnclick/main.py pyntnclick/sound.py |
diffstat | 2 files changed, 99 insertions(+), 47 deletions(-) [+] |
line wrap: on
line diff
--- a/pyntnclick/main.py Sat Feb 11 15:22:16 2012 +0200 +++ b/pyntnclick/main.py Sat Feb 11 15:35:06 2012 +0200 @@ -20,8 +20,8 @@ from pyntnclick.gamescreen import GameScreen from pyntnclick.endscreen import EndScreen from pyntnclick.constants import ( - SCREEN, FRAME_RATE, FREQ, BITSIZE, CHANNELS, BUFFER, DEBUG) -from pyntnclick.sound import no_sound, disable_sound + SCREEN, FRAME_RATE) +from pyntnclick.sound import Sound from pyntnclick import state, data @@ -57,8 +57,8 @@ self._scene_list = self.SCENE_LIST self._debug_rects = False # TODO: make these real objects - self.sound = object() self.resource = object() + self.sound = Sound(self.resource) def initial_state(self): """Create a copy of the initial game state.""" @@ -87,13 +87,9 @@ pygame.display.init() pygame.font.init() if opts.sound: - try: - pygame.mixer.init(FREQ, BITSIZE, CHANNELS, BUFFER) - except pygame.error, exc: - no_sound(exc) + self.sound.enable_sound() else: - # Ensure get_sound returns nothing, so everything else just works - disable_sound() + self.sound.disable_sound() if DEBUG: if opts.scene is not None: # debug the specified scene
--- a/pyntnclick/sound.py Sat Feb 11 15:22:16 2012 +0200 +++ b/pyntnclick/sound.py Sat Feb 11 15:35:06 2012 +0200 @@ -7,53 +7,109 @@ import os import pygame -from pygame.mixer import music -from albow.resource import _resource_path, dummy_sound + +try: + from pygame.mixer import Sound as pygame_Sound + from pygame.mixer import music + pygame_import_error = None +except ImportError, e: + # Save error, so we don't crash and can do the right thing later + pygame_import_error = e + pygame_Sound = None + music = None + +from pyntnclick.constants import FREQ, BITSIZE, CHANNELS, BUFFER +from pyntnclick.resources import ResourceNotFound + import albow.music -sound_cache = {} + +class DummySound(object): + """A dummy sound object. + + This is a placeholder object with the same API as + pygame.mixer.Sound which does nothing. Used when + sounds are disabled so scense don't need to worry + about the details. + + Inpsired by the same idea in Albow (by Greg Ewing)""" + + def play(self, *args): + pass + + def stop(self): + pass + + def get_length(self): + return 0.0 + + def get_num_channel(self): + return 0 + + def get_volume(self): + return 0.0 + + def fadeout(self, *args): + pass -def get_sound(*names): - if sound_cache is None: - return dummy_sound - path = _resource_path("sounds", names) - sound = sound_cache.get(path) - if not sound: - if not os.path.isfile(path): - missing_sound("File does not exist", path) - return dummy_sound +class Sound(object): + """Global sound management and similiar useful things""" + + def __init__(self, resource_finder): + self.sound_enabled = False + self.sound_cache = {} + self._resource_finder = resource_finder + + def enable_sound(self): + """Attempt to initialise the sound system""" + if pygame_Sound is None: + self.disable_sound(pygame_import_error) + return try: - from pygame.mixer import Sound - except ImportError, e: - no_sound(e) - return dummy_sound - try: - sound = Sound(path) - except pygame.error, e: - missing_sound(e, path) + pygame.mixer.init(FREQ, BITSIZE, CHANNELS, BUFFER) + self.sound_enabled = True + except pygame.error, exc: + self.disable_sound(exc) + + def disable_sound(self, exc=None): + """Disable the sound system""" + self.sound_enabled = False + if exc is not None: + print 'Failed to initialise sound system' + print 'Error: %s' % exc + print 'Sound disabled' + + def get_sound(self, *names): + if not self.sound_enabled: return dummy_sound - sound_cache[path] = sound - return sound - - -def no_sound(e): - global sound_cache - print "get_sound: %s" % e - print "get_sound: Sound not available, continuing without it" - sound_cache = None - albow.music.music_enabled = False + soundfile = os.path.join(names) + sound = None + try: + path = self._resource_finder("sounds", soundfile) + sound = sound_cache.get(path, None) + except ResourceNotFound: + print "Sound file not found: %s" % soundfile + # Cache failed lookup + sound = DummySound() + self.sound_cache[path] = sound + if sound is None: + try: + sound = pygame_Sound(path) + except pygame.error, e: + print "Sound file not found: %s" % soundfile + sound = DummySound() + self.sound_cache[path] = sound + return sound + def get_playlist(self, pieces, random=False, repeat=False): + return albow.music.PlayList(pieces, random, repeat) -def disable_sound(): - global sound_cache - sound_cache = None - albow.music.music_enabled = False + def get_music(self, name, prefix): + return albow.music.get_music(name, prefix) - -def missing_sound(e, name): - print "albow.resource.get_sound: %s: %s" % (name, e) - + def change_playlist(self, new_playlist): + albow.music.change_playlist(new_playlist) def start_next_music(): """Start playing the next item from the current playlist immediately."""