Commit 019d9fe8 authored by jhammen's avatar jhammen
Browse files

add script to measure velocity curves

parent 9db2cb3f
/**
*
* This script creates a CSV of lufs output vs velocity values for a given MIDI note
*
*/
// TODO: calculate some kind of deviation
//drum_input <- "a2j:AIR 192 8 [28] (playback): AIR 192 8 MIDI 1"
//drum_out1 <- "system:capture_1"
//drum_out2 <- "system:capture_2"
drum_input <- "handrumr2.lv2:control"
drum_out1 <- "handrumr2.lv2:out_l"
drum_out2 <- "handrumr2.lv2:out_r"
midiout <- Midi.Output("output", drum_input) // to drum-sampler (-plugin, -machine..)
input <- Audio.StereoInput("input") // from sampler
monitor <- Audio.StereoOutput("monitor", true)
// [drum-out1, drum-out2] => input
input.connect(0, drum_out1)
input.connect(1, drum_out2)
local note = 38
local channel = 9
// TODO should be an arg of some kind
local samples = 2 // how many samples to take of each velocity
dbs <- []
local measure = 2.0
for(local v = 1; v <= 127; v++) {
while(dbs.len() < v + 1) {
dbs.append([])
}
for(local i = 0; i < samples; i++) {
//send MIDI note to drums
local note = Midi.Note(note, v, 0.5, channel)
midiout.schedule(note, measure)
// grab and measure result
local vel = v // closure
input.grab(1.0, function(clip) {
// print("velocity " + vel)
monitor.play(clip)
// println(" lufs " + clip.lufs())
dbs[vel].append(clip.lufs())
}, measure)
// advance measure per hit
measure += 1.0
}
}
function equals(a1, a2) {
if(a1.len() != a2.len()) {
return false
}
foreach(i, v in a1) {
if(a2.find(v) == null) {
return false
}
}
return true
}
function printReport() {
// calculate layers
local layer = { low = 1, dbs = dbs[1] }
local layers = []
for(local v = 2; v < 128; v++) {
if(v in dbs && !equals(dbs[v], layer.dbs)) {
layer.hi <- v - 1
layers.append(layer)
layer = { low = v, dbs = dbs[v] }
}
}
layer.hi <- 127 // wrap up last layer
layers.append(layer)
// start stdout report
println("Gains Envelope Report")
println("midi out: " + drum_input)
println("midi note: " + note)
// get baseline value
local baseline = 0.0
if(64 in dbs && dbs[64].len()) {
baseline = dbs[64].reduce(@(a, b) a + b) / dbs[64].len()
}
println("baseline value at velocity 64 is " + baseline)
println("\ndetected layers:")
// calculate and print averages
foreach(i, layer in layers) {
print((i + 1) + ".\t" + layer.low + " - " + layer.hi + "\t")
local sum = layer.dbs.reduce(@(a, b) a + b)
layer.avg <- 0.0
if(sum != null) {
local avg = sum / layer.dbs.len()
layer.avg = avg - baseline
print(layer.avg + "\t[")
}
layer.dbs.sort()
foreach(i, db in layer.dbs) {
if(i) print(", ")
print(db - baseline)
}
println("]")
}
local csv = "velocity\tlufs\n"
foreach(i, layer in layers) {
csv += layer.low + "\t" + layer.avg + "\n"
if(layer.hi != layer.low) {
csv += layer.hi + "\t" + layer.avg + "\n"
}
}
local time = System.Time()
local outfile = "vcurve_" + time.date() + "_" + time.time() + ".csv"
IO.File(outfile).writeAll(csv)
println("\nwrote data to " + outfile)
}
Script.schedule(function(m) { printReport() }, measure + 2)
Time.def.tempo = 90
Time.def.start()
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment