gst/spectrum/gstspectrum.*: Implement a simple compensation algorithm for rounding...
authorSebastian Dröge <slomo@circular-chaos.org>
Mon, 19 Jan 2009 10:13:53 +0000 (10:13 +0000)
committerSebastian Dröge <slomo@circular-chaos.org>
Mon, 19 Jan 2009 10:13:53 +0000 (10:13 +0000)
Original commit message from CVS:
* gst/spectrum/gstspectrum.c: (gst_spectrum_reset_state),
(gst_spectrum_transform_ip):
* gst/spectrum/gstspectrum.h:
Implement a simple compensation algorithm for rounding errors.
This makes sure that a spectrum message is posted on the bus
every interval nanoseconds. Fixes bug #567955.

ChangeLog
gst/spectrum/gstspectrum.c
gst/spectrum/gstspectrum.h

index 982cab3..e3f519d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2009-01-19  Sebastian Dröge  <sebastian.droege@collabora.co.uk>
+
+       * gst/spectrum/gstspectrum.c: (gst_spectrum_reset_state),
+       (gst_spectrum_transform_ip):
+       * gst/spectrum/gstspectrum.h:
+       Implement a simple compensation algorithm for rounding errors.
+       This makes sure that a spectrum message is posted on the bus
+       every interval nanoseconds. Fixes bug #567955.
+
 2009-01-15  Michael Smith <msmith@songbirdnest.com>
 
        * sys/osxaudio/Makefile.am:
index 10ada12..15d3592 100644 (file)
@@ -278,6 +278,8 @@ gst_spectrum_reset_state (GstSpectrum * spectrum)
 
   spectrum->num_frames = 0;
   spectrum->num_fft = 0;
+
+  spectrum->accumulated_error = 0;
 }
 
 static void
@@ -505,10 +507,12 @@ gst_spectrum_transform_ip (GstBaseTransform * trans, GstBuffer * buffer)
     spectrum->fft_ctx = gst_fft_f32_new (nfft, FALSE);
     spectrum->frames_per_interval =
         gst_util_uint64_scale (spectrum->interval, rate, GST_SECOND);
+    spectrum->error_per_interval = (spectrum->interval * rate) % GST_SECOND;
     if (spectrum->frames_per_interval == 0)
       spectrum->frames_per_interval = 1;
     spectrum->num_frames = 0;
     spectrum->num_fft = 0;
+    spectrum->accumulated_error = 0;
   }
 
   if (spectrum->num_frames == 0)
@@ -559,7 +563,12 @@ gst_spectrum_transform_ip (GstBaseTransform * trans, GstBuffer * buffer)
      * FFT of frames that we already handled.
      */
     if (spectrum->num_frames % nfft == 0 ||
-        spectrum->num_frames == spectrum->frames_per_interval) {
+        ((spectrum->accumulated_error < GST_SECOND
+                && spectrum->num_frames == spectrum->frames_per_interval)
+            || (spectrum->accumulated_error >= GST_SECOND
+                && spectrum->num_frames - 1 ==
+                spectrum->frames_per_interval))) {
+
       for (i = 0; i < nfft; i++)
         input_tmp[i] = input[(spectrum->input_pos + i) % nfft];
 
@@ -586,7 +595,16 @@ gst_spectrum_transform_ip (GstBaseTransform * trans, GstBuffer * buffer)
     }
 
     /* Do we have the FFTs for one interval? */
-    if (spectrum->num_frames == spectrum->frames_per_interval) {
+    if ((spectrum->accumulated_error < GST_SECOND
+            && spectrum->num_frames == spectrum->frames_per_interval)
+        || (spectrum->accumulated_error >= GST_SECOND
+            && spectrum->num_frames - 1 == spectrum->frames_per_interval)) {
+
+      if (spectrum->accumulated_error >= GST_SECOND)
+        spectrum->accumulated_error -= GST_SECOND;
+      else
+        spectrum->accumulated_error += spectrum->error_per_interval;
+
       if (spectrum->message) {
         GstMessage *m;
 
index cd42360..28cbb09 100644 (file)
@@ -62,6 +62,9 @@ struct _GstSpectrum
   gfloat *spect_magnitude;
   gfloat *spect_phase;
   GstFFTF32 *fft_ctx;
+
+  guint64 error_per_interval;
+  guint64 accumulated_error;
 };
 
 struct _GstSpectrumClass