Skip to content

Commit 70ba89d

Browse files
committed
cleaning and starting to add more comments
1 parent 1a9cc63 commit 70ba89d

File tree

2 files changed

+86
-62
lines changed

2 files changed

+86
-62
lines changed

textbeat/__main__.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/python
22
"""textbeat
3-
Copyright (c) 2018 Grady O'Connell
3+
Copyright (c) 2018-2020 Grady O'Connell
44
Open-source under MIT License
55
66
Examples:
@@ -29,7 +29,6 @@
2929
-c execute commands sequentially
3030
-l execute commands simultaenously
3131
--stdin read entire file from stdin
32-
-r --remote (STUB) realtime remote (control through stdin/out)
3332
--ring don't mute midi on end
3433
-L --loop loop song
3534
--midi=<fn> generate midi file
@@ -47,6 +46,7 @@
4746
--quiet no output
4847
-a --analyze (STUB) midi input chord analyzer
4948
"""
49+
# -r --remote (STUB) realtime remote (control through stdin/out)
5050
from __future__ import absolute_import, unicode_literals, print_function, generators
5151
# try:
5252
from .defs import *
@@ -105,7 +105,7 @@ def main():
105105
player.tracks[i].patch(val)
106106
elif arg == '--sustain': player.sustain=True
107107
elif arg == '--ring': player.ring=True
108-
elif arg == '--remote': player.remote = True
108+
# elif arg == '--remote': player.remote = True
109109
elif arg == '--lint': LINT = True
110110
elif arg == '--quiet': set_print(False)
111111
elif arg == '--follow':
@@ -174,7 +174,8 @@ def main():
174174
player.cmdmode = ''
175175
player.shell = True
176176

177-
player.interactive = player.shell or player.remote or player.tutorial
177+
player.interactive = player.shell or player.tutorial
178+
# player.interactive = player.shell or player.remote or player.tutorial
178179

179180
pygame.midi.init()
180181
if pygame.midi.get_count()==0:

textbeat/player.py

Lines changed: 81 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
# TODO: This player modulde includes parser and player prototype code
2-
# that may eventually be reorganized into separate modules
3-
41
from .defs import *
52

63
class StackFrame(object):
4+
"""
5+
Stack frames are items on the Player's call stack.
6+
Similar to function calls, the Player uses a stack to track markers/repeats.
7+
"""
78
def __init__(self, row, caller, count):
89
self.row = row
910
self.caller = caller
@@ -13,11 +14,21 @@ def __init__(self, row, caller, count):
1314
# self.returns[row] = 0
1415

1516
class Player(object):
17+
"""
18+
The Player is what parses the txbt format and plays it.
19+
This is the most "quick and dirty" part of textbeat, so it will probably
20+
be rewritten eventually.
21+
"""
1622

