Эх сурвалжийг харах

Tools to make GRUB_INIT_TUNEs!

Graham Northup 8 жил өмнө
parent
commit
19d054741b
4 өөрчлөгдсөн 187 нэмэгдсэн , 4 устгасан
  1. 117 0
      downsamp.py
  2. 3 0
      mkiv.py
  3. 63 0
      mktune.py
  4. 4 4
      shiv.py

+ 117 - 0
downsamp.py

@@ -0,0 +1,117 @@
+from xml.etree import ElementTree as ET
+import optparse
+import os
+
+parser = optparse.OptionParser()
+parser.add_option('-f', '--frequency', dest='frequency', type='float', help='How often to switch between active streams')
+parser.set_defaults(frequency=0.016)
+options, args = parser.parse_args()
+
+class Note(object):
+    def __init__(self, time, dur, pitch, ampl):
+        self.time = time
+        self.dur = dur
+        self.pitch = pitch
+        self.ampl = ampl
+
+for fname in args:
+    try:
+        iv = ET.parse(fname).getroot()
+    except IOError:
+        import traceback
+        traceback.print_exc()
+        print fname, ': Bad file'
+        continue
+
+    print '----', fname, '----'
+
+    notestreams = iv.findall("./streams/stream[@type='ns']")
+    print len(notestreams), 'notestreams'
+
+    print 'Loading all events...'
+
+    evs = []
+
+    dur = 0.0
+
+    for ns in notestreams:
+        for note in ns.findall('note'):
+            n = Note(
+                float(note.get('time')),
+                float(note.get('dur')),
+                float(note.get('pitch')),
+                float(note.get('ampl', float(note.get('vel', 127.0)) / 127.0)),
+            )
+            evs.append(n)
+            if n.time + n.dur > dur:
+                dur = n.time + n.dur
+
+    print len(evs), 'events'
+    print dur, 'duration'
+
+    print 'Scheduling events...'
+
+    sched = {}
+
+    t = 0.0
+    i = 0
+    while t <= dur:
+        nextt = t + options.frequency
+        #print '-t', t, 'nextt', nextt
+
+        evs_now = [n for n in evs if n.time <= t and t < n.time + n.dur]
+        if evs_now:
+            holding = False
+            count = 0
+            while count < len(evs_now):
+                selidx = (count + i) % len(evs_now)
+                sel = evs_now[selidx]
+                sched[t] = (sel.pitch, sel.ampl)
+                if sel.time + sel.dur >= nextt:
+                    holding = True
+                    break
+                t = sel.time + sel.dur
+                count += 1
+            if not holding:
+                sched[t] = (0, 0)
+        else:
+            sched[t] = (0, 0)
+
+        t = nextt
+        i += 1
+
+    print len(sched), 'events scheduled'
+
+    print 'Writing out schedule...'
+
+    newiv = ET.Element('iv')
+    newiv.append(iv.find('meta'))
+    newivstreams = ET.SubElement(newiv, 'streams')
+    newivstream = ET.SubElement(newivstreams, 'stream', type='ns')
+
+    prevt = None
+    prevev = None
+    for t, ev in sorted(sched.items(), key=lambda pair: pair[0]):
+        if prevt is not None:
+            if prevev[0] != 0:
+                ET.SubElement(newivstream, 'note',
+                        pitch = str(prevev[0]),
+                        ampl = str(prevev[1]),
+                        time = str(prevt),
+                        dur = str(t - prevt),
+                )
+        prevev = ev
+        prevt = t
+
+    t = dur
+    if prevev[0] != 0:
+        ET.SubElement(newivstream, 'note',
+                pitch = str(prevev[0]),
+                ampl = str(prevev[1]),
+                time = str(prevt),
+                dur = str(t - prevt),
+        )
+
+    print 'Done.'
+    txt = ET.tostring(newiv, 'UTF-8')
+    open(os.path.splitext(os.path.basename(fname))[0]+'.downsampled.iv', 'wb').write(txt)

+ 3 - 0
mkiv.py

@@ -705,6 +705,9 @@ for fname in args:
         ivev.set('time', str(mev.abstime))
         ivev.set('time', str(mev.abstime))
         ivev.set('data', repr(fw.encode_midi_event(mev.ev)))
         ivev.set('data', repr(fw.encode_midi_event(mev.ev)))
 
 
+    ivargs = ET.SubElement(ivmeta, 'args')
+    ivargs.text = ' '.join('%r' % (i,) for i in sys.argv[1:])
+
     print 'Done.'
     print 'Done.'
     txt = ET.tostring(iv, 'UTF-8')
     txt = ET.tostring(iv, 'UTF-8')
     open(os.path.splitext(os.path.basename(fname))[0]+'.iv', 'wb').write(txt)
     open(os.path.splitext(os.path.basename(fname))[0]+'.iv', 'wb').write(txt)

