Mercurial > touhou
annotate pytouhou/ui/music.pyx @ 612:73f134f84c7f
Request a RGB888 context, since SDL2’s default of RGB332 sucks.
On X11/GLX, it will select the first config available, that is the best
one, while on EGL it will iterate over them to select the one closest
to what the application requested.
Of course, anything lower than RGB888 looks bad and we really don’t
want that.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Thu, 26 Mar 2015 20:20:37 +0100 |
parents | c84227022765 |
children | 4ce3ef053a25 |
rev | line source |
---|---|
321
61adb5453e46
Implement music playback.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
1 # -*- encoding: utf-8 -*- |
61adb5453e46
Implement music playback.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
2 ## |
61adb5453e46
Implement music playback.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
3 ## Copyright (C) 2012 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
61adb5453e46
Implement music playback.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
4 ## |
61adb5453e46
Implement music playback.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
5 ## This program is free software; you can redistribute it and/or modify |
61adb5453e46
Implement music playback.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
6 ## it under the terms of the GNU General Public License as published |
61adb5453e46
Implement music playback.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
7 ## by the Free Software Foundation; version 3 only. |
61adb5453e46
Implement music playback.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
8 ## |
61adb5453e46
Implement music playback.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
9 ## This program is distributed in the hope that it will be useful, |
61adb5453e46
Implement music playback.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
10 ## but WITHOUT ANY WARRANTY; without even the implied warranty of |
61adb5453e46
Implement music playback.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
11 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
61adb5453e46
Implement music playback.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
12 ## GNU General Public License for more details. |
61adb5453e46
Implement music playback.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
13 ## |
61adb5453e46
Implement music playback.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
14 |
61adb5453e46
Implement music playback.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
15 |
341
61caded6b4f5
Clean music playback API a little.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
325
diff
changeset
|
16 from os.path import join |
421
b1248bab2d0f
Add back music and SFX playback using SDL_mixer instead of pyglet, and add FLAC and Vorbis support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
385
diff
changeset
|
17 from glob import glob |
501
4778c482f24a
Make SDL(sound=False) work again, and disable sound if an exception occurs while setting it up.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
474
diff
changeset
|
18 from pytouhou.lib import sdl |
590
e15672733c93
Switch to Python 3.x instead of 2.7.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
535
diff
changeset
|
19 from pytouhou.lib.sdl cimport load_music, Music, load_chunk, Chunk |
369
f305cdd6f6c5
Fix crash with the demo version of Touhou 6
Thibaut Girka <thib@sitedethib.com>
parents:
343
diff
changeset
|
20 from pytouhou.utils.helpers import get_logger |
528
7c3c90468996
Inherit music players from a base class.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
501
diff
changeset
|
21 from pytouhou.game.music cimport MusicPlayer |
369
f305cdd6f6c5
Fix crash with the demo version of Touhou 6
Thibaut Girka <thib@sitedethib.com>
parents:
343
diff
changeset
|
22 |
f305cdd6f6c5
Fix crash with the demo version of Touhou 6
Thibaut Girka <thib@sitedethib.com>
parents:
343
diff
changeset
|
23 logger = get_logger(__name__) |
f305cdd6f6c5
Fix crash with the demo version of Touhou 6
Thibaut Girka <thib@sitedethib.com>
parents:
343
diff
changeset
|
24 |
f305cdd6f6c5
Fix crash with the demo version of Touhou 6
Thibaut Girka <thib@sitedethib.com>
parents:
343
diff
changeset
|
25 |
528
7c3c90468996
Inherit music players from a base class.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
501
diff
changeset
|
26 cdef class BGMPlayer(MusicPlayer): |
7c3c90468996
Inherit music players from a base class.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
501
diff
changeset
|
27 cdef list bgms |
7c3c90468996
Inherit music players from a base class.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
501
diff
changeset
|
28 |
341
61caded6b4f5
Clean music playback API a little.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
325
diff
changeset
|
29 def __init__(self, resource_loader, bgms): |
61caded6b4f5
Clean music playback API a little.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
325
diff
changeset
|
30 self.bgms = [] |
61caded6b4f5
Clean music playback API a little.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
325
diff
changeset
|
31 for bgm in bgms: |
61caded6b4f5
Clean music playback API a little.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
325
diff
changeset
|
32 if not bgm: |
61caded6b4f5
Clean music playback API a little.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
325
diff
changeset
|
33 self.bgms.append(None) |
61caded6b4f5
Clean music playback API a little.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
325
diff
changeset
|
34 continue |
61caded6b4f5
Clean music playback API a little.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
325
diff
changeset
|
35 posname = bgm[1].replace('bgm/', '').replace('.mid', '.pos') |
369
f305cdd6f6c5
Fix crash with the demo version of Touhou 6
Thibaut Girka <thib@sitedethib.com>
parents:
343
diff
changeset
|
36 try: |
f305cdd6f6c5
Fix crash with the demo version of Touhou 6
Thibaut Girka <thib@sitedethib.com>
parents:
343
diff
changeset
|
37 track = resource_loader.get_track(posname) |
f305cdd6f6c5
Fix crash with the demo version of Touhou 6
Thibaut Girka <thib@sitedethib.com>
parents:
343
diff
changeset
|
38 except KeyError: |
535
a50c0a1b628f
Don’t stop music loading if the pos file isn’t found.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
529
diff
changeset
|
39 track = None |
590
e15672733c93
Switch to Python 3.x instead of 2.7.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
535
diff
changeset
|
40 logger.warn('Music description “%s” not found, continuing without looping data.', posname) |
e15672733c93
Switch to Python 3.x instead of 2.7.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
535
diff
changeset
|
41 globname = join(resource_loader.game_dir, bgm[1]).replace('.mid', '.*') |
421
b1248bab2d0f
Add back music and SFX playback using SDL_mixer instead of pyglet, and add FLAC and Vorbis support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
385
diff
changeset
|
42 filenames = glob(globname) |
b1248bab2d0f
Add back music and SFX playback using SDL_mixer instead of pyglet, and add FLAC and Vorbis support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
385
diff
changeset
|
43 for filename in reversed(filenames): |
b1248bab2d0f
Add back music and SFX playback using SDL_mixer instead of pyglet, and add FLAC and Vorbis support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
385
diff
changeset
|
44 try: |
590
e15672733c93
Switch to Python 3.x instead of 2.7.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
535
diff
changeset
|
45 source = load_music(filename) |
421
b1248bab2d0f
Add back music and SFX playback using SDL_mixer instead of pyglet, and add FLAC and Vorbis support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
385
diff
changeset
|
46 except sdl.SDLError as error: |
590
e15672733c93
Switch to Python 3.x instead of 2.7.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
535
diff
changeset
|
47 logger.debug('Music file “%s” unreadable: %s', filename, error) |
421
b1248bab2d0f
Add back music and SFX playback using SDL_mixer instead of pyglet, and add FLAC and Vorbis support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
385
diff
changeset
|
48 continue |
b1248bab2d0f
Add back music and SFX playback using SDL_mixer instead of pyglet, and add FLAC and Vorbis support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
385
diff
changeset
|
49 else: |
535
a50c0a1b628f
Don’t stop music loading if the pos file isn’t found.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
529
diff
changeset
|
50 if track is not None: |
a50c0a1b628f
Don’t stop music loading if the pos file isn’t found.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
529
diff
changeset
|
51 source.set_loop_points(track.start / 44100., track.end / 44100.) #TODO: retrieve the sample rate from the actual track. |
421
b1248bab2d0f
Add back music and SFX playback using SDL_mixer instead of pyglet, and add FLAC and Vorbis support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
385
diff
changeset
|
52 self.bgms.append(source) |
590
e15672733c93
Switch to Python 3.x instead of 2.7.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
535
diff
changeset
|
53 logger.debug('Music file “%s” opened.', filename) |
421
b1248bab2d0f
Add back music and SFX playback using SDL_mixer instead of pyglet, and add FLAC and Vorbis support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
385
diff
changeset
|
54 break |
b1248bab2d0f
Add back music and SFX playback using SDL_mixer instead of pyglet, and add FLAC and Vorbis support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
385
diff
changeset
|
55 else: |
b1248bab2d0f
Add back music and SFX playback using SDL_mixer instead of pyglet, and add FLAC and Vorbis support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
385
diff
changeset
|
56 self.bgms.append(None) |
590
e15672733c93
Switch to Python 3.x instead of 2.7.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
535
diff
changeset
|
57 logger.warn('No working music file for “%s”, disabling bgm.', globname) |
342
83c9354ff3ef
Fix crash when changing levels.
Thibaut Girka <thib@sitedethib.com>
parents:
341
diff
changeset
|
58 |
528
7c3c90468996
Inherit music players from a base class.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
501
diff
changeset
|
59 cpdef play(self, index): |
590
e15672733c93
Switch to Python 3.x instead of 2.7.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
535
diff
changeset
|
60 cdef Music bgm |
341
61caded6b4f5
Clean music playback API a little.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
325
diff
changeset
|
61 bgm = self.bgms[index] |
501
4778c482f24a
Make SDL(sound=False) work again, and disable sound if an exception occurs while setting it up.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
474
diff
changeset
|
62 if bgm is not None: |
421
b1248bab2d0f
Add back music and SFX playback using SDL_mixer instead of pyglet, and add FLAC and Vorbis support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
385
diff
changeset
|
63 bgm.play(-1) |
341
61caded6b4f5
Clean music playback API a little.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
325
diff
changeset
|
64 |
343
94fdb6c782c1
Implement sfx for player and enemies.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
342
diff
changeset
|
65 |
528
7c3c90468996
Inherit music players from a base class.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
501
diff
changeset
|
66 cdef class SFXPlayer(MusicPlayer): |
7c3c90468996
Inherit music players from a base class.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
501
diff
changeset
|
67 cdef object loader |
7c3c90468996
Inherit music players from a base class.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
501
diff
changeset
|
68 cdef dict channels, sounds |
7c3c90468996
Inherit music players from a base class.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
501
diff
changeset
|
69 cdef float volume |
7c3c90468996
Inherit music players from a base class.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
501
diff
changeset
|
70 cdef int next_channel |
7c3c90468996
Inherit music players from a base class.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
501
diff
changeset
|
71 |
379
e0e284fcb288
Make a sound when an enemy is hit.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
377
diff
changeset
|
72 def __init__(self, loader, volume=.42): |
343
94fdb6c782c1
Implement sfx for player and enemies.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
342
diff
changeset
|
73 self.loader = loader |
421
b1248bab2d0f
Add back music and SFX playback using SDL_mixer instead of pyglet, and add FLAC and Vorbis support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
385
diff
changeset
|
74 self.channels = {} |
343
94fdb6c782c1
Implement sfx for player and enemies.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
342
diff
changeset
|
75 self.sounds = {} |
379
e0e284fcb288
Make a sound when an enemy is hit.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
377
diff
changeset
|
76 self.volume = volume |
421
b1248bab2d0f
Add back music and SFX playback using SDL_mixer instead of pyglet, and add FLAC and Vorbis support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
385
diff
changeset
|
77 self.next_channel = 0 |
343
94fdb6c782c1
Implement sfx for player and enemies.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
342
diff
changeset
|
78 |
528
7c3c90468996
Inherit music players from a base class.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
501
diff
changeset
|
79 cdef int get_channel(self, name): |
421
b1248bab2d0f
Add back music and SFX playback using SDL_mixer instead of pyglet, and add FLAC and Vorbis support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
385
diff
changeset
|
80 if name not in self.channels: |
b1248bab2d0f
Add back music and SFX playback using SDL_mixer instead of pyglet, and add FLAC and Vorbis support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
385
diff
changeset
|
81 self.channels[name] = self.next_channel |
b1248bab2d0f
Add back music and SFX playback using SDL_mixer instead of pyglet, and add FLAC and Vorbis support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
385
diff
changeset
|
82 self.next_channel += 1 |
b1248bab2d0f
Add back music and SFX playback using SDL_mixer instead of pyglet, and add FLAC and Vorbis support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
385
diff
changeset
|
83 return self.channels[name] |
379
e0e284fcb288
Make a sound when an enemy is hit.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
377
diff
changeset
|
84 |
590
e15672733c93
Switch to Python 3.x instead of 2.7.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
535
diff
changeset
|
85 cdef Chunk get_sound(self, name): |
e15672733c93
Switch to Python 3.x instead of 2.7.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
535
diff
changeset
|
86 cdef Chunk chunk |
379
e0e284fcb288
Make a sound when an enemy is hit.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
377
diff
changeset
|
87 if name not in self.sounds: |
501
4778c482f24a
Make SDL(sound=False) work again, and disable sound if an exception occurs while setting it up.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
474
diff
changeset
|
88 try: |
602
c84227022765
Don’t crash when a sound file isn’t present in the resources.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
590
diff
changeset
|
89 wave_file = self.loader.get_file(name) |
590
e15672733c93
Switch to Python 3.x instead of 2.7.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
535
diff
changeset
|
90 chunk = load_chunk(wave_file) |
602
c84227022765
Don’t crash when a sound file isn’t present in the resources.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
590
diff
changeset
|
91 except (KeyError, sdl.SDLError) as error: |
c84227022765
Don’t crash when a sound file isn’t present in the resources.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
590
diff
changeset
|
92 logger.warn('Sound “%s” not found: %s', name, error) |
501
4778c482f24a
Make SDL(sound=False) work again, and disable sound if an exception occurs while setting it up.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
474
diff
changeset
|
93 chunk = None |
4778c482f24a
Make SDL(sound=False) work again, and disable sound if an exception occurs while setting it up.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
474
diff
changeset
|
94 else: |
4778c482f24a
Make SDL(sound=False) work again, and disable sound if an exception occurs while setting it up.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
474
diff
changeset
|
95 chunk.set_volume(self.volume) |
455
6864a38b2413
Make pytouhou.lib.sdl cimportable, and convert pytouhou.ui.window.* to extension types.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
421
diff
changeset
|
96 self.sounds[name] = chunk |
343
94fdb6c782c1
Implement sfx for player and enemies.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
342
diff
changeset
|
97 return self.sounds[name] |
94fdb6c782c1
Implement sfx for player and enemies.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
342
diff
changeset
|
98 |
528
7c3c90468996
Inherit music players from a base class.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
501
diff
changeset
|
99 cpdef play(self, name): |
379
e0e284fcb288
Make a sound when an enemy is hit.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
377
diff
changeset
|
100 sound = self.get_sound(name) |
501
4778c482f24a
Make SDL(sound=False) work again, and disable sound if an exception occurs while setting it up.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
474
diff
changeset
|
101 if sound is None: |
4778c482f24a
Make SDL(sound=False) work again, and disable sound if an exception occurs while setting it up.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
474
diff
changeset
|
102 return |
421
b1248bab2d0f
Add back music and SFX playback using SDL_mixer instead of pyglet, and add FLAC and Vorbis support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
385
diff
changeset
|
103 channel = self.get_channel(name) |
b1248bab2d0f
Add back music and SFX playback using SDL_mixer instead of pyglet, and add FLAC and Vorbis support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
385
diff
changeset
|
104 sound.play(channel, 0) |
379
e0e284fcb288
Make a sound when an enemy is hit.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
377
diff
changeset
|
105 |
528
7c3c90468996
Inherit music players from a base class.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
501
diff
changeset
|
106 cpdef set_volume(self, name, float volume): |
529
bd0c15d28dd6
Always verify chunks are not None before using them, fix crash when audio is disabled.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
528
diff
changeset
|
107 sound = self.get_sound(name) |
bd0c15d28dd6
Always verify chunks are not None before using them, fix crash when audio is disabled.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
528
diff
changeset
|
108 if sound is not None: |
bd0c15d28dd6
Always verify chunks are not None before using them, fix crash when audio is disabled.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
528
diff
changeset
|
109 sound.set_volume(volume) |