-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.py
More file actions
71 lines (58 loc) · 3 KB
/
utils.py
File metadata and controls
71 lines (58 loc) · 3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
from mido import *
import random
class LogicHandler:
@staticmethod
def humanizeMidi(mid, trackParams: dict):
newMidi = MidiFile(ticks_per_beat=mid.ticks_per_beat)
for trackIndex, track in enumerate(mid.tracks):
newTrack = MidiTrack()
newMidi.tracks.append(newTrack)
params: dict = trackParams.get(trackIndex, None)
if params is None: continue
timeRange: int = params.get("timeRange", 0)
durationRange: int = params.get("durationRange", 0)
velocityRange: int = params.get("velocityRange", 0)
durationPrecentage: float = params.get("durationPrecent", 0.0)
absTime = 0
events = []
for msg in track:
absTime += msg.time
events.append({"absTime": absTime, "msg": msg})
activeNotes = {}
processedEvents = []
for event in events:
msg = event["msg"]
if msg.type == "note_on" and msg.velocity > 0:
key = (msg.channel, msg.note)
activeNotes[key] = event
elif msg.type == "note_off" or (msg.type == "note_on" and msg.velocity == 0):
key = (msg.channel, msg.note)
if key in activeNotes:
note_on = activeNotes.pop(key)
note_off = event
originalDuration = note_off["absTime"] - note_on["absTime"]
reducedDuration = int(originalDuration * (1 - durationPrecentage / 100.0))
note_off["absTime"] = note_on["absTime"] + reducedDuration
timeOffset = random.randint(0, timeRange)
durationOffset = random.randint(-timeRange, durationRange)
velocityOffset = random.randint(-timeRange, velocityRange)
note_on["absTime"] += timeOffset
note_off["absTime"] += timeOffset
note_off["absTime"] += durationOffset
if note_on["absTime"] >= note_off["absTime"]:
note_off['absTime'] = note_on['absTime'] + 1
newVelocity = note_on["msg"].velocity + velocityOffset
note_on["msg"] = note_on["msg"].copy(velocity=min(max(newVelocity, 1), 127))
processedEvents.extend([note_on, note_off])
else:
processedEvents.append(event)
else:
processedEvents.append(event)
processedEvents.sort(key=lambda x: x["absTime"])
lastTime = 0
for event in processedEvents:
delta = event["absTime"] - lastTime
newMsg = event['msg'].copy(time=delta)
newTrack.append(newMsg)
lastTime = event['absTime']
return newMidi