Currently this only works if the kernel size doesn't change, in the future
it will be possible to change the kernel size too without draining
the complete history and without loosing anything.
Partially based on a patch by
Thiago Santos <thiago.sousa.santos@collabora.co.uk>
When nsamples_out is larger than nsamples_in, using unsigned
ints lead to a overflow and the resulting value is wrong and
way too large for allocating a buffer. Use signed integers
and returning immediatelly when that happens.
This provides another 7% speedup for the time domain convolution and 1.5%
speedup for the FFT convolution on Mono input.
This optimization assumes that the compiler simplifies calculations
and conditions on constant numbers and unrolls loops with a constant
number of repeats.
This will always use time-domain convolution, which lowers the latency.
With FFT convolution it's always a multiple of the kernel length,
with time domain convolution it's only the pre-latency of the filter kernel.
This provides a great speedup, especially the relationship between kernel
length and processing size is now logarithmic instead of linear. Below a
kernel size of 32 it's a bit slower, afterwards it's much faster:
17 0.788000 -> 0.950000
33 1.208000 -> 1.146000
65 2.166000 -> 1.146000
...
4097 107.444000 -> 1.508000
For sizes smaller 32 the normal time-domain convolution is chosen,
for larger sizes the FFT convolution is automatically used.
Fixes bug #594381.
Remove some redundant calculations, move comparisions out of
inner loops, etc.
This makes the convolution about 3 (!) times faster but
processing time is of course still proportional to the
filter size.
The previous patch to add support for additional sample formats possibly
introduced a reentrancy bug: a variable used for a loop index was declared
static. This patch fixes that, and also adds a "/* *INDENT-ON* */" annotation
following the macro block. (I don't know what the annotation is for, but the
adder, where I copied this from, has it).
Introduce a new max-delay property that can only
be set before going to PLAYING or PAUSED. This
is used to limit the maximum delay and is set
to the current delay by default.
Using this will make sure that we have enough data
in our internal ringbuffer for the echo. With dynamic
reallocation of the ringbuffer as used before silence
could've been used as the echo directly after setting
a new delay.
Link to properties. Correct titles for examples. Document a few trivial cases. Keep lists in section file and docs/plugins/Makefile.am alphabetically ordered.
Save some allocations if the echo delay is increased often
during playback by always allocating enough memory to hold
data up to the next complete second, i.e. in the worst case
allocate memory for one additional second.
Add a note to the docs that audioecho's reverb will
sound metallic. This happens because for a real
reverb filter additional filtering is necessary.
Also note which values should be used for the delay
property to get an echo effect.
The element can add an echo and a simple reverb effect to
an audio stream but for a real reverb filter it would need
some additional filtering to prevent a metallic-sounding
result.
Original commit message from CVS:
* gst/audiofx/audiochebband.c: (gst_audio_cheb_band_class_init),
(gst_audio_cheb_band_init), (gst_audio_cheb_band_finalize),
(gst_audio_cheb_band_set_property):
* gst/audiofx/audiochebband.h:
* gst/audiofx/audiocheblimit.c: (gst_audio_cheb_limit_class_init),
(gst_audio_cheb_limit_init), (gst_audio_cheb_limit_finalize),
(gst_audio_cheb_limit_set_property):
* gst/audiofx/audiocheblimit.h:
* gst/audiofx/audiowsincband.c: (gst_audio_wsincband_class_init),
(gst_audio_wsincband_init), (gst_audio_wsincband_finalize),
(gst_audio_wsincband_set_property):
* gst/audiofx/audiowsincband.h:
* gst/audiofx/audiowsinclimit.c: (gst_audio_wsinclimit_class_init),
(gst_audio_wsinclimit_init), (gst_audio_wsinclimit_finalize),
(gst_audio_wsinclimit_set_property):
* gst/audiofx/audiowsinclimit.h:
Use a custom mutex for protecting the instance fields instead of
the GstObject lock. Using the latter can lead to deadlocks, especially
with the FIR filters when updating the latency.
Original commit message from CVS:
* gst/audiofx/Makefile.am:
* gst/audiofx/audiofxbasefirfilter.c:
(gst_audio_fx_base_fir_filter_dispose),
(gst_audio_fx_base_fir_filter_base_init),
(gst_audio_fx_base_fir_filter_class_init),
(gst_audio_fx_base_fir_filter_init),
(gst_audio_fx_base_fir_filter_push_residue),
(gst_audio_fx_base_fir_filter_setup),
(gst_audio_fx_base_fir_filter_transform),
(gst_audio_fx_base_fir_filter_start),
(gst_audio_fx_base_fir_filter_stop),
(gst_audio_fx_base_fir_filter_query),
(gst_audio_fx_base_fir_filter_query_type),
(gst_audio_fx_base_fir_filter_event),
(gst_audio_fx_base_fir_filter_set_kernel):
* gst/audiofx/audiofxbasefirfilter.h:
* gst/audiofx/audiofxbaseiirfilter.c:
Implement a base class for generic audio FIR filters.
* gst/audiofx/audiowsincband.c:
(gst_gst_audio_wsincband_mode_get_type),
(gst_gst_audio_wsincband_window_get_type),
(gst_audio_wsincband_base_init), (gst_audio_wsincband_class_init),
(gst_audio_wsincband_init), (gst_audio_wsincband_build_kernel),
(gst_audio_wsincband_setup), (gst_audio_wsincband_set_property),
(gst_audio_wsincband_get_property):
* gst/audiofx/audiowsincband.h:
* gst/audiofx/audiowsinclimit.c:
(gst_audio_wsinclimit_mode_get_type),
(gst_audio_wsinclimit_window_get_type),
(gst_audio_wsinclimit_base_init),
(gst_audio_wsinclimit_class_init), (gst_audio_wsinclimit_init),
(gst_audio_wsinclimit_build_kernel), (gst_audio_wsinclimit_setup),
(gst_audio_wsinclimit_set_property),
(gst_audio_wsinclimit_get_property):
* gst/audiofx/audiowsinclimit.h:
* tests/check/elements/audiowsincband.c: (GST_START_TEST):
* tests/check/elements/audiowsinclimit.c: (GST_START_TEST):
Use this new base class for audiowsincband and audiowsinclimit.
Also cleanup both elements.
Original commit message from CVS:
* gst/audiofx/Makefile.am:
* gst/audiofx/audiofxbaseiirfilter.c:
(gst_audio_fx_base_iir_filter_base_init),
(gst_audio_fx_base_iir_filter_dispose),
(gst_audio_fx_base_iir_filter_class_init),
(gst_audio_fx_base_iir_filter_init),
(gst_audio_fx_base_iir_filter_calculate_gain),
(gst_audio_fx_base_iir_filter_set_coefficients),
(gst_audio_fx_base_iir_filter_setup), (process),
(gst_audio_fx_base_iir_filter_transform_ip),
(gst_audio_fx_base_iir_filter_stop):
* gst/audiofx/audiofxbaseiirfilter.h:
Implement a base class for IIR filters.
* gst/audiofx/audiochebband.c: (gst_audio_cheb_band_base_init),
(gst_audio_cheb_band_class_init), (gst_audio_cheb_band_init),
(generate_coefficients), (gst_audio_cheb_band_set_property),
(gst_audio_cheb_band_setup):
* gst/audiofx/audiochebband.h:
* gst/audiofx/audiocheblimit.c: (gst_audio_cheb_limit_base_init),
(gst_audio_cheb_limit_class_init), (gst_audio_cheb_limit_init),
(generate_coefficients), (gst_audio_cheb_limit_set_property),
(gst_audio_cheb_limit_setup):
* gst/audiofx/audiocheblimit.h:
Use the IIR filter base class for the chebyshev filters.
Original commit message from CVS:
* gst/audiofx/audiowsincband.c:
* gst/audiofx/audiowsinclimit.c:
* gst/cutter/gstcutter.c:
Make author name consistent with others.