Solved Santa Claus presents: OSS support for audio/cava ... and JACK too?!

Merry Xmas dear FreeBSD community!

A few days ago in the profile posts the user rsronin asked if anyone had success with audio/cava displaying these delicious visualization bars. audio/cava supports almost every important audio backend out there, e.g., alsa, pulseaudio, pipewire, sndio. It can definitly work with sndio or pulseaudio on FreeBSD. BUT what about our beloved almighty superior OSS? It can't be so difficult to add OSS support to audio/cava. Yeah, "Talk is cheap. Show me the code.", so here we go:

I used a 13.2-RELEASE chroot(8) as my build environment. So prepare the build environment anyway you like, i.e. chroot, jail or directly on your host system. I assume we are on / of the build environment and network is up. We are going to compile the latest released version of cava manually from source, because the port is still on a version from over two years ago. Fetch the sourcecode:
Code:
fetch -o - https://github.com/karlstav/cava/archive/refs/tags/0.9.1.tar.gz | tar -xf -
Install the build dependencies (no external audio library needed, har har har, begone pulseaudio!):
Code:
pkg install autotools fftw3 iniparser pkgconf
Go to the sourcecode and autogen it:
Code:
cd /cava-0.9.1
./autogen.sh
Apply the following diffs to make cava ready of the one and only OSS:
Diff:
--- ../cava-0.9.1-orig/Makefile.am    2023-08-12 17:47:21.000000000 +0200
+++ Makefile.am    2023-12-23 01:24:21.247610000 +0100
@@ -3,10 +3,10 @@
 ACLOCAL_AMFLAGS = -I m4

 bin_PROGRAMS = cava
-cava_SOURCES = cava.c cavacore.c config.c input/common.c input/fifo.c input/shmem.c \
+cava_SOURCES = cava.c cavacore.c config.c input/common.c input/fifo.c input/shmem.c input/oss.c \
                output/terminal_noncurses.c output/raw.c output/noritake.c
 cava_CPPFLAGS = -DPACKAGE=\"$(PACKAGE)\" -DVERSION=\"$(VERSION)\" \
-           -D_POSIX_SOURCE -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE_EXTENDED \
+           -D_POSIX_SOURCE -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE_EXTENDED -D__BSD_VISIBLE \
        -DFONTDIR=\"@FONT_DIR@\"
 cava_CFLAGS = -std=c99 -Wall -Wextra -Wno-unused-result -Wno-unknown-warning-option -Wno-maybe-uninitialized -Wno-vla-parameter
Diff:
--- ../cava-0.9.1-orig/cava.c    2023-08-12 17:47:21.000000000 +0200
+++ cava.c    2023-12-23 00:59:35.228339000 +0100
@@ -75,6 +75,7 @@
 #include "input/pulse.h"
 #include "input/shmem.h"
 #include "input/sndio.h"
+#include "input/oss.h"
 #endif

 #ifdef __GNUC__
@@ -407,6 +408,11 @@
             audio.format = 16;
             thr_id = pthread_create(&p_thread, NULL, input_shmem, (void *)&audio);
             break;
+        case INPUT_OSS:
+            audio.format = 16;
+            audio.rate = 44100;
+            thr_id = pthread_create(&p_thread, NULL, input_oss, (void *)&audio);
+            break;
 #ifdef PORTAUDIO
         case INPUT_PORTAUDIO:
             audio.format = 16;
