sudo apt-get install ttf-ancient-fonts ttf-ubuntu-font-family portaudio
-Pour compiler kivy avec la librairie SDL2, il faut certains paquets installés:
+To compile Kivy with the SDL2 library, you need some packages:
sudo apt-get install libsdl2-dev libsdl2-image-dev libsdl2-mixer-dev libsdl2-ttf-dev
### Options available at launch
All the options below are optional; usually, running the program in the correct
-folder is enough
+folder is enough. Most of the parameters can be defined also in the config file.
+The command line parameters always take precedence.
* `-h, --help`: shows a list of available options
* `-c CONFIG, --config CONFIG`: gives the configuration file to load (by
default, `config.yml` in the current folder).
* `-p MUSIC_PATH, --music-path MUSIC_PATH`: gives the path to find the musics
(by default, the current folder)
- * `-d, --debug`: show debug informations in the terminal (disabled by default)
+ * `--no-debug, --debug`: show debug informations in the terminal (disabled by
+ default)
* `-V, --version`: show current version and exit (only for the compiled
version)
* `-L, --language`: change application language. Current languages: fr, en
(default 'fr')
- * `--no-focus-warning`: don't show warning when focus gets lost.
+ * `--focus-warning, --no-focus-warning`: show / don't show warning when focus gets
+ lost (default is to show it)
The following options are reserved for a more advanced use of Music Sampler, or
in case of problem with the standard configuration:
- * `-m, --builtin-mixing`: make the sound mixing locally. By default, Music
- Sampler will let the system do it and open one channel per music loaded. Use
- it only if the system cannot handle it.
+ * `--no-builtin-mixing, --builtin-mixing`: make the sound mixing locally. By
+ default, Music Sampler will let the system do it and open one channel per
+ music loaded. Use it only if the system cannot handle it.
* `-l LATENCY, --latency LATENCY`: "low", "high" or a number of seconds
(default "high")
* `-b BLOCKSIZE, --blocksize BLOCKSIZE`: Number of frames for each mixing
The file contains several sections:
:::yaml
+ config:
+ ...
+
aliases:
...
keys:
...
+### `config`
+
+The config section lets you store configuration parameters that you would
+normally use in the command line parameters. The '-' in the long parameter name
+should be replaced by '_' (e.g. '--music-path' -> 'music_path'). For toggles
+(`debug`, `focus_warning`, `builtin_mixing`) use the version without 'no-' and
+specify `true` or `false` as value. Note that command line arguments always take
+precedence.
### `music_properties`
### Options disponibles au lancement
Toutes les options au lancement sont facultatives ; la plupart du temps lancer
-le programme dans le bon dossier suffit.
+le programme dans le bon dossier suffit. La plupart d'entre elles peuvent être
+définies également dans le fichier de config (à part `--config` bien sûr). Les
+arguments en ligne de commande ont toujours la priorité.
* `-h, --help` : affiche une liste des options disponibles.
* `-c CONFIG, --config CONFIG` : précise le fichier de configuration à charger
music_sampler).
* `-p MUSIC_PATH, --music-path MUSIC_PATH` : précise le chemin des musiques
(par défaut, le dossier courant).
- * `-d, --debug` : Affiche les informations de déboggage (désactivé par défaut)
+ * `--no-debug, --debug` : Affiche les informations de déboggage (désactivé par
+ défaut)
* `-V, --version` : affiche la version courante et quitte (utilisable
uniquement pour la version compilée).
* `-L, --language` : change la langue de l'application. Actuellement: fr, en
(par défaut 'fr')
- * `--no-focus-warning`: Ne pas afficher d'avertissement lorsque l'application
- perd le focus.
+ * `--focus-warning, --no-focus-warning`: Afficher / Ne pas afficher
+ d'avertissement lorsque l'application perd le focus (activé par défaut).
Les options suivantes sont plutôt réservées à un usage avancé de music_sampler,
ou en cas de problème avec la configuration standard :
- * `-m, --builtin-mixing` Effectue en interne le mixage des sons. Par défaut,
- music_sampler confie le mixage au système : n'activer cette option que si le
- système n'y parvient pas.
+ * `--no-builtin-mixing, --builtin-mixing` Effectue en interne le mixage des
+ sons. Par défaut, music_sampler confie le mixage au système : n'activer
+ cette option que si le système n'y parvient pas.
* `-l LATENCY, --latency LATENCY` : latence. Préciser "low", "high" ou un
nombre de secondes (par défaut, "high")
* `-b BLOCKSIZE, --blocksize BLOCKSIZE` : taille des blocs. Nombre de frames
Le fichier contient plusieurs sections :
:::yaml
+ config:
+ ...
+
aliases:
...
...
+### `config`
+
+La section config permet d'enregistrer les paramètres habituellement donnés en
+ligne de commande. Les '-' dans le nom du paramètre long doivent être remplacés
+par des '_' (par exemple '--music-path' -> 'music_path'). Pour les switches
+(`debug`, `focus_warning`, `builtin_mixing`), utilisez la version sans le 'no-'
+et spécifiez `true` / `false` en valeur. Notez que les arguments donnés en ligne
+de commande sont toujours prioritaires sur les valeurs du fichier.
+
### `music_properties` : propriétés des musiques
Cette section sert à définir des propriétés globales des musiques.
import sounddevice as sd
import logging
import gettext
+import yaml
gettext.install('music_sampler')
Logger = logging.getLogger("kivy")
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]
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"),
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("--no-focus-warning",
- action='store_true',
- help=_("Don't show warning when focus is lost")
- )
- parser.add_argument("-L", "--language",
+ parser.add_argument("-c", "--config",
+ default="config.yml",
required=False,
- default="fr",
- help=_("Select another language")
- )
+ 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\
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
- Config.no_focus_warning = args.no_focus_warning
- if args.language != 'en':
+ if Config.device is not None:
+ sd.default.device = Config.device
+
+ if Config.list_devices:
+ print(sd.query_devices())
+ sys.exit()
+
+ if Config.debug:
+ sys.argv.extend(["-c", "kivy:log_level:debug"])
+
+ if Config.language != 'en':
gettext.translation("music_sampler",
localedir=path() + '/locales',
- languages=[args.language]).install()
- if args.music_path.endswith("/"):
- Config.music_path = args.music_path
- else:
- Config.music_path = args.music_path + "/"
+ languages=[Config.language]).install()
+ if not Config.music_path.endswith("/"):
+ Config.music_path = Config.music_path + "/"
-class DebugModeAction(argparse.Action):
- def __call__(self, parser, namespace, values, option_string=None):
- sys.argv.extend(["-c", "kivy:log_level:debug"])
+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 = {}
-class SelectDeviceAction(argparse.Action):
- def __call__(self, parser, namespace, values, option_string=None):
- sd.default.device = values
+ 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):