jarcode-foss / glava

GLava - OpenGL audio spectrum visualizer
GNU General Public License v3.0
1.17k stars 58 forks source link

MPD support & UI features #39

Closed jarcode-foss closed 6 years ago

jarcode-foss commented 6 years ago

I am wondering if anyone is interested in GLava being an MPD client. I can simply add support for MPD as audio input, but the following features are a possibility as well:

Most of the above features will warrant a large amount of code for font rendering and other UI elements. Since I want this to be heavily configurable and exposed to the users, I do not want to do this in pure C. Some options are:

I have been pondering the idea for some time and thought it's probably best to ask for feedback before I start making rapid changes to the respository. Any input (including support for this kind of feature/extension) would be appreciated.

mmhobi7 commented 6 years ago

I thought of something similar, and used conky to reproduce it for album cover color, i resize the image to 1x1 and then take it's color rather than use the album's color, I switched to using the wallpaper's average color. Unity sets the theme color to this by default so the color of glava would match with the systems theme color

but then I thought, why match the color, so rather than match the color I find the opposite color and increase it's saturation to 100 (as to not wash out the color)

What if i'm running youtube, or not music but something else, there isn't an album's color to take, or text to display

The album cover is blown out due to a bug in conky, for which the pull request has never been accepted and I have not rebuilt it with the patch yet

Your idea is to change to radial and then place the album cover in that, or to take what I have and move it down to the left of bars as an overlay (ontop of bars), correct?

Getting the album image and song title is pretty hard, I had to revert to referencing spotify directly like: playing_album = os.popen("dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get string:org.mpris.MediaPlayer2.Player string:Metadata | sed -n \'/album\"/{n;p}\' | cut -d \'\"\' -f 2| cut -d' ' -f-6 | tr -d '\n'").read()

screenshot from 2018-03-24 19-19-13 screenshot from 2018-03-24 19-19-40 screenshot from 2018-03-24 19-20-23 screenshot from 2018-03-24 19-20-52

extra one: average color plus 50% more saturation screenshot from 2018-03-24 19-22-34

jarcode-foss commented 6 years ago

@Aaahh getting the album image via MPD is fairly easy -- I am not sure about other services, though.

Your idea is to change to radial and then place the album cover in that

For radial and perhaps circle, yes. Of course, the ability to render and position the current album art would simply be a feature exposed by the native code in GLava, so nothing would stop the user from altering the modules themselves without needing to recompile GLava itself.

or to take what I have and move it down to the left of bars as an overlay (ontop of bars), correct?

As an overlay, or making space for the album art by shifting over the bars to the left/right, respective of the artwork's position.

Is the visualizer around the artwork in your screenshots provided by GLava? Could you possibly share your configuration?

mmhobi7 commented 6 years ago

The visualizer is a YouTube video playing in the background It’s a video from “chill nation” As for the artwork, I’d assume it’s a low quality image that passed in

jarcode-foss commented 6 years ago

@Aaahh I'll probably re-create that visualizer for fun.

mmhobi7 commented 6 years ago

I think they use a sin wave, and it’s only for bass (lower end of soectrum) https://dribbble.com/shots/3135607-Motion-Audio-Spectrum https://dribbble.com/shots/3984630-Music-Player https://dribbble.com/shots/4381145-Magic-Wave-and-pops https://dribbble.com/shots/4356933-The-Chainsmokers-Break-Up-Every-Night-Visuals-MDNO-Euro-18

jarcode-foss commented 6 years ago

@Aaahh yeah, I'm not sure why some visualizers only use the lowest end of the spectrum -- doesn't look as appealing. Using less averaging and gravity also looks interesting, perhaps I should look at changing the defaults for some modules.

But since I've added alpha blending now, I have quite a few options for cool effects that I haven't tried to play with in GLSL. The idea of taking two radial-style visualizers and stacking them with different frequency windows is really cool, too.

I think they use a sin wave

So does GLava (by default) for FFT output. See #define ROUND_FORMULA sinusoidal in smooth_parameters.glsl. It can also use more pointed peaks (linear), or rounded peaks (circular), but sinusoidal waves are generally the most appealing since they blend nicely with adjacent peaks.

jpope777 commented 6 years ago

To be honest, the reason I even came across GLava was that I was looking for a way to add an audio visualizer to my mpd album cover conky that I created many, many years ago.

I like the idea. :+1:

EDIT: Current screenshot with GLava active behind my conky (top left corner, click image for full view): Link

jarcode-foss commented 6 years ago

@jpope777 I was planning on making the bar and graph modules display information that is very similar to what you have in your screenshot.

I think I will follow through with this using Lua. Using GLSL preprocessor directives for drawing code will get incredibly messy, so I will change GLava's behaviour to do the following:

Things that I am still considering:

jarcode-foss commented 6 years ago

I will probably start on the features mentioned on this issue in a couple weeks. I am currently enjoying the remainder of the skii season here, so my time for contributions doesn't permit me to work on this just yet.

mmhobi7 commented 6 years ago

