Recommendations for DAWs with OBS?

tradrich

New Member
I noticed this response to a recent question.

@AaronD recommends "moving ALL of the audio work out of OBS and into a DAW".

It would be great to have a short guide on this, or at least a suggestion on DAWs (and, err... for Linux?)
 

AaronD

Active Member
Look up how to make a loopback with the audio system that you have. I use Ubuntu Studio 22.04 LTS, which is the last if I remember right, to not use PipeWire by default. So I have a script that sets up a bunch of loopbacks/bridges in PulseAudio, one end of which connects to JACK.
(pactl load-module module-jack-sink ... or pactl load-module module-jack-source ..., depending on which direction it's going)
The DAW (Ardour for me, which comes preinstalled in UStudio and "just works", along with a TON of good plugins!) then connects to the JACK side of those loopbacks just like any other device, and OBS and everything else connects to the PulseAudio side of the same loopbacks just like any other device.

Bash:
#!/bin/bash



###########################################
### HOUSEKEEPING AND ERROR-CHECKING     ###
###########################################

AUDIO_CHECK="$1"
shift
AUDIO_SETUP="$1"
shift
AUDIO_TEARDOWN="$1"
shift

###############################################
### MORE HOUSEKEEPING AND ERROR-CHECKING    ###
###############################################

#
# Wait for Mic, Spk Present
#

echo
"$AUDIO_CHECK"
RESULT=$?
if [[ "$RESULT" != "0" ]]
then
    exit $RESULT
fi

#
# Start Jack
#

echo
echo "Start Jack"
qjackctl &
PID_JACK=$!
sleep 5

#
# Create Bridges to/from PulseAudio
#

echo
echo "Create Bridges to/from PulseAudio"
INDEX_SINK_0=$(     pactl   load-module     module-jack-sink    channels=2    sink_name=PA_out_Playback     client_name=PA_out_Playback     )
INDEX_SINK_1=$(     pactl   load-module     module-jack-sink    channels=2    sink_name=PA_out_Meet_Rtrn    client_name=PA_out_Meet_Rtrn    )
INDEX_SOURCE_0=$(   pactl   load-module     module-jack-source  channels=2  source_name=PA_in_Mics          client_name=PA_in_Mics          )
INDEX_SOURCE_1=$(   pactl   load-module     module-jack-source  channels=2  source_name=PA_in_Meet_Send     client_name=PA_in_Meet_Send     )
INDEX_SOURCE_2=$(   pactl   load-module     module-jack-source  channels=2  source_name=PA_in_Record        client_name=PA_in_Record        )

#
# Remove Automatic Connections
#

disconnect_all ()
{
    for CONNECTION in $(jack_lsp --connections "$1")
    do
        if [[ "$CONNECTION" = "$1" ]]
        then
            continue
        fi
        jack_disconnect "$1" "$CONNECTION"
    done
}
disconnect_all system:capture_1
disconnect_all system:capture_2
disconnect_all system:playback_1
disconnect_all system:playback_2

#
# Save and Set Default Connections
#

PA_DEFAULT_SINK=$(      pactl   get-default-sink    )
PA_DEFAULT_SOURCE=$(    pactl   get-default-source  )
pactl   set-default-sink    PA_out_Playback
pactl   set-default-source  PA_in_Mics

#
# Create Bridges to/from Mic, Spk
#

echo
"$AUDIO_SETUP" "/tmp/pid_audio"
PID_AUDIO=$(<"/tmp/pid_audio")
rm "/tmp/pid_audio"

###########################
### START APPS,         ###
### WAIT FOR DONE,      ###
### CLOSE APPS          ###
###########################

#
# Remove Bridges to/from Mic, Spk
#

echo
"$AUDIO_TEARDOWN" $PID_AUDIO

#
# Restore Default Connections
#

echo
echo "Unload Bridges between Jack and PulseAudio"
pactl   set-default-sink    "$PA_DEFAULT_SINK"
pactl   set-default-source  "$PA_DEFAULT_SOURCE"

#
# Remove Bridges to/from PulseAudio
#

pactl unload-module $INDEX_SOURCE_2
pactl unload-module $INDEX_SOURCE_1
pactl unload-module $INDEX_SOURCE_0
pactl unload-module $INDEX_SINK_1
pactl unload-module $INDEX_SINK_0

#
# Stop Jack
#

echo
echo "Stop Jack"
kill -TERM "$PID_JACK"
sleep 1

#
# End
#
AUDIO_CHECK, AUDIO_SETUP, and AUDIO_TEARDOWN are other scripts. Their filenames/paths are passed as arguments to the main script above, so I can use the same structure with different physical mics and speakers. As an example of how they work:

Audio Check:
Bash:
#!/bin/bash



MIC0=hw:CARD=PowerConf,DEV=0
SPK0=hw:CARD=NVidia,DEV=3



echo
echo "Looking for MIC0: $MIC0"
until arecord -L | grep "$MIC0" > /dev/null
do
    sleep 1
done
echo "Found MIC0: $MIC0"



echo "Looking for SPK0: $SPK0"
until aplay -L | grep $SPK0 > /dev/null
do
    sleep 1
done
echo "Found SPK0: $SPK0"

Audio Setup:
Bash:
#!/bin/bash



MIC0=hw:CARD=PowerConf,DEV=0
# MIC1=hw:CARD=Receiver_1,DEV=0
# MIC2=hw:CARD=Receiver,DEV=0
SPK0=hw:CARD=NVidia,DEV=3



echo "Use MIC0: $MIC0"
zita-a2j -j MIC0 -d $MIC0 -c 1 -r 16000 &
echo $! >> "$1"
sleep 1

# echo "Additional MIC1: $MIC1"
# if arecord -L | grep "$MIC1" > /dev/null
# then
#     echo "Found!  Using."
#     zita-a2j -j MIC1 -d $MIC1 -c 1 -r 48000 &
#     echo $! >> "$1"
#     sleep 1
# else
#     echo "Not found.  Will be unavailable."
# fi

# echo "Additional MIC2: $MIC2"
# if arecord -L | grep "$MIC2" > /dev/null
# then
#     echo "Found!  Using."
#     zita-a2j -j MIC2 -d $MIC2 -c 2 -r 48000 &
#     echo $! >> "$1"
#     sleep 1
# else
#     echo "Not found.  Will be unavailable."
# fi



echo "Use SPK0: $SPK0"
zita-j2a -j SPK0 -d $SPK0 -c 2 -r 48000 -p 4096 &
echo $! >> "$1"
sleep 1
The commented-out code is from trying to use several different mics scattered around. Never completely got that to work, and it turned out I didn't need them anyway. But I kept it there so you can see the option.

Audio Teardown:
Bash:
#!/bin/bash



echo "Unuse MIC, SPK"
until [[ "$1" = "" ]]
do
    kill -TERM "$1"
    shift
    sleep 1
done
 
Last edited:
Top