Skip to content

Commit 9ce2e54

Browse files
committed
small progress on plugin system, print->out, -T
1 parent bca32d7 commit 9ce2e54

File tree

5 files changed

+82
-39
lines changed

5 files changed

+82
-39
lines changed

textbeat/__main__.py

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@
55
66
Examples:
77
textbeat shell
8+
textbeat -T start tutorial
89
textbeat song.txbt play song
910
1011
Usage:
11-
textbeat [--dev=<device> | --midi=<fn> | --ring | --follow --stdin] [-aeftnpsrxhvL] [SONGNAME]
12-
textbeat [+RANGE] [--dev=<device> | --midi=<fn> | --ring | --follow | --stdin] [-aeftnpsrxhvL] [SONGNAME]
12+
textbeat [--dev=<device>] [--midi=<fn>] [--ring] [--follow] [--stdin] [-adeftnpsrxhvL] [INPUT]
13+
textbeat [+RANGE] [--dev=<device> | --midi=<fn> | --ring | --follow | --stdin] [-adeftnpsrxhvL] [INPUT]
14+
textbeat [-rT]
1315
textbeat -c [COMMANDS ...]
1416
textbeat -l [LINE_CONTENT ...]
1517
@@ -26,8 +28,8 @@
2628
-f --flags comma-separated global flags
2729
-c execute commands sequentially
2830
-l execute commands simultaenously
29-
--stdin read from stdin instead of file
30-
-r --remote (STUB) remote/daemon mode, keep alive
31+
--stdin read entire file from stdin
32+
-r --remote (STUB) realtime remote (control through stdin/out)
3133
--ring don't mute midi on end
3234
-L --loop loop song
3335
--midi=<fn> generate midi file
@@ -112,8 +114,7 @@ def main():
112114
elif arg == '--edit': pass
113115
elif arg == '-l': player.cmdmode = 'l'
114116
elif arg == '-c': player.cmdmode = 'c'
115-
elif arg == '-T':
116-
player.tutorial = Tutorial(player)
117+
elif arg == '-T': player.tutorial = Tutorial(player)
117118
elif arg =='--flags':
118119
vals = val.split(',')
119120
player.add_flags(map(player.FLAGS.index, vals))
@@ -124,10 +125,10 @@ def main():
124125
player.buf = ' '.join(ARGS['LINE_CONTENT']).split(';') # ;
125126
elif player.cmdmode=='c':
126127
player.buf = ' '.join(ARGS['COMMANDS']).split(' ') # spaces
127-
else: # mode n
128+
elif not player.tutorial: # mode n
128129
# if len(sys.argv)>=2:
129130
# FN = sys.argv[-1]
130-
FN = ARGS['SONGNAME']
131+
FN = ARGS['INPUT']
131132
from_stdin = False
132133
if FN=='-' or ARGS['--stdin']:
133134
FN = 0 # TEMP: doesnt work with py2
@@ -175,17 +176,17 @@ def main():
175176

176177
pygame.midi.init()
177178
if pygame.midi.get_count()==0:
178-
print('No midi devices found.')
179+
error('No midi devices found.')
179180
sys.exit(1)
180181
dev = -1
181182

182183
# if player.showtext:
183184
# for i in range(pygame.midi.get_count()):
184-
# print(pygame.midi.get_device_info(i))
185+
# log(pygame.midi.get_device_info(i))
185186

186187
DEVS = get_defs()['dev']
187188
if player.showtext:
188-
print('MIDI Devices:')
189+
log('MIDI Devices:')
189190
portnames = []
190191
breakall = False
191192
firstpass = True
@@ -196,7 +197,7 @@ def main():
196197
if port[3]!=1:
197198
continue
198199
if player.showtext:
199-
print(' '*4 + portname)
200+
log(' '*4 + portname)
200201
if player.portname:
201202
if player.portname.lower() in portname.lower():
202203
player.portname = portname
@@ -224,7 +225,7 @@ def main():
224225
# # continue
225226
# portname = port[1].decode('utf-8')
226227
# if player.showtext:
227-
# print(' '*4 + portname)
228+
# log(' '*4 + portname)
228229
# if player.portname:
229230
# if player.portname.lower() in portname.lower():
230231
# player.portname = portname
@@ -238,7 +239,7 @@ def main():
238239
# break
239240
# portnames += [portname]
240241
if player.showtext:
241-
print('')
242+
log('')
242243

243244
if dev == -1:
244245
dev = pygame.midi.get_default_output_id()

textbeat/defs.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,9 @@ def set_print(b):
132132
global PRINT
133133
PRINT = b
134134

135+
def out(msg):
136+
if PRINT:
137+
print(msg)
135138
def log(msg):
136139
if PRINT:
137140
print(msg)

textbeat/player.py

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
# TODO: This file includes code prototype that will be reorganized into
2-
# other modules
1+
# TODO: This player modulde includes parser and player prototype code
2+
# that may eventually be reorganized into separate modules
33

