summaryrefslogtreecommitdiff
path: root/gst/monoscope
diff options
context:
space:
mode:
authorStefan Sauer <ensonic@users.sf.net>2016-02-12 20:57:29 +0100
committerStefan Sauer <ensonic@users.sf.net>2016-02-12 21:01:03 +0100
commitaf29e7785890c7881dd8664eff894664a4c8174e (patch)
treefdb58feebba35df5a442d06e6b5a57fa541fcf16 /gst/monoscope
parent5e68873d22f2c24ca123f72d713ee4a3ae1279dd (diff)
monoscope: rework the scaling code
The running average was wrong and the resulting scaling factor was only held in place using the CLAMP. In addtion we are now convering quickly to volume changes. FInally now with this change, we can change the resolution defines and everythign adjusts.
Diffstat (limited to 'gst/monoscope')
-rw-r--r--gst/monoscope/monoscope.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/gst/monoscope/monoscope.c b/gst/monoscope/monoscope.c
index 90c012ba2..3500879c1 100644
--- a/gst/monoscope/monoscope.c
+++ b/gst/monoscope/monoscope.c
@@ -99,7 +99,7 @@ monoscope_update (struct monoscope_state *stateptr, gint16 data[convolver_big])
int hh1 = hh - 1;
guint32 *loc;
- int factor;
+ double factor;
int max = 1;
short *thisEq = stateptr->copyEq;
@@ -108,21 +108,26 @@ monoscope_update (struct monoscope_state *stateptr, gint16 data[convolver_big])
memset (stateptr->display, 0, scope_width * scope_height * sizeof (guint32));
for (i = 0; i < convolver_small; i++) {
- avg = thisEq[i] + (stateptr->avgEq[i] >> 1);
+ avg = (thisEq[i] + stateptr->avgEq[i]) >> 1;
stateptr->avgEq[i] = avg;
avg = abs (avg);
max = MAX (max, avg);
}
- stateptr->avgMax += max - (stateptr->avgMax >> 8);
- if (stateptr->avgMax < max)
- stateptr->avgMax = max; /* Avoid overflow */
- factor = 0x7fffffff / stateptr->avgMax;
- /* Keep the scaling sensible. */
- factor = CLAMP (factor, (1 << 8), (1 << 18));
+ /* running average, 4 values is enough to make it follow volume changes
+ * if this value is too large it will converge slowly
+ */
+ stateptr->avgMax += (max / 4) - (stateptr->avgMax / 4);
+
+ /* input is +/- avgMax, output is +/- hh */
+ if (stateptr->avgMax) {
+ factor = (gdouble) hh / stateptr->avgMax;
+ } else {
+ factor = 1.0;
+ }
for (i = 0; i < scope_width; i++) {
+ /* scale 16bit signed audio values to scope_height */
foo = stateptr->avgEq[i] * factor;
- foo >>= 18;
foo = CLAMP (foo, -hh1, hh1);
bar = (i + ((foo + hh) * scope_width));
if ((bar > 0) && (bar < (scope_width * scope_height))) {