- loading sfx at init recursively from project path and default path

- return None if config value is missing
This commit is contained in:
Frank DeMarco 2020-02-14 02:10:46 -05:00
parent 7a4f318ac2
commit 7abf359ede
3 changed files with 78 additions and 20 deletions

View File

@ -1,7 +1,4 @@
from os import listdir
from os.path import join
from pygame.mixer import Channel, Sound, music, find_channel, get_num_channels
import os, re, pygame
from .GameChild import *
from .Input import *
@ -18,6 +15,8 @@ class Audio(GameChild):
if self.check_command_line("-mute"):
self.volume = 0
self.subscribe(self.respond)
self.sfx = {}
self.load_sfx()
def set_volume(self, volume=None, increment=None, mute=False):
if mute:
@ -40,9 +39,54 @@ class Audio(GameChild):
elif compare(event, "volume-down"):
self.set_volume(increment=self.DOWN)
# Loading SFX procedure
#
# - load config file name/path definitions at init
# - check project specific sfx paths at init, load any that don't conflict
# - check default sfx paths at init, load any that don't conflict
# - repository paths are not loaded at init but can replace loaded paths
# and get written to config file
#
def load_sfx(self, path=None):
for name, path in self.get_configuration("sfx").items():
self.load_sfx_file(sfx, path, name, True)
if path is None:
path = self.get_configuration("audio", "sfx-project-path") + \
self.get_configuration("audio", "sfx-default-path")
if isinstance(path, str):
path = [path]
for root in path:
prefix = ""
print(root)
root = self.get_resource(root)
print(root)
print("checking {} for sound effects".format(root))
if root:
if os.path.isfile(root):
self.load_sfx_file(root)
else:
for node, branches, leaves in os.walk(root, followlinks=True):
for leaf in leaves:
prefix = re.sub(root, "", node)
prefix = re.sub("^/", "", prefix)
if prefix:
prefix = re.sub("/", "_", prefix) + "_"
self.load_sfx_file(os.path.join(node, leaf,), prefix=prefix)
def load_sfx_file(self, path, name=None, replace=False, prefix=""):
path = self.get_resource(path)
if path and path.split(".")[-1] in self.get_configuration("audio", "sfx-extensions"):
if name is None:
name = prefix + re.sub("\.[^.]*$", "", os.path.basename(path))
if replace and name in self.sfx:
print("skipping existing sound effect for %s => %s" % (path, name))
else:
print("loading sound effect %s into %s" % (path, name))
self.sfx[name] = SoundEffect(self, path)
def update(self):
for ii in range(get_num_channels()):
channel = Channel(ii)
for ii in range(pygame.mixer.get_num_channels()):
channel = pygame.mixer.Channel(ii)
sound = channel.get_sound()
if sound is not None:
if sound not in self.original_volumes.keys():
@ -50,11 +94,11 @@ class Audio(GameChild):
sound.set_volume(self.original_volumes[sound] * self.volume)
class SoundEffect(GameChild, Sound):
class SoundEffect(GameChild, pygame.mixer.Sound):
def __init__(self, parent, path, volume=1.0):
GameChild.__init__(self, parent)
Sound.__init__(self, path)
pygame.mixer.Sound.__init__(self, path)
self.display_surface = self.get_display_surface()
self.initial_volume = volume
self.set_volume(volume)
@ -62,7 +106,7 @@ class SoundEffect(GameChild, Sound):
def play(self, loops=0, maxtime=0, fade_ms=0, position=None, x=None):
self.set_volume(self.initial_volume *
self.get_configuration("audio", "sfx-volume"))
channel = Sound.play(self, loops, maxtime, fade_ms)
channel = pygame.mixer.Sound.play(self, loops, maxtime, fade_ms)
if x is not None:
position = float(x) / self.display_surface.get_width()
if position is not None and channel is not None:

View File

@ -140,8 +140,11 @@ class Configuration(RawConfigParser):
set_option(section, "cancel-flag-key", "cancel", False)
section = "audio"
add_section(section)
set_option(section, "sfx-path", "aud/fx/", False)
set_option(section, "sfx-default-path", "~/storage/audio/sfx/default", False)
set_option(section, "sfx-repository-path", "~/storage/audio/sfx/all", False)
set_option(section, "sfx-project-path", "sfx", False)
set_option(section, "sfx-volume", "1.0", False)
set_option(section, "sfx-extensions", "wav, ogg, mp3", False)
section = "interpolator-gui"
add_section(section)
set_option(section, "margin", "80", False)
@ -428,9 +431,15 @@ class TypeDeclarations(dict):
"bool": "single-xy"},
"audio": {"path": "sfx-path",
"audio": {
"float": "sfx-volume"},
"list": [
"sfx-extensions", "sfx-default-path", "sfx-repository-path",
"sfx-project-path"
],
"float": "sfx-volume"
},
"event": {"int": "command-id-offset"},

View File

@ -25,12 +25,17 @@ class GameChild:
config = self.game.configuration
if option is None and section is None:
return config
if option and section:
rvalue = config.get(section, option)
if not linebreaks and isinstance(rvalue, str):
rvalue = rvalue.replace("\n", " ")
return rvalue
return config.get_section(section)
elif option and section:
if config.has_option(section, option):
rvalue = config.get(section, option)
if not linebreaks and isinstance(rvalue, str):
rvalue = rvalue.replace("\n", " ")
return rvalue
elif option is None:
if config.has_section(section):
return config.get_section(section)
else:
return {}
def get_input(self):
return self.game.input
@ -65,8 +70,8 @@ class GameChild:
path = join(root, rel_path)
if exists(path):
return path
self.print_debug("Couldn't find resource: {0} {1}".\
format(path_or_section, option))
self.print_debug("Couldn't find resource: {0} {1}".format(
path_or_section, option))
def is_shared_mode(self):
return self.check_command_line("s")