Quick actions

cmd+k|ctrl+k

Navigation

Languages

SPEAR decoder

Snippet info

Language

Lua

Visibility

public

Author

thosewhoknow

Created

2024-05-07T19:54:43.188633Z

Updated

2024-05-10T18:43:21.256187Z

-- most of this code is stolen from https://github.com/stephenjbradshaw/SPEAR-to-MIDI
local split = string.split
local gsub = string.gsub

function sublist_index_avg(list, index)
	local sum = 0
	for _, v in list do
		sum += v[index]
	end
	return sum / #list
end

function process_line(line, de)
	local partial = {}
	local split_line = split(line, " ")
	while #split_line > 0 do
		local reachedEnd = false
		local timepoint = {}
		for i = 0, 3 do
			local val = table.remove(split_line, 1)
			if val == nil then
				reachedEnd = true
				break
			end
			local item = gsub(val, ",", ".")
			table.insert(timepoint, item)
		end
		if reachedEnd == true then
			break
		end
		table.insert(partial, timepoint)
	end
	return partial
end

function scaleValue(value, inMin, inMax, outMin, outMax)
	local normalizedValue = (value - inMin) / (inMax - inMin)
	local scaledValue = normalizedValue * (outMax - outMin) + outMin

	return scaledValue
end

return function(data, debugEverything)
	local lines = split(data, "\n")
	-- strip metadata
	for i = 1, 5 do
		table.remove(lines, 1)
	end
	local partials = {}
	for _, v in ipairs(lines) do
		table.insert(partials, process_line(v, debugEverything))
	end
	local min_amp = sublist_index_avg(partials[1], 2)
	local max_amp = sublist_index_avg(partials[1], 2)
	for _, partial in ipairs(partials) do
		local temp_amp = sublist_index_avg(partial, 2)
		if temp_amp < min_amp then
			min_amp = temp_amp
		end
		if temp_amp > max_amp then
			max_amp = temp_amp
		end
	end
	local data = {}
	for _, partial in ipairs(partials) do
		local average_freq = sublist_index_avg(partial, 1)
		local average_amp = sublist_index_avg(partial, 2)
		local volume = scaleValue(average_amp, min_amp, max_amp, 0, 1)
		if partial[1] == nil then
			continue
		end
		local on_time = partial[1][1]
		local off_time = partial[#partial][1]
		table.insert(data, {
			startTime = on_time,
			endTime = off_time,
			freq = average_freq,
			vol_mult = volume
		})
	end
	return data
end
INFO