Gest

Gest

Some lua abstractions for creating gestures with gestvm.

<<gest.lua>>=
Gest = {}

<<behavior_constants>>
<<gest>>
return Gest

1. New

Creates a new instance of Gest. Requires tal, either passed in as a dictionary parameter, or inferred from a global variable.

<<gest>>=
function Gest:new(o)
    o = o or {}
    o.name = o.name or "glive"
    o.bufname = o.bufname or "mem"
    o.tal = o.tal or tal
    o.sigrunes = o.sigrunes or sigrunes
    o.core = o.core or core 
    assert(o.tal ~= nil, "tal not found")
    setmetatable(o, self)
    self.__index = self
    return o
end

2. Create

Allocates a new instance of GestVM, as well of GestLive, the component that allows gestvm to work in realtime.

<<gest>>=
function Gest:create()
    lil("glnew " .. self.name)
    self.tal.membuf(self.bufname)
end

3. Compile

Compiles a Tal program, represented as a list of words, into Gestvm.

<<gest>>=
function Gest:compile(words)
    self.tal.compile_words(words,
        self.bufname,
        string.format("[glget [grab %s]]", self.name))
end

4. Compile Tal Code

Similar to compile, except the program is represented as a string.

<<gest>>=
function Gest:compile_tal(program)
    self.tal.compile(program,
        self.bufname,
        string.format("[glget [grab %s]]", self.name))
end

5. Swapper

Creates a swapper node for gestlive. This should be called before making any GestVM nodes.

<<gest>>=
function Gest:swapper()
    lil(string.format("glswapper [grab %s]", self.name))
end

6. Done

Tells GestLive it is done adding gestures. Should be called right before hotswapping the patch.

<<gest>>=
function Gest:done()
    lil(string.format("gldone [grab %s]", self.name))
end

7. Get

Returns a string of LIL code that grabs the active instance of GestVM being written to.

<<gest>>=
function Gest:get()
    return string.format("[glget [grab %s]]", self.name)
end

8. Node_old (OLD)

Deprecated node that creates a gesture node.

<<gest>>=
function Gest:node_old(program, conductor)
    local cnd = conductor or self.conductor
    if cnd == nil then
        error("conductor signal not defined")
    end

    lil(string.format(
        "gestvmnode %s [gmemsym [grab %s] %s] %s",
        self.get(self), self.bufname, program, cnd))
end
<<gest>>=
function Gest:nodestring(program, conductor)
    local cnd = conductor or self.conductor
    if cnd == nil then
        error("conductor signal not defined")
    end

    local s = string.format(
        "gestvmnode %s [gmemsym [grab %s] %s] %s",
        self.get(self), self.bufname, program, cnd)

    return s
end

9. Node

Creates a diagraf-compatible node that produces a gesture node. The "name" field must be supplied as the name of the gesture to use.

<<gest>>=
function Gest:node()
	local glive = self.get(self)
	local mem = self.bufname
	local glivef =  function(self) return glive end
	local cndstr = self.conductor

    return function(n, p)
        local name = p.name or "gst"
        local program =
            string.format("[gmemsym [grab %s] %s]", mem, name)

        -- TODO: glivef makes this work as a regular node
        -- glive works as only a parameter node. Tests
        -- will break if glivef is used
        -- The quick fix is to just introduce a flag
        local is_param_node = n.sigrune_dummy or false
        if is_param_node then
            n.glive = n:param(glive)
        else
            n.glive = n:param(glivef)
        end

        n.conductor = n:param(p.conductor or cndstr)

        if p.extscale ~= nil then
            n.extscale = n:param(p.extscale)
            n:lil({"gestvmnode", "zz", program, "zz", "zz"})
        else
            n:lil({"gestvmnode", "zz", program, "zz"})
        end

        n:label("gesture: " .. name)
    end
end

10. Gest16fun

This produces a helper function that rescales the output of seq. The input are the sigrunes and core components. The output is a callback that takes in an instance of Gest gst, the name of the gesture, the conductor signal cnd, and the min/max range to scale to mn and mx.

<<gest>>=
function Gest.gest16fun(sr, core)
    return function (gst, name, cnd, mn, mx)
        local pn = sr.paramnode
        local lvl = core.liln

        local node = pn(sr.scale) {
            input = pn(sr.mul) {
                a = pn(gst:node()) {
                    name = name,
                    conductor = lvl(cnd:getstr())
                },
                b = 1.0 / 16.0
            },
            min = mn,
            max = mx
        }

        return node
	end
end

11. GestVM Behavior Constants

<<behavior_constants>>=
Gest.behavior = {
    linear = 0,
    step = 1,
    gliss_medium = 2,
    gliss = 3,
    gate_125 = 4,
    gate_25 = 5,
    gate_50 = 6,
    exp_convex_low = 7,
    exp_convex_high = 8,
    exp_concave_low = 9,
    exp_concave_high = 10,
}

12. Gmemsymstr

Returns the string code for gmemsym#+NAME: gest

function Gest:gmemsymstr(symbol)
	local mem = self.bufname
    local program = 
        string.format("gmemsym [grab %s] %s", mem, symbol)
    return program
end

13. Gesture

Cannonical gesture function.

<<gest>>=
function Gest:gesture(name, cnd, extscale)
    local sr = self.sigrunes
    local core = self.core
    assert(sr ~= nil, "sigrune module not loaded")
    assert(core ~= nil, "core module not loaded")
    sr.node(self.node(self)){
        name = name,
        conductor = core.liln(cnd:getstr()),
        extscale = extscale
    }
end