diff options
| author | 2024-10-08 14:51:21 -0400 | |
|---|---|---|
| committer | 2024-10-08 14:51:21 -0400 | |
| commit | 2bb807dd32e1c18a6f1e8f22c25141de3334de9f (patch) | |
| tree | 64795e558ef7b21655b69327e67027b43bf4b26f | |
| parent | 4d81d3b52952edb7a0cc329b4d0b302599b6c4c7 (diff) | |
| download | mauri-2bb807dd32e1c18a6f1e8f22c25141de3334de9f.tar.gz mauri-2bb807dd32e1c18a6f1e8f22c25141de3334de9f.tar.bz2 mauri-2bb807dd32e1c18a6f1e8f22c25141de3334de9f.zip | |
Remove gstreamer and visualizer, cleanup
Signed-off-by: Andrew Opalach <andrew@akon.city>
| -rw-r--r-- | cross/x86_64-w64-mingw32.txt | 19 | ||||
| -rw-r--r-- | meson.build | 10 | ||||
| -rw-r--r-- | src/assets.cc | 29 | ||||
| -rw-r--r-- | src/assets.h | 11 | ||||
| -rw-r--r-- | src/context.h | 5 | ||||
| -rw-r--r-- | src/engine.cc | 16 | ||||
| -rw-r--r-- | src/engine.h | 7 | ||||
| -rw-r--r-- | src/mauri.cc | 64 | ||||
| -rw-r--r-- | src/objects/effect.cc | 2 | ||||
| -rw-r--r-- | src/objects/material.cc | 2 | ||||
| -rw-r--r-- | src/objects/model.cc | 2 | ||||
| -rw-r--r-- | src/objects/pass.cc | 2 | ||||
| -rw-r--r-- | src/objects/pass.h | 8 | ||||
| -rw-r--r-- | src/objects/scene.cc | 2 | ||||
| -rw-r--r-- | src/shader.cc | 41 | ||||
| -rw-r--r-- | src/shader.h | 4 | ||||
| -rw-r--r-- | src/util.h | 4 | ||||
| -rw-r--r-- | src/vis.cc | 292 | ||||
| -rw-r--r-- | src/vis.h | 87 |
19 files changed, 100 insertions, 507 deletions
diff --git a/cross/x86_64-w64-mingw32.txt b/cross/x86_64-w64-mingw32.txt new file mode 100644 index 0000000..55fc1e6 --- /dev/null +++ b/cross/x86_64-w64-mingw32.txt @@ -0,0 +1,19 @@ +# ubuntu: sudo apt install mingw-w64 mingw-w64-tools binutils-mingw-w64 meson cmake nasm libz-mingw-w64-dev + +[binaries] +c = 'x86_64-w64-mingw32-gcc' +cpp = 'x86_64-w64-mingw32-g++' +ar = 'x86_64-w64-mingw32-gcc-ar' +strip = 'x86_64-w64-mingw32-strip' +exe_wrapper = 'wine64' + +[properties] +nm = 'x86_64-w64-mingw32-gcc-nm' +ar = 'x86_64-w64-mingw32-gcc-ar' +needs_exe_wrapper = true + +[host_machine] +system = 'windows' +cpu_family = 'x86_64' +cpu = 'x86_64' +endian = 'little' diff --git a/meson.build b/meson.build index 27baf30..4a09381 100644 --- a/meson.build +++ b/meson.build @@ -12,7 +12,7 @@ akiyo = subproject('libakiyo', default_options: ['event-loop=disabled', 'json=di stela = subproject('stela', default_options: [ 'api=opengl', - 'window=wayland', + is_windows ? 'window=glfw' : 'window=wayland', 'poll=inline', 'event-buffer=false', 'pause=false' @@ -58,12 +58,10 @@ mauri_src = [ mauri_cpp_args = [] mauri_link_args = [] -if get_option('audio').enabled() and is_linux - gstreamer = dependency('gstreamer-1.0') +if get_option('audio').enabled() fftw3 = dependency('fftw3') - mauri_deps += [gstreamer, fftw3] - mauri_src += ['src/vis.cc'] - mauri_cpp_args += ['-DHAVE_AUDIO'] + mauri_deps += [fftw3] + mauri_cpp_args += ['-DMAURI_HAVE_AUDIO'] endif if is_windows and meson.is_cross_build() diff --git a/src/assets.cc b/src/assets.cc index baf3922..8d2ac18 100644 --- a/src/assets.cc +++ b/src/assets.cc @@ -131,19 +131,6 @@ auto AssetManager::arm_package(const std::string &path, bool can_output) -> bool return true; } -auto AssetManager::unload_package() -> void -{ - for (Asset *asset : this->assets) - { - delete asset; - } - - this->assets.clear(); - - delete this->package; -} - - auto AssetManager::add_search_directory(const std::string &directory) -> bool { if (!std::filesystem::is_directory(directory)) return false; @@ -153,7 +140,7 @@ auto AssetManager::add_search_directory(const std::string &directory) -> bool return true; } -auto AssetManager::get_file(const std::string &part, AssetTypeHint hint) -> Asset * +auto AssetManager::get(const std::string &part, AssetTypeHint hint) -> Asset * { std::string path = part; @@ -238,7 +225,7 @@ auto AssetManager::get_file(const std::string &part, AssetTypeHint hint) -> Asse return asset; } -auto AssetManager::write_files(const std::string &output_path) -> void +auto AssetManager::dump(const std::string &output_path) -> void { if (!std::filesystem::is_directory(output_path) && !std::filesystem::create_directories(output_path)) { @@ -295,3 +282,15 @@ auto AssetManager::write_files(const std::string &output_path) -> void } } } + +auto AssetManager::unload_package() -> void +{ + for (Asset *asset : this->assets) + { + delete asset; + } + + this->assets.clear(); + + delete this->package; +} diff --git a/src/assets.h b/src/assets.h index 498308a..d1b8144 100644 --- a/src/assets.h +++ b/src/assets.h @@ -98,16 +98,13 @@ class AssetManager AssetManager() = default; ~AssetManager() = default; - auto get_file(const std::string &part, AssetTypeHint hint = NONE) -> Asset *; + bool prepare_output; auto arm_package(const std::string &path, bool can_output) -> bool; - auto unload_package() -> void; - auto add_search_directory(const std::string &directory) -> bool; - - bool prepare_output; - - auto write_files(const std::string &output_path) -> void; + auto get(const std::string &part, AssetTypeHint hint = NONE) -> Asset *; + auto dump(const std::string &output_path) -> void; + auto unload_package() -> void; private: std::vector<std::string> directories; diff --git a/src/context.h b/src/context.h index 6919550..8866a7f 100644 --- a/src/context.h +++ b/src/context.h @@ -1,13 +1,14 @@ #ifndef _CONTEXT_H #define _CONTEXT_H -#include "gl.h" - extern "C" { #include <stl/window.h> +#include <stl/gl.h> #include <aki/thread.h> } +#include "gl.h" + namespace Mauri { diff --git a/src/engine.cc b/src/engine.cc index ff90d65..1943357 100644 --- a/src/engine.cc +++ b/src/engine.cc @@ -54,18 +54,8 @@ Engine::Engine(Scene *scene, f32 rate, bool audio) this->view.camera_pos[0] += scene->cam.offset[0]; this->view.camera_pos[1] += scene->cam.offset[1]; -#ifdef HAVE_AUDIO - if (this->audio_enabled) - { - this->vis = new Visualizer(); - if (!this->vis->run()) - { - this->audio_enabled = false; - } - } -#else + // No audio for now. this->audio_enabled = false; -#endif this->shader = get_shader("hdr_downsample"); this->render_shader = this->shader->compile({}); @@ -160,8 +150,4 @@ Engine::~Engine() delete this->default_object; delete this->flipped_object; delete this->fullscreen_object; - -#ifdef HAVE_AUDIO - delete this->vis; -#endif } diff --git a/src/engine.h b/src/engine.h index dc8c052..991c226 100644 --- a/src/engine.h +++ b/src/engine.h @@ -3,10 +3,6 @@ #include "shader.h" -#ifdef HAVE_AUDIO -#include "vis.h" -#endif - static const std::string COMBINE_BUFFER = "_rt_FullFrameBuffer"; static const std::string MIPMAPPED_BUFFER = "_rt_MipMappedFrameBuffer"; @@ -53,9 +49,6 @@ class Engine f32 time; bool audio_enabled; -#ifdef HAVE_AUDIO - Visualizer *vis; -#endif View view; diff --git a/src/mauri.cc b/src/mauri.cc index 03e314f..737af65 100644 --- a/src/mauri.cc +++ b/src/mauri.cc @@ -1,9 +1,10 @@ -#include <janus.h> extern "C" { -#include <stl/window.h> #include <aki/common.h> +#include <stl/window.h> } +#include <janus.h> + #include "context.h" #include "assets.h" #include "engine.h" @@ -12,26 +13,32 @@ extern "C" { using namespace Mauri; +#define HELP_TEXT "\ +Usage: mauri (-p, --package [path_to_scene.pkg]|-d, --directory [path_to_wallpaper]) [OPTIONS]\n\ + -w, --width window width (default: 640)\n\ + -h, --height window height (default: 480)\n\ + -o, --offset offset of scene camera (default: 0,0)\n\ + -m, --monitor set as the background of this monitor (by name)\n\ + -t, --target dump scene into this directory and exit\ +" + #ifndef _WIN32 auto main(s32 argc, char *argv[]) -> s32 #else auto wmain(s32 argc, wchar_t **argv) -> s32 #endif { - if (!aki_common_init() || !stl_global_init()) { - return EXIT_FAILURE; - } + if (!aki_common_init()) return EXIT_FAILURE; - janus::ArgParser args("Usage: ...", "0.12"); + janus::ArgParser args(HELP_TEXT, "0.13"); args.newString("package p", ""); args.newString("directory d", ""); args.newInt("width w", 0); args.newInt("height h", 0); - args.newInt("xoffset x", 0); - args.newInt("yoffset y", 0); + args.newString("offset o", "0,0"); args.newString("monitor m", ""); - args.newString("output o", ""); + args.newString("target t", ""); #ifndef _WIN32 args.parse(argc, argv); #else @@ -46,35 +53,26 @@ auto wmain(s32 argc, wchar_t **argv) -> s32 s32 width = 640; s32 height = 480; - s32 xoffset = 0; - s32 yoffset = 0; - if (args.found("width")) width = args.getInt("width"); if (args.found("height")) height = args.getInt("height"); - if (args.found("xoffset")) xoffset = args.getInt("xoffset"); - if (args.found("yoffset")) yoffset = args.getInt("yoffset"); - if (width == 0 || height == 0) { error("invalid width and/or height in arguments"); return EXIT_FAILURE; } - const std::string monitor = args.found("monitor") ? args.getString("monitor") : ""; - -#ifdef HAVE_AUDIO - gst_init(&argc, &argv); -#endif - - Context *new_context = new Context(); - if (!new_context->create_window(width, height, "mauri", monitor)) - { + s32 xoffset; + s32 yoffset; + if (sscanf(args.getString("offset").c_str(), "%d,%d", &xoffset, &yoffset) != 2) { + error("invalid offset in arguments"); return EXIT_FAILURE; } + if (!stl_global_init()) return EXIT_FAILURE; + if (args.found("package")) { - if (!asset_manager()->arm_package(args.getString("package"), args.found("output"))) + if (!asset_manager()->arm_package(args.getString("package"), args.found("target"))) { return EXIT_FAILURE; } @@ -87,13 +85,19 @@ auto wmain(s32 argc, wchar_t **argv) -> s32 asset_manager()->add_search_directory(args.getString("directory")); } - set_context(new_context); - Scene *scene = Scene::parse("scene.json"); if (!scene) return EXIT_FAILURE; if (width <= 0) width = scene->width; if (height <= 0) height = scene->height; + + Context *new_context = new Context(); + if (!new_context->create_window(width, height, "mauri", args.getString("monitor"))) + { + return EXIT_FAILURE; + } + set_context(new_context); + scene->offset_camera(xoffset, yoffset); context()->resize_window(width, height); @@ -107,7 +111,7 @@ auto wmain(s32 argc, wchar_t **argv) -> s32 u64 duration = aki_get_timestamp() - begin; info("scene loaded in %.2fs", duration / 1000000.f); - if (asset_manager()->prepare_output) asset_manager()->write_files(args.getString("output")); + if (asset_manager()->prepare_output) asset_manager()->dump(args.getString("target")); else engine->run(); delete scene; @@ -120,9 +124,5 @@ auto wmain(s32 argc, wchar_t **argv) -> s32 context()->close_window(); set_context(nullptr); -#ifdef HAVE_AUDIO - //gst_deinit(); -#endif - return EXIT_SUCCESS; } diff --git a/src/objects/effect.cc b/src/objects/effect.cc index 92f7dda..2a6960f 100644 --- a/src/objects/effect.cc +++ b/src/objects/effect.cc @@ -7,7 +7,7 @@ auto Effect::parse(Parser &pr, const json &root) -> Effect * { Effect *effect = new Effect(); - Asset *asset = asset_manager()->get_file(root["file"]); + Asset *asset = asset_manager()->get(root["file"]); if (asset->type == ASSET_VOID) parse_fail(effect); const json &file = json::parse(asset->as_string(), nullptr, false); diff --git a/src/objects/material.cc b/src/objects/material.cc index e3e3e02..7c36d13 100644 --- a/src/objects/material.cc +++ b/src/objects/material.cc @@ -7,7 +7,7 @@ auto Material::parse(Parser &pr, const std::string &path) -> Material * { Material *material = new Material(); - Asset *asset = asset_manager()->get_file(path); + Asset *asset = asset_manager()->get(path); if (asset->type == ASSET_VOID) parse_fail(material); const json &root = json::parse(asset->as_string(), nullptr, false); diff --git a/src/objects/model.cc b/src/objects/model.cc index 830bdaf..f5ce9c4 100644 --- a/src/objects/model.cc +++ b/src/objects/model.cc @@ -6,7 +6,7 @@ auto Model::parse(Parser &pr, const std::string &path) -> Model * { Model *model = new Model(); - Asset *asset = asset_manager()->get_file(path); + Asset *asset = asset_manager()->get(path); if (asset->type == ASSET_VOID) parse_fail(model); const json &root = json::parse(asset->as_string(), nullptr, false); diff --git a/src/objects/pass.cc b/src/objects/pass.cc index 04e23d5..a7cfc09 100644 --- a/src/objects/pass.cc +++ b/src/objects/pass.cc @@ -190,7 +190,7 @@ RenderPass::RenderPass(Engine *engine, Pass *pass) if (!this->textures[i]) { - Asset *asset = asset_manager()->get_file(pass->textures[i], TEXTURE); + Asset *asset = asset_manager()->get(pass->textures[i], TEXTURE); if (asset->type != ASSET_VOID) { this->textures[i] = (Texture *)asset->lasset; diff --git a/src/objects/pass.h b/src/objects/pass.h index 5012ed5..fdec680 100644 --- a/src/objects/pass.h +++ b/src/objects/pass.h @@ -52,8 +52,8 @@ class Pass std::string shader; - std::array<std::string, MAX_TEXTURES> binds = { }; - std::array<std::string, MAX_TEXTURES> textures = { }; + std::array<std::string, MAX_TEXTURES> binds = {}; + std::array<std::string, MAX_TEXTURES> textures = {}; bool model; bool combine; @@ -83,8 +83,8 @@ class RenderPass mat4x4 *mat; RenderObject *render_object; - std::array<Texture *, MAX_TEXTURES> textures = { }; - std::array<TextureType, MAX_TEXTURES> texture_types = { }; + std::array<Texture *, MAX_TEXTURES> textures = {}; + std::array<TextureType, MAX_TEXTURES> texture_types = {}; auto draw(Engine *engine) -> void; diff --git a/src/objects/scene.cc b/src/objects/scene.cc index b7d1192..832cea6 100644 --- a/src/objects/scene.cc +++ b/src/objects/scene.cc @@ -6,7 +6,7 @@ auto Scene::parse(const std::string &path) -> Scene * { Scene *scene = new Scene(); - Asset *asset = asset_manager()->get_file(path); + Asset *asset = asset_manager()->get(path); if (asset->type == ASSET_VOID) parse_fail(scene); const json &root = json::parse(asset->as_string(), nullptr, false); diff --git a/src/shader.cc b/src/shader.cc index 2820b57..e17b4d1 100644 --- a/src/shader.cc +++ b/src/shader.cc @@ -59,8 +59,8 @@ using namespace Mauri; Shader::Shader(const std::string &name) : name(name) { - Asset *vs_asset = asset_manager()->get_file(name, VERTEX_SHADER); - Asset *fs_asset = asset_manager()->get_file(name, FRAGMENT_SHADER); + Asset *vs_asset = asset_manager()->get(name, VERTEX_SHADER); + Asset *fs_asset = asset_manager()->get(name, FRAGMENT_SHADER); this->build_shader_source(vs_asset->as_string(), this->vs_source); this->build_shader_source(fs_asset->as_string(), this->fs_source); } @@ -163,7 +163,7 @@ auto Shader::build_shader_source(const std::string_view &isource, std::stringstr size_t open = line.find('"') + 1; std::string_view include_name = line.substr(open, line.rfind('"') - open); - Asset *asset = asset_manager()->get_file(std::string(include_name), SHADER); + Asset *asset = asset_manager()->get(std::string(include_name), SHADER); if (asset->type != ASSET_VOID) { std::stringstream include_source; @@ -442,37 +442,16 @@ auto Shader::bind(RenderShader *shader, Engine *engine, Object *object, mat4x4 * shader->set_uniform("g_Color4", TYPE_VEC4, glm::value_ptr(object->color4)); } -#ifdef HAVE_AUDIO - if (engine->audio_enabled) - { - engine->vis->update(); - - glUniform1fv(shader->get_uniform_location("g_AudioSpectrum64Right"), 64, engine->vis->bars_right.data()); - glUniform1fv(shader->get_uniform_location("g_AudioSpectrum64Left"), 64, engine->vis->bars_left.data()); + static const std::array<f32, 64> empty_bars = {}; - glUniform1fv(shader->get_uniform_location("g_AudioSpectrum32Right"), 32, engine->vis->bars_32_right.data()); - glUniform1fv(shader->get_uniform_location("g_AudioSpectrum32Left"), 32, engine->vis->bars_32_left.data()); + glUniform1fv(shader->get_uniform_location("g_AudioSpectrum64Left"), 64, empty_bars.data()); + glUniform1fv(shader->get_uniform_location("g_AudioSpectrum64Right"), 64, empty_bars.data()); - glUniform1fv(shader->get_uniform_location("g_AudioSpectrum16Right"), 16, engine->vis->bars_16_right.data()); - glUniform1fv(shader->get_uniform_location("g_AudioSpectrum16Left"), 16, engine->vis->bars_16_left.data()); - } - else - { -#else - static std::array<f32, 64> empty_bars = { }; + glUniform1fv(shader->get_uniform_location("g_AudioSpectrum32Left"), 32, empty_bars.data()); + glUniform1fv(shader->get_uniform_location("g_AudioSpectrum32Right"), 32, empty_bars.data()); - glUniform1fv(shader->get_uniform_location("g_AudioSpectrum64Left"), 64, empty_bars.data()); - glUniform1fv(shader->get_uniform_location("g_AudioSpectrum64Right"), 64, empty_bars.data()); - - glUniform1fv(shader->get_uniform_location("g_AudioSpectrum32Left"), 32, empty_bars.data()); - glUniform1fv(shader->get_uniform_location("g_AudioSpectrum32Right"), 32, empty_bars.data()); - - glUniform1fv(shader->get_uniform_location("g_AudioSpectrum16Left"), 16, empty_bars.data()); - glUniform1fv(shader->get_uniform_location("g_AudioSpectrum16Right"), 16, empty_bars.data()); -#endif -#ifdef HAVE_AUDIO - } -#endif + glUniform1fv(shader->get_uniform_location("g_AudioSpectrum16Left"), 16, empty_bars.data()); + glUniform1fv(shader->get_uniform_location("g_AudioSpectrum16Right"), 16, empty_bars.data()); } Shader::~Shader() diff --git a/src/shader.h b/src/shader.h index c3b2738..132b843 100644 --- a/src/shader.h +++ b/src/shader.h @@ -55,8 +55,8 @@ class Shader std::vector<Combo> combos; std::vector<Uniform *> uniforms; - std::array<std::string, MAX_TEXTURES> textures = { }; - std::array<std::string, MAX_TEXTURES> texture_combos = { }; + std::array<std::string, MAX_TEXTURES> textures = {}; + std::array<std::string, MAX_TEXTURES> texture_combos = {}; u32 texture_count = 0; @@ -5,6 +5,8 @@ extern "C" { #include <al/types.h> } +#include "log.h" + #undef array #include <array> #include <vector> @@ -13,8 +15,6 @@ extern "C" { #include <algorithm> #include <cmath> -#include "log.h" - // Pause after every pass. //#define FRAME_STEP diff --git a/src/vis.cc b/src/vis.cc deleted file mode 100644 index 062bb62..0000000 --- a/src/vis.cc +++ /dev/null @@ -1,292 +0,0 @@ -#include "vis.h" - -using namespace Mauri; - -static const f32 gausian_array[] = {0.242f, 0.399f, 0.242f}; - -auto Visualizer::calc_cutoff() -> void -{ - f64 freqconst = std::log10(freq_cap_low / (f64)freq_cap_high) / ((1.0 / (BAR_COUNT + 1.0)) - 1.0); - - for (s32 i = 0; i <= BAR_COUNT; i++) - { - freqconst_per_bin[i] = freq_cap_high * std::pow(10.0, - (freqconst * -1) + (((i + 1.0) / (BAR_COUNT + 1.0)) * freqconst)); - - f64 freq = freqconst_per_bin[i] / (sample_rate / 2.0); - - cutoff_low[i] = std::floor(freq * (sample_count / 4.0)); - - if (i == 0) continue; - - if (cutoff_low[i] <= cutoff_low[i - 1]) - { - cutoff_low[i] = cutoff_low[i - 1] + 1; - } - - cutoff_high[i - 1] = cutoff_low[i - 1]; - } -} - -auto Visualizer::gaussian(f32 *bars) -> void -{ - for (s32 i = 1; i < BAR_COUNT - 1; i++) - { - bars[i] = bars[i - 1] * gausian_array[0] + bars[i] * gausian_array[1] + bars[i + 1] * gausian_array[2]; - } -} - -auto Visualizer::monstercat_smoothing(f32 *bars) -> void -{ - std::array<f32, BAR_COUNT> smoothing_factors; - - for (s32 i = 0; i < BAR_COUNT; i++) - { - smoothing_factors[i] = std::pow(1.5, i); - } - - for (s32 i = 1; i < BAR_COUNT; i++) - { - for (s32 j = 0; j < BAR_COUNT; j++) - { - if (i == j) continue; - f32 weighted = bars[i] / smoothing_factors[std::abs(i - j)]; - if (bars[j] < weighted) - { - bars[j] = weighted; - } - } - } -} - -auto Visualizer::update_bars(f32 *bars, f32 *bars_32, f32 *bars_16, f32 *bars_falloff, fftw_complex *out) -> void -{ - for (s32 i = 0; i < BAR_COUNT; i++) - { - f64 magnitude = 0.0; - - s32 low = floor(cutoff_low[i]); - s32 high = floor(cutoff_high[i]); - - for (s32 s = low; s <= high && s < (sample_count / 2); ++s) - { - magnitude += std::sqrt((out[s][0] * out[s][0]) + (out[s][1] * out[s][1])); - } - - f32 *bar; - - if (i < BAR_COUNT / 2) bar = &bars[((BAR_COUNT / 2) - 1) - i]; - else bar = &bars[i]; - - *bar = magnitude / (cutoff_high[i] - cutoff_low[i] + 1.f); - *bar *= std::log2(2 + i) * (100.0 / BAR_COUNT); - *bar = std::pow(*bar, 0.5); - - f32 falloff_value = std::min(bars_falloff[i] * 0.945f, bars_falloff[i] - 1.f); - - bars_falloff[i] = std::max(falloff_value, *bar); - } - - monstercat_smoothing(bars_falloff); - - for (s32 i = 0; i < BAR_COUNT; i++) - { - bars[i] = bars_falloff[i] / 2500.f; - } - - const s32 scale_32 = BAR_COUNT / 32; - - for (s32 i = 0; i < 32; i++) - { - s32 s = i * scale_32; - bars_32[i] = 0.f; - for (s32 j = 0; j < scale_32; j++) - { - bars_32[i] += bars[s + j]; - } - bars_32[i] /= (f32)scale_32; - } - - const s32 scale_16 = BAR_COUNT / 16; - - for (s32 i = 0; i < 16; i++) - { - s32 s = i * scale_16; - bars_16[i] = 0.f; - for (s32 j = 0; j < scale_16; j++) - { - bars_16[i] += bars[s + j]; - } - bars_16[i] /= (f32)scale_16; - } -} - -auto Visualizer::update() -> void -{ - if (this->sample_processed) return; - - g_mutex_lock(&this->mutex); - - if (!this->sample) - { - g_mutex_unlock(&this->mutex); - return; - } - - GstBuffer *buffer = gst_sample_get_buffer(sample); - - GstMapInfo info; - gst_buffer_map(buffer, &info, GST_MAP_READ); - - Sample *samples = (Sample *)(info.data); - - for (s32 i = 0; i < sample_count; i++) - { - in_left[i] = (f64)samples[i].left; - in_right[i] = (f64)samples[i].right; - } - - fftw_execute(this->plan_left); - fftw_execute(this->plan_right); - - update_bars(this->bars_left.data(), this->bars_32_left.data(), - this->bars_16_left.data(), this->bars_left_falloff.data(), this->out_left); - update_bars(this->bars_right.data(), this->bars_32_right.data(), - this->bars_16_right.data(), this->bars_right_falloff.data(), this->out_right); - - gst_buffer_unmap(buffer, &info); - - this->sample_processed = true; - - g_mutex_unlock(&this->mutex); -} - -auto Visualizer::update_sample() -> void -{ - GstSample *sample; - g_signal_emit_by_name(this->appsink, "pull-sample", &sample); - - if (this->sample) - { - gst_sample_unref(this->sample); - } - else - { - GstBuffer *buffer = gst_sample_get_buffer(sample); - - GstCaps *caps = gst_sample_get_caps(sample); - GstStructure *structure = gst_caps_get_structure(caps, 0); - gst_structure_get_int(structure, "rate", &this->sample_rate); - - gst_caps_unref(caps); - - this->sample_count = gst_buffer_get_size(buffer) / sizeof(Sample); - - this->in_left = (f64 *)fftw_malloc(sizeof(f64) * this->sample_count); - this->in_right = (f64 *)fftw_malloc(sizeof(f64) * this->sample_count); - - this->out_left = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * this->sample_count); - this->out_right = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * this->sample_count); - - memset(this->out_left, 0, sizeof(fftw_complex) * this->sample_count); - memset(this->out_right, 0, sizeof(fftw_complex) * this->sample_count); - - this->calc_cutoff(); - - this->plan_left = fftw_plan_dft_r2c_1d(this->sample_count, this->in_left, this->out_left, FFTW_ESTIMATE); - this->plan_right = fftw_plan_dft_r2c_1d(this->sample_count, this->in_right, this->out_right, FFTW_ESTIMATE); - } - - this->sample = sample; - this->sample_processed = false; -} - -static auto sample_callback(GstElement *appsink, gpointer *data) -> GstFlowReturn -{ - Visualizer *vis = (Visualizer *)data; - - g_mutex_lock(&vis->mutex); - vis->update_sample(); - g_mutex_unlock(&vis->mutex); - - return GST_FLOW_OK; -} - -/* -static auto main_thread(void *data) -> void * -{ - Visualizer *vis = (Visualizer *)data; - - GstMessageType filter = (GstMessageType)(GST_MESSAGE_ERROR | GST_MESSAGE_EOS); - GstMessage *msg = gst_bus_timed_pop_filtered(vis->bus, GST_CLOCK_TIME_NONE, filter); - - if (!msg) return 0; - - switch (msg->type) - { - case GST_MESSAGE_ERROR: - error("gstreamer pipeline died, audio won't work"); - break; - default: - break; - } - - gst_message_unref(msg); - - return 0; -} -*/ - -auto Visualizer::run() -> bool -{ - g_mutex_init(&this->mutex); - - this->pipeline = gst_pipeline_new(nullptr); - - this->pulsesrc = gst_element_factory_make("pulsesrc", nullptr); - this->appsink = gst_element_factory_make("appsink", nullptr); - - if (this->pulsesrc == nullptr || this->appsink == nullptr) - { - error("failed to create gstreamer pipeline"); - return false; - } - - g_object_set(this->appsink, "emit-signals", TRUE, nullptr); - - gst_bin_add_many(GST_BIN(this->pipeline), this->pulsesrc, this->appsink, nullptr); - gst_element_link(this->pulsesrc, this->appsink); - - gst_element_set_state(this->pipeline, GST_STATE_PLAYING); - - this->signal_handler = g_signal_connect(this->appsink, "new-sample", G_CALLBACK(sample_callback), this); - - //this->bus = gst_pipeline_get_bus(GST_PIPELINE(this->pipeline)); - //this->thread = g_thread_new(nullptr, main_thread, this); - - return true; -} - -Visualizer::~Visualizer() -{ - /* - gst_bus_post(this->bus, gst_message_new_eos(GST_OBJECT(this->pipeline))); - g_thread_join(this->thread); - gst_object_unref(this->bus); - */ - - g_signal_handler_disconnect(this->appsink, this->signal_handler); - - //gst_element_set_state(this->pipeline, GST_STATE_NULL); - //gst_element_get_state(this->pipeline, nullptr, nullptr, GST_CLOCK_TIME_NONE); - //gst_object_unref(this->pipeline); - - if (this->sample) gst_sample_unref(this->sample); - - if (this->in_left) fftw_free(this->in_left); - if (this->in_right) fftw_free(this->in_right); - if (this->out_left) fftw_free(this->out_left); - if (this->out_right) fftw_free(this->out_right); - - g_mutex_clear(&this->mutex); -} diff --git a/src/vis.h b/src/vis.h deleted file mode 100644 index 5d8f38c..0000000 --- a/src/vis.h +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef _VISUALIZER_H -#define _VISUALIZER_H - -#include <gst/gst.h> -#include <fftw3.h> -#include <atomic> - -#include "util.h" - -#define BAR_COUNT 64 - -namespace Mauri -{ - -struct Sample -{ - s16 left; - s16 right; -}; - -class Visualizer -{ - public: - Visualizer() {} - ~Visualizer(); - - std::array<f32, 16> bars_16_left; - std::array<f32, 16> bars_16_right; - - std::array<f32, 32> bars_32_left; - std::array<f32, 32> bars_32_right; - - std::array<f32, BAR_COUNT> bars_left = { }; - std::array<f32, BAR_COUNT> bars_right = { }; - - std::array<f32, BAR_COUNT> bars_left_falloff = { }; - std::array<f32, BAR_COUNT> bars_right_falloff = { }; - - GMutex mutex; - - GstBus *bus; - GstElement *pipeline; - - auto update() -> void; - auto update_sample() -> void; - - auto run() -> bool; - - private: - GstElement *pulsesrc; - GstElement *appsink; - - GThread *thread; - - gulong signal_handler; - - GstSample *sample = nullptr; - std::atomic<bool> sample_processed = false; - - f64 *in_left = nullptr; - f64 *in_right = nullptr; - - fftw_plan plan_left; - fftw_plan plan_right; - - fftw_complex *out_left = nullptr; - fftw_complex *out_right = nullptr; - - std::array<f32, BAR_COUNT + 1> cutoff_low = { }; - std::array<f32, BAR_COUNT + 1> cutoff_high = { }; - std::array<f32, BAR_COUNT + 1> freqconst_per_bin = { }; - - u32 freq_cap_low = 20; - u32 freq_cap_high = 25000; - - s32 sample_rate; - s32 sample_count; - - auto calc_cutoff() -> void; - auto gaussian(f32 *bars) -> void; - auto monstercat_smoothing(f32 *bars) -> void; - auto update_bars(f32 *bars, f32 *bars_32, f32 *bars_16, f32 *bars_falloff, fftw_complex *out) -> void; -}; - -} // namespace Mauri - -#endif // _VISUALIZER_H |