Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package cava for openSUSE:Factory checked in at 2024-01-10 21:51:52 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/cava (Old) and /work/SRC/openSUSE:Factory/.cava.new.21961 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "cava" Wed Jan 10 21:51:52 2024 rev:17 rq:1137795 version:0.10.0 Changes: -------- --- /work/SRC/openSUSE:Factory/cava/cava.changes 2023-08-28 17:12:52.443606534 +0200 +++ /work/SRC/openSUSE:Factory/.cava.new.21961/cava.changes 2024-01-10 21:52:14.772074691 +0100 @@ -1,0 +2,8 @@ +Tue Jan 9 19:03:08 UTC 2024 - Michael Vetter <[email protected]> + +- Update to 0.10.0: + * OSS input backend and general improved FreeBSD support + * pipewire default if supported + * noncurses is now default + +------------------------------------------------------------------- Old: ---- 0.9.1.tar.gz New: ---- 0.10.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ cava.spec ++++++ --- /var/tmp/diff_new_pack.ixsvME/_old 2024-01-10 21:52:15.388097062 +0100 +++ /var/tmp/diff_new_pack.ixsvME/_new 2024-01-10 21:52:15.392097207 +0100 @@ -1,7 +1,7 @@ # # spec file for package cava # -# Copyright (c) 2023 SUSE LLC +# Copyright (c) 2024 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: cava -Version: 0.9.1 +Version: 0.10.0 Release: 0 Summary: Console-based Audio Visualizer for Alsa License: MIT ++++++ 0.9.1.tar.gz -> 0.10.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cava-0.9.1/.github/ISSUE_TEMPLATE/bug_report.md new/cava-0.10.0/.github/ISSUE_TEMPLATE/bug_report.md --- old/cava-0.9.1/.github/ISSUE_TEMPLATE/bug_report.md 2023-08-12 17:47:21.000000000 +0200 +++ new/cava-0.10.0/.github/ISSUE_TEMPLATE/bug_report.md 2024-01-09 19:26:04.000000000 +0100 @@ -7,29 +7,42 @@ --- -**When/where was the bug introduced?** -- Are you using cava from a package repository, like AUR? -- If so, check out the master branch here, is your issue already resolved? -- Don't know how to clone, compile source code? File report to package maintainer instead. -- try using git bisect to find out where the bug was introduced. +**READ THIS BEFORE CREATING NEW ISSUE** + +Are you using cava from a package repository, like AUR? + +If so, clone the master branch from here, build and run. Is your issue already resolved? + +Don't know how to clone or compile source code? File report to package maintainer instead! + + **Describe the bug** + A clear and concise description of what the bug is. + **To Reproduce** + Steps to reproduce the behavior: 1. Set config parameter to 2. run 3. do something 4. See error + **Expected behavior** + A clear and concise description of what you expected to happen. + **Screenshots** + If applicable, add screenshots to help explain your problem. + **Desktop (please complete the following information):** + - OS: [e.g. macOS, Ubuntu] - Version [e.g. 22] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cava-0.9.1/CAVACORE.md new/cava-0.10.0/CAVACORE.md --- old/cava-0.9.1/CAVACORE.md 2023-08-12 17:47:21.000000000 +0200 +++ new/cava-0.10.0/CAVACORE.md 2024-01-09 19:26:04.000000000 +0100 @@ -40,6 +40,17 @@ The range of an input signal can vary a lot. cavacore can keep the output signal within range in real-time. This feature can be disabled. +# Building + +use the root CMakeLists.txt to build it: + +``` +mkdir build +cd build +cmake .. +cmake --build . +``` + # Usage -See cavacore.h for documentation and the cavacore_test.c application for how to use. \ No newline at end of file +See cavacore.h for documentation and the cavacore_test.c application for how to use. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cava-0.9.1/CMakeLists.txt new/cava-0.10.0/CMakeLists.txt --- old/cava-0.9.1/CMakeLists.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/cava-0.10.0/CMakeLists.txt 2024-01-09 19:26:04.000000000 +0100 @@ -0,0 +1,6 @@ +# This is only for the cavacore lib, see CAVACORE.md for details +# to build cava don't use this, use the automake stuff + +cmake_minimum_required(VERSION 3.13.0) +project(cavacore) +add_library(cavacore STATIC cavacore.c) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cava-0.9.1/Makefile.am new/cava-0.10.0/Makefile.am --- old/cava-0.9.1/Makefile.am 2023-08-12 17:47:21.000000000 +0200 +++ new/cava-0.10.0/Makefile.am 2024-01-09 19:26:04.000000000 +0100 @@ -7,7 +7,7 @@ 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 \ - -DFONTDIR=\"@FONT_DIR@\" + -DFONTDIR=\"@FONT_DIR@\" -DFONTFILE=\"@FONT_FILE@\" cava_CFLAGS = -std=c99 -Wall -Wextra -Wno-unused-result -Wno-unknown-warning-option -Wno-maybe-uninitialized -Wno-vla-parameter if OSX @@ -16,7 +16,17 @@ else cava_LDADD = -lrt cava_font_dir = @FONT_DIR@ - cava_font__DATA = cava.psf + cava_font__DATA = @FONT_FILE@ +endif + +if FREEBSD +if CAVAFONT + CLEANFILES = cava.bdf cava.fnt + +cava.fnt: ${srcdir}/cava.psf + ${PSF2BDF} --fontname="-gnu-cava-medium-r-normal--16-160-75-75-c-80-iso10646-1" ${srcdir}/cava.psf cava.bdf + ${VTFONTCVT} -o cava.fnt cava.bdf +endif endif if ALSA @@ -39,6 +49,10 @@ cava_SOURCES += input/sndio.c endif +if OSS + cava_SOURCES += input/oss.c +endif + if NCURSES cava_SOURCES += output/terminal_ncurses.c endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cava-0.9.1/README.md new/cava-0.10.0/README.md --- old/cava-0.9.1/README.md 2023-08-12 17:47:21.000000000 +0200 +++ new/cava-0.10.0/README.md 2024-01-09 19:26:04.000000000 +0100 @@ -5,6 +5,8 @@ by [Karl Stavestrand](mailto:[email protected]) +<a href='https://play.google.com/store/apps/details?id=com.karlstav.cava&pcampaignid=pcampaignidMKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Get it on Google Play' src='https://play.google.com/intl/en_us/badges/static/images/badges/en_badge_web_generic.png' width="200"/></a> +  [Demo video](https://youtu.be/9PSp8VA6yjU) @@ -19,6 +21,7 @@ - [ALSA](#alsa) - [MPD](#mpd) - [sndio](#sndio) + - [OSS](#oss) - [squeezelite](#squeezelite) - [macOS](#macos-1) - [Windows](#windows) @@ -85,6 +88,10 @@ All the requirements can be installed easily in all major distros: +FreeBSD + + pkg install autoconf-archive autotools fftw3 iniparser pkgconf psftools sdl2 sndio + Debian/Ubuntu: sudo apt install build-essential libfftw3-dev libasound2-dev libncursesw5-dev libpulse-dev libtool automake autoconf-archive libiniparser-dev libsdl2-2.0-0 libsdl2-dev libpipewire-0.3-dev pkgconf @@ -180,6 +187,10 @@ All distro specific instalation sources might be out of date. Please check version before reporting any issues here. +#### FreeBSD + + pkg install cava + #### openSUSE Tumbleweed users have cava in their repo. They can just use: @@ -273,7 +284,7 @@ Playing the audio through your Loopback interface makes it possible for cava to capture it, but there will be no sound in your speakers. In order to play audio on the loopback interface and your actual interface you must make use of the ALSA multi channel. -Look at the included example file `example_files/etc/asound.conf` on how to use the multi channel. I was able to make this work on my laptop (an Asus UX31 running Ubuntu), but I had no luck with the ALSA method on my Raspberry Pi (Rasbian) with an USB DAC. The PulseAudio method however works perfectly on my Pi. +Look at the included example file `example_files/etc/asound.conf` on how to use the multi channel. I was able to make this work with a HDA Intel PCH sound card, but I had no luck with the an USB DAC. Read more about the ALSA method [here](http://stackoverflow.com/questions/12984089/capture-playback-on-play-only-sound-card-with-alsa). @@ -283,6 +294,12 @@ dtoverlay=i2s-mmap ``` +#### dmix + +@reluekiss, was able to make cava work with dmix. Check out the example config in `example_files/etc/asound_dmix.conf` and issue [534](https://github.com/karlstav/cava/issues/534). + + + ### mpd Add these lines in mpd: @@ -321,6 +338,72 @@ $ AUDIODEVICE=snd/0.monitor cava ``` +### OSS + +The audio system used on FreeBSD is the Open Sound System (OSS). +The following example demonstrates how to setup CAVA for OSS on FreeBSD: + +```sh +$ cat /dev/sndstat +Installed devices: +pcm0: <Realtek ALC1220 (Rear Analog)> (play/rec) default +pcm1: <Realtek ALC1220 (Front Analog Mic)> (rec) +pcm2: <USB audio> (play/rec) +No devices installed from userspace. +``` + +The system has three `pcm` sound devices, `pcm0`, `pcm1` and `pcm2`. `pcm0` corresponds to the analog +output jack on the rear, in which external stereo speakers are plugged in, and the analog input jack, +in which one could plug in a microphone. Because it encapsulates both, output and input, it is marked +as `play/rec`. It is also set as the `default` sound device. `pcm1` corresponds to another analog input +jack for a mic on the front side and is marked `rec`. A USB headset which an integrated mic is plugged +in an USB port and the system has created the `pcm2` sound device with `play/rec` capabilities for +it. + +In general for every `pcmX` device there is a corresponding `/dev/dspX` audio device. In this example +there are `/dev/dsp0`, `/dev/dsp1` and `/dev/dsp2` (the system creates them when needed, they are not +listet via `ls /dev` if they are currently not in use). The system also creates an implicit `/dev/dsp`, +which acts like a symlink to the `default` audio device, in this example to `/dev/dsp0`. + +Now in order to visualize the mic input in CAVA, the `source` value in the configuration file must +be set to the corresponding audio device, i.e. +```sh +[input] +source = /dev/dsp # or /dev/dsp0 for which /dev/dsp is a symlink in this example +``` +(which is already the default for CAVA) for the `pcm0` mic on the rear, or +```sh +[input] +source = /dev/dsp1 +``` +for the `pcm1` mic on the front, or +```sh +[input] +source = /dev/dsp2 +``` +for the `pcm2` mic on the USB headset. + +OSS can't record the outgoing audio on its own, i.e. the sounds from a music player or a browser which +play on the external stereo speakers through `/dev/dsp0` are not visualized in CAVA. A solution is +to use Virtual OSS. It can create virtual audio devices from existing audio devices and from which +the played back audio can be fed into CAVA: +```sh +$ doas pkg install virtual_oss +$ doas virtual_oss -Q0 -C2 -c2 -r48000 -b16 -s2048 -P /dev/dsp0 -R /dev/null -w vdsp.wav -t vdsp.ctl -T /dev/sndstat -l dsp + +$ cat /dev/sndstat +Installed devices: +pcm0: <Realtek ALC1220 (Rear Analog)> (play/rec) default +pcm1: <Realtek ALC1220 (Front Analog Mic)> (rec) +pcm2: <USB audio> (play/rec) +Installed devices from userspace: +dsp: <Virtual OSS> (play/rec) +``` +It created a virtual device `dsp` from `/dev/dsp0`. Now the audio is visualized in CAVA with the default +`source = /dev/dsp` in the configuration file. Virtual OSS can be configured and started as a service +on FreeBSD. + + ### squeezelite [squeezelite](https://en.wikipedia.org/wiki/Squeezelite) is one of several software clients available for the Logitech Media Server. Squeezelite can export its audio data as shared memory, which is what this input module uses. Just adapt your [config](#configuration): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cava-0.9.1/autogen.sh new/cava-0.10.0/autogen.sh --- old/cava-0.9.1/autogen.sh 2023-08-12 17:47:21.000000000 +0200 +++ new/cava-0.10.0/autogen.sh 2024-01-09 19:26:04.000000000 +0100 @@ -3,7 +3,7 @@ if [ -d .git ]; then git describe --always --tags --dirty > version # get version from git else - echo 0.9.1 > version # hard coded versions + echo 0.10.0 > version # hard coded versions fi libtoolize diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cava-0.9.1/cava.c new/cava-0.10.0/cava.c --- old/cava-0.9.1/cava.c 2023-08-12 17:47:21.000000000 +0200 +++ new/cava-0.10.0/cava.c 2024-01-09 19:26:04.000000000 +0100 @@ -70,6 +70,7 @@ #include "input/alsa.h" #include "input/fifo.h" +#include "input/oss.h" #include "input/pipewire.h" #include "input/portaudio.h" #include "input/pulse.h" @@ -290,7 +291,7 @@ output_mode = p.output; #ifndef _MSC_VER - if (output_mode != OUTPUT_RAW && output_mode != OUTPUT_NORITAKE) { + if (output_mode == OUTPUT_NCURSES || output_mode == OUTPUT_NONCURSES) { // Check if we're running in a tty if (strncmp(ttyname(0), "/dev/tty", 8) == 0 || strcmp(ttyname(0), "/dev/console") == 0) inAtty = 1; @@ -299,17 +300,30 @@ if (strncmp(ttyname(0), "/dev/ttys", 9) == 0) inAtty = 0; if (inAtty) { +#ifdef CAVAFONT // checking if cava psf font is installed in FONTDIR FILE *font_file; - font_file = fopen(FONTDIR "/cava.psf", "r"); + font_file = fopen(FONTDIR "/" FONTFILE, "r"); if (font_file) { fclose(font_file); - system("setfont " FONTDIR "/cava.psf >/dev/null 2>&1"); +#ifdef __FreeBSD__ + system("vidcontrol -f " FONTDIR "/" FONTFILE " >/dev/null 2>&1"); +#else + system("setfont " FONTDIR "/" FONTFILE " >/dev/null 2>&1"); +#endif } else { // if not it might still be available, we dont know, must try - system("setfont cava.psf >/dev/null 2>&1"); +#ifdef __FreeBSD__ + system("vidcontrol -f " FONTFILE " >/dev/null 2>&1"); +#else + system("setfont " FONTFILE " >/dev/null 2>&1"); +#endif } - system("setterm -blank 0"); +#endif // CAVAFONT +#ifndef __FreeBSD__ + if (p.disable_blanking) + system("setterm -blank 0"); +#endif } // We use unicode block characters to draw the bars and @@ -347,6 +361,7 @@ audio.cava_in = (double *)malloc(audio.cava_buffer_size * sizeof(double)); memset(audio.cava_in, 0, sizeof(int) * audio.cava_buffer_size); + audio.threadparams = 0; // most input threads don't adjust the parameters audio.terminate = 0; debug("starting audio thread\n"); @@ -382,8 +397,8 @@ #endif case INPUT_FIFO: - audio.rate = p.fifoSample; - audio.format = p.fifoSampleBits; + audio.rate = p.samplerate; + audio.format = p.samplebits; thr_id = pthread_create(&p_thread, NULL, input_fifo, (void *)&audio); break; #ifdef PULSE @@ -403,6 +418,14 @@ thr_id = pthread_create(&p_thread, NULL, input_sndio, (void *)&audio); break; #endif +#ifdef OSS + case INPUT_OSS: + audio.format = p.samplebits; + audio.rate = p.samplerate; + audio.threadparams = 1; // OSS can adjust parameters + thr_id = pthread_create(&p_thread, NULL, input_oss, (void *)&audio); + break; +#endif case INPUT_SHMEM: audio.format = 16; thr_id = pthread_create(&p_thread, NULL, input_shmem, (void *)&audio); @@ -416,8 +439,8 @@ #endif #ifdef PIPEWIRE case INPUT_PIPEWIRE: - audio.format = 16; - audio.rate = 44100; + audio.format = p.samplebits; + audio.rate = p.samplerate; thr_id = pthread_create(&p_thread, NULL, input_pipewire, (void *)&audio); break; #endif @@ -439,7 +462,7 @@ nanosleep(&timeout_timer, NULL); #endif pthread_mutex_lock(&audio.lock); - if (audio.format != -1 && audio.rate != 0) + if ((audio.threadparams == 0) && (audio.format != -1) && (audio.rate != 0)) break; pthread_mutex_unlock(&audio.lock); @@ -483,15 +506,15 @@ #ifdef SDL // output: start sdl mode if (output_mode == OUTPUT_SDL) { - init_sdl_window(p.sdl_width, p.sdl_height, p.sdl_x, p.sdl_y); + init_sdl_window(p.sdl_width, p.sdl_height, p.sdl_x, p.sdl_y, p.sdl_full_screen); height = p.sdl_height; width = p.sdl_width; } #endif #ifdef SDL_GLSL if (output_mode == OUTPUT_SDL_GLSL) { - init_sdl_glsl_window(p.sdl_width, p.sdl_height, p.sdl_x, p.sdl_y, p.vertex_shader, - p.fragment_shader); + init_sdl_glsl_window(p.sdl_width, p.sdl_height, p.sdl_x, p.sdl_y, p.sdl_full_screen, + p.vertex_shader, p.fragment_shader); height = p.sdl_height; width = p.sdl_width; } @@ -766,11 +789,11 @@ if (output_mode == OUTPUT_NCURSES) ch = getch(); #endif - /* - // disabled key controls in non-curses mode, caused garbage on screen + +#ifndef _MSC_VER if (output_mode == OUTPUT_NONCURSES) - ch = fgetc(stdin); - */ + read(0, &ch, sizeof(ch)); +#endif switch (ch) { case 65: // key up @@ -814,6 +837,8 @@ should_quit = 1; } + ch = 0; + if (should_reload) { reloadConf = true; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cava-0.9.1/cava_win/README.md new/cava-0.10.0/cava_win/README.md --- old/cava-0.9.1/cava_win/README.md 2023-08-12 17:47:21.000000000 +0200 +++ new/cava-0.10.0/cava_win/README.md 2024-01-09 19:26:04.000000000 +0100 @@ -1,11 +1,11 @@ # cava on windows -All dependencies should install themselves via the nuget thing: +All dependencies should install themselves via the NuGet thing: * SDL2 * FFTW * pthreads * glew -include paths are configure relativly to the project so linking and inlcuding should work autmatically with the nugets, but might stop workiong at some point. +include paths are configured relatively to the project so linking and including should work automatically with the nugets, but might stop working at some point. The Visual C++ Redistributable for Visual Studio 2012 (maybe also a newer one) was needed when I first ran it. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cava-0.9.1/cavacore.c new/cava-0.10.0/cavacore.c --- old/cava-0.9.1/cavacore.c 2023-08-12 17:47:21.000000000 +0200 +++ new/cava-0.10.0/cavacore.c 2024-01-09 19:26:04.000000000 +0100 @@ -494,12 +494,6 @@ cava_out[n] = p->cava_mem[n] * p->noise_reduction + cava_out[n]; p->cava_mem[n] = cava_out[n]; if (p->autosens) { - double diff = 1 - cava_out[n]; - if (diff < 0) - diff = 0; - double div = 1 / (diff + 1); - p->cava_mem[n] = p->cava_mem[n] * (1 - div / 20); - // check if we overshoot target height if (cava_out[n] > 1.0) { overshoot = 1; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cava-0.9.1/cavacore_test.c new/cava-0.10.0/cavacore_test.c --- old/cava-0.9.1/cavacore_test.c 2023-08-12 17:47:21.000000000 +0200 +++ new/cava-0.10.0/cavacore_test.c 2024-01-09 19:26:04.000000000 +0100 @@ -1,6 +1,6 @@ -// cavacore standalone test app, build cava first and compile with: +// cavacore standalone test app, build cavacore lib first and compile with: // gcc -c -g cavacore_test.c -// gcc -o cavacore_test cavacore_test.o cava-cavacore.o -lm -lfftw3 +// gcc -o cavacore_test cavacore_test.o build/libcavacore.a -lm -lfftw3 #include "cavacore.h" #include <math.h> @@ -20,8 +20,8 @@ double noise_reduction = 0.77; int low_cut_off = 50; int high_cut_off = 10000; - double blueprint_2000MHz[10] = {0, 0, 0, 0, 0, 0, 0.494, 0.449, 0, 0}; - double blueprint_200MHz[10] = {0, 0, 0.939, 0.008, 0, 0.001, 0, 0, 0, 0}; + double blueprint_2000MHz[10] = {0, 0, 0, 0, 0, 0, 0.493, 0.446, 0, 0}; + double blueprint_200MHz[10] = {0, 0, 0.978, 0.008, 0, 0.001, 0, 0, 0, 0}; printf("planning visualization with %d bars per channel, %d rate, %d channels, autosens, " "%.2f noise reduction, %d - %d MHz bandwith.\n", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cava-0.9.1/config.c new/cava-0.10.0/config.c --- old/cava-0.9.1/config.c 2023-08-12 17:47:21.000000000 +0200 +++ new/cava-0.10.0/config.c 2024-01-09 19:26:04.000000000 +0100 @@ -45,19 +45,20 @@ 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_PULSE, + INPUT_PIPEWIRE, INPUT_WINSCAP, INPUT_SNDIO, 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", "oss", "shmem", "winscap", }; 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_OSS, HAS_SHMEM, HAS_WINSCAP, }; enum input_method input_method_by_name(const char *str) { @@ -129,6 +130,15 @@ } if (p->gradient) { + if (p->gradient_count < 2) { + write_errorf(error, "\nAtleast two colors must be given as gradient!\n"); + return false; + } + if (p->gradient_count > 8) { + write_errorf(error, "\nMaximum 8 colors can be specified as gradient!\n"); + return false; + } + for (int i = 0; i < p->gradient_count; i++) { if (!validate_color(p->gradient_colors[i], p, error)) { write_errorf( @@ -182,17 +192,6 @@ if (p->bcolor[0] == '#') p->bgcol = 8; // default if invalid - if (p->gradient) { - - if (p->gradient_count < 2) { - write_errorf(error, "\nAtleast two colors must be given as gradient!\n"); - return false; - } - if (p->gradient_count > 8) { - write_errorf(error, "\nMaximum 8 colors can be specified as gradient!\n"); - return false; - } - } return true; } @@ -220,7 +219,7 @@ if (strcmp(outputMethod, "sdl_glsl") == 0) { p->output = OUTPUT_SDL_GLSL; #ifndef SDL_GLSL - write_errorf(error, "cava was built without sdl support, install sdl dev files " + write_errorf(error, "cava was built without opengl support, install opengl dev files " "and run make clean && ./configure && make again\n"); return false; #endif @@ -384,6 +383,10 @@ } // setting sens + if (p->sens < 1) { + write_errorf(error, "Sensitivity needs to be at least 1%%\n"); + return false; + } p->sens = p->sens / 100; return validate_colors(p, error); @@ -576,12 +579,7 @@ } #ifndef _MSC_VER -#ifdef NCURSES - outputMethod = strdup(iniparser_getstring(ini, "output:method", "ncurses")); -#endif -#ifndef NCURSES outputMethod = strdup(iniparser_getstring(ini, "output:method", "noncurses")); -#endif orientation = strdup(iniparser_getstring(ini, "output:orientation", "bottom")); xaxisScale = strdup(iniparser_getstring(ini, "output:xaxis", "none")); @@ -635,6 +633,7 @@ p->sdl_height = iniparser_getint(ini, "output:sdl_height", 500); p->sdl_x = iniparser_getint(ini, "output:sdl_x", -1); p->sdl_y = iniparser_getint(ini, "output:sdl_y", -1); + p->sdl_full_screen = iniparser_getint(ini, "output:sdl_full_screen", 0); if (strcmp(outputMethod, "sdl") == 0 || strcmp(outputMethod, "sdl_glsl") == 0) { free(p->color); @@ -647,6 +646,8 @@ p->continuous_rendering = iniparser_getint(ini, "output:continuous_rendering", 0); + p->disable_blanking = iniparser_getint(ini, "output:disable_blanking", 0); + p->sync_updates = iniparser_getint(ini, "output:alacritty_sync", 0); vertexShader = strdup(iniparser_getstring(ini, "output:vertex_shader", "pass_through.vert")); @@ -674,6 +675,9 @@ free(p->audio_source); + p->samplerate = iniparser_getint(ini, "input:sample_rate", 44100); + p->samplebits = iniparser_getint(ini, "input:sample_bits", 16); + enum input_method default_input = INPUT_FIFO; for (size_t i = 0; i < ARRAY_SIZE(default_methods); i++) { enum input_method method = default_methods[i]; @@ -692,8 +696,6 @@ #endif case INPUT_FIFO: p->audio_source = strdup(iniparser_getstring(ini, "input:source", "/tmp/mpd.fifo")); - p->fifoSample = iniparser_getint(ini, "input:sample_rate", 44100); - p->fifoSampleBits = iniparser_getint(ini, "input:sample_bits", 16); break; #ifdef PULSE case INPUT_PULSE: @@ -710,6 +712,11 @@ p->audio_source = strdup(iniparser_getstring(ini, "input:source", SIO_DEVANY)); break; #endif +#ifdef OSS + case INPUT_OSS: + p->audio_source = strdup(iniparser_getstring(ini, "input:source", "/dev/dsp")); + break; +#endif case INPUT_SHMEM: p->audio_source = strdup(iniparser_getstring(ini, "input:source", "/squeezelite-00:00:00:00:00:00")); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cava-0.9.1/config.h new/cava-0.10.0/config.h --- old/cava-0.9.1/config.h 2023-08-12 17:47:21.000000000 +0200 +++ new/cava-0.10.0/config.h 2024-01-09 19:26:04.000000000 +0100 @@ -37,6 +37,12 @@ #define HAS_SNDIO false #endif +#ifdef OSS +#define HAS_OSS true +#else +#define HAS_OSS false +#endif + #ifdef _MSC_VER #define HAS_WINSCAP true #define SDL true @@ -59,6 +65,7 @@ INPUT_ALSA, INPUT_PULSE, INPUT_SNDIO, + INPUT_OSS, INPUT_SHMEM, INPUT_WINSCAP, INPUT_MAX, @@ -97,9 +104,9 @@ enum orientation orientation; int userEQ_keys, userEQ_enabled, col, bgcol, autobars, stereo, raw_format, ascii_range, bit_format, gradient, gradient_count, fixedbars, framerate, bar_width, bar_spacing, - bar_height, autosens, overshoot, waves, fifoSample, fifoSampleBits, sleep_timer, sdl_width, - sdl_height, sdl_x, sdl_y, draw_and_quit, zero_test, non_zero_test, reverse, sync_updates, - continuous_rendering; + bar_height, autosens, overshoot, waves, samplerate, samplebits, sleep_timer, sdl_width, + sdl_height, sdl_x, sdl_y, sdl_full_screen, draw_and_quit, zero_test, non_zero_test, reverse, + sync_updates, continuous_rendering, disable_blanking; }; struct error_s { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cava-0.9.1/configure.ac new/cava-0.10.0/configure.ac --- old/cava-0.9.1/configure.ac 2023-08-12 17:47:21.000000000 +0200 +++ new/cava-0.10.0/configure.ac 2024-01-09 19:26:04.000000000 +0100 @@ -9,6 +9,39 @@ AM_PROG_LIBTOOL +AC_CANONICAL_HOST + +build_linux=no +build_windows=no +build_mac=no +build_freebsd=no + +AC_MSG_NOTICE([Checking OS]) +# Detect the target system +case "${host_os}" in + linux*) + AC_MSG_NOTICE([Linux detected]) + build_linux=yes + ;; + darwin*) + AC_MSG_NOTICE([OSX detected]) + build_mac=yes + ;; + freebsd*) + AC_MSG_NOTICE([FreeBSD detected]) + build_freebsd=yes + ;; + *) + AC_MSG_ERROR(["OS $host_os is not supported"]) + ;; +esac + +# Pass the conditionals to automake +AM_CONDITIONAL([LINUX], [test "$build_linux" = "yes"]) +AM_CONDITIONAL([OSX], [test "$build_mac" = "yes"]) +AM_CONDITIONAL([FREEBSD], [test "$build_freebsd" = "yes"]) + + dnl ############################ dnl checking if debug is enabled dnl ############################ @@ -184,12 +217,38 @@ if [[ $have_sndio = "no" ]] ; then AC_MSG_NOTICE([WARNING: No sndio dev files found building without sndio support]) fi], - [have_portaudio=no] + [have_sndio=no] ) AM_CONDITIONAL([SNDIO], [test "x$have_sndio" = "xyes"]) dnl ###################### +dnl checking for oss dev +dnl ###################### +AC_ARG_ENABLE([input_oss], + AS_HELP_STRING([--disable-input-oss], + [do not include support for input from oss]) +) + +AS_IF([test "x$enable_input_oss" != "xno"], [ + have_oss=no + + if [[ $build_freebsd = "yes" ]] ; then + AC_CHECK_HEADERS(sys/soundcard.h, have_oss=yes, have_oss=no) + if [[ $have_oss = "yes" ]] ; then + CPPFLAGS="$CPPFLAGS -DOSS -D__BSD_VISIBLE" + fi + + if [[ $have_oss = "no" ]] ; then + AC_MSG_NOTICE([WARNING: No oss dev files found building without oss support]) + fi + fi], + [have_oss=no] +) + +AM_CONDITIONAL([OSS], [test "x$have_oss" = "xyes"]) + +dnl ###################### dnl checking for math lib dnl ###################### AC_CHECK_LIB(m, sqrt, have_m=yes, have_m=no) @@ -304,6 +363,39 @@ dnl ###################### +dnl checking for cava font +dnl ###################### +AC_ARG_ENABLE([cava_font], + AS_HELP_STRING([--disable-cava-font], + [do not include support for the console cava font]) +) + +AS_IF([test "x$enable_cava_font" != "xno"], [ + have_cava_font=yes + + if [[ $build_freebsd = "yes" ]] ; then + AC_PATH_PROG(VTFONTCVT, vtfontcvt) + if [[ -z "$VTFONTCVT" ]] ; then + AC_MSG_NOTICE([WARNING: vtfontcvt not found]) + have_cava_font=no + fi + AC_PATH_PROG(PSF2BDF, psf2bdf) + if [[ -z "$PSF2BDF" ]] ; then + AC_MSG_NOTICE([WARNING: psf2bdf not found]) + have_cava_font=no + fi + if [[ $have_cava_font = "no" ]] ; then + AC_MSG_NOTICE([WARNING: Font conversion tool missing. Building without cava font supported!]) + fi + fi], + [have_cava_font=no] +) + +AS_IF([test "x$have_cava_font" = "xyes"], [CPPFLAGS="$CPPFLAGS -DCAVAFONT"], []) +AM_CONDITIONAL([CAVAFONT], [test "x$have_cava_font" = "xyes"]) + + +dnl ###################### dnl checking for iniparser dnl ###################### @@ -326,41 +418,25 @@ dnl ############################ dnl Set font directory dnl ############################ -DEFAULT_FONT_DIR="${datarootdir}/consolefonts" AC_ARG_VAR(FONT_DIR, [Directory where the font will be installed.]) +AC_SUBST([FONT_FILE]) + +AS_IF([test "x$have_cava_font" = "xyes"], [ + if [[ "$build_freebsd" = "yes" ]] ; then + DEFAULT_FONT_DIR="${datarootdir}/cava" + FONT_FILE="cava.fnt" + else + DEFAULT_FONT_DIR="${datarootdir}/consolefonts" + FONT_FILE="cava.psf" + fi], [ + DEFAULT_FONT_DIR= + FONT_FILE=] +) + if test -z "$FONT_DIR" ; then FONT_DIR="$DEFAULT_FONT_DIR" fi -AC_CANONICAL_HOST - -build_linux=no -build_windows=no -build_mac=no - -AC_MSG_NOTICE([Checking OS]) -# Detect the target system -case "${host_os}" in - linux*) - AC_MSG_NOTICE([Linux detected]) - build_linux=yes - ;; - darwin*) - AC_MSG_NOTICE([OSX detected]) - build_mac=yes - ;; - freebsd*) - AC_MSG_NOTICE([FreeBSD detected]) - build_linux=yes - ;; - *) - AC_MSG_ERROR(["OS $host_os is not supported"]) - ;; -esac - -# Pass the conditionals to automake -AM_CONDITIONAL([LINUX], [test "$build_linux" = "yes"]) -AM_CONDITIONAL([OSX], [test "$build_mac" = "yes"]) AC_CONFIG_FILES([Makefile]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cava-0.9.1/example_files/config new/cava-0.10.0/example_files/config --- old/cava-0.9.1/example_files/config 2023-08-12 17:47:21.000000000 +0200 +++ new/cava-0.10.0/example_files/config 2024-01-09 19:26:04.000000000 +0100 @@ -52,8 +52,8 @@ [input] -# Audio capturing method. Possible methods are: 'pulse', 'alsa', 'fifo', 'sndio' or 'shmem' -# Defaults to 'pulse', 'pipewire', 'alsa' or 'fifo', in that order, dependent on what support cava was built with. +# Audio capturing method. Possible methods are: 'fifo', 'portaudio', 'pipewire', 'alsa', 'pulse', 'sndio', 'oss' or 'shmem' +# Defaults to 'oss', 'sndio', 'pipewire', 'pulse', 'alsa', 'portaudio' or 'fifo', in that order, dependent on what support cava was built with. # On Mac it defaults to 'portaudio' or 'fifo' # On windows this is automatic and no input settings are needed. # @@ -63,12 +63,19 @@ # For pulseaudio and pipewire 'source' will be the source. Default: 'auto', which uses the monitor source of the default sink # (all pulseaudio sinks(outputs) have 'monitor' sources(inputs) associated with them). # -# For piepwire 'source' will be the object name or object.serial of the device to capture from. +# For pipewire 'source' will be the object name or object.serial of the device to capture from. # Both input and output devices are supported. # # For alsa 'source' will be the capture device. # For fifo 'source' will be the path to fifo-file. # For shmem 'source' will be /squeezelite-AA:BB:CC:DD:EE:FF where 'AA:BB:CC:DD:EE:FF' will be squeezelite's MAC address +# +# For sndio 'source' will be a monitor sub-device, e.g. 'snd/0.monitor'. Default: 'default', in which case a device +# should be specified with the environment variable AUDIODEVICE, e.g. on the commandline: AUDIODEVICE=snd/0.monitor cava. +# +# For oss 'source' will be the path to a audio device, e.g. '/dev/dsp2'. Default: '/dev/dsp', i.e. the default audio device. +# README.md contains further information on how to setup CAVA for OSS on FreeBSD. +# ; method = pulse ; source = auto @@ -80,8 +87,6 @@ ; method = fifo ; source = /tmp/mpd.fifo -; sample_rate = 44100 -; sample_bits = 16 ; method = shmem ; source = /squeezelite-AA:BB:CC:DD:EE:FF @@ -89,13 +94,32 @@ ; method = portaudio ; source = auto +; method = sndio +; source = default + +; method = oss +; source = /dev/dsp + +# The sample rate and format can be configured for some input methods. Currently +# the following methods support such a configuration: 'fifo', 'pipewire' and 'oss'. +# Other methods ignore these settings. +# +# For 'oss' they are only preferred values, i.e. if the values are not supported +# by the chosen audio device, the device will use other supported values instead. +# Example: 48000 and 32, but the device only supports 44100 and 16, then it will +# use 44100 and 16. +# +; sample_rate = 44100 +; sample_bits = 16 + [output] # Output method. Can be 'ncurses', 'noncurses', 'raw', 'noritake', 'sdl' # or 'sdl_glsl'. -# 'noncurses' uses a custom framebuffer technique and prints only changes -# from frame to frame in the terminal. 'ncurses' is default if supported. +# 'noncurses' (default) uses a buffer and cursor movements to only print +# changes from frame to frame in the terminal. Uses less resources and is less +# prone to tearing (vsync issues) than 'ncurses'. # # 'raw' is an 8 or 16 bit (configurable via the 'bit_format' option) data # stream of the bar heights that can be used to send to other applications. @@ -107,7 +131,7 @@ # 'sdl' uses the Simple DirectMedia Layer to render in a graphical context. # 'sdl_glsl' uses SDL to create an OpenGL context. Write your own shaders or # use one of the predefined ones. -; method = ncurses +; method = noncurses # Orientation of the visualization. Can be 'bottom', 'top', 'left' or 'right'. # Default is 'bottom'. Other orientations are only supported on sdl and ncruses @@ -146,6 +170,7 @@ ; sdl_height = 500 ; sdl_x = -1 ; sdl_y= -1 +; sdl_full_screen = 0 # set label on bars on the x-axis. Can be 'frequency' or 'none'. Default: 'none' # 'frequency' displays the lower cut off frequency of the bar above. @@ -164,6 +189,10 @@ ; for glsl output mode, keep rendering even if no audio ; continuous_rendering = 0 +# disable console blank (screen saver) in tty +# (Not supported on FreeBSD) +; disable_blanking = 0 + [color] # Colors can be one of seven predefined: black, blue, cyan, green, magenta, red, white, yellow. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cava-0.9.1/example_files/etc/asound_dmix.conf new/cava-0.10.0/example_files/etc/asound_dmix.conf --- old/cava-0.9.1/example_files/etc/asound_dmix.conf 1970-01-01 01:00:00.000000000 +0100 +++ new/cava-0.10.0/example_files/etc/asound_dmix.conf 2024-01-09 19:26:04.000000000 +0100 @@ -0,0 +1,90 @@ +pcm.dmixed { + type dmix + ipc_key 1024 + ipc_key_add_uid 0 + slave { + pcm "hw:1,0" #your hardware speaker device + period_time 0 + period_size 1024 + buffer_size 4096 + channels 2 + } + bindings { + 0 0 + 1 1 + } +} + +pcm.dsnooped { + type dsnoop + ipc_key 1025 + slave { + pcm "hw:1,6" #your hardware input device (mic) + period_time 0 + period_size 1024 + buffer_size 4096 + channels 2 + } + bindings { + 0 0 + 1 1 + } +} + +pcm.dmixerloop { + type dmix + ipc_key 2048 + ipc_perm 0666 # allow other users + slave.pcm "hw:Loopback,0,0" + slave { + period_time 0 + period_size 1024 + buffer_size 4096 + channels 2 # must match bindings + } + bindings { + 0 0 + 1 1 + } +} + +pcm.out { + type plug + route_policy "duplicate" + slave.pcm { + type multi + slaves { + a { channels 2 pcm "dmixed" } + b { channels 2 pcm "dmixerloop" } + } + bindings { + 0 { slave a channel 0 } + 1 { slave a channel 1 } + 2 { slave b channel 0 } + 3 { slave b channel 1 } + } + } + ttable [ + [ 1 0 1 0 ] + [ 0 1 0 1 ] + ] +} + +pcm.looprec { + type hw + card "Loopback" + device 1 + subdevice 0 +} + +pcm.!default { + type asym + playback.pcm "out" + #capture.pcm "looprec" + capture.pcm "dsnooped" +} + +ctl.!default { + type hw + card 1 +} \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cava-0.9.1/input/common.h new/cava-0.10.0/input/common.h --- old/cava-0.9.1/input/common.h 2023-08-12 17:47:21.000000000 +0200 +++ new/cava-0.10.0/input/common.h 2024-01-09 19:26:04.000000000 +0100 @@ -24,9 +24,11 @@ int format; unsigned int rate; unsigned int channels; - char *source; // alsa device, fifo path or pulse source - int im; // input mode alsa, fifo, pulse, portaudio, shmem or sndio - int terminate; // shared variable used to terminate audio thread + int threadparams; // shared variable used to prevent main thread from cava_init before input + // threads have finalized parameters + char *source; // alsa device, fifo path or pulse source + int im; // input mode alsa, fifo, pulse, portaudio, shmem or sndio + int terminate; // shared variable used to terminate audio thread char error_message[1024]; int samples_counter; int IEEE_FLOAT; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cava-0.9.1/input/oss.c new/cava-0.10.0/input/oss.c --- old/cava-0.9.1/input/oss.c 1970-01-01 01:00:00.000000000 +0100 +++ new/cava-0.10.0/input/oss.c 2024-01-09 19:26:04.000000000 +0100 @@ -0,0 +1,185 @@ +#include <stdbool.h> +#include <stddef.h> + +#include <sys/ioctl.h> +#include <sys/soundcard.h> + +#include "input/common.h" +#include "input/oss.h" + +static bool set_format(int fd, struct audio_data *audio) { + // CAVA favors signed and little endian (sle) formats. It might actually not work correctly if + // we feed it an unsigned or big endian format. Therefore we prefer to select one of the + // supported sle formats, if any exist. + + // The favored sle formats. 16bit has priority, followed by "bigger is better". + static const int fmts_sle[] = {AFMT_S16_LE, AFMT_S32_LE, AFMT_S24_LE, AFMT_S8}; + + // Bitmasks of formats categorized by bitlength. + static const int fmts_8bits = AFMT_U8 | AFMT_S8; + static const int fmts_16bits = AFMT_S16_LE | AFMT_S16_BE | AFMT_U16_LE | AFMT_U16_BE; + static const int fmts_24bits = AFMT_S24_LE | AFMT_S24_BE | AFMT_U24_LE | AFMT_U24_BE; + static const int fmts_32bits = AFMT_S32_LE | AFMT_S32_BE | AFMT_U32_LE | AFMT_U32_BE; + + int fmts; + int fmt; + + // Get all supported formats from the audio device. + if (ioctl(fd, SNDCTL_DSP_GETFMTS, &fmts) == -1) { + fprintf(stderr, __FILE__ ": ioctl(SNDCTL_DSP_GETFMTS) failed: %s\n", strerror(errno)); + return false; + } + + // Determine the sle format for the requested bitlength. + if (audio->format <= 8) + fmt = AFMT_S8; + else if (audio->format <= 16) + fmt = AFMT_S16_LE; + else if (audio->format <= 24) + fmt = AFMT_S24_LE; + else + fmt = AFMT_S32_LE; + + // If the requested format is not available then test for the other sle formats. + if (!(fmts & fmt)) { + for (size_t i = 0; i < sizeof(fmts_sle) / sizeof(fmts_sle[0]); ++i) { + if (fmts & fmts_sle[i]) { + fmt = fmts_sle[i]; + break; + } + } + } + + // Set the format of the device. If not supported then OSS will adjust to a supported format. + if (ioctl(fd, SNDCTL_DSP_SETFMT, &fmt) == -1) { + fprintf(stderr, __FILE__ ": ioctl(SNDCTL_DSP_SETFMT) failed: %s\n", strerror(errno)); + return false; + } + + // Determine the actual bitlength of the returned format. + if (fmts_8bits & fmt) + audio->format = 8; + else if (fmts_16bits & fmt) + audio->format = 16; + else if (fmts_24bits & fmt) + audio->format = 24; + else if (fmts_32bits & fmt) + audio->format = 32; + else { + fprintf(stderr, __FILE__ ": No support for 8, 16, 24 or 32 bits in OSS source '%s'.\n", + audio->source); + return false; + } + + return true; +} + +static bool set_channels(int fd, struct audio_data *audio) { + // Try to set the requested channels, OSS will adjust to a supported value. If CAVA doesn't + // support the final value then it will complain later. + int channels = audio->channels; + + if (ioctl(fd, SNDCTL_DSP_CHANNELS, &channels) == -1) { + fprintf(stderr, __FILE__ ": ioctl(SNDCTL_DSP_CHANNELS) failed: %s\n", strerror(errno)); + return false; + } + + audio->channels = channels; + + return true; +} + +static bool set_rate(int fd, struct audio_data *audio) { + // Try to set the requested rate, OSS will adjust to a supported value. If CAVA doesn't support + // the final value then it will complain later. + int rate = audio->rate; + + if (ioctl(fd, SNDCTL_DSP_SPEED, &rate) == -1) { + fprintf(stderr, __FILE__ ": ioctl(SNDCTL_DSP_SPEED) failed: %s\n", strerror(errno)); + return false; + } + + audio->rate = rate; + + return true; +} + +static void signal_threadparams(struct audio_data *audio) { + pthread_mutex_lock(&audio->lock); + audio->threadparams = 0; + pthread_mutex_unlock(&audio->lock); +} + +static void signal_terminate(struct audio_data *audio) { + pthread_mutex_lock(&audio->lock); + audio->terminate = 1; + pthread_mutex_unlock(&audio->lock); +} + +void *input_oss(void *data) { + static const int flags = O_RDONLY; + + struct audio_data *audio = (struct audio_data *)data; + int bytes; + size_t buf_size; + ssize_t rd; + + 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; + } + + // For OSS it's adviced to determine format, channels and rate in this order. + if (!(set_format(fd, audio) && set_channels(fd, audio) && set_rate(fd, audio))) + goto cleanup; + + // Parameters finalized. Signal main thread. + signal_threadparams(audio); + + // OSS uses 32 bits for 24bit. + if (audio->format == 24) + bytes = 4; // = 32 / 8 + else + bytes = audio->format / 8; + + buf_size = audio->input_buffer_size * bytes; + + if ((buf = malloc(buf_size)) == NULL) { + fprintf(stderr, __FILE__ ": malloc() failed: %s\n", strerror(errno)); + goto cleanup; + } + + while (audio->terminate != 1) { + if ((rd = read(fd, buf, buf_size)) == -1) { + fprintf(stderr, __FILE__ ": read() failed: %s\n", strerror(errno)); + goto cleanup; + } else if (rd == 0) + signal_terminate(audio); + else + write_to_cava_input_buffers(rd / bytes, buf, audio); + } + + success = true; + +cleanup: + free(buf); + + if ((fd >= 0) && (close(fd) == -1)) { + fprintf(stderr, __FILE__ ": close() failed: %s\n", strerror(errno)); + success = false; + } + + signal_threadparams(audio); + signal_terminate(audio); + + if (!success) + exit(EXIT_FAILURE); + + return NULL; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cava-0.9.1/input/oss.h new/cava-0.10.0/input/oss.h --- old/cava-0.9.1/input/oss.h 1970-01-01 01:00:00.000000000 +0100 +++ new/cava-0.10.0/input/oss.h 2024-01-09 19:26:04.000000000 +0100 @@ -0,0 +1,5 @@ +// header file for oss, part of cava. + +#pragma once + +void *input_oss(void *data); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cava-0.9.1/input/pipewire.c new/cava-0.10.0/input/pipewire.c --- old/cava-0.9.1/input/pipewire.c 2023-08-12 17:47:21.000000000 +0200 +++ new/cava-0.10.0/input/pipewire.c 2024-01-09 19:26:04.000000000 +0100 @@ -1,7 +1,9 @@ #include "input/pipewire.h" #include "input/common.h" +#include <math.h> #include <spa/param/audio/format-utils.h> +#include <spa/param/latency-utils.h> #include <pipewire/pipewire.h> @@ -73,6 +75,8 @@ struct pw_properties *props; struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer)); char **argv; + uint32_t nom; + nom = nearbyint((10000 * data.cava_audio->rate) / 1000000.0); pw_init(0, &argv); @@ -83,13 +87,31 @@ pw_properties_set(props, PW_KEY_TARGET_OBJECT, data.cava_audio->source); pw_properties_set(props, PW_KEY_STREAM_CAPTURE_SINK, "true"); + pw_properties_setf(props, PW_KEY_NODE_LATENCY, "%u/%u", nom, data.cava_audio->rate); data.stream = pw_stream_new_simple(pw_main_loop_get_loop(data.loop), "cava", props, &stream_events, &data); + enum spa_audio_format audio_format = SPA_AUDIO_FORMAT_S16; + + switch (data.cava_audio->format) { + case 8: + audio_format = SPA_AUDIO_FORMAT_S8; + break; + case 16: + audio_format = SPA_AUDIO_FORMAT_S16; + break; + case 24: + audio_format = SPA_AUDIO_FORMAT_S24; + break; + case 32: + audio_format = SPA_AUDIO_FORMAT_S32; + break; + }; + params[0] = spa_format_audio_raw_build( &b, SPA_PARAM_EnumFormat, - &SPA_AUDIO_INFO_RAW_INIT(.format = SPA_AUDIO_FORMAT_S16, .rate = 44100)); + &SPA_AUDIO_INFO_RAW_INIT(.format = audio_format, .rate = data.cava_audio->rate)); pw_stream_connect(data.stream, PW_DIRECTION_INPUT, PW_ID_ANY, PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_MAP_BUFFERS | diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cava-0.9.1/input/sndio.c new/cava-0.10.0/input/sndio.c --- old/cava-0.9.1/input/sndio.c 2023-08-12 17:47:21.000000000 +0200 +++ new/cava-0.10.0/input/sndio.c 2024-01-09 19:26:04.000000000 +0100 @@ -15,7 +15,7 @@ par.le = 1; par.rate = audio->rate; ; - par.rchan = 2; + par.rchan = audio->channels; par.appbufsz = sizeof(buf) / par.rchan; if ((hdl = sio_open(audio->source, SIO_REC, 0)) == NULL) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cava-0.9.1/output/sdl_cava.c new/cava-0.10.0/output/sdl_cava.c --- old/cava-0.9.1/output/sdl_cava.c 2023-08-12 17:47:21.000000000 +0200 +++ new/cava-0.10.0/output/sdl_cava.c 2024-01-09 19:26:04.000000000 +0100 @@ -35,7 +35,7 @@ } } -void init_sdl_window(int width, int height, int x, int y) { +void init_sdl_window(int width, int height, int x, int y, int full_screen) { if (x == -1) x = SDL_WINDOWPOS_UNDEFINED; @@ -45,8 +45,12 @@ if (SDL_Init(SDL_INIT_VIDEO) < 0) { printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError()); } else { - gWindow = - SDL_CreateWindow("cava", x, y, width, height, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE); + Uint32 sdl_flags = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE; + + if (full_screen == 1) + sdl_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; + + gWindow = SDL_CreateWindow("cava", x, y, width, height, sdl_flags); if (gWindow == NULL) { printf("Window could not be created! SDL_Error: %s\n", SDL_GetError()); } else { @@ -185,6 +189,10 @@ free(gradient_colors_sdl); } } + if (e.type == SDL_KEYDOWN) { + if (e.key.keysym.sym == SDLK_q || e.key.keysym.sym == SDLK_ESCAPE) + rc = -2; + } if (e.type == SDL_QUIT) rc = -2; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cava-0.9.1/output/sdl_cava.h new/cava-0.10.0/output/sdl_cava.h --- old/cava-0.9.1/output/sdl_cava.h 2023-08-12 17:47:21.000000000 +0200 +++ new/cava-0.10.0/output/sdl_cava.h 2024-01-09 19:26:04.000000000 +0100 @@ -1,6 +1,6 @@ #include "../config.h" -void init_sdl_window(int width, int height, int x, int y); +void init_sdl_window(int width, int height, int x, int y, int full_screen); void init_sdl_surface(int *width, int *height, char *const fg_color_string, char *const bg_color_string, int gradient, int gradient_count, char **gradient_color_strings); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cava-0.9.1/output/sdl_glsl.c new/cava-0.10.0/output/sdl_glsl.c --- old/cava-0.9.1/output/sdl_glsl.c 2023-08-12 17:47:21.000000000 +0200 +++ new/cava-0.10.0/output/sdl_glsl.c 2024-01-09 19:26:04.000000000 +0100 @@ -41,8 +41,8 @@ GLuint compile_shader(GLenum type, const char **); GLuint program_check(GLuint); -void init_sdl_glsl_window(int width, int height, int x, int y, char *const vertex_shader, - char *const fragmnet_shader) { +void init_sdl_glsl_window(int width, int height, int x, int y, int full_screen, + char *const vertex_shader, char *const fragmnet_shader) { if (x == -1) x = SDL_WINDOWPOS_UNDEFINED; @@ -60,8 +60,12 @@ SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); #endif - glWindow = SDL_CreateWindow("cava", x, y, width, height, - SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); + Uint32 sdl_flags = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE; + + if (full_screen == 1) + sdl_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; + + glWindow = SDL_CreateWindow("cava", x, y, width, height, sdl_flags); if (glWindow == NULL) { fprintf(stderr, "Window could not be created! SDL_Error: %s\n", SDL_GetError()); exit(1); @@ -213,6 +217,10 @@ glViewport(0, 0, event.window.data1, event.window.data2); rc = -1; } + if (event.type == SDL_KEYDOWN) { + if (event.key.keysym.sym == SDLK_q || event.key.keysym.sym == SDLK_ESCAPE) + rc = -2; + } if (event.type == SDL_QUIT) rc = -2; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cava-0.9.1/output/sdl_glsl.h new/cava-0.10.0/output/sdl_glsl.h --- old/cava-0.9.1/output/sdl_glsl.h 2023-08-12 17:47:21.000000000 +0200 +++ new/cava-0.10.0/output/sdl_glsl.h 2024-01-09 19:26:04.000000000 +0100 @@ -1,7 +1,7 @@ #include "../config.h" -void init_sdl_glsl_window(int width, int height, int x, int y, char *const vertex_shader, - char *const fragment_shader); +void init_sdl_glsl_window(int width, int height, int x, int y, int full_screen, + char *const vertex_shader, char *const fragment_shader); void init_sdl_glsl_surface(int *width, int *height, char *const fg_color_string, char *const bg_color_string, int bar_width, int bar_spacing, int gradient, int gradient_count, char **gradient_color_strings); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cava-0.9.1/output/terminal_bcircle.c new/cava-0.10.0/output/terminal_bcircle.c --- old/cava-0.9.1/output/terminal_bcircle.c 2023-08-12 17:47:21.000000000 +0200 +++ new/cava-0.10.0/output/terminal_bcircle.c 2024-01-09 19:26:04.000000000 +0100 @@ -77,9 +77,13 @@ // general: cleanup void cleanup_terminal_bcircle(void) { echo(); +#ifdef __FreeBSD__ + system("vidcontrol -f >/dev/null 2>&1"); +#else system("setfont >/dev/null 2>&1"); system("setfont /usr/share/consolefonts/Lat2-Fixed16.psf.gz >/dev/null 2>&1"); system("setterm -blank 10"); +#endif endwin(); system("clear"); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cava-0.9.1/output/terminal_ncurses.c new/cava-0.10.0/output/terminal_ncurses.c --- old/cava-0.9.1/output/terminal_ncurses.c 2023-08-12 17:47:21.000000000 +0200 +++ new/cava-0.10.0/output/terminal_ncurses.c 2024-01-09 19:26:04.000000000 +0100 @@ -311,9 +311,13 @@ // general: cleanup void cleanup_terminal_ncurses(void) { echo(); +#ifdef __FreeBSD__ + system("vidcontrol -f >/dev/null 2>&1"); +#else system("setfont >/dev/null 2>&1"); system("setfont /usr/share/consolefonts/Lat2-Fixed16.psf.gz >/dev/null 2>&1"); - system("setterm -blank 10 >/dev/null 2>&1"); +#endif + /*for(int i = 0; i < gradient_size; ++i) { if(the_color_redefinitions[i].color) { init_color(the_color_redefinitions[i].color, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cava-0.9.1/output/terminal_noncurses.c new/cava-0.10.0/output/terminal_noncurses.c --- old/cava-0.9.1/output/terminal_noncurses.c 2023-08-12 17:47:21.000000000 +0200 +++ new/cava-0.10.0/output/terminal_noncurses.c 2024-01-09 19:26:04.000000000 +0100 @@ -42,10 +42,15 @@ if (tcgetattr(fd, &t) == -1) return -1; - if (onoff == 0) + if (onoff == 0) { t.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL | ICANON); - else + t.c_cc[VTIME] = 0; + t.c_cc[VMIN] = 0; + } else { t.c_lflag |= (ECHO | ECHOE | ECHOK | ECHONL | ICANON); + t.c_cc[VTIME] = 0; + t.c_cc[VMIN] = 1; + } if (tcsetattr(fd, TCSANOW, &t) == -1) return -1; @@ -153,8 +158,9 @@ system("cls"); #else +#ifndef __FreeBSD__ system("setterm -cursor off"); - system("setterm -blank 0"); +#endif system("clear"); #endif @@ -414,10 +420,13 @@ system("cls"); #else setecho(STDIN_FILENO, 1); +#ifdef __FreeBSD__ + system("vidcontrol -f >/dev/null 2>&1"); +#else system("setfont >/dev/null 2>&1"); system("setfont /usr/share/consolefonts/Lat2-Fixed16.psf.gz >/dev/null 2>&1"); system("setterm -cursor on"); - system("setterm -blank 10"); +#endif system("clear"); #endif printf("\033[0m\n");
