aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsmaël Bouya <ismael.bouya@normalesup.org>2016-06-20 23:08:22 +0200
committerIsmaël Bouya <ismael.bouya@normalesup.org>2016-06-20 23:15:47 +0200
commit9de92b6dd2bd906f6a64fce7c90a6aff0dbb27a2 (patch)
treec654b7691e8bc92bd1726554e0d353604ebb4d71
parentd479af33afa54fee7c22701c6012a1579ead395f (diff)
downloadMusicSampler-9de92b6dd2bd906f6a64fce7c90a6aff0dbb27a2.tar.gz
MusicSampler-9de92b6dd2bd906f6a64fce7c90a6aff0dbb27a2.tar.zst
MusicSampler-9de92b6dd2bd906f6a64fce7c90a6aff0dbb27a2.zip
Added music name, currently playing musics, pause/unpause
-rw-r--r--Symbola.ttfbin0 -> 2188952 bytes
-rw-r--r--config.yml24
-rw-r--r--helpers/__init__.py7
-rw-r--r--helpers/action.py26
-rw-r--r--helpers/key.py4
-rw-r--r--helpers/music_file.py19
-rw-r--r--music_sampler.py31
-rw-r--r--music_sampler.spec6
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
diff --git a/config.yml b/config.yml
index bd67496..a27f2e1 100644
--- a/config.yml
+++ b/config.yml
@@ -1,36 +1,52 @@
1aliases: 1aliases:
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
35key_properties: 51key_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
3import pygame 3import pygame
4 4
5class MusicFile: 5class 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
6pygame.mixer.pre_init(frequency = 44100) 6pygame.mixer.pre_init(frequency = 44100)
7pygame.init() 7pygame.init()
8 8
9size = width, height = 1024, 600 9size = width, height = 913, 563
10screen = pygame.display.set_mode(size) 10screen = pygame.display.set_mode(size)
11screen.fill((250, 250, 250)) 11screen.fill((229, 228, 226))
12 12
13draw_lock = helpers.Lock("draw") 13draw_lock = helpers.Lock("draw")
14 14
15mapping = helpers.Mapping(screen, draw_lock) 15mapping = helpers.Mapping(screen, draw_lock)
16channel_number = helpers.parse_config(mapping) 16channel_number, open_files = helpers.parse_config(mapping)
17pygame.mixer.set_num_channels(channel_number) 17pygame.mixer.set_num_channels(channel_number)
18 18
19mapping.draw() 19mapping.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
5a = Analysis(['music_sampler.py'], 5a = 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',