Diff:
--- ../cava-0.9.1-orig/config.c    2023-08-12 17:47:21.000000000 +0200
+++ config.c    2023-12-23 10:30:13.145505000 +0100
@@ -45,19 +45,19 @@
 double smoothDef[5] = {1, 1, 1, 1, 1};

 enum input_method default_methods[] = {
-    INPUT_FIFO, INPUT_PORTAUDIO, INPUT_ALSA, INPUT_PIPEWIRE, INPUT_PULSE, INPUT_WINSCAP,
+    INPUT_FIFO, INPUT_PORTAUDIO, INPUT_ALSA, INPUT_PIPEWIRE, INPUT_PULSE, INPUT_WINSCAP, INPUT_OSS,
 };

 char *outputMethod, *orientation, *channels, *xaxisScale, *monoOption, *fragmentShader,
     *vertexShader;

 const char *input_method_names[] = {
-    "fifo", "portaudio", "pipewire", "alsa", "pulse", "sndio", "shmem", "winscap",
+    "fifo", "portaudio", "pipewire", "alsa", "pulse", "sndio", "shmem", "winscap", "oss",
 };

 const bool has_input_method[] = {
     HAS_FIFO, /** Always have at least FIFO and shmem input. */
-    HAS_PORTAUDIO, HAS_PIPEWIRE, HAS_ALSA, HAS_PULSE, HAS_SNDIO, HAS_SHMEM, HAS_WINSCAP,
+    HAS_PORTAUDIO, HAS_PIPEWIRE, HAS_ALSA, HAS_PULSE, HAS_SNDIO, HAS_SHMEM, HAS_WINSCAP, HAS_OSS,
 };

 enum input_method input_method_by_name(const char *str) {
@@ -695,6 +695,9 @@
         p->fifoSample = iniparser_getint(ini, "input:sample_rate", 44100);
         p->fifoSampleBits = iniparser_getint(ini, "input:sample_bits", 16);
         break;
+    case INPUT_OSS:
+        p->audio_source = strdup(iniparser_getstring(ini, "input:source", "/dev/dsp"));
+        break;
 #ifdef PULSE
     case INPUT_PULSE:
         p->audio_source = strdup(iniparser_getstring(ini, "input:source", "auto"));
Diff:
--- ../cava-0.9.1-orig/config.h    2023-08-12 17:47:21.000000000 +0200
+++ config.h    2023-12-23 00:49:44.108221000 +0100
@@ -42,11 +42,13 @@
 #define SDL true
 #define HAS_FIFO false
 #define HAS_SHMEM false
+#define HAS_OSS false
 #define PATH_MAX 260
 #else
 #define HAS_WINSCAP false
 #define HAS_FIFO true
 #define HAS_SHMEM true
+#define HAS_OSS true

 #endif

@@ -61,6 +63,7 @@
     INPUT_SNDIO,
     INPUT_SHMEM,
     INPUT_WINSCAP,
+    INPUT_OSS,
     INPUT_MAX,
 };
The real juice is still missing. We need input/oss.h
C:
// header file for oss, part of cava.

#pragma once

void *input_oss(void *data);
and input/oss.c
C:
#include <stdbool.h>

#include <sys/ioctl.h>
#include <sys/soundcard.h>

#include "input/common.h"
#include "input/oss.h"

void* input_oss(void* data) {
    static const int flags = O_RDONLY;

    struct audio_data* audio = (struct audio_data*)data;
    int fmt = AFMT_S16_LE;
    int channels = 2;
    int speed = 44100;
    int buf_size = audio->input_buffer_size * 2 * 2;

    int fd = -1;
    void* buf = NULL;

    bool success = false;

    if ((fd = open(audio->source, flags, 0)) == -1) {
        fprintf(stderr, __FILE__ ": Could not open oss source '%s': %s\n", audio->source, strerror(errno));
        goto cleanup;
    }

    if (ioctl(fd, SNDCTL_DSP_SETFMT, &fmt) == -1)
        fprintf(stderr, __FILE__ ": ioctl(SNDCTL_DSP_SETFMT) failed: %s\n", strerror(errno));

    if (ioctl(fd, SNDCTL_DSP_CHANNELS, &channels) == -1)
        fprintf(stderr, __FILE__ ": ioctl(SNDCTL_DSP_CHANNELS) failed: %s\n", strerror(errno));

    if (ioctl(fd, SNDCTL_DSP_SPEED, &speed) == -1)
        fprintf(stderr, __FILE__ ": ioctl(SNDCTL_DSP_SPEED) failed: %s\n", strerror(errno));

    if ((buf = malloc(buf_size)) == NULL) {
        fprintf(stderr, __FILE__ ": malloc() failed: %s\n", strerror(errno));
        goto cleanup;
    }

    while (audio->terminate != 1) {
        if (read(fd, buf, buf_size) == -1) {
            fprintf(stderr, __FILE__ ": read() failed: %s\n", strerror(errno));
            goto cleanup;
        }

        write_to_cava_input_buffers(audio->input_buffer_size, buf, audio);
    }

    success = true;

cleanup:
    free(buf);

    if ((fd >= 0) && (close(fd) == -1)) {
        fprintf(stderr, __FILE__ ": close() failed: %s\n", strerror(errno));
        success = false;
    }

    if (!success)
        exit(EXIT_FAILURE);

    return NULL;
}
 
