1+ #version 330
2+
3+ // Emulate the "line style" spectrum analyzer from Winamp 2.
4+ // Try this config for a demonstration:
5+
6+ /*
7+ [general]
8+ bar_width = 2
9+ bar_spacing = 0
10+ higher_cutoff_freq = 22000
11+
12+ [output]
13+ method = sdl_glsl
14+ channels = mono
15+ fragment_shader = winamp_line_style_spectrum.frag
16+
17+ [color]
18+ background = '#000000'
19+ gradient = 1
20+ gradient_color_1 = '#319C08'
21+ gradient_color_2 = '#29CE10'
22+ gradient_color_3 = '#BDDE29'
23+ gradient_color_4 = '#DEA518'
24+ gradient_color_5 = '#D66600'
25+ gradient_color_6 = '#CE2910'
26+
27+ [smoothing]
28+ noise_reduction = 10
29+ */
30+
31+ in vec2 fragCoord;
32+ out vec4 fragColor;
33+
34+ // bar values. defaults to left channels first (low to high), then right (high to low).
35+ uniform float bars[512 ];
36+
37+ uniform int bars_count; // number of bars (left + right) (configurable)
38+ uniform int bar_width; // bar width (configurable), not used here
39+ uniform int bar_spacing; // space bewteen bars (configurable)
40+
41+ uniform vec3 u_resolution; // window resolution
42+
43+ // colors, configurable in cava config file (r,g,b) (0.0 - 1.0)
44+ uniform vec3 bg_color; // background color
45+ uniform vec3 fg_color; // foreground color
46+
47+ uniform int gradient_count;
48+ uniform vec3 gradient_colors[8 ]; // gradient colors
49+
50+ vec3 normalize_C(float y,vec3 col_1, vec3 col_2, float y_min, float y_max)
51+ {
52+ // create color based on fraction of this color and next color
53+ float yr = (y - y_min) / (y_max - y_min);
54+ return col_1 * (1.0 - yr) + col_2 * yr;
55+ }
56+
57+ void main()
58+ {
59+ // find which bar to use based on where we are on the x axis
60+ float x = u_resolution.x * fragCoord.x;
61+ int bar = int (bars_count * fragCoord.x);
62+
63+ // calculate a bar size
64+ float bar_size = u_resolution.x / bars_count;
65+
66+ // the y coordinate is stretched by 4X to resemble Winamp
67+ float y = min (bars[bar] * 4.0 , 1.0 );
68+
69+ // make sure there is a thin line at bottom
70+ if (y * u_resolution.y < 1.0 )
71+ {
72+ y = 1.0 / u_resolution.y;
73+ }
74+
75+ vec4 bar_color;
76+
77+ if (gradient_count == 0 )
78+ {
79+ bar_color = vec4 (fg_color,1.0 );
80+ }
81+ else
82+ {
83+ // find color in the configured gradient for the top of the bar
84+ int color = int ((gradient_count - 1 ) * y);
85+
86+ // find where on y this and next color is supposed to be
87+ float y_min = float (color) / (gradient_count - 1.0 );
88+ float y_max = float (color + 1 ) / (gradient_count - 1.0 );
89+
90+ // make a solid color for the entire bar
91+ bar_color = vec4 (normalize_C(y, gradient_colors[color], gradient_colors[color + 1 ], y_min, y_max), 1.0 );
92+ }
93+
94+
95+ // draw the bar up to current height
96+ if (y > fragCoord.y)
97+ {
98+ // make some space between bars based on settings
99+ if (x > (bar + 1 ) * (bar_size) - bar_spacing)
100+ {
101+ fragColor = vec4 (bg_color,1.0 );
102+ }
103+ else
104+ {
105+ fragColor = bar_color;
106+ }
107+ }
108+ else
109+ {
110+ fragColor = vec4 (bg_color,1.0 );
111+ }
112+ }
0 commit comments