44
from .defs import *
55

@@ -138,7 +138,7 @@ def init(self):
138138
embedded_fn = row[1:]
139139
embedded_file = []
140140

141-
# print(self.embedded_files.keys())
141+
# out(self.embedded_files.keys())
142142

143143
def refresh_devices(self):
144144
# determine output device support and load external programs
@@ -149,9 +149,9 @@ def refresh_devices(self):
149149
for dev in self.devices:
150150
if not supports(dev):
151151
if dev!='auto':
152-
print('Device not supported by system: ' + dev)
152+
out('Device not supported by system: ' + dev)
153153
else:
154-
print('Loading instrument presets requires Carla.')
154+
out('Loading instrument presets requires Carla.')
155155
assert False
156156
try:
157157
support_init[dev](self.rack)
@@ -204,15 +204,15 @@ def follow(self):
204204
if self.startrow==-1 and self.canfollow:
205205
cursor = self.row + 1
206206
if cursor != self.last_follow:
207-
print(cursor)
207+
out(cursor)
208208
self.last_cursor = cursor
209-
# print(self.rowno[self.row])
209+
# out(self.rowno[self.row])
210210

211211
def pause(self):
212212
try:
213213
for ch in self.tracks[:self.tracks_active]:
214214
ch.release_all(True)
215-
print('')
215+
out('')
216216
input('PAUSED: Press ENTER to resume. Press Ctrl-C To quit.')
217217
except:
218218
return False
@@ -351,7 +351,7 @@ def run(self):
351351
self.row += 1
352352
continue
353353

354-
# TODO: global 'silent' commands (doesn't take time)
354+
# TODO: global 'silent' commands (doesn't consume time)
355355
if self.line.startswith('%'):
356356
self.line = self.line[1:].strip() # remove % and spaces
357357
for tok in self.line.split(' '):
@@ -407,7 +407,7 @@ def run(self):
407407
elif op=='-':
408408
if var=='K':
409409
self.transpose -= note_offset(val)
410-
print(note_offset(val))
410+
out(note_offset(val))
411411
# elif var=='O': self.octave -= int(1 if val=='-' else val)
412412
elif var=='T': self.tempo -= max(0,float(val))
413413
elif var in 'GX': self.grid -= max(0,float(val))
@@ -505,7 +505,7 @@ def run(self):
505505
# self.transpose = 0
506506

507507
except NoSuchScale:
508-
print(FG.RED + 'No such scale.')
508+
out(FG.RED + 'No such scale.')
509509
pass
510510
else: assert False # no such var
511511
else: assert False # no such op
@@ -677,6 +677,7 @@ def run(self):
677677
ch = self.tracks[cell_idx]
678678
fullcell = cell[:]
679679
ignore = False
680+
skipcell = False
680681

681682
# if self.instrument != ch.instrument:
682683
# self.player.set_instrument(ch.instrument)
@@ -841,6 +842,9 @@ def run(self):
841842
c = int(c)
842843
if c == 0:
843844
ignore = True
845+
# TODO: allow zero if only if fretting mode
846+
# skipcell = True
847+
cell = cell[1:]
844848
break
845849
# n = 1
846850
# break
@@ -999,7 +1003,7 @@ def run(self):
9991003

10001004
num,ct = peel_uint(tok[cut+1:])
10011005
if ct:
1002-
print(num)
1006+
out(num)
10031007
cut += ct
10041008
cut -= 2 # remove "no"
10051009
chordname = chordname[:-2] # cut "no
@@ -1033,9 +1037,9 @@ def run(self):
10331037
# log(chordname)
10341038
# don't include tuplet in chordname
10351039
if 'add' in chordname:
1036-
# print(chordname)
1040+
# out(chordname)
10371041
addtoks = chordname.split('add')
1038-
# print(addtoks)
1042+
# out(addtoks)
10391043
chordname = addtoks[0]
10401044
addnotes = addtoks[1:]
10411045

@@ -1128,7 +1132,6 @@ def run(self):
11281132
ignore = False # reenable default root if chord was w/o note name
11291133
continue
11301134
else:
1131-
# log('not chord, treat as note')
11321135
pass
11331136
# assert False # not a chord, treat as note
11341137
# break
@@ -1146,6 +1149,7 @@ def run(self):
11461149

11471150
slashnotes[0].append(n + chord_root-1)
11481151

1152+
11491153
if expanded:
11501154
if not chord_notes:
11511155
# next chord
@@ -1192,10 +1196,13 @@ def run(self):
11921196
# ch.strings = notes
11931197
# notes = []
11941198

