From 0c4e8c635d9a25712d65af9b6dcf6fbad4a72b05 Mon Sep 17 00:00:00 2001 From: dvs1 Date: Mon, 21 Oct 2024 18:55:20 +1000 Subject: Restructure the APT.exe stuff. --- aataaj.lua | 262 ++++++++++++++++++------------------------------------------- 1 file changed, 75 insertions(+), 187 deletions(-) (limited to 'aataaj.lua') diff --git a/aataaj.lua b/aataaj.lua index 761163e..a92e0fb 100755 --- a/aataaj.lua +++ b/aataaj.lua @@ -14,6 +14,17 @@ ### END INIT INFO ]] +local _ = require '_' +local D = _.D +local I = _.I +local T = _.T +local W = _.W +local E = _.E +local C = _.C +local __ = _._ + + + local Help = [[ This is part of the AllAudioToALSAandJACK project, aataaj for short, pronounced like "attach". @@ -40,14 +51,12 @@ The packages you need installed are - You need to have the snd-aloop kernel module loaded. -The aataaj.lua script should be run at boot time, put it into +The aataaj.lua script should be run at boot time, put it and _.lua into /etc/init.d/ and activate it with - update-rc.d aataaj.lua defaults -It scans for your sound devices and creates /var/lib/aataaj/asoundrc. -You can run it manually with "aataaj start" each time you need to change -your devices. +Note that _.lua might need to be in /usr/local/share/lua/5.1/ @@ -83,131 +92,6 @@ NOTE - Seems both ALSA and JACK are per user. So you need to run --- Most of this APT stuff was copied from apt-panopticon. -local APT = {} - -APT.readCmd = function(cmd) - local result = {} - local output = io.popen(cmd) - if nil ~= output then - for l in output:lines() do - table.insert(result, l) - end - end - -- While this does return the same things as os.execute(), it's just as useless. - output:close() - return result -end - -APT.exe = function(c) - local exe = {status = 0, lines = {}, log = true, cmd = c .. ' ', command = c} - - function exe:log() - self.log = true - return self - end - function exe:Nice(c) - if nil == c then - self.cmd = 'ionice -c3 nice -n 19 ' .. self.cmd - else - self.cmd = self.cmd .. 'ionice -c3 nice -n 19 ' .. c .. ' ' - end - return self - end - function exe:timeout(c) - -- timeout returns a status of - command status if --preserve-status; "128+9" (actually 137) if --kill-after ends up being done; 124 if it had to TERM; command status if all went well. - -- --kill-after means "send KILL after TERM fails. - if nil == c then - self.cmd = 'timeout --kill-after=10.0 --foreground 42.0s ' .. self.cmd - else - self.cmd = 'timeout --kill-after=10.0 --foreground ' .. c .. ' ' .. self.cmd - end - return self - end - function exe:also(c) - if nil == c then c = '' else c = ' ' .. c end - self.cmd = self.cmd .. ';' .. c .. ' ' - return self - end - function exe:And(c) - if nil == c then c = '' else c = ' ' .. c end - self.cmd = self.cmd .. '&&' .. c .. ' ' - return self - end - function exe:Or(c) - if nil == c then c = '' end - self.cmd = self.cmd .. '|| ' .. c .. ' ' - return self - end - function exe:noErr() - self.cmd = self.cmd .. '2>/dev/null ' - return self - end - function exe:wait(w) - self.cmd = self.cmd .. '&& touch ' .. w .. ' ' - return self - end - function exe:Do() - --[[ "The condition expression of a control structure can return any - value. Both false and nil are considered false. All values different - from nil and false are considered true (in particular, the number 0 - and the empty string are also true)." - says the docs, I beg to differ.]] - if true == self.log then D(" executing -   " .. self.cmd .. "") end - --[[ Damn os.execute() - Lua 5.1 says it returns "a status code, which is system-dependent" - Lua 5.2 says it returns true/nil, "exit"/"signal", the status code. - I'm getting 7168 or 0. No idea what the fuck that is. - local ok, rslt, status = os.execute(s) - ]] - self.lines = APT.readCmd(self.cmd .. '; echo "$?"', 'r') - -- The last line will be the command's returned status, collect everything else in result. - self.status = tonumber(self.lines[#self.lines]) - self.lines[#self.lines] = nil --- self.result = '\n' --- for i,l in ipairs(self.lines) do --- self.result = self.result .. l .. "\n" --- end - if (137 == self.status) or (124 == self.status) then - print("timeout killed " .. self.status .. ' ' .. self.command) - print('ERROR ' .. "timeout killed " .. self.status .. ' ' .. self.command) - elseif (nil == self.status) then - print("STATUS |" .. "NIL" .. '| ' .. self.command) - elseif (0 ~= self.status) then - print("STATUS |" .. self.status .. '| ' .. self.command) - end - return self - end - function exe:fork(host) - if nil ~= host then self.cmd = self.cmd .. '; r=$?; if [ $r -ge 124 ]; then echo "$r ' .. host .. ' failed forked command ' .. string.gsub(self.cmd, '"', "'") .. '"; fi' end - self.cmd = '{ ' .. self.cmd .. '; } &' - if true == self.log then D(" forking -   " .. self.cmd .. "") end - os.execute(self.cmd) - return self - end - return exe -end - -APT.exists = function(c) - if 0 == APT.exe('which ' .. c):Do().status then return true end - return false -end - -APT.killEmAll = function(all) - for i,l in ipairs(all) do - local c = 0 - while 0 ~= tonumber(APT.exe("pgrep -u $USER -xc " .. l):Do().lines[1]) do - local s = 'TERM' - if c > 1 then s = 'KILL'; APT.exe("sleep " .. c):Do() end - print( "pkill -" .. s .. " -u $USER -x " .. l) - APT.exe("pkill -" .. s .. " -u $USER -x " .. l):Do() - c = c + 1 - end - end -end - - - local args = {...} if 0 ~= #args then -- for i,a in pairs(args) do @@ -216,23 +100,27 @@ if 0 ~= #args then if 'start' == args[1] then elseif 'stop' == args[1] then - APT.killEmAll{'qsynth'} - APT.exe("a2j_control --stop"):Do() - APT.exe("sleep 2"):Do() - APT.exe("a2j_control --exit"):Do() - APT.exe("sleep 2"):Do() - APT.killEmAll{'alsa_in', 'alsa_out', 'zita-a2j', 'zita-j2a', 'aseqjoy', 'jack-plumbing'} - APT.exe("sleep 2"):Do() - APT.exe("jack_control stop"):Do() - APT.exe("sleep 2"):Do() - APT.exe("jack_control exit"):Do() - APT.exe("sleep 2"):Do() - APT.killEmAll{'jmcore', 'qjackctl'} + _.killEmAll{'qsynth'} + __[[ + a2j_control --stop + sleep 2 + a2j_control --exit + sleep 2 +]]:Do() + _.killEmAll{'alsa_in', 'alsa_out', 'zita-a2j', 'zita-j2a', 'aseqjoy', 'jack-plumbing'} + __[[ + sleep 2 + jack_control stop + sleep 2 + jack_control exit + sleep 2 +]]:Do() + _.killEmAll{'jmcore', 'qjackctl'} -- Catia is python, and no easy way to kill it. -- Also it keeps jackdbus alive, no matter how hard you kill it. - APT.exe("pkill -TERM -u $USER -f catia"):Do() - APT.exe("sleep 2"):Do() - APT.killEmAll{'jackdbus', 'a2jmidid'} + __("pkill -TERM -u $USER -f catia"):Do() + __("sleep 2"):Do() + _.killEmAll{'jackdbus', 'a2jmidid'} return(0) elseif 'JACK' == args[1] then elseif 'restart' == args[1] then args[1] = 'start' @@ -261,31 +149,31 @@ end local asoundrcPath = '/var/lib/aataaj' local asoundrc = 'asoundrc' local GUI = 'qjackctl' -if APT.exists('catia') then GUI = 'catia' end +if _.exists('catia') then GUI = 'catia' end local alias = { -- {name='Screen', dev='HDMI9'}, } local speaker = 'espeak' -if APT.exists('espeak-ng') then speaker = 'espeak-ng' end +if _.exists('espeak-ng') then speaker = 'espeak-ng' end local Cards = {} print('Scanning for audio devices.') -local cards = APT.exe('ls -d1 /proc/asound/card[0-9]*'):noErr():Do() +local cards = __('ls -d1 /proc/asound/card[0-9]*'):noErr():Do() for i,l in ipairs(cards.lines) do local f, e = io.open(l .. '/id', "r") if nil == f then print("Could not open " .. l .. '/id') else Cards[l] = {path = l, name = f:read("*a"):sub(1, -2), devs = {}, captureDevs = {}, playbackDevs = {}} if "Loopback" ~= Cards[l]['name'] then - Cards[l]['capture'] = APT.exe('ls -d1 ' .. l .. '/pcm[0-9]*c*'):noErr():Do() + Cards[l]['capture'] = __('ls -d1 ' .. l .. '/pcm[0-9]*c*'):noErr():Do() for j,c in ipairs(Cards[l]['capture'].lines) do local n = c:match(".*pcm(%d+).*") Cards[l]['captureDevs'][j] = n Cards[l]['devs'][n] = n print("\tFound capture device: " .. Cards[l]['name'] .. "\tDEVICE: " .. Cards[l]['captureDevs'][j] .. ' ' .. n) end - Cards[l]['playback'] = APT.exe('ls -d1 ' .. l .. '/pcm[0-9]*p*'):noErr():Do() + Cards[l]['playback'] = __('ls -d1 ' .. l .. '/pcm[0-9]*p*'):noErr():Do() for j,p in ipairs(Cards[l]['playback'].lines) do local n = p:match(".*pcm(%d+).*") Cards[l]['playbackDevs'][j] = n @@ -293,8 +181,8 @@ for i,l in ipairs(cards.lines) do print("\tFound playback device " .. i - 1 .. " : " .. Cards[l]['name'] .. "\tDEVICE: " .. Cards[l]['playbackDevs'][j] .. ' ' .. n) if 'JACK' ~= args[1] then print('\t\tALSA_CARD=' .. i - 1 .. ' ' .. speaker .. ' "Found playback device ' .. i - 1 .. ' : ' .. Cards[l]['name'] .. ' DEVICE: ' .. Cards[l]['playbackDevs'][j] .. ' ' .. n .. '"') - APT.exe('ALSA_CARD=' .. i - 1 .. ' ' .. speaker .. ' "Found playback device ' .. i - 1 .. ' : ' .. Cards[l]['name'] .. ' DEVICE: ' .. Cards[l]['playbackDevs'][j] .. ' ' .. n .. '"'):noErr():Do() - APT.exe('sleep 1') + __('ALSA_CARD=' .. i - 1 .. ' ' .. speaker .. ' "Found playback device ' .. i - 1 .. ' : ' .. Cards[l]['name'] .. ' DEVICE: ' .. Cards[l]['playbackDevs'][j] .. ' ' .. n .. '"'):noErr():Do() + __('sleep 1'):Do() end end end @@ -302,7 +190,7 @@ for i,l in ipairs(cards.lines) do end if 'start' == args[1] then - APT.exe('mkdir -p ' .. asoundrcPath):Do() + __('mkdir -p ' .. asoundrcPath):Do() local a, e = io.open(asoundrcPath .. '/jack-plumbing', "w") if nil == a then print("Could not open " .. asoundrcPath .. '/jack-plumbing') else a:write([[ @@ -475,58 +363,58 @@ elseif 'JACK' == args[1] then print('') print("Start up JACK and friends.") print("jack_control") - APT.exe('jack_control start'):Do() - APT.exe('jack_control ds alsa'):Do() + __('jack_control start'):Do() + __('jack_control ds alsa'):Do() --jack_control dps device hw:RIG,0 - local r = APT.exe('jack_control status'):Do().status + local r = __('jack_control status'):Do().status while r ~= 0 do print("Waiting for JACK - sleep 1") - APT.exe('sleep 1'):Do() - r = APT.exe('jack_control status'):Do().status + __('sleep 1'):Do() + r = __('jack_control status'):Do().status end if nil ~= GUI then print(GUI) - APT.exe(GUI):fork() + __(GUI):fork() end - if APT.exists('jack-plumbing') then + if _.exists('jack-plumbing') then print("jack-plumbing") - APT.exe('jack-plumbing -o /var/lib/aataaj/jack-plumbing 2>/dev/null'):fork() + __('jack-plumbing -o /var/lib/aataaj/jack-plumbing 2>/dev/null'):fork() end - if APT.exists('a2j_control') then + if _.exists('a2j_control') then -- Bridge ALSA ports to JACK ports. Only handles MIDI. -- MIDI via a2jmidid. The --ehw enables hardware ports as well, equal to using the seq MIDI drivare according to https://freeshell.de/~murks/posts/ALSA_and_JACK_MIDI_explained_(by_a_dummy_for_dummies)/ --a2j_control actually starts a2jmidid. ----a2jmidid -e -u & -- I think the jack_control start and my current alsa config means a2jmidid gets started anyway. But seem to need this bit to get the joystick covered. print("a2j_control") - APT.exe('a2j_control --ehw && a2j_control --start'):Do() + __('a2j_control --ehw && a2j_control --start'):Do() -- print("sleep 2") --- APT.exe('sleep 2'):Do() +-- __('sleep 2'):Do() print("") end local AIN = "alsa_in" - if APT.exists('zita-a2j') then AIN = 'zita-a2j' end + if _.exists('zita-a2j') then AIN = 'zita-a2j' end local AOUT = "alsa_out" - if APT.exists('zita-j2a') then AOUT = 'zita-j2a' end + if _.exists('zita-j2a') then AOUT = 'zita-j2a' end print("Basic ALSA sound devices converted to JACK.") for i,C in pairs(alias) do print('HW playback: ' .. C['name'] .. '\tDEVICE: ' .. C['dev']) - APT.exe(AOUT .. ' -j ' .. C['name'] .. ' -d ' .. C['dev']):fork() + __(AOUT .. ' -j ' .. C['name'] .. ' -d ' .. C['dev']):fork() end print("HW playback: cloop\tDEVICE: cloop") -- No idea why, cloop wont work with zita-a2j. - APT.exe('alsa_in -j cloop -d cloop'):fork() - --APT.exe('sleep 1'):Do() - --APT.exe('jack_connect cloop:capture_1 system:playback_1'):Do() - --APT.exe('jack_connect cloop:capture_2 system:playback_2'):Do() + __('alsa_in -j cloop -d cloop'):fork() + --__('sleep 1'):Do() + --__('jack_connect cloop:capture_1 system:playback_1'):Do() + --__('jack_connect cloop:capture_2 system:playback_2'):Do() print("HW playback: ploop\tDEVICE: ploop") - APT.exe('alsa_out -j ploop -d ploop'):fork() - --APT.exe('sleep 1'):Do() - --APT.exe('jack_connect system:capture_1 ploop:playback_1'):Do() - --APT.exe('jack_connect system:capture_2 ploop:playback_2'):Do() + __('alsa_out -j ploop -d ploop'):fork() + --__('sleep 1'):Do() + --__('jack_connect system:capture_1 ploop:playback_1'):Do() + --__('jack_connect system:capture_2 ploop:playback_2'):Do() print("") @@ -535,39 +423,39 @@ elseif 'JACK' == args[1] then for i,C in pairs(Cards) do for j,c in ipairs(C['playbackDevs']) do print("HW playback: " .. C['name'] .. "\tDEVICE: " .. C['playbackDevs'][j]) - APT.exe(AOUT .. ' -j ' .. C['name'] .. "_" .. C['playbackDevs'][j] .. '-in -d ' .. C['name'] .. C['playbackDevs'][j]):fork() - -- APT.exe('sleep 1'):Do() - -- APT.exe('jack_connect cloop:capture_1 ' .. C['name'] .. '_' .. C['playbackDevs'][j] .. '-in' .. ':playback_1'):Do() - -- APT.exe('jack_connect cloop:capture_2 ' .. C['name'] .. '_' .. C['playbackDevs'][j] .. '-in' .. ':playback_2'):Do() + __(AOUT .. ' -j ' .. C['name'] .. "_" .. C['playbackDevs'][j] .. '-in -d ' .. C['name'] .. C['playbackDevs'][j]):fork() + -- __('sleep 1'):Do() + -- __('jack_connect cloop:capture_1 ' .. C['name'] .. '_' .. C['playbackDevs'][j] .. '-in' .. ':playback_1'):Do() + -- __('jack_connect cloop:capture_2 ' .. C['name'] .. '_' .. C['playbackDevs'][j] .. '-in' .. ':playback_2'):Do() end for j,c in ipairs(C['captureDevs']) do print("HW capture: " .. C['name'] .. "\tDEVICE: " .. C['captureDevs'][j]) - APT.exe(AIN .. ' -j ' .. C['name'] .. "_" .. C['captureDevs'][j] .. '-out -d ' .. C['name'] .. C['captureDevs'][j]):fork() + __(AIN .. ' -j ' .. C['name'] .. "_" .. C['captureDevs'][j] .. '-out -d ' .. C['name'] .. C['captureDevs'][j]):fork() end end print("") - if APT.exists('aseqjoy') then + if _.exists('aseqjoy') then print("Scanning for joysticks.") - local sticks = APT.exe('ls -1 /dev/input/js[0-9]*'):noErr():Do() + local sticks = __('ls -1 /dev/input/js[0-9]*'):noErr():Do() for i,l in ipairs(sticks.lines) do print("aseqjoy " .. l) -- Buttons switch to that numbered MIDI channel, defaults to 1. -- Axis are mapped to MIDI controllers 10 - 15 -- -r means to use high resolution MIDI values. - APT.exe('aseqjoy -d ' .. l:sub(-1,-1) .. ' -r'):fork() + __('aseqjoy -d ' .. l:sub(-1,-1) .. ' -r'):fork() end print("") end - if APT.exists('jack-plumbing') then + if _.exists('jack-plumbing') then print('Stop our jack-plumbing, eventually.') - APT.exe('sleep 4'):Do() - APT.killEmAll{"jack-plumbing"} + __('sleep 4'):Do() + _.killEmAll{"jack-plumbing"} end - if APT.exists('~/.aataaj_JACK.lua') then + if _.exists('~/.aataaj_JACK.lua') then print('Running users aataaj_JACK.lua') - APT.exe('~/.aataaj_JACK.lua'):Do() + __('~/.aataaj_JACK.lua'):Do() end end -- cgit v1.1