On 06.03.2025 15:46, Jan Stary wrote:
Hi,
On Mar 06 10:48:06, em...@kollof.nl wrote:
I was wondering if people with USB audio interfaces have the same issue
as me. When using the microphone of my usb audio interface, the recorded
audio starts to stutter/pop, indicating buffering problems, usually when
I do something that causes a bit of load on the system (e.g. starting a
browser). A good example of this happening is here:
https://youtu.be/Vbi5f1SlXZw?si=5pjaMI4aAf6Luewx&t=380 (at the 6:20
mark, the link should take you there)
I don't have this problem with any of my USB audio inerfaces.
How exactly are you recording this audio/video?
Can you replicate the problem with plain aucat -o?
(Still trying to reliably reproduce this. This seems to happen almost
reliably when I'm *not* actively monitoring things. It's almost
Heisenberg-like)
I'll attach the recording script I made for doing desktop recording and
streaming to this mail. You can flame my hacky ksh scripting :)
I would suspect the recording software rather than
tha audio subsystem itself, and it buffers etc.
At any rate, try to do the same with sndiod -ddd
running in a script(1) and show the results:
any xruns will be reported there.
Got that running in a seperate tag in dwm all the time for now. I do see
a lot of these:
chrome1: xrun, pause cycle
chrome0: xrun, pause cycle
rsnd/0: rec hw xrun, rused = 480 / 3840
rsnd/0: play hw xrun, pused = 3360 / 3840
It would be nice if sndiod debug could have timestamps so I can see
*when* things happen so I can correlate it a bit better with what I was
doing.
This also happens while videoconferencing with platforms like Teams and
Jitsi meet. The remote end claims I sound like a 'robot'.
Again, there are layers betwenn sndiod and what Teams and Jitsi
are doing (inside a browser I suppose? Which browser? Every browser?).
I think I solved the "robot" issue. It was artifacting that seems to
sporadicly happen when you plug your USB2 high speed audio interface in
a USB3 super speed port. I hear this is a common issue?
Cheers,
Emiel Kollof
#!/bin/ksh
# Help message
usage() {
echo "Usage: $0 [-s screen] [-l] [-h] [-c config]"
echo " -s screen Select screen number (0, 1, 2, etc.)"
echo " -l List available screens"
echo " -h Show this help message"
echo " -c config Source configuration file for streaming"
exit 1
}
# Function to list screens with xrandr
list_screens() {
echo "Available screens:"
xrandr --listactivemonitors | tail -n +2 | nl -v 0
}
# Function to get screen geometry for a given screen number
get_screen_geometry() {
screen_num=$1
echo "Debug: Looking for screen $screen_num"
# Get the selected monitor line
monitor_info=$(xrandr --listactivemonitors | tail -n +2 | sed -n
"$((screen_num + 1))p")
echo "Debug: Monitor info: $monitor_info"
if [ -z "$monitor_info" ]; then
echo "Error: Screen $screen_num not found" >&2
exit 1
fi
# Get raw dimensions from xrandr --listmonitors (which shows actual pixels)
raw_info=$(xrandr | grep -A1 "^Screen" | tail -n1)
echo "Debug: Raw screen info: $raw_info"
# First try to get current resolution from xrandr output
current_mode=$(xrandr | grep -A1 "^$(echo "$monitor_info" | awk '{print
$3}')" | grep -v "^--" | grep "*" | awk '{print $1}')
echo "Debug: Current mode: $current_mode"
if [ -n "$current_mode" ]; then
SCREEN_WIDTH=$(echo "$current_mode" | cut -d'x' -f1)
SCREEN_HEIGHT=$(echo "$current_mode" | cut -d'x' -f2)
else
# Fallback to parsing from monitor_info
SCREEN_WIDTH=$(echo "$monitor_info" | awk '{print $3}' | cut -d'/' -f1)
SCREEN_HEIGHT=$(echo "$monitor_info" | awk '{print $3}' | cut -d'x' -f2
| cut -d'/' -f1)
fi
# Extract offsets
SCREEN_OFFSET_X=$(echo "$monitor_info" | awk '{print $3}' | sed
's/.*+\([0-9]*\)+.*/\1/')
SCREEN_OFFSET_Y=$(echo "$monitor_info" | awk '{print $3}' | sed
's/.*+[0-9]*+\([0-9]*\)/\1/')
echo "Debug: Parsed values:"
echo "Width: $SCREEN_WIDTH"
echo "Height: $SCREEN_HEIGHT"
echo "Offset X: $SCREEN_OFFSET_X"
echo "Offset Y: $SCREEN_OFFSET_Y"
# Verify we got valid numbers
if [ -z "$SCREEN_WIDTH" ] || [ -z "$SCREEN_HEIGHT" ] || \
[ -z "$SCREEN_OFFSET_X" ] || [ -z "$SCREEN_OFFSET_Y" ]; then
echo "Error: Failed to parse screen dimensions" >&2
exit 1
fi
}
# Function to source config file
source_config() {
config_file=$1
if [ -f "$config_file" ]; then
. "$config_file"
else
echo "Error: Config file $config_file not found" >&2
exit 1
fi
}
# Initialize variables
SCREEN=""
SCREEN_WIDTH=""
SCREEN_HEIGHT=""
SCREEN_OFFSET_X=""
SCREEN_OFFSET_Y=""
RTMP_URI=""
STREAM_KEY=""
# Parse command line options
while getopts "s:lhc:" opt; do
case $opt in
s)
SCREEN=${OPTARG}
get_screen_geometry "$SCREEN"
;;
l)
list_screens
exit 0
;;
h)
usage
;;
c)
source_config "${OPTARG}"
;;
*)
echo "Invalid option: -$OPTARG" >&2
usage
;;
esac
done
# If no screen specified or geometry not set, show usage
if [ -z "$SCREEN" ] || [ -z "$SCREEN_WIDTH" ]; then
echo "Error: No screen selected or screen geometry not found" >&2
usage
fi
# Get current timestamp
NAME=$(date '+%Y-%m-%d_%H%M%S')
echo "Recording screen $SCREEN (${SCREEN_WIDTH}x${SCREEN_HEIGHT} at offset
${SCREEN_OFFSET_X},${SCREEN_OFFSET_Y})"
# Determine output destination
if [ -n "$RTMP_URI" ] && [ -n "$STREAM_KEY" ]; then
OUTPUT="$RTMP_URI/$STREAM_KEY.flv"
echo "STREAMING"
else
OUTPUT="$HOME/Videos/$NAME.mkv"
fi
ffmpeg -hwaccel vaapi -vaapi_device /dev/dri/renderD128 \
-f sndio -thread_queue_size 4096 -i snd/0.mon \
-f sndio -thread_queue_size 8192 -i snd/0 \
-f x11grab -thread_queue_size 128 -probesize 32M -draw_mouse 1 \
-video_size ${SCREEN_WIDTH}x${SCREEN_HEIGHT} -r 60 \
-i :0.0+${SCREEN_OFFSET_X},${SCREEN_OFFSET_Y} \
-filter_complex "\
[0:a]volume=4.0,pan=stereo|c0=c0|c1=c1[desktop];\
[1:a]volume=3.0,acompressor=threshold=0.125:ratio=4:attack=200:release=1000,dynaudnorm=f=10:g=3:p=0.9,pan=stereo|c0=c0|c1=c1[mic];\
[desktop][mic]amix=inputs=2:duration=first[aout]" \
-map 2:v \
-map '[aout]' \
-c:v h264_vaapi \
-vf 'format=nv12|vaapi,hwupload' \
-qp 0 \
-c:a aac \
-b:a 160k \
-ar 48000 \
-preset ultrafast \
-ac 2 \
-crf 23 \
-b:v 6500k \
-fps_mode cfr \
-async 1 \
-vsync 1 \
-flags +low_delay \
-fflags +nobuffer \
-use_wallclock_as_timestamps 1 \
-y \
"$OUTPUT"
if [ -z $RMTP_URI ]; then
echo "Recording saved in $OUTPUT"
fi