1199+
# 'ignore' means do outer break
11951200
if ignore:
11961201
allnotes = []
11971202
notes = []
1198-
1203+
# if skipcell: # 0 or something weird, completely skip line
1204+
# break
1205+
11991206
# save the intended notes since since scheduling may drop some
12001207
# during control phase
12011208
allnotes = notes
@@ -1595,7 +1602,7 @@ def run(self):
15951602
if not (not arppattern and cell.startswith(':')) or\
15961603
(arppattern and cell.startswith('|')):
15971604
break
1598-
print(cell[1:])
1605+
out(cell[1:])
15991606
num,ct = peel_int(cell[1:],1)
16001607
if not ct:
16011608
break
@@ -1623,8 +1630,8 @@ def run(self):
16231630
denom = 1 << i
16241631
if denom > num:
16251632
break
1626-
# print('denom' + str(denom))
1627-
# print('num ' + str(num))
1633+
# out('denom' + str(denom))
1634+
# out('num ' + str(num))
16281635
ch.note_spacing = denom/float(num) # !
16291636
ch.tuplet_count = int(num)
16301637
ch.tuplet_offset = 0.0

textbeat/support.py

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,35 @@
1-
# TODO: eventually: scan and load plugins
21
from .defs import *
32
from shutilwhich import which
43
import tempfile, shutil
54
# from xml.dom import minidom
65
ARGS = get_args()
76
SUPPORT = set(['midi'])
8-
SUPPORT_ALL = set(['carla','midi', 'fluidsynth']) # gme,mpe,sonicpi,supercollider,csound
7+
SUPPORT_ALL = set(['carla', 'midi', 'fluidsynth', 'soundfonts']) # gme,mpe,sonicpi,supercollider,csound
8+
MIDI = True
9+
SOUNDFONTS = False # TODO: make this a SupportPlugin ref
10+
AUTO = False
911
auto_inited = False
12+
13+
# TODO: eventually: scan and load plugins
14+
15+
class PluginType:
16+
NONE = 0
17+
AUTO = 1
18+
SOUNDFONTS = 2
19+
20+
class Plugin:
21+
def __init__(self, name, typ):
22+
self.name = name
23+
self.type = typ
24+
def register(self):
25+
pass
26+
27+
SUPPORT_PLUGINS = {}
28+
1029
if which('carla'):
1130
SUPPORT.add('carla')
1231
SUPPORT.add('auto') # auto generate
32+
AUTO = True
1333
auto_inited = True
1434

1535
# if which('scsynth'):
@@ -27,7 +47,12 @@
2747

2848
try:
2949
if which('fluidsynth'):
50+
import fluidsynth # https://github.com/flipcoder/pyfluidsynth
3051
SUPPORT.add('fluidsynth')
52+
SUPPORT.add('soundfonts')
53+
SOUNDFONTS = True
54+
except AttributeError:
55+
error("pyFluidSynth AttributeError detected. Use this pyFluidSynth version: https://github.com/flipcoder/pyfluidsynth")
3156
except ImportError:
3257
pass
3358

@@ -108,7 +133,7 @@ def carla_init(gen):
108133
else:
109134
proj = fn.split('.')[0]+'.carxp'
110135
if os.path.exists(proj):
111-
print(proj)
136+
log(proj)
112137
carla_proc = subprocess.Popen(['carla',proj], stdout=subprocess.PIPE, stderr=subprocess.PIPE) # '--nogui',
113138
elif not gen:
114139
log('To load a Carla project headless, create a \'%s\' file.' % proj)
@@ -176,6 +201,13 @@ def bgproc_run(con):
176201
# BGPROC = Process(target=bgproc_run, args=(child,))
177202
# BGPROC.start()
178203

204+
def supports_soundfonts():
205+
return SOUNDFONTS
206+
def supports_auto():
207+
return AUTO
208+
def supports(tech):
209+
return tech in SUPPORT
210+
179211
def support_stop():
180212
global carla_temp_proj
181213
if carla_temp_proj:

textbeat/track.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ def arp_next(self, stop_infinite=True):
340340
# if not self.arp_enabled:
341341
# self.arp_note = None
342342
# return False
343-
# print(self.arp_idx + 1)
343+
# out(self.arp_idx + 1)
344344
if self.arp_notes_left != -1 or stop_infinite:
345345
if self.arp_notes_left != -1:
346346
self.arp_notes_left = max(0, self.arp_notes_left - 1)
@@ -374,7 +374,7 @@ def tuplet_next(self):
374374
delay = self.tuplet_offset
375375
self.tuplet_offset += self.note_spacing - 1.0
376376
# if self.tuplet_offset >= 1.0 - EPSILON:
377-
# print('!!!')
377+
# out('!!!')
378378
# self.tuplet_offset = 0.0
379379
self.tuplet_count -= 1
380380
if not self.tuplet_count:
@@ -383,7 +383,7 @@ def tuplet_next(self):
383383
# self.tuplet_stop()
384384
# if feq(delay,1.0):
385385
# return 0.0
386-
# print(delay)
386+
# out(delay)
387387
return delay
388388
def tuplet_stop(self):
389389
self.tuplets = False

0 commit comments

Comments
 (0)