Last edited:
We are almost there! Now compile it:
Code:
CFLAGS="-I/usr/local/include" \
LDFLAGS="-L/usr/local/lib" \
./configure \
    --prefix=/opt/cava \
    --disable-input-alsa \
    --disable-input-pipewire \
    --disable-input-pulse \
    --disable-input-portaudio \
    --disable-input-sndio \
    --disable-output-sdl \
    --disable-output-sdl-glsl
make
make install
Congrats! Now put a method = oss under the input section of ~/.config/cava/config. If a different dsp than /dev/dsp is needed, e.g., /dev/dsp1, add source = /dev/dsp1 to the same section.

Of course input/oss.c is just a first draft. It's my first adventure into the wonderful world of audio and OSS programming. I'm 95% sure that my buf_size is not what I think it is (magic numbers begone!) and that the relation between channels, format, buf and the internal cava buffer is not right in this implementation. And the cava sourcecode doesn't give me much confidence that channels, the format, etc. are actually supposed to be any different than 2, 44100 and 16bit.

My cava bars are dancing to my OSS desktop sounds much to my satisfaction. This is the way.
 
I tried to follow your directions but was not able to compile:


amw@Z440 ~/g/cava-0.9.1> ./autogen.sh
libtoolize: Consider adding 'AC_CONFIG_MACRO_DIRS([m4])' to configure.ac,
libtoolize: and rerunning libtoolize and aclocal.
/usr/local/share/aclocal/libxosd.m4:9: warning: underquoted definition of AM_PATH_LIBXOSD
/usr/local/share/aclocal/libxosd.m4:9: run info Automake 'Extending aclocal'
/usr/local/share/aclocal/libxosd.m4:9: or see https://www.gnu.org/software/automake/manual/automake.ht
ml#Extending-aclocal
configure.ac:7: warning: m4_warn([obsolete],
configure.ac:7: [AC_PROG_CC_STDC is obsolete; use AC_PROG_CC
configure.ac:7: ])dnl
configure.ac:7: AC_REQUIRE(AC_PROG_CC) is obsolete; use AC_PROG_CC
configure.ac:13: warning: ac_ext=c
configure.ac:13: ac_cpp='$CPP $CPPFLAGS'
configure.ac:13: ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
configure.ac:13: ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&
5'
configure.ac:13: ac_compiler_gnu=$ac_cv_c_compiler_gnu
configure.ac:13: if test -n "$ac_tool_prefix"; then
configure.ac:13: # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with
args.
configure.ac:13: set dummy ${ac_tool_prefix}gcc; ac_word=$2
configure.ac:13: { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
configure.ac:13: printf %s "checking for $ac_word... " >&6; }
configure.ac:13: if test ${ac_cv_prog_CC+y}
configure.ac:13: then :
configure.ac:13: printf %s "(cached) " >&6
configure.ac:13: else $as_nop
configure.ac:13: if test -n "$CC"; then
configure.ac:13: ac_cv_prog_CC="$CC" # Let the user override the test.
configure.ac:13: else
configure.ac:13: as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
configure.ac:13: for as_dir in $PATH
configure.ac:13: do
configure.ac:13: IFS=$as_save_IFS
configure.ac:13: case $as_dir in #(((
configure.ac:13: '' is m4_require'd but not m4_defun'd
lib/m4sugar/m4sh.m4:692: _AS_IF_ELSE is expanded from...
lib/m4sugar/m4sh.m4:699: AS_IF is expanded from...
./lib/autoconf/general.m4:2249: AC_CACHE_VAL is expanded from...
./lib/autoconf/programs.m4:41: _AC_CHECK_PROG is expanded from...
./lib/autoconf/programs.m4:101: AC_CHECK_PROG is expanded from...
./lib/autoconf/programs.m4:221: AC_CHECK_TOOL is expanded from...
./lib/autoconf/c.m4:452: AC_PROG_CC is expanded from...
configure.ac:13: the top level



