Exemple #1
0
    def sysvar(self, s):
        """ Create an internal macro. """

        # Simple/global     system values

        if s == 'CHORDADJUST':
            return ' '.join([
                "%s=%s" % (a, MMA.chords.cdAdjust[a])
                for a in sorted(MMA.chords.cdAdjust)
            ])

        elif s == 'KEYSIG':
            return keySig.getKeysig()

        elif s == 'TIME':
            return str(gbl.QperBar)

        elif s == 'CTABS':
            return ','.join([
                str((float(x) / gbl.BperQ) + 1) for x in MMA.parseCL.chordTabs
            ])

        elif s == 'TIMESIG':
            return timeSig.getAscii()

        elif s == 'TEMPO':
            return str(gbl.tempo)

        elif s == 'OFFSET':
            return str(gbl.tickOffset)

        elif s == 'VOLUME':
            return str(int(MMA.volume.volume * 100))  # INT() is important

        elif s == 'VOLUMERATIO':
            return str((MMA.volume.vTRatio * 100))

        elif s == 'LASTVOLUME':
            return str(int(MMA.volume.lastVolume * 100))

        elif s == 'GROOVE':
            return MMA.grooves.currentGroove

        elif s == 'GROOVELIST':
            return ' '.join(
                sorted([
                    x for x in MMA.grooves.glist.keys() if type(x) == type('')
                ]))

        elif s == 'TRACKLIST':
            return ' '.join(sorted(gbl.tnames.keys()))

        elif s == 'LASTGROOVE':
            return MMA.grooves.lastGroove

        elif s == 'PLUGINS':
            from MMA.regplug import simplePlugs  # to avoid circular import error
            return ' '.join(simplePlugs)

        elif s == 'SEQ':
            return str(gbl.seqCount)

        elif s == 'SEQRND':
            if MMA.seqrnd.seqRnd[0] == 0:
                return "Off"
            if MMA.seqrnd.seqRnd[0] == 1:
                return "On"
            return ' '.join(MMA.seqrnd.seqRnd[1:])

        elif s == 'SEQSIZE':
            return str(gbl.seqSize)

        elif s == 'SWINGMODE':
            return MMA.swing.settings()

        elif s == 'TICKPOS':
            return str(gbl.tickOffset)

        elif s == 'TRANSPOSE':
            return str(gbl.transpose)

        elif s == 'STACKVALUE':
            if not self.pushstack:
                error("Empty push/pull variable stack")
            return self.pushstack.pop()

        elif s == 'DEBUG':
            return "Debug=%s  Filenames=%s Patterns=%s " \
                "Sequence=%s Runtime=%s Warnings=%s Expand=%s " \
                "Roman=%s Plectrum=%s Groove=%s" % \
                (gbl.debug, gbl.showFilenames, gbl.pshow, gbl.seqshow,
                 gbl.showrun,  int(not gbl.noWarn), gbl.showExpand,
                 gbl.rmShow, gbl.plecShow, gbl.gvShow)

        elif s == 'LASTDEBUG':
            return "Debug=%s  Filenames=%s Patterns=%s " \
                "Sequence=%s Runtime=%s Warnings=%s Expand=%s " \
                "Roman=%s Plectrum=%s Groove=%s" % \
                (gbl.Ldebug, gbl.LshowFilenames, gbl.Lpshow, gbl.Lseqshow,
                 gbl.Lshowrun,  int(not gbl.LnoWarn), gbl.LshowExpand,
                 gbl.LrmShow, gbl.LplecShow, gbl.LgvShow)

        elif s == 'VEXPAND':
            if self.expandMode:
                return "On"
            else:
                return "Off"

        elif s == "MIDIPLAYER":
            return "%s Background=%s Delay=%s." % \
                (' '.join(MMA.player.midiPlayer), MMA.player.inBackGround,
                 MMA.player.waitTime)

        elif s == "MIDISPLIT":
            return ' '.join([str(x) for x in MMA.midi.splitChannels])

        elif s.startswith("NOTELEN(") and s.endswith(")"):
            return "%sT" % getNoteLen(s[8:-1])

        elif s == 'SEQRNDWEIGHT':
            return ' '.join([str(x) for x in MMA.seqrnd.seqRndWeight])

        elif s == 'AUTOLIBPATH':
            return ' '.join(MMA.paths.libDirs)

        elif s == 'LIBPATH':
            return ' '.join(MMA.paths.libPath)

        elif s == 'MMAPATH':
            return gbl.MMAdir

        elif s == 'INCPATH':
            return ' '.join(MMA.paths.incPath)

        elif s == 'VOICETR':
            return MMA.translate.vtable.retlist()

        elif s == 'TONETR':
            return MMA.translate.dtable.retlist()

        elif s == 'OUTPATH':
            return gbl.outPath

        elif s == 'BARNUM':
            return str(gbl.barNum + 1)

        elif s == 'LINENUM':
            return str(gbl.lineno)

        elif s == 'LYRIC':
            return lyric.setting()

        # Track vars ... these are in format TRACKNAME_VAR

        a = s.rfind('_')
        if a == -1:
            error("Unknown system variable $_%s" % s)

        tname = s[:a]
        func = s[a + 1:]

        try:
            t = gbl.tnames[tname]
        except KeyError:
            error("System variable $_%s refers to nonexistent track." % s)

        if func == 'ACCENT':
            r = []
            for s in t.accent:
                r.append("{")
                for b, v in s:
                    r.append('%g' % (b / float(gbl.BperQ) + 1))
                    r.append(str(int(v * 100)))
                r.append("}")
            return ' '.join(r)

        elif func == 'ARTICULATE':
            return ' '.join([str(x) for x in t.artic])

        elif func == 'CHORDS':
            r = []
            for l in t.chord:
                r.append('{' + ' '.join(l) + '}')
            return ' '.join(r)

        elif func == 'CHANNEL':
            return str(t.channel)

        elif func == 'COMPRESS':
            return ' '.join([str(x) for x in t.compress])

        elif func == 'DELAY':
            return ' '.join([str(x) for x in t.delay])

        elif func == 'DIRECTION':
            if t.vtype == 'ARIA':
                return ' '.join([str(x) for x in t.selectDir])
            else:
                return ' '.join([str(x) for x in t.direction])

        elif func == 'DUPROOT':
            if t.vtype != "CHORD":
                error("Only CHORD tracks have DUPROOT")
            return t.getDupRootSetting()

        elif func == 'FRETNOISE':
            return t.getFretNoiseOptions()

        elif func == 'HARMONY':
            return ' '.join([str(x) for x in t.harmony])

        elif func == 'HARMONYONLY':
            return ' '.join([str(x) for x in t.harmonyOnly])

        elif func == 'HARMONYVOLUME':
            return ' '.join([str(int(i * 100)) for i in t.harmonyVolume])

        elif func == 'INVERT':
            return ' '.join([str(x) for x in t.invert])

        elif func == 'LIMIT':
            return str(t.chordLimit)

        elif func == 'MALLET':
            if t.vtype not in ("SOLO", "MELODY"):
                error("Mallet only valid in SOLO and MELODY tracks")
            return "Mallet Rate=%i Decay=%i" % (t.mallet, t.malletDecay * 100)

        elif func == 'MIDINOTE':
            return MMA.midinote.mopts(t)

        elif func == 'MIDIVOLUME':
            return "%s" % t.cVolume

        elif func == 'OCTAVE':
            return ' '.join([str(i // 12) for i in t.octave])

        elif func == 'MOCTAVE':
            return ' '.join([str((i // 12) - 1) for i in t.octave])

        elif func == 'ORNAMENT':
            return MMA.ornament.getOrnOpts(t)

        elif func == 'PLUGINS':
            from MMA.regplug import trackPlugs  # avoids circular import
            return ' '.join(trackPlugs)

        elif func == 'RANGE':
            return ' '.join([str(x) for x in t.chordRange])

        elif func == 'RSKIP':
            m = ''
            if t.rSkipBeats:
                m = "Beats=%s " % ','.join(
                    ['%g' % (x / float(gbl.BperQ) + 1) for x in t.rSkipBeats])
            m += ' '.join([str(int(i * 100)) for i in t.rSkip])
            return m

        elif func == 'RDURATION':
            tmp = []
            for a1, a2 in t.rDuration:
                a1 = int(a1 * 100)
                a2 = int(a2 * 100)
                if a1 == a2:
                    tmp.append('%s' % abs(a1))
                else:
                    tmp.append('%s,%s' % (a1, a2))

            return ' '.join(tmp)

        elif func == 'RTIME':
            tmp = []
            for a1, a2 in t.rTime:
                if a1 == a2:
                    tmp.append('%s' % abs(a1))
                else:
                    tmp.append('%s,%s' % (a1, a2))
            return ' '.join(tmp)

        elif func == 'RVOLUME':
            tmp = []
            for a1, a2 in t.rVolume:
                a1 = int(a1 * 100)
                a2 = int(a2 * 100)
                if a1 == a2:
                    tmp.append('%s' % abs(a1))
                else:
                    tmp.append('%s,%s' % (a1, a2))
            return ' '.join(tmp)

        elif func == 'RPITCH':
            return MMA.rpitch.getOpts(t)

        elif func == 'SEQUENCE':
            tmp = []
            for a in range(gbl.seqSize):
                tmp.append('{' + t.formatPattern(t.sequence[a]) + '}')
            return ' '.join(tmp)

        elif func == 'SEQRND':
            if t.seqRnd:
                return 'On'
            else:
                return 'Off'

        elif func == 'SEQRNDWEIGHT':
            return ' '.join([str(x) for x in t.seqRndWeight])

        elif func == 'SPAN':
            return "%s %s" % (t.spanStart, t.spanEnd)

        elif func == 'STICKY':
            if t.sticky:
                return "True"
            else:
                return "False"

        elif func == 'STRUM':
            r = []
            for v in t.strum:
                if v is None:
                    r.append("0")
                else:
                    a, b = v
                    if a == b:
                        r.append("%s" % a)
                    else:
                        r.append("%s,%s" % (a, b))

            return ' '.join(r)

        elif func == 'STRUMADD':
            return ' '.join([str(x) for x in t.strumAdd])

        elif func == 'TRIGGER':
            return MMA.trigger.getTriggerOptions(t)

        elif func == 'TONE':
            if t.vtype != "DRUM":
                error("Only DRUM tracks have TONE")
            return ' '.join([MMA.midiC.valueToDrum(a) for a in t.toneList])

        elif func == 'UNIFY':
            return ' '.join([str(x) for x in t.unify])

        elif func == 'VOICE':
            return ' '.join([MMA.midiC.valueToInst(a) for a in t.voice])

        elif func == 'VOICING':
            if t.vtype != 'CHORD':
                error("Only CHORD tracks have VOICING")
            t = t.voicing
            return "Mode=%s Range=%s Center=%s RMove=%s Move=%s Dir=%s" % \
                (t.mode, t.range, t.center, t.random, t.bcount, t.dir)

        elif func == 'VOLUME':
            return ' '.join([str(int(a * 100)) for a in t.volume])

        else:
            error("Unknown system track variable %s" % s)
Exemple #2
0
    def sysvar(self, s):
        """ Create an internal macro. """

        # Check for system functions.

        m = re.match(r'([^\(]+)\((.*)\)$', s)
        if m:
            return self.sysfun(m.group(1), m.group(2))

        # Simple/global     system values

        if s == 'CHORDADJUST':
            return ' '.join([
                "%s=%s" % (a, MMA.chords.cdAdjust[a])
                for a in sorted(MMA.chords.cdAdjust)
            ])

        elif s == 'FILENAME':
            a = gbl.inpath.fname
            if isinstance(a, int):
                return ''
            else:
                return str(gbl.inpath.fname)

        elif s == 'FILEPATH':
            a = gbl.inpath.fname
            if isinstance(a, int):
                return ''
            else:
                return path.abspath(gbl.inpath.fname)

        elif s == 'SONGPATH':
            a = gbl.infile
            if isinstance(a, int):
                return ''
            else:
                return path.abspath(gbl.infile)

        elif s == 'KEYSIG':
            return keySig.getKeysig()

        elif s == 'TIME':
            return str(gbl.QperBar)

        elif s == 'CTABS':
            return ','.join([
                str((float(x) / gbl.BperQ) + 1) for x in MMA.parseCL.chordTabs
            ])

        elif s == 'TIMESIG':
            return timeSig.getAscii()

        elif s == 'TEMPO':  # get the current tempo via the record in midi.py
            tmp = gbl.tempo
            for o, t in MMA.midi.tempoChanges:
                if o > gbl.tickOffset:
                    break
                tmp = t
            return str(tmp)

        elif s == 'OFFSET':
            return str(gbl.tickOffset)

        elif s == 'SONGFILENAME':
            return str(gbl.infile)

        elif s == 'VOLUME':
            return str(int(MMA.volume.volume * 100))  # INT() is important

        elif s == 'VOLUMERATIO':
            return str((MMA.volume.vTRatio * 100))

        elif s == 'LASTVOLUME':
            return str(int(MMA.volume.lastVolume * 100))

        elif s == 'GROOVE':
            return MMA.grooves.currentGroove

        elif s == 'GROOVELIST':
            return ' '.join(
                sorted([
                    x for x in MMA.grooves.glist.keys() if isinstance(x, str)
                ]))

        elif s == 'TRACKLIST':
            return ' '.join(sorted(gbl.tnames.keys()))

        elif s == 'LASTGROOVE':
            return MMA.grooves.lastGroove

        elif s == 'PLUGINS':
            from MMA.regplug import simplePlugs  # to avoid circular import error
            return ' '.join(simplePlugs)

        elif s == 'TRACKPLUGINS':
            from MMA.regplug import trackPlugs  # to avoid circular import error
            return ' '.join(trackPlugs)

        elif s == 'DATAPLUGINS':
            from MMA.regplug import dataPlugs  # to avoid circular import error
            return ' '.join(dataPlugs)

        elif s == 'SEQ':
            return str(gbl.seqCount)

        elif s == 'SEQRND':
            if MMA.seqrnd.seqRnd[0] == 0:
                return "Off"
            if MMA.seqrnd.seqRnd[0] == 1:
                return "On"
            return ' '.join(MMA.seqrnd.seqRnd[1:])

        elif s == 'SEQSIZE':
            return str(gbl.seqSize)

        elif s == 'SWINGMODE':
            return MMA.swing.settings()

        elif s == 'TICKPOS':
            return str(gbl.tickOffset)

        elif s == 'TRANSPOSE':
            return str(gbl.transpose)

        elif s == 'STACKVALUE':
            if not self.pushstack:
                error("Empty push/pull variable stack")
            return self.pushstack.pop()

        elif s == 'DEBUG':
            return MMA.debug.getFlags()

        elif s == 'LASTDEBUG':
            return MMA.debug.getLFlags()

        elif s == 'VEXPAND':
            if self.expandMode:
                return "On"
            else:
                return "Off"

        elif s == "MIDIPLAYER":
            return "%s Background=%s Delay=%s." % \
                (' '.join(MMA.player.midiPlayer), MMA.player.inBackGround,
                 MMA.player.waitTime)

        elif s == "MIDISPLIT":
            return ' '.join([str(x) for x in MMA.midi.splitChannels])

        elif s == "MIDIASSIGNS":
            x = []
            for c, n in sorted(gbl.midiAssigns.items()):
                if n:
                    x.append("%s=%s" % (c, ','.join(n)))
            return ' '.join(x)

        elif s == 'SEQRNDWEIGHT':
            return ' '.join([str(x) for x in MMA.seqrnd.seqRndWeight])

        elif s == 'AUTOLIBPATH':
            return ' '.join(MMA.paths.libDirs)

        elif s == 'LIBPATH':
            return ' '.join(MMA.paths.libPath)

        elif s == 'MMAPATH':
            return gbl.MMAdir

        elif s == 'INCPATH':
            return ' '.join(MMA.paths.incPath)

        elif s == 'PLUGPATH':
            return ' '.join(MMA.paths.plugPaths)

        elif s == 'VOICETR':
            return MMA.translate.vtable.retlist()

        elif s == 'TONETR':
            return MMA.translate.dtable.retlist()

        elif s == 'OUTPATH':
            return gbl.outPath

        elif s == 'BARNUM':
            return str(gbl.barNum + 1)

        elif s == 'LINENUM':
            return str(gbl.lineno)

        elif s == 'LYRIC':
            return MMA.lyric.lyric.setting()

        # Some time/date macros. Useful for generating copyright strings

        elif s == 'DATEYEAR':
            return str(datetime.datetime.now().year)

        elif s == 'DATEDATE':
            return datetime.datetime.now().strftime("%Y-%m-%d")

        elif s == 'DATETIME':
            return datetime.datetime.now().strftime("%H:%M:%S")

        # Track vars ... these are in format TRACKNAME_VAR

        a = s.rfind('_')
        if a == -1:
            error("Unknown system variable $_%s" % s)

        tname = s[:a]
        func = s[a + 1:]

        try:
            t = gbl.tnames[tname]
        except KeyError:
            error("System variable $_%s refers to nonexistent track." % s)

        if func == 'ACCENT':
            r = []
            for s in t.accent:
                r.append("{")
                for b, v in s:
                    r.append('%g' % (b / float(gbl.BperQ) + 1))
                    r.append(str(int(v * 100)))
                r.append("}")
            return ' '.join(r)

        elif func == 'ARTICULATE':
            return ' '.join([str(x) for x in t.artic])

        elif func == 'CHORDS':
            r = []
            for l in t.chord:
                r.append('{' + ' '.join(l) + '}')
            return ' '.join(r)

        elif func == 'CHANNEL':
            return str(t.channel)

        elif func == 'COMPRESS':
            return ' '.join([str(x) for x in t.compress])

        elif func == 'DELAY':
            return ' '.join([str(x) for x in t.delay])

        elif func == 'DIRECTION':
            if t.vtype == 'ARIA':
                return ' '.join([str(x) for x in t.selectDir])
            else:
                return ' '.join([str(x) for x in t.direction])

        elif func == 'DUPROOT':
            if t.vtype != "CHORD":
                error("Only CHORD tracks have DUPROOT")
            return t.getDupRootSetting()

        elif func == 'FRETNOISE':
            return t.getFretNoiseOptions()

        elif func == 'HARMONY':
            return ' '.join([str(x) for x in t.harmony])

        elif func == 'HARMONYONLY':
            return ' '.join([str(x) for x in t.harmonyOnly])

        elif func == 'HARMONYVOLUME':
            return ' '.join([str(int(i * 100)) for i in t.harmonyVolume])

        elif func == 'INVERT':
            return ' '.join([str(x) for x in t.invert])

        elif func == 'LIMIT':
            return "%s mode=%s" % (t.chordLimit[0], t.chordLimit[1])

        elif func == 'MALLET':
            if t.vtype not in ("SOLO", "MELODY"):
                error("Mallet only valid in SOLO and MELODY tracks")
            return "Mallet Rate=%i Decay=%i" % (t.mallet, t.malletDecay * 100)

        elif func == 'MIDINOTE':
            return MMA.midinote.mopts(t)

        elif func == 'MIDIVOLUME':
            return "%s" % t.cVolume

        elif func == 'OCTAVE':
            return ' '.join([str(i // 12) for i in t.octave])

        elif func == 'MOCTAVE':
            return ' '.join([str((i // 12) - 1) for i in t.octave])

        elif func == 'ORNAMENT':
            return MMA.ornament.getOrnOpts(t)

        elif func == 'PLUGINS':
            from MMA.regplug import trackPlugs  # avoids circular import
            return ' '.join(trackPlugs)

        elif func == 'RANGE':
            return ' '.join([str(x) for x in t.chordRange])

        elif func == 'RSKIP':
            m = ''
            if t.rSkipBeats:
                m = "Beats=%s " % ','.join(
                    ['%g' % (x / float(gbl.BperQ) + 1) for x in t.rSkipBeats])
            m += ' '.join([str(int(i * 100)) for i in t.rSkip])
            return m

        elif func == 'RDURATION':
            tmp = []
            for a1, a2 in t.rDuration:
                a1 = int(a1 * 100)
                a2 = int(a2 * 100)
                if a1 == a2:
                    tmp.append('%s' % abs(a1))
                else:
                    tmp.append('%s,%s' % (a1, a2))

            return ' '.join(tmp)

        elif func == 'RTIME':
            tmp = []
            for a1, a2 in t.rTime:
                if a1 == a2:
                    tmp.append('%s' % abs(a1))
                else:
                    tmp.append('%s,%s' % (a1, a2))
            return ' '.join(tmp)

        elif func == 'RVOLUME':
            tmp = []
            for a1, a2 in t.rVolume:
                a1 = int(a1 * 100)
                a2 = int(a2 * 100)
                if a1 == a2:
                    tmp.append('%s' % abs(a1))
                else:
                    tmp.append('%s,%s' % (a1, a2))
            return ' '.join(tmp)

        elif func == 'RPITCH':
            return MMA.rpitch.getOpts(t)

        elif func == 'SEQUENCE':
            tmp = []
            for a in range(gbl.seqSize):
                tmp.append('{' + t.formatPattern(t.sequence[a]) + '}')
            return ' '.join(tmp)

        elif func == 'SEQRND':
            if t.seqRnd:
                return 'On'
            else:
                return 'Off'

        elif func == 'SEQRNDWEIGHT':
            return ' '.join([str(x) for x in t.seqRndWeight])

        elif func == 'SPAN':
            return "%s %s" % (t.spanStart, t.spanEnd)

        elif func == 'STICKY':
            if t.sticky:
                return "True"
            else:
                return "False"

        elif func == 'STRUM':
            r = []
            for v in t.strum:
                if v is None:
                    r.append("0")
                else:
                    a, b = v
                    if a == b:
                        r.append("%s" % a)
                    else:
                        r.append("%s,%s" % (a, b))

            return ' '.join(r)

        elif func == 'STRUMADD':
            return ' '.join([str(x) for x in t.strumAdd])

        elif func == 'TRIGGER':
            return MMA.trigger.getTriggerOptions(t)

        elif func == 'TONE':
            if t.vtype in ('MELODY', 'SOLO'):
                if not t.drumType:
                    error("Melody/Solo tracks must be DRUMTYPE for tone.")
                return str(MMA.midiC.valueToDrum(t.drumTone))

            elif t.vtype != 'DRUM':
                error("Tracktype %s doesn't have TONE" % t.vtype)

            return ' '.join([MMA.midiC.valueToDrum(a) for a in t.toneList])

        elif func == 'UNIFY':
            return ' '.join([str(x) for x in t.unify])

        elif func == 'VOICE':
            return ' '.join([MMA.midiC.valueToInst(a) for a in t.voice])

        elif func == 'VOICING':
            if t.vtype != 'CHORD':
                error("Only CHORD tracks have VOICING")
            t = t.voicing
            return "Mode=%s Range=%s Center=%s RMove=%s Move=%s Dir=%s" % \
                (t.mode, t.range, t.center, t.random, t.bcount, t.dir)

        elif func == 'VOLUME':
            return ' '.join([str(int(a * 100)) for a in t.volume])

        else:
            error("Unknown system track variable %s" % s)
Exemple #3
0
def setTime(ln):
    """ Set the 'time' value. This is NOT a time sig, it
        is the number of quarters/beat.

        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.
    """

    tabList = []
    defaultTabs = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
    sigSet = False

    ln, options = opt2pair(ln, 1)

    for cmd, opt in options:
        if cmd == 'TABS':
            tabList = [stof(i) for i in opt.split(',')]
            if tabList != sorted(tabList):
                error("Time: Tabs must be in order, not %s." % tabList)
            if len(tabList) != len(set(tabList)):
                error("Time: Tabs must not contain duplicates, %s" % tabList)
            if tabList[0] != 1:
                error("Time: First tab must be 1, not %s." % tabList[0])
        else:
            error("TIME: Unknown option '%s'." % cmd)

    if len(ln) != 1:
        error("Time: Too many options. Use TIME BperBar [Tabs=xx].")

    # is this a timesig?

    n = ln[0]
    if n.upper() == 'COMMON':
        n = '4/4'
    elif n.upper() == 'CUT':
        n = '2/2'

    if n in timeTable:
        i = timeTable[n]
        timeSig.setSig([n])
        n = i[0]
        if not tabList:
            tabList = i[1]
        sigSet = True
    else:
        if '/' in n:  # unknown time sig
            error(
                "Time: Unknown timesignature '%s'. You may need to set TIME and TIMESIG separately."
                % n)
        n = stof(n)

        if n < 1 or n > 12:
            error("Time: Value must be 1..12.")

    # If no change, just ignore this.

    origTime = gbl.QperBar
    if origTime != n:
        gbl.QperBar = n
        gbl.barLen = int(gbl.QperBar * gbl.BperQ)

        # Time changes zap all predfined sequences

        for a in gbl.tnames.values():
            if a.riff:
                warning("Time: Change from %s to %s deleting %s riffs." %
                        (origTime, n, a.name))
                a.riff = []
            a.clearSequence()

    if not tabList:
        tabList = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)[:int(gbl.QperBar)]

    # need to do this after setting time.
    if (tabList[-1] - 1) * gbl.BperQ >= gbl.barLen:
        error("Time: Last tab must be < %s, not '%s'." %
              (float(gbl.barLen / gbl.BperQ) + 1, tabList[-1]))

    setChordTabs(tabList)

    if gbl.debug:
        if sigSet:
            sig = "TimeSig %s " % timeSig.getAscii()
        else:
            sig = ''
        print("Time: Time %s %sTabs=%s." %
              (gbl.QperBar, sig, ','.join([str(x) for x in tabList])))
def setTime(ln):
    """ Set the 'time' value. This is NOT a time sig, it
        is the number of quarters/beat.

        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.
    """

    tabList = []
    defaultTabs = (1,2,3,4,5,6,7,8,9,10,11,12)
    sigSet = False

    ln, options = opt2pair(ln, 1)

    for cmd, opt in options:
        if cmd == 'TABS':
            tabList = [ stof(i) for i in opt.split(',')]
            if tabList != sorted(tabList):
                error("Time: Tabs must be in order, not %s." % tabList)
            if len(tabList) != len(set(tabList)):
                error("Time: Tabs must not contain duplicates, %s" % tabList)
            if tabList[0] != 1:
                error("Time: First tab must be 1, not %s." % tabList[0])
        else:
            error("TIME: Unknown option '%s'." % cmd)
        
    if len(ln) != 1:
        error("Time: Too many options. Use TIME BperBar [Tabs=xx].")

    # is this a timesig?

    n = ln[0]
    if n.upper() == 'COMMON':
        n = '4/4'
    elif n.upper() == 'CUT':
        n = '2/2'

    if n in timeTable:
        i = timeTable[n]
        timeSig.setSig([n])
        n = i[0]
        if not tabList:
            tabList = i[1]
        sigSet = True
    else:
        if '/' in n:  # unknown time sig
            error("Time: Unknown timesignature '%s'. You may need to set TIME and TIMESIG separately." % n) 
        n = stof(n)

        if n < 1 or n > 12:
            error("Time: Value must be 1..12.")

    # If no change, just ignore this.

    origTime = gbl.QperBar
    if origTime != n:
        gbl.QperBar = n
        gbl.barLen =  int(gbl.QperBar * gbl.BperQ)

        # Time changes zap all predfined sequences

        for a in gbl.tnames.values():
            if a.riff:
                warning("Time: Change from %s to %s deleting %s riffs." %
                        (origTime, n, a.name))
                a.riff = []
            a.clearSequence()

    if not tabList:
        tabList = (1,2,3,4,5,6,7,8,9,10,11,12)[:int(gbl.QperBar)]

    # need to do this after setting time.
    if (tabList[-1]-1) * gbl.BperQ >= gbl.barLen:
        error("Time: Last tab must be < %s, not '%s'." % 
              (float(gbl.barLen/gbl.BperQ)+1, tabList[-1]))

    setChordTabs(tabList)

    if gbl.debug:
        if sigSet:
            sig =  "TimeSig %s " % timeSig.getAscii()
        else:
            sig = ''
        print ("Time: Time %s %sTabs=%s." % 
               (gbl.QperBar, sig,  ','.join([str(x) for x in tabList])))