https://dribbble.com/shots/4356853-Wallpaper-Siri-by-Apple

jarcode-foss commented 6 years ago

The two referenced commits add ~600 lines of font rendering code to a file called ui.c. It has a sizable interface in ui.h. I plan to expose a bunch of rendering primitives in this code later via a ui_lua.c file.

At the moment I only plan to add fonts, texture boxes, and some other primitives. Interaction with any of the UI is still being considered, and I will implement it later if it seems worthwhile (will require modifications to the wcb code for interaction events).

Fonts are currently fixed sized and cached in OpenGL textures. This will have a pretty big impact on memory usage, so I will definately have an option to disable the UI code altogether.

Some wheels are being reinvented here -- the other option was to use a UI toolkit (GTK, Qt) and embed the OpenGL context in the window, but I had a few concerns doing this:

This code is being ported from one of my incomplete private projects, and I'm just pushing progress at the moment (nothing is finished). I had some free time so I thought I would get started.

jarcode-foss commented 6 years ago

Looks like I was able to get things working faster than I expected (note the translucent box and font rendering the in the blue glava window):

The scripting portion that can be used in modules comes next (using Lua).

jarcode-foss commented 6 years ago

Some progress:

This is just a sample of what MPD strings might look like and what the rendering code within the module looks like (it's pretty simple to use!).

mmhobi7 commented 6 years ago

When do we get that gradient bars lol

jarcode-foss commented 6 years ago

@Aaahh you can already specify gradials in the relevant .glsl files for most modules with some simple openGL code. The bars.glsl file in my personal configuration uses the following code to produce the gradient on my desktop:

/* right color offset */
#define RCOL_OFF (gl_FragCoord.x / 3000)
/* left color offset */
#define LCOL_OFF ((screen.x - gl_FragCoord.x) / 3000)
/* vertical color step */
#define LSTEP (d / 170)
/* Bar color */
#define COLOR vec4((0.2 + RCOL_OFF) + LSTEP, max(0.3 - LSTEP, 0.08), (0.15 + LCOL_OFF) - (LSTEP * 0.5), 1)

It's a bit crude (I'm not actually blending two colors), but you can make it look much nicer. I also have added custom hexidecimal color specifies that expand #ffffff syntax to vec4(1.0, 1.0, 1.0, 1.0).

mmhobi7 commented 6 years ago

So I came up with the idea of an overlay, and editing the "background" (everything since the glava would be ontop) so that for example the bars are inversing the color of the display and acting on the windows (visually anyway), This could be done by exposing what's behind glava (through xroot) so that the shader can act on it.

jarcode-foss commented 6 years ago

@Aaahh xroot only reads the background pixbuf of the root window, which is generally the desktop background for most window managers. Using a screen capture will not work since it will include GLava itself, rather than the contents behind the window. Obtaining the contents of all the windows via xcomposite and reconstructing the desktop is the only way to obtain layered image data from the X server, which will be incredibly slow and would essentially be re-implementing what the compositor does.

These kinds of effects are the responsibility of the compositor, not the application. You can do some interesting things (ab)using premultiplied alpha values in X, but that's about it.

jarcode-foss commented 6 years ago

Just an update, unstable still contains the code for this (although needs some merging with master), but I'm not completely sure if I should move forward with support for this. I need to optimize a lot of the font-rendering (reduce draw calls), and I can't help that a lot of wheel-reinventing is going on here.

I'm also having second thoughts about whether this goes beyond GLava's scope. Maybe a separate window should contain this functionality?

mmhobi7 commented 6 years ago

I mean song name and title is kind of standard, but I guess that should be dond by open gl? Honestly I feel like all these issues come from not being able to pass variables (like color or song name) to open gl. And play and pause

Glava can expand, I don’t think we should be drawing so many window layers

As for the Wheel, I agree and if you see anything that could be used, we could just import it

It could be like modular, where there’s programs and we can refecnce them or addons, and the addons can all independently stand by themselves (like glava) but they also combined onto one render window (a bit far feteched I admit)

jarcode-foss commented 6 years ago

I mean song name and title is kind of standard, but I guess that should be dond by open gl? Honestly I feel like all these issues come from not being able to pass variables (like color or song name) to open gl.

The renderer itself really isn't configurable in that sense and the only 'passing' that occurs is through GLSL, which isn't the entirety of OpenGL. These kinds of displays on the desktop have no need to be drawn with graphics acceleration (low repaint frequency) and might be better suited to a project like Conky.

mmhobi7 commented 6 years ago

Conky doesn’t follow our window rules but yeah I see what your saying

Heck why don’t I fork and become the new conky with graphics acceleration

jarcode-foss commented 6 years ago

@Aaahh there's no need for Conky to have graphics acceleration. Also, if dedicated desktop windows don't behave that well in Conky, I can PR changes in from GLava. Conky does drawing a little differently since it can get away with drawing directly on the root window, where OpenGL contexts can't be instantiated.

jarcode-foss commented 6 years ago

Closing for the time being.