+ 63 - 0
mktune.py

@@ -0,0 +1,63 @@
+from xml.etree import ElementTree as ET
+import optparse
+
+parser = optparse.OptionParser()
+parser.add_option('-t', '--tempo', dest='tempo', type='float', help='Tempo (in BPM)')
+parser.add_option('-r', '--resolution', dest='resolution', type='float', help='Approximate resolution in seconds (overrides tempo)')
+parser.add_option('-f', '--float', dest='float', action='store_true', help='Allow floating point representations on output')
+parser.add_option('-T', '--transpose', dest='transpose', type='float', help='Transpose by this many semitones')
+parser.set_defaults(tempo=60000, resolution=None, transpose=0)
+options, args = parser.parse_args()
+
+maybe_int = int
+if options.float:
+    maybe_int = float
+
+class Note(object):
+    def __init__(self, time, dur, pitch, ampl):
+        self.time = time
+        self.dur = dur
+        self.pitch = pitch
+        self.ampl = ampl
+
+if options.resolution is not None:
+    options.tempo = 60.0 / options.resolution
+
+options.tempo = maybe_int(options.tempo)
+
+def to_beats(tm):
+    return options.tempo * tm / 60.0
+
+for fname in args:
+    try:
+        iv = ET.parse(fname).getroot()
+    except IOError:
+        import traceback
+        traceback.print_exc()
+        print fname, ': Bad file'
+        continue
+
+    print options.tempo,
+
+    ns = iv.find('./streams/stream[@type="ns"]')
+    prevn = None
+    for note in ns.findall('note'):
+        n = Note(
+            float(note.get('time')),
+            float(note.get('dur')),
+            float(note.get('pitch')) + options.transpose,
+            float(note.get('ampl', float(note.get('vel', 127.0)) / 127.0)),
+        )
+        if prevn is not None:
+            rtime = to_beats(n.time - (prevn.time + prevn.dur))
+            if rtime >= 1:
+                print 0, maybe_int(rtime),
+            ntime = to_beats(prevn.dur)
+            if ntime < 1 and not options.float:
+                ntime = 1
+            print maybe_int(440.0 * 2**((prevn.pitch-69)/12.0)), maybe_int(ntime),
+        prevn = n
+    ntime = to_beats(n.dur)
+    if ntime < 1 and not options.float:
+        ntime = 1
+    print int(440.0 * 2**((n.pitch-69)/12.0)), int(ntime),

+ 4 - 4
shiv.py

@@ -202,7 +202,7 @@ for fname in args:
         notes = stream.findall('note')
         notes = stream.findall('note')
         for note in notes:
         for note in notes:
             pitch = float(note.get('pitch'))
             pitch = float(note.get('pitch'))
-            vel = int(note.get('vel'))
+            ampl = float(note.get('ampl', float(note.get('vel', 127.0)) / 127.0))
             time = float(note.get('time'))
             time = float(note.get('time'))
             dur = float(note.get('dur'))
             dur = float(note.get('dur'))
             if options.notes:
             if options.notes:
@@ -218,11 +218,11 @@ for fname in args:
             if options.histogram_tracks:
             if options.histogram_tracks:
                 pitch_tracks[sidx][pitch] = pitch_tracks[sidx].get(pitch, 0) + 1
                 pitch_tracks[sidx][pitch] = pitch_tracks[sidx].get(pitch, 0) + 1
             if options.vel_hist:
             if options.vel_hist:
-                velocities[vel] = velocities.get(vel, 0) + 1
+                velocities[ampl] = velocities.get(ampl, 0) + 1
                 if options.total:
                 if options.total:
-                    tot_velocities[vel] = tot_velocities.get(vel, 0) + 1
+                    tot_velocities[ampl] = tot_velocities.get(ampl, 0) + 1
             if options.vel_hist_tracks:
             if options.vel_hist_tracks:
-                velocities_tracks[sidx][vel] = velocities_tracks[sidx].get(vel, 0) + 1
+                velocities_tracks[sidx][ampl] = velocities_tracks[sidx].get(ampl, 0) + 1
             if (options.duration or options.duty_cycle) and time + dur > max_dur:
             if (options.duration or options.duty_cycle) and time + dur > max_dur:
                 max_dur = time + dur
                 max_dur = time + dur
             if options.duty_cycle:
             if options.duty_cycle: