Rob 2 years ago
parent
commit
1548ba279f

+ 2
- 2
config.txt View File

@@ -1,5 +1,5 @@
1
-default_song = r100.sng
2
-theme = default.thm
1
+default_song = default
2
+theme = default
3 3
 title = default
4 4
 bpm = 90
5 5
 volume = 10

+ 5
- 1
lib/FSM.py View File

@@ -77,7 +77,11 @@ class ProgFSM(Char):
77 77
         'Util', 
78 78
         'File',
79 79
         'Ball',
80
-        'Clock'
80
+        'Clock',
81
+        'Exit',
82
+        'SelTheme',
83
+        'OpenSong',
84
+        'EnterText'
81 85
         ]
82 86
         
83 87
         for s in state_list:

+ 1094
- 152
lib/StatesProg.py View File

@@ -2,7 +2,7 @@
2 2
 import random
3 3
 import time
4 4
 import pygame
5
-
5
+import sys
6 6
 import pyaudio
7 7
 import wave
8 8
 import glob
@@ -10,6 +10,7 @@ import os
10 10
 from itertools import cycle
11 11
 from datetime import datetime
12 12
 import ast
13
+import random
13 14
 #====================================     
14 15
 
15 16
 State = type("State", (object,), {})
@@ -31,11 +32,13 @@ class State(object):
31 32
 
32 33
 def play_seq(o, message):
33 34
 	_id = 0
35
+	o.clear_notes_on()
34 36
 	for s in o.soundSlots:
35 37
 		if s.notes[message[0]][message[1]][0] == 1:
38
+			o.notes_on[_id] = 1
36 39
 			o.soundSlots[_id].play(s.notes[message[0]][message[1]][1])
37 40
 		_id += 1
38
-
41
+	#print(o.notes_on)
39 42
 def draw_header(o):
40 43
 	o.draw.rectangle((0, 0, o.width, o.height), outline=0, fill=o.blue)
41 44
 	o.center_text(o.header_text, o.h1, o.width, 25, o.light_grey)
@@ -117,7 +120,7 @@ def draw_menu1(o):
117 120
 		if _id == 9:
