GNOME Bugzilla – Bug 517813
[audioconvert] make gap aware
Last modified: 2008-04-03 15:21:23 UTC
Audioconvert should try to skip processing GAP buffers.
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
Created attachment 105682 [details] modified controller test to try the gap handling
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; } }
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?
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.
> 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.)
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.
* 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.
Created attachment 105908 [details] [review] make audioconvert gap aware make it build
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.
thanks, that looks cleaner.
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