X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=music_sampler%2Fhelpers.py;h=943e5a197465143dc2f47e193bfbcc0f3bdf94e2;hb=16847231fa5a85cbb0f792e6e461392879047c36;hp=6acaba4f7e9300523ef6c9a20c389b2eb9d79484;hpb=2010311b76299bb3f0803a52510ab41d64d8e41a;p=perso%2FImmae%2FProjets%2FPython%2FMusicSampler.git diff --git a/music_sampler/helpers.py b/music_sampler/helpers.py index 6acaba4..943e5a1 100644 --- a/music_sampler/helpers.py +++ b/music_sampler/helpers.py @@ -5,6 +5,9 @@ import os import math import sounddevice as sd import logging +import gettext +import yaml +gettext.install('music_sampler') Logger = logging.getLogger("kivy") from . import sysfont @@ -50,6 +53,96 @@ def path(): else: return os.path.dirname(os.path.realpath(__file__)) + +Configs = { + 'music_path': { + 'abbr': '-p', + 'default': '.', + 'help': _("Folder in which to find the music files"), + 'type': None + }, + 'latency': { + 'abbr': '-l', + 'default': 'high', + 'help': _("Latency: low, high or number of seconds"), + 'type': None + }, + 'language': { + 'abbr': '-L', + 'default': "fr", + 'help': _("Select another language"), + 'type': None + }, + 'device': { + 'abbr': '-d', + 'default': None, + 'help': _("Select this sound device"), + 'type': None + }, + 'blocksize': { + 'abbr': '-b', + 'default': 0, + 'help': _("Blocksize: If not 0, the number of frames to take\ + at each step for the mixer"), + 'type': int + }, + 'frame_rate': { + 'abbr': '-f', + 'default': 44100, + 'help': _("Frame rate to play the musics"), + 'type': int + }, + 'channels': { + 'abbr': '-x', + 'default': 2, + 'help': _("Number of channels to use"), + 'type': int + }, + 'sample_width': { + 'abbr': '-s', + 'default': 2, + 'help': _("Sample width (number of bytes for each frame)"), + 'type': int + }, + 'builtin_mixing': { + 'default': False, + 'help_yes': _("Make the mixing of sounds manually\ + (do it if the system cannot handle it correctly)"), + 'help_no': _("Don't make the mixing of sounds manually (default)"), + 'type': 'boolean' + }, + 'debug': { + 'abbr': '-d', + 'default': False, + 'help_yes': _("Print messages in console"), + 'help_no': _("Don't print messages in console (default)"), + 'type': 'boolean' + }, + 'focus_warning': { + 'default': True, + 'help_yes': _("Show a warning when focus is lost (default)"), + 'help_no': _("Don't show warning when focus is lost"), + 'type': 'boolean' + }, + 'list_devices': { + 'help': _("List available sound devices"), + 'type': 'action' + }, +} +Configs_order = [ + 'debug', + 'music_path', + 'builtin_mixing', + 'latency', + 'blocksize', + 'frame_rate', + 'channels', + 'sample_width', + 'focus_warning', + 'language', + 'list_devices', + 'device', +] def parse_args(): argv = sys.argv[1 :] sys.argv = sys.argv[: 1] @@ -66,103 +159,101 @@ def parse_args(): sys.argv.extend(["-c", "kivy:log_name:/tmp/music_sampler_%_.txt"]) parser = argparse.ArgumentParser( - description="A Music Sampler application.", - formatter_class=argparse.ArgumentDefaultsHelpFormatter) - parser.add_argument("-c", "--config", - default="config.yml", - required=False, - help="Config file to load") - parser.add_argument("-p", "--music-path", - default=".", - required=False, - help="Folder in which to find the music files") - parser.add_argument("-d", "--debug", - nargs=0, - action=DebugModeAction, - help="Print messages in console") - parser.add_argument("-m", "--builtin-mixing", - action="store_true", - help="Make the mixing of sounds manually\ - (do it if the system cannot handle it correctly)") - parser.add_argument("-l", "--latency", - default="high", - required=False, - help="Latency: low, high or number of seconds") - parser.add_argument("-b", "--blocksize", - default=0, - type=int, - required=False, - help="Blocksize: If not 0, the number of frames to take\ - at each step for the mixer") - parser.add_argument("-f", "--frame-rate", - default=44100, - type=int, - required=False, - help="Frame rate to play the musics") - parser.add_argument("-x", "--channels", - default=2, - type=int, - required=False, - help="Number of channels to use") - parser.add_argument("-s", "--sample-width", - default=2, - type=int, - required=False, - help="Sample width (number of bytes for each frame)") + argument_default=argparse.SUPPRESS, + description=_("A Music Sampler application.")) parser.add_argument("-V", "--version", action="version", - help="Displays the current version and exits. Only use\ - in bundled package", + help=_("Displays the current version and exits. Only use\ + in bundled package"), version=show_version()) - parser.add_argument("--device", - action=SelectDeviceAction, - help="Select this sound device" - ) - parser.add_argument("--list-devices", - nargs=0, - action=ListDevicesAction, - help="List available sound devices" - ) + parser.add_argument("-c", "--config", + default="config.yml", + required=False, + help=_("Config file to load (default: config.yml)")) + for argument in Configs_order: + arg = Configs[argument] + if arg['type'] != 'boolean' and arg['type'] != 'action': + parser.add_argument(arg['abbr'], '--' + argument.replace('_', '-'), + type=arg['type'], + help=arg['help']+_(" (default: {})").format(arg['default'])) + elif arg['type'] == 'boolean': + parser.add_argument('--' + argument.replace('_', '-'), + action='store_const', const=True, + help=arg['help_yes']) + parser.add_argument('--no-' + argument.replace('_', '-'), + action='store_const', const=True, + help=arg['help_no']) + else: + parser.add_argument('--' + argument.replace('_', '-'), + action='store_const', const=True, + help=arg['help']) parser.add_argument('--', dest="args", - help="Kivy arguments. All arguments after this are interpreted\ - by Kivy. Pass \"-- --help\" to get Kivy's usage.") + help=_("Kivy arguments. All arguments after this are interpreted\ + by Kivy. Pass \"-- --help\" to get Kivy's usage.")) args = parser.parse_args(argv) Config.yml_file = args.config + build_config(args) - Config.latency = args.latency - Config.blocksize = args.blocksize - Config.frame_rate = args.frame_rate - Config.channels = args.channels - Config.sample_width = args.sample_width - Config.builtin_mixing = args.builtin_mixing - if args.music_path.endswith("/"): - Config.music_path = args.music_path - else: - Config.music_path = args.music_path + "/" + if Config.device is not None: + sd.default.device = Config.device + + if Config.list_devices: + print(sd.query_devices()) + sys.exit() -class DebugModeAction(argparse.Action): - def __call__(self, parser, namespace, values, option_string=None): + if Config.debug: sys.argv.extend(["-c", "kivy:log_level:debug"]) -class SelectDeviceAction(argparse.Action): - def __call__(self, parser, namespace, values, option_string=None): - sd.default.device = values + if Config.language != 'en': + gettext.translation("music_sampler", + localedir=path() + '/locales', + languages=[Config.language]).install() + if not Config.music_path.endswith("/"): + Config.music_path = Config.music_path + "/" + +def build_config(args): + stream = open(Config.yml_file, "r") + try: + config = yaml.safe_load(stream) + except Exception as e: + error_print("Error while loading config file: {}".format(e)) + config = {} + stream.close() + if 'config' in config: + config = config['config'] + else: + config = {} + + for config_item in Configs_order: + if Configs[config_item]['type'] != 'boolean' and \ + Configs[config_item]['type'] != 'action': + t = Configs[config_item]['type'] or str + if hasattr(args, config_item): + setattr(Config, config_item, getattr(args, config_item)) + elif config_item in config: + setattr(Config, config_item, t(config[config_item])) + else: + setattr(Config, config_item, Configs[config_item]['default']) + elif Configs[config_item]['type'] == 'boolean': + if hasattr(args, 'no_' + config_item) or hasattr(args, config_item): + setattr(Config, config_item, hasattr(args, config_item)) + elif config_item in config: + setattr(Config, config_item, config[config_item]) + else: + setattr(Config, config_item, Configs[config_item]['default']) + else: + setattr(Config, config_item, hasattr(args, config_item)) -class ListDevicesAction(argparse.Action): - nargs = 0 - def __call__(self, parser, namespace, values, option_string=None): - print(sd.query_devices()) - sys.exit() def show_version(): if getattr(sys, 'frozen', False): with open(path() + ".pyinstaller_commit", "r") as f: return f.read() else: - return "option '-v' can only be used in bundled package" + return _("option '-V' can only be used in bundled package") def duration_to_min_sec(duration): minutes = int(duration / 60)