After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 517813 - [audioconvert] make gap aware
[audioconvert] make gap aware
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-base
git master
Other Linux
: Normal enhancement
: 0.10.20
Assigned To: Stefan Sauer (gstreamer, gtkdoc dev)
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2008-02-21 08:02 UTC by Stefan Sauer (gstreamer, gtkdoc dev)
Modified: 2008-04-03 15:21 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
make audioconvert gap aware (3.90 KB, patch)
2008-02-21 08:16 UTC, Stefan Sauer (gstreamer, gtkdoc dev)
needs-work Details | Review
modified controller test to try the gap handling (3.20 KB, text/plain)
2008-02-21 08:16 UTC, Stefan Sauer (gstreamer, gtkdoc dev)
  Details
make audioconvert gap aware (5.29 KB, patch)
2008-02-25 13:08 UTC, Stefan Sauer (gstreamer, gtkdoc dev)
none Details | Review
make audioconvert gap aware (4.54 KB, patch)
2008-02-25 13:48 UTC, Stefan Sauer (gstreamer, gtkdoc dev)
none Details | Review
audioconvert-gap-aware.diff (3.34 KB, patch)
2008-03-18 14:28 UTC, Sebastian Dröge (slomo)
committed Details | Review

Description Stefan Sauer (gstreamer, gtkdoc dev) 2008-02-21 08:02:48 UTC
Audioconvert should try to skip processing GAP buffers.
Comment 1 Stefan Sauer (gstreamer, gtkdoc dev) 2008-02-21 08:16:10 UTC
Created attachment 105681 [details] [review]
make audioconvert gap aware

There is a GST_INFO in gstaudioqauntize still. The code that checks if the noiseshapingconverged to silence currently uses:
if (fabs(ctx->error_buf[i]) < 0.000001)
instead of
if (ctx->error_buf[i] == 0.0)

This indicates that the values never really become 0.0 and looking at the noiseshaping formulas it becomes clear why. Now there is a problem called denormals. CPUs switch to different istructions when processing close to zero values and those are slow. If we don't need the precission, its better to clamp them to zero. There is a good articel here:
http://www.musicdsp.org/showone.php?id=51
Comment 2 Stefan Sauer (gstreamer, gtkdoc dev) 2008-02-21 08:16:59 UTC
Created attachment 105682 [details]
modified controller test to try the gap handling
Comment 3 Stefan Sauer (gstreamer, gtkdoc dev) 2008-02-21 12:27:41 UTC
The check was the wrong way around. below its corrected. I also added checking for denormals, but this is not the issue. I get exponents ranging from 997 to 1008, but not 0. It seems that the noise will not converge to digital silence. Thus if noise-shaping is used, I don't need to check the history to mark as GAP. There won't be silence.

for (i=0; i<(ctx->out.channels * size); i++) {
  if (ctx->error_buf[i] != 0.0) {
    // http://steve.hollasch.net/cgindex/coding/ieeefloat.html
    // for denormals the exponent would become all zero
    GST_INFO("exponent : %u",((GDoubleIEEE754)ctx->error_buf[i]).mpn.biased_exponent);
    is_null = FALSE;
    break;
  }
}
Comment 4 Tim-Philipp Müller 2008-02-21 13:33:01 UTC
I didn't look too closely at this, but I was wondering if the 

  } else {
   memset (dst, 0, outsize);
  }

is correct even for the case where the output is unsigned audio/x-raw-int?
Comment 5 Sebastian Dröge (slomo) 2008-02-21 13:44:42 UTC
Hm, it that point we use the intermediate S32 or F64 format. Needs a second look though, not sure if this is always the case at that point.
Comment 6 Tim-Philipp Müller 2008-02-21 13:59:50 UTC
> Hm, it that point we use the intermediate S32 or F64 format.

This is two lines away from returning GST_FLOW_OK in GstBaseTransform::transform(), so it seemed unlikely to me that this is still the intermediary format.

(I didn't mean to modify the bug status btw, feel free to commit if you think it's correct.)
Comment 7 Stefan Sauer (gstreamer, gtkdoc dev) 2008-02-25 13:08:40 UTC
Created attachment 105902 [details] [review]
make audioconvert gap aware

This works, but is ugly. I'll look into gstringbuffer and see if/how gst_ring_buffer_clear() can be generalized to allow clearning a buffer.
Comment 8 Stefan Sauer (gstreamer, gtkdoc dev) 2008-02-25 13:47:48 UTC
* We would need to move
static const FormatDef xxx and build_linear_format() to e.g. audio_format.c.
* FormatDef should be renamed to e.g. GstAudioFormat (do we want that to be opaque? - ringbuffer accesses the 'format' member). GstBufferFormat is a bit ugly (should have been GstRingBufferFormat)
* build_linear_format() should be renamed to gst_audio_format_get()

* AudioConvertFmt could then call gst_audio_format_get() whenever the format changes.

* audio_format.c should offer new api to clear a buffer: 
gst_audio_format_clear_memory(GstAudioFormat *def, guint8 *mem, gsize length)
{
  /* FIXME: what about having bytes as part of GstAudioFormat */
  bytes = spec->width >> 3;
  for (i = 0; i < length; i++) {
    for (j = 0; j < bytes; j++) {
      mem[i * bytes + j] = def->silence[j];
    }
  }
}

* this can be used by audioconvert to simplyfiy the current patch.
* it can be easily used by ringbuffer still.
Comment 9 Stefan Sauer (gstreamer, gtkdoc dev) 2008-02-25 13:48:46 UTC
Created attachment 105908 [details] [review]
make audioconvert gap aware

make it build
Comment 10 Sebastian Dröge (slomo) 2008-03-18 14:28:21 UTC
Created attachment 107538 [details] [review]
audioconvert-gap-aware.diff

This does things properly now (I hope).

It doesn't matter if we use noise shaping or not, we can simply output silence buffer as the data that is generated by the noise shaper is -1, 0 or 1 (for integer formats) and thus can be ignored.

Then I've created a function now, that generates silence buffers for all supported formats, memset() for the easy ones and magic for the other ones.

If nobody objects this will be committed after freeze.
Comment 11 Stefan Sauer (gstreamer, gtkdoc dev) 2008-03-19 11:32:08 UTC
thanks, that looks cleaner.
Comment 12 Stefan Sauer (gstreamer, gtkdoc dev) 2008-03-20 13:01:46 UTC
BEFORE
time gst-launch-0.10 audiotestsrc num-buffers=100000 wave=silence ! audioconvert ! audio/x-raw-int,channels=2 ! fakesink
real    0m25.012s
user    0m24.254s
sys     0m0.104s

AFTER
$ time gst-launch-0.10 audiotestsrc num-buffers=100000 wave=silence ! audioconvert ! audio/x-raw-int,channels=2 ! fakesink
real    0m2.954s
user    0m2.868s
sys     0m0.016s