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/
|
||||
*.wav
|
||||
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/sys",
|
||||
"/proc/sysrq-trigger"
|
||||
]
|
||||
],
|
||||
"resources":{
|
||||
"devices":[
|
||||
{
|
||||
"allow": true,
|
||||
"type": "c",
|
||||
"major": 116,
|
||||
"access": "rw"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,18 @@
|
||||
},
|
||||
"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" :
|
||||
{
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
"deviceIdentifier": "hw:0,0",
|
||||
"direction": "playback",
|
||||
"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