M lua/liam.lua => lua/liam.lua +30 -6
@@ 13,6 13,7 @@ local displaying <const> = require('displaying')
local tonewheeling <const> = require('tonewheeling')
local pianoteqing <const> = require('pianoteqing')
local gatekeeping <const> = require('gatekeeping')
+local shifting <const> = require('shifting')
local tags <const> = {
clock = 'clock',
@@ 94,6 95,31 @@ local tonewheel <const> = tonewheeling.Tonewheel:new {
}
interface[6] = tonewheel
+local shifter1 <const> = shifting.Shifter:new {
+ channel = 0x0,
+ interface = interface --FIXME
+}
+interface[7] = shifter1
+
+local shifter2 <const> = shifting.Shifter:new {
+ channel = 0x1,
+ interface = interface --FIXME
+}
+interface[8] = shifter2
+
+local shifter3 <const> = shifting.Shifter:new {
+ channel = 0x2,
+ interface = interface --FIXME
+}
+interface[9] = shifter3
+
+local shifter4 <const> = shifting.Shifter:new {
+ channel = 0x3,
+ interface = interface --FIXME
+}
+interface[10] = shifter4
+interface.index = 9 --FIXME
+
local monitor <const> = monitoring.Monitor:new()
local pk88 <const> = {
@@ 164,23 190,21 @@ function process(nframes)
if gatekeeper1:pass(msg) then
local msg <const> = table.pack(table.unpack(msg))
- msg[1] = (msg[1] & 0xf0) | 0x00 -- channel 1
- fh2.writer:write(time, msg)
+ fh2.writer:write(time, shifter1:shift(msg))
end
if gatekeeper2:pass(msg) then
local msg <const> = table.pack(table.unpack(msg))
- msg[1] = (msg[1] & 0xf0) | 0x01 -- channel 2
- fh2.writer:write(time, msg)
+ fh2.writer:write(time, shifter2:shift(msg))
end
if not pianoteq.mute and gatekeeper3:pass(msg) then
- piano.writer:write(time, msg)
+ piano.writer:write(time, shifter3:shift(msg))
end
if not tonewheel.mute and gatekeeper4:pass(msg) then
- bfree.writer:write(time, msg)
+ bfree.writer:write(time, shifter4:shift(msg))
end
elseif source == fh2.reader then
monitor:write(time, msg)
A lua/shifting.lua => lua/shifting.lua +81 -0
@@ 0,0 1,81 @@
+-- SPDX-FileCopyrightText: Hanspeter Portner <dev@open-music-kontrollers.ch>
+-- SPDX-License-Identifier: Artistic-2.0
+
+local tooling <const> = require('tooling')
+local interfacing <const> = require('interfacing')
+
+local Offset <const> = tooling.Class:new {
+ color_off = 0x1,
+ color_act = 0xd,
+ color_hot = 0x3,
+
+ down = function(self, time)
+ self.pressed = true
+
+ self.page:set_offset(time, self.offset)
+ end,
+
+ up = function(self, time)
+ self.pressed = false
+ end,
+
+ color = function(self)
+ if self.pressed then
+ return self.color_hot
+ elseif self.offset == self.page.offset then
+ return self.color_act
+ else
+ return self.color_off
+ end
+ end
+}
+
+local Shifter <const> = interfacing.Page:new {
+ channel = 0x0,
+ offset = 0,
+
+ -- private
+ octave_offset = 0,
+ note_offset = 0,
+
+ set_offset = function(self, time, offset)
+ self.offset = offset
+ self:refresh(time)
+ end,
+
+ init = function(self)
+ interfacing.Page.init(self)
+
+ --FIXME separate block for notes
+
+ for j = 1, 9 do
+ local offset <const> = j - 5
+ local num <const> = 10 + j
+
+ self[num] = Offset:new {
+ offset = offset,
+ page = self
+ }
+ end
+ end,
+
+ shift = function(self, msg)
+ local cmd <const> = msg[1] & 0xf0
+
+ -- check for matching note range
+ if cmd == midi.NoteOn
+ or cmd == midi.NoteOff
+ or cmd == midi.NotePressure then
+ return { cmd | self.channel, msg[2] + self.offset, msg[3] }
+ end
+
+ return msg
+ end
+}
+
+-- module
+local shifting <const> = {
+ Shifter = Shifter
+}
+
+return shifting
M meson.build => meson.build +7 -0
@@ 130,6 130,13 @@ gatekeeping_lua = configure_file(
install : true,
install_dir : lua_datadir)
+shifting_lua = configure_file(
+ input : join_paths('lua', 'shifting.lua'),
+ output : 'shifting.lua',
+ copy : true,
+ install : true,
+ install_dir : lua_datadir)
+
if build_tests
if reuse.found()
test('REUSE', reuse, args : [