118 121
 			o.center_block("Vol+", o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
119 122
 		if _id == 11:
120
-			o.center_block("Save", o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
123
+			o.center_block("", o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
121 124
 		if _id == 12:
122 125
 			o.center_block("Play", o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
123 126
 		if _id == 13:
@@ -135,7 +138,7 @@ def draw_menu1(o):
135 138
 			o_x = og_x
136 139
 
137 140
 
138
-def draw_menu2(o):
141
+def draw_menu2_sample(o):
139 142
 	bpm_inc = 4
140 143
 	x_size = o.width / 4
141 144
 	y_size = o.height / 4
@@ -148,54 +151,83 @@ def draw_menu2(o):
148 151
 	   
149 152
 		o.draw.rectangle((o_x, o_y, o_x + x_size, o_y - y_size), outline=0, fill=o.dark_grey)
150 153
 
151
-		# if _id == 0:
152
-		#     o.center_block("Main", o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
153
-		# if _id == 1:
154
-		#     o.center_block("Note", o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
155
-		# if _id == 2:
156
-		#     o.center_block("Patt", o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
157
-		# if _id == 3:
158
-		#     o.center_block("Song", o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
159
-		# if _id == 4:
160
-		#     o.center_block("File", o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
161
-		# if _id == 5:
162
-		#     o.center_block("Util", o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
163
-
164
-		# if _id == 6:
165
-		#     o.center_block("Bank-", o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
166
-			
167
-		# if _id == 7:
168
-		#     o.center_block("Bank+", o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
169
-			
170
-		# if _id == 8:
171
-		#     o.center_block("Vol-", o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
172
-		#     #if o.volume > 0:
173
-		#         #o.volume -= 1
174
-		# if _id == 9:
175
-		#     o.center_block("Vol+", o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
176
-		#     #if o.volume < 16:
177
-		#         #o.volume += 1
178
-		# if _id == 11:
179
-		#     o.center_block("Save", o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
180
-		# if _id == 12:
181
-		#     o.center_block("Play", o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
182
-		# if _id == 13:
183
-		#     o.center_block("Stop", o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
184
-		# if _id == 14:
185
-		#     o.center_block("BPM-", o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
186
-		# if _id == 15:
187
-		#     o.center_block("BPM+", o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
188
-			
154
+		
155
+		if _id == 0:
156
+			o.center_block("Copy", o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
157
+		if _id == 1:
158
+			o.center_block("Paste", o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
159
+		if _id == 2:
160
+			o.center_block("Del-", o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
161
+		if _id == 3:
162
+			o.center_block("Load", o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
189 163
 
164
+		if _id == 4:
165
+			o.center_block("Vol-", o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
166
+		if _id == 5:
167
+			o.center_block("Vol+", o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
168
+		if _id == 6:
169
+			o.center_block("Pitch-", o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
170
+		if _id == 7:
171
+			o.center_block("Pitch+", o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
190 172
 		o_x = o_x + x_size
191 173
 		_id += 1
192 174
 		if _id % 4 == 0:
193 175
 			o_y -= y_size
194 176
 			o_x = og_x
195 177
 
178
+def draw_menu2_pattern(o):
179
+	bpm_inc = 4
180
+	x_size = o.width / 4
181
+	y_size = o.height / 4
182
+	og_x = 0
183
+	o_x = og_x
184
+	o_y = o.height
185
+	text_padding = 6
186
+	_id = 0
187
+	while _id < 16:
188
+	   
189
+		o.draw.rectangle((o_x, o_y, o_x + x_size, o_y - y_size), outline=0, fill=o.dark_grey)
190
+
191
+		if _id == 0:
192
+			o.center_block("Copy", o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
193
+		if _id == 1:
194
+			o.center_block("Paste", o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
195
+		if _id == 2:
196
+			o.center_block("Clear", o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
197
+		if _id == 6:
198
+			o.center_block("Bank -", o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
199
+		if _id == 7:
200
+			o.center_block("Bank +", o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
196 201
 
202
+		o_x = o_x + x_size
203
+		_id += 1
204
+		if _id % 4 == 0:
205
+			o_y -= y_size
206
+			o_x = og_x
197 207
 
208
+def draw_menu2_note(o):
209
+	bpm_inc = 4
210
+	x_size = o.width / 4
211
+	y_size = o.height / 4
212
+	og_x = 0
213
+	o_x = og_x
214
+	o_y = o.height
215
+	text_padding = 6
216
+	_id = 0
217
+	while _id < 16:
218
+	   
219
+		o.draw.rectangle((o_x, o_y, o_x + x_size, o_y - y_size), outline=0, fill=o.dark_grey)
198 220
 
221
+		if _id == 0:
222
+			o.center_block("Vol -", o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
223
+		if _id == 1:
224
+			o.center_block("Vol +", o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
225
+		
226
+		o_x = o_x + x_size
227
+		_id += 1
228
+		if _id % 4 == 0:
229
+			o_y -= y_size
230
+			o_x = og_x
199 231
 
200 232
 def menu1_actions(self, o):
201 233
 	if o.keyState[16] == 2:
@@ -210,7 +242,7 @@ def menu1_actions(self, o):
210 242
 		elif o.keyState[4] == 1:
211 243
 			self.FSM.ToTransition('toFile')
212 244
 		elif o.keyState[5] == 1:
213
-			self.FSM.ToTransition('toClock')
245
+			self.FSM.ToTransition('toUtil')
214 246
 		if o.keyState[12] == 1:
215 247
 			o.start_playback()
216 248
 		if o.keyState[13] == 1:
@@ -225,28 +257,186 @@ def menu1_actions(self, o):
225 257
 			if o.volume > 0:
226 258
 				o.volume -= 1
227 259
 				text_center(o, "Master Volume", str(o.volume))
228
-				o.disp.image(o.image, o.rotation)
260
+				o.update_display(0)
229 261
 		if o.keyState[9] == 1:
230 262
 			if o.volume < 16:
231 263
 				o.volume += 1
232 264
 				text_center(o, "Master Volume", str(o.volume))
233
-				o.disp.image(o.image, o.rotation)
265
+				o.update_display(0)
234 266
 		if o.keyState[11] == 1:
235
-			o.save_song()
267
+			#o.save_song()
268
+			pass
236 269
 		if o.keyState[14] == 1:
237 270
 			if o.sconf.as_int('bpm') > 60:
238 271
 				o.sconf['bpm'] = o.sconf.as_int('bpm') - o.bpm_inc
239 272
 				o.update_bpm()
240 273
 				text_center(o, "Master BPM", str(o.sconf['bpm']))
241
-				o.disp.image(o.image, o.rotation)
274
+				o.update_display(0)
242 275
 		if o.keyState[15] == 1:
243 276
 			if o.sconf.as_int('bpm') < 240:
244 277
 				o.sconf['bpm'] = o.sconf.as_int('bpm') + o.bpm_inc
245 278
 				o.update_bpm()
246 279
 				text_center(o, "Master BPM", str(o.sconf['bpm']))
247
-				o.disp.image(o.image, o.rotation)
280
+				o.update_display(0)
281
+
282
+
283
+def menu2_actions_sample(self, o):
284
+	if o.keyState[17] == 2:
285
+		if o.keyState[0] == 1:
286
+			if o.soundSlots[o.eSound].volume > 0:
287
+				print('copy')
288
+				o.soundClipboard = [o.soundSlots[o.eSound].file, o.soundSlots[o.eSound].volume, o.soundSlots[o.eSound].pitch]
289
+				print(o.soundClipboard)
290
+				#text_center(o, "Sample Volume", str(o.soundSlots[o.eSound].volume))
291
+				#o.update_display(0)
292
+		elif o.keyState[1] == 1:
293
+			if o.soundSlots[o.eSound].volume < 16:
294
+				print('pasting ', o.soundClipboard)
295
+				#o.soundSlots[o.eSound].volume += 1
296
+				#text_center(o, "Sample Volume", str(o.soundSlots[o.eSound].volume))
297
+				#o.update_display(0)
298
+		elif o.keyState[2] == 1:
299
+			if o.soundSlots[o.eSound].pitch > -10:
300
+				o.soundSlots[o.eSound].pitch -= 1
301
+				text_center(o, "Sample Pitch", str(o.soundSlots[o.eSound].pitch))
302
+				o.soundSlots[o.eSound].set_pitch()
303
+				o.update_display(0)
304
+		elif o.keyState[3] == 1:
305
+			if o.soundSlots[o.eSound].pitch < 10:
306
+				o.soundSlots[o.eSound].pitch += 1
307
+				text_center(o, "Sample Pitch", str(o.soundSlots[o.eSound].pitch))
308
+				o.soundSlots[o.eSound].set_pitch()
309
+				o.update_display(0)
310
+
311
+		elif o.keyState[4] == 1:
312
+			if o.soundSlots[o.eSound].volume > 0:
313
+				o.soundSlots[o.eSound].volume -= 1
314
+				text_center(o, "Sample Volume", str(o.soundSlots[o.eSound].volume))
315
+				o.update_display(0)
316
+		elif o.keyState[5] == 1:
317
+			if o.soundSlots[o.eSound].volume < 16:
318
+				o.soundSlots[o.eSound].volume += 1
319
+				text_center(o, "Sample Volume", str(o.soundSlots[o.eSound].volume))
320
+				o.update_display(0)
321
+		elif o.keyState[6] == 1:
322
+			if o.soundSlots[o.eSound].pitch > -10:
323
+				o.soundSlots[o.eSound].pitch -= 1
324
+				text_center(o, "Sample Pitch", str(o.soundSlots[o.eSound].pitch))
325
+				o.soundSlots[o.eSound].set_pitch()
326
+				o.update_display(0)
327
+		elif o.keyState[7] == 1:
328
+			if o.soundSlots[o.eSound].pitch < 10:
329
+				o.soundSlots[o.eSound].pitch += 1
330
+				text_center(o, "Sample Pitch", str(o.soundSlots[o.eSound].pitch))
331
+				o.soundSlots[o.eSound].set_pitch()
332
+				o.update_display(0)
333
+
334
+def menu2_actions_pattern(self, o):
335
+	if o.keyState[17] == 2:
336
+		if o.keyState[0] == 1:
337
+			print('copy')
338
+			o.patternClipboard = []
339
+			for s in o.soundSlots:
340
+				notes = []
341
+				for i in s.notes[o.ePattern]:
342
+					notes.append([i[0], i[1]])
343
+					#i[0] = 0
344
+					#i[1] = 0
345
+				o.patternClipboard.append(notes)
346
+				print('adding to clip ', notes)
347
+			# if o.soundSlots[o.eSound].volume > 0:
348
+			# 	o.soundSlots[o.eSound].volume -= 1
349
+			# 	text_center(o, "Sample Volume", str(o.soundSlots[o.eSound].volume))
350
+			# 	o.update_display(0)
351
+		elif o.keyState[1] == 1:
352
+			print('paste')
353
+			if o.patternClipboard != []:
354
+				p = 0
355
+				for s in o.soundSlots:
356
+					n = 0
357
+					for i in s.notes[o.ePattern]:
358
+						i[0] = o.patternClipboard[p][n][0]
359
+						i[1] = o.patternClipboard[p][n][1]
360
+						n += 1
361
+					print('added ', o.patternClipboard[p])
362
+					p += 1
363
+					
364
+				
365
+			else:
366
+				print('nothing to paste')
367
+			# if o.soundSlots[o.eSound].volume < 16:
368
+			# 	o.soundSlots[o.eSound].volume += 1
369
+			# 	text_center(o, "Sample Volume", str(o.soundSlots[o.eSound].volume))
370
+			# 	o.update_display(0)
371
+		elif o.keyState[2] == 1:
372
+			print('clear')
373
+			print(o.soundSlots[o.eSound].notes[o.ePattern])
374
+			for s in o.soundSlots:
375
+				for i in s.notes[o.ePattern]:
376
+					i[0] = 0
377
+					i[1] = 0
378
+			#print(o.soundSlots[o.eSound].notes[o.ePattern])
379
+			# if o.soundSlots[o.eSound].pitch > -10:
380
+			# 	o.soundSlots[o.eSound].pitch -= 1
381
+			# 	text_center(o, "Sample Pitch", str(o.soundSlots[o.eSound].pitch))
382
+			# 	o.soundSlots[o.eSound].set_pitch()
383
+			# 	o.update_display(0)
384
+		elif o.keyState[6] == 1:
385
+			if o.pat_bank > 0:
386
+				o.pat_bank -= 1
387
+				text_center(o, "Pattern Bank", str(o.pat_bank))
388
+				o.update_display(0)		
389
+
390
+		elif o.keyState[7] == 1:
391
+			if o.pat_bank < 4:
392
+				o.pat_bank += 1
393
+				text_center(o, "Pattern Bank", str(o.pat_bank))
394
+				o.update_display(0)		
395
+				
248 396
 				
249 397
 
398
+def menu2_actions_note(self, o):
399
+	if o.keyState[17] == 2:
400
+		if o.keyState[0] == 1:
401
+			if o.note_vol > 0:
402
+				o.note_vol -= 1
403
+				text_center(o, "Note Volume", str(o.note_vol))
404
+				o.update_display(0)		
405
+
406
+
407
+		elif o.keyState[1] == 1:
408
+			if o.note_vol < 16:
409
+				o.note_vol += 1
410
+				text_center(o, "Note Volume", str(o.note_vol))
411
+				o.update_display(0)
412
+			
413
+		
414
+					
415
+
416
+def util_command(self, o, command):
417
+	if command == "Clock":
418
+		self.FSM.ToTransition('toClock')		
419
+	elif command == "Ball":
420
+		self.FSM.ToTransition('toBall')		
421
+	elif command == "Exit":
422
+		self.FSM.ToTransition('toExit')		
423
+	elif command == "Theme":
424
+		self.FSM.ToTransition('toSelTheme')		
425
+	elif command == "Reboot":
426
+		#self.FSM.ToTransition('toSelTheme')		
427
+		os.system("sudo reboot")
428
+
429
+
430
+def file_command(self, o, command):
431
+	if command == "Save":
432
+		o.save_song()
433
+	
434
+	elif command == "Open":
435
+		self.FSM.ToTransition('toOpenSong')	
436
+	elif command == "Save As":
437
+		self.FSM.ToTransition('toEnterText')	
438
+#==================================== 
439
+
250 440
 class Example(State):
251 441
 	def __init__(self,FSM):
252 442
 		super(Example, self).__init__(FSM)    
@@ -297,8 +487,12 @@ class Intro(State):
297 487
 		o = self.FSM.owner
298 488
 		o.header_text = "Starting up..."
299 489
 		o.draw.rectangle((0, 0, self.FSM.owner.width, self.FSM.owner.height), outline=0, fill=o.blue)
300
-		draw_header(o)
301
-		o.disp.image(o.image, o.rotation)
490
+		#draw_header(o)
491
+		#o.draw.rectangle((0, 0, o.width, o.height), outline=0, fill=o.blue)			
492
+		o.center_block("Starting up...", o.h2, [0, 0, o.width, o.height], o.light_grey)
493
+		#o.display_thread.start()
494
+		o.update_display(0)
495
+		#o.update_display(0)
302 496
 		super(Intro, self).Enter()        
303 497
 		
304 498
 	def Execute(self):
@@ -320,6 +514,7 @@ class LoadDefault(State):
320 514
 
321 515
 
322 516
 		o = self.FSM.owner
517
+		o.init_slots()
323 518
 		o.load_song()
324 519
 
325 520
 
@@ -329,18 +524,11 @@ class LoadDefault(State):
329 524
 		self.globbed = glob.glob('/home/pi/skull/*.wav') + glob.glob('/home/pi/skull/*.mp3')
330 525
 		self.globbed.sort()
331 526
 		obj_id = 0
332
-		# for f in self.globbed:
333
-		#     #self.sounds.append(pygame.mixer.Sound(f))
334
-		#     p1 = self.FSM.owner.SoundSlot(f, obj_id)
335
-		#     self.FSM.owner.soundSlots.append(p1)
336
-		#     obj_id += 1
337
-
338
-		# self.sound_names = [os.path.basename(x) for x in self.globbed]
339
-
340
-		for s in o.sconf['sounds']:
341
-			p1 = self.FSM.owner.SoundSlot(s, obj_id, o)
342
-			self.FSM.owner.soundSlots.append(p1)
343
-			obj_id += 1
527
+		
528
+		# for s in o.sconf['sounds']:
529
+		# 	p1 = self.FSM.owner.SoundSlot(s, obj_id, o)
530
+		# 	self.FSM.owner.soundSlots.append(p1)
531
+		# 	obj_id += 1
344 532
 
345 533
 		_iter = 0
346 534
 
@@ -349,8 +537,9 @@ class LoadDefault(State):
349 537
 
350 538
 		for n in o.soundSlots:
351 539
 			m = []
352
-			lst = ast.literal_eval(o.sconf.as_list('notes')[_iter])
353
-			n.notes = lst
540
+			if _iter < (len(o.sconf.as_list('notes')) - 1):
541
+				lst = ast.literal_eval(o.sconf.as_list('notes')[_iter])
542
+				n.notes = lst
354 543
 			_iter += 1
355 544
 
356 545
 		super(LoadDefault, self).Enter()        
@@ -381,42 +570,47 @@ class Main(State):
381 570
 		else:
382 571
 			draw_header(o)
383 572
 			self.draw_square()
384
-			text_box1(o, "Vol", str(o.sconf['volume']))
573
+
574
+			text_box1(o, "SVol", str(o.soundSlots[o.eSound].volume))
385 575
 			text_box2(o, "BPM", str(o.sconf['bpm']))
386 576
 			text_box4(o, "Bank", str(o.note_bank))
387
-			o.disp.image(o.image, o.rotation)
577
+			text_box3(o, "Pitch", str(o.soundSlots[o.eSound].pitch))
578
+			o.update_display(0)
388 579
 
389
-		o.soundSlots[2].volume = 2
580
+		#o.soundSlots[2].volume = 2
390 581
 		super(Main, self).Enter()        
391 582
 		
392 583
 	def Execute(self):
393 584
 		o = self.FSM.owner 
394 585
 		menu1_actions(self, o)
586
+		menu2_actions_sample(self, o)
395 587
 		
396 588
 		if o.keyState[16] == 1:
397 589
 			draw_menu1(o)
398
-			o.disp.image(o.image, o.rotation)
590
+			o.update_display(0)
399 591
 		elif o.keyState[16] == 4:
400 592
 			draw_header(o)
401 593
 			self.draw_square()
402
-			text_box1(o, "Vol", str(o.volume))
594
+			#print('esound ', o.eSound)
595
+			#print('oss ', o.soundSlots[o.eSound].volume)
596
+			text_box1(o, "SVol", str(o.soundSlots[o.eSound].volume))
403 597
 			text_box2(o, "BPM", str(o.sconf['bpm']))
404 598
 			text_box4(o, "Bank", str(o.note_bank))
405
-			#text_box3(o, "BPM", "90.0")
406
-			o.disp.image(o.image, o.rotation)
599
+			text_box3(o, "Pitch", str(o.soundSlots[o.eSound].pitch))
600
+			o.update_display(0)
407 601
 
408 602
 
409 603
 		if o.keyState[17] == 1:
410
-			draw_menu2(o)
411
-			o.disp.image(o.image, o.rotation)
604
+			draw_menu2_sample(o)
605
+			o.update_display(0)
412 606
 		elif o.keyState[17] == 4:
413 607
 			draw_header(o)
414 608
 			self.draw_square()
415
-			text_box1(o, "Vol", str(o.volume))
609
+			text_box1(o, "SVol", str(o.soundSlots[o.eSound].volume))
416 610
 			text_box2(o, "BPM", str(o.sconf['bpm']))
417 611
 			text_box4(o, "Bank", str(o.note_bank))
418
-			#text_box3(o, "BPM", "90.0")
419
-			o.disp.image(o.image, o.rotation)
612
+			text_box3(o, "Pitch", str(o.soundSlots[o.eSound].pitch))
613
+			o.update_display(0)
420 614
 
421 615
 		_id = 0
422 616
 		for k in o.keyState:
@@ -428,16 +622,22 @@ class Main(State):
428 622
 				else:
429 623
 					if k == 1:
430 624
 						note = _id + o.note_bank * 16
431
-						if len(o.soundSlots) > note:
625
+						#if len(o.soundSlots) > note:
626
+						if 12 == 12:
432 627
 							
433
-							self.FSM.owner.soundSlots[note].play(o.note_vol)
628
+							#o.soundSlots[note].play(o.note_vol)
629
+							o.slots[note].play(o.note_vol)
434 630
 							o.eSound = note
435 631
 							#print('now editing sound ', o.eSound) 
436
-							text_box1(o, "Vol", str(o.volume))
632
+							draw_header(o)
633
+							#text_box1(o, "SVol", str(o.soundSlots[o.eSound].volume))
634
+							text_box1(o, "SVol", str(o.slots[o.eSound].volume))
437 635
 							text_box2(o, "BPM", str(o.sconf['bpm']))
438
-							text_box4(o, "Bank", str(o.note_bank))          
636
+							text_box4(o, "Bank", str(o.note_bank))
637
+							#text_box3(o, "Pitch", str(o.soundSlots[o.eSound].pitch))
638
+							text_box3(o, "Pitch", str(o.slots[o.eSound].pitch))
439 639
 							self.draw_square()
440
-							o.disp.image(o.image, o.rotation)
640
+							o.update_display(0)
441 641
 			_id += 1
442 642
 
443 643
 	def ReceiveMessage(self, message):
@@ -447,7 +647,12 @@ class Main(State):
447 647
 			pass
448 648
 		else:
449 649
 			draw_header(o)            
450
-			self.draw_square()            
650
+			self.draw_square()   
651
+			text_box1(o, "SVol", str(o.soundSlots[o.eSound].volume))
652
+			text_box2(o, "BPM", str(o.sconf['bpm']))
653
+			text_box4(o, "Bank", str(o.note_bank))
654
+			text_box3(o, "Pitch", str(o.soundSlots[o.eSound].pitch))			         
655
+			o.update_display(0)
451 656
 	
452 657
 	def draw_square(self):
453 658
 		o = self.FSM.owner 
@@ -460,6 +665,11 @@ class Main(State):
460 665
 		while _id < ((o.note_bank * 16) + 16):
461 666
 			if _id == o.eSound:
462 667
 				o.draw.rectangle((o_x, o_y, o_x + size, o_y - size), outline=o.light_grey, fill=o.light_grey, width=1)
668
+			elif o.notes_on[_id] == 1:
669
+				o.draw.rectangle((o_x, o_y, o_x + size, o_y - size), outline=o.light_grey, fill=o.grey, width=1)
670
+			elif _id > (len(o.soundSlots) - 1):
671
+				o.draw.rectangle((o_x, o_y, o_x + size, o_y - size), outline=o.light_grey, fill=o.dark_blue, width=1)
672
+
463 673
 			else:
464 674
 				o.draw.rectangle((o_x, o_y, o_x + size, o_y - size), outline=o.light_grey, fill=o.blue, width=1)
465 675
 			o_x = o_x + size
@@ -514,7 +724,7 @@ class SeqPlayer(State):
514 724
 		o = self.FSM.owner
515 725
 		o.draw.rectangle((0, 0, o.width, o.height), outline=0, fill=o.blue)
516 726
 		o.draw.text((20, 0), 'SeqPlayer', font=o.h1, fill="#FFFFFF")
517
-		o.disp.image(o.image, o.rotation)
727
+		o.update_display(0)
518 728
 		super(SeqPlayer, self).Enter()        
519 729
 		
520 730
 	def Execute(self):
@@ -538,7 +748,7 @@ class SeqPlayer(State):
538 748
 		o = self.FSM.owner
539 749
 		o.draw.rectangle((0, 0, o.width, o.height), outline=0, fill=o.blue)
540 750
 		o.draw.text((20, 0), str(message[0]) + ' - ' + str(message[1]), font=o.h1, fill="#FFFFFF")
541
-		o.disp.image(o.image, o.rotation)
751
+		o.update_display(0)
542 752
 		play_seq(o, message)
543 753
 
544 754
 	def Exit(self):
@@ -558,18 +768,18 @@ class SelectSound(State):
558 768
 		o.pub.register("beat", self)
559 769
 		draw_header(o)
560 770
 		self.draw_square()
561
-		o.disp.image(o.image, o.rotation)
771
+		o.update_display(0)
562 772
 		super(SelectSound, self).Enter()        
563 773
 		
564 774
 	def Execute(self):
565 775
 		o = self.FSM.owner 
566 776
 		if o.keyState[16] == 1:
567 777
 			draw_menu1(o)
568
-			o.disp.image(o.image, o.rotation)
778
+			o.update_display(0)
569 779
 		elif o.keyState[16] == 4:
570 780
 			draw_header(o)
571 781
 			self.draw_square()
572
-			o.disp.image(o.image, o.rotation)
782
+			o.update_display(0)
573 783
 
574 784
 		if o.keyState[16] == 2:
575 785
 			if o.keyState[0] == 1:
@@ -586,7 +796,7 @@ class SelectSound(State):
586 796
 						o.draw.text((0, 0), "SelSou", font=o.h1, fill=o.color_a)
587 797
 						o.draw.text((20, 60), str(o.eSound), font=o.h2, fill=o.color_b)
588 798
 						self.draw_square()
589
-						o.disp.image(o.image, o.rotation)
799
+						o.update_display(0)
590 800
 						self.FSM.owner.soundSlots[_id].play()
591 801
 						#print('now editing sound ', _id)    
592 802
 				_id += 1        
@@ -597,7 +807,7 @@ class SelectSound(State):
597 807
 		o.draw.rectangle((0, 0, o.width, o.height), outline=0, fill=(0, 0, 0))
598 808
 		o.draw.text((0, 0), "SelSou", font=o.h1, fill="#FFFFFF")
599 809
 		o.draw.text((0, 20), str(o.eSound), font=o.h2, fill="#FFFFFF")
600
-		o.disp.image(o.image, o.rotation)
810
+		o.update_display(0)
601 811
 		play_seq(o, message)
602 812
 
603 813
 	def draw_square(self):
@@ -634,26 +844,48 @@ class SelectPattern(State):
634 844
 		o = self.FSM.owner 
635 845
 		o.header_text = "Select Pattern"
636 846
 		o.pub.register("beat", self)
637
-
847
+		self.cur_playing = 0
848
+		self.active_patterns = []
849
+		self.get_active_patterns(o)
638 850
 		if o.keyState[16] > 0 or o.keyState[17] > 0:
639 851
 			pass
640 852
 		else:
641 853
 			draw_header(o)
642 854
 			self.draw_square()
643
-			o.disp.image(o.image, o.rotation)
855
+			text_box1(o, "Pat", str(o.ePattern))
856
+			text_box4(o, "Bank", str(o.pat_bank))
857
+			o.update_display(0)
644 858
 		
645 859
 		super(SelectPattern, self).Enter()        
646 860
 		
647 861
 	def Execute(self):
648 862
 		o = self.FSM.owner 
649 863
 		menu1_actions(self, o)
864
+		menu2_actions_pattern(self, o)
650 865
 		if o.keyState[16] == 1:
651 866
 			draw_menu1(o)
652
-			o.disp.image(o.image, o.rotation)
867
+			o.update_display(0)
653 868
 		elif o.keyState[16] == 4:
654 869
 			draw_header(o)
655 870
 			self.draw_square()
656
-			o.disp.image(o.image, o.rotation)
871
+			text_box1(o, "Pat", str(o.ePattern))
872
+			text_box4(o, "Bank", str(o.pat_bank))
873
+			o.update_display(0)
874
+
875
+		if o.keyState[17] == 1:
876
+			draw_menu2_pattern(o)
877
+			o.update_display(0)
878
+		elif o.keyState[17] == 4:
879
+			draw_header(o)
880
+			self.draw_square()
881
+			#text_box1(o, "SVol", str(o.soundSlots[o.eSound].volume))
882
+			#text_box2(o, "BPM", str(o.sconf['bpm']))
883
+			text_box1(o, "Pat", str(o.ePattern))
884
+			text_box4(o, "Bank", str(o.pat_bank))
885
+			#text_box3(o, "Pitch", str(o.soundSlots[o.eSound].pitch))
886
+			self.get_active_patterns(o)
887
+			o.update_display(0)
888
+
657 889
 
658 890
 		if o.keyState[16] > 0 or o.keyState[17] > 0:
659 891
 			pass
@@ -664,20 +896,33 @@ class SelectPattern(State):
664 896
 					pass
665 897
 				else:
666 898
 					if k == 1:
667
-						o.ePattern = _id
899
+						o.ePattern = (o.pat_bank * 16) +_id 
668 900
 
669
-						o.draw.rectangle((0, 0, o.width, o.height), outline=0, fill=o.blue)
670
-						o.draw.text((0, 0), "SelPat", font=o.h1, fill=o.color_a)
671
-						o.draw.text((20, 60), str(o.ePattern), font=o.h2, fill=o.color_b)
901
+						draw_header(o)
672 902
 						self.draw_square()
673
-						o.disp.image(o.image, o.rotation)						
674
-						#print('now editing sound ', _id)                
903
+						
904
+						text_box1(o, "Pat", str(o.ePattern))
905
+						text_box4(o, "Bank", str(o.pat_bank))
906
+						o.update_display(0)
907
+						
675 908
 
676 909
 				_id += 1        
677 910
 
678 911
 	def ReceiveMessage(self, message):
679 912
 		o = self.FSM.owner
680 913
 		play_seq(o, message) 
914
+		
915
+		if message[0] != self.cur_playing:
916
+			#print('playing ', message)
917
+			self.cur_playing = message[0]
918
+			if o.keyState[16] > 0 or o.keyState[17] > 0:
919
+				pass
920
+			else:
921
+				draw_header(o)
922
+				self.draw_square()
923
+				text_box1(o, "Pat", str(o.ePattern))
924
+				text_box4(o, "PBank", str(o.pat_bank))
925
+				o.update_display(0)
681 926
 
682 927
 	def draw_square(self):
683 928
 		o = self.FSM.owner 
@@ -687,16 +932,47 @@ class SelectPattern(State):
687 932
 		o_y = 127
688 933
 		_id = 0
689 934
 		for n in o.soundSlots[o.eSound].notes[o.ePattern]:
690
-			if _id == o.ePattern:
935
+			if (_id + (o.pat_bank * 16)) == o.ePattern:
691 936
 				o.draw.rectangle((o_x, o_y, o_x + size, o_y - size), outline=o.olive, fill=o.olive, width=1)
692
-			else:
937
+			elif (_id + (o.pat_bank * 16)) == self.cur_playing:
938
+				o.draw.rectangle((o_x, o_y, o_x + size, o_y - size), outline=o.olive, fill=o.light_grey, width=1)
939
+			elif self.active_patterns[_id] == 1:
693 940
 				o.draw.rectangle((o_x, o_y, o_x + size, o_y - size), outline=o.light_grey, fill=o.blue, width=1)
941
+			else:
942
+				o.draw.rectangle((o_x, o_y, o_x + size, o_y - size), outline=o.light_grey, fill=o.dark_blue, width=1)
694 943
 			o_x = o_x + size
695 944
 			_id += 1
696 945
 			if _id % 4 == 0:
697 946
 				o_y -= size
698 947
 				o_x = og_x          
699 948
 
949
+	def get_active_patterns(self, o):
950
+		#for n in o.soundSlots[o.eSound]
951
+		self.active_patterns = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
952
+		pat_iter = o.pat_bank * 16
953
+		_iter = 0
954
+		print('is this note on? ', o.soundSlots[0].notes[0][0][0])
955
+
956
+
957
+		while pat_iter < ((o.pat_bank * 16) + 16):
958
+			
959
+			for s in o.soundSlots:
960
+				print('checking soundSlot ', s.id)
961
+				pat_used = 0
962
+				for p in s.notes[pat_iter]:
963
+					if self.active_patterns[_iter] == 1:
964
+						break
965
+					if p[0] == 1:
966
+						#pat_used = 1
967
+						self.active_patterns[_iter] = 1
968
+						print('found ', pat_iter, ' -- ', p[0])
969
+						break
970
+				#self.active_patterns.append(pat_used)
971
+			pat_iter += 1
972
+			_iter += 1
973
+	
974
+		print('active patterns ', self.active_patterns)
975
+
700 976
 	def Exit(self):
701 977
 		self.FSM.owner.pub.unregister("beat", self)
702 978
 
@@ -716,19 +992,32 @@ class EditSoundSequence(State):
716 992
 		else:
717 993
 			draw_header(o)
718 994
 			self.draw_square()
719
-			o.disp.image(o.image, o.rotation)
995
+			text_box1(o, "Note Vol", str(o.note_vol))
996
+			o.update_display(0)
720 997
 		super(EditSoundSequence, self).Enter()        
721 998
 		
722 999
 	def Execute(self):
723 1000
 		o = self.FSM.owner 
724 1001
 		menu1_actions(self, o)
1002
+		menu2_actions_note(self, o)
725 1003
 		if o.keyState[16] == 1:
726 1004
 			draw_menu1(o)
727
-			o.disp.image(o.image, o.rotation)
1005
+			o.update_display(0)
728 1006
 		elif o.keyState[16] == 4:
729 1007
 			draw_header(o)
730 1008
 			self.draw_square()
731
-			o.disp.image(o.image, o.rotation)
1009
+			text_box1(o, "Note Vol", str(o.note_vol))
1010
+			o.update_display(0)
1011
+
1012
+		if o.keyState[17] == 1:
1013
+			draw_menu2_note(o)
1014
+			o.update_display(0)
1015
+		elif o.keyState[17] == 4:
1016
+			draw_header(o)
1017
+			self.draw_square()
1018
+			text_box1(o, "Note Vol", str(o.note_vol))
1019
+			
1020
+			o.update_display(0)
732 1021
 
733 1022
 		if o.keyState[16] == 2:
734 1023
 			pass
@@ -740,9 +1029,11 @@ class EditSoundSequence(State):
740 1029
 					if o.soundSlots[o.eSound].notes[o.ePattern][_id][0] == 1:
741 1030
 						print('turn note off')
742 1031
 						o.soundSlots[o.eSound].notes[o.ePattern][_id][0] = 0
1032
+						o.soundSlots[o.eSound].notes[o.ePattern][_id][1] = 0
743 1033
 					else:
744 1034
 						print('turn note on')
745 1035
 						o.soundSlots[o.eSound].notes[o.ePattern][_id][0] = 1
1036
+						o.soundSlots[o.eSound].notes[o.ePattern][_id][1] = o.note_vol
746 1037
 				_id += 1
747 1038
 
748 1039
 		
@@ -778,8 +1069,8 @@ class EditSoundSequence(State):
778 1069
 		else:
779 1070
 			draw_header(o)            
780 1071
 			self.draw_square()  
781
-		
782
-		o.disp.image(o.image, o.rotation)
1072
+			text_box1(o, "Note Vol", str(o.note_vol))
1073
+		o.update_display(0)
783 1074
 		
784 1075
 	def Exit(self):
785 1076
 		self.FSM.owner.pub.unregister("beat", self)
@@ -800,7 +1091,7 @@ class EditSong(State):
800 1091
 			draw_header(o)
801 1092
 			o.draw.text((20, 30), "Current Song", font=o.h2, fill=o.light_grey)
802 1093
 			o.draw.text((20, 50), str(o.song), font=o.h2, fill=o.light_grey)
803
-			o.disp.image(o.image, o.rotation)
1094
+			o.update_display(0)
804 1095
 		self.new_song = []
805 1096
 		super(EditSong, self).Enter()        
806 1097
 		
@@ -810,7 +1101,7 @@ class EditSong(State):
810 1101
 		menu1_actions(self, o)
811 1102
 		if o.keyState[16] == 1:
812 1103
 			draw_menu1(o)
813
-			o.disp.image(o.image, o.rotation)
1104
+			o.update_display(0)
814 1105
 		elif o.keyState[16] == 4:
815 1106
 			draw_header(o)
816 1107
 			if self.new_song == []:
@@ -819,7 +1110,7 @@ class EditSong(State):
819 1110
 			else:
820 1111
 				o.draw.text((20, 30), "New Song", font=o.h2, fill=o.pink)
821 1112
 				o.draw.text((20, 50), str(self.new_song), font=o.h2, fill=o.pink)
822
-			o.disp.image(o.image, o.rotation)
1113
+			o.update_display(0)
823 1114
 
824 1115
 		if o.keyState[16] > 0:
825 1116
 			pass
@@ -827,11 +1118,11 @@ class EditSong(State):
827 1118
 			_id = 0
828 1119
 			for k in self.FSM.owner.keyState:
829 1120
 				if k == 1 and _id < 16:
830
-					self.new_song.append(_id)
1121
+					self.new_song.append((_id + (o.pat_bank * 16)))
831 1122
 					draw_header(o)
832 1123
 					o.draw.text((20, 30), "New Song", font=o.h2, fill=o.pink)
833 1124
 					o.draw.text((20, 50), str(self.new_song), font=o.h2, fill=o.pink)
834
-					o.disp.image(o.image, o.rotation)
1125
+					o.update_display(0)
835 1126
 				_id += 1        
836 1127
 
837 1128
 	def ReceiveMessage(self, message):
@@ -859,12 +1150,16 @@ class File(State):
859 1150
 		o = self.FSM.owner 
860 1151
 		o.header_text = "File"
861 1152
 		o.pub.register("beat", self)
1153
+		self.cur_el = 0
862 1154
 		if o.keyState[16] > 0 or o.keyState[17] > 0:
863 1155
 			pass
864 1156
 		else:
865 1157
 			draw_header(o)
866
-			o.disp.image(o.image, o.rotation)
867
-		self.menu = ["New", "Save", "Save As", "Open"]
1158
+			self.draw_footer(o)
1159
+			self.draw_main(o)
1160
+			o.update_display(0)
1161
+		self.menu = ["Save", "Save As", "Open", "New"]
1162
+		
868 1163
 		super(File, self).Enter()        
869 1164
 		
870 1165
 	def Execute(self):
@@ -872,24 +1167,104 @@ class File(State):
872 1167
 		menu1_actions(self, o)
873 1168
 		if o.keyState[16] == 1:
874 1169
 			draw_menu1(o)
875
-			o.disp.image(o.image, o.rotation)
1170
+			#self.draw_footer(o)
1171
+			o.update_display(0)
876 1172
 		elif o.keyState[16] == 4:
877 1173
 			draw_header(o)
878
-			#self.draw_square()
879
-			o.disp.image(o.image, o.rotation)
1174
+			self.draw_footer(o)
1175
+			self.draw_main(o)
1176
+			o.update_display(0)
1177
+
1178
+		if o.keyState[0] == 1 or o.keyState[0] == 3 or o.keyState[1] == 1 or o.keyState[1] == 3 or o.keyState[2] == 1 or o.keyState[2] == 3 or o.keyState[3] == 1 or o.keyState[3] == 3:
1179
+			draw_header(o)
1180
+			self.draw_footer(o)
1181
+			self.draw_main(o)
1182
+			o.update_display(0)	
1183
+			print('draw butt')				
1184
+
880 1185
 
881
-	def ReceiveMessage(self, message):
882
-		o = self.FSM.owner 
883
-		play_seq(o, message)
884 1186
 		if o.keyState[16] > 0 or o.keyState[17] > 0:
885 1187
 			pass
886 1188
 		else:
887
-			draw_header(o)            
888
-		
889
-		o.disp.image(o.image, o.rotation)
1189
+			if o.keyState[0] == 1:
1190
+				if self.cur_el > 0:
1191
+					self.cur_el -= 1
1192
+					print('cur el down is ', self.cur_el)
1193
+			if o.keyState[1] == 1:
1194
+				if self.cur_el < (len(self.menu) - 1):
1195
+					self.cur_el += 1
1196
+					print('cur el up is ', self.cur_el)
1197
+			
1198
+			if o.keyState[3] == 1:
1199
+				file_command(self, o, self.menu[self.cur_el])
1200
+				pass
1201
+
1202
+	def draw_footer(self, o):
1203
+		_iter = 0
1204
+		width = o.width / 4
1205
+		xpos = 0
1206
+		yposa = 135 - 25
1207
+		yposb = 135
1208
+		opts = ["Up", "Down", "Esc", "OK"]
1209
+		while _iter < 4:
1210
+			o.draw.rectangle((xpos, yposa, xpos + width, yposb), outline=0, fill=o.blue)
1211
+			
1212
+			if o.keyState[_iter] == 1:
1213
+				o.draw.rectangle((xpos, yposa, xpos + width, yposb), outline=0, fill=o.light_grey)
1214
+				o.center_block(opts[_iter], o.h2, [xpos,yposa,xpos + width,yposb], o.blue)
1215
+			else:
1216
+				o.center_block(opts[_iter], o.h2, [xpos,yposa,xpos + width,yposb], o.light_grey)
1217
+			
1218
+			xpos += width
1219
+			_iter += 1
1220
+
890 1221
 
1222
+	def draw_main(self, o):
1223
+		al = []
1224
+		ypos = 30
1225
+		if self.cur_el == 0:
1226
+			_iter = 0
1227
+			while len(al) < 4:
1228
+				al.append(self.menu[_iter])
1229
+				_iter += 1
1230
+		elif self.cur_el == 1:
1231
+			al.append(self.menu[self.cur_el - 1])
1232
+			al.append(self.menu[self.cur_el])
1233
+			al.append(self.menu[self.cur_el + 1])
1234
+			al.append(self.menu[self.cur_el + 2])
1235
+		elif self.cur_el == (len(self.menu) - 2):
1236
+			al.append(self.menu[self.cur_el - 2])
1237
+			al.append(self.menu[self.cur_el - 1])
1238
+			al.append(self.menu[self.cur_el])
1239
+			al.append(self.menu[self.cur_el + 1])
1240
+		elif self.cur_el == (len(self.menu) - 1):
1241
+			al.append(self.menu[self.cur_el - 3])
1242
+			al.append(self.menu[self.cur_el - 2])
1243
+			al.append(self.menu[self.cur_el - 1])
1244
+			al.append(self.menu[self.cur_el])
1245
+		else:
1246
+			al.append(self.menu[self.cur_el - 1])
1247
+			al.append(self.menu[self.cur_el])
1248
+			al.append(self.menu[self.cur_el + 1])
1249
+			al.append(self.menu[self.cur_el + 2])
1250
+		_iter = 0 
1251
+		for i in al:
1252
+			if i == self.menu[self.cur_el]:
1253
+			#if _iter == self.cur_el:
1254
+				o.draw.rectangle((0, ypos, o.width, ypos + 20), outline=0, fill=o.light_grey)
1255
+				o.center_block(i, o.h2, [0, ypos, o.width,ypos + 20], o.blue)
1256
+			else:
1257
+				o.draw.rectangle((0, ypos, o.width, ypos + 20), outline=0, fill=o.blue)
1258
+				o.center_block(i, o.h2, [0, ypos, o.width,ypos + 20], o.light_grey)
1259
+			ypos += 20
1260
+			_iter += 1
1261
+
1262
+	def ReceiveMessage(self, message):
1263
+		o = self.FSM.owner 
1264
+		play_seq(o, message)
1265
+		
891 1266
 	def Exit(self):
892
-		pass
1267
+		self.FSM.owner.pub.unregister("beat", self)
893 1268
 
894 1269
 class Util(State):
895 1270
 	def __init__(self,FSM):
@@ -899,13 +1274,18 @@ class Util(State):
899 1274
 		o = self.FSM.owner 
900 1275
 		o.header_text = "Utilities"
901 1276
 		o.pub.register("beat", self)
1277
+		self.menu = ["Clock", "Ball", "Exit", "Shutdown", "Reboot", "Theme", "Update"]
1278
+		self.cur_el = 0
1279
+
902 1280
 		if o.keyState[16] > 0 or o.keyState[17] > 0:
903 1281
 			pass
904 1282
 		else:
905 1283
 			draw_header(o)
906
-			o.disp.image(o.image, o.rotation)
1284
+			self.draw_footer(o)
1285
+			self.draw_main(o)
1286
+			o.update_display(0)
907 1287
 
908
-		self.menu = ["Clock", "Ball", "Theme", "Shutdown", "Reboot", "Update"]
1288
+		
909 1289
 		super(Util, self).Enter()        
910 1290
 		
911 1291
 	def Execute(self):
@@ -913,23 +1293,106 @@ class Util(State):
913 1293
 		menu1_actions(self, o)
914 1294
 		if o.keyState[16] == 1:
915 1295
 			draw_menu1(o)
916
-			o.disp.image(o.image, o.rotation)
1296
+			o.update_display(0)
917 1297
 		elif o.keyState[16] == 4:
918 1298
 			draw_header(o)
919
-			o.disp.image(o.image, o.rotation)
1299
+			self.draw_footer(o)
1300
+			self.draw_main(o)
1301
+			o.update_display(0)
1302
+
1303
+		if o.keyState[0] == 1 or o.keyState[0] == 3 or o.keyState[1] == 1 or o.keyState[1] == 3 or o.keyState[2] == 1 or o.keyState[2] == 3 or o.keyState[3] == 1 or o.keyState[3] == 3:
1304
+			draw_header(o)
1305
+			self.draw_footer(o)
1306
+			self.draw_main(o)
1307
+			o.update_display(0)	
1308
+			print('draw butt')				
1309
+
1310
+		if o.keyState[16] > 0 or o.keyState[17] > 0:
1311
+			pass
1312
+		else:
1313
+			if o.keyState[0] == 1:
1314
+				if self.cur_el > 0:
1315
+					self.cur_el -= 1
1316
+					print('cur el down is ', self.cur_el)
1317
+			if o.keyState[1] == 1:
1318
+				if self.cur_el < (len(self.menu) - 1):
1319
+					self.cur_el += 1
1320
+					print('cur el up is ', self.cur_el)
1321
+			
1322
+			if o.keyState[3] == 1:
1323
+				util_command(self, o, self.menu[self.cur_el])
920 1324
 		
921 1325
 	def ReceiveMessage(self, message):
922 1326
 		_id = 0
923 1327
 		o = self.FSM.owner 
924 1328
 		play_seq(o, message)
925
-		if o.keyState[16] > 0 or o.keyState[17] > 0:
926
-			pass
1329
+		# if o.keyState[16] > 0 or o.keyState[17] > 0:
1330
+		# 	pass
1331
+		# else:
1332
+		# 	draw_header(o)           		
1333
+		# o.update_display(0)
1334
+
1335
+	def draw_main(self, o):
1336
+		al = []
1337
+		ypos = 30
1338
+		if self.cur_el == 0:
1339
+			_iter = 0
1340
+			while len(al) < 4:
1341
+				al.append(self.menu[_iter])
1342
+				_iter += 1
1343
+		elif self.cur_el == 1:
1344
+			al.append(self.menu[self.cur_el - 1])
1345
+			al.append(self.menu[self.cur_el])
1346
+			al.append(self.menu[self.cur_el + 1])
1347
+			al.append(self.menu[self.cur_el + 2])
1348
+		elif self.cur_el == (len(self.menu) - 2):
1349
+			al.append(self.menu[self.cur_el - 2])
1350
+			al.append(self.menu[self.cur_el - 1])
1351
+			al.append(self.menu[self.cur_el])
1352
+			al.append(self.menu[self.cur_el + 1])
1353
+		elif self.cur_el == (len(self.menu) - 1):
1354
+			al.append(self.menu[self.cur_el - 3])
1355
+			al.append(self.menu[self.cur_el - 2])
1356
+			al.append(self.menu[self.cur_el - 1])
1357
+			al.append(self.menu[self.cur_el])
927 1358
 		else:
928
-			draw_header(o)           		
929
-		o.disp.image(o.image, o.rotation)
1359
+			al.append(self.menu[self.cur_el - 1])
1360
+			al.append(self.menu[self.cur_el])
1361
+			al.append(self.menu[self.cur_el + 1])
1362
+			al.append(self.menu[self.cur_el + 2])
1363
+		_iter = 0 
1364
+		for i in al:
1365
+			if i == self.menu[self.cur_el]:
1366
+			#if _iter == self.cur_el:
1367
+				o.draw.rectangle((0, ypos, o.width, ypos + 20), outline=0, fill=o.light_grey)
1368
+				o.center_block(i, o.h2, [0, ypos, o.width,ypos + 20], o.blue)
1369
+			else:
1370
+				o.draw.rectangle((0, ypos, o.width, ypos + 20), outline=0, fill=o.blue)
1371
+				o.center_block(i, o.h2, [0, ypos, o.width,ypos + 20], o.light_grey)
1372
+			ypos += 20
1373
+			_iter += 1
1374
+
1375
+	def draw_footer(self, o):
1376
+		_iter = 0
1377
+		width = o.width / 4
1378
+		xpos = 0
1379
+		yposa = 135 - 25
1380
+		yposb = 135
1381
+		opts = ["Up", "Down", "Esc", "OK"]
1382
+		while _iter < 4:
1383
+			o.draw.rectangle((xpos, yposa, xpos + width, yposb), outline=0, fill=o.blue)
1384
+			
1385
+			if o.keyState[_iter] == 1:
1386
+				o.draw.rectangle((xpos, yposa, xpos + width, yposb), outline=0, fill=o.light_grey)
1387
+				o.center_block(opts[_iter], o.h2, [xpos,yposa,xpos + width,yposb], o.blue)
1388
+			else:
1389
+				o.center_block(opts[_iter], o.h2, [xpos,yposa,xpos + width,yposb], o.light_grey)
1390
+			
1391
+			xpos += width
1392
+			_iter += 1
930 1393
 
931 1394
 	def Exit(self):
932
-		pass        
1395
+		self.FSM.owner.pub.unregister("beat", self)        
933 1396
 
934 1397
 
935 1398
 
@@ -952,6 +1415,8 @@ class Ball(State):
952 1415
 		self.ball2_x_dir = -1
953 1416
 		self.ball2_y_dir = -1
954 1417
 
1418
+		self.xmult = 1.0
1419
+
955 1420
 		o = self.FSM.owner 
956 1421
 		o.header_text = "Ball"
957 1422
 		o.pub.register("beat", self)
@@ -959,7 +1424,7 @@ class Ball(State):
959 1424
 			pass
960 1425
 		else:
961 1426
 			draw_header(o)
962
-			o.disp.image(o.image, o.rotation)
1427
+			o.update_display(0)
963 1428
 		super(Ball, self).Enter()        
964 1429
 		
965 1430
 	def Execute(self):
@@ -967,41 +1432,70 @@ class Ball(State):
967 1432
 		menu1_actions(self, o)
968 1433
 		if o.keyState[16] == 1:
969 1434
 			draw_menu1(o)
970
-			o.disp.image(o.image, o.rotation)
971
-		else:
1435
+			o.update_display(0)
1436
+		
1437
+
1438
+		if o.keyState[16] > 0 or o.keyState[17] > 0:
1439
+			pass
1440
+		else:			
972 1441
 			now = datetime.now()
973 1442
 			current_time = time.strftime("%-I:%M %p")
974 1443
 
975
-			if self.ballx > (o.width - self.ball_size) or self.ballx < (0 + self.ball_size):
976
-				self.ball_x_dir *= -1
977
-			if (self.bally > o.height - self.ball_size) or (self.bally < 0 + self.ball_size):
978
-				self.ball_y_dir *= -1
1444
+
1445
+			if self.ballx < (0 + self.ball_size):
1446
+				self.ball_x_dir = 1
1447
+			if self.ballx > (o.width - self.ball_size):
1448
+				self.ball_x_dir = -1
1449
+
1450
+			if self.bally < (0 + self.ball_size):
1451
+				self.ball_y_dir = 1
1452
+			if self.bally > (o.height - self.ball_size):
1453
+				self.ball_y_dir = -1
1454
+
1455
+			# if self.ballx > (o.width - self.ball_size) or self.ballx < (0 + self.ball_size):
1456
+			# 	self.ball_x_dir *= -1
1457
+			# if self.bally > (o.height - self.ball_size) or self.bally < (0 + self.ball_size):
1458
+			# 	self.ball_y_dir *= -1
979 1459
 
980 1460
 			self.ballx += self.ball_speed * self.ball_x_dir
981 1461
 			self.bally += self.ball_speed * self.ball_y_dir
982 1462
 
983 1463
 
984
-			if self.ball2x > (o.width - self.ball_size) or self.ball2x < (0 + self.ball_size):
985
-				self.ball2_x_dir *= -1
986
-			if (self.ball2y > o.height - self.ball_size) or (self.ball2y < 0 + self.ball_size):
987
-				self.ball2_y_dir *= -1
1464
+			if self.ball2x < (0 + self.ball_size):
1465
+				self.ball2_x_dir = 1
1466
+				self.xmult = random.uniform(.6, 1.2)
1467
+			if self.ball2x > (o.width - self.ball_size):
1468
+				self.ball2_x_dir = -1
1469
+				self.xmult = random.uniform(.6, 1.2)
1470
+
1471
+			if self.ball2y < (0 + self.ball_size):
1472
+				self.ball2_y_dir = 1
1473
+			if self.ball2y > (o.height - self.ball_size):
1474
+				self.ball2_y_dir = -1			
988 1475
 
989
-			self.ball2x += self.ball_speed * self.ball2_x_dir
990
-			self.ball2y += self.ball_speed * self.ball2_y_dir
1476
+
1477
+			# if self.ball2x > (o.width - self.ball_size) or self.ball2x < (0 + self.ball_size):
1478
+			# 	self.ball2_x_dir *= -1
1479
+			# 	self.xmult = random.uniform(.8, 1.2)
1480
+			# if self.ball2y > (o.height - self.ball_size) or self.ball2y < (0 + self.ball_size):
1481
+			# 	self.ball2_y_dir *= -1
1482
+
1483
+			self.ball2x += (self.ball_speed * self.ball2_x_dir) * self.xmult
1484
+			self.ball2y += (self.ball_speed * self.ball2_y_dir) 
991 1485
 
992 1486
 			o.draw.rectangle((0, 0, o.width, o.height), outline=0, fill=o.blue)
993 1487
 			
994 1488
 			o.draw.ellipse((self.ballx - self.ball_size, self.bally - self.ball_size, self.ballx + self.ball_size, self.bally + self.ball_size), fill = o.light_grey, outline =o.light_grey)
995 1489
 			o.draw.ellipse((self.ball2x - self.ball_size, self.ball2y - self.ball_size, self.ball2x + self.ball_size, self.ball2y + self.ball_size), fill = o.light_grey, outline =o.light_grey)
996
-			o.center_block(current_time, o.h3, [0,0,o.width,o.height], o.pink)
997
-			o.disp.image(o.image, o.rotation)
1490
+			#o.center_block(current_time, o.h3, [0,0,o.width,o.height], o.pink)
1491
+			o.update_display(0)
998 1492
 		
999 1493
 	def ReceiveMessage(self, message):
1000 1494
 		o = self.FSM.owner 
1001 1495
 		play_seq(o, message)
1002 1496
 		
1003 1497
 	def Exit(self):
1004
-		pass        
1498
+		self.FSM.owner.pub.unregister("beat", self)        
1005 1499
 
1006 1500
 #==================================== 
1007 1501
 
@@ -1033,10 +1527,15 @@ class Clock(State):
1033 1527
 	def Execute(self):
1034 1528
 		o = self.FSM.owner 
1035 1529
 		menu1_actions(self, o)
1530
+
1036 1531
 		if o.keyState[16] == 1:
1037 1532
 			draw_menu1(o)
1038
-			o.disp.image(o.image, o.rotation)
1039
-		else:
1533
+			o.update_display(0)
1534
+
1535
+
1536
+		if o.keyState[16] > 0 or o.keyState[17] > 0:
1537
+			pass
1538
+		else:			
1040 1539
 			current_time = time.strftime("%-I:%M:%S")
1041 1540
 
1042 1541
 			if self.ballx > (o.width - self.ball_sizex) or self.ballx < (0 + self.ball_sizex):
@@ -1048,13 +1547,456 @@ class Clock(State):
1048 1547
 			self.bally += self.ball_speed * self.ball_y_dir
1049 1548
 			o.draw.rectangle((0, 0, o.width, o.height), outline=0, fill=o.black)			
1050 1549
 			o.draw.text((self.ballx - self.ball_sizex, self.bally - self.ball_sizey), current_time, align='center', font=o.h3, fill=o.olive)
1051
-			o.disp.image(o.image, o.rotation)
1550
+			o.update_display(0)
1551
+		
1552
+	def ReceiveMessage(self, message):
1553
+		o = self.FSM.owner 
1554
+		play_seq(o, message)
1555
+		
1556
+	def Exit(self):
1557
+		self.FSM.owner.pub.unregister("beat", self)        
1558
+
1559
+#==================================== 
1560
+
1561
+class Exit(State):
1562
+	def __init__(self,FSM):
1563
+		super(Exit, self).__init__(FSM)    
1564
+		
1565
+	def Enter(self):
1566
+		o = self.FSM.owner
1567
+		o.draw.rectangle((0, 0, o.width, o.height), outline=0, fill=o.blue)			
1568
+		o.center_block("goodbye", o.h2, [0, 0, o.width,o.height], o.light_grey)
1569
+		o.update_display(0)
1570
+		pygame.quit()
1571
+		sys.exit()
1572
+		super(Exit, self).Enter()        
1573
+		
1574
+	def Execute(self):
1575
+		self.FSM.stateLife += 1
1576
+		
1577
+	def Exit(self):
1578
+		pass
1579
+
1580
+#==================================== 
1581
+
1582
+class SelTheme(State):
1583
+	def __init__(self,FSM):
1584
+		super(SelTheme, self).__init__(FSM)    
1585
+		
1586
+	def Enter(self):
1587
+		o = self.FSM.owner
1588
+		o.header_text = "Select Theme"
1589
+		o.pub.register("beat", self)
1590
+		self.cur_el = 0
1591
+		self.globbed = glob.glob('/home/pi/zpc_ct/themes/*.thm')
1592
+		self.globbed.sort()
1593
+		self.names = [os.path.basename(x) for x in self.globbed]
1594
+		self.names = [os.path.splitext(x)[0] for x in self.names]
1595
+		if o.mconf['theme'] in self.names:
1596
+			_id = self.names.index(o.mconf['theme'])
1597
+			self.cur_el = _id
1598
+			#print('found theme ', _id)
1599
+		else:
1600
+			print('nope ', o.mconf['theme'], ' - ', self.globbed)
1601
+		#self.theme = ConfigObj("/home/pi/zpc_ct/themes/" + self.mconf['theme'])
1602
+		#print(os.path.splitext(x)[0])
1603
+		self.menu = self.names
1604
+
1605
+		#self.cur_el = 0
1606
+		print('theme menu is ', self.menu)
1607
+
1608
+		if o.keyState[16] > 0 or o.keyState[17] > 0:
1609
+			pass
1610
+		else:
1611
+			draw_header(o)
1612
+			self.draw_main(o)			
1613
+			
1614
+			o.update_display(0)
1615
+		super(SelTheme, self).Enter()    
1616
+
1617
+	def Execute(self):
1618
+		o = self.FSM.owner 
1619
+		menu1_actions(self, o)
1620
+		if o.keyState[16] == 1:
1621
+			draw_menu1(o)
1622
+			o.update_display(0)
1623
+		elif o.keyState[16] == 4:
1624
+			draw_header(o)
1625
+			self.draw_footer(o)
1626
+			self.draw_main(o)
1627
+			o.update_display(0)
1628
+
1629
+		if o.keyState[0] == 1 or o.keyState[0] == 3 or o.keyState[1] == 1 or o.keyState[1] == 3 or o.keyState[2] == 1 or o.keyState[2] == 3 or o.keyState[3] == 1 or o.keyState[3] == 3:
1630
+			draw_header(o)
1631
+			self.draw_footer(o)
1632
+			self.draw_main(o)
1633
+			o.update_display(0)	
1634
+			print('draw butt')				
1635
+
1636
+		if o.keyState[16] > 0 or o.keyState[17] > 0:
1637
+			pass
1638
+		else:
1639
+			if o.keyState[0] == 1:
1640
+				if self.cur_el > 0:
1641
+					self.cur_el -= 1
1642
+					o.mconf['theme'] = self.menu[self.cur_el]					
1643
+					o.save_config()
1644
+					o.load_config()
1645
+					o.apply_theme()
1646
+					print('cur el down is ', self.cur_el)
1647
+
1648
+					#o.applyTheme
1649
+			if o.keyState[1] == 1:
1650
+				if self.cur_el < (len(self.menu) - 1):
1651
+					self.cur_el += 1
1652
+					o.mconf['theme'] = self.menu[self.cur_el]					
1653
+					o.save_config()
1654
+					o.load_config()
1655
+					o.apply_theme()
1656
+					print('cur el up is ', self.cur_el)
1657
+					print('loading theme ', self.menu[self.cur_el], '-- ', o.mconf['theme'])
1658
+			if o.keyState[3] == 1:
1659
+				util_command(self, o, self.menu[self.cur_el])
1660
+
1661
+	def draw_main(self, o):
1662
+		al = []
1663
+		ypos = 30
1664
+		if self.cur_el == 0:
1665
+			_iter = 0
1666
+			while len(al) < 4:
1667
+				al.append(self.menu[_iter])
1668
+				_iter += 1
1669
+		elif self.cur_el == 1:
1670
+			al.append(self.menu[self.cur_el - 1])
1671
+			al.append(self.menu[self.cur_el])
1672
+			al.append(self.menu[self.cur_el + 1])
1673
+			al.append(self.menu[self.cur_el + 2])
1674
+		elif self.cur_el == (len(self.menu) - 2):
1675
+			al.append(self.menu[self.cur_el - 2])
1676
+			al.append(self.menu[self.cur_el - 1])
1677
+			al.append(self.menu[self.cur_el])
1678
+			al.append(self.menu[self.cur_el + 1])
1679
+		elif self.cur_el == (len(self.menu) - 1):
1680
+			al.append(self.menu[self.cur_el - 3])
1681
+			al.append(self.menu[self.cur_el - 2])
1682
+			al.append(self.menu[self.cur_el - 1])
1683
+			al.append(self.menu[self.cur_el])
1684
+		else:
1685
+			al.append(self.menu[self.cur_el - 1])
1686
+			al.append(self.menu[self.cur_el])
1687
+			al.append(self.menu[self.cur_el + 1])
1688
+			al.append(self.menu[self.cur_el + 2])
1689
+		_iter = 0 
1690
+		for i in al:
1691
+			if i == self.menu[self.cur_el]:
1692
+			#if _iter == self.cur_el:
1693
+				o.draw.rectangle((0, ypos, o.width, ypos + 20), outline=0, fill=o.light_grey)
1694
+				o.center_block(i, o.h2, [0, ypos, o.width,ypos + 20], o.blue)
1695
+			else:
1696
+				o.draw.rectangle((0, ypos, o.width, ypos + 20), outline=0, fill=o.blue)
1697
+				o.center_block(i, o.h2, [0, ypos, o.width,ypos + 20], o.light_grey)
1698
+			ypos += 20
1699
+			_iter += 1		    
1700
+
1701
+	def draw_footer(self, o):
1702
+		_iter = 0
1703
+		width = o.width / 4
1704
+		xpos = 0
1705
+		yposa = 135 - 25
1706
+		yposb = 135
1707
+		opts = ["Up", "Down", "", ""]
1708
+		while _iter < 4:
1709
+			o.draw.rectangle((xpos, yposa, xpos + width, yposb), outline=0, fill=o.blue)
1710
+			
1711
+			if o.keyState[_iter] == 1:
1712
+				o.draw.rectangle((xpos, yposa, xpos + width, yposb), outline=0, fill=o.light_grey)
1713
+				o.center_block(opts[_iter], o.h2, [xpos,yposa,xpos + width,yposb], o.blue)
1714
+			else:
1715
+				o.center_block(opts[_iter], o.h2, [xpos,yposa,xpos + width,yposb], o.light_grey)
1716
+			
1717
+			xpos += width
1718
+			_iter += 1
1719
+		
1720
+
1721
+	def ReceiveMessage(self, message):
1722
+		o = self.FSM.owner 
1723
+		play_seq(o, message)
1724
+		
1725
+	def Exit(self):
1726
+		self.FSM.owner.pub.unregister("beat", self)
1727
+
1728
+#==================================== 
1729
+
1730
+class OpenSong(State):
1731
+	def __init__(self,FSM):
1732
+		super(OpenSong, self).__init__(FSM)    
1733
+		
1734
+	def Enter(self):
1735
+		o = self.FSM.owner
1736
+		o.header_text = "Open Song"
1737
+		o.pub.register("beat", self)
1738
+		self.cur_el = 0
1739
+		self.globbed = glob.glob('/home/pi/zpc_ct/user/songs/*.sng')
1740
+		self.globbed.sort()
1741
+		if '/home/pi/zpc_ct/user/songs/_blank.sng' in self.globbed:
1742
+			self.globbed.remove('/home/pi/zpc_ct/user/songs/_blank.sng')
1743
+		#del self.globbed[0]
1744
+		self.names = [os.path.basename(x) for x in self.globbed]
1745
+		self.names = [os.path.splitext(x)[0] for x in self.names]
1746
+		print('we got these songs ', self.names)
1747
+		print('in these paths ', self.globbed)
1748
+		if o.mconf['default_song'] in self.names:
1749
+			_id = self.names.index(o.mconf['default_song'])
1750
+			self.cur_el = _id
1751
+		else:
1752
+			print('nope ', o.mconf['default_song'], ' - ', self.globbed)
1753
+		self.menu = self.names
1754
+
1755
+		#self.cur_el = 0
1756
+		#print('theme menu is ', self.menu)
1757
+
1758
+		if o.keyState[16] > 0 or o.keyState[17] > 0:
1759
+			pass
1760
+		else:
1761
+			draw_header(o)
1762
+			self.draw_main(o)			
1763
+			
1764
+			o.update_display(0)
1765
+		super(OpenSong, self).Enter()    
1766
+
1767
+	def Execute(self):
1768
+		o = self.FSM.owner 
1769
+		menu1_actions(self, o)
1770
+		if o.keyState[16] == 1:
1771
+			draw_menu1(o)
1772
+			o.update_display(0)
1773
+		elif o.keyState[16] == 4:
1774
+			draw_header(o)
1775
+			self.draw_footer(o)
1776
+			self.draw_main(o)
1777
+			o.update_display(0)
1778
+
1779
+		if o.keyState[0] == 1 or o.keyState[0] == 3 or o.keyState[1] == 1 or o.keyState[1] == 3 or o.keyState[2] == 1 or o.keyState[2] == 3 or o.keyState[3] == 1 or o.keyState[3] == 3:
1780
+			draw_header(o)
1781
+			self.draw_footer(o)
1782
+			self.draw_main(o)
1783
+			o.update_display(0)	
1784
+			print('draw butt')				
1785
+
1786
+		if o.keyState[16] > 0 or o.keyState[17] > 0:
1787
+			pass
1788
+		else:
1789
+			if o.keyState[0] == 1:
1790
+				if self.cur_el > 0:
1791
+					self.cur_el -= 1
1792
+					# o.mconf['theme'] = self.menu[self.cur_el]					
1793
+					# o.save_config()
1794
+					# o.load_config()
1795
+					# o.apply_theme()
1796
+					print('cur el down is ', self.cur_el)
1797
+
1798
+					#o.applyTheme
1799
+			if o.keyState[1] == 1:
1800
+				if self.cur_el < (len(self.menu) - 1):
1801
+					self.cur_el += 1
1802
+					# o.mconf['theme'] = self.menu[self.cur_el]					
1803
+					# o.save_config()
1804
+					# o.load_config()
1805
+					# o.apply_theme()
1806
+					print('cur el up is ', self.cur_el)
1807
+					#print('loading theme ', self.menu[self.cur_el], '-- ', o.mconf['theme'])
1808
+			if o.keyState[3] == 1:
1809
+				#open_command(self, o, self.menu[self.cur_el])
1810
+				o.mconf['default_song'] = self.menu[self.cur_el]
1811
+				o.load_song()
1812
+				#pass
1813
+
1814
+	def draw_main(self, o):
1815
+		al = []
1816
+		ypos = 30
1817
+		if self.cur_el == 0:
1818
+			_iter = 0
1819
+			while len(al) < 4:
1820
+				al.append(self.menu[_iter])
1821
+				_iter += 1
1822
+		elif self.cur_el == 1:
1823
+			al.append(self.menu[self.cur_el - 1])
1824
+			al.append(self.menu[self.cur_el])
1825
+			al.append(self.menu[self.cur_el + 1])
1826
+			al.append(self.menu[self.cur_el + 2])
1827
+		elif self.cur_el == (len(self.menu) - 2):
1828
+			al.append(self.menu[self.cur_el - 2])
1829
+			al.append(self.menu[self.cur_el - 1])
1830
+			al.append(self.menu[self.cur_el])
1831
+			al.append(self.menu[self.cur_el + 1])
1832
+		elif self.cur_el == (len(self.menu) - 1):
1833
+			al.append(self.menu[self.cur_el - 3])
1834
+			al.append(self.menu[self.cur_el - 2])
1835
+			al.append(self.menu[self.cur_el - 1])
1836
+			al.append(self.menu[self.cur_el])
1837
+		else:
1838
+			al.append(self.menu[self.cur_el - 1])
1839
+			al.append(self.menu[self.cur_el])
1840
+			al.append(self.menu[self.cur_el + 1])
1841
+			al.append(self.menu[self.cur_el + 2])
1842
+		_iter = 0 
1843
+		for i in al:
1844
+			if i == self.menu[self.cur_el]:
1845
+			#if _iter == self.cur_el:
1846
+				o.draw.rectangle((0, ypos, o.width, ypos + 20), outline=0, fill=o.light_grey)
1847
+				o.center_block(i, o.h2, [0, ypos, o.width,ypos + 20], o.blue)
1848
+			else:
1849
+				o.draw.rectangle((0, ypos, o.width, ypos + 20), outline=0, fill=o.blue)
1850
+				o.center_block(i, o.h2, [0, ypos, o.width,ypos + 20], o.light_grey)
1851
+			ypos += 20
1852
+			_iter += 1		    
1853
+
1854
+	def draw_footer(self, o):
1855
+		_iter = 0
1856
+		width = o.width / 4
1857
+		xpos = 0
1858
+		yposa = 135 - 25
1859
+		yposb = 135
1860
+		opts = ["Up", "Down", "Esc", "Open"]
1861
+		while _iter < 4:
1862
+			o.draw.rectangle((xpos, yposa, xpos + width, yposb), outline=0, fill=o.blue)
1863
+			
1864
+			if o.keyState[_iter] == 1:
1865
+				o.draw.rectangle((xpos, yposa, xpos + width, yposb), outline=0, fill=o.light_grey)
1866
+				o.center_block(opts[_iter], o.h2, [xpos,yposa,xpos + width,yposb], o.blue)
1867
+			else:
1868
+				o.center_block(opts[_iter], o.h2, [xpos,yposa,xpos + width,yposb], o.light_grey)
1869
+			
1870
+			xpos += width
1871
+			_iter += 1
1052 1872
 		
1873
+
1874
+	def ReceiveMessage(self, message):
1875
+		o = self.FSM.owner 
1876
+		play_seq(o, message)
1877
+		
1878
+	def Exit(self):
1879
+		self.FSM.owner.pub.unregister("beat", self)
1880
+
1881
+
1882
+class EnterText(State):
1883
+	def __init__(self,FSM):
1884
+		super(EnterText, self).__init__(FSM)    
1885
+		
1886
+	def Enter(self):
1887
+		o = self.FSM.owner 
1888
+		
1889
+		self.input_string = ""
1890
+		o.header_text = "EnterText"
1891
+		o.pub.register("beat", self)
1892
+		self.last_action = pygame.time.get_ticks()
1893
+
1894
+		self.cur_but = 18
1895
+		self.cur_letter = ""
1896
+		if o.keyState[16] > 0 or o.keyState[17] > 0:
1897
+			pass
1898
+		else:
1899
+			pass
1900
+
1901
+		self.skips = [7, 11, 12, 13, 14, 15]
1902
+		
1903
+		self.labels = [["p", "q", "r", "s"], ["t", "u", "v"], ["w", "x", "y", "z"], ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"], 
1904
+				["g", "h", "i"], ["j", "k", "l"], ["m", "n", "o"], ["D", "E", "L"],
1905
+				["_", "-"], ["a", "b", "c"], ["d", "e", "f"], ["O", "K"],
1906
+				[], [], [], []]
1907
+
1908
+		#self.songCycle = cycle(self.song)
1909
+		#self.curPattern = next(self.songCycle)
1910
+
1911
+		self.cycles = []
1912
+		for l in self.labels:
1913
+			self.cycles.append(cycle(l))
1914
+
1915
+		self.draw(o)
1916
+		o.update_display(0)
1917
+		super(EnterText, self).Enter()        
1918
+		
1919
+	def Execute(self):
1920
+		o = self.FSM.owner 
1921
+		y_size = o.height / 4
1922
+		if o.keyState[11] == 1:
1923
+			self.FSM.ToTransition('toFile')		
1924
+		if o.keyState[16] > 0 and o.keyState[17] > 0:
1925
+			pass
1926
+		else:
1927
+			_iter = 0
1928
+			for k in o.keyState:
1929
+				if k == 1:
1930
+					cur_time = pygame.time.get_ticks()
1931
+					print(cur_time - self.last_action)
1932
+					
1933
+					#print('cur letter ', next(self.cycles[_iter]))
1934
+					if _iter not in self.skips:
1935
+						self.last_action = cur_time
1936
+						self.cur_letter = next(self.cycles[_iter])
1937
+						self.cur_but = _iter
1938
+						self.draw(o)
1939
+						o.center_block(self.input_string + self.cur_letter, o.h2, [0, 0, o.width, y_size], o.light_grey)
1940
+
1941
+					if _iter == 7:
1942
+						
1943
+						self.input_string = self.input_string[:-1]
1944
+						#self.input_string = self.input_string.rstrip(self.input_string[-1])
1945
+						print('deleting')
1946
+						self.last_action = 100000000
1947
+						self.draw(o)
1948
+						o.center_block(self.input_string, o.h2, [0, 0, o.width, y_size], o.light_grey)
1949
+					
1950
+					o.update_display(0)
1951
+				_iter += 1
1952
+
1953
+		cur_time = pygame.time.get_ticks()
1954
+		delay = cur_time - self.last_action
1955
+		if delay > 1000 and delay < 100000:
1956
+			self.input_string += self.cur_letter
1957
+			self.last_action = 100000000
1958
+			self.reset_cycles()
1959
+			self.draw(o)
1960
+
1961
+			o.center_block(self.input_string, o.h2, [0, 0, o.width, y_size], o.light_grey)
1962
+			o.update_display(0)
1963
+	
1053 1964
 	def ReceiveMessage(self, message):
1054 1965
 		o = self.FSM.owner 
1055 1966
 		play_seq(o, message)
1967
+
1968
+	def draw(self, o):
1969
+		x_size = o.width / 4
1970
+		y_size = o.height / 4
1971
+		og_x = 0
1972
+		o_x = og_x
1973
+		o_y = o.height
1974
+		text_padding = 6
1975
+		
1976
+
1977
+		_id = 0
1978
+		while _id < 16:
1979
+			lab = ""
1980
+			for i in self.labels[_id]:
1981
+				lab += i
1982
+			o.draw.rectangle((o_x, o_y, o_x + x_size, o_y - y_size), outline=0, fill=o.blue)
1983
+			if _id == 3:
1984
+				lab = "123"
1985
+			o.center_block(lab, o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey)
1986
+
1987
+			o_x = o_x + x_size
1988
+			_id += 1
1989
+			if _id % 4 == 0:
1990
+				o_y -= y_size
1991
+				o_x = og_x
1992
+		o.draw.rectangle((0, 0, o.width, y_size), outline=0, fill=o.blue)
1056 1993
 		
1994
+	def reset_cycles(self):
1995
+		self.cycles = []
1996
+		for l in self.labels:
1997
+			self.cycles.append(cycle(l))
1998
+
1057 1999
 	def Exit(self):
1058
-		pass        
2000
+		self.FSM.owner.pub.unregister("beat", self)        
1059 2001
 
1060 2002
 #==================================== 

+ 145
- 15
main.py View File

@@ -21,6 +21,7 @@ from configobj import ConfigObj
21 21
 import ast
22 22
 import RPi.GPIO as GPIO
23 23
 from time import sleep
24
+import threading
24 25
 GPIO.setmode(GPIO.BCM)
25 26
 
26 27
 # set up GPIO output channel - internal led
@@ -40,6 +41,7 @@ keypad = adafruit_matrixkeypad.Matrix_Keypad(rows, cols, keys)
40 41
 
41 42
 pygame.init()
42 43
 mixer.init()
44
+mixer.set_num_channels(32)
43 45
 done = False
44 46
 clock = pygame.time.Clock()
45 47
 TIMER = pygame.USEREVENT + 1
@@ -52,6 +54,7 @@ cs_pin = digitalio.DigitalInOut(board.CE0)
52 54
 dc_pin = digitalio.DigitalInOut(board.D25)
53 55
 reset_pin = None
54 56
 BAUDRATE = 64000000  # The pi can be very fast!
57
+#BAUDRATE = 24000000
55 58
 # display = st7789.ST7789(
56 59
 # 	board.SPI(),
57 60
 # 	cs=cs_pin,
@@ -135,10 +138,12 @@ class Prog:
135 138
 		#self.bpm = 90
136 139
 		self.bpm_inc = 1
137 140
 		self.note_bank = 0
141
+		self.pat_bank = 0
138 142
 		self.volume = 10
139 143
 		self.note_vol = 16
140 144
 		self.note_pitch = 0.0
141 145
 		self.soundSlots = []
146
+		self.slots = []
142 147
 		self.keys = []
143 148
 		self.keyState = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
144 149
 		#self.song = [2, 3, 0, 1, 0, 1, 0, 1, 0, 1]
@@ -148,6 +153,8 @@ class Prog:
148 153
 		self.songStart = self.curPattern
149 154
 		self.eSound = 0
150 155
 		self.ePattern = 0
156
+		self.patternClipboard = []
157
+		self.soundClipboard = []
151 158
 		self.black = "#000000"
152 159
 		self.bg_color = "#336699"
153 160
 		self.color_a = "#FFFFFF"
@@ -162,27 +169,36 @@ class Prog:
162 169
 		self.red = "#D52A2A"
163 170
 		self.olive = "#80D52A"
164 171
 		self.green = "#2AD52A"
172
+		self.notes_on = []
173
+		self.clear_notes_on()
174
+
165 175
 
166 176
 		self.pub = observer.Publisher(['beat', 'the joint'])
167 177
 
168
-		self.song_file_name = "default.sng"
178
+		#self.song_file_name = "default.sng"
169 179
 		self.mconf = ConfigObj("config.txt")
170 180
 		self.sconf = ConfigObj("/home/pi/zpc_ct/user/songs/" + self.mconf['default_song'])
171
-		self.theme = ConfigObj("/home/pi/zpc_ct/themes/" + self.mconf['theme'])
181
+		self.theme = ConfigObj("/home/pi/zpc_ct/themes/" + self.mconf['theme'] + ".thm")
172 182
 		
173 183
 		self.light_grey = self.theme['light_grey']
174 184
 		self.apply_theme()
185
+		self.display_thread = threading.Thread(target=self.update_display, args=([0]))
175 186
 
176 187
 	class SoundSlot:
177 188
 		def __init__(self, file, obj_id, o):
178 189
 			self.file = file
179 190
 			self.id = obj_id
180 191
 			self.o = o
181
-			self.mixerSound = pygame.mixer.Sound(self.file)
182
-			self.og_sound = self.mixerSound
183
-			self.pattern = [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0]
192
+			self.mixerSound = None
193
+			self.soundArray = None
194
+			self.og_sound = None
195
+			if file != None:
196
+				self.mixerSound = pygame.mixer.Sound(self.file)
197
+				self.soundArray = pygame.sndarray.array(self.mixerSound)
198
+				self.og_sound = self.mixerSound
199
+			#self.pattern = [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0]
184 200
 			self.notes = self.init_notes()
185
-			self.pitch = 0.0
201
+			self.pitch = 0
186 202
 			self.volume = 16
187 203
 			self.start = 0
188 204
 			self.end = 0
@@ -193,12 +209,27 @@ class Prog:
193 209
 			# snd_resample = resample(snd_array, 2.5, "sinc_fastest").astype(snd_array.dtype)
194 210
 			# snd_out = pygame.sndarray.make_sound(snd_resample)
195 211
 			# snd_out.play()
196
-			
197
-			if vol != 0:
198
-				vol = (vol / 16) * (self.volume / 16) * (self.o.volume / 16)
199
-				self.mixerSound.set_volume(vol)
200 212
 
201
-			pygame.mixer.Sound.play(self.mixerSound)  
213
+			#lst = ast.literal_eval(self.o.sconf.as_list('volumes')[self.id])
214
+			#print('---------- ', 'this is a volume')
215
+			#print(lst)
216
+			#print('note vol ', self.volume)
217
+			#o.sconf
218
+			if self.file != None:
219
+				if vol != 0:
220
+					vol = (vol / 16) * (self.volume / 16) * (self.o.volume / 16)
221
+					self.mixerSound.set_volume(vol)
222
+
223
+				pygame.mixer.Sound.play(self.mixerSound)  
224
+
225
+		def set_pitch(self):
226
+			if self.pitch == 0:
227
+				self.mixerSound = self.og_sound
228
+			else:
229
+				snd_resample = resample(self.soundArray, ((self.pitch * - 1) / 10) + 1, "sinc_fastest").astype(self.soundArray.dtype)
230
+				self.mixerSound = pygame.sndarray.make_sound(snd_resample)
231
+				# snd_array = pygame.sndarray.array(self.mixerSound)
232
+			print('setting pitch to ', self.pitch)
202 233
 
203 234
 
204 235
 		def init_notes(self):
@@ -215,6 +246,17 @@ class Prog:
215 246
 				_id += 1		
216 247
 			return outp
217 248
 				
249
+	def init_slots(self):
250
+		# slot_id, file, volume, pitch, notes
251
+		_iter = 0 
252
+		self.slots = []
253
+		while _iter < 64:
254
+
255
+			#def __init__(self, file, obj_id, o):
256
+			p1 = self.SoundSlot(None, _iter, self)
257
+			self.slots.append(p1)
258
+			_iter += 1
259
+			print('adding slot ', _iter)
218 260
 
219 261
 	def Execute(self):
220 262
 		self.keys = keypad.pressed_keys
@@ -321,37 +363,125 @@ class Prog:
321 363
 
322 364
 	def save_song(self):
323 365
 		base_dir = "/home/pi/zpc_ct/user/songs/"
324
-		self.sconf = ConfigObj(base_dir + self.song_file_name)
325
-		self.sconf['title'] = "default"
366
+		self.sconf = ConfigObj(base_dir + self.sconf['title'] + '.sng')
367
+		#self.sconf['title'] = "default"
326 368
 		self.sconf['volume'] = self.volume
327 369
 		sounds = []
328 370
 		notes = []
329 371
 		vols = []
330 372
 		pitches = []
373
+
374
+		outp = []
331 375
 		for x in self.soundSlots:
332 376
 			sounds.append(x.file)
333 377
 			notes.append(x.notes)
334 378
 			vols.append(x.volume)
335 379
 			pitches.append(x.pitch)
380
+			outp.append([x.id, x.file, x.volume, x.pitch, x.notes])
336 381
 		self.sconf['sounds'] = sounds
337 382
 		self.sconf['notes'] = notes
338 383
 		self.sconf['song'] = self.song
384
+		self.sconf['volumes'] = vols
385
+		self.sconf['pitches'] = pitches
386
+		self.sconf['Sound Slot'] = outp
339 387
 		self.sconf.write()
340 388
 
389
+
390
+		c2 = ConfigObj(base_dir + self.sconf['title'] + '.sn2')
391
+		c2['volume'] = self.volume
392
+		c2['song'] = self.song
393
+		c2['bpm'] = self.sconf['bpm']
394
+		notes = []
395
+		for n in self.slots:
396
+			notes.append([n.id, n.file, n.volume, n.pitch, n.notes])
397
+		c2['sounds'] = notes
398
+
399
+		#tmp
400
+		for s in self.soundSlots:
401
+			c2['sounds'][s.id] = [s.id, s.file, s.volume, s.pitch, s.notes]
402
+
403
+		c2.write()
404
+
405
+	def save_config(self):
406
+		base_dir = "/home/pi/zpc_ct/"
407
+		#self.mconf = ConfigObj(base_dir + 'config.txt')
408
+		print('before writing')
409
+		print(self.mconf['theme'])
410
+		self.mconf.write()
411
+
412
+	def load_config(self):
413
+		base_dir = "/home/pi/zpc_ct/"
414
+		self.sconf = ConfigObj(base_dir + 'config.txt')
415
+		self.theme = ConfigObj("/home/pi/zpc_ct/themes/" + self.mconf['theme'] + ".thm")
416
+
341 417
 	def load_song(self):
342 418
 		base_dir = "/home/pi/zpc_ct/user/songs/"
343
-		self.sconf = ConfigObj(base_dir + 'default.sng')
344
-		one = self.sconf['song']
419
+		self.sconf = ConfigObj(base_dir + self.mconf['default_song'] + '.sng')
420
+		print(base_dir + self.mconf['default_song'] + '.sng')
421
+		#one = self.sconf['song']
422
+		one = self.sconf['title']
423
+		print('song ', one)
345 424
 		
346 425
 		song = []
347 426
 		for i in self.sconf['song']:
348 427
 			song.append(int(i))
428
+
429
+		obj_id = 0
430
+		self.soundSlots = []
431
+		for s in self.sconf['sounds']:
432
+			p1 = self.SoundSlot(s, obj_id, self)
433
+			self.soundSlots.append(p1)
434
+			if (len(self.sconf.as_list('volumes')) - 1) > obj_id:
435
+				p1.volume = int(self.sconf.as_list('volumes')[obj_id])
436
+			else:
437
+				p1.volume = 12
438
+			if (len(self.sconf.as_list('pitches')) - 1) > obj_id:
439
+				p1.pitch = int(self.sconf.as_list('pitches')[obj_id])
440
+				p1.set_pitch()
441
+			else:
442
+				p1.pitch = 0
443
+			print('adding ', s)
444
+			obj_id += 1
445
+		print(self.soundSlots)
446
+
447
+		_iter = 0
448
+
449
+		lst = ast.literal_eval(self.sconf['notes'][0])
450
+		print('length ', len(lst))
451
+
452
+		for n in self.soundSlots:
453
+			m = []
454
+			if (len(self.sconf.as_list('notes')) - 1) > _iter:
455
+				lst = ast.literal_eval(self.sconf.as_list('notes')[_iter])
456
+				n.notes = lst
457
+			_iter += 1
458
+
349 459
 		self.song = song
350 460
 
351 461
 		self.songCycle = cycle(self.song)
352 462
 		self.curPattern = next(self.songCycle)
353 463
 		self.songStart = self.curPattern
354 464
 
465
+	def update_display(self, x):
466
+		# if self.display_thread.is_alive():
467
+		# 	pass
468
+		# 	#self.disp.image(self.image, self.rotation)
469
+		# else:
470
+		# 	self.display_thread = threading.Thread(target=self.ud, args=([0]))
471
+		
472
+		# 	self.display_thread.start()
473
+		# 	time.sleep(.001)
474
+		self.disp.image(self.image, self.rotation)
475
+	def ud(self, x):
476
+		self.disp.image(self.image, self.rotation)
477
+
478
+	def clear_notes_on(self):
479
+		_iter = 0
480
+		self.notes_on = []
481
+		while _iter < 64:
482
+			self.notes_on.append(0)
483
+			_iter += 1
484
+
355 485
 p = Prog()
356 486
 
357 487
 #while True:

+ 94
- 0
scripts/button_test.py View File

@@ -0,0 +1,94 @@
1
+import sys
2
+from pygame import mixer
3
+import time
4
+import digitalio
5
+import board
6
+import adafruit_matrixkeypad
7
+import pygame
8
+import digitalio
9
+import board
10
+import RPi.GPIO as GPIO
11
+from time import sleep
12
+
13
+GPIO.setmode(GPIO.BCM)
14
+
15
+GPIO.setup(47, GPIO.OUT)
16
+cols = [digitalio.DigitalInOut(x) for x in (board.D21, board.D20, board.D16, board.D12)]
17
+rows = [digitalio.DigitalInOut(x) for x in (board.D26, board.D13, board.D6, board.D5)]
18
+
19
+keys = ((15, 14, 13, 12),
20
+		(11, 10, 9, 8),
21
+		(7, 6, 5, 4),
22
+		(3, 2, 1, 0))
23
+
24
+
25
+keypad = adafruit_matrixkeypad.Matrix_Keypad(rows, cols, keys)
26
+
27
+pygame.init()
28
+mixer.init()
29
+mixer.set_num_channels(32)
30
+done = False
31
+clock = pygame.time.Clock()
32
+TIMER = pygame.USEREVENT + 1
33
+playhead = 0
34
+
35
+timer = pygame.time.get_ticks
36
+start = now = timer()
37
+
38
+cs_pin = digitalio.DigitalInOut(board.CE0)
39
+dc_pin = digitalio.DigitalInOut(board.D25)
40
+reset_pin = None
41
+BAUDRATE = 64000000 
42
+
43
+spi = board.SPI()
44
+
45
+class Prog:
46
+	def __init__(self):
47
+		self.keys = []
48
+		self.keyState = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
49
+		
50
+
51
+	class SoundSlot:
52
+		def __init__(self, file, obj_id, o):
53
+			self.file = file
54
+
55
+	def Execute(self):
56
+		self.keys = keypad.pressed_keys
57
+		self.update_keys()
58
+		#self.FSM.Execute()
59
+
60
+	def update_keys(self):
61
+		_id = 0 
62
+		for k in self.keyState:
63
+			if k == 0:
64
+				if _id in self.keys:
65
+					self.keyState[_id] = 1
66
+					print('key on ', _id)
67
+
68
+			elif k == 1:
69
+				if _id in self.keys:
70
+					self.keyState[_id] = 2
71
+				else:
72
+					self.keyState[_id] = 3
73
+			elif k == 2:
74
+				if _id in self.keys:
75
+					self.keyState[_id] = 2
76
+				else:
77
+					self.keyState[_id] = 3
78
+			else:
79
+				self.keyState[_id] = 0
80
+			_id += 1
81
+
82
+
83
+p = Prog()
84
+	
85
+while not done:
86
+	p.Execute()
87
+	if pygame.event.get(pygame.USEREVENT + 1):
88
+		
89
+		p.playhead += 1
90
+
91
+	clock.tick_busy_loop()
92
+	#print(clock.get_fps())
93
+
94
+pygame.quit()

+ 14
- 0
themes/bw.thm View File

@@ -0,0 +1,14 @@
1
+#main text
2
+light_grey = "#D3D3D3"
3
+#main background
4
+blue = "#000000"
5
+#highlight1
6
+pink = "#D52A80"
7
+#highlight2
8
+olive = "#80D52A"
9
+black = "#000000"
10
+dark_grey = "#404040"
11
+grey = "#808080"
12
+dark_blue = "#2A2AD5"
13
+red = "#D52A2A"
14
+green = "#2AD52A"

+ 14
- 0
themes/dark2.thm View File

@@ -0,0 +1,14 @@
1
+#main text
2
+light_grey = "#D3D3D3"
3
+#main background
4
+blue = "#000000"
5
+#highlight1
6
+pink = "#D52A80"
7
+#highlight2
8
+olive = "#80D52A"
9
+black = "#000000"
10
+dark_grey = "#404040"
11
+grey = "#808080"
12
+dark_blue = "#2A2AD5"
13
+red = "#D52A2A"
14
+green = "#2AD52A"

+ 14
- 0
themes/pumpkin.thm View File

@@ -0,0 +1,14 @@
1
+#main text
2
+light_grey = "#FF4400"
3
+#main background
4
+blue = "#404040"
5
+#highlight1
6
+pink = "#FFC400"
7
+#highlight2
8
+olive = "#3BFF00"
9
+black = "#000000"
10
+dark_grey = "#404040"
11
+grey = "#808080"
12
+dark_blue = "#2A2AD5"
13
+red = "#D52A2A"
14
+green = "#2AD52A"

+ 7
- 0
user/songs/Casio_RZ-1.sng
File diff suppressed because it is too large
View File


+ 9
- 0
user/songs/EMU_E-Drum.sng
File diff suppressed because it is too large
View File


+ 4
- 0
user/songs/EMU_SP-12.sn2
File diff suppressed because it is too large
View File


+ 10
- 0
user/songs/EMU_SP-12.sng
File diff suppressed because it is too large
View File


+ 8
- 0
user/songs/EMU_SP-12a.sng
File diff suppressed because it is too large
View File


+ 4
- 0
user/songs/Linn_Linndrum.sn2
File diff suppressed because it is too large
View File


+ 11
- 0
user/songs/Linn_Linndrum.sng
File diff suppressed because it is too large
View File


+ 8
- 0
user/songs/Roland_TR-505.sng
File diff suppressed because it is too large
View File


+ 4
- 0
user/songs/Roland_TR-808.sn2
File diff suppressed because it is too large
View File


+ 9
- 0
user/songs/Roland_TR-808.sng
File diff suppressed because it is too large
View File


+ 8
- 0
user/songs/Roland_TR-808bak.sng
File diff suppressed because it is too large
View File


+ 4
- 0
user/songs/default.sn2
File diff suppressed because it is too large
View File


+ 4
- 2
user/songs/default.sng
File diff suppressed because it is too large
View File


+ 7
- 0
user/songs/defaultback.sng
File diff suppressed because it is too large
View File


+ 6
- 5
user/songs/r100.sng
File diff suppressed because it is too large
View File


+ 7
- 0
user/songs/tr909.sng
File diff suppressed because it is too large
View File


Loading…
Cancel
Save