Skip to content
Permalink
main
Go to file
 
 
Cannot retrieve contributors at this time
233 lines (196 sloc) 11 KB
--- Envelope graph drawing module.
-- Subclass of Graph for drawing common envelope graphs. Includes DADSR, ADSR, ASR and AR (Perc).
--
-- @module lib.EnvGraph
-- @release v1.0.1
-- @author Mark Eats
local EnvGraph = {}
EnvGraph.__index = EnvGraph
local Graph = require "graph"
-------- Private utility methods --------
local function new_env_graph(x_min, x_max, y_min, y_max)
local graph = Graph.new(x_min, x_max, "lin", y_min, y_max, "lin", "line_and_point", false, false)
setmetatable(EnvGraph, {__index = Graph})
setmetatable(graph, EnvGraph)
return graph
end
local function set_env_values(self, delay, attack, decay, sustain, release, level, curve)
if not self._env then self._env = {} end
if delay then self._env.delay = math.max(0, delay) end
if attack then self._env.attack = math.max(0, attack) end
if decay then self._env.decay = math.max(0, decay) end
if sustain then self._env.sustain = util.clamp(sustain, 0, 1) end
if release then self._env.release = math.max(0, release) end
if level then self._env.level = util.clamp(level, self._y_min, self._y_max) end
if curve then self._env.curve = curve end
end
-------- Public methods --------
--- Create a new DADSR EnvGraph object.
-- All arguments optional.
-- @tparam number x_min Minimum value for x axis, defaults to 0.
-- @tparam number x_max Maximum value for x axis, defaults to 1.
-- @tparam number y_min Minimum value for y axis, defaults to 0.
-- @tparam number y_max Maximum value for y axis, defaults to 1.
-- @tparam number delay Delay value, defaults to 0.1
-- @tparam number attack Attack value, defaults to 0.05.
-- @tparam number decay Decay value, defaults to 0.2.
-- @tparam number sustain Sustain value, accepts 0-1, defaults to 0.5.
-- @tparam number release Release value, defaults to 0.3.
-- @tparam number level Level value, accepts y_min to y_max, defaults to 1.
-- @tparam string|number curve Curve of envelope, accepts "lin", "exp" or a number where 0 is linear and positive and negative numbers curve the envelope up and down, defaults to -4.
-- @treturn EnvGraph Instance of EnvGraph.
function EnvGraph.new_dadsr(x_min, x_max, y_min, y_max, delay, attack, decay, sustain, release, level, curve)
local graph = new_env_graph(x_min, x_max, y_min, y_max)
set_env_values(graph, delay or 0.1, attack or 0.05, decay or 0.2, sustain or 0.5, release or 0.3, level or 1, curve or -4)
graph:add_point(0, 0)
graph:add_point(graph._env.delay, 0)
graph:add_point(graph._env.delay + graph._env.attack, graph._env.level, graph._env.curve)
graph:add_point(graph._env.delay + graph._env.attack + graph._env.decay, graph._env.level * graph._env.sustain, graph._env.curve)
graph:add_point(graph._x_max - graph._env.release, graph._env.level * graph._env.sustain, graph._env.curve)
graph:add_point(graph._x_max, 0, graph._env.curve)
return graph
end
--- Edit a DADSR EnvGraph object.
-- All arguments optional.
-- @tparam number delay Delay value.
-- @tparam number attack Attack value.
-- @tparam number decay Decay value.
-- @tparam number sustain Sustain value, accepts 0-1.
-- @tparam number release Release value.
-- @tparam number level Level value, accepts y_min to y_max.
-- @tparam string|number curve Curve of envelope, accepts "lin", "exp" or a number where 0 is linear and positive and negative numbers curve the envelope up and down, defaults to -4.
function EnvGraph:edit_dadsr(delay, attack, decay, sustain, release, level, curve)
if #self._points ~= 6 then return end
set_env_values(self, delay, attack, decay, sustain, release, level, curve)
self:edit_point(2, self._env.delay)
self:edit_point(3, self._env.delay + self._env.attack, self._env.level, self._env.curve)
self:edit_point(4, self._env.delay + self._env.attack + self._env.decay, self._env.level * self._env.sustain, self._env.curve)
self:edit_point(5, self._x_max - self._env.release, self._env.level * self._env.sustain, self._env.curve)
self:edit_point(6, nil, nil, self._env.curve)
end
--- Create a new ADSR EnvGraph object.
-- All arguments optional.
-- @tparam number x_min Minimum value for x axis, defaults to 0.
-- @tparam number x_max Maximum value for x axis, defaults to 1.
-- @tparam number y_min Minimum value for y axis, defaults to 0.
-- @tparam number y_max Maximum value for y axis, defaults to 1.
-- @tparam number attack Attack value, defaults to 0.05.
-- @tparam number decay Decay value, defaults to 0.2.
-- @tparam number sustain Sustain value, accepts 0-1, defaults to 0.5.
-- @tparam number release Release value, defaults to 0.3.
-- @tparam number level Level value, accepts y_min to y_max, defaults to 1.
-- @tparam string|number curve Curve of envelope, accepts "lin", "exp" or a number where 0 is linear and positive and negative numbers curve the envelope up and down, defaults to -4.
-- @treturn EnvGraph Instance of EnvGraph.
function EnvGraph.new_adsr(x_min, x_max, y_min, y_max, attack, decay, sustain, release, level, curve)
local graph = new_env_graph(x_min, x_max, y_min, y_max)
set_env_values(graph, nil, attack or 0.05, decay or 0.2, sustain or 0.5, release or 0.3, level or 1, curve or -4)
graph:add_point(0, 0)
graph:add_point(graph._env.attack, graph._env.level, graph._env.curve)
graph:add_point(graph._env.attack + graph._env.decay, graph._env.level * graph._env.sustain, graph._env.curve)
graph:add_point(graph._x_max - graph._env.release, graph._env.level * graph._env.sustain, graph._env.curve)
graph:add_point(graph._x_max, 0, graph._env.curve)
return graph
end
--- Edit an ADSR EnvGraph object.
-- All arguments optional.
-- @tparam number attack Attack value.
-- @tparam number decay Decay value.
-- @tparam number sustain Sustain value, accepts 0-1.
-- @tparam number release Release value.
-- @tparam number level Level value, accepts y_min to y_max.
-- @tparam string|number curve Curve of envelope, accepts "lin", "exp" or a number where 0 is linear and positive and negative numbers curve the envelope up and down, defaults to -4.
function EnvGraph:edit_adsr(attack, decay, sustain, release, level, curve)
if #self._points ~= 5 then return end
set_env_values(self, nil, attack, decay, sustain, release, level, curve)
self:edit_point(2, self._env.attack, self._env.level, self._env.curve)
self:edit_point(3, self._env.attack + self._env.decay, self._env.level * self._env.sustain, self._env.curve)
self:edit_point(4, self._x_max - self._env.release, self._env.level * self._env.sustain, self._env.curve)
self:edit_point(5, nil, nil, self._env.curve)
end
--- Create a new ASR EnvGraph object.
-- All arguments optional.
-- @tparam number x_min Minimum value for x axis, defaults to 0.
-- @tparam number x_max Maximum value for x axis, defaults to 1.
-- @tparam number y_min Minimum value for y axis, defaults to 0.
-- @tparam number y_max Maximum value for y axis, defaults to 1.
-- @tparam number attack Attack value, defaults to 0.05.
-- @tparam number release Release value, defaults to 0.3.
-- @tparam number level Level value, accepts y_min to y_max, defaults to 1.
-- @tparam string|number curve Curve of envelope, accepts "lin", "exp" or a number where 0 is linear and positive and negative numbers curve the envelope up and down, defaults to -4.
-- @treturn EnvGraph Instance of EnvGraph.
function EnvGraph.new_asr(x_min, x_max, y_min, y_max, attack, release, level, curve)
local graph = new_env_graph(x_min, x_max, y_min, y_max)
set_env_values(graph, nil, attack or 0.05, nil, nil, release or 0.3, level or 1, curve or -4)
graph:add_point(0, 0)
graph:add_point(graph._env.attack, graph._env.level, graph._env.curve)
graph:add_point(graph._x_max - graph._env.release, graph._env.level, graph._env.curve)
graph:add_point(graph._x_max, 0, graph._env.curve)
return graph
end
--- Edit an ASR EnvGraph object.
-- All arguments optional.
-- @tparam number attack Attack value.
-- @tparam number release Release value.
-- @tparam number level Level value, accepts y_min to y_max.
-- @tparam string|number curve Curve of envelope, accepts "lin", "exp" or a number where 0 is linear and positive and negative numbers curve the envelope up and down, defaults to -4.
function EnvGraph:edit_asr(attack, release, level, curve)
if #self._points ~= 4 then return end
set_env_values(self, nil, attack, nil, nil, release, level, curve)
self:edit_point(2, self._env.attack, self._env.level, self._env.curve)
self:edit_point(3, self._x_max - self._env.release, self._env.level, self._env.curve)
self:edit_point(4, nil, nil, self._env.curve)
end
--- Create a new AR (Perc) EnvGraph object.
-- All arguments optional.
-- @tparam number x_min Minimum value for x axis, defaults to 0.
-- @tparam number x_max Maximum value for x axis, defaults to 1.
-- @tparam number y_min Minimum value for y axis, defaults to 0.
-- @tparam number y_max Maximum value for y axis, defaults to 1.
-- @tparam number attack Attack value, defaults to 0.05.
-- @tparam number release Release value, defaults to 0.3.
-- @tparam number level Level value, accepts y_min to y_max, defaults to 1.
-- @tparam string|number curve Curve of envelope, accepts "lin", "exp" or a number where 0 is linear and positive and negative numbers curve the envelope up and down, defaults to -4.
-- @treturn EnvGraph Instance of EnvGraph.
function EnvGraph.new_ar(x_min, x_max, y_min, y_max, attack, release, level, curve)
local graph = new_env_graph(x_min, x_max, y_min, y_max)
set_env_values(graph, nil, attack or 0.1, nil, nil, release or 0.9, level or 1, curve or -4)
graph:add_point(0, 0)
graph:add_point(graph._env.attack, graph._env.level, graph._env.curve)
graph:add_point(graph._env.attack + graph._env.release, 0, graph._env.curve)
return graph
end
--- Edit an AR (Perc) EnvGraph object.
-- All arguments optional.
-- @tparam number attack Attack value.
-- @tparam number release Release value.
-- @tparam number level Level value, accepts y_min to y_max.
-- @tparam string|number curve Curve of envelope, accepts "lin", "exp" or a number where 0 is linear and positive and negative numbers curve the envelope up and down, defaults to -4.
function EnvGraph:edit_ar(attack, release, level, curve)
if #self._points ~= 3 then return end
set_env_values(self, nil, attack, nil, nil, release, level, curve)
self:edit_point(2, self._env.attack, self._env.level, self._env.curve)
self:edit_point(3, self._env.attack + self._env.release, nil, self._env.curve)
end
-- Getters
--- Get delay value.
-- @treturn number Delay value.
function EnvGraph:get_delay() return self._env.delay end
--- Get attack value.
-- @treturn number Attack value.
function EnvGraph:get_attack() return self._env.attack end
--- Get decay value.
-- @treturn number Decay value.
function EnvGraph:get_decay() return self._env.decay end
--- Get sustain value.
-- @treturn number Sustain value.
function EnvGraph:get_sustain() return self._env.sustain end
--- Get release value.
-- @treturn number Release value.
function EnvGraph:get_release() return self._env.release end
--- Get level value.
-- @treturn number Level value.
function EnvGraph:get_level() return self._env.level end
--- Get curve value.
-- @treturn string|number Curve value.
function EnvGraph:get_curve() return self._env.curve end
return EnvGraph