aboutsummaryrefslogtreecommitdiff
path: root/music_sampler/helpers.py
diff options
context:
space:
mode:
Diffstat (limited to 'music_sampler/helpers.py')
-rw-r--r--music_sampler/helpers.py243
1 files changed, 159 insertions, 84 deletions
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):