Draw tile backgrounds
[naja.git] / naja / sound.py
1 """Sound utilities."""
2
3 from pygame import mixer
4
5 from naja.options import options
6 from naja.resources import resources
7 from naja.constants import (
8     FREQ, BITSIZE, CHANNELS, BUFFER, DEFAULT_SOUND_VOLUME,
9     DEFAULT_MUSIC_VOLUME)
10
11
12 class DummySound(object):
13     def init(self):
14         pass
15
16     def play_sound(self, name, volume=DEFAULT_SOUND_VOLUME):
17         pass
18
19     def play_music(self, name, volume=DEFAULT_MUSIC_VOLUME):
20         pass
21
22     def pause_music(self):
23         pass
24
25     def resume_music(self):
26         pass
27
28     def stop(self):
29         pass
30
31
32 class PygameSound(object):
33     def __init__(self):
34         self._sounds = {}
35
36     def init(self):
37         mixer.init(FREQ, BITSIZE, CHANNELS, BUFFER)
38         silence = self.load_sound("silence.ogg")
39         if silence.get_length() < 1:
40             raise RuntimeError("Sound load error - silence.ogg too short")
41         self.play_sound("silence.ogg")
42
43     def load_sound(self, name):
44         track_name = resources.get_resource_path("sounds", name)
45         sound = self._sounds.get(track_name)
46         if sound is None:
47             sound = self._sounds[track_name] = mixer.Sound(track_name)
48         return sound
49
50     def play_sound(self, name, volume=DEFAULT_SOUND_VOLUME):
51         sound = self.load_sound(name)
52         if sound is not None:
53             sound.set_volume(volume)
54             sound.play()
55
56     def play_music(self, name, volume=DEFAULT_MUSIC_VOLUME):
57         if not options.music:
58             return
59         track_name = resources.get_resource_path("music", name)
60         mixer.music.load(track_name)
61         mixer.music.set_volume(volume)
62         mixer.music.play(-1)  # loop sound
63
64     def pause_music(self):
65         mixer.music.pause()
66
67     def unpause_music(self):
68         mixer.music.unpause()
69
70     def stop(self):
71         mixer.fadeout(1000)
72         mixer.music.stop()
73
74
75 class SoundProxy(object):
76     def __init__(self):
77         self._sound = DummySound()
78
79     def init(self):
80         """Attempt to initialize the sound system."""
81         if options.sound:
82             try:
83                 pyg_sound = PygameSound()
84                 pyg_sound.init()
85                 self._sound = pyg_sound
86             except Exception, err:
87                 print "Failed to enable sound: %r" % (err,)
88
89     def __getattr__(self, name):
90         return getattr(self._sound, name)
91
92
93 sound = SoundProxy()