amw@Z440 ~/g/cava-0.9.1> CFLAGS="-I/usr/local/include" \
LDFLAGS="-L/usr/local/lib" \
./configure \
--prefix=/opt/cava \
--disable-input-alsa \
--disable-input-pipewire \
--disable-input-pulse \
--disable-input-portaudio \
--disable-input-sndio \
--disable-output-sdl \
--disable-output-sdl-glsl
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a race-free mkdir -p... /usr/local/bin/gmkdir -p
checking for gawk... no
checking for mawk... no
checking for nawk... nawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking whether make supports the include directive... yes (GNU style)
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether the compiler supports GNU C... yes
checking whether gcc accepts -g... yes
checking for gcc option to enable C11 features... none needed
checking whether gcc understands -c and -o together... yes
checking dependency style of gcc... gcc3
checking for ar... ar
checking the archiver (ar) interface... ar
checking build system type... amd64-unknown-freebsd14.0
checking host system type... amd64-unknown-freebsd14.0
checking how to print strings... printf
checking for a sed that does not truncate output... /usr/bin/sed
checking for grep that handles long lines and -e... /usr/bin/grep
checking for egrep... /usr/bin/grep -E
checking for fgrep... /usr/bin/grep -F
checking for ld used by gcc... /usr/local/bin/ld
checking if the linker (/usr/local/bin/ld) is GNU ld... yes
checking for BSD- or MS-compatible name lister (nm)... /usr/local/bin/nm -B
checking the name lister (/usr/local/bin/nm -B) interface... BSD nm
checking whether ln -s works... yes
checking the maximum length of command line arguments... 393216
checking how to convert amd64-unknown-freebsd14.0 file names to amd64-unknown-freebsd14.0 format... func
_convert_file_noop
checking how to convert amd64-unknown-freebsd14.0 file names to toolchain format... func_convert_file_no
op
checking for /usr/local/bin/ld option to reload object files... -r
checking for file... file
checking for objdump... objdump
checking how to recognize dependent libraries... pass_all
checking for dlltool... no
checking how to associate runtime and link libraries... printf %s\n
checking for archiver @FILE support... no
checking for strip... strip
checking for ranlib... ranlib
checking command to parse /usr/local/bin/nm -B output from gcc object... ok
checking for sysroot... no
checking for a working dd... /bin/dd
checking how to truncate binary pipes... /bin/dd bs=4096 count=1
checking for mt... mt
checking if mt is a manifest tool... no
checking for stdio.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for strings.h... yes
checking for sys/stat.h... yes
checking for sys/types.h... yes
checking for unistd.h... yes
checking for dlfcn.h... yes
checking for objdir... .libs
checking if gcc supports -fno-rtti -fno-exceptions... no
checking for gcc option to produce PIC... -fPIC -DPIC
checking if gcc PIC flag -fPIC -DPIC works... yes
checking if gcc static flag -static works... yes
checking if gcc supports -c -o file.o... yes
checking if gcc supports -c -o file.o... (cached) yes
checking whether the gcc linker (/usr/local/bin/ld) supports shared libraries... yes
checking whether -lc should be explicitly linked in... no
checking dynamic linker characteristics... freebsd14.0 ld.so
checking how to hardcode library paths into programs... immediate
checking whether stripping libraries is possible... yes
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... yes
checking whether to build static libraries... yes
checking for gcc... (cached) gcc
checking whether the compiler supports GNU C... (cached) yes
checking whether gcc accepts -g... (cached) yes
checking for gcc option to enable C11 features... (cached) none needed
checking whether gcc understands -c and -o together... (cached) yes
checking dependency style of gcc... (cached) gcc3
./configure: 13745: Syntax error: word unexpected (expecting ")")
 
