feat: komplette Codebase vom Board ins Repo gespiegelt
app/ = /opt/callrec (Node-Backend, Vite-Frontend, Python-Inferenz, Audio-Skripte, rkllm_server.cpp), system/ = systemd-Units, WirePlumber/PipeWire-Drop-ins, sudoers. Modelle, Binaries, Aufnahmen und node_modules bleiben draussen (.gitignore). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1 @@
|
||||
callrec ALL=(root) NOPASSWD: /opt/callrec/aime-cpucap.sh
|
||||
@@ -0,0 +1,14 @@
|
||||
[Unit]
|
||||
Description=Aime PC->headset audio bridge (USB gadget capture -> ES8323 playback)
|
||||
After=aime-gadget.service sound.target
|
||||
Wants=aime-gadget.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStartPre=/opt/callrec/aime-mixer-out.sh
|
||||
ExecStart=/bin/sh -c 'exec arecord -D hw:2,0 -f S16_LE -r 48000 -c 2 -B 300000 -F 30000 | aplay -D plughw:0 -f S16_LE -r 48000 -c 2 -B 300000 -F 30000'
|
||||
Restart=always
|
||||
RestartSec=2
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,13 @@
|
||||
[Unit]
|
||||
Description=Aime UAC2 USB audio gadget
|
||||
After=sys-kernel-config.mount usb-gadget.target
|
||||
Wants=sys-kernel-config.mount
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/local/sbin/aime-gadget.sh
|
||||
ExecStop=/bin/sh -c "echo > /sys/kernel/config/usb_gadget/aime/UDC 2>/dev/null; true"
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,10 @@
|
||||
[Unit]
|
||||
Description=Aime H390 inline volume/mute buttons -> headset sink
|
||||
After=sound.target
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/bin/python3 /opt/callrec/aime-headset-keys.py
|
||||
Restart=always
|
||||
RestartSec=2
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,13 @@
|
||||
[Unit]
|
||||
Description=Aime Windows volume -> ES8323 output bridge
|
||||
After=aime-audio-out.service
|
||||
Wants=aime-audio-out.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/opt/callrec/aime-volbridge-alsa.sh
|
||||
Restart=always
|
||||
RestartSec=2
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,12 @@
|
||||
[Unit]
|
||||
Description=CallRec BT headset auto-connect watcher
|
||||
After=bluetooth.service
|
||||
Requires=bluetooth.service
|
||||
|
||||
[Service]
|
||||
ExecStart=/opt/callrec/btwatch.sh
|
||||
Restart=always
|
||||
RestartSec=3
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,12 @@
|
||||
[Unit]
|
||||
Description=CallRec performance tuning (CPU governor = performance)
|
||||
After=multi-user.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/bin/sh -c 'for g in /sys/devices/system/cpu/cpufreq/policy*/scaling_governor; do echo performance > $g; done'
|
||||
ExecStop=/bin/sh -c 'for g in /sys/devices/system/cpu/cpufreq/policy*/scaling_governor; do echo ondemand > $g; done'
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,19 @@
|
||||
[Unit]
|
||||
Description=CallRec - BT recording + Whisper transcription web app
|
||||
After=network-online.target mariadb.service
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=callrec
|
||||
WorkingDirectory=/opt/callrec
|
||||
Environment=NODE_ENV=production
|
||||
Environment=XDG_RUNTIME_DIR=/run/user/1000
|
||||
Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
|
||||
Environment=PORT=3000
|
||||
ExecStart=/usr/bin/node /opt/callrec/server.js
|
||||
Restart=on-failure
|
||||
RestartSec=3
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,2 @@
|
||||
[Service]
|
||||
Environment=RKLLM_MODEL=/opt/rkllm-models/gemma3-4b-w8a8g128-16k.rkllm
|
||||
@@ -0,0 +1,5 @@
|
||||
wireplumber.profiles = {
|
||||
main = {
|
||||
monitor.bluez.seat-monitoring = disabled
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
monitor.bluez.rules = [
|
||||
{
|
||||
matches = [ { node.name = "~bluez_.*" } ]
|
||||
actions = { update-props = { session.suspend-timeout-seconds = 0 node.pause-on-idle = false } }
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
# es8323: S16 mode buggy -> force S24LE. Also rockchip-es8323 glitches under pw's
|
||||
# MMAP/timer access (arecord RW is clean) -> force RW (disable-mmap) + big period.
|
||||
monitor.alsa.rules = [
|
||||
{
|
||||
matches = [ { node.name = "~alsa_(input|output)\.platform-es8323-sound.*" } ]
|
||||
actions = {
|
||||
update-props = {
|
||||
audio.format = "S24LE"
|
||||
api.alsa.disable-mmap = true
|
||||
api.alsa.disable-batch = true
|
||||
api.alsa.period-size = 1024
|
||||
api.alsa.headroom = 8192
|
||||
session.suspend-timeout-seconds = 0
|
||||
node.pause-on-idle = false
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,15 @@
|
||||
context.modules = [
|
||||
{ name = libpipewire-module-filter-chain
|
||||
args = {
|
||||
node.description = "Mic Gate"
|
||||
filter.graph = {
|
||||
nodes = [
|
||||
{ type = ladspa name = gate plugin = "/usr/lib/ladspa/gate_1410.so" label = gate
|
||||
control = { "LF key filter (Hz)" = 50.0 "HF key filter (Hz)" = 8000.0 "Threshold (dB)" = -45.0 "Attack (ms)" = 5.0 "Hold (ms)" = 250.0 "Decay (ms)" = 200.0 "Range (dB)" = -60.0 "Output select (-1 = key listen, 0 = gate, 1 = bypass)" = 0 } }
|
||||
]
|
||||
}
|
||||
capture.props = { node.name = "micgate" media.class = Audio/Sink audio.channels = 1 audio.position = [ MONO ] }
|
||||
playback.props = { node.name = "micgate.out" node.target = "alsa_output.platform-fc000000.usb.stereo-fallback" node.passive = true audio.channels = 1 audio.position = [ MONO ] }
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,10 @@
|
||||
[Unit]
|
||||
Description=CallRec iPhone HFP call auto-routing (gated mic uplink + far-end into rec mix)
|
||||
After=wireplumber.service
|
||||
|
||||
[Service]
|
||||
ExecStart=/opt/callrec/aime-iphone-route.sh
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
@@ -0,0 +1,15 @@
|
||||
[Unit]
|
||||
Description=CallRec mic noise-gate (PipeWire filter-chain: kills far-end self-echo)
|
||||
After=wireplumber.service pipewire-pulse.service
|
||||
Wants=wireplumber.service
|
||||
|
||||
[Service]
|
||||
# Loads ~/.config/pipewire/filter-chain.conf.d/micgate.conf via the stock
|
||||
# filter-chain.conf boilerplate; creates the "micgate" Audio/Sink (LADSPA
|
||||
# gate_1410) whose output feeds the UAC2 gadget sink (Teams/Discord mic).
|
||||
ExecStart=/usr/bin/pipewire -c filter-chain.conf
|
||||
Restart=always
|
||||
RestartSec=2
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
@@ -0,0 +1,10 @@
|
||||
[Unit]
|
||||
Description=CallRec USB-headset audio topology (null-sink mix + loopbacks)
|
||||
After=wireplumber.service pipewire-pulse.service
|
||||
Wants=wireplumber.service
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/opt/callrec/aime-usb-audio-setup.sh
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
@@ -0,0 +1,11 @@
|
||||
[Unit]
|
||||
Description=CallRec Windows volume -> USB headset bridge
|
||||
After=aime-usb-audio.service
|
||||
Wants=aime-usb-audio.service
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/opt/callrec/aime-volbridge-headset.sh
|
||||
Restart=always
|
||||
RestartSec=2
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
Binary file not shown.
@@ -0,0 +1,4 @@
|
||||
monitor.bluez.properties = {
|
||||
bluez5.roles = [ a2dp_sink hfp_hf hsp_hs ]
|
||||
bluez5.hfphsp-backend = "native"
|
||||
}
|
||||
Reference in New Issue
Block a user