/
play.py
183 lines (136 loc) · 5.48 KB
/
play.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
import alsaseq
import pygame
import os
import os.path
import argparse
import configparser
import options_play
class SoundGame(object):
"""docstring forSoundGame."""
def __init__(self, options):
self.options = options
self.perform_initializations()
def print_newpage(self):
newpage_string = '\x1bc'
print(newpage_string)
def load_files(self):
self.images = []
if self.options["presentation_mode"]:
filename = self.options["song_folder_complete"] + "/presentation_mode_start.png"
img = pygame.image.load(filename)
self.images.append(img)
folder = self.options["song_folder_complete"]
files = [f for f in os.listdir(folder) if os.path.isfile(os.path.join(folder, f))]
files = sorted(files)
for f in files:
extension = os.path.splitext(f)[1]
if extension == ".png" and f != "presentation_mode_start.png":
filename = os.path.join(folder, f)
img = pygame.image.load(filename)
self.images.append(img)
no_of_steps = len(self.images)
print(str(no_of_steps) + " images loaded.")
self.midi_notes = []
read_data_to_container(self.midi_notes, "midi_notes", self.options["song_folder_complete"], int)
if self.options["presentation_mode"]:
self.midi_notes.append([])
def update_step(self, direction="forward"):
if direction == "forward":
self.current_step = (self.current_step + 1) % len(self.images)
elif direction == "backward":
self.current_step = (self.current_step - 1)
if self.current_step == -1:
self.current_step = len(self.images) - 1
self.current_activations = []
self.correct_notes = self.midi_notes[self.current_step]
white = (255,255,255)
self.display.fill(white)
self.display.blit(self.images[self.current_step], (0,0))
pygame.display.update()
def perform_initializations(self):
self.init_pygame()
self.init_alsa()
self.load_files()
self.is_running = True
self.interrupt = False
self.current_step = -1
self.update_step()
def init_alsa(self):
# prepare alsaseq
device_no = self.options["midi_device_no"] # find out using aconnect or aconnectgui
alsaseq.client('Recorder', 1, 0, True )
alsaseq.connectfrom( 0, device_no, 0 )
alsaseq.start()
def init_pygame(self):
# pygame mixer
# mixer_buffer = 10
# pygame.mixer.pre_init(44100, -16, 1, mixer_buffer)
# pygame.mixer.init()
# display
full_screen = False
full_screen = True
if full_screen:
os.environ['SDL_VIDEO_WINDOW_POS'] = "0,0"
pygame.init()
info = pygame.display.Info()
self.display = pygame.display.set_mode((info.current_w, info.current_h), pygame.NOFRAME)
else:
self.display = pygame.display.set_mode((0,0))
pygame.display.set_caption('Lilypond Piano Trainer')
def reaction_note_on(self,event):
if not self.interrupt:
pitch = event[7][1]
velocity = event[7][2]
if velocity > 0:
if pitch in self.correct_notes:
if not pitch in self.current_activations:
self.current_activations.append(pitch)
if len(self.current_activations) == len(self.correct_notes):
self.update_step()
elif self.options["presentation_mode"] and self.current_step == len(self.images) - 1:
self.update_step()
def reaction_note_off(self,event):
pass
def play(self):
while self.is_running:
# check for quit in pygame
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
self.interrupt = not self.interrupt
print("toggle interrupt")
if event.key == pygame.K_ESCAPE:
self.is_running = False
if event.key == pygame.K_RIGHT:
self.update_step()
if event.key == pygame.K_LEFT:
self.update_step(direction="backward")
elif event.type == pygame.QUIT:
self.is_running = False
if alsaseq.inputpending():
event = alsaseq.input()
if event[0] == 6: # note on event (zumindest bei kleinem midikeyboard)
self.reaction_note_on(event)
elif event[0] == 7:
self.reaction_note_off(event)
def get_config(filename):
"""
All settings are stored in an external text file.
"""
config = configparser.ConfigParser()
config.read(filename)
return config
def main():
options = options_play.get_options()
game = SoundGame(options)
game.play()
def read_data_to_container(container, filename, song_folder, conversion_func, no_list=False):
with open(song_folder + filename + ".txt") as infile:
for line in infile.read().split("\n"):
if line != "":
data = [conversion_func(n) for n in line.split(" ")]
if no_list:
data = data[0]
container.append(data)
if __name__ == "__main__":
main()