]> git.immae.eu Git - perso/Immae/Projets/Python/MusicSampler.git/blob - music_sampler/helpers.py
Use pip setup file
[perso/Immae/Projets/Python/MusicSampler.git] / music_sampler / helpers.py
1 # -*- coding: utf-8 -*-
2 import argparse
3 import sys
4 import os
5 import math
6 import sounddevice as sd
7 import logging
8
9 from . import sysfont
10
11 class Config:
12 pass
13
14 def find_font(name, style=sysfont.STYLE_NONE):
15 if getattr(sys, 'frozen', False):
16 font = sys._MEIPASS + "/fonts/{}_{}.ttf".format(name, style)
17 else:
18 font = sysfont.get_font(name, style=style)
19 if font is not None:
20 font = font[4]
21 return font
22
23 def register_fonts():
24 from kivy.core.text import LabelBase
25
26 ubuntu_regular = find_font("Ubuntu", style=sysfont.STYLE_NORMAL)
27 ubuntu_bold = find_font("Ubuntu", style=sysfont.STYLE_BOLD)
28 symbola = find_font("Symbola")
29
30 if ubuntu_regular is None:
31 error_print("Font Ubuntu regular could not be found, please install it.")
32 sys.exit()
33 if symbola is None:
34 error_print("Font Symbola could not be found, please install it.")
35 sys.exit()
36 if ubuntu_bold is None:
37 warn_print("Font Ubuntu Bold could not be found.")
38
39 LabelBase.register(name="Ubuntu",
40 fn_regular=ubuntu_regular,
41 fn_bold=ubuntu_bold)
42 LabelBase.register(name="Symbola",
43 fn_regular=symbola)
44
45
46 def path():
47 if getattr(sys, 'frozen', False):
48 return sys._MEIPASS + "/"
49 else:
50 return os.path.dirname(os.path.realpath(__file__))
51
52 def parse_args():
53 argv = sys.argv[1 :]
54 sys.argv = sys.argv[: 1]
55 if "--" in argv:
56 index = argv.index("--")
57 kivy_args = argv[index+1 :]
58 argv = argv[: index]
59
60 sys.argv.extend(kivy_args)
61
62 parser = argparse.ArgumentParser(
63 description="A Music Sampler application.",
64 formatter_class=argparse.ArgumentDefaultsHelpFormatter)
65 parser.add_argument("-c", "--config",
66 default="config.yml",
67 required=False,
68 help="Config file to load")
69 parser.add_argument("-p", "--music-path",
70 default=".",
71 required=False,
72 help="Folder in which to find the music files")
73 parser.add_argument("-d", "--debug",
74 nargs=0,
75 action=DebugModeAction,
76 help="Print messages in console")
77 parser.add_argument("-m", "--builtin-mixing",
78 action="store_true",
79 help="Make the mixing of sounds manually\
80 (do it if the system cannot handle it correctly)")
81 parser.add_argument("-l", "--latency",
82 default="high",
83 required=False,
84 help="Latency: low, high or number of seconds")
85 parser.add_argument("-b", "--blocksize",
86 default=0,
87 type=int,
88 required=False,
89 help="Blocksize: If not 0, the number of frames to take\
90 at each step for the mixer")
91 parser.add_argument("-f", "--frame-rate",
92 default=44100,
93 type=int,
94 required=False,
95 help="Frame rate to play the musics")
96 parser.add_argument("-x", "--channels",
97 default=2,
98 type=int,
99 required=False,
100 help="Number of channels to use")
101 parser.add_argument("-s", "--sample-width",
102 default=2,
103 type=int,
104 required=False,
105 help="Sample width (number of bytes for each frame)")
106 parser.add_argument("-V", "--version",
107 action="version",
108 help="Displays the current version and exits. Only use\
109 in bundled package",
110 version=show_version())
111 parser.add_argument("--device",
112 action=SelectDeviceAction,
113 help="Select this sound device"
114 )
115 parser.add_argument("--list-devices",
116 nargs=0,
117 action=ListDevicesAction,
118 help="List available sound devices"
119 )
120 parser.add_argument('--',
121 dest="args",
122 help="Kivy arguments. All arguments after this are interpreted\
123 by Kivy. Pass \"-- --help\" to get Kivy's usage.")
124
125 from kivy.logger import Logger
126 Logger.setLevel(logging.WARN)
127
128 args = parser.parse_args(argv)
129
130 Config.yml_file = args.config
131
132 Config.latency = args.latency
133 Config.blocksize = args.blocksize
134 Config.frame_rate = args.frame_rate
135 Config.channels = args.channels
136 Config.sample_width = args.sample_width
137 Config.builtin_mixing = args.builtin_mixing
138 if args.music_path.endswith("/"):
139 Config.music_path = args.music_path
140 else:
141 Config.music_path = args.music_path + "/"
142
143 class DebugModeAction(argparse.Action):
144 def __call__(self, parser, namespace, values, option_string=None):
145 from kivy.logger import Logger
146 Logger.setLevel(logging.DEBUG)
147
148 class SelectDeviceAction(argparse.Action):
149 def __call__(self, parser, namespace, values, option_string=None):
150 sd.default.device = values
151
152 class ListDevicesAction(argparse.Action):
153 nargs = 0
154 def __call__(self, parser, namespace, values, option_string=None):
155 print(sd.query_devices())
156 sys.exit()
157
158 def show_version():
159 if getattr(sys, 'frozen', False):
160 with open(path() + ".pyinstaller_commit", "r") as f:
161 return f.read()
162 else:
163 return "option '-v' can only be used in bundled package"
164
165 def duration_to_min_sec(duration):
166 minutes = int(duration / 60)
167 seconds = int(duration) % 60
168 if minutes < 100:
169 return "{:2}:{:0>2}".format(minutes, seconds)
170 else:
171 return "{}:{:0>2}".format(minutes, seconds)
172
173 def gain(volume, old_volume=None):
174 if old_volume is None:
175 return 20 * math.log10(max(volume, 0.1) / 100)
176 else:
177 return [
178 20 * math.log10(max(volume, 0.1) / max(old_volume, 0.1)),
179 max(volume, 0)]
180
181 def debug_print(message, with_trace=False):
182 from kivy.logger import Logger
183 Logger.debug('MusicSampler: ' + message, exc_info=with_trace)
184
185 def error_print(message, with_trace=False):
186 from kivy.logger import Logger
187 Logger.error('MusicSampler: ' + message, exc_info=with_trace)
188
189 def warn_print(message, with_trace=False):
190 from kivy.logger import Logger
191 Logger.warn('MusicSampler: ' + message, exc_info=with_trace)
192