diff options
author | Ismaël Bouya <ismael.bouya@normalesup.org> | 2016-07-27 22:15:25 +0200 |
---|---|---|
committer | Ismaël Bouya <ismael.bouya@normalesup.org> | 2016-07-27 23:08:57 +0200 |
commit | 6ebe62478a49df22c55ef6a2b1200473500a7f80 (patch) | |
tree | 20541528abe9df35592347ade1e15c005644bf58 /music_sampler | |
parent | 63ba5a8dc2aa4ec3e6f203b0ba4db249ecf0b00e (diff) | |
download | MusicSampler-6ebe62478a49df22c55ef6a2b1200473500a7f80.tar.gz MusicSampler-6ebe62478a49df22c55ef6a2b1200473500a7f80.tar.zst MusicSampler-6ebe62478a49df22c55ef6a2b1200473500a7f80.zip |
Use pip setup file1.0.0
Diffstat (limited to 'music_sampler')
-rw-r--r-- | music_sampler/__init__.py | 193 | ||||
-rw-r--r-- | music_sampler/action.py | 2 | ||||
-rw-r--r-- | music_sampler/app.py | 91 | ||||
-rw-r--r-- | music_sampler/helpers.py | 192 | ||||
-rw-r--r-- | music_sampler/key.py | 2 | ||||
-rw-r--r-- | music_sampler/lock.py | 2 | ||||
-rw-r--r-- | music_sampler/mapping.py | 2 | ||||
-rw-r--r-- | music_sampler/mixer.py | 2 | ||||
-rw-r--r-- | music_sampler/music_file.py | 2 | ||||
-rw-r--r-- | music_sampler/music_sampler.kv | 900 |
10 files changed, 1190 insertions, 198 deletions
diff --git a/music_sampler/__init__.py b/music_sampler/__init__.py index 4827e6c..aa551fb 100644 --- a/music_sampler/__init__.py +++ b/music_sampler/__init__.py | |||
@@ -1,192 +1 @@ | |||
1 | # -*- coding: utf-8 -*- | from . import app | |
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 | path = os.path.dirname(os.path.realpath(__file__)) | ||
51 | return path + "/../" | ||
52 | |||
53 | def parse_args(): | ||
54 | argv = sys.argv[1 :] | ||
55 | sys.argv = sys.argv[: 1] | ||
56 | if "--" in argv: | ||
57 | index = argv.index("--") | ||
58 | kivy_args = argv[index+1 :] | ||
59 | argv = argv[: index] | ||
60 | |||
61 | sys.argv.extend(kivy_args) | ||
62 | |||
63 | parser = argparse.ArgumentParser( | ||
64 | description="A Music Sampler application.", | ||
65 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) | ||
66 | parser.add_argument("-c", "--config", | ||
67 | default="config.yml", | ||
68 | required=False, | ||
69 | help="Config file to load") | ||
70 | parser.add_argument("-p", "--music-path", | ||
71 | default=".", | ||
72 | required=False, | ||
73 | help="Folder in which to find the music files") | ||
74 | parser.add_argument("-d", "--debug", | ||
75 | nargs=0, | ||
76 | action=DebugModeAction, | ||
77 | help="Print messages in console") | ||
78 | parser.add_argument("-m", "--builtin-mixing", | ||
79 | action="store_true", | ||
80 | help="Make the mixing of sounds manually\ | ||
81 | (do it if the system cannot handle it correctly)") | ||
82 | parser.add_argument("-l", "--latency", | ||
83 | default="high", | ||
84 | required=False, | ||
85 | help="Latency: low, high or number of seconds") | ||
86 | parser.add_argument("-b", "--blocksize", | ||
87 | default=0, | ||
88 | type=int, | ||
89 | required=False, | ||
90 | help="Blocksize: If not 0, the number of frames to take\ | ||
91 | at each step for the mixer") | ||
92 | parser.add_argument("-f", "--frame-rate", | ||
93 | default=44100, | ||
94 | type=int, | ||
95 | required=False, | ||
96 | help="Frame rate to play the musics") | ||
97 | parser.add_argument("-x", "--channels", | ||
98 | default=2, | ||
99 | type=int, | ||
100 | required=False, | ||
101 | help="Number of channels to use") | ||
102 | parser.add_argument("-s", "--sample-width", | ||
103 | default=2, | ||
104 | type=int, | ||
105 | required=False, | ||
106 | help="Sample width (number of bytes for each frame)") | ||
107 | parser.add_argument("-V", "--version", | ||
108 | action="version", | ||
109 | help="Displays the current version and exits. Only use\ | ||
110 | in bundled package", | ||
111 | version=show_version()) | ||
112 | parser.add_argument("--device", | ||
113 | action=SelectDeviceAction, | ||
114 | help="Select this sound device" | ||
115 | ) | ||
116 | parser.add_argument("--list-devices", | ||
117 | nargs=0, | ||
118 | action=ListDevicesAction, | ||
119 | help="List available sound devices" | ||
120 | ) | ||
121 | parser.add_argument('--', | ||
122 | dest="args", | ||
123 | help="Kivy arguments. All arguments after this are interpreted\ | ||
124 | by Kivy. Pass \"-- --help\" to get Kivy's usage.") | ||
125 | |||
126 | from kivy.logger import Logger | ||
127 | Logger.setLevel(logging.WARN) | ||
128 | |||
129 | args = parser.parse_args(argv) | ||
130 | |||
131 | Config.yml_file = args.config | ||
132 | |||
133 | Config.latency = args.latency | ||
134 | Config.blocksize = args.blocksize | ||
135 | Config.frame_rate = args.frame_rate | ||
136 | Config.channels = args.channels | ||
137 | Config.sample_width = args.sample_width | ||
138 | Config.builtin_mixing = args.builtin_mixing | ||
139 | if args.music_path.endswith("/"): | ||
140 | Config.music_path = args.music_path | ||
141 | else: | ||
142 | Config.music_path = args.music_path + "/" | ||
143 | |||
144 | class DebugModeAction(argparse.Action): | ||
145 | def __call__(self, parser, namespace, values, option_string=None): | ||
146 | from kivy.logger import Logger | ||
147 | Logger.setLevel(logging.DEBUG) | ||
148 | |||
149 | class SelectDeviceAction(argparse.Action): | ||
150 | def __call__(self, parser, namespace, values, option_string=None): | ||
151 | sd.default.device = values | ||
152 | |||
153 | class ListDevicesAction(argparse.Action): | ||
154 | nargs = 0 | ||
155 | def __call__(self, parser, namespace, values, option_string=None): | ||
156 | print(sd.query_devices()) | ||
157 | sys.exit() | ||
158 | |||
159 | def show_version(): | ||
160 | if getattr(sys, 'frozen', False): | ||
161 | with open(path() + ".pyinstaller_commit", "r") as f: | ||
162 | return f.read() | ||
163 | else: | ||
164 | return "option '-v' can only be used in bundled package" | ||
165 | |||
166 | def duration_to_min_sec(duration): | ||
167 | minutes = int(duration / 60) | ||
168 | seconds = int(duration) % 60 | ||
169 | if minutes < 100: | ||
170 | return "{:2}:{:0>2}".format(minutes, seconds) | ||
171 | else: | ||
172 | return "{}:{:0>2}".format(minutes, seconds) | ||
173 | |||
174 | def gain(volume, old_volume=None): | ||
175 | if old_volume is None: | ||
176 | return 20 * math.log10(max(volume, 0.1) / 100) | ||
177 | else: | ||
178 | return [ | ||
179 | 20 * math.log10(max(volume, 0.1) / max(old_volume, 0.1)), | ||
180 | max(volume, 0)] | ||
181 | |||
182 | def debug_print(message, with_trace=False): | ||
183 | from kivy.logger import Logger | ||
184 | Logger.debug('MusicSampler: ' + message, exc_info=with_trace) | ||
185 | |||
186 | def error_print(message, with_trace=False): | ||
187 | from kivy.logger import Logger | ||
188 | Logger.error('MusicSampler: ' + message, exc_info=with_trace) | ||
189 | |||
190 | def warn_print(message, with_trace=False): | ||
191 | from kivy.logger import Logger | ||
192 | Logger.warn('MusicSampler: ' + message, exc_info=with_trace) | ||
diff --git a/music_sampler/action.py b/music_sampler/action.py index 4b5a71d..ef56b7c 100644 --- a/music_sampler/action.py +++ b/music_sampler/action.py | |||
@@ -1,5 +1,5 @@ | |||
1 | from transitions.extensions import HierarchicalMachine as Machine | 1 | from transitions.extensions import HierarchicalMachine as Machine |
2 | from . import debug_print, error_print | 2 | from .helpers import debug_print, error_print |
3 | from . import actions | 3 | from . import actions |
4 | 4 | ||
5 | class Action: | 5 | class Action: |
diff --git a/music_sampler/app.py b/music_sampler/app.py new file mode 100644 index 0000000..81c47a7 --- /dev/null +++ b/music_sampler/app.py | |||
@@ -0,0 +1,91 @@ | |||
1 | from .helpers import parse_args, register_fonts, duration_to_min_sec, path | ||
2 | |||
3 | parse_args() | ||
4 | |||
5 | import kivy | ||
6 | kivy.require("1.9.1") | ||
7 | from kivy.app import App | ||
8 | from kivy.uix.floatlayout import FloatLayout | ||
9 | from kivy.uix.relativelayout import RelativeLayout | ||
10 | from kivy.properties import ListProperty, StringProperty | ||
11 | from kivy.clock import Clock | ||
12 | from kivy.core.window import Window | ||
13 | from kivy.lang import Builder | ||
14 | from .key import Key | ||
15 | from .mapping import Mapping | ||
16 | |||
17 | register_fonts() | ||
18 | |||
19 | class KeyList(RelativeLayout): | ||
20 | keylist = ListProperty([]) | ||
21 | first_key = StringProperty("") | ||
22 | second_key = StringProperty("") | ||
23 | third_key = StringProperty("") | ||
24 | |||
25 | def append(self, value): | ||
26 | self.keylist.insert(0, value) | ||
27 | |||
28 | def on_keylist(self, instance, new_key_list): | ||
29 | if len(self.keylist) > 0: | ||
30 | self.first_key = self.keylist[0] | ||
31 | if len(self.keylist) > 1: | ||
32 | self.second_key = self.keylist[1] | ||
33 | if len(self.keylist) > 2: | ||
34 | self.third_key = self.keylist[2] | ||
35 | |||
36 | class PlayList(RelativeLayout): | ||
37 | playlist = ListProperty([]) | ||
38 | |||
39 | def __init__(self, **kwargs): | ||
40 | super(PlayList, self).__init__(**kwargs) | ||
41 | Clock.schedule_interval(self.update_playlist, 0.5) | ||
42 | |||
43 | def update_playlist(self, dt): | ||
44 | if self.parent is None or 'Mapping' not in self.parent.ids: | ||
45 | return True | ||
46 | |||
47 | open_files = self.parent.ids['Mapping'].open_files | ||
48 | self.playlist = [] | ||
49 | for music_file in open_files.values(): | ||
50 | if not music_file.is_in_use(): | ||
51 | continue | ||
52 | |||
53 | text = "{}/{}".format( | ||
54 | duration_to_min_sec(music_file.sound_position), | ||
55 | duration_to_min_sec(music_file.sound_duration)) | ||
56 | |||
57 | if music_file.is_loaded_paused(): | ||
58 | self.playlist.append(["⏸", music_file.name, text, False]) | ||
59 | else: | ||
60 | self.playlist.append(["⏵", music_file.name, text, True]) | ||
61 | |||
62 | |||
63 | class ActionList(RelativeLayout): | ||
64 | action_title = StringProperty("") | ||
65 | action_list = ListProperty([]) | ||
66 | |||
67 | def update_list(self, key, action_descriptions): | ||
68 | self.action_title = "actions linked to key {}:".format(key.key_sym) | ||
69 | self.action_list = [] | ||
70 | |||
71 | for [action, status] in action_descriptions: | ||
72 | if status == "done": | ||
73 | icon = "✓" | ||
74 | elif status == "current": | ||
75 | icon = "✅" | ||
76 | else: | ||
77 | icon = " " | ||
78 | self.action_list.append([icon, action]) | ||
79 | |||
80 | class Screen(FloatLayout): | ||
81 | pass | ||
82 | |||
83 | class MusicSamplerApp(App): | ||
84 | def build(self): | ||
85 | Window.size = (913, 563) | ||
86 | |||
87 | return Screen() | ||
88 | |||
89 | def main(): | ||
90 | Builder.load_file(path() + "/music_sampler.kv") | ||
91 | MusicSamplerApp().run() | ||
diff --git a/music_sampler/helpers.py b/music_sampler/helpers.py new file mode 100644 index 0000000..1788084 --- /dev/null +++ b/music_sampler/helpers.py | |||
@@ -0,0 +1,192 @@ | |||
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 | |||
diff --git a/music_sampler/key.py b/music_sampler/key.py index 66e792d..b05de4c 100644 --- a/music_sampler/key.py +++ b/music_sampler/key.py | |||
@@ -4,7 +4,7 @@ from kivy.properties import AliasProperty, BooleanProperty, \ | |||
4 | from kivy.uix.behaviors import ButtonBehavior | 4 | from kivy.uix.behaviors import ButtonBehavior |
5 | 5 | ||
6 | from .action import Action | 6 | from .action import Action |
7 | from . import debug_print | 7 | from .helpers import debug_print |
8 | import time | 8 | import time |
9 | import threading | 9 | import threading |
10 | from transitions.extensions import HierarchicalMachine as Machine | 10 | from transitions.extensions import HierarchicalMachine as Machine |
diff --git a/music_sampler/lock.py b/music_sampler/lock.py index 9beafcd..5befe33 100644 --- a/music_sampler/lock.py +++ b/music_sampler/lock.py | |||
@@ -1,6 +1,6 @@ | |||
1 | import threading | 1 | import threading |
2 | 2 | ||
3 | from . import debug_print | 3 | from .helpers import debug_print |
4 | 4 | ||
5 | class Lock: | 5 | class Lock: |
6 | def __init__(self, lock_type): | 6 | def __init__(self, lock_type): |
diff --git a/music_sampler/mapping.py b/music_sampler/mapping.py index bb20e67..ca471ef 100644 --- a/music_sampler/mapping.py +++ b/music_sampler/mapping.py | |||
@@ -12,7 +12,7 @@ from transitions.extensions import HierarchicalMachine as Machine | |||
12 | 12 | ||
13 | from .music_file import MusicFile | 13 | from .music_file import MusicFile |
14 | from .mixer import Mixer | 14 | from .mixer import Mixer |
15 | from . import Config, gain, error_print, warn_print | 15 | from .helpers import Config, gain, error_print, warn_print |
16 | from .action import Action | 16 | from .action import Action |
17 | 17 | ||
18 | class Mapping(RelativeLayout): | 18 | class Mapping(RelativeLayout): |
diff --git a/music_sampler/mixer.py b/music_sampler/mixer.py index 9242b61..c8ec907 100644 --- a/music_sampler/mixer.py +++ b/music_sampler/mixer.py | |||
@@ -2,7 +2,7 @@ import sounddevice as sd | |||
2 | import audioop | 2 | import audioop |
3 | import time | 3 | import time |
4 | 4 | ||
5 | from . import Config | 5 | from .helpers import Config |
6 | 6 | ||
7 | sample_width = Config.sample_width | 7 | sample_width = Config.sample_width |
8 | 8 | ||
diff --git a/music_sampler/music_file.py b/music_sampler/music_file.py index 2d3ba72..fa6293d 100644 --- a/music_sampler/music_file.py +++ b/music_sampler/music_file.py | |||
@@ -8,7 +8,7 @@ import os.path | |||
8 | import audioop | 8 | import audioop |
9 | 9 | ||
10 | from .lock import Lock | 10 | from .lock import Lock |
11 | from . import Config, gain, debug_print, error_print | 11 | from .helpers import Config, gain, debug_print, error_print |
12 | from .mixer import Mixer | 12 | from .mixer import Mixer |
13 | from .music_effect import GainEffect | 13 | from .music_effect import GainEffect |
14 | 14 | ||
diff --git a/music_sampler/music_sampler.kv b/music_sampler/music_sampler.kv new file mode 100644 index 0000000..9057532 --- /dev/null +++ b/music_sampler/music_sampler.kv | |||
@@ -0,0 +1,900 @@ | |||
1 | #:import math math | ||
2 | #:import h music_sampler | ||
3 | |||
4 | <Key>: | ||
5 | pad_col_sep: 0 if not self.pad_cols else self.parent.pad_x | ||
6 | pad_cols: False | ||
7 | |||
8 | y: (self.parent.top-self.parent.y) - (self.row) * self.parent.key_size - (self.row - 1) * self.parent.key_sep | ||
9 | x: (self.col - 1) * self.parent.key_size + int(self.col - 1) * self.parent.key_sep + self.pad_col_sep | ||
10 | size_hint: None, None | ||
11 | enabled: True | ||
12 | line_width: 2 | ||
13 | row: 1 | ||
14 | col: 0 | ||
15 | key_code: 0 | ||
16 | key_sym: "" | ||
17 | key_width: 1 | ||
18 | key_height: 1 | ||
19 | width: self.key_width * (self.parent.key_size + self.parent.key_sep) - self.parent.key_sep | ||
20 | height: self.key_height * (self.parent.key_size + self.parent.key_sep) - self.parent.key_sep | ||
21 | canvas.before: | ||
22 | Color: | ||
23 | rgba: self.color | ||
24 | RoundedRectangle: | ||
25 | pos: self.x, self.y | ||
26 | size: self.size | ||
27 | canvas: | ||
28 | Color: | ||
29 | rgba: self.line_color | ||
30 | Line: | ||
31 | rounded_rectangle: self.x + self.line_width, self.y + self.line_width, self.width - 2 * self.line_width, self.height - 2 * self.line_width, 10 | ||
32 | width: self.line_width | ||
33 | Color: | ||
34 | rgba: self.line_cross_color | ||
35 | Line: | ||
36 | points: self.x + self.line_width + 3, self.y + self.line_width + 3, self.x + self.width - 2 * self.line_width - 3, self.y + self.height - 2 * self.line_width - 3 | ||
37 | width: self.line_width | ||
38 | Line: | ||
39 | points: self.x + self.line_width + 3, self.y + self.height - 2 * self.line_width - 3, self.x + self.width - 2 * self.line_width - 3, self.y + self.line_width + 3 | ||
40 | width: self.line_width | ||
41 | Label: | ||
42 | id: key_label | ||
43 | font_name: "Ubuntu" | ||
44 | bold: True | ||
45 | font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size)) | ||
46 | color: 0, 0, 0, 1 | ||
47 | text: self.parent.key_sym | ||
48 | text_size: self.parent.width,self.font_size | ||
49 | shorten: True | ||
50 | shorten_from: "right" | ||
51 | split_str: "" | ||
52 | center_x: self.parent.x + self.texture_size[0] /2 + 5 | ||
53 | center_y: self.parent.y + self.parent.height - self.texture_size[1] /2 - 5 | ||
54 | Label: | ||
55 | id: key_description_title | ||
56 | font_name: "Ubuntu" | ||
57 | font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size / 2)) | ||
58 | color: 0, 0, 0, 1 | ||
59 | text: self.parent.description_title | ||
60 | text_size: self.parent.width - 2*self.parent.line_width, self.font_size | ||
61 | halign: "right" | ||
62 | valign: "middle" | ||
63 | center_x: self.parent.x + self.texture_size[0] /2 | ||
64 | center_y: self.parent.y + self.parent.height - self.texture_size[1] /2 - 5 | ||
65 | Label: | ||
66 | id: key_description | ||
67 | font_name: "Ubuntu" | ||
68 | font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size / 2)) | ||
69 | color: 0, 0, 0, 1 | ||
70 | text: "\n".join(self.parent.description) | ||
71 | text_size: 2 * self.parent.width,self.parent.height - key_label.font_size | ||
72 | halign: "left" | ||
73 | valign: "middle" | ||
74 | pos: self.parent.x + 2 * self.parent.line_width + 2, self.parent.y | ||
75 | size_hint: None, None | ||
76 | size: 2 * self.parent.width - 2 * self.parent.line_width, self.parent.height - key_label.font_size | ||
77 | |||
78 | <Screen>: | ||
79 | canvas: | ||
80 | Color: | ||
81 | rgba: 229/255, 228/255, 226/255, 1 | ||
82 | Rectangle: | ||
83 | pos: 0, 0 | ||
84 | size: self.width, self.height | ||
85 | |||
86 | key_size: int( (3 * self.width - 16) / 56) | ||
87 | key_sep: int( self.key_size / 24) | ||
88 | key_pad_sep: int( self.key_size / 7) + 1 | ||
89 | |||
90 | border: (self.width - self.key_size * 18 - self.key_sep * 16 - self.key_pad_sep)/ 2 | ||
91 | |||
92 | mapping_height: self.key_size * 6 + self.key_sep * 5 | ||
93 | mapping_width: self.key_size * 18 + self.key_sep * 16 + self.key_pad_sep | ||
94 | mapping_x: self.border | ||
95 | mapping_y: self.top - self.mapping_height - self.border | ||
96 | |||
97 | key_list_width: 4 * (mock_ubuntu_regular.width or 0) | ||
98 | key_list_height: self.height - self.mapping_height - 3 * self.border | ||
99 | key_list_x: (self.action_list_width or 0) + 2 * self.border | ||
100 | key_list_y: self.border | ||
101 | |||
102 | action_list_height: self.height - self.mapping_height - 3 * self.border | ||
103 | action_list_width: 3 * self.width / 4 - self.key_list_width - self.border | ||
104 | action_list_x: self.border | ||
105 | action_list_y: self.border | ||
106 | |||
107 | play_list_height: self.action_list_height | ||
108 | play_list_width: self.width - self.action_list_width - 3* self.border | ||
109 | play_list_y: self.border | ||
110 | play_list_x: self.action_list_width + self.key_list_width + 3 * self.border | ||
111 | |||
112 | min_height: min(mock_symbola.height, mock_ubuntu_regular.height, mock_ubuntu_bold.height) | ||
113 | symbola_line_height: self.min_height / max(mock_symbola.height,1) | ||
114 | ubuntu_regular_line_height: self.min_height / max(mock_ubuntu_regular.height,1) | ||
115 | ubuntu_bold_line_height: self.min_height / max(mock_ubuntu_bold.height,1) | ||
116 | Label: | ||
117 | id: mock_symbola | ||
118 | font_name: "Symbola" | ||
119 | font_size: math.ceil(2 * math.sqrt(self.parent.key_size or 10)) | ||
120 | color: 0, 0, 0, 0 | ||
121 | text: "A" | ||
122 | text_size: None, None | ||
123 | size_hint: None, None | ||
124 | size: self.texture_size | ||
125 | Label: | ||
126 | id: mock_ubuntu_regular | ||
127 | font_name: "Ubuntu" | ||
128 | font_size: math.ceil(2 * math.sqrt(self.parent.key_size or 10)) | ||
129 | color: 0, 0, 0, 0 | ||
130 | text: "A" | ||
131 | text_size: None, None | ||
132 | size_hint: None, None | ||
133 | size: self.texture_size | ||
134 | Label: | ||
135 | id: mock_ubuntu_bold | ||
136 | font_name: "Ubuntu" | ||
137 | bold: True | ||
138 | font_size: math.ceil(2 * math.sqrt(self.parent.key_size or 10)) | ||
139 | color: 0, 0, 0, 0 | ||
140 | text: "A" | ||
141 | text_size: None, None | ||
142 | size_hint: None, None | ||
143 | size: self.texture_size | ||
144 | |||
145 | Mapping: | ||
146 | id: Mapping | ||
147 | pos: self.parent.mapping_x, self.parent.mapping_y | ||
148 | size: self.parent.mapping_width, self.parent.mapping_height | ||
149 | |||
150 | key_size: self.parent.key_size | ||
151 | key_sep: self.parent.key_sep | ||
152 | key_pad_sep: self.parent.key_pad_sep | ||
153 | pad_x: self.key_size * 15 + 14 * self.key_sep + self.key_pad_sep | ||
154 | ActionList: | ||
155 | id: ActionList | ||
156 | pos: self.parent.action_list_x, self.parent.action_list_y | ||
157 | size: self.parent.action_list_width, self.parent.action_list_height | ||
158 | KeyList: | ||
159 | id: KeyList | ||
160 | pos: self.parent.key_list_x, self.parent.key_list_y | ||
161 | size: self.parent.key_list_width, self.parent.key_list_height | ||
162 | PlayList: | ||
163 | id: PlayList | ||
164 | pos: self.parent.play_list_x, self.parent.play_list_y | ||
165 | size: self.parent.play_list_width, self.parent.play_list_height | ||
166 | |||
167 | <KeyList>: | ||
168 | size_hint: None, None | ||
169 | canvas: | ||
170 | Color: | ||
171 | rgba: 250./255, 250./255, 250./255, 1 | ||
172 | Rectangle: | ||
173 | pos: 0, 0 | ||
174 | size: self.width, self.height | ||
175 | Label: | ||
176 | id: key_list_first | ||
177 | font_name: "Ubuntu" | ||
178 | bold: True | ||
179 | font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size or 10)) | ||
180 | color: 0, 0, 0, 1 | ||
181 | text: self.parent.first_key | ||
182 | text_size: None, None | ||
183 | valign: "top" | ||
184 | halign: "center" | ||
185 | size_hint: None, None | ||
186 | size: self.parent.width, self.texture_size[1] | ||
187 | pos: 0, self.parent.height - self.height | ||
188 | Label: | ||
189 | id: key_list_second | ||
190 | font_name: "Ubuntu" | ||
191 | font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size or 10)) | ||
192 | color: 0, 0, 0, 1 | ||
193 | text: self.parent.second_key | ||
194 | text_size: None, None | ||
195 | valign: "top" | ||
196 | halign: "center" | ||
197 | size_hint: None, None | ||
198 | size: self.parent.width, self.texture_size[1] | ||
199 | pos: 0, self.parent.height - key_list_first.height - self.height | ||
200 | Label: | ||
201 | id: key_list_third | ||
202 | font_name: "Ubuntu" | ||
203 | font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size or 10)) | ||
204 | color: 0, 0, 0, 0.75 | ||
205 | text: self.parent.third_key | ||
206 | text_size: None, None | ||
207 | valign: "top" | ||
208 | halign: "center" | ||
209 | size_hint: None, None | ||
210 | size: self.parent.width, self.texture_size[1] | ||
211 | pos: 0, self.parent.height - key_list_first.height - key_list_second.height - self.height | ||
212 | Label: | ||
213 | id: key_list_rest | ||
214 | font_name: "Ubuntu" | ||
215 | font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size or 10)) | ||
216 | color: 0, 0, 0, 0.5 | ||
217 | text: "\n".join(self.parent.keylist[3:]) | ||
218 | text_size: None, None | ||
219 | valign: "top" | ||
220 | halign: "center" | ||
221 | size_hint: None, None | ||
222 | size: self.parent.width, self.texture_size[1] | ||
223 | pos: 0, self.parent.height - key_list_first.height - key_list_second.height - key_list_third.height - self.height | ||
224 | |||
225 | <ActionList>: | ||
226 | size_hint: None, None | ||
227 | canvas: | ||
228 | Color: | ||
229 | rgba: 250./255, 250./255, 250./255, 1 | ||
230 | Rectangle: | ||
231 | pos: 0, 0 | ||
232 | size: self.width, self.height | ||
233 | |||
234 | Label: | ||
235 | id: action_list_title | ||
236 | font_name: "Ubuntu" | ||
237 | bold: True | ||
238 | font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size or 10)) | ||
239 | color: 0, 0, 0, 1 | ||
240 | text: self.parent.action_title | ||
241 | text_size: None, self.parent.height | ||
242 | halign: "left" | ||
243 | valign: "top" | ||
244 | size_hint: None, None | ||
245 | size: self.texture_size[0], self.parent.height | ||
246 | Label: | ||
247 | id: action_list_icons | ||
248 | font_name: "Symbola" | ||
249 | font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size or 10)) | ||
250 | line_height: self.parent.parent.symbola_line_height or 1 | ||
251 | color: 0, 0, 0, 1 | ||
252 | text: "\n".join(map(lambda x: x[0], self.parent.action_list)) | ||
253 | text_size: None, self.parent.height | ||
254 | halign: "left" | ||
255 | valign: "top" | ||
256 | size_hint: None, None | ||
257 | size: self.texture_size[0], self.parent.height - 3 * self.line_height * self.font_size | ||
258 | Label: | ||
259 | id: action_list_names | ||
260 | font_name: "Ubuntu" | ||
261 | font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size or 10)) | ||
262 | line_height: self.parent.parent.ubuntu_regular_line_height or 1 | ||
263 | color: 0, 0, 0, 1 | ||
264 | text: "\n".join(map(lambda x: x[1], self.parent.action_list)) | ||
265 | text_size: None, self.parent.height | ||
266 | halign: "left" | ||
267 | valign: "top" | ||
268 | size_hint: None, None | ||
269 | pos: 15, self.y | ||
270 | size: self.texture_size[0], self.parent.height - 3 * self.line_height * self.font_size | ||
271 | |||
272 | <PlayList>: | ||
273 | size_hint: None, None | ||
274 | canvas: | ||
275 | Color: | ||
276 | rgba: 250./255, 250./255, 250./255, 1 | ||
277 | Rectangle: | ||
278 | pos: 0, 0 | ||
279 | size: self.width, self.height | ||
280 | |||
281 | Label: | ||
282 | id: playlist_icons | ||
283 | font_name: "Symbola" | ||
284 | font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size or 10)) | ||
285 | line_height: self.parent.parent.symbola_line_height or 1 | ||
286 | color: 0, 0, 0, 1 | ||
287 | text: "\n".join(map(lambda x: x[0], self.parent.playlist)) | ||
288 | text_size: None, self.parent.height | ||
289 | halign: "left" | ||
290 | valign: "top" | ||
291 | size_hint: None, None | ||
292 | size: self.texture_size[0], self.parent.height | ||
293 | Label: | ||
294 | id: playlist_names | ||
295 | font_name: "Ubuntu" # FIXME: Mettre en gras quand c'est en cours | ||
296 | line_height: self.parent.parent.ubuntu_regular_line_height or 1 | ||
297 | font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size or 10)) | ||
298 | color: 0, 0, 0, 1 | ||
299 | text: "\n".join(map(lambda x: x[1], self.parent.playlist)) | ||
300 | text_size: None, self.parent.height | ||
301 | halign: "left" | ||
302 | valign: "top" | ||
303 | size_hint: None, None | ||
304 | pos: 15, self.y | ||
305 | size: self.texture_size[0], self.parent.height | ||
306 | Label: | ||
307 | canvas.before: | ||
308 | Color: | ||
309 | rgba: 250./255, 250./255, 250./255, 1 | ||
310 | Rectangle: | ||
311 | pos: self.pos | ||
312 | size: self.width, self.height | ||
313 | id: playlist_times | ||
314 | font_name: "Ubuntu" | ||
315 | line_height: self.parent.parent.ubuntu_regular_line_height or 1 | ||
316 | font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size or 10)) | ||
317 | color: 0, 0, 0, 1 | ||
318 | text: "\n".join(map(lambda x: x[2], self.parent.playlist)) | ||
319 | text_size: None, self.parent.height | ||
320 | halign: "left" | ||
321 | valign: "top" | ||
322 | size_hint: None, None | ||
323 | pos: self.parent.width - 3 * self.width / 2 - 2 * (self.parent.parent.border or 0), self.y | ||
324 | size: self.texture_size[0], self.parent.height | ||
325 | |||
326 | <Mapping>: | ||
327 | size_hint: None, None | ||
328 | key_size: 48 | ||
329 | key_sep: 2 | ||
330 | key_pad_sep: 7 | ||
331 | pad_x: 755 | ||
332 | canvas: | ||
333 | Color: | ||
334 | rgba: 250./255, 250./255, 250./255, 1 | ||
335 | Rectangle: | ||
336 | pos: 0, 0 | ||
337 | size: self.width, self.height | ||
338 | Color: | ||
339 | rgba: self.ready_color | ||
340 | Ellipse: | ||
341 | pos: self.width - self.key_size / 2, self.height - self.key_size /2 | ||
342 | size: self.key_size / 3, self.key_size / 3 | ||
343 | Label: | ||
344 | font_name: "Ubuntu" | ||
345 | font_size: math.ceil(2 * math.sqrt(self.parent.key_size or 10)) | ||
346 | color: 0, 0, 0, 1 | ||
347 | text: "volume: {}%".format(self.parent.master_volume) | ||
348 | valign: "top" | ||
349 | size_hint: None, None | ||
350 | size: self.texture_size[0], self.texture_size[1] | ||
351 | x: self.parent.width - self.width - 2 * self.parent.key_size / 3 | ||
352 | center_y: self.parent.height - self.height | ||
353 | Key: | ||
354 | id: Key_27 | ||
355 | key_code: 27 | ||
356 | key_sym: "ESC" | ||
357 | row: 1 | ||
358 | col: 1 | ||
359 | Key: | ||
360 | id: Key_282 | ||
361 | key_code: 282 | ||
362 | key_sym: "F1" | ||
363 | row: 1 | ||
364 | col: 3 | ||
365 | Key: | ||
366 | id: Key_283 | ||
367 | key_code: 283 | ||
368 | key_sym: "F2" | ||
369 | row: 1 | ||
370 | col: 4 | ||
371 | Key: | ||
372 | id: Key_284 | ||
373 | key_code: 284 | ||
374 | key_sym: "F3" | ||
375 | row: 1 | ||
376 | col: 5 | ||
377 | Key: | ||
378 | id: Key_285 | ||
379 | key_code: 285 | ||
380 | key_sym: "F4" | ||
381 | row: 1 | ||
382 | col: 6 | ||
383 | |||
384 | Key: | ||
385 | id: Key_286 | ||
386 | key_code: 286 | ||
387 | key_sym: "F5" | ||
388 | row: 1 | ||
389 | col: 7.5 | ||
390 | Key: | ||
391 | id: Key_287 | ||
392 | key_code: 287 | ||
393 | key_sym: "F6" | ||
394 | row: 1 | ||
395 | col: 8.5 | ||
396 | Key: | ||
397 | id: Key_288 | ||
398 | key_code: 288 | ||
399 | key_sym: "F7" | ||
400 | row: 1 | ||
401 | col: 9.5 | ||
402 | Key: | ||
403 | id: Key_289 | ||
404 | key_code: 289 | ||
405 | key_sym: "F8" | ||
406 | row: 1 | ||
407 | col: 10.5 | ||
408 | |||
409 | Key: | ||
410 | id: Key_290 | ||
411 | key_code: 290 | ||
412 | key_sym: "F9" | ||
413 | row: 1 | ||
414 | col: 12 | ||
415 | Key: | ||
416 | id: Key_291 | ||
417 | key_code: 291 | ||
418 | key_sym: "F10" | ||
419 | row: 1 | ||
420 | col: 13 | ||
421 | Key: | ||
422 | id: Key_292 | ||
423 | key_code: 292 | ||
424 | key_sym: "F11" | ||
425 | row: 1 | ||
426 | col: 14 | ||
427 | Key: | ||
428 | id: Key_293 | ||
429 | key_code: 293 | ||
430 | key_sym: "F12" | ||
431 | row: 1 | ||
432 | col: 15 | ||
433 | |||
434 | Key: | ||
435 | id: Key_178 | ||
436 | key_code: 178 | ||
437 | key_sym: "²" | ||
438 | row: 2 | ||
439 | col: 1 | ||
440 | Key: | ||
441 | id: Key_38 | ||
442 | key_code: 38 | ||
443 | key_sym: "&" | ||
444 | row: 2 | ||
445 | col: 2 | ||
446 | Key: | ||
447 | id: Key_233 | ||
448 | key_code: 233 | ||
449 | key_sym: "é" | ||
450 | row: 2 | ||
451 | col: 3 | ||
452 | Key: | ||
453 | id: Key_34 | ||
454 | key_code: 34 | ||
455 | key_sym: '"' | ||
456 | row: 2 | ||
457 | col: 4 | ||
458 | Key: | ||
459 | id: Key_39 | ||
460 | key_code: 39 | ||
461 | key_sym: "'" | ||
462 | row: 2 | ||
463 | col: 5 | ||
464 | Key: | ||
465 | id: Key_40 | ||
466 | key_code: 40 | ||
467 | key_sym: "(" | ||
468 | row: 2 | ||
469 | col: 6 | ||
470 | Key: | ||
471 | id: Key_45 | ||
472 | key_code: 45 | ||
473 | key_sym: "-" | ||
474 | row: 2 | ||
475 | col: 7 | ||
476 | Key: | ||
477 | id: Key_232 | ||
478 | key_code: 232 | ||
479 | key_sym: "è" | ||
480 | row: 2 | ||
481 | col: 8 | ||
482 | Key: | ||
483 | id: Key_95 | ||
484 | key_code: 95 | ||
485 | key_sym: "_" | ||
486 | row: 2 | ||
487 | col: 9 | ||
488 | Key: | ||
489 | id: Key_231 | ||
490 | key_code: 231 | ||
491 | key_sym: "ç" | ||
492 | row: 2 | ||
493 | col: 10 | ||
494 | Key: | ||
495 | id: Key_224 | ||
496 | key_code: 224 | ||
497 | key_sym: "à" | ||
498 | row: 2 | ||
499 | col: 11 | ||
500 | Key: | ||
501 | id: Key_41 | ||
502 | key_code: 41 | ||
503 | key_sym: ")" | ||
504 | row: 2 | ||
505 | col: 12 | ||
506 | Key: | ||
507 | id: Key_61 | ||
508 | key_code: 61 | ||
509 | key_sym: "=" | ||
510 | row: 2 | ||
511 | col: 13 | ||
512 | Key: | ||
513 | id: Key_8 | ||
514 | key_code: 8 | ||
515 | key_sym: "<-" | ||
516 | row: 2 | ||
517 | col: 14 | ||
518 | key_width: 2 | ||
519 | Key: | ||
520 | id: Key_9 | ||
521 | key_code: 9 | ||
522 | key_sym: "tab" | ||
523 | row: 3 | ||
524 | col: 1 | ||
525 | key_width: 1.48 | ||
526 | Key: | ||
527 | id: Key_97 | ||
528 | key_code: 97 | ||
529 | key_sym: "a" | ||
530 | row: 3 | ||
531 | col: 2.5 | ||
532 | Key: | ||
533 | id: Key_122 | ||
534 | key_code: 122 | ||
535 | key_sym: "z" | ||
536 | row: 3 | ||
537 | col: 3.5 | ||
538 | Key: | ||
539 | id: Key_101 | ||
540 | key_code: 101 | ||
541 | key_sym: "e" | ||
542 | row: 3 | ||
543 | col: 4.5 | ||
544 | Key: | ||
545 | id: Key_114 | ||
546 | key_code: 114 | ||
547 | key_sym: "r" | ||
548 | row: 3 | ||
549 | col: 5.5 | ||
550 | Key: | ||
551 | id: Key_116 | ||
552 | key_code: 116 | ||
553 | key_sym: "t" | ||
554 | row: 3 | ||
555 | col: 6.5 | ||
556 | Key: | ||
557 | id: Key_121 | ||
558 | key_code: 121 | ||
559 | key_sym: "y" | ||
560 | row: 3 | ||
561 | col: 7.5 | ||
562 | Key: | ||
563 | id: Key_117 | ||
564 | key_code: 117 | ||
565 | key_sym: "u" | ||
566 | row: 3 | ||
567 | col: 8.5 | ||
568 | Key: | ||
569 | id: Key_105 | ||
570 | key_code: 105 | ||
571 | key_sym: "i" | ||
572 | row: 3 | ||
573 | col: 9.5 | ||
574 | Key: | ||
575 | id: Key_111 | ||
576 | key_code: 111 | ||
577 | key_sym: "o" | ||
578 | row: 3 | ||
579 | col: 10.5 | ||
580 | Key: | ||
581 | id: Key_112 | ||
582 | key_code: 112 | ||
583 | key_sym: "p" | ||
584 | row: 3 | ||
585 | col: 11.5 | ||
586 | Key: | ||
587 | id: Key_94 | ||
588 | key_code: 94 | ||
589 | key_sym: "^" | ||
590 | row: 3 | ||
591 | col: 12.5 | ||
592 | Key: | ||
593 | id: Key_36 | ||
594 | key_code: 36 | ||
595 | key_sym: "$" | ||
596 | row: 3 | ||
597 | col: 13.5 | ||
598 | Key: | ||
599 | id: Key_13 | ||
600 | key_code: 13 | ||
601 | key_sym: "Enter" | ||
602 | row: 4 | ||
603 | col: 14.8 | ||
604 | key_width: 1.23 | ||
605 | key_height: 2 | ||
606 | Key: | ||
607 | id: Key_301 | ||
608 | key_code: 301 | ||
609 | key_sym: "CAPS" | ||
610 | row: 4 | ||
611 | col: 1 | ||
612 | key_width: 1.75 | ||
613 | line_width: 1 | ||
614 | enabled: False | ||
615 | |||
616 | Key: | ||
617 | id: Key_113 | ||
618 | key_code: 113 | ||
619 | key_sym: "q" | ||
620 | row: 4 | ||
621 | col: 2.8 | ||
622 | Key: | ||
623 | id: Key_115 | ||
624 | key_code: 115 | ||
625 | key_sym: "s" | ||
626 | row: 4 | ||
627 | col: 3.8 | ||
628 | Key: | ||
629 | id: Key_100 | ||
630 | key_code: 100 | ||
631 | key_sym: "d" | ||
632 | row: 4 | ||
633 | col: 4.8 | ||
634 | Key: | ||
635 | id: Key_102 | ||
636 | key_code: 102 | ||
637 | key_sym: "f" | ||
638 | row: 4 | ||
639 | col: 5.8 | ||
640 | Key: | ||
641 | id: Key_103 | ||
642 | key_code: 103 | ||
643 | key_sym: "g" | ||
644 | row: 4 | ||
645 | col: 6.8 | ||
646 | Key: | ||
647 | id: Key_104 | ||
648 | key_code: 104 | ||
649 | key_sym: "h" | ||
650 | row: 4 | ||
651 | col: 7.8 | ||
652 | Key: | ||
653 | id: Key_106 | ||
654 | key_code: 106 | ||
655 | key_sym: "j" | ||
656 | row: 4 | ||
657 | col: 8.8 | ||
658 | Key: | ||
659 | id: Key_107 | ||
660 | key_code: 107 | ||
661 | key_sym: "k" | ||
662 | row: 4 | ||
663 | col: 9.8 | ||
664 | Key: | ||
665 | id: Key_108 | ||
666 | key_code: 108 | ||
667 | key_sym: "l" | ||
668 | row: 4 | ||
669 | col: 10.8 | ||
670 | Key: | ||
671 | id: Key_109 | ||
672 | key_code: 109 | ||
673 | key_sym: "m" | ||
674 | row: 4 | ||
675 | col: 11.8 | ||
676 | Key: | ||
677 | id: Key_249 | ||
678 | key_code: 249 | ||
679 | key_sym: "ù" | ||
680 | row: 4 | ||
681 | col: 12.8 | ||
682 | Key: | ||
683 | id: Key_42 | ||
684 | key_code: 42 | ||
685 | key_sym: "*" | ||
686 | row: 4 | ||
687 | col: 13.8 | ||
688 | Key: | ||
689 | id: Key_304 | ||
690 | key_code: 304 | ||
691 | key_sym: "LShift" | ||
692 | row: 5 | ||
693 | col: 1 | ||
694 | key_width: 1.3 | ||
695 | line_width: 1 | ||
696 | enabled: False | ||
697 | Key: | ||
698 | id: Key_60 | ||
699 | key_code: 60 | ||
700 | key_sym: "<" | ||
701 | row: 5 | ||
702 | col: 2.3 | ||
703 | Key: | ||
704 | id: Key_119 | ||
705 | key_code: 119 | ||
706 | key_sym: "w" | ||
707 | row: 5 | ||
708 | col: 3.3 | ||
709 | Key: | ||
710 | id: Key_120 | ||
711 | key_code: 120 | ||
712 | key_sym: "x" | ||
713 | row: 5 | ||
714 | col: 4.3 | ||
715 | Key: | ||
716 | id: Key_99 | ||
717 | key_code: 99 | ||
718 | key_sym: "c" | ||
719 | row: 5 | ||
720 | col: 5.3 | ||
721 | Key: | ||
722 | id: Key_118 | ||
723 | key_code: 118 | ||
724 | key_sym: "v" | ||
725 | row: 5 | ||
726 | col: 6.3 | ||
727 | Key: | ||
728 | id: Key_98 | ||
729 | key_code: 98 | ||
730 | key_sym: "b" | ||
731 | row: 5 | ||
732 | col: 7.3 | ||
733 | Key: | ||
734 | id: Key_110 | ||
735 | key_code: 110 | ||
736 | key_sym: "n" | ||
737 | row: 5 | ||
738 | col: 8.3 | ||
739 | Key: | ||
740 | id: Key_44 | ||
741 | key_code: 44 | ||
742 | key_sym: "," | ||
743 | row: 5 | ||
744 | col: 9.3 | ||
745 | Key: | ||
746 | id: Key_59 | ||
747 | key_code: 59 | ||
748 | key_sym: ";" | ||
749 | row: 5 | ||
750 | col: 10.3 | ||
751 | Key: | ||
752 | id: Key_58 | ||
753 | key_code: 58 | ||
754 | key_sym: ":" | ||
755 | row: 5 | ||
756 | col: 11.3 | ||
757 | Key: | ||
758 | id: Key_33 | ||
759 | key_code: 33 | ||
760 | key_sym: "!" | ||
761 | row: 5 | ||
762 | col: 12.3 | ||
763 | Key: | ||
764 | id: Key_303 | ||
765 | key_code: 303 | ||
766 | key_sym: "RShift" | ||
767 | row: 5 | ||
768 | col: 13.3 | ||
769 | key_width: 2.7 | ||
770 | line_width: 1 | ||
771 | enabled: False | ||
772 | Key: | ||
773 | id: Key_306 | ||
774 | key_code: 306 | ||
775 | key_sym: "LCtrl" | ||
776 | row: 6 | ||
777 | col: 1 | ||
778 | key_width: 1.3 | ||
779 | line_width: 1 | ||
780 | enabled: False | ||
781 | Key: | ||
782 | id: Key_311 | ||
783 | key_code: 311 | ||
784 | key_sym: "LSuper" | ||
785 | row: 6 | ||
786 | col: 3.3 | ||
787 | line_width: 1 | ||
788 | enabled: False | ||
789 | Key: | ||
790 | id: Key_308 | ||
791 | key_code: 308 | ||
792 | key_sym: "LAlt" | ||
793 | row: 6 | ||
794 | col: 4.3 | ||
795 | line_width: 1 | ||
796 | enabled: False | ||
797 | Key: | ||
798 | id: Key_32 | ||
799 | key_code: 32 | ||
800 | key_sym: "Espace" | ||
801 | row: 6 | ||
802 | col: 5.3 | ||
803 | key_width: 5 | ||
804 | Key: | ||
805 | id: Key_313 | ||
806 | key_code: 313 | ||
807 | key_sym: "AltGr" | ||
808 | row: 6 | ||
809 | col: 10.3 | ||
810 | line_width: 1 | ||
811 | enabled: False | ||
812 | Key: | ||
813 | id: Key_314 | ||
814 | key_code: 314 | ||
815 | key_sym: "Compose" | ||
816 | row: 6 | ||
817 | col: 11.3 | ||
818 | line_width: 1 | ||
819 | enabled: False | ||
820 | Key: | ||
821 | id: Key_305 | ||
822 | key_code: 305 | ||
823 | key_sym: "RCtrl" | ||
824 | row: 6 | ||
825 | col: 12.3 | ||
826 | key_width: 1.3 | ||
827 | line_width: 1 | ||
828 | enabled: False | ||
829 | |||
830 | |||
831 | Key: | ||
832 | id: Key_277 | ||
833 | key_code: 277 | ||
834 | key_sym: "ins" | ||
835 | row: 2 | ||
836 | col: 1 | ||
837 | pad_cols: True | ||
838 | Key: | ||
839 | id: Key_278 | ||
840 | key_code: 278 | ||
841 | key_sym: "home" | ||
842 | row: 2 | ||
843 | col: 2 | ||
844 | pad_cols: True | ||
845 | Key: | ||
846 | id: Key_280 | ||
847 | key_code: 280 | ||
848 | key_sym: "pg_u" | ||
849 | row: 2 | ||
850 | col: 3 | ||
851 | pad_cols: True | ||
852 | Key: | ||
853 | id: Key_127 | ||
854 | key_code: 127 | ||
855 | key_sym: "del" | ||
856 | row: 3 | ||
857 | col: 1 | ||
858 | pad_cols: True | ||
859 | Key: | ||
860 | id: Key_279 | ||
861 | key_code: 279 | ||
862 | key_sym: "end" | ||
863 | row: 3 | ||
864 | col: 2 | ||
865 | pad_cols: True | ||
866 | Key: | ||
867 | id: Key_281 | ||
868 | key_code: 281 | ||
869 | key_sym: "pg_d" | ||
870 | row: 3 | ||
871 | col: 3 | ||
872 | pad_cols: True | ||
873 | Key: | ||
874 | id: Key_273 | ||
875 | key_code: 273 | ||
876 | key_sym: "up" | ||
877 | row: 5 | ||
878 | col: 2 | ||
879 | pad_cols: True | ||
880 | Key: | ||
881 | id: Key_274 | ||
882 | key_code: 274 | ||
883 | key_sym: "down" | ||
884 | row: 6 | ||
885 | col: 2 | ||
886 | pad_cols: True | ||
887 | Key: | ||
888 | id: Key_276 | ||
889 | key_code: 276 | ||
890 | key_sym: "left" | ||
891 | row: 6 | ||
892 | col: 1 | ||
893 | pad_cols: True | ||
894 | Key: | ||
895 | id: Key_275 | ||
896 | key_code: 275 | ||
897 | key_sym: "right" | ||
898 | row: 6 | ||
899 | col: 3 | ||
900 | pad_cols: True | ||