-
Notifications
You must be signed in to change notification settings - Fork 2
/
paws.py
98 lines (81 loc) · 3.18 KB
/
paws.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
import midi;
import time;
import copy;
import pygame;
import configparser;
import logging;
import threading;
import argparse;
from constants import *;
import pawsload;
import tempo;
import visuals;
import spotifycontrol;
PYGAME_SEEK_API_POLL = pygame.USEREVENT;
PYGAME_API_POLL_RETURN = pygame.USEREVENT + 1;
def backgroundAPIPoll( sc, pre_delay = None ):
if( pre_delay ):
time.sleep( pre_delay );
event = pygame.event.Event( PYGAME_API_POLL_RETURN, message = sc.getPlaybackPosition() );
pygame.event.post( event );
def playPattern( pattern_original, spotify_uri, delay_audio ):
pattern = copy.deepcopy( pattern_original );
time_steps = tempo.tempoStepsToTimeSteps( pattern );
spotify_controller = spotifycontrol.SpotifyController();
screen_controller = visuals.PawsVisualState( 800, 600, tpsc = 8, gem_height = 4 );
quitting = False;
start_time = time.time();
spotify_controller.playSong( spotify_uri );
if( len( spotify_uri ) > 1 ):
logging.warning( "this song has multiple spotify uris - %s - ongoing position polling will be disabled" % spotify_uri );
backgroundAPIPoll( spotify_controller, pre_delay = 1 );
else:
pygame.time.set_timer( PYGAME_SEEK_API_POLL, 1000 );
while( not quitting ):
loop_begin = time.time();
passed = loop_begin - start_time;
music_time = passed + delay_audio;
tick = tempo.timeToTick( time_steps, music_time );
screen_controller.redrawScreen( pattern[1], tick, passed );
for event in pygame.event.get():
if( event.type == pygame.QUIT ):
quitting = True;
elif( event.type == PYGAME_SEEK_API_POLL ):
t = threading.Thread( target = backgroundAPIPoll, args = ( spotify_controller, ) );
t.start();
elif( event.type == PYGAME_API_POLL_RETURN ):
start_time = time.time() - event.message;
elif( event.type == pygame.VIDEORESIZE ):
w, h = event.dict[ "size" ];
screen_controller.resize( w, h );
elif( event.type == pygame.KEYUP ):
if( event.key == pygame.K_ESCAPE ):
quitting = True;
elif( event.key == pygame.K_f ):
screen_controller.toggleFullscreen();
elif( event.key == pygame.K_LEFT ):
delay_audio -= 0.1;
logging.info( "delay_audio is now %.3f" % delay_audio );
elif( event.key == pygame.K_RIGHT ):
delay_audio += 0.1;
logging.info( "delay_audio is now %.3f" % delay_audio );
rest_time = loop_begin + 1/30;
while( time.time() < rest_time ):
pass;
spotify_controller.pauseSong();
if __name__ == '__main__':
logging.basicConfig( level = logging.INFO );
parser = argparse.ArgumentParser( description = "p.a.w.s. - play along with spotify for drummers" );
parser.add_argument( "songfile", type = argparse.FileType( "r" ) );
parser.add_argument( "--pro", action = "store_true" );
parser.add_argument( "--difficulty", choices = [ "easy", "medium", "hard", "expert" ], default = "medium" );
args = parser.parse_args();
song_file = configparser.ConfigParser();
song_file.read_file( args.songfile );
song_pattern = pawsload.loadAndProcessPattern(
song_file[ "Song" ][ "MidiFile" ],
args.difficulty,
args.pro );
spotify_tracks = song_file[ "Song" ][ "Spotify" ].split( "," );
delay = float( song_file[ "Song" ][ "Delay" ] );
playPattern( song_pattern, spotify_tracks, delay );