summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--gst/spectrum/gstspectrum.c22
-rw-r--r--gst/spectrum/gstspectrum.h3
3 files changed, 32 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 982cab3c..e3f519d3 100644
--- 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:
diff --git a/gst/spectrum/gstspectrum.c b/gst/spectrum/gstspectrum.c
index 10ada123..15d3592e 100644
--- a/gst/spectrum/gstspectrum.c
+++ b/gst/spectrum/gstspectrum.c
@@ -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;
diff --git a/gst/spectrum/gstspectrum.h b/gst/spectrum/gstspectrum.h
index cd42360f..28cbb09a 100644
--- a/gst/spectrum/gstspectrum.h
+++ b/gst/spectrum/gstspectrum.h
@@ -62,6 +62,9 @@ struct _GstSpectrum
gfloat *spect_magnitude;
gfloat *spect_phase;
GstFFTF32 *fft_ctx;
+
+ guint64 error_per_interval;
+ guint64 accumulated_error;
};
struct _GstSpectrumClass