-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.py
103 lines (78 loc) · 3.03 KB
/
main.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
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import time
import signal
import traceback
import config
import util
from display import Display
from audio import Audio
from animation import Animation
from gui import gui
if __name__ == '__main__':
def file(path):
path = os.path.abspath(path)
if not os.path.isfile(path):
raise ValueError('{} is not a valid file'.format(path))
return path
def float_normal(x):
x = float(x)
if not (0 <= x <= 1):
raise ValueError('must be between 0 and 1')
return x
import argparse
parser = argparse.ArgumentParser(description='LED Music Visualizer by Daniel Beckwith')
parser.add_argument('-t', '--test_mode', action='store_true', help='Test mode. Don\'t connect to external LED setup.')
parser.add_argument('-b', '--brightness', type=float_normal, default=1.0, help='LED brightness factor from 0 to 1.')
parser.add_argument('-a', '--audio_path', type=file, required=False, help='Path to MP3 file to use for visualization. If not given, a test signal is used.')
parser.add_argument('-v', '--volume', type=float_normal, default=0.5, help='Music volume from 0 to 1.')
parser.add_argument('-d', '--show_debug_window', action='store_true', help='Show the debug window.')
args = parser.parse_args()
gui.setup()
display = Display(brightness=args.brightness) if not args.test_mode else None
audio = Audio(args.audio_path, audio_volume=args.volume)
animation = Animation(audio.samples, audio.sample_rate)
def sigint(signum, frame):
audio.stop()
signal.signal(signal.SIGINT, signal.SIG_DFL)
signal.signal(signal.SIGINT, sigint)
gui.on_close = lambda: audio.stop()
gui.spec_viewer.on_scrub = lambda t: audio.skip_to(t)
gui.spec_viewer.set_spectrogram(animation.spec, animation.spec_freqs, animation.frame_rate)
gui.start(args.show_debug_window)
if display: display.start()
audio.start()
frame_times = []
util.timer('Running visualization')
try:
while audio.running:
t = audio.elapsed_time
frame_timer = time.time()
frame_times.append(frame_timer)
while frame_timer - frame_times[0] >= 1.0:
frame_times.pop(0)
pixels = animation.get_frame(t)
if display: display.send_pixels(pixels)
gui.update_fps(len(frame_times))
if not audio.is_paused:
gui.update_time(t)
gui.update_pixels(pixels)
gui.app.processEvents()
if gui.pause_requested:
gui.pause_requested = False
if not audio.is_paused:
audio.pause()
else:
audio.unpause()
if display and not display.running:
break
except:
traceback.print_exc()
finally:
audio.stop()
if display: display.stop()
gui.stop()
util.timer()
import pyqtgraph
pyqtgraph.exit()