diff options
-rw-r--r-- | config.yml | 32 | ||||
-rw-r--r-- | documentation_en.md | 28 | ||||
-rw-r--r-- | documentation_fr.md | 29 | ||||
-rw-r--r-- | music_sampler/app.py | 2 | ||||
-rw-r--r-- | music_sampler/helpers.py | 243 |
5 files changed, 233 insertions, 101 deletions
@@ -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. | ||
6 | config: | ||
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 | ||
47 | key_properties: | 75 | key_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 | ||
42 | Pour compiler kivy avec la librairie SDL2, il faut certains paquets installés: | 42 | To 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 | ||
98 | All the options below are optional; usually, running the program in the correct | 98 | All the options below are optional; usually, running the program in the correct |
99 | folder is enough | 99 | folder is enough. Most of the parameters can be defined also in the config file. |
100 | The 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 | ||
113 | The following options are reserved for a more advanced use of Music Sampler, or | 116 | The following options are reserved for a more advanced use of Music Sampler, or |
114 | in case of problem with the standard configuration: | 117 | in 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. | |||
144 | The file contains several sections: | 147 | The 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 | |||
167 | The config section lets you store configuration parameters that you would | ||
168 | normally use in the command line parameters. The '-' in the long parameter name | ||
169 | should be replaced by '_' (e.g. '--music-path' -> 'music_path'). For toggles | ||
170 | (`debug`, `focus_warning`, `builtin_mixing`) use the version without 'no-' and | ||
171 | specify `true` or `false` as value. Note that command line arguments always take | ||
172 | precedence. | ||
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 | ||
105 | Toutes les options au lancement sont facultatives ; la plupart du temps lancer | 105 | Toutes les options au lancement sont facultatives ; la plupart du temps lancer |
106 | le programme dans le bon dossier suffit. | 106 | le programme dans le bon dossier suffit. La plupart d'entre elles peuvent être |
107 | définies également dans le fichier de config (à part `--config` bien sûr). Les | ||
108 | arguments 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 | ||
122 | Les options suivantes sont plutôt réservées à un usage avancé de music_sampler, | 125 | Les options suivantes sont plutôt réservées à un usage avancé de music_sampler, |
123 | ou en cas de problème avec la configuration standard : | 126 | ou 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. | |||
158 | Le fichier contient plusieurs sections : | 161 | Le 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 | |||
182 | La section config permet d'enregistrer les paramètres habituellement donnés en | ||
183 | ligne de commande. Les '-' dans le nom du paramètre long doivent être remplacés | ||
184 | par des '_' (par exemple '--music-path' -> 'music_path'). Pour les switches | ||
185 | (`debug`, `focus_warning`, `builtin_mixing`), utilisez la version sans le 'no-' | ||
186 | et spécifiez `true` / `false` en valeur. Notez que les arguments donnés en ligne | ||
187 | de 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 | ||
176 | Cette section sert à définir des propriétés globales des musiques. | 191 | Cette 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 | |||
6 | import sounddevice as sd | 6 | import sounddevice as sd |
7 | import logging | 7 | import logging |
8 | import gettext | 8 | import gettext |
9 | import yaml | ||
9 | gettext.install('music_sampler') | 10 | gettext.install('music_sampler') |
10 | Logger = logging.getLogger("kivy") | 11 | Logger = 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 | |||
57 | Configs = { | ||
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 | } | ||
132 | Configs_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 | ] | ||
55 | def parse_args(): | 146 | def 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 | ||
162 | class DebugModeAction(argparse.Action): | 217 | def 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 | ||
166 | class 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 | ||
170 | class 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 | ||
176 | def show_version(): | 251 | def show_version(): |
177 | if getattr(sys, 'frozen', False): | 252 | if getattr(sys, 'frozen', False): |