File cava-headers.patch of Package waybar
diff -ruN Waybar-0.14.0.orig/include/modules/cava.hpp Waybar-0.14.0/include/modules/cava.hpp
--- Waybar-0.14.0.orig/include/modules/cava.hpp 2025-08-19 12:29:36.607882863 +0800
+++ Waybar-0.14.0/include/modules/cava.hpp 2025-08-19 15:50:27.718412454 +0800
@@ -10,7 +10,66 @@
#define SDL_GLSL
#endif
-#include <cava/common.h>
+#include <cava/cavacore.h>
+#include <cava/config.h>
+#include <cava/input/common.h>
+
+struct audio_data_ext {
+ double *cava_in;
+
+ int input_buffer_size;
+ int cava_buffer_size;
+
+ int format;
+ unsigned int rate;
+ unsigned int channels;
+ int threadparams; // shared variable used to prevent main thread from cava_init before input
+ // threads have finalized parameters (0=allow cava_init, 1=disallow)
+ 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; // format for 32bit (0=int, 1=float)
+ int autoconnect; // auto connect to audio source (0=off, 1=once at startup, 2=regularly)
+ pthread_mutex_t lock;
+ pthread_cond_t resumeCond;
+ bool suspendFlag;
+};
+
+struct audio_raw {
+ int *bars;
+ int *previous_frame;
+ float *bars_left;
+ float *bars_right;
+ float *bars_raw;
+ float *previous_bars_raw;
+ double *cava_out;
+ int *dimension_bar;
+ int *dimension_value;
+ double userEQ_keys_to_bars_ratio;
+ int channels;
+ int number_of_bars;
+ int output_channels;
+ int height;
+ int lines;
+ int width;
+ int remainder;
+};
+
+int audio_raw_init(struct audio_data_ext *audio, struct audio_raw *audio_raw, struct config_params *prm,
+ struct cava_plan *plan);
+
+int audio_raw_fetch(struct audio_raw *audio_raw, struct config_params *prm, int *re_paint,
+ struct cava_plan *plan);
+
+int audio_raw_clean(struct audio_raw *audio_raw);
+int audio_raw_destroy(struct audio_raw *audio_raw);
+enum input_method input_method_by_name(const char *str);
+
+
+typedef void *(*ptr)(void *);
+ptr get_input(struct audio_data_ext *audio, struct config_params *prm);
#ifdef SDL_GLSL
#undef SDL_GLSL
@@ -33,9 +92,9 @@
util::SleeperThread thread_fetch_input_;
struct cava::error_s error_{}; // cava errors
- struct cava::config_params prm_{}; // cava parameters
- struct cava::audio_raw audio_raw_{}; // cava handled raw audio data(is based on audio_data)
- struct cava::audio_data audio_data_{}; // cava audio data
+ struct cava::config_params prm_{};
+ struct cava::audio_raw audio_raw_{}; // cava handled raw audio data(is based on audio_data_ext)
+ struct cava::audio_data_ext audio_data_ext_{}; // cava audio data
struct cava::cava_plan* plan_; //{new cava_plan{}};
// Cava API to read audio source
cava::ptr input_source_;
diff -ruN Waybar-0.14.0.orig/src/modules/cava.cpp Waybar-0.14.0/src/modules/cava.cpp
--- Waybar-0.14.0.orig/src/modules/cava.cpp 2025-08-19 12:29:36.638883295 +0800
+++ Waybar-0.14.0/src/modules/cava.cpp 2025-08-19 16:16:42.579629738 +0800
@@ -1,6 +1,547 @@
#include "modules/cava.hpp"
#include <spdlog/spdlog.h>
+#include "cava/debug.h"
+#include "cava/util.h"
+#include <math.h>
+#include <sys/stat.h>
+
+float *monstercat_filter(float *bars, int number_of_bars, int waves, double monstercat,
+ int height) {
+ int z;
+
+ // process [smoothing]: monstercat-style "average"
+ int m_y, de;
+ float height_normalizer = 1.0;
+ if (height > 1000) {
+ height_normalizer = height / 912.76;
+ }
+ if (waves > 0) {
+ for (z = 0; z < number_of_bars; z++) { // waves
+ bars[z] = bars[z] / 1.25;
+ // if (bars[z] < 1) bars[z] = 1;
+ for (m_y = z - 1; m_y >= 0; m_y--) {
+ de = z - m_y;
+ bars[m_y] = max(bars[z] - height_normalizer * pow(de, 2), bars[m_y]);
+ }
+ for (m_y = z + 1; m_y < number_of_bars; m_y++) {
+ de = m_y - z;
+ bars[m_y] = max(bars[z] - height_normalizer * pow(de, 2), bars[m_y]);
+ }
+ }
+ } else if (monstercat > 0) {
+ for (z = 0; z < number_of_bars; z++) {
+ // if (bars[z] < 1)bars[z] = 1;
+ for (m_y = z - 1; m_y >= 0; m_y--) {
+ de = z - m_y;
+ bars[m_y] = max(bars[z] / pow(monstercat * 1.5, de), bars[m_y]);
+ }
+ for (m_y = z + 1; m_y < number_of_bars; m_y++) {
+ de = m_y - z;
+ bars[m_y] = max(bars[z] / pow(monstercat * 1.5, de), bars[m_y]);
+ }
+ }
+ }
+
+ return bars;
+}
+
+int audio_raw_init(struct cava::audio_data_ext *audio, struct cava::audio_raw *audio_raw, struct config_params *prm,
+ struct cava_plan *plan) {
+ audio_raw->channels = audio->channels;
+
+ if (prm->upper_cut_off > audio->rate / 2) {
+ cleanup(prm->output);
+ fprintf(stderr,
+ "higher cutoff frequency can't be higher than sample rate / 2\nhigher "
+ "cutoff frequency is set to: %d, got sample rate: %d\n",
+ prm->upper_cut_off, audio->rate);
+ exit(EXIT_FAILURE);
+ }
+
+ if (prm->orientation == ORIENT_LEFT || prm->orientation == ORIENT_RIGHT) {
+ audio_raw->dimension_bar = &audio_raw->height;
+ audio_raw->dimension_value = &audio_raw->width;
+ } else {
+ audio_raw->dimension_bar = &audio_raw->width;
+ audio_raw->dimension_value = &audio_raw->height;
+ }
+
+ // frequencies on x axis require a bar width of four or more
+ if (prm->xaxis == FREQUENCY && prm->bar_width < 4)
+ prm->bar_width = 4;
+
+ switch (prm->output) {
+#ifdef NCURSES
+ // output: start ncurses mode
+ case OUTPUT_NCURSES:
+ init_terminal_ncurses(prm->color, prm->bcolor, prm->col, prm->bgcol, prm->gradient,
+ prm->gradient_count, prm->gradient_colors, &audio_raw->width,
+ &audio_raw->lines);
+ if (prm->xaxis != NONE)
+ audio_raw->lines--;
+ audio_raw->height = audio_raw->lines;
+ *audio_raw->dimension_value *=
+ 8; // we have 8 times as much height due to using 1/8 block characters
+ break;
+#endif
+#ifdef SDL
+ // output: get sdl window size
+ case OUTPUT_SDL:
+ init_sdl_surface(&audio_raw->width, &audio_raw->height, prm->color, prm->bcolor,
+ prm->gradient, prm->gradient_count, prm->gradient_colors);
+ break;
+#endif
+#ifdef SDL_GLSL
+ // output: get sdl window size
+ case OUTPUT_SDL_GLSL:
+ init_sdl_glsl_surface(&audio_raw->width, &audio_raw->height, prm->color, prm->bcolor,
+ prm->bar_width, prm->bar_spacing, prm->gradient, prm->gradient_count,
+ prm->gradient_colors);
+ break;
+#endif
+ case OUTPUT_NONCURSES:
+ get_terminal_dim_noncurses(&audio_raw->width, &audio_raw->lines);
+
+ if (prm->xaxis != NONE)
+ audio_raw->lines--;
+
+ audio_raw->height = audio_raw->lines * 8;
+ break;
+ case OUTPUT_RAW:
+ case OUTPUT_NORITAKE:
+ if (strcmp(prm->raw_target, "/dev/stdout") != 0) {
+#ifndef _WIN32
+ int fptest;
+ // checking if file exists
+ if (access(prm->raw_target, F_OK) != -1) {
+ // file exists, testopening in case it's a fifo
+ fptest = open(prm->raw_target, O_RDONLY | O_NONBLOCK, 0644);
+
+ if (fptest == -1) {
+ fprintf(stderr, "could not open file %s for writing\n", prm->raw_target);
+ exit(1);
+ }
+ } else {
+ printf("creating fifo %s\n", prm->raw_target);
+ if (mkfifo(prm->raw_target, 0664) == -1) {
+ fprintf(stderr, "could not create fifo %s\n", prm->raw_target);
+ exit(1);
+ }
+ // fifo needs to be open for reading in order to write to it
+ fptest = open(prm->raw_target, O_RDONLY | O_NONBLOCK, 0644);
+ }
+ prm->fp = open(prm->raw_target, O_WRONLY | O_NONBLOCK | O_CREAT, 0644);
+#else
+ int pipeLength = strlen("\\\\.\\pipe\\") + strlen(prm->raw_target) + 1;
+ char *pipePath = malloc(pipeLength);
+ pipePath[pipeLength - 1] = '\0';
+ strcat(pipePath, "\\\\.\\pipe\\");
+ strcat(pipePath, prm->raw_target);
+ DWORD pipeMode = strcmp(prm->data_format, "ascii")
+ ? PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE
+ : PIPE_TYPE_BYTE | PIPE_READMODE_BYTE;
+ prm->hFile = CreateNamedPipeA(pipePath, PIPE_ACCESS_OUTBOUND | FILE_FLAG_OVERLAPPED,
+ pipeMode | PIPE_NOWAIT, PIPE_UNLIMITED_INSTANCES, 0, 0,
+ NMPWAIT_USE_DEFAULT_WAIT, NULL);
+ free(pipePath);
+#endif
+ } else {
+#ifndef _WIN32
+ prm->fp = fileno(stdout);
+#else
+ prm->hFile = GetStdHandle(STD_OUTPUT_HANDLE);
+#endif
+ }
+#ifndef _WIN32
+ if (prm->fp == -1) {
+#else
+ if (prm->hFile == INVALID_HANDLE_VALUE) {
+#endif
+ fprintf(stderr, "could not open file %s for writing\n", prm->raw_target);
+ exit(1);
+ }
+
+#ifndef NDEBUG
+ debug("open file %s for writing raw output\n", prm->raw_target);
+#endif
+ // width must be hardcoded for raw output.
+ audio_raw->width = 512;
+
+ prm->bar_width = 1; // not used
+ prm->bar_spacing = 1;
+
+ if (strcmp(prm->data_format, "ascii") != 0) {
+ // "binary" or "noritake"
+ audio_raw->height = pow(2, prm->bit_format) - 1;
+ } else {
+ audio_raw->height = prm->ascii_range;
+ }
+ break;
+ default:
+ exit(EXIT_FAILURE); // Can't happen.
+ }
+
+ // force stereo if only one channel is available
+ if (prm->stereo && audio->channels == 1)
+ prm->stereo = 0;
+
+ // handle for user setting too many bars
+ if (prm->fixedbars) {
+ prm->autobars = 0;
+ if (prm->fixedbars * prm->bar_width + prm->fixedbars * prm->bar_spacing - prm->bar_spacing >
+ audio_raw->width)
+ prm->autobars = 1;
+ }
+
+ // getting numbers of bars
+ audio_raw->number_of_bars = prm->fixedbars;
+
+ if (prm->autobars == 1)
+ audio_raw->number_of_bars =
+ (*audio_raw->dimension_bar + prm->bar_spacing) / (prm->bar_width + prm->bar_spacing);
+
+ if (audio_raw->number_of_bars <= 1) {
+ audio_raw->number_of_bars = 1; // must have at least 1 bars
+ if (prm->stereo) {
+ audio_raw->number_of_bars = 2; // stereo have at least 2 bars
+ }
+ }
+ if (audio_raw->number_of_bars > 512)
+ audio_raw->number_of_bars = 512; // cant have more than 512 bars on 44100 rate
+
+ audio_raw->output_channels = 1;
+ if (prm->stereo) { // stereo must have even numbers of bars
+ audio_raw->output_channels = 2;
+ if (audio_raw->number_of_bars % 2 != 0)
+ audio_raw->number_of_bars--;
+ }
+ // checks if there is stil extra room, will use this to center
+ audio_raw->remainder = (*audio_raw->dimension_bar - audio_raw->number_of_bars * prm->bar_width -
+ audio_raw->number_of_bars * prm->bar_spacing + prm->bar_spacing) /
+ 2;
+ if (audio_raw->remainder < 0)
+ audio_raw->remainder = 0;
+
+ if (prm->output == OUTPUT_NONCURSES) {
+ init_terminal_noncurses(prm->color, prm->bcolor, prm->col, prm->bgcol,
+ prm->gradient, prm->gradient_count, prm->gradient_colors,
+ prm->horizontal_gradient, prm->horizontal_gradient_count,
+ prm->horizontal_gradient_colors, audio_raw->number_of_bars,
+ audio_raw->width, audio_raw->lines, prm->bar_width,
+ prm->orientation, prm->blendDirection);
+ }
+#ifndef NDEBUG
+ debug("height: %d width: %d dimension_bar: %d dimension_value: %d bars:%d bar width: "
+ "%d remainder: %d\n",
+ audio_raw->height, audio_raw->width, *audio_raw->dimension_bar,
+ *audio_raw->dimension_value, audio_raw->number_of_bars, prm->bar_width,
+ audio_raw->remainder);
+#endif
+
+ if (prm->userEQ_enabled && (audio_raw->number_of_bars / audio_raw->output_channels > 0)) {
+ audio_raw->userEQ_keys_to_bars_ratio =
+ (double)(((double)prm->userEQ_keys) /
+ ((double)(audio_raw->number_of_bars / audio_raw->output_channels)));
+ }
+
+ *plan = *cava_init(audio_raw->number_of_bars / audio_raw->output_channels, audio->rate,
+ audio->channels, prm->autosens, prm->noise_reduction, prm->lower_cut_off,
+ prm->upper_cut_off);
+
+ if (plan->status == -1) {
+ cleanup(prm->output);
+ fprintf(stderr, "Error initializing cava . %s", plan->error_message);
+ exit(EXIT_FAILURE);
+ }
+
+ audio_raw->bars_left =
+ (float *)malloc(audio_raw->number_of_bars / audio_raw->output_channels * sizeof(float));
+ audio_raw->bars_right =
+ (float *)malloc(audio_raw->number_of_bars / audio_raw->output_channels * sizeof(float));
+ memset(audio_raw->bars_left, 0,
+ sizeof(float) * audio_raw->number_of_bars / audio_raw->output_channels);
+ memset(audio_raw->bars_right, 0,
+ sizeof(float) * audio_raw->number_of_bars / audio_raw->output_channels);
+
+ audio_raw->bars = (int *)malloc(audio_raw->number_of_bars * sizeof(int));
+ audio_raw->bars_raw = (float *)malloc(audio_raw->number_of_bars * sizeof(float));
+ audio_raw->previous_bars_raw = (float *)malloc(audio_raw->number_of_bars * sizeof(float));
+ audio_raw->previous_frame = (int *)malloc(audio_raw->number_of_bars * sizeof(int));
+ audio_raw->cava_out = (double *)malloc(audio_raw->number_of_bars * audio->channels /
+ audio_raw->output_channels * sizeof(double));
+
+ memset(audio_raw->bars, 0, sizeof(int) * audio_raw->number_of_bars);
+ memset(audio_raw->bars_raw, 0, sizeof(float) * audio_raw->number_of_bars);
+ memset(audio_raw->previous_bars_raw, 0, sizeof(float) * audio_raw->number_of_bars);
+ memset(audio_raw->previous_frame, 0, sizeof(int) * audio_raw->number_of_bars);
+ memset(audio_raw->cava_out, 0,
+ sizeof(double) * audio_raw->number_of_bars * audio->channels /
+ audio_raw->output_channels);
+
+ // process: calculate x axis values
+ prm->x_axis_info = 0;
+
+ if (prm->xaxis != NONE) {
+ prm->x_axis_info = 1;
+ double cut_off_frequency;
+ if (prm->output == OUTPUT_NONCURSES) {
+ printf("\r\033[%dB", audio_raw->lines + 1);
+ if (audio_raw->remainder)
+ printf("\033[%dC", audio_raw->remainder);
+ }
+ for (int n = 0; n < audio_raw->number_of_bars; n++) {
+ if (prm->stereo) {
+ if (n < audio_raw->number_of_bars / 2)
+ cut_off_frequency =
+ plan->cut_off_frequency[audio_raw->number_of_bars / 2 - 1 - n];
+ else
+ cut_off_frequency = plan->cut_off_frequency[n - audio_raw->number_of_bars / 2];
+ } else {
+ cut_off_frequency = plan->cut_off_frequency[n];
+ }
+
+ float freq_kilohz = cut_off_frequency / 1000;
+ int freq_floor = cut_off_frequency;
+
+ if (prm->output == OUTPUT_NCURSES) {
+#ifdef NCURSES
+ if (cut_off_frequency < 1000)
+ mvprintw(audio_raw->lines,
+ n * (prm->bar_width + prm->bar_spacing) + audio_raw->remainder, "%-4d",
+ freq_floor);
+ else if (cut_off_frequency > 1000 && cut_off_frequency < 10000)
+ mvprintw(audio_raw->lines,
+ n * (prm->bar_width + prm->bar_spacing) + audio_raw->remainder, "%.2f",
+ freq_kilohz);
+ else
+ mvprintw(audio_raw->lines,
+ n * (prm->bar_width + prm->bar_spacing) + audio_raw->remainder, "%.1f",
+ freq_kilohz);
+#endif
+ } else if (prm->output == OUTPUT_NONCURSES) {
+ if (cut_off_frequency < 1000)
+ printf("%-4d", freq_floor);
+ else if (cut_off_frequency > 1000 && cut_off_frequency < 10000)
+ printf("%.2f", freq_kilohz);
+ else
+ printf("%.1f", freq_kilohz);
+
+ if (n < audio_raw->number_of_bars - 1)
+ printf("\033[%dC", prm->bar_width + prm->bar_spacing - 4);
+ }
+ }
+ printf("\r\033[%dA", audio_raw->lines + 1);
+ }
+
+ return 0;
+}
+#ifndef SDL_GLSL
+int audio_raw_fetch(struct cava::audio_raw *audio_raw, struct config_params *prm,
+ struct cava_plan *plan) {
+#else
+int audio_raw_fetch(struct cava::audio_raw *audio_raw, struct config_params *prm, int *re_paint,
+ struct cava_plan *plan) {
+#endif
+ (void)plan;
+ for (int n = 0; n < audio_raw->number_of_bars; n++) {
+ if (!prm->waveform) {
+ audio_raw->cava_out[n] *= prm->sens;
+ } else {
+ if (audio_raw->cava_out[n] > 1.0)
+ prm->sens *= 0.999;
+ else
+ prm->sens *= 1.0001;
+
+ if (prm->orientation != ORIENT_SPLIT_H)
+ audio_raw->cava_out[n] = (audio_raw->cava_out[n] + 1.0) / 2.0;
+ }
+
+ if (prm->output == OUTPUT_SDL_GLSL) {
+ if (audio_raw->cava_out[n] > 1.0)
+ audio_raw->cava_out[n] = 1.0;
+ else if (audio_raw->cava_out[n] < 0.0)
+ audio_raw->cava_out[n] = 0.0;
+ } else {
+ audio_raw->cava_out[n] *= *audio_raw->dimension_value;
+ if (prm->orientation == ORIENT_SPLIT_H || prm->orientation == ORIENT_SPLIT_V) {
+ audio_raw->cava_out[n] /= 2;
+ }
+ }
+ if (prm->waveform) {
+ audio_raw->bars_raw[n] = audio_raw->cava_out[n];
+ }
+ }
+
+ if (!prm->waveform) {
+ if (audio_raw->channels == 2) {
+ for (int n = 0; n < audio_raw->number_of_bars / audio_raw->output_channels; n++) {
+ if (prm->userEQ_enabled)
+ audio_raw->cava_out[n] *=
+ prm->userEQ[(int)floor(((double)n) * audio_raw->userEQ_keys_to_bars_ratio)];
+ audio_raw->bars_left[n] = audio_raw->cava_out[n];
+ }
+ for (int n = 0; n < audio_raw->number_of_bars / audio_raw->output_channels; n++) {
+ if (prm->userEQ_enabled)
+ audio_raw
+ ->cava_out[n + audio_raw->number_of_bars / audio_raw->output_channels] *=
+ prm->userEQ[(int)floor(((double)n) * audio_raw->userEQ_keys_to_bars_ratio)];
+ audio_raw->bars_right[n] =
+ audio_raw->cava_out[n + audio_raw->number_of_bars / audio_raw->output_channels];
+ }
+ } else {
+ for (int n = 0; n < audio_raw->number_of_bars; n++) {
+ if (prm->userEQ_enabled)
+ audio_raw->cava_out[n] *=
+ prm->userEQ[(int)floor(((double)n) * audio_raw->userEQ_keys_to_bars_ratio)];
+ audio_raw->bars_raw[n] = audio_raw->cava_out[n];
+ }
+ }
+
+ // process [filter]
+ if (prm->monstercat) {
+ if (audio_raw->channels == 2) {
+ audio_raw->bars_left = monstercat_filter(
+ audio_raw->bars_left, audio_raw->number_of_bars / audio_raw->output_channels,
+ prm->waves, prm->monstercat, *audio_raw->dimension_value);
+ audio_raw->bars_right = monstercat_filter(
+ audio_raw->bars_right, audio_raw->number_of_bars / audio_raw->output_channels,
+ prm->waves, prm->monstercat, *audio_raw->dimension_value);
+ } else {
+ audio_raw->bars_raw =
+ monstercat_filter(audio_raw->bars_raw, audio_raw->number_of_bars, prm->waves,
+ prm->monstercat, *audio_raw->dimension_value);
+ }
+ }
+ if (audio_raw->channels == 2) {
+ if (prm->stereo) {
+ // mirroring stereo channels
+ for (int n = 0; n < audio_raw->number_of_bars; n++) {
+ if (n < audio_raw->number_of_bars / 2) {
+ if (prm->reverse) {
+ audio_raw->bars_raw[n] = audio_raw->bars_left[n];
+ } else {
+ audio_raw->bars_raw[n] =
+ audio_raw->bars_left[audio_raw->number_of_bars / 2 - n - 1];
+ }
+ } else {
+ if (prm->reverse) {
+ audio_raw->bars_raw[n] =
+ audio_raw->bars_right[audio_raw->number_of_bars - n - 1];
+ } else {
+ audio_raw->bars_raw[n] =
+ audio_raw->bars_right[n - audio_raw->number_of_bars / 2];
+ }
+ }
+ }
+ } else {
+ // stereo mono output
+ for (int n = 0; n < audio_raw->number_of_bars; n++) {
+ if (prm->reverse) {
+ if (prm->mono_opt == AVERAGE) {
+ audio_raw->bars_raw[audio_raw->number_of_bars - n - 1] =
+ (audio_raw->bars_left[n] + audio_raw->bars_right[n]) / 2;
+ } else if (prm->mono_opt == LEFT) {
+ audio_raw->bars_raw[audio_raw->number_of_bars - n - 1] =
+ audio_raw->bars_left[n];
+ } else if (prm->mono_opt == RIGHT) {
+ audio_raw->bars_raw[audio_raw->number_of_bars - n - 1] =
+ audio_raw->bars_right[n];
+ }
+ } else {
+ if (prm->mono_opt == AVERAGE) {
+ audio_raw->bars_raw[n] =
+ (audio_raw->bars_left[n] + audio_raw->bars_right[n]) / 2;
+ } else if (prm->mono_opt == LEFT) {
+ audio_raw->bars_raw[n] = audio_raw->bars_left[n];
+ } else if (prm->mono_opt == RIGHT) {
+ audio_raw->bars_raw[n] = audio_raw->bars_right[n];
+ }
+ }
+ }
+ }
+ }
+ }
+#ifdef SDL_GLSL
+ *re_paint = 0;
+#endif
+
+#ifndef NDEBUG
+ int maxvalue = 0;
+ int minvalue = 0;
+#endif
+
+ for (int n = 0; n < audio_raw->number_of_bars; n++) {
+ audio_raw->bars[n] = audio_raw->bars_raw[n];
+ // show idle bar heads
+ if (prm->output != OUTPUT_RAW && prm->output != OUTPUT_NORITAKE && audio_raw->bars[n] < 1 &&
+ prm->waveform == 0 && prm->show_idle_bar_heads == 1)
+ audio_raw->bars[n] = 1;
+#ifdef SDL_GLSL
+
+ if (prm->output == OUTPUT_SDL_GLSL)
+ audio_raw->bars[n] =
+ audio_raw->bars_raw[n] * 1000; // values are 0-1, only used to check for changes
+
+ if (audio_raw->bars[n] != audio_raw->previous_frame[n])
+ *re_paint = 1;
+#endif
+
+#ifndef NDEBUG
+ mvprintw(n, 0, "%d: f:%f->%f (%d->%d), eq:%15e, peak:%d \n", n, plan->cut_off_frequency[n],
+ plan->cut_off_frequency[n + 1], plan->FFTbuffer_lower_cut_off[n],
+ plan->FFTbuffer_upper_cut_off[n], plan->eq[n], audio_raw->bars[n]);
+
+ if (audio_raw->bars[n] < minvalue) {
+ minvalue = audio_raw->bars[n];
+ debug("min value: %d\n", minvalue); // checking maxvalue 10000
+ }
+ if (audio_raw->bars[n] > maxvalue) {
+ maxvalue = audio_raw->bars[n];
+ }
+
+ if (audio_raw->bars[n] < 0) {
+ debug("negative bar value!! %d\n", audio_raw->bars[n]);
+ // exit(EXIT_FAILURE); // Can't happen.
+ }
+
+#endif
+ }
+
+#ifndef NDEBUG
+ mvprintw(audio_raw->number_of_bars + 1, 0, "sensitivity %.10e", prm->sens);
+ mvprintw(audio_raw->number_of_bars + 2, 0, "min value: %d\n",
+ minvalue); // checking maxvalue 10000
+ mvprintw(audio_raw->number_of_bars + 3, 0, "max value: %d\n",
+ maxvalue); // checking maxvalue 10000
+#endif
+
+ return 0;
+}
+
+int audio_raw_clean(struct cava::audio_raw *audio_raw) {
+ free(audio_raw->bars);
+ free(audio_raw->previous_frame);
+ if (audio_raw->channels == 2) {
+ free(audio_raw->bars_left);
+ free(audio_raw->bars_right);
+ }
+ free(audio_raw->bars_raw);
+ free(audio_raw->cava_out);
+
+ return 0;
+}
+
+int audio_raw_destroy(struct cava::audio_raw *audio_raw) {
+ audio_raw_clean(audio_raw);
+
+ free(audio_raw->dimension_bar);
+ free(audio_raw->dimension_value);
+ free(audio_raw);
+
+ return 0;
+}
+
waybar::modules::Cava::Cava(const std::string& id, const Json::Value& config)
: ALabel(config, "cava", id, "{}", 60, false, false, false) {
@@ -18,7 +559,6 @@
}
// Override cava parameters by the user config
- prm_.inAtty = 0;
prm_.output = cava::output_method::OUTPUT_RAW;
strcpy(prm_.data_format, "ascii");
strcpy(prm_.raw_target, "/dev/stdout");
@@ -64,24 +604,24 @@
plan_ = new cava::cava_plan{};
audio_raw_.height = prm_.ascii_range;
- audio_data_.format = -1;
- audio_data_.source = new char[1 + strlen(prm_.audio_source)];
- audio_data_.source[0] = '\0';
- strcpy(audio_data_.source, prm_.audio_source);
-
- audio_data_.rate = 0;
- audio_data_.samples_counter = 0;
- audio_data_.channels = 2;
- audio_data_.IEEE_FLOAT = 0;
-
- audio_data_.input_buffer_size = BUFFER_SIZE * audio_data_.channels;
- audio_data_.cava_buffer_size = audio_data_.input_buffer_size * 8;
-
- audio_data_.cava_in = new double[audio_data_.cava_buffer_size]{0.0};
-
- audio_data_.terminate = 0;
- audio_data_.suspendFlag = false;
- input_source_ = get_input(&audio_data_, &prm_);
+ audio_data_ext_.format = -1;
+ audio_data_ext_.source = new char[1 + strlen(prm_.audio_source)];
+ audio_data_ext_.source[0] = '\0';
+ strcpy(audio_data_ext_.source, prm_.audio_source);
+
+ audio_data_ext_.rate = 0;
+ audio_data_ext_.samples_counter = 0;
+ audio_data_ext_.channels = 2;
+ audio_data_ext_.IEEE_FLOAT = 0;
+
+ audio_data_ext_.input_buffer_size = BUFFER_SIZE * audio_data_ext_.channels;
+ audio_data_ext_.cava_buffer_size = audio_data_ext_.input_buffer_size * 8;
+
+ audio_data_ext_.cava_in = new double[audio_data_ext_.cava_buffer_size]{0.0};
+
+ audio_data_ext_.terminate = 0;
+ audio_data_ext_.suspendFlag = false;
+ input_source_ = get_input(&audio_data_ext_, &prm_);
if (!input_source_) {
spdlog::error("cava API didn't provide input audio source method");
@@ -91,13 +631,13 @@
frame_time_milsec_ = std::chrono::milliseconds((int)(1e3 / prm_.framerate));
// Init cava plan, audio_raw structure
- audio_raw_init(&audio_data_, &audio_raw_, &prm_, plan_);
+ audio_raw_init(&audio_data_ext_, &audio_raw_, &prm_, plan_);
if (!plan_) spdlog::error("cava plan is not provided");
audio_raw_.previous_frame[0] = -1; // For first Update() call need to rePaint text message
// Read audio source trough cava API. Cava orginizes this process via infinity loop
thread_fetch_input_ = [this] {
thread_fetch_input_.sleep_for(fetch_input_delay_);
- input_source_(&audio_data_);
+ input_source_(&audio_data_ext_);
};
thread_ = [this] {
@@ -128,11 +668,11 @@
}
auto waybar::modules::Cava::update() -> void {
- if (audio_data_.suspendFlag) return;
+ if (audio_data_ext_.suspendFlag) return;
silence_ = true;
- for (int i{0}; i < audio_data_.input_buffer_size; ++i) {
- if (audio_data_.cava_in[i]) {
+ for (int i{0}; i < audio_data_ext_.input_buffer_size; ++i) {
+ if (audio_data_ext_.cava_in[i]) {
silence_ = false;
sleep_counter_ = 0;
break;
@@ -150,11 +690,11 @@
if (!silence_ || prm_.sleep_timer == 0) {
downThreadDelay(frame_time_milsec_, suspend_silence_delay_);
// Process: execute cava
- pthread_mutex_lock(&audio_data_.lock);
- cava::cava_execute(audio_data_.cava_in, audio_data_.samples_counter, audio_raw_.cava_out,
+ pthread_mutex_lock(&audio_data_ext_.lock);
+ cava::cava_execute(audio_data_ext_.cava_in, audio_data_ext_.samples_counter, audio_raw_.cava_out,
plan_);
- if (audio_data_.samples_counter > 0) audio_data_.samples_counter = 0;
- pthread_mutex_unlock(&audio_data_.lock);
+ if (audio_data_ext_.samples_counter > 0) audio_data_ext_.samples_counter = 0;
+ pthread_mutex_unlock(&audio_data_ext_.lock);
// Do transformation under raw data
audio_raw_fetch(&audio_raw_, &prm_, &rePaint_, plan_);
@@ -198,14 +738,14 @@
// Cava actions
void waybar::modules::Cava::pause_resume() {
- pthread_mutex_lock(&audio_data_.lock);
- if (audio_data_.suspendFlag) {
- audio_data_.suspendFlag = false;
- pthread_cond_broadcast(&audio_data_.resumeCond);
+ pthread_mutex_lock(&audio_data_ext_.lock);
+ if (audio_data_ext_.suspendFlag) {
+ audio_data_ext_.suspendFlag = false;
+ pthread_cond_broadcast(&audio_data_ext_.resumeCond);
downThreadDelay(frame_time_milsec_, suspend_silence_delay_);
} else {
- audio_data_.suspendFlag = true;
+ audio_data_ext_.suspendFlag = true;
upThreadDelay(frame_time_milsec_, suspend_silence_delay_);
}
- pthread_mutex_unlock(&audio_data_.lock);
+ pthread_mutex_unlock(&audio_data_ext_.lock);
}