First functioning ASRC with dante.
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,5 +1,5 @@
|
|||||||
dep/dante_package/dante_data/config/
|
dep/dante_package/dante_data/config/
|
||||||
*.wav
|
*.wav
|
||||||
recordings/
|
recordings/
|
||||||
|
tmp/
|
||||||
|
|
||||||
|
|||||||
71
asoundrc.danteasrc
Normal file
71
asoundrc.danteasrc
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
# ============================================================
|
||||||
|
# DEP Dante RX -> ALSA Loopback is now done by DEP ALSA ASRC.
|
||||||
|
# So: NO alsaloop needed anymore.
|
||||||
|
#
|
||||||
|
# Apps read from hw:Loopback,1,0 via dsnoop fanout,
|
||||||
|
# then we split into 6 mono virtual devices.
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
# ---- shared 6ch capture from Loopback with dsnoop fanout ----
|
||||||
|
pcm.dante_asrc_shared6 {
|
||||||
|
type dsnoop
|
||||||
|
ipc_key 1048577
|
||||||
|
ipc_key_add_uid true
|
||||||
|
ipc_perm 0666
|
||||||
|
|
||||||
|
slave {
|
||||||
|
pcm "hw:Loopback,1,0" # capture side of ALSA loopback
|
||||||
|
channels 6
|
||||||
|
rate 48000
|
||||||
|
format S16_LE
|
||||||
|
|
||||||
|
period_size 256
|
||||||
|
buffer_size 1024
|
||||||
|
}
|
||||||
|
|
||||||
|
hint { show on ; description "DEP RX (via ASRC) shared 6ch (loopback+dsnoop)" }
|
||||||
|
}
|
||||||
|
|
||||||
|
# ---- 6 mono devices (each maps one of the 6 channels) ----
|
||||||
|
# (Using route explicitly makes the intent very clear.)
|
||||||
|
pcm.dante_asrc_ch1 {
|
||||||
|
type route
|
||||||
|
slave { pcm "dante_asrc_shared6"; channels 6; }
|
||||||
|
ttable.0.0 1
|
||||||
|
hint { show on ; description "DEP RX CH1" }
|
||||||
|
}
|
||||||
|
|
||||||
|
pcm.dante_asrc_ch2 {
|
||||||
|
type route
|
||||||
|
slave { pcm "dante_asrc_shared6"; channels 6; }
|
||||||
|
ttable.0.1 1
|
||||||
|
hint { show on ; description "DEP RX CH2" }
|
||||||
|
}
|
||||||
|
|
||||||
|
pcm.dante_asrc_ch3 {
|
||||||
|
type route
|
||||||
|
slave { pcm "dante_asrc_shared6"; channels 6; }
|
||||||
|
ttable.0.2 1
|
||||||
|
hint { show on ; description "DEP RX CH3" }
|
||||||
|
}
|
||||||
|
|
||||||
|
pcm.dante_asrc_ch4 {
|
||||||
|
type route
|
||||||
|
slave { pcm "dante_asrc_shared6"; channels 6; }
|
||||||
|
ttable.0.3 1
|
||||||
|
hint { show on ; description "DEP RX CH4" }
|
||||||
|
}
|
||||||
|
|
||||||
|
pcm.dante_asrc_ch5 {
|
||||||
|
type route
|
||||||
|
slave { pcm "dante_asrc_shared6"; channels 6; }
|
||||||
|
ttable.0.4 1
|
||||||
|
hint { show on ; description "DEP RX CH5" }
|
||||||
|
}
|
||||||
|
|
||||||
|
pcm.dante_asrc_ch6 {
|
||||||
|
type route
|
||||||
|
slave { pcm "dante_asrc_shared6"; channels 6; }
|
||||||
|
ttable.0.5 1
|
||||||
|
hint { show on ; description "DEP RX CH6" }
|
||||||
|
}
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
# DEP dsoundcard ALSA plugin configuration
|
|
||||||
# Install with: sudo bash install_dsoundcard.sh
|
|
||||||
|
|
||||||
# Needs this command running in background to loopback the dsoundcard to dsnoop
|
|
||||||
# sudo alsaloop -C dsoundcard -c 6 -r 48000 -f S16_LE -P hw:Loopback,0,0
|
|
||||||
|
|
||||||
pcm_type.dsoundcard {
|
|
||||||
lib "/opt/dep/dsoundcard.so"
|
|
||||||
}
|
|
||||||
|
|
||||||
pcm.dsoundcard {
|
|
||||||
type dsoundcard
|
|
||||||
hint { show on ; description "DEP Sound Card (raw 6ch)" }
|
|
||||||
}
|
|
||||||
|
|
||||||
# ---- shared 6ch capture from Loopback with dsnoop fanout ----
|
|
||||||
pcm.dsoundcard_shared6 {
|
|
||||||
type dsnoop
|
|
||||||
ipc_key 1048577
|
|
||||||
ipc_key_add_uid true
|
|
||||||
ipc_perm 0666
|
|
||||||
|
|
||||||
slave {
|
|
||||||
pcm "hw:Loopback,1,0"
|
|
||||||
channels 6
|
|
||||||
rate 48000
|
|
||||||
format S16_LE
|
|
||||||
}
|
|
||||||
|
|
||||||
hint { show on ; description "DEP Sound Card (shared 6ch via loopback+dsnoop)" }
|
|
||||||
}
|
|
||||||
|
|
||||||
# ---- 6 mono devices (each maps one of the 6 channels) ----
|
|
||||||
pcm.dsoundcard_ch1 { type plug; slave.pcm "dsoundcard_shared6"; slave.channels 6; ttable.0.0 1
|
|
||||||
hint { show on ; description "DEP Sound Card - CH1" } }
|
|
||||||
pcm.dsoundcard_ch2 { type plug; slave.pcm "dsoundcard_shared6"; slave.channels 6; ttable.0.1 1
|
|
||||||
hint { show on ; description "DEP Sound Card - CH2" } }
|
|
||||||
pcm.dsoundcard_ch3 { type plug; slave.pcm "dsoundcard_shared6"; slave.channels 6; ttable.0.2 1
|
|
||||||
hint { show on ; description "DEP Sound Card - CH3" } }
|
|
||||||
pcm.dsoundcard_ch4 { type plug; slave.pcm "dsoundcard_shared6"; slave.channels 6; ttable.0.3 1
|
|
||||||
hint { show on ; description "DEP Sound Card - CH4" } }
|
|
||||||
pcm.dsoundcard_ch5 { type plug; slave.pcm "dsoundcard_shared6"; slave.channels 6; ttable.0.4 1
|
|
||||||
hint { show on ; description "DEP Sound Card - CH5" } }
|
|
||||||
pcm.dsoundcard_ch6 { type plug; slave.pcm "dsoundcard_shared6"; slave.channels 6; ttable.0.5 1
|
|
||||||
hint { show on ; description "DEP Sound Card - CH6" } }
|
|
||||||
@@ -305,6 +305,16 @@
|
|||||||
"/proc/irq",
|
"/proc/irq",
|
||||||
"/proc/sys",
|
"/proc/sys",
|
||||||
"/proc/sysrq-trigger"
|
"/proc/sysrq-trigger"
|
||||||
]
|
],
|
||||||
|
"resources":{
|
||||||
|
"devices":[
|
||||||
|
{
|
||||||
|
"allow": true,
|
||||||
|
"type": "c",
|
||||||
|
"major": 116,
|
||||||
|
"access": "rw"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,18 @@
|
|||||||
},
|
},
|
||||||
"alsaAsrc":
|
"alsaAsrc":
|
||||||
{
|
{
|
||||||
"enableAlsaAsrc": false
|
"enableAlsaAsrc": true,
|
||||||
|
"deviceConfigurations": [
|
||||||
|
{
|
||||||
|
"deviceIdentifier": "hw:0,0",
|
||||||
|
"direction": "playback",
|
||||||
|
"bitDepth": 16,
|
||||||
|
"numOpenChannels": 6,
|
||||||
|
"alsaChannelRange": "0-5",
|
||||||
|
"danteChannelRange": "0-5",
|
||||||
|
"bufferSize": 48000
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"product" :
|
"product" :
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -62,7 +62,7 @@
|
|||||||
"deviceIdentifier": "hw:0,0",
|
"deviceIdentifier": "hw:0,0",
|
||||||
"direction": "playback",
|
"direction": "playback",
|
||||||
"bitDepth": 16,
|
"bitDepth": 16,
|
||||||
"bufferSize": 48000
|
"bufferSize": 480
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
148
test_dep_asrc_onedeviceperchannel.sh
Normal file
148
test_dep_asrc_onedeviceperchannel.sh
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Quiet locale warnings (optional)
|
||||||
|
export LC_ALL="${LC_ALL:-C}"
|
||||||
|
|
||||||
|
OUTPUT_DIR="./tmp"
|
||||||
|
DURATION=10
|
||||||
|
RATE=48000
|
||||||
|
FORMAT="S16_LE"
|
||||||
|
CHANNELS=1
|
||||||
|
TIMESTAMP="$(date +%Y%m%d_%H%M%S)"
|
||||||
|
|
||||||
|
mkdir -p "$OUTPUT_DIR"
|
||||||
|
|
||||||
|
echo "======================================================"
|
||||||
|
echo "DEP ASRC -> ALSA Loopback -> dsnoop Test (parallel)"
|
||||||
|
echo "======================================================"
|
||||||
|
echo "Recording one channel from each device IN PARALLEL:"
|
||||||
|
echo " dante_asrc_ch1 .. dante_asrc_ch6"
|
||||||
|
echo "Duration: $DURATION seconds"
|
||||||
|
echo "Output directory: $OUTPUT_DIR"
|
||||||
|
echo "Timestamp: $TIMESTAMP"
|
||||||
|
echo "======================================================"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Check if DEP is running
|
||||||
|
if ! pgrep -f "dep_manager" >/dev/null; then
|
||||||
|
echo "ERROR: DEP is not running!"
|
||||||
|
echo "Start DEP first: cd /home/caster/dante_beacon && sudo bash dep.sh start"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
device_exists() {
|
||||||
|
local dev="$1"
|
||||||
|
aplay -L 2>/dev/null | grep -qx "$dev" || arecord -L 2>/dev/null | grep -qx "$dev"
|
||||||
|
}
|
||||||
|
|
||||||
|
loopback_present() {
|
||||||
|
# Hardware device list is more reliable than arecord -L naming
|
||||||
|
arecord -l 2>/dev/null | grep -qi "Loopback" || aplay -l 2>/dev/null | grep -qi "Loopback"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Warn (don’t hard-fail) if Loopback hardware isn't visible
|
||||||
|
if ! loopback_present; then
|
||||||
|
echo "WARNING: ALSA Loopback hardware not found in 'arecord -l' / 'aplay -l'."
|
||||||
|
echo "If you expect Loopback, load it with:"
|
||||||
|
echo " sudo modprobe snd-aloop"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Ensure our virtual per-channel devices exist (from your asound.conf)
|
||||||
|
missing=0
|
||||||
|
for i in $(seq 1 6); do
|
||||||
|
if ! device_exists "dante_asrc_ch${i}"; then
|
||||||
|
echo "ERROR: dante_asrc_ch${i} not found (asound.conf not applied?)"
|
||||||
|
missing=1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$missing" -ne 0 ]; then
|
||||||
|
echo ""
|
||||||
|
echo "Hint: list relevant devices with:"
|
||||||
|
echo " arecord -L | grep -E 'dante_asrc_(shared6|ch[1-6])' -n"
|
||||||
|
echo ""
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Track background jobs
|
||||||
|
declare -a DEVICES=()
|
||||||
|
declare -a FILES=()
|
||||||
|
declare -a PIDS=()
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
echo ""
|
||||||
|
echo "Stopping recordings..."
|
||||||
|
for pid in "${PIDS[@]:-}"; do
|
||||||
|
kill "$pid" 2>/dev/null || true
|
||||||
|
done
|
||||||
|
wait 2>/dev/null || true
|
||||||
|
echo "Done."
|
||||||
|
}
|
||||||
|
trap cleanup INT TERM
|
||||||
|
|
||||||
|
echo "Launching recordings..."
|
||||||
|
for i in $(seq 1 6); do
|
||||||
|
DEVICE="dante_asrc_ch${i}"
|
||||||
|
OUTPUT_FILE="${OUTPUT_DIR}/${DEVICE}_${TIMESTAMP}.wav"
|
||||||
|
LOG_FILE="${OUTPUT_DIR}/${DEVICE}_${TIMESTAMP}.log"
|
||||||
|
|
||||||
|
echo " -> $DEVICE => $OUTPUT_FILE"
|
||||||
|
arecord -D "$DEVICE" \
|
||||||
|
-c "$CHANNELS" -f "$FORMAT" -r "$RATE" -d "$DURATION" \
|
||||||
|
"$OUTPUT_FILE" >"$LOG_FILE" 2>&1 &
|
||||||
|
|
||||||
|
pid=$!
|
||||||
|
DEVICES+=("$DEVICE")
|
||||||
|
FILES+=("$OUTPUT_FILE")
|
||||||
|
PIDS+=("$pid")
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "All recordings started. Waiting for completion..."
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
SUCCESS_COUNT=0
|
||||||
|
FAIL_COUNT=0
|
||||||
|
|
||||||
|
for idx in "${!PIDS[@]}"; do
|
||||||
|
pid="${PIDS[$idx]}"
|
||||||
|
dev="${DEVICES[$idx]}"
|
||||||
|
out="${FILES[$idx]}"
|
||||||
|
|
||||||
|
if wait "$pid"; then
|
||||||
|
if [ -f "$out" ]; then
|
||||||
|
SUCCESS_COUNT=$((SUCCESS_COUNT + 1))
|
||||||
|
size="$(ls -lh "$out" | awk '{print $5}')"
|
||||||
|
echo "OK $dev -> $out ($size)"
|
||||||
|
else
|
||||||
|
FAIL_COUNT=$((FAIL_COUNT + 1))
|
||||||
|
echo "FAIL $dev -> file not created: $out"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
FAIL_COUNT=$((FAIL_COUNT + 1))
|
||||||
|
echo "FAIL $dev (arecord exit != 0). See log: ${out%.wav}.log"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "======================================================"
|
||||||
|
echo "Summary: $SUCCESS_COUNT successful, $FAIL_COUNT failed"
|
||||||
|
echo "======================================================"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if command -v sox &>/dev/null; then
|
||||||
|
echo "Audio file info (sox stat):"
|
||||||
|
for out in "${FILES[@]}"; do
|
||||||
|
if [ -f "$out" ]; then
|
||||||
|
echo "---- $(basename "$out") ----"
|
||||||
|
sox "$out" -n stat 2>&1 | grep -E "Sample Rate|Channels|Duration|Length|Maximum amplitude|RMS"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "To play a recording:"
|
||||||
|
echo " aplay ${OUTPUT_DIR}/dante_asrc_ch1_${TIMESTAMP}.wav"
|
||||||
|
echo ""
|
||||||
@@ -1,139 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -u
|
|
||||||
|
|
||||||
# Record ALL channels at the same time (one device per channel)
|
|
||||||
# Starts arecord for dsoundcard_ch1 .. dsoundcard_ch6 in parallel.
|
|
||||||
|
|
||||||
OUTPUT_DIR="./recordings"
|
|
||||||
DURATION=10 # seconds
|
|
||||||
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
|
||||||
|
|
||||||
mkdir -p "$OUTPUT_DIR"
|
|
||||||
|
|
||||||
echo "=========================================="
|
|
||||||
echo "DEP dsoundcard ALSA Plugin Test (parallel)"
|
|
||||||
echo "=========================================="
|
|
||||||
echo "Recording one channel from each device IN PARALLEL:"
|
|
||||||
echo " dsoundcard_ch1 .. dsoundcard_ch6"
|
|
||||||
echo "Duration: $DURATION seconds"
|
|
||||||
echo "Output directory: $OUTPUT_DIR"
|
|
||||||
echo "Timestamp: $TIMESTAMP"
|
|
||||||
echo "=========================================="
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Check if DEP is running
|
|
||||||
if ! pgrep -f "dep_manager" > /dev/null; then
|
|
||||||
echo "ERROR: DEP is not running!"
|
|
||||||
echo "Start DEP first: cd /home/caster/dante_beacon && sudo bash dep.sh start"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check base dsoundcard plugin existence (list both playback+capture definitions)
|
|
||||||
if ! (aplay -L 2>/dev/null | grep -q "^dsoundcard$" || arecord -L 2>/dev/null | grep -q "^dsoundcard$"); then
|
|
||||||
echo "ERROR: dsoundcard ALSA plugin not found!"
|
|
||||||
echo "Make sure dsoundcard.so is installed in /opt/dep/"
|
|
||||||
echo "And ~/.asoundrc is configured correctly"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
device_exists() {
|
|
||||||
local dev="$1"
|
|
||||||
aplay -L 2>/dev/null | grep -q "^${dev}$" || arecord -L 2>/dev/null | grep -q "^${dev}$"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Track background jobs
|
|
||||||
declare -a DEVICES=()
|
|
||||||
declare -a FILES=()
|
|
||||||
declare -a PIDS=()
|
|
||||||
|
|
||||||
# Kill all jobs on Ctrl-C / termination
|
|
||||||
cleanup() {
|
|
||||||
echo ""
|
|
||||||
echo "Stopping recordings..."
|
|
||||||
for pid in "${PIDS[@]:-}"; do
|
|
||||||
kill "$pid" 2>/dev/null || true
|
|
||||||
done
|
|
||||||
wait 2>/dev/null || true
|
|
||||||
echo "Done."
|
|
||||||
}
|
|
||||||
trap cleanup INT TERM
|
|
||||||
|
|
||||||
# Start all recordings
|
|
||||||
echo "Launching recordings..."
|
|
||||||
for i in $(seq 1 6); do
|
|
||||||
DEVICE="dsoundcard_ch${i}"
|
|
||||||
OUTPUT_FILE="${OUTPUT_DIR}/${DEVICE}_${TIMESTAMP}.wav"
|
|
||||||
LOG_FILE="${OUTPUT_DIR}/${DEVICE}_${TIMESTAMP}.log"
|
|
||||||
|
|
||||||
if ! device_exists "$DEVICE"; then
|
|
||||||
echo "WARNING: $DEVICE not found in ALSA device lists, skipping."
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo " -> $DEVICE => $OUTPUT_FILE"
|
|
||||||
# Run in background; capture stderr/stdout into a log for debugging
|
|
||||||
arecord -D "$DEVICE" \
|
|
||||||
-c 1 -f S16_LE -r 48000 -d "$DURATION" \
|
|
||||||
--buffer-size=4096 \
|
|
||||||
"$OUTPUT_FILE" >"$LOG_FILE" 2>&1 &
|
|
||||||
|
|
||||||
pid=$!
|
|
||||||
DEVICES+=("$DEVICE")
|
|
||||||
FILES+=("$OUTPUT_FILE")
|
|
||||||
PIDS+=("$pid")
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ "${#PIDS[@]}" -eq 0 ]; then
|
|
||||||
echo "ERROR: No devices were started. Nothing to do."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "All recordings started. Waiting for completion..."
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Wait for all and collect results
|
|
||||||
SUCCESS_COUNT=0
|
|
||||||
FAIL_COUNT=0
|
|
||||||
|
|
||||||
for idx in "${!PIDS[@]}"; do
|
|
||||||
pid="${PIDS[$idx]}"
|
|
||||||
dev="${DEVICES[$idx]}"
|
|
||||||
out="${FILES[$idx]}"
|
|
||||||
|
|
||||||
if wait "$pid"; then
|
|
||||||
if [ -f "$out" ]; then
|
|
||||||
SUCCESS_COUNT=$((SUCCESS_COUNT + 1))
|
|
||||||
size=$(ls -lh "$out" | awk '{print $5}')
|
|
||||||
echo "OK $dev -> $out ($size)"
|
|
||||||
else
|
|
||||||
FAIL_COUNT=$((FAIL_COUNT + 1))
|
|
||||||
echo "FAIL $dev -> file not created: $out"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
FAIL_COUNT=$((FAIL_COUNT + 1))
|
|
||||||
echo "FAIL $dev (arecord exit != 0). See log: ${out%.wav}.log"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "=========================================="
|
|
||||||
echo "Summary: $SUCCESS_COUNT successful, $FAIL_COUNT failed/skipped"
|
|
||||||
echo "=========================================="
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Optional: show brief file stats
|
|
||||||
if command -v sox &> /dev/null; then
|
|
||||||
echo "Audio file info (sox stat):"
|
|
||||||
for out in "${FILES[@]}"; do
|
|
||||||
if [ -f "$out" ]; then
|
|
||||||
echo "---- $(basename "$out") ----"
|
|
||||||
sox "$out" -n stat 2>&1 | grep -E "Sample Rate|Channels|Duration|Length|Maximum amplitude|RMS"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "To play a recording:"
|
|
||||||
echo " aplay ${OUTPUT_DIR}/dsoundcard_ch1_${TIMESTAMP}.wav"
|
|
||||||
echo ""
|
|
||||||
Reference in New Issue
Block a user