commit
d012de3cde
|
|
@ -0,0 +1,43 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <epoxy/gl.h>
|
||||||
|
|
||||||
|
#include "AModule.hpp"
|
||||||
|
#include "cava_backend.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules::cava {
|
||||||
|
|
||||||
|
class CavaGLSL final : public AModule, public Gtk::GLArea {
|
||||||
|
public:
|
||||||
|
CavaGLSL(const std::string&, const Json::Value&);
|
||||||
|
~CavaGLSL() = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<CavaBackend> backend_;
|
||||||
|
struct ::cava::config_params prm_;
|
||||||
|
int frame_counter{0};
|
||||||
|
bool silence_{false};
|
||||||
|
bool hide_on_silence_{false};
|
||||||
|
// Cava method
|
||||||
|
auto onUpdate(const ::cava::audio_raw& input) -> void;
|
||||||
|
auto onSilence() -> void;
|
||||||
|
// Member variable to store the shared pointer
|
||||||
|
std::shared_ptr<::cava::audio_raw> m_data_;
|
||||||
|
GLuint shaderProgram_;
|
||||||
|
// OpenGL variables
|
||||||
|
GLuint fbo_;
|
||||||
|
GLuint texture_;
|
||||||
|
GLint uniform_bars_;
|
||||||
|
GLint uniform_previous_bars_;
|
||||||
|
GLint uniform_bars_count_;
|
||||||
|
GLint uniform_time_;
|
||||||
|
// Methods
|
||||||
|
void onRealize();
|
||||||
|
bool onRender(const Glib::RefPtr<Gdk::GLContext>& context);
|
||||||
|
|
||||||
|
void initShaders();
|
||||||
|
void initSurface();
|
||||||
|
void initGLSL();
|
||||||
|
GLuint loadShader(const std::string& fileName, GLenum type);
|
||||||
|
};
|
||||||
|
} // namespace waybar::modules::cava
|
||||||
|
|
@ -9,20 +9,20 @@ class Cava final : public ALabel, public sigc::trackable {
|
||||||
public:
|
public:
|
||||||
Cava(const std::string&, const Json::Value&);
|
Cava(const std::string&, const Json::Value&);
|
||||||
~Cava() = default;
|
~Cava() = default;
|
||||||
auto onUpdate(const std::string& input) -> void;
|
|
||||||
auto onSilence() -> void;
|
|
||||||
auto doAction(const std::string& name) -> void override;
|
auto doAction(const std::string& name) -> void override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<CavaBackend> backend_;
|
std::shared_ptr<CavaBackend> backend_;
|
||||||
// Text to display
|
// Text to display
|
||||||
std::string label_text_{""};
|
Glib::ustring label_text_{""};
|
||||||
|
bool silence_{false};
|
||||||
bool hide_on_silence_{false};
|
bool hide_on_silence_{false};
|
||||||
std::string format_silent_{""};
|
std::string format_silent_{""};
|
||||||
int ascii_range_{0};
|
int ascii_range_{0};
|
||||||
bool silence_{false};
|
|
||||||
// Cava method
|
// Cava method
|
||||||
void pause_resume();
|
void pause_resume();
|
||||||
|
auto onUpdate(const std::string& input) -> void;
|
||||||
|
auto onSilence() -> void;
|
||||||
// ModuleActionMap
|
// ModuleActionMap
|
||||||
static inline std::map<const std::string, void (waybar::modules::cava::Cava::* const)()>
|
static inline std::map<const std::string, void (waybar::modules::cava::Cava::* const)()>
|
||||||
actionMap_{{"mode", &waybar::modules::cava::Cava::pause_resume}};
|
actionMap_{{"mode", &waybar::modules::cava::Cava::pause_resume}};
|
||||||
|
|
@ -32,16 +32,22 @@ class CavaBackend final {
|
||||||
int getAsciiRange();
|
int getAsciiRange();
|
||||||
void doPauseResume();
|
void doPauseResume();
|
||||||
void Update();
|
void Update();
|
||||||
|
const struct ::cava::config_params* getPrm();
|
||||||
|
std::chrono::milliseconds getFrameTimeMilsec();
|
||||||
|
|
||||||
// Signal accessor
|
// Signal accessor
|
||||||
using type_signal_update = sigc::signal<void(const std::string&)>;
|
using type_signal_update = sigc::signal<void(const std::string&)>;
|
||||||
type_signal_update signal_update();
|
type_signal_update signal_update();
|
||||||
|
using type_signal_audio_raw_update = sigc::signal<void(const ::cava::audio_raw&)>;
|
||||||
|
type_signal_audio_raw_update signal_audio_raw_update();
|
||||||
using type_signal_silence = sigc::signal<void()>;
|
using type_signal_silence = sigc::signal<void()>;
|
||||||
type_signal_silence signal_silence();
|
type_signal_silence signal_silence();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CavaBackend(const Json::Value& config);
|
CavaBackend(const Json::Value& config);
|
||||||
util::SleeperThread thread_;
|
|
||||||
util::SleeperThread read_thread_;
|
util::SleeperThread read_thread_;
|
||||||
|
util::SleeperThread out_thread_;
|
||||||
|
|
||||||
// Cava API to read audio source
|
// Cava API to read audio source
|
||||||
::cava::ptr input_source_{NULL};
|
::cava::ptr input_source_{NULL};
|
||||||
|
|
||||||
|
|
@ -55,6 +61,7 @@ class CavaBackend final {
|
||||||
// Delay to handle audio source
|
// Delay to handle audio source
|
||||||
std::chrono::milliseconds frame_time_milsec_{1s};
|
std::chrono::milliseconds frame_time_milsec_{1s};
|
||||||
|
|
||||||
|
const Json::Value& config_;
|
||||||
int re_paint_{0};
|
int re_paint_{0};
|
||||||
bool silence_{false};
|
bool silence_{false};
|
||||||
bool silence_prev_{false};
|
bool silence_prev_{false};
|
||||||
|
|
@ -66,9 +73,12 @@ class CavaBackend final {
|
||||||
void execute();
|
void execute();
|
||||||
bool isSilence();
|
bool isSilence();
|
||||||
void doUpdate(bool force = false);
|
void doUpdate(bool force = false);
|
||||||
|
void loadConfig();
|
||||||
|
void freeBackend();
|
||||||
|
|
||||||
// Signal
|
// Signal
|
||||||
type_signal_update m_signal_update_;
|
type_signal_update m_signal_update_;
|
||||||
|
type_signal_audio_raw_update m_signal_audio_raw_;
|
||||||
type_signal_silence m_signal_silence_;
|
type_signal_silence m_signal_silence_;
|
||||||
};
|
};
|
||||||
} // namespace waybar::modules::cava
|
} // namespace waybar::modules::cava
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBCAVA
|
||||||
|
#include "cavaRaw.hpp"
|
||||||
|
#include "cava_backend.hpp"
|
||||||
|
#ifdef HAVE_LIBCAVAGLSL
|
||||||
|
#include "cavaGLSL.hpp"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace waybar::modules::cava {
|
||||||
|
AModule* getModule(const std::string& id, const Json::Value& config) {
|
||||||
|
#ifdef HAVE_LIBCAVA
|
||||||
|
const std::shared_ptr<CavaBackend> backend_{waybar::modules::cava::CavaBackend::inst(config)};
|
||||||
|
switch (backend_->getPrm()->output) {
|
||||||
|
case ::cava::output_method::OUTPUT_RAW:
|
||||||
|
return new waybar::modules::cava::Cava(id, config);
|
||||||
|
break;
|
||||||
|
#ifdef HAVE_LIBCAVAGLSL
|
||||||
|
case ::cava::output_method::OUTPUT_SDL_GLSL:
|
||||||
|
return new waybar::modules::cava::CavaGLSL(id, config);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
throw std::runtime_error("Unknown module");
|
||||||
|
};
|
||||||
|
} // namespace waybar::modules::cava
|
||||||
17
meson.build
17
meson.build
|
|
@ -497,16 +497,24 @@ else
|
||||||
man_files += files('man/waybar-clock.5.scd')
|
man_files += files('man/waybar-clock.5.scd')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
cava = dependency('cava',
|
cava = dependency('libcava',
|
||||||
version : '>=0.10.6',
|
version : '>=0.10.7',
|
||||||
required: get_option('cava'),
|
required: get_option('cava'),
|
||||||
fallback : ['cava', 'cava_dep'],
|
fallback : ['libcava', 'cava_dep'],
|
||||||
not_found_message: 'cava is not found. Building waybar without cava')
|
not_found_message: 'cava is not found. Building waybar without cava')
|
||||||
|
|
||||||
|
eproxy = dependency('epoxy', required: false)
|
||||||
|
|
||||||
if cava.found()
|
if cava.found()
|
||||||
add_project_arguments('-DHAVE_LIBCAVA', language: 'cpp')
|
add_project_arguments('-DHAVE_LIBCAVA', language: 'cpp')
|
||||||
src_files += files('src/modules/cava/cava.cpp', 'src/modules/cava/cava_backend.cpp')
|
src_files += files('src/modules/cava/cavaRaw.cpp',
|
||||||
|
'src/modules/cava/cava_backend.cpp')
|
||||||
man_files += files('man/waybar-cava.5.scd')
|
man_files += files('man/waybar-cava.5.scd')
|
||||||
|
|
||||||
|
if eproxy.found()
|
||||||
|
add_project_arguments('-DHAVE_LIBCAVAGLSL', language: 'cpp')
|
||||||
|
src_files += files('src/modules/cava/cavaGLSL.cpp')
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if libgps.found()
|
if libgps.found()
|
||||||
|
|
@ -554,6 +562,7 @@ executable(
|
||||||
tz_dep,
|
tz_dep,
|
||||||
xkbregistry,
|
xkbregistry,
|
||||||
cava,
|
cava,
|
||||||
|
eproxy,
|
||||||
libgps
|
libgps
|
||||||
],
|
],
|
||||||
include_directories: inc_dirs,
|
include_directories: inc_dirs,
|
||||||
|
|
|
||||||
|
|
@ -108,15 +108,13 @@
|
||||||
#ifdef HAVE_LIBWIREPLUMBER
|
#ifdef HAVE_LIBWIREPLUMBER
|
||||||
#include "modules/wireplumber.hpp"
|
#include "modules/wireplumber.hpp"
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_LIBCAVA
|
|
||||||
#include "modules/cava/cava.hpp"
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYSTEMD_MONITOR
|
#ifdef HAVE_SYSTEMD_MONITOR
|
||||||
#include "modules/systemd_failed_units.hpp"
|
#include "modules/systemd_failed_units.hpp"
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_LIBGPS
|
#ifdef HAVE_LIBGPS
|
||||||
#include "modules/gps.hpp"
|
#include "modules/gps.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
#include "modules/cava/cava_frontend.hpp"
|
||||||
#include "modules/cffi.hpp"
|
#include "modules/cffi.hpp"
|
||||||
#include "modules/custom.hpp"
|
#include "modules/custom.hpp"
|
||||||
#include "modules/image.hpp"
|
#include "modules/image.hpp"
|
||||||
|
|
@ -341,11 +339,9 @@ waybar::AModule* waybar::Factory::makeModule(const std::string& name,
|
||||||
return new waybar::modules::Wireplumber(id, config_[name]);
|
return new waybar::modules::Wireplumber(id, config_[name]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_LIBCAVA
|
|
||||||
if (ref == "cava") {
|
if (ref == "cava") {
|
||||||
return new waybar::modules::cava::Cava(id, config_[name]);
|
return waybar::modules::cava::getModule(id, config_[name]);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYSTEMD_MONITOR
|
#ifdef HAVE_SYSTEMD_MONITOR
|
||||||
if (ref == "systemd-failed-units") {
|
if (ref == "systemd-failed-units") {
|
||||||
return new waybar::modules::SystemdFailedUnits(id, config_[name]);
|
return new waybar::modules::SystemdFailedUnits(id, config_[name]);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,271 @@
|
||||||
|
#include "modules/cava/cavaGLSL.hpp"
|
||||||
|
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
waybar::modules::cava::CavaGLSL::CavaGLSL(const std::string& id, const Json::Value& config)
|
||||||
|
: AModule(config, "cavaGLSL", id, false, false),
|
||||||
|
backend_{waybar::modules::cava::CavaBackend::inst(config)} {
|
||||||
|
set_name(name_);
|
||||||
|
if (config_["hide_on_silence"].isBool()) hide_on_silence_ = config_["hide_on_silence"].asBool();
|
||||||
|
if (!id.empty()) {
|
||||||
|
get_style_context()->add_class(id);
|
||||||
|
}
|
||||||
|
get_style_context()->add_class(MODULE_CLASS);
|
||||||
|
|
||||||
|
set_use_es(true);
|
||||||
|
// set_auto_render(true);
|
||||||
|
signal_realize().connect(sigc::mem_fun(*this, &CavaGLSL::onRealize));
|
||||||
|
signal_render().connect(sigc::mem_fun(*this, &CavaGLSL::onRender), false);
|
||||||
|
|
||||||
|
// Get parameters_config struct from the backend
|
||||||
|
prm_ = *backend_->getPrm();
|
||||||
|
|
||||||
|
// Set widget length
|
||||||
|
int length{0};
|
||||||
|
if (config_["min-length"].isUInt())
|
||||||
|
length = config_["min-length"].asUInt();
|
||||||
|
else if (config_["max-length"].isUInt())
|
||||||
|
length = config_["max-length"].asUInt();
|
||||||
|
else
|
||||||
|
length = prm_.sdl_width;
|
||||||
|
|
||||||
|
set_size_request(length, prm_.sdl_height);
|
||||||
|
|
||||||
|
// Subscribe for changes
|
||||||
|
backend_->signal_audio_raw_update().connect(sigc::mem_fun(*this, &CavaGLSL::onUpdate));
|
||||||
|
// Subscribe for silence
|
||||||
|
backend_->signal_silence().connect(sigc::mem_fun(*this, &CavaGLSL::onSilence));
|
||||||
|
event_box_.add(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto waybar::modules::cava::CavaGLSL::onUpdate(const ::cava::audio_raw& input) -> void {
|
||||||
|
Glib::signal_idle().connect_once([this, input]() {
|
||||||
|
m_data_ = std::make_shared<::cava::audio_raw>(input);
|
||||||
|
if (silence_) {
|
||||||
|
get_style_context()->remove_class("silent");
|
||||||
|
if (!get_style_context()->has_class("updated")) get_style_context()->add_class("updated");
|
||||||
|
show();
|
||||||
|
silence_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
queue_render();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
auto waybar::modules::cava::CavaGLSL::onSilence() -> void {
|
||||||
|
Glib::signal_idle().connect_once([this]() {
|
||||||
|
if (!silence_) {
|
||||||
|
if (get_style_context()->has_class("updated")) get_style_context()->remove_class("updated");
|
||||||
|
|
||||||
|
if (hide_on_silence_) hide();
|
||||||
|
silence_ = true;
|
||||||
|
get_style_context()->add_class("silent");
|
||||||
|
// Set clear color to black
|
||||||
|
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
queue_render();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool waybar::modules::cava::CavaGLSL::onRender(const Glib::RefPtr<Gdk::GLContext>& context) {
|
||||||
|
if (!m_data_) return true;
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texture_);
|
||||||
|
glUniform1i(glGetUniformLocation(shaderProgram_, "inputTexture"), 0);
|
||||||
|
|
||||||
|
glUniform1fv(uniform_bars_, m_data_->number_of_bars, m_data_->bars_raw);
|
||||||
|
glUniform1fv(uniform_previous_bars_, m_data_->number_of_bars, m_data_->previous_bars_raw);
|
||||||
|
glUniform1i(uniform_bars_count_, m_data_->number_of_bars);
|
||||||
|
++frame_counter;
|
||||||
|
glUniform1f(uniform_time_, (frame_counter / backend_->getFrameTimeMilsec().count()) / 1e3);
|
||||||
|
|
||||||
|
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_INT, nullptr);
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
|
||||||
|
glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_INT, nullptr);
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void waybar::modules::cava::CavaGLSL::onRealize() {
|
||||||
|
make_current();
|
||||||
|
initShaders();
|
||||||
|
initGLSL();
|
||||||
|
initSurface();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct colors {
|
||||||
|
uint16_t R;
|
||||||
|
uint16_t G;
|
||||||
|
uint16_t B;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void parse_color(char* color_string, struct colors* color) {
|
||||||
|
if (color_string[0] == '#') {
|
||||||
|
sscanf(++color_string, "%02hx%02hx%02hx", &color->R, &color->G, &color->B);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void waybar::modules::cava::CavaGLSL::initGLSL() {
|
||||||
|
GLint gVertexPos2DLocation{glGetAttribLocation(shaderProgram_, "vertexPosition_modelspace")};
|
||||||
|
if (gVertexPos2DLocation == -1) {
|
||||||
|
spdlog::error("{0}. Could not find vertex position shader variable", name_);
|
||||||
|
}
|
||||||
|
|
||||||
|
glClearColor(0.f, 0.f, 0.f, 1.f);
|
||||||
|
|
||||||
|
GLfloat vertexData[]{-1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f};
|
||||||
|
GLint indexData[]{0, 1, 2, 3};
|
||||||
|
|
||||||
|
GLuint gVBO{0};
|
||||||
|
glGenBuffers(1, &gVBO);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, gVBO);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, 2 * 4 * sizeof(GLfloat), vertexData, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
GLuint gIBO{0};
|
||||||
|
glGenBuffers(1, &gIBO);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gIBO);
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 4 * sizeof(GLuint), indexData, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
GLuint gVAO{0};
|
||||||
|
glGenVertexArrays(1, &gVAO);
|
||||||
|
glBindVertexArray(gVAO);
|
||||||
|
glEnableVertexAttribArray(gVertexPos2DLocation);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, gVBO);
|
||||||
|
glVertexAttribPointer(gVertexPos2DLocation, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), nullptr);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gIBO);
|
||||||
|
|
||||||
|
glGenFramebuffers(1, &fbo_);
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
|
||||||
|
|
||||||
|
// Create a texture to attach the framebuffer
|
||||||
|
glGenTextures(1, &texture_);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texture_);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, prm_.sdl_width, prm_.sdl_height, 0, GL_RGBA,
|
||||||
|
GL_UNSIGNED_BYTE, nullptr);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_, 0);
|
||||||
|
|
||||||
|
// Check is framebuffer is complete
|
||||||
|
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||||
|
spdlog::error("{0}. Framebuffer not complete", name_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unbind the framebuffer
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
uniform_bars_ = glGetUniformLocation(shaderProgram_, "bars");
|
||||||
|
uniform_previous_bars_ = glGetUniformLocation(shaderProgram_, "previous_bars");
|
||||||
|
uniform_bars_count_ = glGetUniformLocation(shaderProgram_, "bars_count");
|
||||||
|
uniform_time_ = glGetUniformLocation(shaderProgram_, "shader_time");
|
||||||
|
|
||||||
|
GLuint err{glGetError()};
|
||||||
|
if (err != 0) {
|
||||||
|
spdlog::error("{0}. Error on initGLSL: {1}", name_, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void waybar::modules::cava::CavaGLSL::initSurface() {
|
||||||
|
colors color = {0};
|
||||||
|
GLint uniform_bg_col{glGetUniformLocation(shaderProgram_, "bg_color")};
|
||||||
|
parse_color(prm_.bcolor, &color);
|
||||||
|
glUniform3f(uniform_bg_col, (float)color.R / 255.0, (float)color.G / 255.0,
|
||||||
|
(float)color.B / 255.0);
|
||||||
|
GLint uniform_fg_col{glGetUniformLocation(shaderProgram_, "fg_color")};
|
||||||
|
parse_color(prm_.color, &color);
|
||||||
|
glUniform3f(uniform_fg_col, (float)color.R / 255.0, (float)color.G / 255.0,
|
||||||
|
(float)color.B / 255.0);
|
||||||
|
GLint uniform_res{glGetUniformLocation(shaderProgram_, "u_resolution")};
|
||||||
|
glUniform3f(uniform_res, (float)prm_.sdl_width, (float)prm_.sdl_height, 0.0f);
|
||||||
|
GLint uniform_bar_width{glGetUniformLocation(shaderProgram_, "bar_width")};
|
||||||
|
glUniform1i(uniform_bar_width, prm_.bar_width);
|
||||||
|
GLint uniform_bar_spacing{glGetUniformLocation(shaderProgram_, "bar_spacing")};
|
||||||
|
glUniform1i(uniform_bar_spacing, prm_.bar_spacing);
|
||||||
|
GLint uniform_gradient_count{glGetUniformLocation(shaderProgram_, "gradient_count")};
|
||||||
|
glUniform1i(uniform_gradient_count, prm_.gradient_count);
|
||||||
|
GLint uniform_gradient_colors{glGetUniformLocation(shaderProgram_, "gradient_colors")};
|
||||||
|
GLfloat gradient_colors[8][3];
|
||||||
|
for (int i{0}; i < prm_.gradient_count; ++i) {
|
||||||
|
parse_color(prm_.gradient_colors[i], &color);
|
||||||
|
gradient_colors[i][0] = (float)color.R / 255.0;
|
||||||
|
gradient_colors[i][1] = (float)color.G / 255.0;
|
||||||
|
gradient_colors[i][2] = (float)color.B / 255.0;
|
||||||
|
}
|
||||||
|
glUniform3fv(uniform_gradient_colors, 8, (const GLfloat*)gradient_colors);
|
||||||
|
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_INT, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void waybar::modules::cava::CavaGLSL::initShaders() {
|
||||||
|
shaderProgram_ = glCreateProgram();
|
||||||
|
|
||||||
|
GLuint vertexShader{loadShader(prm_.vertex_shader, GL_VERTEX_SHADER)};
|
||||||
|
GLuint fragmentShader{loadShader(prm_.fragment_shader, GL_FRAGMENT_SHADER)};
|
||||||
|
|
||||||
|
glAttachShader(shaderProgram_, vertexShader);
|
||||||
|
glAttachShader(shaderProgram_, fragmentShader);
|
||||||
|
|
||||||
|
glLinkProgram(shaderProgram_);
|
||||||
|
|
||||||
|
glDeleteShader(vertexShader);
|
||||||
|
glDeleteShader(fragmentShader);
|
||||||
|
|
||||||
|
// Check for linking errors
|
||||||
|
GLint success, len;
|
||||||
|
glGetProgramiv(shaderProgram_, GL_LINK_STATUS, &success);
|
||||||
|
if (!success) {
|
||||||
|
glGetProgramiv(shaderProgram_, GL_INFO_LOG_LENGTH, &len);
|
||||||
|
GLchar* infoLog{(char*)'\0'};
|
||||||
|
glGetProgramInfoLog(shaderProgram_, len, &len, infoLog);
|
||||||
|
spdlog::error("{0}. Shader linking error: {1}", name_, infoLog);
|
||||||
|
}
|
||||||
|
|
||||||
|
glReleaseShaderCompiler();
|
||||||
|
glUseProgram(shaderProgram_);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint waybar::modules::cava::CavaGLSL::loadShader(const std::string& fileName, GLenum type) {
|
||||||
|
spdlog::debug("{0}. loadShader: {1}", name_, fileName);
|
||||||
|
|
||||||
|
// Read shader source code from the file
|
||||||
|
std::ifstream shaderFile{fileName};
|
||||||
|
|
||||||
|
if (!shaderFile.is_open()) {
|
||||||
|
spdlog::error("{0}. Could not open shader file: {1}", name_, fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostringstream buffer;
|
||||||
|
buffer << shaderFile.rdbuf(); // read file content into stringstream
|
||||||
|
std::string str{buffer.str()};
|
||||||
|
const char* shaderSource = str.c_str();
|
||||||
|
shaderFile.close();
|
||||||
|
|
||||||
|
GLuint shaderID{glCreateShader(type)};
|
||||||
|
if (shaderID == 0) spdlog::error("{0}. Error creating shader type: {0}", type);
|
||||||
|
glShaderSource(shaderID, 1, &shaderSource, nullptr);
|
||||||
|
glCompileShader(shaderID);
|
||||||
|
|
||||||
|
// Check for compilation errors
|
||||||
|
GLint success, len;
|
||||||
|
|
||||||
|
glGetShaderiv(shaderID, GL_COMPILE_STATUS, &success);
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &len);
|
||||||
|
|
||||||
|
GLchar* infoLog{(char*)'\0'};
|
||||||
|
glGetShaderInfoLog(shaderID, len, nullptr, infoLog);
|
||||||
|
spdlog::error("{0}. Shader compilation error in {1}: {2}", name_, fileName, infoLog);
|
||||||
|
}
|
||||||
|
|
||||||
|
return shaderID;
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#include "modules/cava/cava.hpp"
|
#include "modules/cava/cavaRaw.hpp"
|
||||||
|
|
||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
|
|
@ -24,28 +24,35 @@ auto waybar::modules::cava::Cava::doAction(const std::string& name) -> void {
|
||||||
// Cava actions
|
// Cava actions
|
||||||
void waybar::modules::cava::Cava::pause_resume() { backend_->doPauseResume(); }
|
void waybar::modules::cava::Cava::pause_resume() { backend_->doPauseResume(); }
|
||||||
auto waybar::modules::cava::Cava::onUpdate(const std::string& input) -> void {
|
auto waybar::modules::cava::Cava::onUpdate(const std::string& input) -> void {
|
||||||
if (silence_) {
|
Glib::signal_idle().connect_once([this, input]() {
|
||||||
label_.get_style_context()->remove_class("silent");
|
if (silence_) {
|
||||||
label_.get_style_context()->add_class("updated");
|
label_.get_style_context()->remove_class("silent");
|
||||||
}
|
if (!label_.get_style_context()->has_class("updated"))
|
||||||
label_text_.clear();
|
label_.get_style_context()->add_class("updated");
|
||||||
for (auto& ch : input)
|
}
|
||||||
label_text_.append(getIcon((ch > ascii_range_) ? ascii_range_ : ch, "", ascii_range_ + 1));
|
label_text_.clear();
|
||||||
|
for (auto& ch : input)
|
||||||
|
label_text_.append(getIcon((ch > ascii_range_) ? ascii_range_ : ch, "", ascii_range_ + 1));
|
||||||
|
|
||||||
label_.set_markup(label_text_);
|
label_.set_markup(label_text_);
|
||||||
label_.show();
|
label_.show();
|
||||||
ALabel::update();
|
ALabel::update();
|
||||||
|
});
|
||||||
silence_ = false;
|
silence_ = false;
|
||||||
}
|
}
|
||||||
auto waybar::modules::cava::Cava::onSilence() -> void {
|
|
||||||
if (!silence_) {
|
|
||||||
label_.get_style_context()->remove_class("updated");
|
|
||||||
|
|
||||||
if (hide_on_silence_)
|
auto waybar::modules::cava::Cava::onSilence() -> void {
|
||||||
label_.hide();
|
Glib::signal_idle().connect_once([this]() {
|
||||||
else if (config_["format_silent"].isString())
|
if (!silence_) {
|
||||||
label_.set_markup(format_silent_);
|
if (label_.get_style_context()->has_class("updated"))
|
||||||
silence_ = true;
|
label_.get_style_context()->remove_class("updated");
|
||||||
label_.get_style_context()->add_class("silent");
|
|
||||||
}
|
if (hide_on_silence_)
|
||||||
|
label_.hide();
|
||||||
|
else if (config_["format_silent"].isString())
|
||||||
|
label_.set_markup(format_silent_);
|
||||||
|
silence_ = true;
|
||||||
|
label_.get_style_context()->add_class("silent");
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -9,91 +9,9 @@ std::shared_ptr<waybar::modules::cava::CavaBackend> waybar::modules::cava::CavaB
|
||||||
return backend_ptr;
|
return backend_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
waybar::modules::cava::CavaBackend::CavaBackend(const Json::Value& config) {
|
waybar::modules::cava::CavaBackend::CavaBackend(const Json::Value& config) : config_(config) {
|
||||||
// Load waybar module config
|
// Load waybar module config
|
||||||
char cfgPath[PATH_MAX];
|
loadConfig();
|
||||||
cfgPath[0] = '\0';
|
|
||||||
|
|
||||||
if (config["cava_config"].isString()) strcpy(cfgPath, config["cava_config"].asString().data());
|
|
||||||
// Load cava config
|
|
||||||
error_.length = 0;
|
|
||||||
|
|
||||||
if (!load_config(cfgPath, &prm_, false, &error_, 0)) {
|
|
||||||
spdlog::error("cava backend. Error loading config. {0}", error_.message);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Override cava parameters by the user config
|
|
||||||
prm_.inAtty = 0;
|
|
||||||
prm_.output = ::cava::output_method::OUTPUT_RAW;
|
|
||||||
if (prm_.data_format) free(prm_.data_format);
|
|
||||||
prm_.data_format = strdup("ascii");
|
|
||||||
if (prm_.raw_target) free(prm_.raw_target);
|
|
||||||
prm_.raw_target = strdup("/dev/stdout");
|
|
||||||
prm_.ascii_range = config["format-icons"].size() - 1;
|
|
||||||
|
|
||||||
prm_.bar_width = 2;
|
|
||||||
prm_.bar_spacing = 0;
|
|
||||||
prm_.bar_height = 32;
|
|
||||||
prm_.bar_width = 1;
|
|
||||||
prm_.orientation = ::cava::ORIENT_TOP;
|
|
||||||
prm_.xaxis = ::cava::xaxis_scale::NONE;
|
|
||||||
prm_.mono_opt = ::cava::AVERAGE;
|
|
||||||
prm_.autobars = 0;
|
|
||||||
prm_.gravity = 0;
|
|
||||||
prm_.integral = 1;
|
|
||||||
|
|
||||||
if (config["framerate"].isInt()) prm_.framerate = config["framerate"].asInt();
|
|
||||||
// Calculate delay for Update() thread
|
|
||||||
frame_time_milsec_ = std::chrono::milliseconds((int)(1e3 / prm_.framerate));
|
|
||||||
if (config["autosens"].isInt()) prm_.autosens = config["autosens"].asInt();
|
|
||||||
if (config["sensitivity"].isInt()) prm_.sens = config["sensitivity"].asInt();
|
|
||||||
if (config["bars"].isInt()) prm_.fixedbars = config["bars"].asInt();
|
|
||||||
if (config["lower_cutoff_freq"].isNumeric())
|
|
||||||
prm_.lower_cut_off = config["lower_cutoff_freq"].asLargestInt();
|
|
||||||
if (config["higher_cutoff_freq"].isNumeric())
|
|
||||||
prm_.upper_cut_off = config["higher_cutoff_freq"].asLargestInt();
|
|
||||||
if (config["sleep_timer"].isInt()) prm_.sleep_timer = config["sleep_timer"].asInt();
|
|
||||||
if (config["method"].isString())
|
|
||||||
prm_.input = ::cava::input_method_by_name(config["method"].asString().c_str());
|
|
||||||
if (config["source"].isString()) {
|
|
||||||
if (prm_.audio_source) free(prm_.audio_source);
|
|
||||||
prm_.audio_source = config["source"].asString().data();
|
|
||||||
}
|
|
||||||
if (config["sample_rate"].isNumeric()) prm_.samplerate = config["sample_rate"].asLargestInt();
|
|
||||||
if (config["sample_bits"].isInt()) prm_.samplebits = config["sample_bits"].asInt();
|
|
||||||
if (config["stereo"].isBool()) prm_.stereo = config["stereo"].asBool();
|
|
||||||
if (config["reverse"].isBool()) prm_.reverse = config["reverse"].asBool();
|
|
||||||
if (config["bar_delimiter"].isInt()) prm_.bar_delim = config["bar_delimiter"].asInt();
|
|
||||||
if (config["monstercat"].isBool()) prm_.monstercat = config["monstercat"].asBool();
|
|
||||||
if (config["waves"].isBool()) prm_.waves = config["waves"].asBool();
|
|
||||||
if (config["noise_reduction"].isDouble())
|
|
||||||
prm_.noise_reduction = config["noise_reduction"].asDouble();
|
|
||||||
if (config["input_delay"].isInt())
|
|
||||||
fetch_input_delay_ = std::chrono::seconds(config["input_delay"].asInt());
|
|
||||||
|
|
||||||
audio_raw_.height = prm_.ascii_range;
|
|
||||||
audio_data_.format = -1;
|
|
||||||
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_.terminate = 0;
|
|
||||||
audio_data_.suspendFlag = false;
|
|
||||||
input_source_ = get_input(&audio_data_, &prm_);
|
|
||||||
|
|
||||||
if (!input_source_) {
|
|
||||||
spdlog::error("cava backend API didn't provide input audio source method");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make cava parameters configuration
|
|
||||||
// Init cava plan, audio_raw structure
|
|
||||||
audio_raw_init(&audio_data_, &audio_raw_, &prm_, &plan_);
|
|
||||||
if (!plan_) spdlog::error("cava backend 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
|
// Read audio source trough cava API. Cava orginizes this process via infinity loop
|
||||||
read_thread_ = [this] {
|
read_thread_ = [this] {
|
||||||
try {
|
try {
|
||||||
|
|
@ -102,41 +20,38 @@ waybar::modules::cava::CavaBackend::CavaBackend(const Json::Value& config) {
|
||||||
spdlog::warn("Cava backend. Read source error: {0}", e.what());
|
spdlog::warn("Cava backend. Read source error: {0}", e.what());
|
||||||
}
|
}
|
||||||
read_thread_.sleep_for(fetch_input_delay_);
|
read_thread_.sleep_for(fetch_input_delay_);
|
||||||
|
loadConfig();
|
||||||
};
|
};
|
||||||
|
// Write outcoming data. Emit signals
|
||||||
thread_ = [this] {
|
out_thread_ = [this] {
|
||||||
doUpdate();
|
doUpdate(false);
|
||||||
thread_.sleep_for(frame_time_milsec_);
|
out_thread_.sleep_for(frame_time_milsec_);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
waybar::modules::cava::CavaBackend::~CavaBackend() {
|
waybar::modules::cava::CavaBackend::~CavaBackend() {
|
||||||
thread_.stop();
|
out_thread_.stop();
|
||||||
read_thread_.stop();
|
read_thread_.stop();
|
||||||
cava_destroy(plan_);
|
|
||||||
delete plan_;
|
freeBackend();
|
||||||
plan_ = nullptr;
|
|
||||||
audio_raw_clean(&audio_raw_);
|
|
||||||
pthread_mutex_lock(&audio_data_.lock);
|
|
||||||
audio_data_.terminate = 1;
|
|
||||||
pthread_mutex_unlock(&audio_data_.lock);
|
|
||||||
config_clean(&prm_);
|
|
||||||
free(audio_data_.source);
|
|
||||||
free(audio_data_.cava_in);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void upThreadDelay(std::chrono::milliseconds& delay, std::chrono::seconds& delta) {
|
static bool upThreadDelay(std::chrono::milliseconds& delay, std::chrono::seconds& delta) {
|
||||||
if (delta == std::chrono::seconds{0}) {
|
if (delta == std::chrono::seconds{0}) {
|
||||||
delta += std::chrono::seconds{1};
|
delta += std::chrono::seconds{1};
|
||||||
delay += delta;
|
delay += delta;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void downThreadDelay(std::chrono::milliseconds& delay, std::chrono::seconds& delta) {
|
static bool downThreadDelay(std::chrono::milliseconds& delay, std::chrono::seconds& delta) {
|
||||||
if (delta > std::chrono::seconds{0}) {
|
if (delta > std::chrono::seconds{0}) {
|
||||||
delay -= delta;
|
delay -= delta;
|
||||||
delta -= std::chrono::seconds{1};
|
delta -= std::chrono::seconds{1};
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool waybar::modules::cava::CavaBackend::isSilence() {
|
bool waybar::modules::cava::CavaBackend::isSilence() {
|
||||||
|
|
@ -186,6 +101,7 @@ void waybar::modules::cava::CavaBackend::doPauseResume() {
|
||||||
upThreadDelay(frame_time_milsec_, suspend_silence_delay_);
|
upThreadDelay(frame_time_milsec_, suspend_silence_delay_);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&audio_data_.lock);
|
pthread_mutex_unlock(&audio_data_.lock);
|
||||||
|
Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
waybar::modules::cava::CavaBackend::type_signal_update
|
waybar::modules::cava::CavaBackend::type_signal_update
|
||||||
|
|
@ -193,6 +109,11 @@ waybar::modules::cava::CavaBackend::signal_update() {
|
||||||
return m_signal_update_;
|
return m_signal_update_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
waybar::modules::cava::CavaBackend::type_signal_audio_raw_update
|
||||||
|
waybar::modules::cava::CavaBackend::signal_audio_raw_update() {
|
||||||
|
return m_signal_audio_raw_;
|
||||||
|
}
|
||||||
|
|
||||||
waybar::modules::cava::CavaBackend::type_signal_silence
|
waybar::modules::cava::CavaBackend::type_signal_silence
|
||||||
waybar::modules::cava::CavaBackend::signal_silence() {
|
waybar::modules::cava::CavaBackend::signal_silence() {
|
||||||
return m_signal_silence_;
|
return m_signal_silence_;
|
||||||
|
|
@ -215,12 +136,138 @@ void waybar::modules::cava::CavaBackend::doUpdate(bool force) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!silence_ || prm_.sleep_timer == 0) {
|
if (!silence_ || prm_.sleep_timer == 0) {
|
||||||
downThreadDelay(frame_time_milsec_, suspend_silence_delay_);
|
if (downThreadDelay(frame_time_milsec_, suspend_silence_delay_)) Update();
|
||||||
execute();
|
execute();
|
||||||
if (re_paint_ == 1 || force) m_signal_update_.emit(output_);
|
if (re_paint_ == 1 || force || prm_.continuous_rendering) {
|
||||||
|
m_signal_update_.emit(output_);
|
||||||
|
m_signal_audio_raw_.emit(audio_raw_);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
upThreadDelay(frame_time_milsec_, suspend_silence_delay_);
|
if (upThreadDelay(frame_time_milsec_, suspend_silence_delay_)) Update();
|
||||||
if (silence_ != silence_prev_ || force) m_signal_silence_.emit();
|
if (silence_ != silence_prev_ || force) m_signal_silence_.emit();
|
||||||
}
|
}
|
||||||
silence_prev_ = silence_;
|
silence_prev_ = silence_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void waybar::modules::cava::CavaBackend::freeBackend() {
|
||||||
|
if (plan_ != NULL) {
|
||||||
|
cava_destroy(plan_);
|
||||||
|
plan_ = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
audio_raw_clean(&audio_raw_);
|
||||||
|
pthread_mutex_lock(&audio_data_.lock);
|
||||||
|
audio_data_.terminate = 1;
|
||||||
|
pthread_mutex_unlock(&audio_data_.lock);
|
||||||
|
free_config(&prm_);
|
||||||
|
free(audio_data_.source);
|
||||||
|
free(audio_data_.cava_in);
|
||||||
|
}
|
||||||
|
|
||||||
|
void waybar::modules::cava::CavaBackend::loadConfig() {
|
||||||
|
freeBackend();
|
||||||
|
// Load waybar module config
|
||||||
|
char cfgPath[PATH_MAX];
|
||||||
|
cfgPath[0] = '\0';
|
||||||
|
|
||||||
|
if (config_["cava_config"].isString()) strcpy(cfgPath, config_["cava_config"].asString().data());
|
||||||
|
// Load cava config
|
||||||
|
error_.length = 0;
|
||||||
|
|
||||||
|
if (!load_config(cfgPath, &prm_, &error_)) {
|
||||||
|
spdlog::error("cava backend. Error loading config. {0}", error_.message);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Override cava parameters by the user config
|
||||||
|
prm_.inAtty = 0;
|
||||||
|
auto const output{prm_.output};
|
||||||
|
// prm_.output = ::cava::output_method::OUTPUT_RAW;
|
||||||
|
if (config_["data_format"].isString()) {
|
||||||
|
if (prm_.data_format) free(prm_.data_format);
|
||||||
|
prm_.data_format = strdup(config_["data_format"].asString().c_str());
|
||||||
|
}
|
||||||
|
if (config_["raw_target"].isString()) {
|
||||||
|
if (prm_.raw_target) free(prm_.raw_target);
|
||||||
|
prm_.raw_target = strdup(config_["raw_target"].asString().c_str());
|
||||||
|
}
|
||||||
|
prm_.ascii_range = config_["format-icons"].size() - 1;
|
||||||
|
|
||||||
|
if (config_["bar_spacing"].isInt()) prm_.bar_spacing = config_["bar_spacing"].asInt();
|
||||||
|
if (config_["bar_width"].isInt()) prm_.bar_width = config_["bar_width"].asInt();
|
||||||
|
if (config_["bar_height"].isInt()) prm_.bar_height = config_["bar_height"].asInt();
|
||||||
|
prm_.orientation = ::cava::ORIENT_TOP;
|
||||||
|
prm_.xaxis = ::cava::xaxis_scale::NONE;
|
||||||
|
prm_.mono_opt = ::cava::AVERAGE;
|
||||||
|
prm_.autobars = 0;
|
||||||
|
if (config_["gravity"].isInt()) prm_.gravity = config_["gravity"].asInt();
|
||||||
|
if (config_["integral"].isInt()) prm_.integral = config_["integral"].asInt();
|
||||||
|
|
||||||
|
if (config_["framerate"].isInt()) prm_.framerate = config_["framerate"].asInt();
|
||||||
|
// Calculate delay for Update() thread
|
||||||
|
frame_time_milsec_ = std::chrono::milliseconds((int)(1e3 / prm_.framerate));
|
||||||
|
if (config_["autosens"].isInt()) prm_.autosens = config_["autosens"].asInt();
|
||||||
|
if (config_["sensitivity"].isInt()) prm_.sens = config_["sensitivity"].asInt();
|
||||||
|
if (config_["bars"].isInt()) prm_.fixedbars = config_["bars"].asInt();
|
||||||
|
if (config_["lower_cutoff_freq"].isNumeric())
|
||||||
|
prm_.lower_cut_off = config_["lower_cutoff_freq"].asLargestInt();
|
||||||
|
if (config_["higher_cutoff_freq"].isNumeric())
|
||||||
|
prm_.upper_cut_off = config_["higher_cutoff_freq"].asLargestInt();
|
||||||
|
if (config_["sleep_timer"].isInt()) prm_.sleep_timer = config_["sleep_timer"].asInt();
|
||||||
|
if (config_["method"].isString())
|
||||||
|
prm_.input = ::cava::input_method_by_name(config_["method"].asString().c_str());
|
||||||
|
if (config_["source"].isString()) {
|
||||||
|
if (prm_.audio_source) free(prm_.audio_source);
|
||||||
|
prm_.audio_source = config_["source"].asString().data();
|
||||||
|
}
|
||||||
|
if (config_["sample_rate"].isNumeric()) prm_.samplerate = config_["sample_rate"].asLargestInt();
|
||||||
|
if (config_["sample_bits"].isInt()) prm_.samplebits = config_["sample_bits"].asInt();
|
||||||
|
if (config_["stereo"].isBool()) prm_.stereo = config_["stereo"].asBool();
|
||||||
|
if (config_["reverse"].isBool()) prm_.reverse = config_["reverse"].asBool();
|
||||||
|
if (config_["bar_delimiter"].isInt()) prm_.bar_delim = config_["bar_delimiter"].asInt();
|
||||||
|
if (config_["monstercat"].isBool()) prm_.monstercat = config_["monstercat"].asBool();
|
||||||
|
if (config_["waves"].isBool()) prm_.waves = config_["waves"].asBool();
|
||||||
|
if (config_["noise_reduction"].isDouble())
|
||||||
|
prm_.noise_reduction = config_["noise_reduction"].asDouble();
|
||||||
|
if (config_["input_delay"].isInt())
|
||||||
|
fetch_input_delay_ = std::chrono::seconds(config_["input_delay"].asInt());
|
||||||
|
if (config_["gradient"].isInt()) prm_.gradient = config_["gradient"].asInt();
|
||||||
|
if (prm_.gradient == 0)
|
||||||
|
prm_.gradient_count = 0;
|
||||||
|
else if (config_["gradient_count"].isInt())
|
||||||
|
prm_.gradient_count = config_["gradient_count"].asInt();
|
||||||
|
if (config_["sdl_width"].isInt()) prm_.sdl_width = config_["sdl_width"].asInt();
|
||||||
|
if (config_["sdl_height"].isInt()) prm_.sdl_height = config_["sdl_height"].asInt();
|
||||||
|
|
||||||
|
audio_raw_.height = prm_.ascii_range;
|
||||||
|
audio_data_.format = -1;
|
||||||
|
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_.terminate = 0;
|
||||||
|
audio_data_.suspendFlag = false;
|
||||||
|
input_source_ = get_input(&audio_data_, &prm_);
|
||||||
|
|
||||||
|
if (!input_source_) {
|
||||||
|
spdlog::error("cava backend API didn't provide input audio source method");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
prm_.output = ::cava::output_method::OUTPUT_RAW;
|
||||||
|
|
||||||
|
// Make cava parameters configuration
|
||||||
|
// Init cava plan, audio_raw structure
|
||||||
|
audio_raw_init(&audio_data_, &audio_raw_, &prm_, &plan_);
|
||||||
|
if (!plan_) spdlog::error("cava backend plan is not provided");
|
||||||
|
audio_raw_.previous_frame[0] = -1; // For first Update() call need to rePaint text message
|
||||||
|
|
||||||
|
prm_.output = output;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct ::cava::config_params* waybar::modules::cava::CavaBackend::getPrm() { return &prm_; }
|
||||||
|
std::chrono::milliseconds waybar::modules::cava::CavaBackend::getFrameTimeMilsec() {
|
||||||
|
return frame_time_milsec_;
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
[wrap-git]
|
|
||||||
url = https://github.com/LukashonakV/cava.git
|
|
||||||
revision = 23efcced43b5a395747b18a2e5f2171fc0925d18
|
|
||||||
depth = 1
|
|
||||||
|
|
||||||
#directory = cava-0.10.6
|
|
||||||
#source_url = https://github.com/LukashonakV/cava/archive/0.10.6.tar.gz
|
|
||||||
#source_filename = cava-0.10.6.tar.gz
|
|
||||||
#source_hash = e715c4c6a625b8dc063e57e8e81c80e4d1015ec1b98db69a283b2c6770f839f4
|
|
||||||
[provide]
|
|
||||||
cava = cava_dep
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
#[wrap-git]
|
||||||
|
#url = https://github.com/LukashonakV/cava.git
|
||||||
|
#revision = 866cfec40b7b9d38e97148d004d3134c1385b52f
|
||||||
|
#depth = 1
|
||||||
|
|
||||||
|
[wrap-file]
|
||||||
|
directory = cava-0.10.7-beta
|
||||||
|
source_url = https://github.com/LukashonakV/cava/archive/v0.10.7-beta.tar.gz
|
||||||
|
source_filename = cava-0.10.7.tar.gz
|
||||||
|
source_hash = 8915d7214f2046554c158fe6f2ae518881dfb573e421ea848727be11a5dfa8c4
|
||||||
|
[provide]
|
||||||
|
libcava = cava_dep
|
||||||
Loading…
Reference in New Issue