diff options
author | Ismaël Bouya <ismael.bouya@normalesup.org> | 2016-06-20 23:08:22 +0200 |
---|---|---|
committer | Ismaël Bouya <ismael.bouya@normalesup.org> | 2016-06-20 23:15:47 +0200 |
commit | 9de92b6dd2bd906f6a64fce7c90a6aff0dbb27a2 (patch) | |
tree | c654b7691e8bc92bd1726554e0d353604ebb4d71 | |
parent | d479af33afa54fee7c22701c6012a1579ead395f (diff) | |
download | MusicSampler-9de92b6dd2bd906f6a64fce7c90a6aff0dbb27a2.tar.gz MusicSampler-9de92b6dd2bd906f6a64fce7c90a6aff0dbb27a2.tar.zst MusicSampler-9de92b6dd2bd906f6a64fce7c90a6aff0dbb27a2.zip |
Added music name, currently playing musics, pause/unpause
-rw-r--r-- | Symbola.ttf | bin | 0 -> 2188952 bytes | |||
-rw-r--r-- | config.yml | 24 | ||||
-rw-r--r-- | helpers/__init__.py | 7 | ||||
-rw-r--r-- | helpers/action.py | 26 | ||||
-rw-r--r-- | helpers/key.py | 4 | ||||
-rw-r--r-- | helpers/music_file.py | 19 | ||||
-rw-r--r-- | music_sampler.py | 31 | ||||
-rw-r--r-- | music_sampler.spec | 6 |
8 files changed, 96 insertions, 21 deletions
diff --git a/Symbola.ttf b/Symbola.ttf new file mode 100644 index 0000000..51d9a88 --- /dev/null +++ b/Symbola.ttf | |||
Binary files differ | |||
@@ -1,36 +1,52 @@ | |||
1 | aliases: | 1 | aliases: |
2 | intro_jonglacro: | 2 | intro_jonglacro: |
3 | file: "PIRATE_01-1-intro_jonglacro.mp3" | 3 | file: "PIRATE_01-1-intro_jonglacro.mp3" |
4 | name: Intro Jonglacro | ||
4 | jonglacro_suite: | 5 | jonglacro_suite: |
5 | file: "PIRATE_01-2-jonglacro_suite.mp3" | 6 | file: "PIRATE_01-2-jonglacro_suite.mp3" |
7 | name: Jonglacro suite | ||
6 | lancer_prisonniere: | 8 | lancer_prisonniere: |
7 | file: "PIRATE_02-lancers_de_prisonniere.mp3" | 9 | file: "PIRATE_02-lancers_de_prisonniere.mp3" |
10 | name: Lancer prisonnière | ||
8 | quete: | 11 | quete: |
9 | file: "PIRATE_03-quete.mp3" | 12 | file: "PIRATE_03-quete.mp3" |
13 | name: Quête | ||
10 | entree_ondine: | 14 | entree_ondine: |
11 | file: "PIRATE_04-entree_ondine.mp3" | 15 | file: "PIRATE_04-entree_ondine.mp3" |
16 | name: Entrée Ondine | ||
12 | cour_ondine: | 17 | cour_ondine: |
13 | file: "PIRATE_05-cour_a_londine.mp3" | 18 | file: "PIRATE_05-cour_a_londine.mp3" |
19 | name: Cour à l'Ondine | ||
14 | fouille_jonglage: | 20 | fouille_jonglage: |
15 | file: "PIRATE_07-fouille_jonglage.mp3" | 21 | file: "PIRATE_07-fouille_jonglage.mp3" |
22 | name: Fouille jonglage | ||
16 | liberation_prisonniere: | 23 | liberation_prisonniere: |
17 | file: "PIRATE_08-liberation_prisonniere.mp3" | 24 | file: "PIRATE_08-liberation_prisonniere.mp3" |
25 | name: Libération prisonnière | ||
18 | duo_pirate_ondine: | 26 | duo_pirate_ondine: |
19 | file: "PIRATE_09-duo_pirate_ondine.mp3" | 27 | file: "PIRATE_09-duo_pirate_ondine.mp3" |
28 | name: Duo pirate Ondine | ||
20 | trio_jalousie: | 29 | trio_jalousie: |
21 | file: "PIRATE_10-trios_jalousie.mp3" | 30 | file: "PIRATE_10-trios_jalousie.mp3" |
31 | name: Trio Jalousie | ||
22 | piquage_2_4: | 32 | piquage_2_4: |
23 | file: "PIRATE_11-piquage_2_4.mp3" | 33 | file: "PIRATE_11-piquage_2_4.mp3" |
34 | name: Piquage 2-4 | ||
24 | baston: | 35 | baston: |
25 | file: "PIRATE_12-1-baston.mp3" | 36 | file: "PIRATE_12-1-baston.mp3" |
37 | name: Baston | ||
26 | baston_ascension: | 38 | baston_ascension: |
27 | file: "PIRATE_12-3-baston_ascension.mp3" | 39 | file: "PIRATE_12-3-baston_ascension.mp3" |
40 | name: Baston ascension | ||
28 | bruit: | 41 | bruit: |
29 | file: "PIRATE_bruit.wav" | 42 | file: "PIRATE_bruit.wav" |
43 | name: Bruit | ||
30 | paf: | 44 | paf: |
31 | file: "PIRATE_paf.mp3" | 45 | file: "PIRATE_paf.mp3" |
46 | name: Paf | ||
32 | ralenti: | 47 | ralenti: |
33 | file: "PIRATE_12-2-ralenti.mp3" | 48 | file: "PIRATE_12-2-ralenti.mp3" |
49 | name: Ralenti | ||
34 | 50 | ||
35 | key_properties: | 51 | key_properties: |
36 | 'a': | 52 | 'a': |
@@ -42,7 +58,7 @@ key_properties: | |||
42 | description: | 58 | description: |
43 | - #Chloé | 59 | - #Chloé |
44 | - Jonglacro | 60 | - Jonglacro |
45 | - 2 | 61 | - "2" |
46 | color: [73, 221, 226] | 62 | color: [73, 221, 226] |
47 | 'e': | 63 | 'e': |
48 | description: | 64 | description: |
@@ -140,7 +156,7 @@ key_properties: | |||
140 | description: | 156 | description: |
141 | - #Jérôme | 157 | - #Jérôme |
142 | - Jeu à | 158 | - Jeu à |
143 | - 2 4 | 159 | - "2 4" |
144 | color: [240, 158, 0] | 160 | color: [240, 158, 0] |
145 | 'm': | 161 | 'm': |
146 | description: | 162 | description: |
@@ -162,12 +178,12 @@ key_properties: | |||
162 | 'c': | 178 | 'c': |
163 | description: | 179 | description: |
164 | - #Christophe | 180 | - #Christophe |
165 | - Baston 2 | 181 | - Baston "2" |
166 | color: [255, 255, 0] | 182 | color: [255, 255, 0] |
167 | 'v': | 183 | 'v': |
168 | description: | 184 | description: |
169 | - #Auréliane | 185 | - #Auréliane |
170 | - Fin baston 2 | 186 | - Fin baston "2" |
171 | color: [0, 190, 27] | 187 | color: [0, 190, 27] |
172 | 188 | ||
173 | 189 | ||
diff --git a/helpers/__init__.py b/helpers/__init__.py index d0d3f46..b3ab1eb 100644 --- a/helpers/__init__.py +++ b/helpers/__init__.py | |||
@@ -41,7 +41,10 @@ def parse_config(mapping): | |||
41 | if argument == 'file': | 41 | if argument == 'file': |
42 | filename = action[action_name]['file'] | 42 | filename = action[action_name]['file'] |
43 | if filename not in seen_files: | 43 | if filename not in seen_files: |
44 | seen_files[filename] = MusicFile(filename, file_lock, channel_id) | 44 | if 'name' in action[action_name]: |
45 | seen_files[filename] = MusicFile(filename, file_lock, channel_id, name = action[action_name]['name']) | ||
46 | else: | ||
47 | seen_files[filename] = MusicFile(filename, file_lock, channel_id) | ||
45 | channel_id = channel_id + 1 | 48 | channel_id = channel_id + 1 |
46 | 49 | ||
47 | action_args['music'] = seen_files[filename] | 50 | action_args['music'] = seen_files[filename] |
@@ -62,4 +65,4 @@ def parse_config(mapping): | |||
62 | key.set_color(config['key_properties'][key_property]['color']) | 65 | key.set_color(config['key_properties'][key_property]['color']) |
63 | 66 | ||
64 | # Return the number of channels reserved | 67 | # Return the number of channels reserved |
65 | return channel_id + 1 | 68 | return (channel_id + 1, seen_files) |
diff --git a/helpers/action.py b/helpers/action.py index 5afe437..1cb1686 100644 --- a/helpers/action.py +++ b/helpers/action.py | |||
@@ -8,6 +8,7 @@ class Action: | |||
8 | 'play', | 8 | 'play', |
9 | 'stop', | 9 | 'stop', |
10 | 'stop_all_actions', | 10 | 'stop_all_actions', |
11 | 'unpause', | ||
11 | 'volume', | 12 | 'volume', |
12 | 'wait', | 13 | 'wait', |
13 | ] | 14 | ] |
@@ -29,7 +30,8 @@ class Action: | |||
29 | 30 | ||
30 | def run(self): | 31 | def run(self): |
31 | print(self.description()) | 32 | print(self.description()) |
32 | return getattr(self, self.action)(**self.arguments) | 33 | getattr(self, self.action)(**self.arguments) |
34 | pygame.event.post(pygame.event.Event(pygame.USEREVENT)) | ||
33 | 35 | ||
34 | def description(self): | 36 | def description(self): |
35 | return getattr(self, self.action + "_print")(**self.arguments) | 37 | return getattr(self, self.action + "_print")(**self.arguments) |
@@ -43,6 +45,12 @@ class Action: | |||
43 | else: | 45 | else: |
44 | pygame.mixer.pause() | 46 | pygame.mixer.pause() |
45 | 47 | ||
48 | def unpause(self, music = None, **kwargs): | ||
49 | if music is not None: | ||
50 | music.unpause() | ||
51 | else: | ||
52 | pygame.mixer.unpause() | ||
53 | |||
46 | def play(self, music = None, fade_in = 0, start_at = 0, | 54 | def play(self, music = None, fade_in = 0, start_at = 0, |
47 | restart_if_running = False, volume = 100, **kwargs): | 55 | restart_if_running = False, volume = 100, **kwargs): |
48 | if music is not None: | 56 | if music is not None: |
@@ -88,15 +96,21 @@ class Action: | |||
88 | 96 | ||
89 | def pause_print(self, music = None, **kwargs): | 97 | def pause_print(self, music = None, **kwargs): |
90 | if music is not None: | 98 | if music is not None: |
91 | return "pausing {}".format(music.filename) | 99 | return "pausing « {} »".format(music.name) |
92 | else: | 100 | else: |
93 | return "pausing all musics" | 101 | return "pausing all musics" |
94 | 102 | ||
103 | def unpause_print(self, music = None, **kwargs): | ||
104 | if music is not None: | ||
105 | return "unpausing « {} »".format(music.name) | ||
106 | else: | ||
107 | return "unpausing all musics" | ||
108 | |||
95 | def play_print(self, music = None, fade_in = 0, start_at = 0, | 109 | def play_print(self, music = None, fade_in = 0, start_at = 0, |
96 | restart_if_running = False, volume = 100, **kwargs): | 110 | restart_if_running = False, volume = 100, **kwargs): |
97 | message = "starting " | 111 | message = "starting " |
98 | if music is not None: | 112 | if music is not None: |
99 | message += music.filename | 113 | message += "« {} »".format(music.name) |
100 | else: | 114 | else: |
101 | message += "music" | 115 | message += "music" |
102 | 116 | ||
@@ -116,9 +130,9 @@ class Action: | |||
116 | def stop_print(self, music = None, fade_out = 0, **kwargs): | 130 | def stop_print(self, music = None, fade_out = 0, **kwargs): |
117 | if music is not None: | 131 | if music is not None: |
118 | if fade_out == 0: | 132 | if fade_out == 0: |
119 | return "stopping music {}".format(music.filename) | 133 | return "stopping music « {} »".format(music.name) |
120 | else: | 134 | else: |
121 | return "stopping music {} with {}s fadeout".format(music.filename, fade_out) | 135 | return "stopping music « {} » with {}s fadeout".format(music.name, fade_out) |
122 | else: | 136 | else: |
123 | if fade_out == 0: | 137 | if fade_out == 0: |
124 | return "stopping all musics" | 138 | return "stopping all musics" |
@@ -130,7 +144,7 @@ class Action: | |||
130 | 144 | ||
131 | def volume_print(self, music = None, value = 100, **kwargs): | 145 | def volume_print(self, music = None, value = 100, **kwargs): |
132 | if music is not None: | 146 | if music is not None: |
133 | return "setting volume of {} to {}%".format(music.filename, value) | 147 | return "setting volume of « {} » to {}%".format(music.name, value) |
134 | else: | 148 | else: |
135 | return "setting volume to {}%".format(value) | 149 | return "setting volume to {}%".format(value) |
136 | 150 | ||
diff --git a/helpers/key.py b/helpers/key.py index 7b8051e..57fdef1 100644 --- a/helpers/key.py +++ b/helpers/key.py | |||
@@ -149,7 +149,7 @@ class Key: | |||
149 | #print("actions linked to key {}:".format(self.key_sym)) | 149 | #print("actions linked to key {}:".format(self.key_sym)) |
150 | #print("\t" + "\n\t".join(action_descriptions)) | 150 | #print("\t" + "\n\t".join(action_descriptions)) |
151 | self.draw_lock.acquire() | 151 | self.draw_lock.acquire() |
152 | surface = pygame.Surface((800, 250)).convert() | 152 | surface = pygame.Surface((690, 250)).convert() |
153 | surface.fill((250, 250, 250)) | 153 | surface.fill((250, 250, 250)) |
154 | if getattr(sys, 'frozen', False): | 154 | if getattr(sys, 'frozen', False): |
155 | police = pygame.font.Font(sys._MEIPASS + "/Ubuntu-Regular.ttf", 14) | 155 | police = pygame.font.Font(sys._MEIPASS + "/Ubuntu-Regular.ttf", 14) |
@@ -168,7 +168,7 @@ class Key: | |||
168 | surface.blit(text, (0, offset)) | 168 | surface.blit(text, (0, offset)) |
169 | offset += police.get_linesize() | 169 | offset += police.get_linesize() |
170 | 170 | ||
171 | screen.blit(surface, (10, 330)) | 171 | screen.blit(surface, (5, 308)) |
172 | pygame.display.flip() | 172 | pygame.display.flip() |
173 | self.draw_lock.release() | 173 | self.draw_lock.release() |
174 | 174 | ||
diff --git a/helpers/music_file.py b/helpers/music_file.py index f6b0117..d40a132 100644 --- a/helpers/music_file.py +++ b/helpers/music_file.py | |||
@@ -3,28 +3,35 @@ import pydub | |||
3 | import pygame | 3 | import pygame |
4 | 4 | ||
5 | class MusicFile: | 5 | class MusicFile: |
6 | def __init__(self, filename, lock, channel_id): | 6 | def __init__(self, filename, lock, channel_id, name = None): |
7 | self.filename = filename | 7 | self.filename = filename |
8 | self.channel_id = channel_id | 8 | self.channel_id = channel_id |
9 | self.name = name or filename | ||
9 | self.raw_data = None | 10 | self.raw_data = None |
10 | self.sound = None | 11 | self.sound = None |
11 | 12 | ||
12 | self.loaded = False | 13 | self.loaded = False |
14 | self.flag_paused = False | ||
13 | threading.Thread(name = "MSMusicLoad", target = self.load_sound, args = [lock]).start() | 15 | threading.Thread(name = "MSMusicLoad", target = self.load_sound, args = [lock]).start() |
14 | 16 | ||
15 | def load_sound(self, lock): | 17 | def load_sound(self, lock): |
16 | lock.acquire() | 18 | lock.acquire() |
17 | print("Loading {}".format(self.filename)) | 19 | print("Loading « {} »".format(self.name)) |
18 | self.raw_data = pydub.AudioSegment.from_file(self.filename).raw_data | 20 | self.raw_data = pydub.AudioSegment.from_file(self.filename).raw_data |
19 | self.sound = pygame.mixer.Sound(self.raw_data) | 21 | self.sound = pygame.mixer.Sound(self.raw_data) |
20 | print("Loaded {}".format(self.filename)) | 22 | print("Loaded « {} »".format(self.name)) |
21 | self.loaded = True | 23 | self.loaded = True |
22 | lock.release() | 24 | lock.release() |
23 | 25 | ||
24 | def is_playing(self): | 26 | def is_playing(self): |
25 | return self.channel().get_busy() | 27 | return self.channel().get_busy() |
26 | 28 | ||
29 | def is_paused(self): | ||
30 | return self.flag_paused | ||
31 | |||
27 | def play(self, fade_in = 0, volume = 100, start_at = 0): | 32 | def play(self, fade_in = 0, volume = 100, start_at = 0): |
33 | self.channel().set_endevent() | ||
34 | self.channel().set_endevent(pygame.USEREVENT) | ||
28 | self.set_volume(volume) | 35 | self.set_volume(volume) |
29 | 36 | ||
30 | if start_at > 0: | 37 | if start_at > 0: |
@@ -37,9 +44,15 @@ class MusicFile: | |||
37 | self.sound = pygame.mixer.Sound(self.raw_data) | 44 | self.sound = pygame.mixer.Sound(self.raw_data) |
38 | 45 | ||
39 | self.channel().play(self.sound, fade_ms = fade_in * 1000) | 46 | self.channel().play(self.sound, fade_ms = fade_in * 1000) |
47 | self.flag_paused = False | ||
40 | 48 | ||
41 | def pause(self): | 49 | def pause(self): |
42 | self.channel().pause() | 50 | self.channel().pause() |
51 | self.flag_paused = True | ||
52 | |||
53 | def unpause(self): | ||
54 | self.channel().unpause() | ||
55 | self.flag_paused = False | ||
43 | 56 | ||
44 | def stop(self, fade_out = 0): | 57 | def stop(self, fade_out = 0): |
45 | if fade_out > 0: | 58 | if fade_out > 0: |
diff --git a/music_sampler.py b/music_sampler.py index 8dbbc28..ff04fd1 100644 --- a/music_sampler.py +++ b/music_sampler.py | |||
@@ -6,14 +6,14 @@ import threading | |||
6 | pygame.mixer.pre_init(frequency = 44100) | 6 | pygame.mixer.pre_init(frequency = 44100) |
7 | pygame.init() | 7 | pygame.init() |
8 | 8 | ||
9 | size = width, height = 1024, 600 | 9 | size = width, height = 913, 563 |
10 | screen = pygame.display.set_mode(size) | 10 | screen = pygame.display.set_mode(size) |
11 | screen.fill((250, 250, 250)) | 11 | screen.fill((229, 228, 226)) |
12 | 12 | ||
13 | draw_lock = helpers.Lock("draw") | 13 | draw_lock = helpers.Lock("draw") |
14 | 14 | ||
15 | mapping = helpers.Mapping(screen, draw_lock) | 15 | mapping = helpers.Mapping(screen, draw_lock) |
16 | channel_number = helpers.parse_config(mapping) | 16 | channel_number, open_files = helpers.parse_config(mapping) |
17 | pygame.mixer.set_num_channels(channel_number) | 17 | pygame.mixer.set_num_channels(channel_number) |
18 | 18 | ||
19 | mapping.draw() | 19 | mapping.draw() |
@@ -49,12 +49,37 @@ while 1: | |||
49 | key = mapping.find_by_key_num(event.key) | 49 | key = mapping.find_by_key_num(event.key) |
50 | if key is not None: | 50 | if key is not None: |
51 | threading.Thread(name = "MSKeyAction", target=key.do_actions).start() | 51 | threading.Thread(name = "MSKeyAction", target=key.do_actions).start() |
52 | threading.Thread(name = "MSClic", target=key.list_actions, args = [screen]).start() | ||
52 | elif event.type == pygame.MOUSEBUTTONUP: | 53 | elif event.type == pygame.MOUSEBUTTONUP: |
53 | key = mapping.find_by_collidepoint(pygame.mouse.get_pos()) | 54 | key = mapping.find_by_collidepoint(pygame.mouse.get_pos()) |
54 | if key is not None: | 55 | if key is not None: |
55 | threading.Thread(name = "MSClic", target=key.list_actions, args = [screen]).start() | 56 | threading.Thread(name = "MSClic", target=key.list_actions, args = [screen]).start() |
56 | 57 | ||
57 | draw_lock.acquire() | 58 | draw_lock.acquire() |
59 | if getattr(sys, 'frozen', False): | ||
60 | icon_police = pygame.font.Font(sys._MEIPASS + "/Symbola.ttf", 19) | ||
61 | police = pygame.font.Font(sys._MEIPASS + "/Ubuntu-Regular.ttf", 14) | ||
62 | else: | ||
63 | icon_police = pygame.font.Font("Symbola.ttf", 19) | ||
64 | police = pygame.font.Font("Ubuntu-Regular.ttf", 14) | ||
65 | |||
66 | surface = pygame.Surface((208, 250)).convert() | ||
67 | surface.fill((250, 250, 250)) | ||
68 | offset = 0 | ||
69 | for music_file in open_files.values(): | ||
70 | police.set_bold(False) | ||
71 | if music_file.is_playing(): | ||
72 | icon = icon_police.render("⏵", True, (0,0,0)) | ||
73 | if music_file.is_paused(): | ||
74 | icon = icon_police.render("⏸", True, (0,0,0)) | ||
75 | else: | ||
76 | police.set_bold(True) | ||
77 | text = police.render(music_file.name, True, (0,0,0)) | ||
78 | surface.blit(icon, (0, offset)) | ||
79 | surface.blit(text, (20, offset)) | ||
80 | offset += police.get_linesize() | ||
81 | screen.blit(surface, (700, 308)) | ||
82 | |||
58 | pygame.display.flip() | 83 | pygame.display.flip() |
59 | draw_lock.release() | 84 | draw_lock.release() |
60 | 85 | ||
diff --git a/music_sampler.spec b/music_sampler.spec index 3c85a2a..a60c546 100644 --- a/music_sampler.spec +++ b/music_sampler.spec | |||
@@ -4,7 +4,11 @@ block_cipher = None | |||
4 | 4 | ||
5 | a = Analysis(['music_sampler.py'], | 5 | a = Analysis(['music_sampler.py'], |
6 | binaries=None, | 6 | binaries=None, |
7 | datas=[('config.yml', '.'), ('Ubuntu-Regular.ttf', '.')], | 7 | datas=[ |
8 | ('config.yml', '.'), | ||
9 | ('Ubuntu-Regular.ttf', '.'), | ||
10 | ('Symbola.ttf', '.') | ||
11 | ], | ||
8 | hiddenimports=[ | 12 | hiddenimports=[ |
9 | 'six', | 13 | 'six', |
10 | 'packaging', | 14 | 'packaging', |