svg - How do I draw a EQ Curve based on 8 bandpoints? - Stack Overflow

I'm working on drawing an EQ curve using Lua and the EzSVG library, based on 8 bandpoints and filt

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

相关推荐

  • svg - How do I draw a EQ Curve based on 8 bandpoints? - Stack Overflow

    I'm working on drawing an EQ curve using Lua and the EzSVG library, based on 8 bandpoints and filt

    2天前
    100

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信