I tried to follow your directions but was not able to compile:
You are missing the build dependency pkgconf. Do pkg install pkgconf. That should work. If I omit pkgconf I get the same error as you.

I am currently working on refining the OSS support. The ultimate plan is to upstream OSS support to cava and update our FreeBSD port, so everyone can enjoy the one true OSS experience with cava on FreeBSD without compiling it manually.
 
Ok, I see that you are building on 14.0 and are compiling with gcc, atleast ./configure picks gcc up as its C compiler. Are you building in a clean build environment? I am still on 13.2 and used an unpacked base.txz as a chroot(8), updated to the latest patchlevel with freebsd-update(8).

Can you please post the content of your configure around the offending line 13745 ?
 

checking for gcc... (cached) gcc
checking whether the compiler supports GNU C... (cached) yes
checking whether gcc accepts -g... (cached) yes
checking for gcc option to enable C11 features... (cached) none needed
checking whether gcc understands -c and -o together... (cached) yes
checking dependency style of gcc... (cached) gcc3
./configure: 13745: Syntax error: word unexpected (expecting ")")


More in the spoiler of a earlier post.
 
Sorry, I meant the content of the file ~/g/cava-0.9.1/configure at line 13745 and little bit around it.
 
Code:
for as_dir in $PATH
do
  IFS=$as_save_IFS
  case $as_dir in #(((
    ''
 as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
    ac_cv_prog_CC="${ac_tool_prefix}gcc"
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
 
Ok, unfortunatly I have no further clue... There is a possibility that there's a problem with building on 14.0, but I cannot test that myself, because I'm still on 13.2 and I am currently building cava only in a 13.2 chroot build environment. Because your configure seems to pick up gcc as C compiler, I think you are not building in a true clean environment. It should pick up cc, which is clang from base in a clean environment. What does cc -v say?

I think the problem is somewhere inside this whole autotools mess. But I can't provide a solution right now. Sorry. Have to wait till I'm done with the actual OSS work for cava and I'm gonna tackle the port.
 

