예제 #1
0
def main(g):
    # Ensure the BPM is a float, not an integer
    g['bpm'] = float(g['bpm'])
    
    # Convert each gimmick line into a set of BPMs and stops.
    t = {
        'bpms': {0: g['bpm']},
        'stops': {},
    }
    gimmicks = sorted(((str(a), str(b)) for a, b in g['gimmicks'].iteritems()),
                      key=(lambda t: str(t[0]).split('-')[0]))
    for i, gimmick in enumerate(gimmicks):
        parse_gimmick(g, t, gimmicks, gimmick,
                      gimmicks[i + 1] if i + 1 < len(gimmicks) else None)
    
    # Sort BPMs and stops
    last_bpm = None
    rtn = {}
    for timing in ('bpms', 'stops'):
        tlist = []
        while t[timing]:
            k = min(t[timing].keys())
            v = t[timing].pop(k)
            if timing == 'bpms' and v == last_bpm:
                continue
            tlist.append('%s=%s' % (decimal_from_192nd(k),
                                    decimal_from_192nd(v)))
            if timing == 'bpms':
                last_bpm = v
        rtn[timing.upper()] = Timing(','.join(tlist))
    
    return rtn
예제 #2
0
def parse_gimmick(g, t, gimmicks, gimmick, nextgimmick):
    beats = gimmick[0]
    gimmick = gimmick[1].split()
    
    # Copy gimmicks
    if gimmick[0] == 'copy':
        start, stop = parse_beats(beats,
            nextgimmick[0] if nextgimmick else None, None)
        copy_start = float(gimmick[1])
        copy_stop = copy_start + stop - start
        offset = start - copy_start
        for j, copy_gimmick in enumerate(gimmicks):
            if (copy_start <=
                    parse_beats(copy_gimmick[0], '0', 0)[0] <
                    copy_stop):
                parse_gimmick(g, t, gimmicks,
                              add_offset(copy_gimmick, offset),
                              add_offset(gimmicks[j + 1], offset)
                              if j + 1 < len(gimmicks) else None)
        return
    
    # Split the gimmick into its segments
    try:
        length, mul, name = gimmick
    except ValueError:
        raise ValueError("%s is not of the form 'length mul name'")
    length = float(Fraction(length)) * 4
    mul = float(Fraction(mul.rstrip('x')))
    start, stop = parse_beats(beats,
                                   nextgimmick[0] if nextgimmick else None,
                                   length)
    full_length = stop - start
    
    if 'definitions' in g and name in g['definitions']:
        definition = g['definitions'][name]
    elif name in builtin_gimmicks:
        definition = builtin_gimmicks[name]
    
    for timing in ('bpms', 'stops'):
        if timing in definition:
            for loc, eq in definition[timing].iteritems():
                loc = float(loc)
                pos = start + length * loc
                val = eval(eq, {
                    '__builtins__': None,
                    'mul': mul,
                    'len': length,
                    'bpm': g['bpm'],
                })
                while decimal_from_192nd(pos) < decimal_from_192nd(stop):
                    t[timing][pos] = val
                    pos += length
            
            if timing == 'bpms':
                t['bpms'][stop] = g['bpm']