Skip to content
Permalink
1f4f5d9002
Go to file
3 contributors

Users who have contributed to this file

@trentgill @tehn @csboling
146 lines (134 sloc) 5 KB
--- cv input library
-- examples of how the user will interract with the cv input
local Input = {}
Input.__index = Input
Input.inputs = {1,2}
function Input.new( chan )
local i = { channel = chan
, _mode = 'none'
, time = 0.1
, threshold = 1.0
, hysteresis = 0.1
, direction = 'both'
, windows = {}
, notes = {}
, temp = 12
, scaling = 1.0
}
setmetatable( i, Input )
i:reset_events()
Input.inputs[chan] = i -- save reference for callback engine
return i
end
function Input:reset_events()
self.stream = function(value) _c.tell('stream',self.channel,value) end
self.change = function(state) _c.tell('change',self.channel,state and 1 or 0) end
self.midi = function(data) _c.tell('midi',table.unpack(data)) end
self.window = function(win, dir) _c.tell('window',self.channel,win,dir and 1 or 0) end
self.scale = function(s)
local str = '{index=' .. s.index
.. ',octave=' .. s.octave
.. ',note=' .. s.note
.. ',volts=' .. s.volts .. '}'
_c.tell('scale',self.channel,str)
end
self.volume = function(level) _c.tell('volume',self.channel,level) end
self.peak = function() _c.tell('peak',self.channel) end
end
function Input:get_value()
return io_get_input( self.channel )
end
function Input:set_mode( mode, ... )
-- TODO short circuit these comparisons by only looking at first char
local args = {...}
if mode == 'stream' then
self.time = args[1] or self.time
set_input_stream( self.channel, self.time )
elseif mode == 'change' then
self.threshold = args[1] or self.threshold
self.hysteresis = args[2] or self.hysteresis
self.direction = args[3] or self.direction
set_input_change( self.channel
, self.threshold
, self.hysteresis
, self.direction
)
elseif mode == 'midi' then
set_input_midi( self.channel )
elseif mode == 'window' then
self.windows = args[1] or self.windows
self.hysteresis = args[2] or self.hysteresis
set_input_window( self.channel, self.windows, self.hysteresis )
elseif mode == 'scale' then
self.notes = args[1] or self.notes
self.temp = args[2] or self.temp
self.scaling = args[3] or self.scaling
set_input_scale( self.channel
, self.notes
, self.temp
, self.scaling
)
elseif mode == 'volume' then
self.time = args[1] or self.time
set_input_volume( self.channel, self.time )
elseif mode == 'peak' then
self.threshold = args[1] or self.threshold
self.hysteresis = args[2] or self.hysteresis
set_input_peak( self.channel
, self.threshold
, self.hysteresis
)
else
set_input_none( self.channel )
end
self._mode = mode
end
--- METAMETHODS
Input.__newindex = function(self, ix, val)
if ix == 'mode' then
self._mode = val
Input.set_mode(self, self._mode)
else
return rawset(self,ix,val)
end
end
Input.__index = function(self, ix)
if ix == 'volts' then
return Input.get_value(self)
elseif ix == 'query' then
return function() _c.tell('stream',self.channel,Input.get_value(self)) end
elseif ix == 'mode' then
return function(...) Input.set_mode( self, ...) end
elseif ix == 'reset_events' then
return function() Input.reset_events(self) end
end
end
Input.__call = function(self, ...)
local args = {...}
if #args == 0 then
-- FIXME this should be removed? use .volts instead
return Input.get_value(self)
else -- table call
local m = 0
--if #args[1] == 0 then _ end -- implies empty table call
for k,v in pairs( args[1] ) do
if k == 'mode' then m = v end -- defer mode change after setting params
self[k] = v
end
if m ~= 0 then self.mode = m end -- apply mode change
end
end
setmetatable(Input, Input) -- capture the metamethods
-- callback
function stream_handler( chan, val ) Input.inputs[chan].stream( val ) end
function change_handler( chan, val ) Input.inputs[chan].change( val ~= 0 ) end
function midi_handler( ... ) d = {...}; Input.inputs[1].midi(d) end
function window_handler( chan, win, dir ) Input.inputs[chan].window( win, dir ~= 0 ) end
function scale_handler(chan,i,o,n,v)
--TODO build this table in C as it'll be faster?
s={index=i, octave=o, note=n, volts=v}
Input.inputs[chan].scale(s)
end
function volume_handler( chan, val ) Input.inputs[chan].volume( val ) end
function peak_handler( chan ) Input.inputs[chan].peak() end
return Input