amw@Z440 ~> cc -v
FreeBSD clang version 16.0.6 (https://github.com/llvm/llvm-project.git llvmorg-16.0.6-0-g7cbf1a259152)
Target: x86_64-unknown-freebsd14.0
Thread model: posix
InstalledDir: /usr/bin
amw@Z440 ~>

amw@Z440 ~/g/cava-0.9.1> lsa configure*
-rwxr-xr-x 1 amw amw 516K Dec 26 15:03 configure
-rw-r--r-- 1 amw amw 9.9K Dec 26 15:03 configure.ac
-rw-r--r-- 1 amw amw 9.9K Dec 26 15:03 configure.ac~
-rwxr-xr-x 1 amw amw 491K Dec 26 14:24 configure~
amw@Z440 ~/g/cava-0.9.1>
 
Hmmm.... spooky. I would retry the whole building process with a new cava-0.9.1 copy, because I have no idea what kind of black magic is going on. Maybe leftovers from previous bulid artifacts.
 
I am almost done. The OSS backend is finished. I am currently checking the FreeBSD port patches for audio/cava and try to incorporate them for upstreaming to cava.

In the meantime look at this awesomeness! cava using the OSS input backend and the SDL GLSL shader output backend. Now I want to write custom shaders for cava. Another rabithole...

shot.png
 
Hi steps,

I mentioned earlier that I was able to get it working using an obscure configure~ file. I removed the git download and fetched cava again, patched the files and compiled. The compiling finished but /dev/dsp and /dev/dspX.Y where not recognized by the freshly compiled cava, so no bars again. I know that in FreeBSD 14 mixer has been rewritten.


amw@Z440 /dev> lsa dsp*
crw-rw-rw- 1 root wheel 0xec Dec 27 11:23 dsp0.0
crw-rw-rw- 1 root wheel 0xee Dec 27 11:23 dsp1.0
crw-rw-rw- 1 root wheel 0xf0 Dec 27 11:23 dsp2.0
crw-rw-rw- 1 root wheel 0xf2 Dec 27 11:23 dsp3.0
crw-rw-rw- 1 root wheel 0xf4 Dec 27 11:23 dsp4.0
crw-rw-rw- 1 root wheel 0xf6 Dec 27 11:23 dsp5.0
crw-rw-rw- 1 root wheel 0xfd Dec 27 20:27 dsp5.1
amw@Z440 /dev>


Anyway I was also struggling with sndio before and the correct syntax for the device names...
 
Are you sure you are executing your new cava executable /path/to/new/cava and not /usr/local/bin/cava from the installed package? This happend to me more than two times in the last few days ;).

If that's not the case: Did you see an error message (input/oss.c : Could not open oss source '/dev/dspX': ...)? What does your cat /dev/sndstat say? And are you running virtual_oss(8)? You know that you can't record from a dsp device with plain OSS if that device is not a "nativ" input device? That's why I'm running virtual_oss(8) as you can see in my screenshot above.

Code:
virtual_oss -Q0 -C2 -C2 -r48000 -b16 -s2048 -P /dev/dspX -R /dev/null -w vdsp.wav -l dsp -T /dev/sndstat -t vdsp.ctl

(-s2048 might not be right for you, a buffer too large can introduce noticabe latency. But it's ok for testing.)
 
Are you sure you are executing your new cava executable /path/to/new/cava and not /usr/local/bin/cava from the installed package? This happend to me more than two times in the last few days ;).

If that's not the case: Did you see an error message (input/oss.c : Could not open oss source '/dev/dspX': ...)? What does your cat /dev/sndstat say? And are you running virtual_oss(8)? You know that you can't record from a dsp device with plain OSS if that device is not a "nativ" input device? That's why I'm running virtual_oss(8) like you can see in my screenshot above.

Code:
virtual_oss -Q2 -C2 -C2 -r48000 -b16 -s2048 -P /dev/dspX -R /dev/null -w vdsp.wav -l dsp -T /dev/sndstat -t vdsp.ctl

