aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsmaël Bouya <ismael.bouya@normalesup.org>2016-08-12 12:22:01 +0200
committerIsmaël Bouya <ismael.bouya@normalesup.org>2016-08-12 12:22:01 +0200
commit16847231fa5a85cbb0f792e6e461392879047c36 (patch)
treed5cc6d9d5f23ebf8c680421024e823c531d8623e
parent06ed113dedfb39cecf6f195bc38cbab9bb797189 (diff)
downloadMusicSampler-16847231fa5a85cbb0f792e6e461392879047c36.tar.gz
MusicSampler-16847231fa5a85cbb0f792e6e461392879047c36.tar.zst
MusicSampler-16847231fa5a85cbb0f792e6e461392879047c36.zip
Add config key to config.yml to store command line arguments
-rw-r--r--config.yml32
-rw-r--r--documentation_en.md28
-rw-r--r--documentation_fr.md29
-rw-r--r--music_sampler/app.py2
-rw-r--r--music_sampler/helpers.py243
5 files changed, 233 insertions, 101 deletions
diff --git a/config.yml b/config.yml
index e543b04..8802dcf 100644
--- a/config.yml
+++ b/config.yml
@@ -1,3 +1,31 @@
1#################################
2##### General configuration #####
3## Keep in mind that in-line option override these
4
5#option listed here are the default options.
6config:
7# debug info
8 debug: false
9# languages. Available: fr, en
10 language: fr
11# path to the musics.
12 music_path: .
13# The awful red message that shows up when you lose the focus
14 focus_warning: true
15# built-in mixing
16 builtin_mixing: true
17# Device used for playing musics. Default value depends on your system
18# device:
19# Advanced parameters: use at your own risk! (your computer probably won't explode, though)
20 latency: high
21 blocksize: 0
22 frame_rate: 44100
23 sample_width: 2
24 channels: 2
25
26
27
28
1################### 29###################
2##### Aliases ##### 30##### Aliases #####
3 31
@@ -41,8 +69,8 @@ music_properties:
41 name: Crocodile noise 69 name: Crocodile noise
42 gain: 1.2 70 gain: 1.2
43 71
44#################################################### 72###############################################################################
45##### Key properties: how do the key look like ##### 73##### Key properties: how do the key look like, and some other properties #####
46 74
47key_properties: 75key_properties:
48 'a': 76 'a':
diff --git a/documentation_en.md b/documentation_en.md
index 87b9bd7..1cf5cfd 100644
--- a/documentation_en.md
+++ b/documentation_en.md
@@ -39,7 +39,7 @@ must be available on your system, as well as the `portaudio` library:
39 39
40 sudo apt-get install ttf-ancient-fonts ttf-ubuntu-font-family portaudio 40 sudo apt-get install ttf-ancient-fonts ttf-ubuntu-font-family portaudio
41 41
42Pour compiler kivy avec la librairie SDL2, il faut certains paquets installés: 42To compile Kivy with the SDL2 library, you need some packages:
43 43
44 sudo apt-get install libsdl2-dev libsdl2-image-dev libsdl2-mixer-dev libsdl2-ttf-dev 44 sudo apt-get install libsdl2-dev libsdl2-image-dev libsdl2-mixer-dev libsdl2-ttf-dev
45 45
@@ -96,26 +96,29 @@ understand just by looking at it.
96### Options available at launch 96### Options available at launch
97 97
98All the options below are optional; usually, running the program in the correct 98All the options below are optional; usually, running the program in the correct
99folder is enough 99folder is enough. Most of the parameters can be defined also in the config file.
100The command line parameters always take precedence.
100 101
101 * `-h, --help`: shows a list of available options 102 * `-h, --help`: shows a list of available options
102 * `-c CONFIG, --config CONFIG`: gives the configuration file to load (by 103 * `-c CONFIG, --config CONFIG`: gives the configuration file to load (by
103 default, `config.yml` in the current folder). 104 default, `config.yml` in the current folder).
104 * `-p MUSIC_PATH, --music-path MUSIC_PATH`: gives the path to find the musics 105 * `-p MUSIC_PATH, --music-path MUSIC_PATH`: gives the path to find the musics
105 (by default, the current folder) 106 (by default, the current folder)
106 * `-d, --debug`: show debug informations in the terminal (disabled by default) 107 * `--no-debug, --debug`: show debug informations in the terminal (disabled by
108 default)
107 * `-V, --version`: show current version and exit (only for the compiled 109 * `-V, --version`: show current version and exit (only for the compiled
108 version) 110 version)
109 * `-L, --language`: change application language. Current languages: fr, en 111 * `-L, --language`: change application language. Current languages: fr, en
110 (default 'fr') 112 (default 'fr')
111 * `--no-focus-warning`: don't show warning when focus gets lost. 113 * `--focus-warning, --no-focus-warning`: show / don't show warning when focus gets
114 lost (default is to show it)
112 115
113The following options are reserved for a more advanced use of Music Sampler, or 116The following options are reserved for a more advanced use of Music Sampler, or
114in case of problem with the standard configuration: 117in case of problem with the standard configuration:
115 118
116 * `-m, --builtin-mixing`: make the sound mixing locally. By default, Music 119 * `--no-builtin-mixing, --builtin-mixing`: make the sound mixing locally. By
117 Sampler will let the system do it and open one channel per music loaded. Use 120 default, Music Sampler will let the system do it and open one channel per
118 it only if the system cannot handle it. 121 music loaded. Use it only if the system cannot handle it.
119 * `-l LATENCY, --latency LATENCY`: "low", "high" or a number of seconds 122 * `-l LATENCY, --latency LATENCY`: "low", "high" or a number of seconds
120 (default "high") 123 (default "high")
121 * `-b BLOCKSIZE, --blocksize BLOCKSIZE`: Number of frames for each mixing 124 * `-b BLOCKSIZE, --blocksize BLOCKSIZE`: Number of frames for each mixing
@@ -144,6 +147,9 @@ corresponding problems) or abort.
144The file contains several sections: 147The file contains several sections:
145 148
146 :::yaml 149 :::yaml
150 config:
151 ...
152
147 aliases: 153 aliases:
148 ... 154 ...
149 155
@@ -156,6 +162,14 @@ The file contains several sections:
156 keys: 162 keys:
157 ... 163 ...
158 164
165### `config`
166
167The config section lets you store configuration parameters that you would
168normally use in the command line parameters. The '-' in the long parameter name
169should be replaced by '_' (e.g. '--music-path' -> 'music_path'). For toggles
170(`debug`, `focus_warning`, `builtin_mixing`) use the version without 'no-' and
171specify `true` or `false` as value. Note that command line arguments always take
172precedence.
159 173
160### `music_properties` 174### `music_properties`
161 175
diff --git a/documentation_fr.md b/documentation_fr.md
index a55ae73..b739aa2 100644
--- a/documentation_fr.md
+++ b/documentation_fr.md
@@ -103,7 +103,9 @@ gardées d'une fois sur l'autre.
103### Options disponibles au lancement 103### Options disponibles au lancement
104 104
105Toutes les options au lancement sont facultatives ; la plupart du temps lancer 105Toutes les options au lancement sont facultatives ; la plupart du temps lancer
106le programme dans le bon dossier suffit. 106le programme dans le bon dossier suffit. La plupart d'entre elles peuvent être
107définies également dans le fichier de config (à part `--config` bien sûr). Les
108arguments en ligne de commande ont toujours la priorité.
107 109
108 * `-h, --help` : affiche une liste des options disponibles. 110 * `-h, --help` : affiche une liste des options disponibles.
109 * `-c CONFIG, --config CONFIG` : précise le fichier de configuration à charger 111 * `-c CONFIG, --config CONFIG` : précise le fichier de configuration à charger
@@ -111,20 +113,21 @@ le programme dans le bon dossier suffit.
111 music_sampler). 113 music_sampler).
112 * `-p MUSIC_PATH, --music-path MUSIC_PATH` : précise le chemin des musiques 114 * `-p MUSIC_PATH, --music-path MUSIC_PATH` : précise le chemin des musiques
113 (par défaut, le dossier courant). 115 (par défaut, le dossier courant).
114 * `-d, --debug` : Affiche les informations de déboggage (désactivé par défaut) 116 * `--no-debug, --debug` : Affiche les informations de déboggage (désactivé par
117 défaut)
115 * `-V, --version` : affiche la version courante et quitte (utilisable 118 * `-V, --version` : affiche la version courante et quitte (utilisable
116 uniquement pour la version compilée). 119 uniquement pour la version compilée).
117 * `-L, --language` : change la langue de l'application. Actuellement: fr, en 120 * `-L, --language` : change la langue de l'application. Actuellement: fr, en
118 (par défaut 'fr') 121 (par défaut 'fr')
119 * `--no-focus-warning`: Ne pas afficher d'avertissement lorsque l'application 122 * `--focus-warning, --no-focus-warning`: Afficher / Ne pas afficher
120 perd le focus. 123 d'avertissement lorsque l'application perd le focus (activé par défaut).
121 124
122Les options suivantes sont plutôt réservées à un usage avancé de music_sampler, 125Les options suivantes sont plutôt réservées à un usage avancé de music_sampler,
123ou en cas de problème avec la configuration standard : 126ou en cas de problème avec la configuration standard :
124 127
125 * `-m, --builtin-mixing` Effectue en interne le mixage des sons. Par défaut, 128 * `--no-builtin-mixing, --builtin-mixing` Effectue en interne le mixage des
126 music_sampler confie le mixage au système : n'activer cette option que si le 129 sons. Par défaut, music_sampler confie le mixage au système : n'activer
127 système n'y parvient pas. 130 cette option que si le système n'y parvient pas.
128 * `-l LATENCY, --latency LATENCY` : latence. Préciser "low", "high" ou un 131 * `-l LATENCY, --latency LATENCY` : latence. Préciser "low", "high" ou un
129 nombre de secondes (par défaut, "high") 132 nombre de secondes (par défaut, "high")
130 * `-b BLOCKSIZE, --blocksize BLOCKSIZE` : taille des blocs. Nombre de frames 133 * `-b BLOCKSIZE, --blocksize BLOCKSIZE` : taille des blocs. Nombre de frames
@@ -158,6 +161,9 @@ ne se lance pas du tout.
158Le fichier contient plusieurs sections : 161Le fichier contient plusieurs sections :
159 162
160 :::yaml 163 :::yaml
164 config:
165 ...
166
161 aliases: 167 aliases:
162 ... 168 ...
163 169
@@ -171,6 +177,15 @@ Le fichier contient plusieurs sections :
171 ... 177 ...
172 178
173 179
180### `config`
181
182La section config permet d'enregistrer les paramètres habituellement donnés en
183ligne de commande. Les '-' dans le nom du paramètre long doivent être remplacés
184par des '_' (par exemple '--music-path' -> 'music_path'). Pour les switches
185(`debug`, `focus_warning`, `builtin_mixing`), utilisez la version sans le 'no-'
186et spécifiez `true` / `false` en valeur. Notez que les arguments donnés en ligne
187de commande sont toujours prioritaires sur les valeurs du fichier.
188
174### `music_properties` : propriétés des musiques 189### `music_properties` : propriétés des musiques
175 190
176Cette section sert à définir des propriétés globales des musiques. 191Cette section sert à définir des propriétés globales des musiques.
diff --git a/music_sampler/app.py b/music_sampler/app.py
index e7c90db..ce84235 100644
--- a/music_sampler/app.py
+++ b/music_sampler/app.py
@@ -50,7 +50,7 @@ class Screen(FloatLayout):
50 Window.on_request_close = self.on_request_close 50 Window.on_request_close = self.on_request_close
51 51
52 def focus_changed(self, instance, focus): 52 def focus_changed(self, instance, focus):
53 if Config.no_focus_warning: 53 if not Config.focus_warning:
54 return 54 return
55 if not focus: 55 if not focus:
56 self.add_widget(self.unfocused_widget) 56 self.add_widget(self.unfocused_widget)
diff --git a/music_sampler/helpers.py b/music_sampler/helpers.py
index 2199058..943e5a1 100644
--- a/music_sampler/helpers.py
+++ b/music_sampler/helpers.py
@@ -6,6 +6,7 @@ import math
6import sounddevice as sd 6import sounddevice as sd
7import logging 7import logging
8import gettext 8import gettext
9import yaml
9gettext.install('music_sampler') 10gettext.install('music_sampler')
10Logger = logging.getLogger("kivy") 11Logger = logging.getLogger("kivy")
11 12
@@ -52,6 +53,96 @@ def path():
52 else: 53 else:
53 return os.path.dirname(os.path.realpath(__file__)) 54 return os.path.dirname(os.path.realpath(__file__))
54 55
56
57Configs = {
58 'music_path': {
59 'abbr': '-p',
60 'default': '.',
61 'help': _("Folder in which to find the music files"),
62 'type': None
63 },
64 'latency': {
65 'abbr': '-l',
66 'default': 'high',
67 'help': _("Latency: low, high or number of seconds"),
68 'type': None
69 },
70 'language': {
71 'abbr': '-L',
72 'default': "fr",
73 'help': _("Select another language"),
74 'type': None
75 },
76 'device': {
77 'abbr': '-d',
78 'default': None,
79 'help': _("Select this sound device"),
80 'type': None
81 },
82 'blocksize': {
83 'abbr': '-b',
84 'default': 0,
85 'help': _("Blocksize: If not 0, the number of frames to take\
86 at each step for the mixer"),
87 'type': int
88 },
89 'frame_rate': {
90 'abbr': '-f',
91 'default': 44100,
92 'help': _("Frame rate to play the musics"),
93 'type': int
94 },
95 'channels': {
96 'abbr': '-x',
97 'default': 2,
98 'help': _("Number of channels to use"),
99 'type': int
100 },
101 'sample_width': {
102 'abbr': '-s',
103 'default': 2,
104 'help': _("Sample width (number of bytes for each frame)"),
105 'type': int
106 },
107 'builtin_mixing': {
108 'default': False,
109 'help_yes': _("Make the mixing of sounds manually\
110 (do it if the system cannot handle it correctly)"),
111 'help_no': _("Don't make the mixing of sounds manually (default)"),
112 'type': 'boolean'
113 },
114 'debug': {
115 'abbr': '-d',
116 'default': False,
117 'help_yes': _("Print messages in console"),
118 'help_no': _("Don't print messages in console (default)"),
119 'type': 'boolean'
120 },
121 'focus_warning': {
122 'default': True,
123 'help_yes': _("Show a warning when focus is lost (default)"),
124 'help_no': _("Don't show warning when focus is lost"),
125 'type': 'boolean'
126 },
127 'list_devices': {
128 'help': _("List available sound devices"),
129 'type': 'action'
130 },
131}
132Configs_order = [
133 'debug',
134 'music_path',
135 'builtin_mixing',
136 'latency',
137 'blocksize',
138 'frame_rate',
139 'channels',
140 'sample_width',
141 'focus_warning',
142 'language',
143 'list_devices',
144 'device',
145]
55def parse_args(): 146def parse_args():
56 argv = sys.argv[1 :] 147 argv = sys.argv[1 :]
57 sys.argv = sys.argv[: 1] 148 sys.argv = sys.argv[: 1]
@@ -68,72 +159,34 @@ def parse_args():
68 sys.argv.extend(["-c", "kivy:log_name:/tmp/music_sampler_%_.txt"]) 159 sys.argv.extend(["-c", "kivy:log_name:/tmp/music_sampler_%_.txt"])
69 160
70 parser = argparse.ArgumentParser( 161 parser = argparse.ArgumentParser(
71 description=_("A Music Sampler application."), 162 argument_default=argparse.SUPPRESS,
72 formatter_class=argparse.ArgumentDefaultsHelpFormatter) 163 description=_("A Music Sampler application."))
73 parser.add_argument("-c", "--config",
74 default="config.yml",
75 required=False,
76 help=_("Config file to load"))
77 parser.add_argument("-p", "--music-path",
78 default=".",
79 required=False,
80 help=_("Folder in which to find the music files"))
81 parser.add_argument("-d", "--debug",
82 nargs=0,
83 action=DebugModeAction,
84 help=_("Print messages in console"))
85 parser.add_argument("-m", "--builtin-mixing",
86 action="store_true",
87 help=_("Make the mixing of sounds manually\
88 (do it if the system cannot handle it correctly)"))
89 parser.add_argument("-l", "--latency",
90 default="high",
91 required=False,
92 help=_("Latency: low, high or number of seconds"))
93 parser.add_argument("-b", "--blocksize",
94 default=0,
95 type=int,
96 required=False,
97 help=_("Blocksize: If not 0, the number of frames to take\
98 at each step for the mixer"))
99 parser.add_argument("-f", "--frame-rate",
100 default=44100,
101 type=int,
102 required=False,
103 help=_("Frame rate to play the musics"))
104 parser.add_argument("-x", "--channels",
105 default=2,
106 type=int,
107 required=False,
108 help=_("Number of channels to use"))
109 parser.add_argument("-s", "--sample-width",
110 default=2,
111 type=int,
112 required=False,
113 help=_("Sample width (number of bytes for each frame)"))
114 parser.add_argument("-V", "--version", 164 parser.add_argument("-V", "--version",
115 action="version", 165 action="version",
116 help=_("Displays the current version and exits. Only use\ 166 help=_("Displays the current version and exits. Only use\
117 in bundled package"), 167 in bundled package"),
118 version=show_version()) 168 version=show_version())
119 parser.add_argument("--device", 169 parser.add_argument("-c", "--config",
120 action=SelectDeviceAction, 170 default="config.yml",
121 help=_("Select this sound device")
122 )
123 parser.add_argument("--list-devices",
124 nargs=0,
125 action=ListDevicesAction,
126 help=_("List available sound devices")
127 )
128 parser.add_argument("--no-focus-warning",
129 action='store_true',
130 help=_("Don't show warning when focus is lost")
131 )
132 parser.add_argument("-L", "--language",
133 required=False, 171 required=False,
134 default="fr", 172 help=_("Config file to load (default: config.yml)"))
135 help=_("Select another language") 173 for argument in Configs_order:
136 ) 174 arg = Configs[argument]
175 if arg['type'] != 'boolean' and arg['type'] != 'action':
176 parser.add_argument(arg['abbr'], '--' + argument.replace('_', '-'),
177 type=arg['type'],
178 help=arg['help']+_(" (default: {})").format(arg['default']))
179 elif arg['type'] == 'boolean':
180 parser.add_argument('--' + argument.replace('_', '-'),
181 action='store_const', const=True,
182 help=arg['help_yes'])
183 parser.add_argument('--no-' + argument.replace('_', '-'),
184 action='store_const', const=True,
185 help=arg['help_no'])
186 else:
187 parser.add_argument('--' + argument.replace('_', '-'),
188 action='store_const', const=True,
189 help=arg['help'])
137 parser.add_argument('--', 190 parser.add_argument('--',
138 dest="args", 191 dest="args",
139 help=_("Kivy arguments. All arguments after this are interpreted\ 192 help=_("Kivy arguments. All arguments after this are interpreted\
@@ -142,36 +195,58 @@ def parse_args():
142 args = parser.parse_args(argv) 195 args = parser.parse_args(argv)
143 196
144 Config.yml_file = args.config 197 Config.yml_file = args.config
198 build_config(args)
145 199
146 Config.latency = args.latency 200 if Config.device is not None:
147 Config.blocksize = args.blocksize 201 sd.default.device = Config.device
148 Config.frame_rate = args.frame_rate 202
149 Config.channels = args.channels 203 if Config.list_devices:
150 Config.sample_width = args.sample_width 204 print(sd.query_devices())
151 Config.builtin_mixing = args.builtin_mixing 205 sys.exit()
152 Config.no_focus_warning = args.no_focus_warning 206
153 if args.language != 'en': 207 if Config.debug:
208 sys.argv.extend(["-c", "kivy:log_level:debug"])
209
210 if Config.language != 'en':
154 gettext.translation("music_sampler", 211 gettext.translation("music_sampler",
155 localedir=path() + '/locales', 212 localedir=path() + '/locales',
156 languages=[args.language]).install() 213 languages=[Config.language]).install()
157 if args.music_path.endswith("/"): 214 if not Config.music_path.endswith("/"):
158 Config.music_path = args.music_path 215 Config.music_path = Config.music_path + "/"
159 else:
160 Config.music_path = args.music_path + "/"
161 216
162class DebugModeAction(argparse.Action): 217def build_config(args):
163 def __call__(self, parser, namespace, values, option_string=None): 218 stream = open(Config.yml_file, "r")
164 sys.argv.extend(["-c", "kivy:log_level:debug"]) 219 try:
220 config = yaml.safe_load(stream)
221 except Exception as e:
222 error_print("Error while loading config file: {}".format(e))
223 config = {}
224 stream.close()
225 if 'config' in config:
226 config = config['config']
227 else:
228 config = {}
165 229
166class SelectDeviceAction(argparse.Action): 230 for config_item in Configs_order:
167 def __call__(self, parser, namespace, values, option_string=None): 231 if Configs[config_item]['type'] != 'boolean' and \
168 sd.default.device = values 232 Configs[config_item]['type'] != 'action':
233 t = Configs[config_item]['type'] or str
234 if hasattr(args, config_item):
235 setattr(Config, config_item, getattr(args, config_item))
236 elif config_item in config:
237 setattr(Config, config_item, t(config[config_item]))
238 else:
239 setattr(Config, config_item, Configs[config_item]['default'])
240 elif Configs[config_item]['type'] == 'boolean':
241 if hasattr(args, 'no_' + config_item) or hasattr(args, config_item):
242 setattr(Config, config_item, hasattr(args, config_item))
243 elif config_item in config:
244 setattr(Config, config_item, config[config_item])
245 else:
246 setattr(Config, config_item, Configs[config_item]['default'])
247 else:
248 setattr(Config, config_item, hasattr(args, config_item))
169 249
170class ListDevicesAction(argparse.Action):
171 nargs = 0
172 def __call__(self, parser, namespace, values, option_string=None):
173 print(sd.query_devices())
174 sys.exit()
175 250
176def show_version(): 251def show_version():
177 if getattr(sys, 'frozen', False): 252 if getattr(sys, 'frozen', False):