1723
class Flag:
18-
ROMAN = bit(0)
19-
TRANSPOSE = bit(1)
20-
LOOP = bit(2)
24+
"""
25+
Bitflags for Roman numeral notation, transposition, and looping
26+
"""
27+
ROMAN = bit(0) # use roman numeral notation
28+
TRANSPOSE = bit(1) # allow transposition of note letters
29+
LOOP = bit(2) # loop the textbeat file (good for jamtrack, metronome)
30+
31+
# string names for the bitflags
2132
FLAGS = [
2233
'roman',
2334
'transpose',
@@ -30,66 +41,75 @@ class Flag:
3041
# ])
3142

3243
def __init__(self):
33-
self.quitflag = False
34-
self.vimode = False
35-
self.bcproc = None
36-
self.log = False
44+
self.quitflag = False # Set this bool to escape to stop the parser
45+
self.vimode = False # use vi readline mode for prompt_toolkit
46+
# self.log = False
47+
# 'canfollow' means cursor location is printed for interop with vim and others
3748
self.canfollow = False
49+
self.last_follow = 0 # the last line 'followed' (printed)
50+
# sleeping can be disabled for writing to midi files instead of playback
3851
self.cansleep = True
39-
self.lint = False
40-
self.tracks_active = 1
52+
self.lint = False # analyze file (not yet implemented)
53+
self.tracks_active = 1 # the current number of known active tracks found by Player
4154
self.showmidi = False
42-
self.scale = DIATONIC
43-
self.mode = 1
44-
self.transpose = 0
45-
self.octave = 0
46-
self.tempo = 90.0
55+
self.scale = DIATONIC # default scale, see other options in theory.py
56+
self.mode = 1 # musical mode number, 1=ionian
57+
self.transpose = 0 # current transposion of entire song (in steps)
58+
self.octave = 0 # relative octave transposition of entire song
59+
self.tempo = 90.0 # default tempo when unspecified (may be different inside shell)
4760
self.grid = 4.0 # Grid subdivisions of a beat (4 = sixteenth note)
61+
# columns/shift is hardcoded column placement and widths for
62+
# when working in text editors with column highlighting
4863
self.columns = 0
4964
self.column_shift = 0
50-
self.showtextstr = []
65+
# self.showtextstr = []
5166
self.showtext = False # nice output (-v), only shell and cmd modes by default
52-
self.sustain = False # start sustained
53-
self.ring = False # disables midi muting on program exit
67+
self.sustain = False # start sustained?
68+
self.ring = False # ring: disables midi muting on program exit, letting notes ring out
5469
self.buf = []
55-
self.markers = {}
70+
self.markers = {} # markers are for doing jumps and repeats
5671
f = StackFrame(-1,-1,0)
5772
f.returns[''] = 0
58-
self.tutorial = None
59-
self.callstack = [f]
60-
self.separators = []
61-
self.track_history = ['.'] * NUM_TRACKS
62-
self.fn = None
63-
self.row = 0
73+
self.tutorial = None # Tutorial object to run (should be run inside shell, see -T)
74+
self.callstack = [f] # callstack for moving around the file using markers/repeats
75+
# self.separators = [] # separators are currently not supported
76+
self.track_history = ['.'] * NUM_TRACKS # keep track of track history for replaying with " symbol
77+
self.fn = None # filename
78+
self.row = 0 # parser location, row #
6479
# self.rowno = []
65-
self.startrow = -1
66-
self.stoprow = -1
80+
self.startrow = -1 # last row processed, def -1
81+
self.stoprow = -1 # row to stop on, if playing a specific region (-1 is entire file)
6782
self.cmdmode = 'n' # n normal c command s sequence
68-
self.schedule = Schedule(self)
69-
self.host = []
83+
self.plugins = [] # (under dev) textbeat interop plugins
7084
self.tracks = []
7185
self.shell = False
72-
self.remote = False
86+
# eventually, text editor interop may be done by controlling txbt through a socket
87+
# instead of column following
88+
# self.remote = None
7389
self.interactive = False
7490
self.gui = False
7591
self.portname = ''
76-
self.speed = 1.0
77-
self.muted = False # mute all except for solo tracks
92+
self.speed = 1.0 # speed multiplier (this one is per file)
93+
self.muted = False # mute all except for "solo" tracks
7894
self.midi = []
79-
self.instrument = None
80-
self.t = 0.0 # actual time
81-
self.last_follow = 0
82-
self.last_marker = -1
83-
self.midifile = None
84-
self.flags = 0
95+
# self.instrument = None
96+
self.t = 0.0 # time since file processing started, in sec
97+
self.last_follow = -1 # last follow location (row #)
98+
self.last_marker = -1 # last marker location (row #)
99+
self.midifile = None # midi file to write output to
100+
self.flags = 0 # see FLAGS (bitflags)
85101
self.version = '0'
86-
self.auto = False
102+
self.auto = False # (under dev) automatically generate VST rack using a plugin
103+
# embedded config files (key=filename), for things like synth/plugin customization
87104
self.embedded_files = {}
88105
self.vibrato_tracks = set() # tracks that currently have vibrato going
89106

90-
# require enable at top of file
107+
# other devices require enabling them at the top of the file
91108
self.devices = ['midi']
92109

110+
# (under dev) schedule will eventually decouple the player and parser
111+
self.schedule = Schedule(self)
112+
93113
def init(self):
94114

95115
for i in range(len(sys.argv)):
@@ -156,14 +176,14 @@ def refresh_devices(self):
156176
assert False
157177
try:
158178
# support_enable[dev](self.rack)
159-
SUPPORT_PLUGINS[dev].enable(self.host)
179+
SUPPORT_PLUGINS[dev].enable(self.plugins)
160180
except KeyError:
161181
# no init needed, silent
162182
pass
163183
self.auto = 'auto' in self.devices
164184

165185
def set_host(self, plugins):
166-
self.host = plugins
186+
self.plugins = plugins
167187
self.refresh_devices()
168188

169189
# def remove_flags(self, f):
@@ -303,8 +323,8 @@ def run(self):
303323
bufline = prompt(cline, history=HISTORY, vi_mode=self.vimode)
304324
bufline = list(filter(None, bufline.split(' ')))
305325
bufline = list(map(lambda b: b.replace(';',' '), bufline))
306-
elif self.remote:
307-
pass
326+
# elif self.remote:
327+
# pass # not yet implemented
308328
else:
309329
assert False
310330

@@ -655,7 +675,8 @@ def run(self):
655675
# separate into chunks based on column width
656676
cells = [cells[i:i + self.columns] for i in range(0, len(cells), self.columns)]
657677
# log(cells)
658-
elif not self.separators:
678+
else:
679+
# elif not self.separators:
659680
# AUTOGENERATE CELL self.separators
660681
cells = fullline.split(' ')
661682
pos = 0
@@ -670,17 +691,19 @@ def run(self):
670691
# if fullline.startswith(' '):
671692
# cells = ['.'] + cells # dont filter first one
672693
autoseparate = True
673-
else:
674-
# SPLIT BASED ON self.separators
675-
s = 0
676-
seplen = len(self.separators)
677-
# log(seplen)
678-
pos = 0
679-
for i in range(seplen):
680-
cells.append(fullline[pos:self.separators[i]].strip())
681-
pos = self.separators[i]
682-
lastcell = fullline[pos:].strip()
683-
if lastcell: cells.append(lastcell)
694+
# else:
695+
# log('Track separators are no longer supported.')
696+
# assert False
697+
# # SPLIT BASED ON self.separators
698+
# s = 0
699+
# seplen = len(self.separators)
700+
# # log(seplen)
701+
# pos = 0
702+
# for i in range(seplen):
703+
# cells.append(fullline[pos:self.separators[i]].strip())
704+
# pos = self.separators[i]
705+
# lastcell = fullline[pos:].strip()
706+
# if lastcell: cells.append(lastcell)
684707

685708
# make sure active tracks get empty cell
686709
len_cells = len(cells)

0 commit comments

Comments
 (0)