summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cross/x86_64-w64-mingw32.txt19
-rw-r--r--meson.build10
-rw-r--r--src/assets.cc29
-rw-r--r--src/assets.h11
-rw-r--r--src/context.h5
-rw-r--r--src/engine.cc16
-rw-r--r--src/engine.h7
-rw-r--r--src/mauri.cc64
-rw-r--r--src/objects/effect.cc2
-rw-r--r--src/objects/material.cc2
-rw-r--r--src/objects/model.cc2
-rw-r--r--src/objects/pass.cc2
-rw-r--r--src/objects/pass.h8
-rw-r--r--src/objects/scene.cc2
-rw-r--r--src/shader.cc41
-rw-r--r--src/shader.h4
-rw-r--r--src/util.h4
-rw-r--r--src/vis.cc292
-rw-r--r--src/vis.h87
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;
diff --git a/src/util.h b/src/util.h
index 6548a9b..1cad09d 100644
--- a/src/util.h
+++ b/src/util.h
@@ -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