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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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)