]>
git.immae.eu Git - perso/Immae/Projets/Python/MusicSampler.git/blob - helpers/mapping.py
d60e709bde0a80e96be783131d5ad4b847be6faa
1 from kivy
.uix
.relativelayout
import RelativeLayout
2 from kivy
.properties
import NumericProperty
, ListProperty
3 from kivy
.core
.window
import Window
4 from kivy
.clock
import Clock
10 from .music_file
import *
11 from .mixer
import Mixer
12 from . import Config
, gain
, error_print
13 from .music_effect
import GainEffect
14 from .action
import Action
16 class Mapping(RelativeLayout
):
17 expected_keys
= NumericProperty(0)
18 master_volume
= NumericProperty(100)
19 ready_color
= ListProperty([1, 165/255, 0, 1])
21 def __init__(self
, **kwargs
):
22 if Config
.builtin_mixing
:
28 self
.key_config
, self
.open_files
= self
.parse_config()
29 except Exception as e
:
30 error_print("Error while loading configuration: {}".format(e
))
33 super(Mapping
, self
).__init
__(**kwargs
)
34 self
._keyboard
= Window
.request_keyboard(self
._keyboard
_closed
, self
)
35 self
._keyboard
.bind(on_key_down
=self
._on
_keyboard
_down
)
38 Clock
.schedule_interval(self
.not_all_keys_ready
, 1)
41 def master_gain(self
):
42 return gain(self
.master_volume
)
44 def set_master_volume(self
, value
, delta
=False, fade
=0):
45 [db_gain
, self
.master_volume
] = gain(
46 value
+ int(delta
) * self
.master_volume
,
49 for music
in self
.open_files
.values():
50 if not (music
.is_loaded_playing() or music
.is_loaded_paused()):
54 music
.gain_effects
.append(GainEffect(
56 music
.current_audio_segment
,
59 music
.sound_position
+ fade
,
62 music
.set_gain(db_gain
)
64 def add_wait_id(self
, wait_id
, action_or_wait
):
65 self
.wait_ids
[wait_id
] = action_or_wait
67 def interrupt_wait(self
, wait_id
):
68 if wait_id
in self
.wait_ids
:
69 action_or_wait
= self
.wait_ids
[wait_id
]
70 del(self
.wait_ids
[wait_id
])
71 if isinstance(action_or_wait
, Action
):
72 action_or_wait
.interrupt()
76 def _keyboard_closed(self
):
77 self
._keyboard
.unbind(on_key_down
=self
._on
_keyboard
_down
)
80 def _on_keyboard_down(self
, keyboard
, keycode
, text
, modifiers
):
81 key
= self
.find_by_key_code(keycode
)
82 if len(modifiers
) == 0 and key
is not None:
83 threading
.Thread(name
="MSKeyAction", target
=key
.do_actions
).start()
84 elif 'ctrl' in modifiers
and (keycode
[0] == 113 or keycode
[0] == '99'):
85 for thread
in threading
.enumerate():
86 if thread
.getName()[0:2] != "MS":
93 def find_by_key_code(self
, key_code
):
94 if "Key_" + str(key_code
[0]) in self
.ids
:
95 return self
.ids
["Key_" + str(key_code
[0])]
98 def not_all_keys_ready(self
, dt
):
99 for key
in self
.children
:
100 if not type(key
).__name
__ == "Key":
102 if not key
.is_key_ready
:
104 self
.ready_color
= [0, 1, 0, 1]
107 def stop_all_running(self
):
108 running
= self
.running
110 for (key
, start_time
) in running
:
111 key
.interrupt_action()
113 def start_running(self
, key
, start_time
):
114 self
.running
.append((key
, start_time
))
116 def keep_running(self
, key
, start_time
):
117 return (key
, start_time
) in self
.running
119 def finished_running(self
, key
, start_time
):
120 if (key
, start_time
) in self
.running
:
121 self
.running
.remove((key
, start_time
))
123 def parse_config(self
):
124 stream
= open(Config
.yml_file
, "r")
126 config
= yaml
.load(stream
)
127 except Exception as e
:
128 error_print("Error while loading config file: {}".format(e
))
132 aliases
= config
['aliases']
137 for key
in config
['key_properties']:
138 if key
not in key_properties
:
139 key_prop
= config
['key_properties'][key
]
140 if 'include' in key_prop
:
141 included
= key_prop
['include']
142 del(key_prop
['include'])
144 if isinstance(included
, str):
145 key_prop
.update(aliases
[included
], **key_prop
)
147 for included_
in included
:
148 key_prop
.update(aliases
[included_
], **key_prop
)
150 key_properties
[key
] = {
152 "properties": key_prop
,
156 for mapped_key
in config
['keys']:
157 if mapped_key
not in key_properties
:
158 key_properties
[mapped_key
] = {
163 for action
in config
['keys'][mapped_key
]:
164 action_name
= list(action
)[0]
166 if action
[action_name
] is None:
167 action
[action_name
] = []
169 if 'include' in action
[action_name
]:
170 included
= action
[action_name
]['include']
171 del(action
[action_name
]['include'])
173 if isinstance(included
, str):
174 action
[action_name
].update(
176 **action
[action_name
])
178 for included_
in included
:
179 action
[action_name
].update(
181 **action
[action_name
])
183 for argument
in action
[action_name
]:
184 if argument
== 'file':
185 filename
= action
[action_name
]['file']
186 if filename
not in seen_files
:
187 if filename
in config
['music_properties']:
188 seen_files
[filename
] = MusicFile(
191 **config
['music_properties'][filename
])
193 seen_files
[filename
] = MusicFile(
197 if filename
not in key_properties
[mapped_key
]['files']:
198 key_properties
[mapped_key
]['files'] \
199 .append(seen_files
[filename
])
201 action_args
['music'] = seen_files
[filename
]
204 action_args
[argument
] = action
[action_name
][argument
]
206 key_properties
[mapped_key
]['actions'] \
207 .append([action_name
, action_args
])
209 return (key_properties
, seen_files
)