I'm working on drawing an EQ curve using Lua and the EzSVG library, based on 8 bandpoints and filters. However, the EQ curve isn't rendering as expected, and I'm unsure how to base the calculations for the curve properly. I don't have much experience with audio processing or equalizers, so I need help understanding how to calculate the curve based on the bandpoints and filters.
Here’s the core of my implementation:
local Props = Properties["Channel Count"].Value
CurrentChannel = 1
SelectedBandPoint = 1
local Channels = {}
for i = 1, Props do
local channel = {
Name = "Channel " .. i,
Display = "",
High_PassFilter = 20,
Low_PassFilter = 20000,
LinkGroup = nil,
Bandpoints = {},
Filters = {}
}
table.insert(channel.Bandpoints, {freq = 23.3, gain = 0, BW = 1.0,fill="#996633", offcolor="#472E16"})
table.insert(channel.Bandpoints, {freq = 54.1, gain = 0, BW = 1.0,fill="#FF0000", offcolor="#7C0000"})
table.insert(channel.Bandpoints, {freq = 126, gain = 0, BW = 1.0,fill="#FF9900", offcolor="#7C4700"})
table.insert(channel.Bandpoints, {freq = 293, gain = 0, BW = 1.0,fill="#FFFF00", offcolor="#7C7C00"})
table.insert(channel.Bandpoints, {freq = 682, gain = 0, BW = 1.0,fill="#00FF00", offcolor="#007C00"})
table.insert(channel.Bandpoints, {freq = 1590, gain = 0, BW = 1.0,fill="#0000FF", offcolor="#00007C"})
table.insert(channel.Bandpoints, {freq = 3690, gain = 0, BW = 1.0,fill="#FF00FF", offcolor="#7C007C"})
table.insert(channel.Bandpoints, {freq = 8600, gain = 0, BW = 1.0,fill="#CCCCCC", offcolor="#626262"})
--[High-Pass Filter]--
table.insert(channel.Filters, {freq = 20, gain = -6, fill="#000000"})
--[Low-Pass Filter]--
table.insert(channel.Filters, {freq = 20000, gain = -6, fill="#000000"})
table.insert(Channels, channel)
end
function draw()
local doc = EzSVG.Document(1045, 598) -- SVG canvas size
local grid_left = 64.686971 -- Leftmost grid line
local grid_right = 1044.5671 -- Rightmost grid line
local grid_top = 26.333343 -- Topmost grid line
local grid_bottom = 586.12834 -- Bottommost grid line
local BackgroundGroup = EzSVG.Group()
EzSVG.setStyle({
stroke_width = 1.73,
stroke = Controls["Colors Background"].String,
fill = Controls["Colors Background"].String
})
doc:add(BackgroundGroup)
local function get_x_position(freq)
local min_freq = 20
local max_freq = 20000
local x_pos = grid_left + (math.log(freq) - math.log(min_freq)) / (math.log(max_freq) - math.log(min_freq)) * (grid_right - grid_left)
return x_pos
end
local function get_y_position(gain)
local min_gain = 20
local max_gain = -20
local y_pos = grid_top + ((gain - min_gain) / (max_gain - min_gain)) * (grid_bottom - grid_top)
return y_pos
end
if Controls["Show Grid"].Value == 1.0 then
local GridGroup = EzSVG.Group()
EzSVG.setStyle({
stroke_width = 1.73,
stroke = Controls["Colors Grid"].String
})
-- Vertical grid lines
local vertical_positions = {1044.5671, 547.17588, 64.686971, 122.15287, 162.98117,
194.62317, 220.54914, 242.3923, 261.37748, 278.01503, 293.01945,
391.31368, 448.77957, 489.60792, 521.24988, 569.01904, 588.00422,
604.64177, 619.64619, 717.94042, 775.40631, 816.23465, 847.87662,
873.80262, 895.64578, 914.63096, 931.26851, 946.27293 }
for _, x in ipairs(vertical_positions) do
GridGroup:add(EzSVG.Line(x, 25.822773, x, 586.63892))
end
-- Horizontal grid lines
local horizontal_positions = {26.333343, 96.282193, 166.23103, 236.282,
306.23083, 376.17968, 446.23065, 516.17949, 586.12834}
for _, y in ipairs(horizontal_positions) do
GridGroup:add(EzSVG.Line(63.666271, y, 1045.5879, y))
end
doc:add(GridGroup)
end
if Controls["Show Band Points"].Value == 1.0 then
local BandPointsGroup = EzSVG.Group()
local bandpoint_radius = 9
local bandpoint_radius_selected = 11
for i, point in ipairs(Channels[CurrentChannel].Bandpoints) do
local x_pos = get_x_position(point.freq)
local y_pos = get_y_position(point.gain)-- grid_top + (graph_height / 2)
local radius = (i == SelectedBandPoint) and bandpoint_radius_selected or bandpoint_radius
if x_pos then
local circle = EzSVG.Circle(x_pos, y_pos, radius, {
fill = point.fill,
stroke = Controls["Colors Labels"].String,
stroke_width = 1.5
})
BandPointsGroup:add(circle)
end
end
for _, filter in ipairs(Channels[CurrentChannel].Filters) do
local x_pos = get_x_position(filter.freq)
local y_pos = get_y_position(filter.gain)
if x_pos then
local circle = EzSVG.Circle(x_pos, y_pos, bandpoint_radius, {
fill = filter.fill,
stroke = Controls["Colors Labels"].String,
stroke_width = 1.5
})
BandPointsGroup:add(circle)
end
end
doc:add(BandPointsGroup)
end
if Controls["Show EQ Curve"].Value == 1.0 then
local EQCurveGroup = EzSVG.Group()
local path = EzSVG.Path({
stroke = Controls["Colors EQ Curve"].String,
stroke_width = 2,
fill = Controls["Colors EQ Curve"].String,
fill_opacity = "0.2"
})
local graph_width = grid_right - grid_left
local graph_height = grid_bottom - grid_top
local x_offset = grid_left
local y_offset = grid_top
local min_freq = 20
local max_freq = 20000
local num_points = 150
local function interpolate_gain(freq)
local points = {}
for _, bp in ipairs(Channels[CurrentChannel].Bandpoints) do
table.insert(points, bp)
end
for _, filter in ipairs(Channels[CurrentChannel].Filters) do
table.insert(points, filter)
end
table.sort(points, function(a, b) return a.freq < b.freq end)
local HPF = Channels[CurrentChannel].Filters[1]
local LPF = Channels[CurrentChannel].Filters[2]
if freq < HPF.freq then
local alpha = 0.05 -- Controls steepness
return HPF.gain * math.exp(-alpha * (HPF.freq - freq))
end
if freq > LPF.freq then
local alpha = 0.05
return LPF.gain * math.exp(-alpha * (freq - LPF.freq))
end
local prev, next = points[1], points[#points]
for i = 1, #points - 1 do
if points[i].freq <= freq and points[i + 1].freq >= freq then
prev = points[i]
next = points[i + 1]
break
end
end
local t = (math.log(freq) - math.log(prev.freq)) / (math.log(next.freq) - math.log(prev.freq))
return prev.gain * (1 - t) + next.gain * t
end
path:moveToA(get_x_position(0),get_y_position(-6))
path:lineToA(get_x_position(0),get_y_position(-6))
for i = 0, num_points do
local freq = min_freq * ((max_freq / min_freq) ^ (i / num_points))
local gain = interpolate_gain(freq)
local x_pos = x_offset + ((math.log(freq) - math.log(min_freq)) / (math.log(max_freq) - math.log(min_freq))) * graph_width
local y_pos = y_offset + ((1 - ((gain + 18) / 36)) * graph_height)
if i == 0 then
path:moveToA(x_pos, y_pos)
else
path:lineToA(x_pos, y_pos)
end
end
EQCurveGroup:add(path)
doc:add(EQCurveGroup)
end
if Controls["Show Axes"].Value == 1.0 then
local BandLabelsGroup = EzSVG.Group()
doc:add(BandLabelsGroup)
end
return doc:toString("Design\\eq-graph.svg")
end
Result: myEQCurve
What I'm trying to create: endgoal
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744852845a4597230.html
评论列表(0条)