2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
# parse.py
|
|
|
|
|
|
|
|
"""
|
|
|
|
This module is an integeral part of the program
|
|
|
|
MMA - Musical Midi Accompaniment.
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
Bob van der Poel <bob@mellowood.ca>
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
This module does all file parsing. Most commands
|
|
|
|
are passed to the track classes; however, things
|
|
|
|
like TIME, SEQRND, etc. which just set global flags
|
|
|
|
are completely handled here.
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
import os
|
|
|
|
import random
|
|
|
|
import copy
|
|
|
|
|
|
|
|
import gbl
|
2009-05-17 22:34:44 +00:00
|
|
|
from MMA.common import *
|
|
|
|
|
2006-11-10 08:07:56 +00:00
|
|
|
import MMA.notelen
|
|
|
|
import MMA.chords
|
|
|
|
import MMA.file
|
|
|
|
import MMA.midi
|
|
|
|
import MMA.midiIn
|
2009-05-17 22:34:44 +00:00
|
|
|
import MMA.grooves
|
|
|
|
import MMA.docs
|
2006-11-10 08:07:56 +00:00
|
|
|
import MMA.auto
|
|
|
|
import MMA.translate
|
|
|
|
import MMA.patSolo
|
|
|
|
import MMA.mdefine
|
|
|
|
import MMA.volume
|
2009-05-17 22:34:44 +00:00
|
|
|
import MMA.seqrnd
|
|
|
|
import MMA.patch
|
|
|
|
|
|
|
|
import gbl
|
|
|
|
|
|
|
|
from MMA.common import *
|
|
|
|
from MMA.lyric import lyric
|
|
|
|
from MMA.macro import macros
|
|
|
|
from MMA.alloc import trackAlloc
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
lastChord = None # tracks last chord for "/ /" data lines.
|
|
|
|
|
|
|
|
beginData = [] # Current data set by a BEGIN statement
|
2007-04-29 06:47:40 +00:00
|
|
|
beginPoints = [] # since BEGINs can be nested, we need ptrs for backing out of BEGINs
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2009-05-17 22:34:44 +00:00
|
|
|
gmagic = 9988 # magic name for groove saved with USE
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
|
2006-11-10 08:07:56 +00:00
|
|
|
""" This table is passed to the track classes. It has
|
|
|
|
an instance for each chord in the current bar.
|
|
|
|
"""
|
|
|
|
|
|
|
|
class CTable:
|
2007-04-29 06:47:40 +00:00
|
|
|
chord = None # A pointer to the chordNotes structures
|
|
|
|
chordZ = None # set if chord is tacet
|
|
|
|
arpeggioZ = None # set if arpeggio is tacet
|
|
|
|
walkZ = None # set if walking bass is tacet
|
|
|
|
drumZ = None # set if drums are tacet
|
|
|
|
bassZ = None # set if bass is tacet
|
|
|
|
scaleZ = None # set if scale track is tacet
|
|
|
|
ariaZ = None # set if aria track is tacet
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
def __init__(self, offset):
|
|
|
|
self.offset=offset
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
########################################
|
|
|
|
# File processing. Mostly jumps to pats
|
|
|
|
########################################
|
|
|
|
|
|
|
|
|
|
|
|
def parseFile(n):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Open and process a file. Errors exit. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
fp=gbl.inpath
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
f=MMA.file.ReadFile(n)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
parse(f)
|
|
|
|
gbl.inpath=fp
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if gbl.debug:
|
|
|
|
print "File '%s' closed." % n
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def parse(inpath):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Process a mma input file. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
global beginData, lastChord
|
2009-05-17 22:34:44 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.inpath = inpath
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
curline = None
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
while 1:
|
|
|
|
curline = inpath.read()
|
2009-05-17 22:34:44 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if curline == None:
|
|
|
|
MMA.docs.docDump()
|
|
|
|
break
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
l = macros.expand(curline)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Handle BEGIN and END here. This is outside of the Repeat/End
|
|
|
|
and variable expand loops so SHOULD be pretty bullet proof.
|
|
|
|
Note that the beginData stuff is global to this module ... the
|
|
|
|
Include/Use directives check to make sure we're not doing that
|
|
|
|
inside a Begin/End.
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
beginData[] is a list which we append to as more Begins are
|
|
|
|
encountered.
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
The placement here is pretty deliberate. Variable expand comes
|
2009-05-17 22:34:44 +00:00
|
|
|
later so you can't macroize BEGIN ... I think this makes sense.
|
|
|
|
|
|
|
|
The tests for 'begin', 'end' and the appending of the current
|
|
|
|
begin[] stuff have to be here, in this order.
|
2007-04-29 06:47:40 +00:00
|
|
|
"""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2009-05-17 22:34:44 +00:00
|
|
|
action=l[0].upper() # 1st arg in line
|
|
|
|
|
|
|
|
if action == 'BEGIN':
|
2007-04-29 06:47:40 +00:00
|
|
|
if not l:
|
|
|
|
error("Use: Begin STUFF")
|
|
|
|
beginPoints.append(len(beginData))
|
|
|
|
beginData.extend(l[1:])
|
|
|
|
continue
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2009-05-17 22:34:44 +00:00
|
|
|
if action == 'END':
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(l) > 1:
|
|
|
|
error("No arguments permitted for END")
|
|
|
|
if not beginData:
|
|
|
|
error("No 'BEGIN' for 'END'")
|
|
|
|
beginData=beginData[:beginPoints.pop(-1)]
|
|
|
|
continue
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if beginData:
|
|
|
|
l = beginData + l
|
2009-05-17 22:34:44 +00:00
|
|
|
action = l[0].upper()
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2009-05-17 22:34:44 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if gbl.showExpand and action !='REPEAT':
|
|
|
|
print l
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
# If the command is in the simple function table, jump & loop.
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if action in simpleFuncs:
|
|
|
|
simpleFuncs[action](l[1:])
|
|
|
|
continue
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
""" We have several possibilities ...
|
|
|
|
1. The command is a valid assigned track name,
|
|
|
|
2. The command is a valid track name, but needs to be
|
|
|
|
dynamically allocated,
|
|
|
|
3. It's really a chord action
|
|
|
|
"""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not action in gbl.tnames:
|
|
|
|
trackAlloc(action, 0) # ensure that track is allocated
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if action in gbl.tnames: # BASS/DRUM/APEGGIO/CHORD
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
name = action
|
|
|
|
if len(l) < 2:
|
|
|
|
error("Expecting argument after '%s'" % name)
|
|
|
|
action = l[1].upper()
|
2009-05-17 22:34:44 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if action in trackFuncs:
|
|
|
|
trackFuncs[action](name, l[2:])
|
|
|
|
else:
|
|
|
|
error ("Don't know '%s'" % curline)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
continue
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
### Gotta be a chord data line!
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
""" A data line can have an optional bar number at the start
|
|
|
|
of the line. Makes debugging input easier. The next
|
|
|
|
block strips leading integers off the line. Note that
|
|
|
|
a line number on a line by itself it okay.
|
|
|
|
"""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2009-05-17 22:34:44 +00:00
|
|
|
if action.isdigit(): # isdigit() matches '1', '1234' but not '1a'!
|
2007-04-29 06:47:40 +00:00
|
|
|
l = l[1:]
|
|
|
|
if not l: # ignore empty lines
|
|
|
|
continue
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
""" A bar can have an optional repeat count. This must
|
|
|
|
be at the end of bar in the form '* xx'.
|
|
|
|
"""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(l)>1 and l[-2]=='*':
|
|
|
|
rptcount = stoi(l[-1], "Expecting integer after '*'")
|
|
|
|
l=l[:-2]
|
|
|
|
else:
|
|
|
|
rptcount = 1
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Extract solo(s) from line ... this is anything in {}s.
|
|
|
|
The solo data is pushed into RIFFs and discarded from
|
|
|
|
the current line.
|
|
|
|
"""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
l = ' '.join(l)
|
|
|
|
l = MMA.patSolo.extractSolo(l, rptcount)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2009-05-17 22:34:44 +00:00
|
|
|
""" Set lyrics from [stuff] in the current line.
|
|
|
|
NOTE: lyric.extract() inserts previously created
|
|
|
|
data from LYRICS SET and inserts the chord names
|
|
|
|
if that flag is active.
|
2007-04-29 06:47:40 +00:00
|
|
|
"""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
l, lyrics = lyric.extract(l, rptcount)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2009-05-17 22:34:44 +00:00
|
|
|
l = l.split()
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
""" At this point we have only chord info. A number
|
|
|
|
of sanity checks are made:
|
|
|
|
1. Make sure there is some chord data,
|
|
|
|
2. Ensure the correct number of chords.
|
|
|
|
"""
|
2009-05-17 22:34:44 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not l:
|
|
|
|
error("Expecting music (chord) data. Even lines with\n"
|
|
|
|
" lyrics or solos still need a chord")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
i = gbl.QperBar - len(l)
|
2009-05-17 22:34:44 +00:00
|
|
|
if i < 0:
|
2007-04-29 06:47:40 +00:00
|
|
|
error("Too many chords in line. Max is %s, not %s" %
|
|
|
|
(gbl.QperBar, len(l) ) )
|
|
|
|
if i:
|
|
|
|
l.extend( ['/'] * i )
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
""" We now have a valid line. It'll look something like:
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2009-05-17 22:34:44 +00:00
|
|
|
['Cm', '/', 'z', 'F#'] or ['C', '/', '/', '/' ]
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
For each bar we create a ctable structure. This is just
|
|
|
|
a list of CTables, one for each beat division.
|
|
|
|
Each entry has the offset (in midi ticks), chordname, etc.
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
Special processing in needed for 'z' options in chords. A 'z' can
|
|
|
|
be of the form 'CHORDzX', 'z!' or just 'z'.
|
|
|
|
"""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
beat = 0
|
|
|
|
ctable = []
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
for c in l:
|
|
|
|
if c == '/':
|
|
|
|
if not lastChord:
|
|
|
|
error("A chord has to be set before you can use a '/'")
|
|
|
|
c = lastChord
|
|
|
|
else:
|
|
|
|
lastChord = c
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
ctable.append(parseZs(c, beat))
|
|
|
|
beat += 1
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
# Create MIDI data for the bar
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2009-05-17 22:34:44 +00:00
|
|
|
for rpt in range(rptcount): # for each bar in the repeat count ( Cm * 3)
|
|
|
|
|
|
|
|
""" Handle global (de)cresc by popping a new volume off stack. """
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if MMA.volume.futureVol:
|
|
|
|
MMA.volume.volume = MMA.volume.futureVol.pop(0)
|
2009-05-17 22:34:44 +00:00
|
|
|
if MMA.volume.futureVol:
|
|
|
|
MMA.volume.nextVolume = MMA.volume.futureVol[0]
|
|
|
|
else:
|
|
|
|
MMA.volume.nextVolume = None
|
|
|
|
|
|
|
|
|
|
|
|
""" Set up for rnd seq. This may set the current seq point. If return
|
|
|
|
is >=0 then we're doing track rnd.
|
|
|
|
"""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2009-05-17 22:34:44 +00:00
|
|
|
rsq, seqlist = MMA.seqrnd.setseq()
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Process each track. It is important that the track classes
|
|
|
|
are written so that the ctable passed to them IS NOT MODIFIED.
|
|
|
|
This applies especially to chords. If the track class changes
|
|
|
|
the chord, then restore it before returning!!!
|
|
|
|
"""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
for a in gbl.tnames.values():
|
2009-05-17 22:34:44 +00:00
|
|
|
if rsq >= 0:
|
|
|
|
seqSave = gbl.seqCount
|
|
|
|
if a.name in seqlist: # for seqrnd with tracklist
|
|
|
|
gbl.seqCount = rsq
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
a.bar(ctable) ## process entire bar!
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2009-05-17 22:34:44 +00:00
|
|
|
if rsq >= 0:
|
|
|
|
gbl.seqCount = seqSave
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
# Adjust counters
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2009-05-17 22:34:44 +00:00
|
|
|
gbl.totTime += float(gbl.QperBar) / gbl.tempo
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.barNum += 1
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if gbl.barNum > gbl.maxBars:
|
|
|
|
error("Capacity exceeded. Maxbar setting is %s. Use -m option"
|
|
|
|
% gbl.maxBars)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tickOffset += (gbl.QperBar * gbl.BperQ)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.seqCount = (gbl.seqCount+1) % gbl.seqSize
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2009-05-17 22:34:44 +00:00
|
|
|
MMA.grooves.nextGroove() # using groove list? Advance.
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
# Enabled with the -r command line option
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if gbl.showrun:
|
|
|
|
print "%3d:" % gbl.barNum,
|
|
|
|
for c in l:
|
|
|
|
print c,
|
|
|
|
if lyrics:
|
|
|
|
print lyrics,
|
|
|
|
print
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def parseZs(c, beat):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Parse a chord in a barline, create Ctable and strips 'z's.
|
|
|
|
|
|
|
|
This is called only from the main parser, but it's
|
|
|
|
complicated (ugly) enough to have its own function.
|
|
|
|
"""
|
|
|
|
|
|
|
|
ctab = CTable(beat * gbl.BperQ)
|
|
|
|
|
|
|
|
if 'z' in c:
|
|
|
|
c, r = c.split('z', 1) # chord name/track mute
|
|
|
|
|
|
|
|
if not c:
|
|
|
|
if r=='!': # mute all for 'z!'
|
|
|
|
r='DCAWBSR'
|
|
|
|
c='z' # dummy chord name
|
|
|
|
elif not r: # mute all tracks except Drum 'z'
|
|
|
|
r='CBAWSR'
|
|
|
|
c='z'
|
|
|
|
|
|
|
|
else:
|
|
|
|
error("To mute individual tracks you must "
|
|
|
|
"use a chord/z combination not '%s'" % r)
|
|
|
|
|
|
|
|
else: # illegal construct -- 'Cz!'
|
|
|
|
if r=='!':
|
|
|
|
error("'%sz!' is illegal. 'z!' mutes all tracks "
|
|
|
|
"so you can't include the chord" % c)
|
|
|
|
|
|
|
|
elif not r:
|
|
|
|
error("'%sz' is illegal. You must specify tracks "
|
|
|
|
"if you use a chord" % c )
|
|
|
|
|
|
|
|
for v in r:
|
|
|
|
if v == 'C':
|
|
|
|
ctab.chordZ = 1
|
|
|
|
elif v == 'B':
|
|
|
|
ctab.bassZ = 1
|
|
|
|
elif v == 'A':
|
|
|
|
ctab.arpeggioZ = 1
|
|
|
|
elif v == 'W':
|
|
|
|
ctab.walkZ = 1
|
|
|
|
elif v == 'D':
|
|
|
|
ctab.drumZ = 1
|
|
|
|
elif v == 'S':
|
|
|
|
ctab.scaleZ = 1
|
|
|
|
elif v == 'R':
|
|
|
|
ctab.ariaZ = 1
|
|
|
|
|
|
|
|
else:
|
|
|
|
error("Unknown voice '%s' for rest in '%s'" % (v,r))
|
|
|
|
|
|
|
|
ctab.chord = MMA.chords.ChordNotes(c)
|
|
|
|
|
|
|
|
return ctab
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
##################################################################
|
|
|
|
|
|
|
|
def allTracks(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Apply track to all tracks. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
allTypes = ('BASS', 'CHORD', 'ARPEGGIO', 'SCALE', 'DRUM', 'WALK', 'MELODY', 'SOLO')
|
|
|
|
ttypes = []
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(ln) < 1:
|
|
|
|
error("AllTracks: argument (track?) required")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
i = 0
|
|
|
|
while i < len(ln) and ln[i].upper() in allTypes:
|
|
|
|
ttypes.append(ln[i].upper())
|
|
|
|
i += 1
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if ttypes == []:
|
|
|
|
ttypes = allTypes
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if i>=len(ln):
|
|
|
|
error("AllTracks: Additional argument (command?) required")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
cmd = ln[i].upper()
|
|
|
|
args = i+1
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not cmd in trackFuncs:
|
|
|
|
error("AllTracks: command '%s' doen't exist" % cmd)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
for n in gbl.tnames:
|
|
|
|
if not gbl.tnames[n].vtype in ttypes:
|
|
|
|
continue
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
trackFuncs[cmd](n, ln[args:])
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
#######################################
|
|
|
|
# Do-nothing functions
|
|
|
|
|
|
|
|
def comment(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
pass
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
def repeatend(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
error("Repeatend/EndRepeat without Repeat")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
def repeatending(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
error("Repeatending without Repeat")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
def endmset(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
error("EndMset/MSetEnd without If")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
def ifend(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
error("ENDIF without IF")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
def ifelse(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
error("ELSE without IF")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#######################################
|
|
|
|
# Repeat/jumps
|
|
|
|
|
|
|
|
|
|
|
|
def repeat(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Repeat/RepeatEnd/RepeatEnding.
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
Read input until a RepeatEnd is found. The entire
|
|
|
|
chunk is pushed back into the input stream the
|
|
|
|
correct number of times. This accounts for endings and
|
|
|
|
nested repeats.
|
2007-04-29 06:47:40 +00:00
|
|
|
"""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
def repeatChunk():
|
|
|
|
q=[]
|
|
|
|
qnum=[]
|
|
|
|
nesting = 0
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
while 1:
|
|
|
|
l=gbl.inpath.read()
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not l:
|
|
|
|
error("EOF encountered processing Repeat")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
act=l[0].upper()
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if act=='REPEAT':
|
|
|
|
nesting += 1
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
elif act in ('REPEATEND', 'ENDREPEAT') and nesting:
|
|
|
|
nesting -= 1
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
elif act == 'REPEATENDING' and nesting:
|
|
|
|
pass
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
elif act in ('REPEATEND', 'ENDREPEAT', 'REPEATENDING'):
|
|
|
|
return (q, qnum, act, l[1:])
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
q.append(l)
|
|
|
|
qnum.append(gbl.lineno)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
stack=[]
|
|
|
|
stacknum=[]
|
|
|
|
main=[]
|
|
|
|
mainnum=[]
|
|
|
|
ending = 0
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if ln:
|
|
|
|
error("REPEAT takes no arguments")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
main, mainnum, act, l = repeatChunk()
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
while 1:
|
|
|
|
if act in ('REPEATEND', 'ENDREPEAT'):
|
|
|
|
if l:
|
2009-05-17 22:34:44 +00:00
|
|
|
l = macros.expand(l)
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(l) == 2 and l[0].upper() == 'NOWARN':
|
|
|
|
l=l[1:]
|
|
|
|
warn=0
|
|
|
|
else:
|
|
|
|
warn=1
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(l) != 1:
|
|
|
|
error("%s: Use [NoWarn] Count" % act)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
count=stoi(l[0], "%s takes an integer arg" % act)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if count == 2 and warn:
|
|
|
|
warning("%s count of 2 duplicates default. Did you mean 3 or more?" % act)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
elif count == 1 and warn:
|
|
|
|
warning("%s count of 1 means NO REPEAT" % act)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
elif count == 0 and warn:
|
|
|
|
warning("%s count of 0, Skipping entire repeated section" % act)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
elif count < 0:
|
|
|
|
error("%s count must be 0 or greater" % act)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
elif count > 10 and warn:
|
|
|
|
warning("%s is a large value for %s" % (count, act) )
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
else:
|
|
|
|
count=2
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ending:
|
|
|
|
count += 1
|
|
|
|
for c in range(count-1):
|
|
|
|
stack.extend(main)
|
|
|
|
stacknum.extend(mainnum)
|
|
|
|
gbl.inpath.push(stack, stacknum)
|
|
|
|
break
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
elif act == 'REPEATENDING':
|
|
|
|
ending = 1
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if l:
|
2009-05-17 22:34:44 +00:00
|
|
|
l = macros.expand(l)
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(l) == 2 and l[0].upper() == 'NOWARN':
|
|
|
|
warn=0
|
|
|
|
l=l[1:]
|
|
|
|
else:
|
|
|
|
warn=1
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(l) != 1:
|
|
|
|
error("REPEATENDING: Use [NoWarn] Count")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
count=stoi(l[0], "RepeatEnding takes an integer arg")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if count < 0:
|
|
|
|
error("RepeatEnding count must be postive, not '%s'" % count)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
elif count == 0 and warn:
|
|
|
|
warning("RepeatEnding count of 0, skipping section")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
elif count == 1 and warn:
|
|
|
|
warning("RepeatEnding count of 1 duplicates default")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
elif count > 10 and warn:
|
|
|
|
warning("%s is a large value for RepeatEnding" % count)
|
|
|
|
else:
|
|
|
|
count = 1
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
rpt, rptnum, act, l = repeatChunk()
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
for c in range(count):
|
|
|
|
stack.extend(main)
|
|
|
|
stacknum.extend(mainnum)
|
|
|
|
stack.extend(rpt)
|
|
|
|
stacknum.extend(rptnum)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
else:
|
|
|
|
error("Unexpected line in REPEAT")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
def goto(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(ln) != 1:
|
|
|
|
error("Usage: GOTO Label")
|
|
|
|
gbl.inpath.goto(ln[0].upper())
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
def eof(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.inpath.toEof()
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
#######################################
|
|
|
|
# Tempo/timing
|
|
|
|
|
|
|
|
|
|
|
|
def setTime(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set the 'time sig'.
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
We do restrict the time setting to the range of 1..12.
|
|
|
|
No particular reason, but we do need some limit? Certainly
|
|
|
|
it has to be greater than 0.
|
2007-04-29 06:47:40 +00:00
|
|
|
"""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(ln) != 1:
|
|
|
|
error("Use: Time N")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
n = stoi(ln[0], "Argument for time must be integer")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if n < 1 or n > 12:
|
|
|
|
error("Time (beats/bar) must be 1..12")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
# If no change, just ignore this.
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if gbl.QperBar != n:
|
|
|
|
gbl.QperBar = int(n)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
# Time changes zap all predfined sequences
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
for a in gbl.tnames.values():
|
|
|
|
a.clearSequence()
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def tempo(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set tempo. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln or len(ln) >2:
|
|
|
|
error("Use: Tempo [*,+,-]BperM [BARS]")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
# Get new value.
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
a = ln[0][0]
|
|
|
|
if a in "+-*":
|
|
|
|
v = stof(ln[0][1:], "Tempo expecting value for rate adjustment, not '%s'" % ln[0])
|
|
|
|
if a == '-':
|
|
|
|
v = gbl.tempo - v
|
|
|
|
elif a == '+':
|
|
|
|
v += gbl.tempo
|
|
|
|
elif a == '*':
|
|
|
|
v *= gbl.tempo
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
else:
|
|
|
|
v = stof(ln[0], "Tempo expecting rate, not '%s'" % ln[0])
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
# is this immediate or over time?
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(ln) == 1:
|
|
|
|
gbl.tempo = int(v)
|
|
|
|
gbl.mtrks[0].addTempo(gbl.tickOffset, gbl.tempo)
|
|
|
|
if gbl.debug:
|
|
|
|
print "Set Tempo to %s" % gbl.tempo
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
else: # Do a tempo change over bar count
|
|
|
|
bars = ln[1]
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
bars = stof(bars, "Expecting value, not %s" % bars )
|
|
|
|
numbeats = int(bars * gbl.QperBar)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if numbeats < 1:
|
|
|
|
error("Beat count must be greater than 1")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
# Vary the rate in the meta track
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
tincr = (v - gbl.tempo) / float(numbeats) # incr per beat
|
|
|
|
bstart = gbl.tickOffset # start
|
|
|
|
boff = 0
|
|
|
|
tempo = gbl.tempo
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
for n in range(numbeats):
|
|
|
|
tempo += tincr
|
|
|
|
if tempo:
|
|
|
|
gbl.mtrks[0].addTempo(bstart + boff, int(tempo))
|
|
|
|
boff += gbl.BperQ
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if tempo != v:
|
|
|
|
gbl.mtrks[0].addTempo(bstart + boff, int(v) )
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tempo = int(v)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if gbl.debug:
|
|
|
|
print "Set future Tempo to %s over %s beats" % \
|
|
|
|
( int(tempo), numbeats)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2009-05-17 22:34:44 +00:00
|
|
|
if gbl.tempo <=0:
|
|
|
|
error("Tempo setting must be greater than 0.")
|
|
|
|
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
def beatAdjust(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Delete or insert some beats into the sequence.
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
This just adjusts the current song position. Nothing is
|
|
|
|
lost or added to the actual file.
|
|
|
|
"""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(ln) != 1:
|
|
|
|
error("Use: BeatAdjust NN")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
adj = stof(ln[0], "Expecting a value (not %s) for BeatAdjust" % ln[0])
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tickOffset += int(adj * gbl.BperQ)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2009-05-17 22:34:44 +00:00
|
|
|
gbl.totTime += adj / gbl.tempo # adjust total time
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if gbl.debug:
|
|
|
|
print "BeatAdjust: inserted %s at bar %s." % (adj, gbl.barNum + 1)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def cut(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Insert a all-note-off into all tracks. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not len(ln):
|
|
|
|
ln=['0']
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(ln) != 1:
|
|
|
|
error("Use: Cut Offset")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Loop though all the tracks. Note that trackCut() checks
|
2006-11-10 08:07:56 +00:00
|
|
|
to make sure that there is a need to insert in specified track.
|
|
|
|
In this loop we create a list of channels as we loop though
|
|
|
|
all the tracks, skipping over any duplicate channels or
|
|
|
|
tracks with no channel assigned.
|
2007-04-29 06:47:40 +00:00
|
|
|
"""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
l=[]
|
|
|
|
for t in sorted(gbl.tnames.keys()):
|
|
|
|
c = gbl.tnames[t].channel
|
|
|
|
if not c or c in l:
|
|
|
|
continue
|
|
|
|
l.append(c)
|
|
|
|
trackCut(t, ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def fermata(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Apply a fermata timing to the specified beat. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(ln) != 3:
|
|
|
|
error("Use: Fermata 'offset' 'duration' 'adjustment'")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
offset = stof(ln[0], "Expecting a value (not '%s') "
|
|
|
|
"for Fermata Offset" % ln[0] )
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if offset < -gbl.QperBar or offset > gbl.QperBar:
|
|
|
|
warning("Fermata: %s is a large beat offset" % offset)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
dur = stof(ln[1], "Expecting a value (not '%s') for Fermata Duration" % ln[1])
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if dur <= 0:
|
|
|
|
error("Fermata duration must be greater than 0")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if dur > gbl.QperBar:
|
|
|
|
warning("Fermata: %s is a large duration" % dur)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
adj = stof(ln[2], "Expecting a value (not '%s') for Fermata Adjustment" % ln[2])
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if adj< 100:
|
|
|
|
warning("Fermata: Adjustment less than 100 is shortening beat value")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if adj == 100:
|
|
|
|
error("Fermata: using value of 100 makes no difference, must be an error")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
moff=int(gbl.tickOffset + (gbl.BperQ * offset))
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if moff < 0:
|
|
|
|
error("Fermata offset comes before track start")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.mtrks[0].addTempo(moff, int(gbl.tempo / (adj/100)) )
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
tickDur = int(gbl.BperQ * dur)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.mtrks[0].addTempo(moff + tickDur, gbl.tempo)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
# Clear out NoteOn events in all tracks
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if offset < 0:
|
|
|
|
start = moff + int(.05 * gbl.BperQ)
|
|
|
|
end = moff + tickDur - int(.05 * gbl.BperQ)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
for n, tr in gbl.mtrks.items():
|
|
|
|
if n <= 0: continue # skip meta track
|
|
|
|
tr.zapRangeTrack(start, end )
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if gbl.debug:
|
|
|
|
print "Fermata: Beat %s, Duration %s, Change %s, Bar %s" % \
|
|
|
|
(offset, dur, adj, gbl.barNum + 1)
|
|
|
|
if offset < 0:
|
|
|
|
print "\tNoteOn Events removed in tick range %s to %s" \
|
|
|
|
% (start, end)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#######################################
|
|
|
|
# File and I/O
|
|
|
|
|
|
|
|
def include(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Include a file. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
global beginData
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if beginData:
|
|
|
|
error("INCLUDE not permitted in Begin/End block")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(ln) != 1:
|
|
|
|
error("Use: Include FILE" )
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
fn = MMA.file.locFile(ln[0], gbl.incPath)
|
|
|
|
if not fn:
|
|
|
|
error("Could not find include file '%s'" % ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
else:
|
|
|
|
parseFile(fn)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def usefile(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Include a library file. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
global beginData
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if beginData:
|
|
|
|
error("USE not permitted in Begin/End block")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(ln) != 1:
|
|
|
|
error("Use: Use FILE")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
ln = ln[0]
|
|
|
|
fn = MMA.file.locFile(ln, gbl.libPath)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not fn:
|
|
|
|
error("Unable to locate library file '%s'" % ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
""" USE saves current state, just like defining a groove.
|
2006-11-10 08:07:56 +00:00
|
|
|
Here we use a magic number which can't be created with
|
|
|
|
a defgroove ('cause it's an integer). Save, read, restore.
|
2007-04-29 06:47:40 +00:00
|
|
|
"""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
slot = gmagic
|
2009-05-17 22:34:44 +00:00
|
|
|
MMA.grooves.grooveDefineDo(slot)
|
2007-04-29 06:47:40 +00:00
|
|
|
parseFile(fn)
|
2009-05-17 22:34:44 +00:00
|
|
|
MMA.grooves.grooveDo(slot)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
def mmastart(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
error ("Use: MMAstart FILE [file...]")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.mmaStart.extend(ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if gbl.debug:
|
|
|
|
print "MMAstart set to:",
|
|
|
|
printList(ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
def mmaend(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
error ("Use: MMAend FILE [file...]")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.mmaEnd.extend(ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if gbl.debug:
|
|
|
|
print "MMAend set to:",
|
|
|
|
printList(ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def setLibPath(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set the LibPath variable. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(ln) > 1:
|
|
|
|
error("Only one path can be entered for LibPath")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
f = os.path.expanduser(ln[0])
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if gbl.debug:
|
|
|
|
print "LibPath set to", f
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.libPath = f
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def setAutoPath(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set the autoPath variable. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(ln) > 1:
|
|
|
|
error("Only one path can be entered for AutoLibPath")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
f = os.path.expanduser(ln[0])
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
MMA.auto.grooveDir = {}
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
# To avoid conflicts, delete all existing grooves (current seq not effected)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2009-05-17 22:34:44 +00:00
|
|
|
MMA.grooves.glist = {}
|
|
|
|
MMA.grooves.lastGroove = ''
|
|
|
|
MMA.grooves.currentGroove = ''
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if gbl.debug:
|
|
|
|
print "AutoLibPath set to", f
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.autoLib = f
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def setIncPath(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set the IncPath variable. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(ln)>1:
|
|
|
|
error("Only one path is permitted in SetIncPath")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
f = os.path.expanduser(ln[0])
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if gbl.debug:
|
|
|
|
print "IncPath set to", f
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.incPath=f
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def setOutPath(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set the Outpath variable. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
gbl.outPath = ""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
elif len(ln) > 1:
|
|
|
|
error ("Use: SetOutPath PATH")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
else:
|
|
|
|
gbl.outPath = os.path.expanduser(ln[0])
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2009-05-17 22:34:44 +00:00
|
|
|
if gbl.debug:
|
|
|
|
print "OutPath set to", gbl.outPath
|
|
|
|
|
|
|
|
|
|
|
|
def setMidiPlayer(ln):
|
|
|
|
""" Set the MIDI file player (used with -P). """
|
|
|
|
|
|
|
|
if len(ln) != 1:
|
|
|
|
error("Use: MidiPlayer <program name>")
|
|
|
|
|
|
|
|
gbl.midiPlayer = ln[0]
|
|
|
|
|
|
|
|
if gbl.debug:
|
|
|
|
print "MidiPlayer set to", gbl.MidiPlayer
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
#######################################
|
|
|
|
# Sequence
|
|
|
|
|
|
|
|
def seqsize(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set the length of sequences. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(ln) !=1:
|
|
|
|
error("Usage 'SeqSize N'")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
n = stoi(ln[0], "Argument for SeqSize must be integer")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2009-05-17 22:34:44 +00:00
|
|
|
if n < 1:
|
|
|
|
error("SeqSize: sequence size must be 1 or greater, not '%s'." % n)
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
# Setting the sequence size always resets the seq point
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.seqCount = 0
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Now set the sequence size for each track. The class call
|
|
|
|
will expand/contract existing patterns to match the new
|
|
|
|
size.
|
|
|
|
"""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if n != gbl.seqSize:
|
|
|
|
gbl.seqSize = n
|
|
|
|
for a in gbl.tnames.values():
|
|
|
|
a.setSeqSize()
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2009-05-17 22:34:44 +00:00
|
|
|
MMA.seqrnd.seqRndWeight = seqBump(MMA.seqrnd.seqRndWeight)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if gbl.debug:
|
|
|
|
print "Set SeqSize to ", n
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def seq(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set the sequence point. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(ln) == 0:
|
|
|
|
s = 0
|
|
|
|
elif len(ln)==1:
|
|
|
|
s = stoi(ln[0], "Expecting integer value after SEQ")
|
|
|
|
else:
|
|
|
|
error("Use: SEQ or SEQ NN to reset seq point")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if s > gbl.seqSize:
|
|
|
|
error("Sequence size is '%d', you can't set to '%d'" %
|
|
|
|
(gbl.seqSize, s))
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if s==0:
|
|
|
|
s=1
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if s<0:
|
|
|
|
error("Seq parm must be greater than 0, not %s", s)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.seqCount = s-1
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2009-05-17 22:34:44 +00:00
|
|
|
if MMA.seqrnd.seqRnd[0] == 1:
|
2007-04-29 06:47:40 +00:00
|
|
|
warning("SeqRnd has been disabled by a Seq command")
|
2009-05-17 22:34:44 +00:00
|
|
|
MMA.seqrnd.seqRnd = [0]
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def seqClear(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Clear all sequences (except SOLO tracks). """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if ln:
|
|
|
|
error ("Use: 'SeqClear' with no args")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
for n in gbl.tnames.values():
|
|
|
|
if n.vtype != "SOLO":
|
|
|
|
n.clearSequence()
|
|
|
|
MMA.volume.futureVol = []
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2009-05-17 22:34:44 +00:00
|
|
|
MMA.seqrnd.setSeqRndWeight(['1'])
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def restart(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Restart all tracks to almost-default condidions. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if ln:
|
|
|
|
error ("Use: 'Restart' with no args")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
for n in gbl.tnames.values():
|
|
|
|
n.restart()
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
#######################################
|
|
|
|
# Midi
|
|
|
|
|
|
|
|
def midiMarker(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Parse off midi marker. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(ln) == 2:
|
|
|
|
offset = stof(ln[0])
|
|
|
|
msg = ln[1]
|
|
|
|
elif len(ln) == 1:
|
|
|
|
offset = 0
|
|
|
|
msg = ln[0]
|
|
|
|
else:
|
|
|
|
error("Usage: MidiMark [offset] Label")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
offset = int(gbl.tickOffset + (gbl.BperQ * offset))
|
|
|
|
if offset < 0:
|
|
|
|
error("MidiMark offset points before start of file")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.mtrks[0].addMarker(offset, msg)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def rawMidi(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Send hex bytes as raw midi stream. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
mb=''
|
|
|
|
for a in ln:
|
|
|
|
a=stoi(a)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if a<0 or a >0xff:
|
|
|
|
error("All values must be in the range "
|
|
|
|
"0 to 0xff, not '%s'" % a)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
mb += chr(a)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.mtrks[0].addToTrack(gbl.tickOffset, mb)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if gbl.debug:
|
|
|
|
print "Inserted raw midi in metatrack: ",
|
|
|
|
for b in mb:
|
|
|
|
print '%02x' % ord(b),
|
|
|
|
print
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def mdefine(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set a midi seq pattern. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
error("MDefine needs arguments")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
name = ln[0]
|
|
|
|
if name.startswith('_'):
|
|
|
|
error("Names with a leading underscore are reserved")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if name.upper() == 'Z':
|
|
|
|
error("The name 'Z' is reserved")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
MMA.mdefine.mdef.set(name, ' '.join(ln[1:]))
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def setMidiFileType(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set some MIDI file generation flags. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
error("USE: MidiFile [SMF=0/1] [RUNNING=0/1]")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
for l in ln:
|
|
|
|
try:
|
|
|
|
mode, val = l.upper().split('=')
|
|
|
|
except:
|
|
|
|
error("Each arg must contain an '=', not '%s'" % l)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if mode == 'SMF':
|
|
|
|
if val == '0':
|
|
|
|
gbl.midiFileType = 0
|
|
|
|
elif val == '1':
|
|
|
|
gbl.midiFileType = 1
|
|
|
|
else:
|
|
|
|
error("Use: MIDIFile SMF=0/1")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if gbl.debug:
|
|
|
|
print "Midi Filetype set to", gbl.midiFileType
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
elif mode == 'RUNNING':
|
|
|
|
if val == '0':
|
|
|
|
gbl.runningStatus = 0
|
|
|
|
elif val == '1':
|
|
|
|
gbl.runningStatus = 1
|
|
|
|
else:
|
|
|
|
error("Use: MIDIFile RUNNING=0/1")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if gbl.debug:
|
|
|
|
print "Midi Running Status Generation set to",
|
|
|
|
if gbl.runningStatus:
|
|
|
|
print 'ON (Default)'
|
|
|
|
else:
|
|
|
|
print 'OFF'
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
else:
|
|
|
|
error("Use: MIDIFile [SMF=0/1] [RUNNING=0/1]")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def setChPref(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set MIDI Channel Preference. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
error("Use: ChannelPref TRACKNAME=CHANNEL [...]")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
for i in ln:
|
|
|
|
if '=' not in i:
|
|
|
|
error("Each item in ChannelPref must have an '='")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
n,c = i.split('=')
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
c = stoi(c, "Expecting an integer for ChannelPref, not '%s'" % c)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if c<1 or c>16:
|
|
|
|
error("Channel for ChannelPref must be 1..16, not %s" % c)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.midiChPrefs[n.upper()]=c
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if gbl.debug:
|
|
|
|
print "ChannelPref:",
|
|
|
|
for n,c in gbl.midiChPrefs.items():
|
|
|
|
print "%s=%s" % (n,c),
|
|
|
|
print
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def setTimeSig(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set the midi time signature. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(ln) == 1:
|
|
|
|
a=ln[0].upper()
|
|
|
|
if a == 'COMMON':
|
|
|
|
ln=('4','4')
|
|
|
|
elif a == 'CUT':
|
|
|
|
ln=('2','2')
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(ln) != 2:
|
|
|
|
error("TimeSig: Usage (num dem) or ('cut' or 'common')")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
nn = stoi(ln[0])
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if nn<1 or nn>126:
|
|
|
|
error("Timesig NN must be 1..126")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
dd = stoi(ln[1])
|
|
|
|
if dd == 1: dd = 0
|
|
|
|
elif dd == 2: dd = 1
|
|
|
|
elif dd == 4: dd = 2
|
|
|
|
elif dd == 8: dd = 3
|
|
|
|
elif dd == 16: dd = 4
|
|
|
|
elif dd == 32: dd = 5
|
|
|
|
elif dd == 64: dd = 6
|
|
|
|
else:
|
|
|
|
error("Unknown value for timesig denominator")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
MMA.midi.timeSig.set(nn,dd)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#######################################
|
|
|
|
# Misc
|
|
|
|
|
2009-05-17 22:34:44 +00:00
|
|
|
def synchronize(ln):
|
|
|
|
""" Set synchronization in the MIDI. A file mode for -0 and -1. """
|
|
|
|
|
|
|
|
if not ln:
|
|
|
|
error("SYNCHRONIZE: requires args END and/or START.")
|
|
|
|
|
|
|
|
for a in ln:
|
|
|
|
if a.upper() == 'END':
|
|
|
|
gbl.endsync = 1
|
|
|
|
elif a.upper() == 'START':
|
|
|
|
gbl.synctick = 1
|
|
|
|
else:
|
|
|
|
error("SYNCHRONIZE: expecting END or START")
|
|
|
|
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
def rndseed(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Reseed the random number generator. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
random.seed()
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
elif len(ln)>1:
|
|
|
|
error("RNDSEED: requires 0 or 1 arguments")
|
|
|
|
else:
|
|
|
|
random.seed(stof(ln[0]))
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
def transpose(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set transpose value. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(ln) != 1:
|
|
|
|
error("Use: Transpose N")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
t = stoi(ln[0], "Argument for Tranpose must be an integer, not '%s'" % ln[0])
|
|
|
|
if t < -12 or t > 12:
|
|
|
|
error("Tranpose %s out-of-range; must be -12..12" % t)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.transpose = t
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if gbl.debug:
|
|
|
|
print "Set Transpose to %s" % t
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def lnPrint(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Print stuff in a "print" command. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
print " ".join(ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def printActive(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Print a list of the active tracks. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2009-05-17 22:34:44 +00:00
|
|
|
print "Active tracks, groove:", MMA.grooves.currentGroove, ' '.join(ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
for a in sorted(gbl.tnames.keys()):
|
|
|
|
f=gbl.tnames[a]
|
|
|
|
if f.sequence:
|
|
|
|
print " ",a
|
|
|
|
print
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def setDebug(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set debugging options dynamically. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
msg=( "Use: Debug MODE=On/Off where MODE is one or more of "
|
|
|
|
"DEBUG, FILENAMES, PATTERNS, SEQUENCE, "
|
|
|
|
"RUNTIME, WARNINGS or EXPAND" )
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not len(ln):
|
|
|
|
error(msg)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
# save current flags
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.Ldebug = gbl.debug
|
|
|
|
gbl.LshowFilenames = gbl.showFilenames
|
|
|
|
gbl.Lpshow = gbl.pshow
|
|
|
|
gbl.Lseqshow = gbl.seqshow
|
|
|
|
gbl.Lshowrun = gbl.showrun
|
|
|
|
gbl.LnoWarn = gbl.noWarn
|
|
|
|
gbl.LnoOutput = gbl.noOutput
|
|
|
|
gbl.LshowExpand = gbl.showExpand
|
|
|
|
gbl.Lchshow = gbl.chshow
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
for l in ln:
|
|
|
|
try:
|
|
|
|
mode, val = l.upper().split('=')
|
|
|
|
except:
|
|
|
|
error("Each debug option must contain a '=', not '%s'" % l)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if val == 'ON' or val == '1':
|
|
|
|
setting = 1
|
|
|
|
elif val == 'OFF' or val == '0':
|
|
|
|
setting = 0
|
|
|
|
else:
|
|
|
|
error(msg)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if mode == 'DEBUG':
|
|
|
|
gbl.debug = setting
|
|
|
|
if gbl.debug:
|
|
|
|
print "Debug=%s." % val
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
elif mode == 'FILENAMES':
|
|
|
|
gbl.showFilenames = setting
|
|
|
|
if gbl.debug:
|
|
|
|
print "ShowFilenames=%s." % val
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
elif mode == 'PATTERNS':
|
|
|
|
gbl.pshow = setting
|
|
|
|
if gbl.debug:
|
|
|
|
print "Pattern display=%s." % val
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
elif mode == 'SEQUENCE':
|
|
|
|
gbl.seqshow = setting
|
|
|
|
if gbl.debug:
|
|
|
|
print "Sequence display=%s." % val
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
elif mode == 'RUNTIME':
|
|
|
|
gbl.showrun = setting
|
|
|
|
if gbl.debug:
|
|
|
|
print "Runtime display=%s." % val
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
elif mode == 'WARNINGS':
|
|
|
|
gbl.noWarn = not(setting)
|
|
|
|
if gbl.debug:
|
|
|
|
print "Warning display=%s" % val
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
elif mode == 'EXPAND':
|
|
|
|
gbl.showExpand = setting
|
|
|
|
if gbl.debug:
|
|
|
|
print "Expand display=%s." % val
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
else:
|
|
|
|
error(msg)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
###########################################################
|
|
|
|
###########################################################
|
|
|
|
## Track specific commands
|
|
|
|
|
|
|
|
|
|
|
|
#######################################
|
|
|
|
# Pattern/Groove
|
|
|
|
|
|
|
|
def trackDefPattern(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Define a pattern for a track.
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
Use the type-name for all defines.... check the track
|
|
|
|
names and if it has a '-' in it, we use only the
|
|
|
|
part BEFORE the '-'. So DRUM-Snare becomes DRUM.
|
|
|
|
"""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
ln=ln[:]
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
name=name.split('-')[0]
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
trackAlloc(name, 1)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if ln:
|
|
|
|
pattern = ln.pop(0).upper()
|
|
|
|
else:
|
|
|
|
error("Define is expecting a pattern name")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if pattern in ('z', 'Z', '-'):
|
|
|
|
error("Pattern name '%s' is reserved" % pattern)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if pattern.startswith('_'):
|
|
|
|
error("Names with a leading underscore are reserved")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
error("No pattern list given for '%s %s'" % (name, pattern) )
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
ln=' '.join(ln)
|
|
|
|
gbl.tnames[name].definePattern(pattern, ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def trackSequence(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Define a sequence for a track.
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
The format for a sequence:
|
|
|
|
TrackName Seq1 [Seq2 ... ]
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
Note, that SeqX can be a predefined seq or { seqdef }
|
|
|
|
The {} is dynamically interpreted into a def.
|
|
|
|
"""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
error ("Use: %s Sequence NAME [...]" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
ln = ' '.join(ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Extract out any {} definitions and assign them to new
|
|
|
|
define variables (__1, __99, etc) and melt them
|
|
|
|
back into the string.
|
|
|
|
"""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
ids=1
|
|
|
|
while 1:
|
|
|
|
sp = ln.find("{")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if sp<0:
|
|
|
|
break
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
ln, s = pextract(ln, "{", "}", 1)
|
|
|
|
if not s:
|
|
|
|
error("Did not find matching '}' for '{'")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
pn = "_%s" % ids
|
|
|
|
ids+=1
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
trk=name.split('-')[0]
|
|
|
|
trackAlloc(trk, 1)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[trk].definePattern(pn, s[0])
|
|
|
|
ln = ln[:sp] + ' ' + pn + ' ' + ln[sp:]
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
ln=ln.split()
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setSequence(ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
def trackSeqClear(name, ln):
|
|
|
|
""" Clear sequence for specified tracks.
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
Note: "Drum SeqClear" clears all Drum tracks,
|
|
|
|
"Drum-3 SeqClear" clears track Drum-3.
|
|
|
|
"""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if ln:
|
|
|
|
error("No args permitted. Use %s SEQCLEAR" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
for n in gbl.tnames:
|
|
|
|
if n.find(name) == 0:
|
|
|
|
if gbl.debug:
|
|
|
|
print "SeqClear: Track %s cleared." % n
|
|
|
|
gbl.tnames[n].clearSequence()
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def trackSeqRnd(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set random order for specified track. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(ln) != 1:
|
|
|
|
error("Use: %s SeqRnd [On, Off]" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setRnd(ln[0].upper())
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
def trackSeqRndWeight(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set rnd weight for track. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
error("Use: %s RndWeight <weight factors>" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setRndWeight(ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def trackRestart(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Restart track to almost-default condidions. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if ln:
|
|
|
|
error ("Use: '%s Resart' with no args", name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].restart()
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def trackRiff(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set a riff for a track. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setRiff(' '.join(ln))
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def deleteTrks(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Delete a track and free the MIDI track. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not len(ln):
|
|
|
|
error("Use Delete Track [...]")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
for name in ln:
|
|
|
|
name=name.upper()
|
|
|
|
if name in gbl.tnames:
|
|
|
|
tr = gbl.tnames[name]
|
|
|
|
else:
|
|
|
|
error("Track '%s' does not exist" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if tr.channel:
|
|
|
|
tr.doMidiClear()
|
|
|
|
tr.clearPending()
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if tr.riff:
|
|
|
|
warning("%s has pending RIFF(s)" % name)
|
|
|
|
gbl.midiAvail[tr.channel] -= 1
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
# NOTE: Don't try deleting 'tr' since it's just a copy!!
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
del gbl.tnames[name]
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not name in gbl.deletedTracks:
|
|
|
|
gbl.deletedTracks.append(name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if gbl.debug:
|
|
|
|
print "Track '%s' deleted" % name
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#######################################
|
|
|
|
# Volume
|
|
|
|
|
|
|
|
def trackRvolume(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set random volume for specific track. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
error ("Use: %s RVolume N [...]" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setRVolume(ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2009-05-17 22:34:44 +00:00
|
|
|
def trackSwell(name, ln):
|
|
|
|
gbl.tnames[name].setSwell(ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
def trackCresc(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setCresc(1, ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
def trackDeCresc(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setCresc(-1, ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
def trackVolume(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set volume for specific track. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
error ("Use: %s Volume DYN [...]" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setVolume(ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def trackChannelVol(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set the channel volume for a track."""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(ln) != 1:
|
|
|
|
error("Use: %s ChannelVolume" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
v=stoi(ln[0], "Expecting integer arg, not %s" % ln[0])
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if v<0 or v>127:
|
|
|
|
error("ChannelVolume must be 0..127")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setChannelVolume(v)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def trackAccent(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set emphasis beats for track."""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setAccent(ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
#######################################
|
|
|
|
# Timing
|
|
|
|
|
|
|
|
def trackCut(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Insert a ALL NOTES OFF at the given offset. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not len(ln):
|
|
|
|
ln=['0']
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(ln) != 1:
|
|
|
|
error("Use: %s Cut Offset" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
offset = stof(ln[0], "Cut offset expecting value, (not '%s')" % ln[0])
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if offset < -gbl.QperBar or offset > gbl.QperBar:
|
|
|
|
warning("Cut: %s is a large beat offset" % offset)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
moff = int(gbl.tickOffset + (gbl.BperQ * offset))
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if moff < 0:
|
|
|
|
error("Calculated offset for Cut comes before start of track")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Insert allnoteoff directly in track. This skips the normal
|
|
|
|
queueing in pats because it would never take if at the end
|
|
|
|
of a track.
|
|
|
|
"""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
m = gbl.tnames[name].channel
|
|
|
|
if m and len(gbl.mtrks[m].miditrk) > 1:
|
|
|
|
gbl.mtrks[m].addNoteOff(moff)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if gbl.debug:
|
|
|
|
print "%s Cut: Beat %s, Bar %s" % (name, offset, gbl.barNum + 1)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def trackMallet(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set repeating-mallet options for solo/melody track. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
error("Use: %s Mallet <Option=Value> [...]" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setMallet(ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def trackRtime(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set random timing for specific track. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
error ("Use: %s RTime N [...]" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setRTime(ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def trackRskip(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set random skip for specific track. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
error ("Use: %s RSkip N [...]" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setRSkip(ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def trackArtic(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set articulation. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
error("Use: %s Articulation N [...]" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setArtic(ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
#######################################
|
|
|
|
# Chord stuff
|
|
|
|
|
|
|
|
|
|
|
|
def trackCompress(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set (unset) compress for track. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
error("Use: %s Compress <value[s]>" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setCompress(ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def trackVoicing(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set Voicing options. Only valid for chord tracks at this time."""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
error("Use: %s Voicing <MODE=VALUE> [...]" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setVoicing(ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def trackDupRoot(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set (unset) the root note duplication. Only applies to chord tracks. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
error("Use: %s DupRoot <value> ..." % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setDupRoot(ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def trackChordLimit(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set (unset) ChordLimit for track. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(ln) != 1:
|
|
|
|
error("Use: %s ChordLimit <value>" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setChordLimit(ln[0])
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
def trackRange(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set (unset) Range for track. Only effects arp and scale. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
error("Use: %s Range <value> ... " % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setRange(ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def trackInvert(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set invert for track."""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
error("Use: %s Invert N [...]" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setInvert(ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def trackSpan(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set midi note span for track. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(ln) != 2:
|
|
|
|
error("Use: %s Start End" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
start = stoi(ln[0], "Expecting integer for SPAN 1st arg")
|
|
|
|
if start <0 or start >127:
|
|
|
|
error("Start arg for Span must be 0..127, not %s" % start)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
end = stoi(ln[1], "Expecting integer for SPAN 2nd arg")
|
|
|
|
if end <0 or end >127:
|
|
|
|
error("End arg for Span must be 0..127, not %s" % end)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if end <= start:
|
|
|
|
error("End arg for Span must be greater than start")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if end-start < 11:
|
|
|
|
error("Span range must be at least 12")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setSpan(start, end)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def trackOctave(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set octave for specific track. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
error ("Use: %s Octave N [...], (n=0..10)" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setOctave( ln )
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def trackStrum(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set all specified track strum. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
error ("Use: %s Strum N [...]" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setStrum( ln )
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def trackHarmony(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set harmony value. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
error("Use: %s Harmony N [...]" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setHarmony(ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def trackHarmonyOnly(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set harmony only for track. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
error("Use: %s HarmonyOnly N [...]" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setHarmonyOnly(ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
def trackHarmonyVolume(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set harmony volume for track."""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
error("Use: %s HarmonyVolume N [...]" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setHarmonyVolume(ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
#######################################
|
|
|
|
# MIDI setting
|
|
|
|
|
|
|
|
|
|
|
|
def trackChannel(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set the midi channel for a track."""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
error("Use: %s Channel" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setChannel(ln[0])
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def trackMdefine(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set a midi seq pattern. Ignore track name."""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
mdefine(ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def trackMidiExt(ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Helper for trackMidiSeq() and trackMidiVoice()."""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
ids=1
|
|
|
|
while 1:
|
|
|
|
sp = ln.find("{")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if sp<0:
|
|
|
|
break
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
ln, s = pextract(ln, "{", "}", 1)
|
|
|
|
if not s:
|
|
|
|
error("Did not find matching '}' for '{'")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
pn = "_%s" % ids
|
|
|
|
ids+=1
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
MMA.mdefine.mdef.set(pn, s[0])
|
|
|
|
ln = ln[:sp] + ' ' + pn + ' ' + ln[sp:]
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
return ln.split()
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def trackMidiClear(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set MIDI command to send at end of groove. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
error("Use %s MIDIClear Controller Data" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(ln) == 1 and ln[0] == '-':
|
|
|
|
gbl.tnames[name].setMidiClear( '-' )
|
|
|
|
else:
|
|
|
|
ln=' '.join(ln)
|
|
|
|
if '{' in ln or '}' in ln:
|
|
|
|
error("{}s are not permitted in %s MIDIClear command" % name)
|
|
|
|
gbl.tnames[name].setMidiClear( trackMidiExt( '{' + ln + '}' ))
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def trackMidiSeq(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set reoccurring MIDI command for track. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
error("Use %s MidiSeq Controller Data" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(ln) == 1 and ln[0]== '-':
|
|
|
|
gbl.tnames[name].setMidiSeq('-')
|
|
|
|
else:
|
|
|
|
gbl.tnames[name].setMidiSeq( trackMidiExt(' '.join(ln) ))
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def trackMidiVoice(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set single shot MIDI command for track. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
error("Use %s MidiVoice Controller Data" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(ln) == 1 and ln[0] == '-':
|
|
|
|
gbl.tnames[name].setMidiVoice( '-' )
|
|
|
|
else:
|
|
|
|
gbl.tnames[name].setMidiVoice( trackMidiExt(' '.join(ln) ))
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def trackChShare(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set MIDI channel sharing."""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(ln) !=1:
|
|
|
|
error("Use: %s ChShare TrackName" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setChShare(ln[0])
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def trackVoice(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set voice for specific track. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
error ("Use: %s Voice NN [...]" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setVoice(ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def trackPan(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set the Midi Pan value for a track."""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2009-05-17 22:34:44 +00:00
|
|
|
if len(ln)==1 or len(ln)==3:
|
|
|
|
gbl.tnames[name].setPan(ln)
|
|
|
|
else:
|
|
|
|
error("Use %s MidiPAN [Value] OR [Initvalue DestValue Beats]." % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
def trackOff(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Turn a track off """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if ln:
|
|
|
|
error("Use: %s OFF with no paramater" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setOff()
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def trackOn(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Turn a track on """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if ln:
|
|
|
|
error("Use: %s ON with no paramater" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setOn()
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def trackMidiName(name,ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set channel track name."""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
error("Use: %s TrackName" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setTname(ln[0])
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def trackTone(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set the tone (note). Only valid in drum tracks."""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
error("Use: %s Tone N [...]" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setTone(ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def trackGlis(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Enable/disable portamento. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(ln) != 1:
|
|
|
|
error("Use: %s Portamento NN, off=0, 1..127==on" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setGlis(ln[0])
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
def trackForceOut(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Force output of voice settings. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(ln):
|
|
|
|
error("Use %s ForceOut (no options)" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setForceOut()
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
#######################################
|
|
|
|
# Misc
|
|
|
|
|
|
|
|
def trackDrumType(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set a melody or solo track to be a drum solo track."""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
tr = gbl.tnames[name]
|
|
|
|
if tr.vtype not in ('SOLO', 'MELODY'):
|
|
|
|
error ("Only Solo and Melody tracks can be to DrumType, not '%s'" % name)
|
|
|
|
if ln:
|
|
|
|
error("No parmeters permitted for DrumType command")
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
tr.setDrumType()
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def trackDirection(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set scale/arp direction. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
error("Use: %s Direction OPT" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setDirection(ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def trackScaletype(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set the scale type. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not ln:
|
|
|
|
error("Use: %s ScaleType OPT" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setScaletype(ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def trackCopy(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Copy setting in 'ln' to 'name'. """
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if len(ln) != 1:
|
|
|
|
error("Use: %s Copy ExistingTrack" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].copySettings(ln[0].upper())
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def trackUnify(name, ln):
|
2007-04-29 06:47:40 +00:00
|
|
|
""" Set UNIFY for track."""
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
if not len(ln):
|
|
|
|
error("Use %s UNIFY 1 [...]" % name)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
gbl.tnames[name].setUnify(ln)
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
""" =================================================================
|
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
Command jump tables. These need to be at the end of this module
|
|
|
|
to avoid undefined name errors. The tables are only used in
|
|
|
|
the parse() function.
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
The first table is for the simple commands ... those which DO NOT
|
|
|
|
have a leading trackname. The second table is for commands which
|
|
|
|
require a leading track name.
|
2006-11-10 08:07:56 +00:00
|
|
|
|
2007-04-29 06:47:40 +00:00
|
|
|
The alphabetic order is NOT needed, just convenient.
|
2006-11-10 08:07:56 +00:00
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
simpleFuncs={
|
2007-04-29 06:47:40 +00:00
|
|
|
'ADJUSTVOLUME': MMA.volume.adjvolume,
|
2009-05-17 22:34:44 +00:00
|
|
|
'ALLGROOVES': MMA.grooves.allgrooves,
|
2007-04-29 06:47:40 +00:00
|
|
|
'ALLTRACKS': allTracks,
|
|
|
|
'AUTHOR': MMA.docs.docAuthor,
|
|
|
|
'AUTOSOLOTRACKS': MMA.patSolo.setAutoSolo,
|
|
|
|
'BEATADJUST': beatAdjust,
|
|
|
|
'CHANNELPREF': setChPref,
|
2009-05-17 22:34:44 +00:00
|
|
|
'CHORDADJUST': MMA.chords.chordAdjust,
|
2007-04-29 06:47:40 +00:00
|
|
|
'COMMENT': comment,
|
|
|
|
'CRESC': MMA.volume.setCresc,
|
|
|
|
'CUT': cut,
|
|
|
|
'DEBUG': setDebug,
|
|
|
|
'DEC': macros.vardec,
|
|
|
|
'DECRESC': MMA.volume.setDecresc,
|
2009-05-17 22:34:44 +00:00
|
|
|
'DEFALIAS': MMA.grooves.grooveAlias,
|
2007-04-29 06:47:40 +00:00
|
|
|
'DEFCHORD': MMA.chords.defChord,
|
2009-05-17 22:34:44 +00:00
|
|
|
'DEFGROOVE': MMA.grooves.grooveDefine,
|
2007-04-29 06:47:40 +00:00
|
|
|
'DELETE': deleteTrks,
|
|
|
|
'DOC': MMA.docs.docNote,
|
|
|
|
'DOCVAR': MMA.docs.docVars,
|
|
|
|
'DRUMVOLTR': MMA.translate.drumVolTable.set,
|
|
|
|
'ELSE': ifelse,
|
|
|
|
'ENDIF': ifend,
|
|
|
|
'ENDMSET': endmset,
|
|
|
|
'ENDREPEAT': repeatend,
|
|
|
|
'EOF': eof,
|
|
|
|
'FERMATA': fermata,
|
|
|
|
'GOTO': goto,
|
2009-05-17 22:34:44 +00:00
|
|
|
'GROOVE': MMA.grooves.groove,
|
|
|
|
'GROOVECLEAR': MMA.grooves.grooveClear,
|
2007-04-29 06:47:40 +00:00
|
|
|
'IF': macros.varIF,
|
|
|
|
'IFEND': ifend,
|
|
|
|
'INC': macros.varinc,
|
|
|
|
'INCLUDE': include,
|
|
|
|
'KEYSIG': MMA.patSolo.keySig.set,
|
|
|
|
'LABEL': comment,
|
|
|
|
'LYRIC': lyric.option,
|
|
|
|
'MIDIDEF': mdefine,
|
|
|
|
'MIDI': rawMidi,
|
|
|
|
'MIDIFILE': setMidiFileType,
|
|
|
|
'MIDIINC': MMA.midiIn.midiinc,
|
|
|
|
'MIDIMARK': midiMarker,
|
|
|
|
'MIDISPLIT': MMA.midi.setSplitChannels,
|
|
|
|
'MMAEND': mmaend,
|
|
|
|
'MMASTART': mmastart,
|
|
|
|
'MSET': macros.msetvar,
|
|
|
|
'MSETEND': endmset,
|
|
|
|
'NEWSET': macros.newsetvar,
|
2009-05-17 22:34:44 +00:00
|
|
|
'PATCH': MMA.patch.patch,
|
2007-04-29 06:47:40 +00:00
|
|
|
'PRINT': lnPrint,
|
|
|
|
'PRINTACTIVE': printActive,
|
|
|
|
'PRINTCHORD': MMA.chords.printChord,
|
|
|
|
'REPEAT': repeat,
|
|
|
|
'REPEATEND': repeatend,
|
|
|
|
'REPEATENDING': repeatending,
|
|
|
|
'RESTART': restart,
|
|
|
|
'RNDSEED': rndseed,
|
|
|
|
'RNDSET': macros.rndvar,
|
|
|
|
'SEQ': seq,
|
|
|
|
'SEQCLEAR': seqClear,
|
2009-05-17 22:34:44 +00:00
|
|
|
'SEQRND': MMA.seqrnd.setSeqRnd,
|
|
|
|
'SEQRNDWEIGHT': MMA.seqrnd.setSeqRndWeight,
|
2007-04-29 06:47:40 +00:00
|
|
|
'SEQSIZE': seqsize,
|
|
|
|
'SET': macros.setvar,
|
|
|
|
'SETAUTOLIBPATH': setAutoPath,
|
|
|
|
'SETINCPATH': setIncPath,
|
|
|
|
'SETLIBPATH': setLibPath,
|
2009-05-17 22:34:44 +00:00
|
|
|
'SETMIDIPLAYER': setMidiPlayer,
|
2007-04-29 06:47:40 +00:00
|
|
|
'SETOUTPATH': setOutPath,
|
|
|
|
'SHOWVARS': macros.showvars,
|
|
|
|
'STACKVALUE': macros.stackValue,
|
2009-05-17 22:34:44 +00:00
|
|
|
'SWELL': MMA.volume.setSwell,
|
2007-04-29 06:47:40 +00:00
|
|
|
'SWINGMODE': MMA.notelen.swingMode,
|
2009-05-17 22:34:44 +00:00
|
|
|
'SYNCHRONIZE': synchronize,
|
2007-04-29 06:47:40 +00:00
|
|
|
'TEMPO': tempo,
|
|
|
|
'TIME': setTime,
|
|
|
|
'TIMESIG': setTimeSig,
|
|
|
|
'TONETR': MMA.translate.dtable.set,
|
|
|
|
'UNSET': macros.unsetvar,
|
|
|
|
'USE': usefile,
|
|
|
|
'VARCLEAR': macros.clear,
|
|
|
|
'VEXPAND': macros.vexpand,
|
|
|
|
'VOICEVOLTR': MMA.translate.voiceVolTable.set,
|
|
|
|
'VOICETR': MMA.translate.vtable.set,
|
|
|
|
'VOLUME': MMA.volume.setVolume,
|
|
|
|
'TRANSPOSE': transpose
|
2006-11-10 08:07:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
trackFuncs={
|
2007-04-29 06:47:40 +00:00
|
|
|
'ACCENT': trackAccent,
|
|
|
|
'ARTICULATE': trackArtic,
|
|
|
|
'CHANNEL': trackChannel,
|
|
|
|
'MIDIVOLUME': trackChannelVol,
|
|
|
|
'CHSHARE': trackChShare,
|
|
|
|
'COMPRESS': trackCompress,
|
|
|
|
'COPY': trackCopy,
|
|
|
|
'CRESC': trackCresc,
|
|
|
|
'CUT': trackCut,
|
|
|
|
'DECRESC': trackDeCresc,
|
|
|
|
'DIRECTION': trackDirection,
|
|
|
|
'DRUMTYPE': trackDrumType,
|
|
|
|
'DUPROOT': trackDupRoot,
|
|
|
|
'FORCEOUT': trackForceOut,
|
2009-05-17 22:34:44 +00:00
|
|
|
'GROOVE': MMA.grooves.trackGroove,
|
2007-04-29 06:47:40 +00:00
|
|
|
'HARMONY': trackHarmony,
|
|
|
|
'HARMONYONLY': trackHarmonyOnly,
|
|
|
|
'HARMONYVOLUME': trackHarmonyVolume,
|
|
|
|
'INVERT': trackInvert,
|
|
|
|
'LIMIT': trackChordLimit,
|
|
|
|
'MALLET': trackMallet,
|
|
|
|
'MIDIDEF': trackMdefine,
|
|
|
|
'MIDIGLIS': trackGlis,
|
|
|
|
'MIDICLEAR': trackMidiClear,
|
|
|
|
'MIDIPAN': trackPan,
|
|
|
|
'MIDIGLIS': trackGlis,
|
|
|
|
'MIDISEQ': trackMidiSeq,
|
|
|
|
'MIDITNAME': trackMidiName,
|
|
|
|
'MIDIVOICE': trackMidiVoice,
|
|
|
|
'OCTAVE': trackOctave,
|
|
|
|
'OFF': trackOff,
|
|
|
|
'ON': trackOn,
|
|
|
|
'RANGE': trackRange,
|
|
|
|
'RESTART': trackRestart,
|
|
|
|
'RIFF': trackRiff,
|
|
|
|
'RSKIP': trackRskip,
|
|
|
|
'RTIME': trackRtime,
|
|
|
|
'RVOLUME': trackRvolume,
|
|
|
|
'SCALETYPE': trackScaletype,
|
|
|
|
'SEQCLEAR': trackSeqClear,
|
|
|
|
'SEQRND': trackSeqRnd,
|
|
|
|
'SEQUENCE': trackSequence,
|
|
|
|
'SEQRNDWEIGHT': trackSeqRndWeight,
|
2009-05-17 22:34:44 +00:00
|
|
|
'SWELL': trackSwell,
|
2007-04-29 06:47:40 +00:00
|
|
|
'NOTESPAN': trackSpan,
|
|
|
|
'STRUM': trackStrum,
|
|
|
|
'TONE': trackTone,
|
|
|
|
'UNIFY': trackUnify,
|
|
|
|
'VOICE': trackVoice,
|
|
|
|
'VOICING': trackVoicing,
|
|
|
|
'VOLUME': trackVolume,
|
|
|
|
'DEFINE': trackDefPattern
|
2006-11-10 08:07:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|