GstAudioResamplerFlags flags;
GstAudioFormat format;
GstStructure *options;
+ gint format_index;
gint channels;
gint in_rate;
gint out_rate;
get_kaiser_tap (x + i, resampler->n_taps,
resampler->cutoff, resampler->kaiser_beta);
break;
-
- default:
- break;
}
return weight;
}
static void
setup_functions (GstAudioResampler * resampler)
{
- gboolean non_interleaved;
gint index, fidx;
- non_interleaved =
- (resampler->flags & GST_AUDIO_RESAMPLER_FLAG_NON_INTERLEAVED);
-
- /* we resample each channel separately */
- resampler->blocks = resampler->channels;
- resampler->inc = 1;
- resampler->ostride = non_interleaved ? 1 : resampler->channels;
-
- switch (resampler->format) {
- case GST_AUDIO_FORMAT_S16:
- GST_DEBUG ("using S16 functions");
- index = 0;
- break;
- case GST_AUDIO_FORMAT_S32:
- GST_DEBUG ("using S32 functions");
- index = 1;
- break;
- case GST_AUDIO_FORMAT_F32:
- GST_DEBUG ("using F32 functions");
- index = 2;
- break;
- case GST_AUDIO_FORMAT_F64:
- GST_DEBUG ("using F64 functions");
- index = 3;
- break;
- default:
- g_assert_not_reached ();
- break;
- }
- resampler->deinterleave = deinterleave_funcs[index];
- resampler->convert_taps = convert_taps_funcs[index];
+ index = resampler->format_index;
switch (resampler->filter_interpolation) {
default:
GET_OPT_FILTER_MODE_THRESHOLD (resampler->options);
filter_interpolation = GET_OPT_FILTER_INTERPOLATION (resampler->options);
- /* interpolated table but no interpolation given, assume default */
- if (resampler->filter_mode != GST_AUDIO_RESAMPLER_FILTER_MODE_FULL &&
- filter_interpolation == GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_NONE)
- filter_interpolation = DEFAULT_OPT_FILTER_INTERPOLATION;
} else {
resampler->filter_mode = GST_AUDIO_RESAMPLER_FILTER_MODE_FULL;
filter_interpolation = GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_NONE;
oversample = 1;
}
resampler->oversample = oversample;
- resampler->filter_interpolation = filter_interpolation;
n_taps = resampler->n_taps;
bps = resampler->bps;
oversample);
if (resampler->filter_mode == GST_AUDIO_RESAMPLER_FILTER_MODE_AUTO) {
- if (out_rate <= oversample) {
+ if (out_rate <= oversample
+ && !(resampler->flags & GST_AUDIO_RESAMPLER_FLAG_VARIABLE_RATE)) {
/* don't interpolate if we need to calculate at least the same amount
* of filter coefficients than the full table case */
resampler->filter_mode = GST_AUDIO_RESAMPLER_FILTER_MODE_FULL;
resampler->filter_mode = GST_AUDIO_RESAMPLER_FILTER_MODE_INTERPOLATED;
}
}
+ /* interpolated table but no interpolation given, assume default */
+ if (resampler->filter_mode != GST_AUDIO_RESAMPLER_FILTER_MODE_FULL &&
+ filter_interpolation == GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_NONE)
+ filter_interpolation = DEFAULT_OPT_FILTER_INTERPOLATION;
+
+ resampler->filter_interpolation = filter_interpolation;
if (resampler->filter_mode == GST_AUDIO_RESAMPLER_FILTER_MODE_FULL &&
resampler->method != GST_AUDIO_RESAMPLER_METHOD_NEAREST) {
alloc_cache_mem (resampler, bps, n_taps, out_rate);
}
- setup_functions (resampler);
-
if (resampler->filter_interpolation !=
GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_NONE) {
gint i, isize;
resampler->convert_taps (tmp_taps, taps, weight, n_taps);
}
}
+ setup_functions (resampler);
}
#define PRINT_TAPS(type,print) \
GstAudioFormat format, gint channels,
gint in_rate, gint out_rate, GstStructure * options)
{
+ gboolean non_interleaved;
GstAudioResampler *resampler;
const GstAudioFormatInfo *info;
GstStructure *def_options = NULL;
- g_return_val_if_fail (channels > 0, FALSE);
- g_return_val_if_fail (in_rate > 0, FALSE);
- g_return_val_if_fail (out_rate > 0, FALSE);
+ g_return_val_if_fail (method >= GST_AUDIO_RESAMPLER_METHOD_NEAREST
+ && method <= GST_AUDIO_RESAMPLER_METHOD_KAISER, NULL);
+ g_return_val_if_fail (format == GST_AUDIO_FORMAT_S16 ||
+ format == GST_AUDIO_FORMAT_S32 || format == GST_AUDIO_FORMAT_F32 ||
+ format == GST_AUDIO_FORMAT_F64, NULL);
+ g_return_val_if_fail (channels > 0, NULL);
+ g_return_val_if_fail (in_rate > 0, NULL);
+ g_return_val_if_fail (out_rate > 0, NULL);
audio_resampler_init ();
resampler->format = format;
resampler->channels = channels;
+ switch (format) {
+ case GST_AUDIO_FORMAT_S16:
+ resampler->format_index = 0;
+ break;
+ case GST_AUDIO_FORMAT_S32:
+ resampler->format_index = 1;
+ break;
+ case GST_AUDIO_FORMAT_F32:
+ resampler->format_index = 2;
+ break;
+ case GST_AUDIO_FORMAT_F64:
+ resampler->format_index = 3;
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
info = gst_audio_format_get_info (format);
resampler->bps = GST_AUDIO_FORMAT_INFO_WIDTH (info) / 8;
resampler->sbuf = g_malloc0 (sizeof (gpointer) * channels);
+ non_interleaved =
+ (resampler->flags & GST_AUDIO_RESAMPLER_FLAG_NON_INTERLEAVED);
+
+ /* we resample each channel separately */
+ resampler->blocks = resampler->channels;
+ resampler->inc = 1;
+ resampler->ostride = non_interleaved ? 1 : resampler->channels;
+ resampler->deinterleave = deinterleave_funcs[resampler->format_index];
+ resampler->convert_taps = convert_taps_funcs[resampler->format_index];
+
GST_DEBUG ("method %d, bps %d, channels %d", method, resampler->bps,
resampler->channels);
/**
* GstAudioResamplerFilterMode:
* @GST_AUDIO_RESAMPLER_FILTER_MODE_INTERPOLATED: Use interpolated filter tables. This
- * uses less memory but more CPU and is slightly less accurate.
+ * uses less memory but more CPU and is slightly less accurate but it allows for more
+ * efficient variable rate resampling with gst_audio_resampler_update().
* @GST_AUDIO_RESAMPLER_FILTER_MODE_FULL: Use full filter table. This uses more memory
* but less CPU.
* @GST_AUDIO_RESAMPLER_FILTER_MODE_AUTO: Automatically choose between interpolated
*
* GST_TYPE_AUDIO_RESAMPLER_INTERPOLATION: how the filter coeficients should be
* interpolated.
- * GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_LINEAR is default.
+ * GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_CUBIC is default.
*/
#define GST_AUDIO_RESAMPLER_OPT_FILTER_INTERPOLATION "GstAudioResampler.filter-interpolation"
/**
*
* G_TYPE_DOUBLE: The maximum allowed phase error when switching sample
* rates.
- * 0.05 is the default.
+ * 0.1 is the default.
*/
#define GST_AUDIO_RESAMPLER_OPT_MAX_PHASE_ERROR "GstAudioResampler.max-phase-error"
* @GST_AUDIO_RESAMPLER_FLAG_NON_INTERLEAVED: samples are non-interleaved. an array
* of blocks of samples, one for each channel, should be passed to the resample
* function.
+ * @GST_AUDIO_RESAMPLER_FLAG_VARIABLE_RATE: optimize for dynamic updates of the sample
+ * rates with gst_audio_resampler_update(). This will select an interpolating filter
+ * when #GST_AUDIO_RESAMPLER_FILTER_MODE_AUTO is configured.
*
* Different resampler flags.
*/
typedef enum {
GST_AUDIO_RESAMPLER_FLAG_NONE = (0),
GST_AUDIO_RESAMPLER_FLAG_NON_INTERLEAVED = (1 << 0),
+ GST_AUDIO_RESAMPLER_FLAG_VARIABLE_RATE = (1 << 1),
} GstAudioResamplerFlags;
#define GST_AUDIO_RESAMPLER_QUALITY_MIN 0