Added GLSL sampling modes

This commit is contained in:
Jarcode
2019-03-09 14:52:38 -08:00
parent f87c70af2b
commit 5fdf0545a8
2 changed files with 47 additions and 6 deletions

View File

@@ -13,10 +13,25 @@
- circular heavily rounded points - circular heavily rounded points
- sinusoidal rounded at both low and high weighted values - sinusoidal rounded at both low and high weighted values
like a sine wave like a sine wave
- linear not rounded at all, just use linear distance - linear not rounded at all; linear distance
*/ */
#define ROUND_FORMULA sinusoidal #define ROUND_FORMULA sinusoidal
/* The sampling mode for processing raw FFT input:
- average averages all the inputs in the sample range for
a given point. Produces smooth output, but peaks
are not well represented
- maximum obtains the best value from the closest peak in
the sample range. Very accurate peaks, but
output is jagged and sporadic.
- hybrid uses the results from both `average` and `maximum`
with the weight provided in `SAMPLE_HYBRID_WEIGHT` */
#define SAMPLE_MODE average
/* Weight should be provided in the range (0, 1). Higher values favour
averaged results. `hybrid` mode only. */
#define SAMPLE_HYBRID_WEIGHT 0.65
/* Factor used to scale frequencies. Lower values allows lower /* Factor used to scale frequencies. Lower values allows lower
frequencies to occupy more space. */ frequencies to occupy more space. */
#define SAMPLE_SCALE 8 #define SAMPLE_SCALE 8

View File

@@ -21,6 +21,10 @@
/* take value x that scales linearly between [0, 1) and return its circlar curve */ /* take value x that scales linearly between [0, 1) and return its circlar curve */
#define circular(x) sqrt(1 - (((x) - 1) * ((x) - 1))) #define circular(x) sqrt(1 - (((x) - 1) * ((x) - 1)))
#define average 0
#define maximum 1
#define hybrid 2
float scale_audio(float idx) { float scale_audio(float idx) {
return -log((-(SAMPLE_RANGE) * idx) + 1) / (SAMPLE_SCALE); return -log((-(SAMPLE_RANGE) * idx) + 1) / (SAMPLE_SCALE);
} }
@@ -32,20 +36,42 @@ float iscale_audio(float idx) {
/* Note: the SMOOTH_FACTOR macro is defined by GLava itself, from `#request setsmoothfactor`*/ /* Note: the SMOOTH_FACTOR macro is defined by GLava itself, from `#request setsmoothfactor`*/
float smooth_audio(in sampler1D tex, int tex_sz, highp float idx) { float smooth_audio(in sampler1D tex, int tex_sz, highp float idx) {
#if PRE_SMOOTHED_AUDIO < 1 #if PRE_SMOOTHED_AUDIO < 1
float float
smin = scale_audio(clamp(idx - SMOOTH_FACTOR, 0, 1)) * tex_sz, smin = scale_audio(clamp(idx - SMOOTH_FACTOR, 0, 1)) * tex_sz,
smax = scale_audio(clamp(idx + SMOOTH_FACTOR, 0, 1)) * tex_sz, smax = scale_audio(clamp(idx + SMOOTH_FACTOR, 0, 1)) * tex_sz;
avg = 0, s, weight = 0; float m = ((smax - smin) / 2.0F), s, w;
float m = ((smax - smin) / 2.0F);
float rm = smin + m; /* middle */ float rm = smin + m; /* middle */
#if SAMPLE_MODE == average
float avg = 0, weight = 0;
for (s = smin; s <= smax; s += 1.0F) { for (s = smin; s <= smax; s += 1.0F) {
float w = ROUND_FORMULA(clamp((m - abs(rm - s)) / m, 0, 1)); w = ROUND_FORMULA(clamp((m - abs(rm - s)) / m, 0, 1));
weight += w; weight += w;
avg += texelFetch(tex, int(round(s)), 0).r * w; avg += texelFetch(tex, int(round(s)), 0).r * w;
} }
avg /= weight; avg /= weight;
return avg; return avg;
#elif SAMPLE_MODE == hybrid
float vmax = 0, avg = 0, weight = 0, v;
for (s = smin; s < smax; s += 1.0F) {
w = ROUND_FORMULA(clamp((m - abs(rm - s)) / m, 0, 1));
weight += w;
v = texelFetch(tex, int(round(s)), 0).r * w;
avg += v;
if (vmax < v)
vmax = v;
}
return (vmax * (1 - SAMPLE_HYBRID_WEIGHT)) + ((avg / weight) * SAMPLE_HYBRID_WEIGHT);
#elif SAMPLE_MODE == maximum
float vmax = 0, v;
for (s = smin; s < smax; s += 1.0F) {
w = texelFetch(tex, int(round(s)), 0).r * ROUND_FORMULA(clamp((m - abs(rm - s)) / m, 0, 1));
if (vmax < w)
vmax = w;
}
return vmax;
#endif
#else #else
return texelFetch(tex, int(round(idx * tex_sz)), 0).r; return texelFetch(tex, int(round(idx * tex_sz)), 0).r;
#endif #endif