(-s2048 might not be right for you, a buffer too large can introduce noticabe latency. But it's ok for testing.)
I was sure to run cava from /opt/cava/bin/cava and I am not using virtual_oss(8) mainly due to lack of understanding.

Yes I saw input/oss.c : Could not open oss source '/dev/dspX': ...

My cat /dev/sndstat

amw@Z440 ~> cat /dev/sndstat
Installed devices:
pcm0: <NVIDIA (0x0084) (HDMI/DP 8ch)> (play)
pcm1: <NVIDIA (0x0084) (HDMI/DP 8ch)> (play)
pcm2: <NVIDIA (0x0084) (HDMI/DP 8ch)> (play)
pcm3: <NVIDIA (0x0084) (HDMI/DP 8ch)> (play)
pcm4: <Realtek ALC221 (Analog)> (play/rec)
pcm5: <Realtek ALC221 (Analog 2.0+HP)> (play) default
No devices installed from userspace.
amw@Z440 ~>


Hope it helps!
 
Yes, you need to run virtual_oss(8) in order to be able to record your "desktop sound" with OSS. Don't worry, I also don't understand virtual_oss in many (all?) aspects.

According to your /dev/sndstat, you would run
Code:
virtual_oss -Q0 -C2 -C2 -r48000 -b16 -s2048 -P /dev/dsp5 -R /dev/null -w vdsp.wav -l dsp -T /dev/sndstat -t vdsp.ctl
Then restart cava and your sound application and then it should work(TM).
 
So this "recorded sound" is used as an input for cava?
Yes.
Code:
SYNOPSIS
     virtual_oss [-h]

DESCRIPTION
     virtual_oss is an audio mixing application that multiplexes and
     demultiplexes a single OSS device into multiple customizable OSS
     compatible devices using character devices from userspace. These devices
     can be used to record played back audio and mix the individual channels
     in multiple ways.

That's for "recording" your "desktop audio" and feed it into cava. If you wanted to visualize your voice from your mic (pcm4 according to your /dev/sndstat), then you would not need virtual_oss(8), because it's a "native" input device. source = /dev/dsp4 in ~/.config/cava/config would be enough.
 
amw@Z440 ~> doas service virtual_oss onestart 1
Starting Virtual OSS config dsp ...hw.snd.basename_clone: 0 -> 0
done
amw@Z440 ~>virtual_oss -Q0 -C2 -C2 -r48000 -b16 -s2048 -P /dev/dsp5 -R /dev/null -w vdsp.wav -l dsp -T /dev/sndstat -t vdsp.ctl
virtual_oss: Could not connect to cuse module

amw@Z440 ~> kldstat 64
Id Refs Address Size Name
1 104 0xffffffff80200000 1d345d8 kernel
2 1 0xffffffff81f35000 6cd8 uplcom.ko
3 2 0xffffffff81f3c000 a088 ucom.ko
4 1 0xffffffff81f47000 5d5958 zfs.ko
5 1 0xffffffff8251e000 a2f8 ng_ubt.ko
6 3 0xffffffff82529000 13f40 ng_hci.ko
7 3 0xffffffff8253d000 4318 ng_bluetooth.ko
8 4 0xffffffff82542000 16cf0 netgraph.ko
9 1 0xffffffff82559000 7718 cryptodev.ko
10 1 0xffffffff82561000 1a098 if_rtwn_usb.ko
11 2 0xffffffff8257c000 260d8 rtwn.ko
12 1 0xffffffff83563000 3558 fdescfs.ko
13 1 0xffffffff83567000 73c0 linprocfs.ko
14 6 0xffffffff8356f000 be70 linux_common.ko
15 1 0xffffffff8357b000 440c linsysfs.ko
16 1 0xffffffff83580000 11e630 nvidia-modeset.ko
17 1 0xffffffff83800000 33a5358 nvidia.ko
18 2 0xffffffff8369f000 31a10 linux.ko
19 1 0xffffffff836d1000 3390 acpi_wmi.ko
20 1 0xffffffff836d5000 3250 ichsmb.ko
21 1 0xffffffff836d9000 2178 smbus.ko
22 1 0xffffffff836dc000 2dc30 linux64.ko
23 1 0xffffffff8370a000 2278 pty.ko
24 1 0xffffffff8370d000 3360 uhid.ko
25 1 0xffffffff83711000 4364 ums.ko
26 1 0xffffffff83716000 33c0 usbhid.ko
27 1 0xffffffff8371a000 3380 hidbus.ko
28 1 0xffffffff8371e000 5bd8 autofs.ko
29 1 0xffffffff83724000 2a68 mac_ntpd.ko
30 1 0xffffffff83727000 6760 cuse.ko

amw@Z440 ~> cat /dev/sndstat
Installed devices:
pcm0: <NVIDIA (0x0084) (HDMI/DP 8ch)> (play)
pcm1: <NVIDIA (0x0084) (HDMI/DP 8ch)> (play)
pcm2: <NVIDIA (0x0084) (HDMI/DP 8ch)> (play)
pcm3: <NVIDIA (0x0084) (HDMI/DP 8ch)> (play)
pcm4: <Realtek ALC221 (Analog)> (play/rec)
pcm5: <Realtek ALC221 (Analog 2.0+HP)> (play) default
Installed devices from userspace:
dsp: <Virtual OSS> (play/rec)
amw@Z440 ~>


amw@Z440 /dev> lsa dsp*
crw-rw-rw- 1 root wheel 0x102 Dec 28 00:00 dsp
crw-rw-rw- 1 root wheel 0x103 Dec 28 00:00 dsp.ctl
crw-rw-rw- 1 root wheel 0xec Dec 27 11:23 dsp0.0
crw-rw-rw- 1 root wheel 0xc2 Dec 27 23:45 dsp0.1
crw-rw-rw- 1 root wheel 0xee Dec 27 11:23 dsp1.0
crw-rw-rw- 1 root wheel 0xf0 Dec 27 11:23 dsp2.0
crw-rw-rw- 1 root wheel 0xf2 Dec 27 11:23 dsp3.0
crw-rw-rw- 1 root wheel 0xc0 Dec 27 23:51 dsp3.1
crw-rw-rw- 1 root wheel 0xf4 Dec 27 11:23 dsp4.0
crw-rw-rw- 1 root wheel 0xf6 Dec 27 11:23 dsp5.0
crw-rw-rw- 1 root wheel 0xfd Dec 27 20:27 dsp5.1
crw-rw-rw- 1 root wheel 0xfe Dec 27 22:07 dsp5.2
crw-rw-rw- 1 root wheel 0xff Dec 27 23:14 dsp5.3
crw-rw-rw- 1 root wheel 0xbb Dec 27 23:52 dsp5.4
crw-rw-rw- 1 root wheel 0xc3 Dec 27 23:46 dsp5.5
crw-rw-rw- 1 root wheel 0x100 Dec 27 23:48 dsp5.6
amw@Z440 /dev>
 
Stop the service. You can enable it and configure it through /etc/rc.conf after we have tested. For now, only run the command virtual_oss -Q0 -C2 -C2 -r48000 -b16 -s2048 -P /dev/dsp5 -R /dev/null -w vdsp.wav -l dsp -T /dev/sndstat -t vdsp.ctl.

(The error is: you are trying to run virtual_oss while it's already running as a service)
 
I rebooted and entered the following commands...

amw@Z440 ~> cat /etc/rc.conf | grep cuse
kld_list="${kld_list} cuse"
amw@Z440 ~> cat /dev/sndstat
Installed devices:
pcm0: <NVIDIA (0x0084) (HDMI/DP 8ch)> (play)
pcm1: <NVIDIA (0x0084) (HDMI/DP 8ch)> (play)
pcm2: <NVIDIA (0x0084) (HDMI/DP 8ch)> (play)
pcm3: <NVIDIA (0x0084) (HDMI/DP 8ch)> (play)
pcm4: <Realtek ALC221 (Analog)> (play/rec)
pcm5: <Realtek ALC221 (Analog 2.0+HP)> (play) default
No devices installed from userspace.
amw@Z440 ~> pgrep virtual
amw@Z440 ~> kldstat | grep cuse 1
19 1 0xffffffff836d1000 6760 cuse.ko
amw@Z440 ~> virtual_oss -Q0 -C2 -C2 -r48000 -b16 -s2048 -P /dev/dsp5 -R /dev/null -w vdsp.wav -l dsp -T /dev/sndstat -t vdsp.ctl
virtual_oss: Could not connect to cuse module
amw@Z440 ~>


Let's call it a day.
 
Back
Top