diff options
Diffstat (limited to '')
-rw-r--r-- | README.md | 4 | ||||
-rwxr-xr-x | _.lua | 170 | ||||
-rwxr-xr-x | aataaj.lua | 262 | ||||
-rwxr-xr-x | test_.lua | 122 |
4 files changed, 370 insertions, 188 deletions
@@ -23,11 +23,13 @@ The packages you need installed are - | |||
23 | 23 | ||
24 | You need to have the snd-aloop kernel module loaded. | 24 | You need to have the snd-aloop kernel module loaded. |
25 | 25 | ||
26 | The aataaj.lua script should be run at boot time, put it into | 26 | The aataaj.lua script should be run at boot time, put it and _.lua into |
27 | /etc/init.d/ and activate it with - | 27 | /etc/init.d/ and activate it with - |
28 | 28 | ||
29 | update-rc.d aataaj.lua defaults | 29 | update-rc.d aataaj.lua defaults |
30 | 30 | ||
31 | Note that _.lua might need to be in /usr/local/share/lua/5.1/ | ||
32 | |||
31 | It scans for your sound devices and creates /var/lib/aataaj/asoundrc. | 33 | It scans for your sound devices and creates /var/lib/aataaj/asoundrc. |
32 | You can run it manually with "aataaj start" each time you need to change | 34 | You can run it manually with "aataaj start" each time you need to change |
33 | your devices. | 35 | your devices. |
@@ -0,0 +1,170 @@ | |||
1 | #!/usr/bin/env luajit | ||
2 | |||
3 | |||
4 | -- Most of this _ stuff was copied from apt-panopticon. | ||
5 | local _ = {} | ||
6 | |||
7 | _.version = '0.0 crap' | ||
8 | |||
9 | _.D = function(s) print('DEBUG ' .. s) end | ||
10 | _.I = function(s) print('INFO ' .. s) end | ||
11 | _.T = function(s) print('TIMEOUT ' .. s) end | ||
12 | _.W = function(s) print('WARNING ' .. s) end | ||
13 | _.E = function(s) print('ERROR ' .. s) end | ||
14 | _.C = function(s) print('CRITICAL ' .. s) end | ||
15 | local D = _.D | ||
16 | local I = _.I | ||
17 | local T = _.T | ||
18 | local W = _.W | ||
19 | local E = _.E | ||
20 | local C = _.C | ||
21 | |||
22 | |||
23 | _.readCmd = function(cmd) | ||
24 | local result = {} | ||
25 | local output = io.popen(cmd) | ||
26 | if nil ~= output then | ||
27 | for l in output:lines() do | ||
28 | table.insert(result, l) | ||
29 | end | ||
30 | end | ||
31 | -- While this does return the same things as os.execute(), it's just as useless. | ||
32 | output:close() | ||
33 | return result | ||
34 | end | ||
35 | |||
36 | |||
37 | _._ = function(c) | ||
38 | local exe = {status = 0, lines = {}, logging = false, showing = false, cmd = '', command = c} | ||
39 | local n = 0 | ||
40 | |||
41 | exe.cmd = '{ ' | ||
42 | if 'table' == type(c) then | ||
43 | for i, l in ipairs(c) do | ||
44 | n = n + 1 | ||
45 | exe.cmd = exe.cmd .. l .. ' ; ' | ||
46 | end | ||
47 | elseif 'string' == type(c) then | ||
48 | for l in string.gmatch(c, "\n*([^\n]+)\n*") do | ||
49 | if '' ~= l then | ||
50 | n = n + 1 | ||
51 | exe.cmd = exe.cmd .. l .. ' ; ' | ||
52 | end | ||
53 | end | ||
54 | end | ||
55 | exe.cmd = exe.cmd .. ' } ' | ||
56 | if 1 == n then exe.cmd = c end | ||
57 | |||
58 | function exe:log() | ||
59 | self.logging = true | ||
60 | return self | ||
61 | end | ||
62 | function exe:show() | ||
63 | self.showing = true | ||
64 | return self | ||
65 | end | ||
66 | function exe:Nice(c) | ||
67 | if nil == c then | ||
68 | self.cmd = 'ionice -c3 nice -n 19 ' .. self.cmd | ||
69 | else | ||
70 | self.cmd = self.cmd .. ' ionice -c3 nice -n 19 ' .. c .. ' ' | ||
71 | end | ||
72 | return self | ||
73 | end | ||
74 | function exe:timeout(c) | ||
75 | -- 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. | ||
76 | -- --kill-after means "send KILL after TERM fails. | ||
77 | if nil == c then | ||
78 | self.cmd = 'timeout --kill-after=10.0 --foreground 42.0s ' .. self.cmd | ||
79 | else | ||
80 | self.cmd = 'timeout --kill-after=10.0 --foreground ' .. c .. ' ' .. self.cmd | ||
81 | end | ||
82 | return self | ||
83 | end | ||
84 | function exe:also(c) | ||
85 | if nil == c then c = '' else c = ' ' .. c end | ||
86 | self.cmd = self.cmd .. '; ' .. c .. ' ' | ||
87 | return self | ||
88 | end | ||
89 | function exe:And(c) | ||
90 | if nil == c then c = '' else c = ' ' .. c end | ||
91 | self.cmd = self.cmd .. ' && ' .. c .. ' ' | ||
92 | return self | ||
93 | end | ||
94 | function exe:Or(c) | ||
95 | if nil == c then c = '' end | ||
96 | self.cmd = self.cmd .. ' || ' .. c .. ' ' | ||
97 | return self | ||
98 | end | ||
99 | function exe:noErr() | ||
100 | self.cmd = self.cmd .. ' 2>/dev/null ' | ||
101 | return self | ||
102 | end | ||
103 | function exe:noOut() | ||
104 | self.cmd = self.cmd .. ' 1>/dev/null ' | ||
105 | return self | ||
106 | end | ||
107 | function exe:wait(w) | ||
108 | self.cmd = self.cmd .. ' && touch ' .. w .. ' ' | ||
109 | return self | ||
110 | end | ||
111 | function exe:Do() | ||
112 | --[[ "The condition expression of a control structure can return any | ||
113 | value. Both false and nil are considered false. All values different | ||
114 | from nil and false are considered true (in particular, the number 0 | ||
115 | and the empty string are also true)." | ||
116 | says the docs, I beg to differ.]] | ||
117 | if true == self.logging then D(" executing - " .. self.cmd) end | ||
118 | --[[ Damn os.execute() | ||
119 | Lua 5.1 says it returns "a status code, which is system-dependent" | ||
120 | Lua 5.2 says it returns true/nil, "exit"/"signal", the status code. | ||
121 | I'm getting 7168 or 0. No idea what the fuck that is. | ||
122 | local ok, rslt, status = os.execute(s) | ||
123 | ]] | ||
124 | self.lines = _.readCmd(self.cmd .. '; echo "$?"', 'r') | ||
125 | -- The last line will be the command's returned status, collect everything else in lines. | ||
126 | self.status = tonumber(self.lines[#self.lines]) | ||
127 | self.lines[#self.lines] = nil | ||
128 | if true == self.showing then for i, l in ipairs(self.lines) do D(l) end end | ||
129 | if (137 == self.status) or (124 == self.status) then | ||
130 | T("timeout killed " .. self.status .. ' ' .. self.command) | ||
131 | elseif (nil == self.status) then | ||
132 | I("STATUS |" .. "NIL" .. '| ' .. self.command) | ||
133 | elseif (0 ~= self.status) then | ||
134 | I("STATUS |" .. self.status .. '| ' .. self.command) | ||
135 | end | ||
136 | return self | ||
137 | end | ||
138 | function exe:fork(host) | ||
139 | 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 | ||
140 | self.cmd = '{ ' .. self.cmd .. ' ; } & ' | ||
141 | if true == self.logging then D(" forking - " .. self.cmd) end | ||
142 | os.execute(self.cmd) | ||
143 | return self | ||
144 | end | ||
145 | return exe | ||
146 | end | ||
147 | local __ = _._ | ||
148 | |||
149 | |||
150 | _.exists = function(c) | ||
151 | if 0 == __('which ' .. c):Do().status then return true end | ||
152 | return false | ||
153 | end | ||
154 | |||
155 | |||
156 | _.killEmAll = function(all) | ||
157 | for i,l in ipairs(all) do | ||
158 | local c = 0 | ||
159 | while 0 ~= tonumber(__("pgrep -u $USER -xc " .. l):Do().lines[1]) do | ||
160 | local s = 'TERM' | ||
161 | if c > 1 then s = 'KILL'; __("sleep " .. c):Do() end | ||
162 | __("pkill -" .. s .. " -u $USER -x " .. l):log():Do() | ||
163 | c = c + 1 | ||
164 | end | ||
165 | end | ||
166 | end | ||
167 | |||
168 | |||
169 | |||
170 | return _ | ||
@@ -14,6 +14,17 @@ | |||
14 | ### END INIT INFO | 14 | ### END INIT INFO |
15 | ]] | 15 | ]] |
16 | 16 | ||
17 | local _ = require '_' | ||
18 | local D = _.D | ||
19 | local I = _.I | ||
20 | local T = _.T | ||
21 | local W = _.W | ||
22 | local E = _.E | ||
23 | local C = _.C | ||
24 | local __ = _._ | ||
25 | |||
26 | |||
27 | |||
17 | local Help = [[ | 28 | local Help = [[ |
18 | This is part of the AllAudioToALSAandJACK project, aataaj for short, | 29 | This is part of the AllAudioToALSAandJACK project, aataaj for short, |
19 | pronounced like "attach". | 30 | pronounced like "attach". |
@@ -40,14 +51,12 @@ The packages you need installed are - | |||
40 | 51 | ||
41 | You need to have the snd-aloop kernel module loaded. | 52 | You need to have the snd-aloop kernel module loaded. |
42 | 53 | ||
43 | The aataaj.lua script should be run at boot time, put it into | 54 | The aataaj.lua script should be run at boot time, put it and _.lua into |
44 | /etc/init.d/ and activate it with - | 55 | /etc/init.d/ and activate it with - |
45 | 56 | ||
46 | update-rc.d aataaj.lua defaults | 57 | update-rc.d aataaj.lua defaults |
47 | 58 | ||
48 | It scans for your sound devices and creates /var/lib/aataaj/asoundrc. | 59 | Note that _.lua might need to be in /usr/local/share/lua/5.1/ |
49 | You can run it manually with "aataaj start" each time you need to change | ||
50 | your devices. | ||
51 | 60 | ||
52 | 61 | ||
53 | 62 | ||
@@ -83,131 +92,6 @@ NOTE - Seems both ALSA and JACK are per user. So you need to run | |||
83 | 92 | ||
84 | 93 | ||
85 | 94 | ||
86 | -- Most of this APT stuff was copied from apt-panopticon. | ||
87 | local APT = {} | ||
88 | |||
89 | APT.readCmd = function(cmd) | ||
90 | local result = {} | ||
91 | local output = io.popen(cmd) | ||
92 | if nil ~= output then | ||
93 | for l in output:lines() do | ||
94 | table.insert(result, l) | ||
95 | end | ||
96 | end | ||
97 | -- While this does return the same things as os.execute(), it's just as useless. | ||
98 | output:close() | ||
99 | return result | ||
100 | end | ||
101 | |||
102 | APT.exe = function(c) | ||
103 | local exe = {status = 0, lines = {}, log = true, cmd = c .. ' ', command = c} | ||
104 | |||
105 | function exe:log() | ||
106 | self.log = true | ||
107 | return self | ||
108 | end | ||
109 | function exe:Nice(c) | ||
110 | if nil == c then | ||
111 | self.cmd = 'ionice -c3 nice -n 19 ' .. self.cmd | ||
112 | else | ||
113 | self.cmd = self.cmd .. 'ionice -c3 nice -n 19 ' .. c .. ' ' | ||
114 | end | ||
115 | return self | ||
116 | end | ||
117 | function exe:timeout(c) | ||
118 | -- 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. | ||
119 | -- --kill-after means "send KILL after TERM fails. | ||
120 | if nil == c then | ||
121 | self.cmd = 'timeout --kill-after=10.0 --foreground 42.0s ' .. self.cmd | ||
122 | else | ||
123 | self.cmd = 'timeout --kill-after=10.0 --foreground ' .. c .. ' ' .. self.cmd | ||
124 | end | ||
125 | return self | ||
126 | end | ||
127 | function exe:also(c) | ||
128 | if nil == c then c = '' else c = ' ' .. c end | ||
129 | self.cmd = self.cmd .. ';' .. c .. ' ' | ||
130 | return self | ||
131 | end | ||
132 | function exe:And(c) | ||
133 | if nil == c then c = '' else c = ' ' .. c end | ||
134 | self.cmd = self.cmd .. '&&' .. c .. ' ' | ||
135 | return self | ||
136 | end | ||
137 | function exe:Or(c) | ||
138 | if nil == c then c = '' end | ||
139 | self.cmd = self.cmd .. '|| ' .. c .. ' ' | ||
140 | return self | ||
141 | end | ||
142 | function exe:noErr() | ||
143 | self.cmd = self.cmd .. '2>/dev/null ' | ||
144 | return self | ||
145 | end | ||
146 | function exe:wait(w) | ||
147 | self.cmd = self.cmd .. '&& touch ' .. w .. ' ' | ||
148 | return self | ||
149 | end | ||
150 | function exe:Do() | ||
151 | --[[ "The condition expression of a control structure can return any | ||
152 | value. Both false and nil are considered false. All values different | ||
153 | from nil and false are considered true (in particular, the number 0 | ||
154 | and the empty string are also true)." | ||
155 | says the docs, I beg to differ.]] | ||
156 | if true == self.log then D(" executing - <code>" .. self.cmd .. "</code>") end | ||
157 | --[[ Damn os.execute() | ||
158 | Lua 5.1 says it returns "a status code, which is system-dependent" | ||
159 | Lua 5.2 says it returns true/nil, "exit"/"signal", the status code. | ||
160 | I'm getting 7168 or 0. No idea what the fuck that is. | ||
161 | local ok, rslt, status = os.execute(s) | ||
162 | ]] | ||
163 | self.lines = APT.readCmd(self.cmd .. '; echo "$?"', 'r') | ||
164 | -- The last line will be the command's returned status, collect everything else in result. | ||
165 | self.status = tonumber(self.lines[#self.lines]) | ||
166 | self.lines[#self.lines] = nil | ||
167 | -- self.result = '\n' | ||
168 | -- for i,l in ipairs(self.lines) do | ||
169 | -- self.result = self.result .. l .. "\n" | ||
170 | -- end | ||
171 | if (137 == self.status) or (124 == self.status) then | ||
172 | print("timeout killed " .. self.status .. ' ' .. self.command) | ||
173 | print('ERROR ' .. "timeout killed " .. self.status .. ' ' .. self.command) | ||
174 | elseif (nil == self.status) then | ||
175 | print("STATUS |" .. "NIL" .. '| ' .. self.command) | ||
176 | elseif (0 ~= self.status) then | ||
177 | print("STATUS |" .. self.status .. '| ' .. self.command) | ||
178 | end | ||
179 | return self | ||
180 | end | ||
181 | function exe:fork(host) | ||
182 | 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 | ||
183 | self.cmd = '{ ' .. self.cmd .. '; } &' | ||
184 | if true == self.log then D(" forking - <code>" .. self.cmd .. "</code>") end | ||
185 | os.execute(self.cmd) | ||
186 | return self | ||
187 | end | ||
188 | return exe | ||
189 | end | ||
190 | |||
191 | APT.exists = function(c) | ||
192 | if 0 == APT.exe('which ' .. c):Do().status then return true end | ||
193 | return false | ||
194 | end | ||
195 | |||
196 | APT.killEmAll = function(all) | ||
197 | for i,l in ipairs(all) do | ||
198 | local c = 0 | ||
199 | while 0 ~= tonumber(APT.exe("pgrep -u $USER -xc " .. l):Do().lines[1]) do | ||
200 | local s = 'TERM' | ||
201 | if c > 1 then s = 'KILL'; APT.exe("sleep " .. c):Do() end | ||
202 | print( "pkill -" .. s .. " -u $USER -x " .. l) | ||
203 | APT.exe("pkill -" .. s .. " -u $USER -x " .. l):Do() | ||
204 | c = c + 1 | ||
205 | end | ||
206 | end | ||
207 | end | ||
208 | |||
209 | |||
210 | |||
211 | local args = {...} | 95 | local args = {...} |
212 | if 0 ~= #args then | 96 | if 0 ~= #args then |
213 | -- for i,a in pairs(args) do | 97 | -- for i,a in pairs(args) do |
@@ -216,23 +100,27 @@ if 0 ~= #args then | |||
216 | 100 | ||
217 | if 'start' == args[1] then | 101 | if 'start' == args[1] then |
218 | elseif 'stop' == args[1] then | 102 | elseif 'stop' == args[1] then |
219 | APT.killEmAll{'qsynth'} | 103 | _.killEmAll{'qsynth'} |
220 | APT.exe("a2j_control --stop"):Do() | 104 | __[[ |
221 | APT.exe("sleep 2"):Do() | 105 | a2j_control --stop |
222 | APT.exe("a2j_control --exit"):Do() | 106 | sleep 2 |
223 | APT.exe("sleep 2"):Do() | 107 | a2j_control --exit |
224 | APT.killEmAll{'alsa_in', 'alsa_out', 'zita-a2j', 'zita-j2a', 'aseqjoy', 'jack-plumbing'} | 108 | sleep 2 |
225 | APT.exe("sleep 2"):Do() | 109 | ]]:Do() |
226 | APT.exe("jack_control stop"):Do() | 110 | _.killEmAll{'alsa_in', 'alsa_out', 'zita-a2j', 'zita-j2a', 'aseqjoy', 'jack-plumbing'} |
227 | APT.exe("sleep 2"):Do() | 111 | __[[ |
228 | APT.exe("jack_control exit"):Do() | 112 | sleep 2 |
229 | APT.exe("sleep 2"):Do() | 113 | jack_control stop |
230 | APT.killEmAll{'jmcore', 'qjackctl'} | 114 | sleep 2 |
115 | jack_control exit | ||
116 | sleep 2 | ||
117 | ]]:Do() | ||
118 | _.killEmAll{'jmcore', 'qjackctl'} | ||
231 | -- Catia is python, and no easy way to kill it. | 119 | -- Catia is python, and no easy way to kill it. |
232 | -- Also it keeps jackdbus alive, no matter how hard you kill it. | 120 | -- Also it keeps jackdbus alive, no matter how hard you kill it. |
233 | APT.exe("pkill -TERM -u $USER -f catia"):Do() | 121 | __("pkill -TERM -u $USER -f catia"):Do() |
234 | APT.exe("sleep 2"):Do() | 122 | __("sleep 2"):Do() |
235 | APT.killEmAll{'jackdbus', 'a2jmidid'} | 123 | _.killEmAll{'jackdbus', 'a2jmidid'} |
236 | return(0) | 124 | return(0) |
237 | elseif 'JACK' == args[1] then | 125 | elseif 'JACK' == args[1] then |
238 | elseif 'restart' == args[1] then args[1] = 'start' | 126 | elseif 'restart' == args[1] then args[1] = 'start' |
@@ -261,31 +149,31 @@ end | |||
261 | local asoundrcPath = '/var/lib/aataaj' | 149 | local asoundrcPath = '/var/lib/aataaj' |
262 | local asoundrc = 'asoundrc' | 150 | local asoundrc = 'asoundrc' |
263 | local GUI = 'qjackctl' | 151 | local GUI = 'qjackctl' |
264 | if APT.exists('catia') then GUI = 'catia' end | 152 | if _.exists('catia') then GUI = 'catia' end |
265 | local alias = { | 153 | local alias = { |
266 | -- {name='Screen', dev='HDMI9'}, | 154 | -- {name='Screen', dev='HDMI9'}, |
267 | } | 155 | } |
268 | 156 | ||
269 | local speaker = 'espeak' | 157 | local speaker = 'espeak' |
270 | if APT.exists('espeak-ng') then speaker = 'espeak-ng' end | 158 | if _.exists('espeak-ng') then speaker = 'espeak-ng' end |
271 | 159 | ||
272 | local Cards = {} | 160 | local Cards = {} |
273 | 161 | ||
274 | print('Scanning for audio devices.') | 162 | print('Scanning for audio devices.') |
275 | local cards = APT.exe('ls -d1 /proc/asound/card[0-9]*'):noErr():Do() | 163 | local cards = __('ls -d1 /proc/asound/card[0-9]*'):noErr():Do() |
276 | for i,l in ipairs(cards.lines) do | 164 | for i,l in ipairs(cards.lines) do |
277 | local f, e = io.open(l .. '/id', "r") | 165 | local f, e = io.open(l .. '/id', "r") |
278 | if nil == f then print("Could not open " .. l .. '/id') else | 166 | if nil == f then print("Could not open " .. l .. '/id') else |
279 | Cards[l] = {path = l, name = f:read("*a"):sub(1, -2), devs = {}, captureDevs = {}, playbackDevs = {}} | 167 | Cards[l] = {path = l, name = f:read("*a"):sub(1, -2), devs = {}, captureDevs = {}, playbackDevs = {}} |
280 | if "Loopback" ~= Cards[l]['name'] then | 168 | if "Loopback" ~= Cards[l]['name'] then |
281 | Cards[l]['capture'] = APT.exe('ls -d1 ' .. l .. '/pcm[0-9]*c*'):noErr():Do() | 169 | Cards[l]['capture'] = __('ls -d1 ' .. l .. '/pcm[0-9]*c*'):noErr():Do() |
282 | for j,c in ipairs(Cards[l]['capture'].lines) do | 170 | for j,c in ipairs(Cards[l]['capture'].lines) do |
283 | local n = c:match(".*pcm(%d+).*") | 171 | local n = c:match(".*pcm(%d+).*") |
284 | Cards[l]['captureDevs'][j] = n | 172 | Cards[l]['captureDevs'][j] = n |
285 | Cards[l]['devs'][n] = n | 173 | Cards[l]['devs'][n] = n |
286 | print("\tFound capture device: " .. Cards[l]['name'] .. "\tDEVICE: " .. Cards[l]['captureDevs'][j] .. ' ' .. n) | 174 | print("\tFound capture device: " .. Cards[l]['name'] .. "\tDEVICE: " .. Cards[l]['captureDevs'][j] .. ' ' .. n) |
287 | end | 175 | end |
288 | Cards[l]['playback'] = APT.exe('ls -d1 ' .. l .. '/pcm[0-9]*p*'):noErr():Do() | 176 | Cards[l]['playback'] = __('ls -d1 ' .. l .. '/pcm[0-9]*p*'):noErr():Do() |
289 | for j,p in ipairs(Cards[l]['playback'].lines) do | 177 | for j,p in ipairs(Cards[l]['playback'].lines) do |
290 | local n = p:match(".*pcm(%d+).*") | 178 | local n = p:match(".*pcm(%d+).*") |
291 | Cards[l]['playbackDevs'][j] = n | 179 | Cards[l]['playbackDevs'][j] = n |
@@ -293,8 +181,8 @@ for i,l in ipairs(cards.lines) do | |||
293 | print("\tFound playback device " .. i - 1 .. " : " .. Cards[l]['name'] .. "\tDEVICE: " .. Cards[l]['playbackDevs'][j] .. ' ' .. n) | 181 | print("\tFound playback device " .. i - 1 .. " : " .. Cards[l]['name'] .. "\tDEVICE: " .. Cards[l]['playbackDevs'][j] .. ' ' .. n) |
294 | if 'JACK' ~= args[1] then | 182 | if 'JACK' ~= args[1] then |
295 | print('\t\tALSA_CARD=' .. i - 1 .. ' ' .. speaker .. ' "Found playback device ' .. i - 1 .. ' : ' .. Cards[l]['name'] .. ' DEVICE: ' .. Cards[l]['playbackDevs'][j] .. ' ' .. n .. '"') | 183 | print('\t\tALSA_CARD=' .. i - 1 .. ' ' .. speaker .. ' "Found playback device ' .. i - 1 .. ' : ' .. Cards[l]['name'] .. ' DEVICE: ' .. Cards[l]['playbackDevs'][j] .. ' ' .. n .. '"') |
296 | APT.exe('ALSA_CARD=' .. i - 1 .. ' ' .. speaker .. ' "Found playback device ' .. i - 1 .. ' : ' .. Cards[l]['name'] .. ' DEVICE: ' .. Cards[l]['playbackDevs'][j] .. ' ' .. n .. '"'):noErr():Do() | 184 | __('ALSA_CARD=' .. i - 1 .. ' ' .. speaker .. ' "Found playback device ' .. i - 1 .. ' : ' .. Cards[l]['name'] .. ' DEVICE: ' .. Cards[l]['playbackDevs'][j] .. ' ' .. n .. '"'):noErr():Do() |
297 | APT.exe('sleep 1') | 185 | __('sleep 1'):Do() |
298 | end | 186 | end |
299 | end | 187 | end |
300 | end | 188 | end |
@@ -302,7 +190,7 @@ for i,l in ipairs(cards.lines) do | |||
302 | end | 190 | end |
303 | 191 | ||
304 | if 'start' == args[1] then | 192 | if 'start' == args[1] then |
305 | APT.exe('mkdir -p ' .. asoundrcPath):Do() | 193 | __('mkdir -p ' .. asoundrcPath):Do() |
306 | local a, e = io.open(asoundrcPath .. '/jack-plumbing', "w") | 194 | local a, e = io.open(asoundrcPath .. '/jack-plumbing', "w") |
307 | if nil == a then print("Could not open " .. asoundrcPath .. '/jack-plumbing') else | 195 | if nil == a then print("Could not open " .. asoundrcPath .. '/jack-plumbing') else |
308 | a:write([[ | 196 | a:write([[ |
@@ -475,58 +363,58 @@ elseif 'JACK' == args[1] then | |||
475 | print('') | 363 | print('') |
476 | print("Start up JACK and friends.") | 364 | print("Start up JACK and friends.") |
477 | print("jack_control") | 365 | print("jack_control") |
478 | APT.exe('jack_control start'):Do() | 366 | __('jack_control start'):Do() |
479 | APT.exe('jack_control ds alsa'):Do() | 367 | __('jack_control ds alsa'):Do() |
480 | --jack_control dps device hw:RIG,0 | 368 | --jack_control dps device hw:RIG,0 |
481 | local r = APT.exe('jack_control status'):Do().status | 369 | local r = __('jack_control status'):Do().status |
482 | while r ~= 0 do | 370 | while r ~= 0 do |
483 | print("Waiting for JACK - sleep 1") | 371 | print("Waiting for JACK - sleep 1") |
484 | APT.exe('sleep 1'):Do() | 372 | __('sleep 1'):Do() |
485 | r = APT.exe('jack_control status'):Do().status | 373 | r = __('jack_control status'):Do().status |
486 | end | 374 | end |
487 | if nil ~= GUI then | 375 | if nil ~= GUI then |
488 | print(GUI) | 376 | print(GUI) |
489 | APT.exe(GUI):fork() | 377 | __(GUI):fork() |
490 | end | 378 | end |
491 | if APT.exists('jack-plumbing') then | 379 | if _.exists('jack-plumbing') then |
492 | print("jack-plumbing") | 380 | print("jack-plumbing") |
493 | APT.exe('jack-plumbing -o /var/lib/aataaj/jack-plumbing 2>/dev/null'):fork() | 381 | __('jack-plumbing -o /var/lib/aataaj/jack-plumbing 2>/dev/null'):fork() |
494 | end | 382 | end |
495 | if APT.exists('a2j_control') then | 383 | if _.exists('a2j_control') then |
496 | -- Bridge ALSA ports to JACK ports. Only handles MIDI. | 384 | -- Bridge ALSA ports to JACK ports. Only handles MIDI. |
497 | -- 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)/ | 385 | -- 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)/ |
498 | --a2j_control actually starts a2jmidid. | 386 | --a2j_control actually starts a2jmidid. |
499 | ----a2jmidid -e -u & | 387 | ----a2jmidid -e -u & |
500 | -- 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. | 388 | -- 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. |
501 | print("a2j_control") | 389 | print("a2j_control") |
502 | APT.exe('a2j_control --ehw && a2j_control --start'):Do() | 390 | __('a2j_control --ehw && a2j_control --start'):Do() |
503 | -- print("sleep 2") | 391 | -- print("sleep 2") |
504 | -- APT.exe('sleep 2'):Do() | 392 | -- __('sleep 2'):Do() |
505 | print("") | 393 | print("") |
506 | end | 394 | end |
507 | 395 | ||
508 | 396 | ||
509 | local AIN = "alsa_in" | 397 | local AIN = "alsa_in" |
510 | if APT.exists('zita-a2j') then AIN = 'zita-a2j' end | 398 | if _.exists('zita-a2j') then AIN = 'zita-a2j' end |
511 | local AOUT = "alsa_out" | 399 | local AOUT = "alsa_out" |
512 | if APT.exists('zita-j2a') then AOUT = 'zita-j2a' end | 400 | if _.exists('zita-j2a') then AOUT = 'zita-j2a' end |
513 | 401 | ||
514 | print("Basic ALSA sound devices converted to JACK.") | 402 | print("Basic ALSA sound devices converted to JACK.") |
515 | for i,C in pairs(alias) do | 403 | for i,C in pairs(alias) do |
516 | print('HW playback: ' .. C['name'] .. '\tDEVICE: ' .. C['dev']) | 404 | print('HW playback: ' .. C['name'] .. '\tDEVICE: ' .. C['dev']) |
517 | APT.exe(AOUT .. ' -j ' .. C['name'] .. ' -d ' .. C['dev']):fork() | 405 | __(AOUT .. ' -j ' .. C['name'] .. ' -d ' .. C['dev']):fork() |
518 | end | 406 | end |
519 | print("HW playback: cloop\tDEVICE: cloop") | 407 | print("HW playback: cloop\tDEVICE: cloop") |
520 | -- No idea why, cloop wont work with zita-a2j. | 408 | -- No idea why, cloop wont work with zita-a2j. |
521 | APT.exe('alsa_in -j cloop -d cloop'):fork() | 409 | __('alsa_in -j cloop -d cloop'):fork() |
522 | --APT.exe('sleep 1'):Do() | 410 | --__('sleep 1'):Do() |
523 | --APT.exe('jack_connect cloop:capture_1 system:playback_1'):Do() | 411 | --__('jack_connect cloop:capture_1 system:playback_1'):Do() |
524 | --APT.exe('jack_connect cloop:capture_2 system:playback_2'):Do() | 412 | --__('jack_connect cloop:capture_2 system:playback_2'):Do() |
525 | print("HW playback: ploop\tDEVICE: ploop") | 413 | print("HW playback: ploop\tDEVICE: ploop") |
526 | APT.exe('alsa_out -j ploop -d ploop'):fork() | 414 | __('alsa_out -j ploop -d ploop'):fork() |
527 | --APT.exe('sleep 1'):Do() | 415 | --__('sleep 1'):Do() |
528 | --APT.exe('jack_connect system:capture_1 ploop:playback_1'):Do() | 416 | --__('jack_connect system:capture_1 ploop:playback_1'):Do() |
529 | --APT.exe('jack_connect system:capture_2 ploop:playback_2'):Do() | 417 | --__('jack_connect system:capture_2 ploop:playback_2'):Do() |
530 | 418 | ||
531 | 419 | ||
532 | print("") | 420 | print("") |
@@ -535,39 +423,39 @@ elseif 'JACK' == args[1] then | |||
535 | for i,C in pairs(Cards) do | 423 | for i,C in pairs(Cards) do |
536 | for j,c in ipairs(C['playbackDevs']) do | 424 | for j,c in ipairs(C['playbackDevs']) do |
537 | print("HW playback: " .. C['name'] .. "\tDEVICE: " .. C['playbackDevs'][j]) | 425 | print("HW playback: " .. C['name'] .. "\tDEVICE: " .. C['playbackDevs'][j]) |
538 | APT.exe(AOUT .. ' -j ' .. C['name'] .. "_" .. C['playbackDevs'][j] .. '-in -d ' .. C['name'] .. C['playbackDevs'][j]):fork() | 426 | __(AOUT .. ' -j ' .. C['name'] .. "_" .. C['playbackDevs'][j] .. '-in -d ' .. C['name'] .. C['playbackDevs'][j]):fork() |
539 | -- APT.exe('sleep 1'):Do() | 427 | -- __('sleep 1'):Do() |
540 | -- APT.exe('jack_connect cloop:capture_1 ' .. C['name'] .. '_' .. C['playbackDevs'][j] .. '-in' .. ':playback_1'):Do() | 428 | -- __('jack_connect cloop:capture_1 ' .. C['name'] .. '_' .. C['playbackDevs'][j] .. '-in' .. ':playback_1'):Do() |
541 | -- APT.exe('jack_connect cloop:capture_2 ' .. C['name'] .. '_' .. C['playbackDevs'][j] .. '-in' .. ':playback_2'):Do() | 429 | -- __('jack_connect cloop:capture_2 ' .. C['name'] .. '_' .. C['playbackDevs'][j] .. '-in' .. ':playback_2'):Do() |
542 | end | 430 | end |
543 | for j,c in ipairs(C['captureDevs']) do | 431 | for j,c in ipairs(C['captureDevs']) do |
544 | print("HW capture: " .. C['name'] .. "\tDEVICE: " .. C['captureDevs'][j]) | 432 | print("HW capture: " .. C['name'] .. "\tDEVICE: " .. C['captureDevs'][j]) |
545 | APT.exe(AIN .. ' -j ' .. C['name'] .. "_" .. C['captureDevs'][j] .. '-out -d ' .. C['name'] .. C['captureDevs'][j]):fork() | 433 | __(AIN .. ' -j ' .. C['name'] .. "_" .. C['captureDevs'][j] .. '-out -d ' .. C['name'] .. C['captureDevs'][j]):fork() |
546 | end | 434 | end |
547 | end | 435 | end |
548 | print("") | 436 | print("") |
549 | 437 | ||
550 | if APT.exists('aseqjoy') then | 438 | if _.exists('aseqjoy') then |
551 | print("Scanning for joysticks.") | 439 | print("Scanning for joysticks.") |
552 | local sticks = APT.exe('ls -1 /dev/input/js[0-9]*'):noErr():Do() | 440 | local sticks = __('ls -1 /dev/input/js[0-9]*'):noErr():Do() |
553 | for i,l in ipairs(sticks.lines) do | 441 | for i,l in ipairs(sticks.lines) do |
554 | print("aseqjoy " .. l) | 442 | print("aseqjoy " .. l) |
555 | -- Buttons switch to that numbered MIDI channel, defaults to 1. | 443 | -- Buttons switch to that numbered MIDI channel, defaults to 1. |
556 | -- Axis are mapped to MIDI controllers 10 - 15 | 444 | -- Axis are mapped to MIDI controllers 10 - 15 |
557 | -- -r means to use high resolution MIDI values. | 445 | -- -r means to use high resolution MIDI values. |
558 | APT.exe('aseqjoy -d ' .. l:sub(-1,-1) .. ' -r'):fork() | 446 | __('aseqjoy -d ' .. l:sub(-1,-1) .. ' -r'):fork() |
559 | end | 447 | end |
560 | print("") | 448 | print("") |
561 | end | 449 | end |
562 | 450 | ||
563 | if APT.exists('jack-plumbing') then | 451 | if _.exists('jack-plumbing') then |
564 | print('Stop our jack-plumbing, eventually.') | 452 | print('Stop our jack-plumbing, eventually.') |
565 | APT.exe('sleep 4'):Do() | 453 | __('sleep 4'):Do() |
566 | APT.killEmAll{"jack-plumbing"} | 454 | _.killEmAll{"jack-plumbing"} |
567 | end | 455 | end |
568 | 456 | ||
569 | if APT.exists('~/.aataaj_JACK.lua') then | 457 | if _.exists('~/.aataaj_JACK.lua') then |
570 | print('Running users aataaj_JACK.lua') | 458 | print('Running users aataaj_JACK.lua') |
571 | APT.exe('~/.aataaj_JACK.lua'):Do() | 459 | __('~/.aataaj_JACK.lua'):Do() |
572 | end | 460 | end |
573 | end | 461 | end |
diff --git a/test_.lua b/test_.lua new file mode 100755 index 0000000..4d0e723 --- /dev/null +++ b/test_.lua | |||
@@ -0,0 +1,122 @@ | |||
1 | #!/usr/bin/env luajit | ||
2 | |||
3 | |||
4 | local _ = require '_' | ||
5 | local D = _.D | ||
6 | local I = _.I | ||
7 | local T = _.T | ||
8 | local W = _.W | ||
9 | local E = _.E | ||
10 | local C = _.C | ||
11 | local __ = _._ | ||
12 | |||
13 | |||
14 | D('Starting from the top.') | ||
15 | |||
16 | local Help = [[ | ||
17 | This is part of the blah blah blah... | ||
18 | ]] | ||
19 | |||
20 | |||
21 | |||
22 | local args = {...} | ||
23 | if 0 ~= #args then | ||
24 | -- for i,a in pairs(args) do | ||
25 | -- print('Argument ' .. i .. ' = ' .. a) | ||
26 | -- end | ||
27 | |||
28 | if 'start' == args[1] then | ||
29 | elseif 'stop' == args[1] then | ||
30 | --[=[ | ||
31 | _.killEmAll{'qsynth'} | ||
32 | __[[ | ||
33 | a2j_control --stop | ||
34 | sleep 2 | ||
35 | a2j_control --exit | ||
36 | sleep 2 | ||
37 | ]]:Do() | ||
38 | _.killEmAll{'alsa_in', 'alsa_out', 'zita-a2j', 'zita-j2a', 'aseqjoy', 'jack-plumbing'} | ||
39 | __[[ | ||
40 | sleep 2 | ||
41 | jack_control stop | ||
42 | sleep 2 | ||
43 | jack_control exit | ||
44 | sleep 2 | ||
45 | ]]:Do() | ||
46 | _.killEmAll{'jmcore', 'qjackctl'} | ||
47 | -- Catia is python, and no easy way to kill it. | ||
48 | -- Also it keeps jackdbus alive, no matter how hard you kill it. | ||
49 | __"pkill -TERM -u $USER -f catia":Do() | ||
50 | __"sleep 2":Do() | ||
51 | _.killEmAll{'jackdbus', 'a2jmidid'} | ||
52 | ]=] | ||
53 | return(0) | ||
54 | elseif 'JACK' == args[1] then | ||
55 | elseif 'restart' == args[1] then args[1] = 'start' | ||
56 | elseif 'force-reload' == args[1] then args[1] = 'start' | ||
57 | elseif 'status' == args[1] then | ||
58 | return(0) | ||
59 | elseif 'help' == args[1] then | ||
60 | print(Help) | ||
61 | return(0) | ||
62 | elseif '--help' == args[1] then | ||
63 | print(Help) | ||
64 | return(0) | ||
65 | else | ||
66 | print("Usage: /etc/init.d/aataaj.lua {start|stop|restart|force-reload|status}") | ||
67 | return(1) | ||
68 | end | ||
69 | else | ||
70 | print("Usage: /etc/init.d/aataaj.lua {help|start|stop|restart|force-reload|status|JACK}") | ||
71 | return(1) | ||
72 | end | ||
73 | |||
74 | |||
75 | |||
76 | |||
77 | -- CHANGE these to suit. | ||
78 | local asoundrcPath = '/var/lib/aataaj' | ||
79 | local asoundrc = 'asoundrc' | ||
80 | local GUI = 'qjackctl' | ||
81 | if _.exists'catia' then GUI = 'catia' end | ||
82 | local alias = { | ||
83 | {name='Screen', dev='HDMI9'}, | ||
84 | } | ||
85 | |||
86 | local speaker = 'espeak' | ||
87 | if _.exists'espeak-ng' then speaker = 'espeak-ng' end | ||
88 | |||
89 | |||
90 | for i,l in ipairs(__'df -h':log():Do().lines) do | ||
91 | print(l) | ||
92 | end | ||
93 | print('') | ||
94 | |||
95 | __'df -h':log():also'free -h':show():Do() | ||
96 | print('') | ||
97 | |||
98 | for i,l in ipairs(__'df -h\nfree -h':log():Do().lines) do | ||
99 | print(l) | ||
100 | end | ||
101 | print('') | ||
102 | |||
103 | __[[ | ||
104 | df -h | ||
105 | free -h | ||
106 | ]]:log():show():Do() | ||
107 | print('') | ||
108 | |||
109 | for i,l in ipairs(__{'df -h', 'free -h'}:log():Do().lines) do | ||
110 | print(l) | ||
111 | end | ||
112 | print('') | ||
113 | |||
114 | print('' .. GUI) | ||
115 | print('') | ||
116 | |||
117 | print(__'true':log():show():Do().status) | ||
118 | print(__'false':log():show():Do().status) | ||
119 | print(__'exit 42':log():show():Do().status) | ||
120 | print(__'return 42':log():show():Do().status) | ||
121 | print(__'command NoSuchCommand':log():show():Do().status) | ||
122 | |||