From 270e903b7165045d4c0e29c77591b7e905f9a978 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Denis-Courmont?= <remi@remlab.net> Date: Tue, 9 Aug 2011 19:22:38 +0300 Subject: [PATCH] libsamplerate resampling filter --- NEWS | 1 + configure.ac | 7 +- modules/LIST | 1 + modules/audio_filter/Modules.am | 1 + modules/audio_filter/resampler/src.c | 153 +++++++++++++++++++++++++++ po/POTFILES.in | 1 + 6 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 modules/audio_filter/resampler/src.c diff --git a/NEWS b/NEWS index 58dfe7f4622f..7e846a008667 100644 --- a/NEWS +++ b/NEWS @@ -105,6 +105,7 @@ Audio Output: * New audio output in memory (amem) * Important simplification and improvements in the core audio output * New audio output based on OpenSL ES API for Android + * New audio resampler using the Secret Rabbit Code (a.k.a. libsamplerate) Video Filter: * New gradfun filter for debanding videos using dithering diff --git a/configure.ac b/configure.ac index 0dd1565eae9d..1befae90b9ba 100644 --- a/configure.ac +++ b/configure.ac @@ -703,7 +703,7 @@ AC_CHECK_FUNC(getopt_long,, [ AC_SUBST(GNUGETOPT_LIBS) AC_CHECK_LIB(m,cos,[ - VLC_ADD_LIBS([adjust wave ripple psychedelic gradient a52tofloat32 dtstofloat32 x264 goom visual panoramix rotate noise grain scene kate flac lua chorus_flanger freetype avcodec avformat access_avio swscale postproc i420_rgb faad twolame equalizer spatializer param_eq libvlccore freetype mod mpc dmo quicktime realvideo qt4 compressor headphone_channel_mixer normvol audiobargraph_a speex mono colorthres extract ball access_imem hotkeys mosaic gaussianblur dbus x264],[-lm]) + VLC_ADD_LIBS([adjust wave ripple psychedelic gradient a52tofloat32 dtstofloat32 x264 goom visual panoramix rotate noise grain scene kate flac lua chorus_flanger freetype avcodec avformat access_avio swscale postproc i420_rgb faad twolame equalizer spatializer param_eq samplerate libvlccore freetype mod mpc dmo quicktime realvideo qt4 compressor headphone_channel_mixer normvol audiobargraph_a speex mono colorthres extract ball access_imem hotkeys mosaic gaussianblur dbus x264],[-lm]) LIBM="-lm" ], [ LIBM="" @@ -3015,6 +3015,11 @@ dnl libfluidsynth (MIDI synthetizer) plugin dnl PKG_ENABLE_MODULES_VLC([FLUIDSYNTH], [], [fluidsynth], [MIDI synthetiser with libfluidsynth], [auto]) +dnl +dnl libsamplerate plugin +dnl +PKG_ENABLE_MODULES_VLC([SAMPLERATE], [], [samplerate], [Resampler with libsamplerate], [auto]) + dnl dnl Teletext Modules dnl vbi decoder plugin (using libzbvi) diff --git a/modules/LIST b/modules/LIST index 7a6620f37509..ae234e080e95 100644 --- a/modules/LIST +++ b/modules/LIST @@ -275,6 +275,7 @@ $Id$ * rss: Display a RSS feed on the video output * rtp: rtp demux module * rv32: RV32 image format conversion module + * samplerate: Secret Rabbit Code (libsamplerate) audio resampler * sap: Interface module to read SAP/SDP announcements * scale: Images rescaler * scaletempo: Scale audio tempo in sync with playback rate diff --git a/modules/audio_filter/Modules.am b/modules/audio_filter/Modules.am index 4dc2602601ef..db4d9a795e3d 100644 --- a/modules/audio_filter/Modules.am +++ b/modules/audio_filter/Modules.am @@ -56,6 +56,7 @@ libvlc_LTLIBRARIES += \ SOURCES_bandlimited_resampler = \ resampler/bandlimited.c resampler/bandlimited.h SOURCES_ugly_resampler = resampler/ugly.c +SOURCES_samplerate = resampler/src.c libvlc_LTLIBRARIES += \ libugly_resampler_plugin.la diff --git a/modules/audio_filter/resampler/src.c b/modules/audio_filter/resampler/src.c new file mode 100644 index 000000000000..75e531c2eecc --- /dev/null +++ b/modules/audio_filter/resampler/src.c @@ -0,0 +1,153 @@ +/***************************************************************************** + * src.c : Secret Rabbit Code (a.k.a. libsamplerate) resampler + ***************************************************************************** + * Copyright (C) 2011 Rémi Denis-Courmont + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <vlc_common.h> +#include <vlc_plugin.h> +#include <vlc_aout.h> +#include <vlc_filter.h> +#include <samplerate.h> +#include <math.h> + +#define SRC_CONV_TYPE_TEXT N_("Sample rate converter type") +#define SRC_CONV_TYPE_LONGTEXT N_( \ + "Different resampling algorithm are supported. " \ + "The best one is slower, while the fast one exhibits low quality.") +static const int conv_type_values[] = { + SRC_SINC_BEST_QUALITY, SRC_SINC_MEDIUM_QUALITY, SRC_SINC_FASTEST, + SRC_ZERO_ORDER_HOLD, SRC_LINEAR, +}; +static const char *const conv_type_texts[] = { + "Sinc function (best quality)", "Sinc function (medium quality)", + "Sinc function (fast)", "Zero Order Hold (fastest)", "Linear (fastest)", +}; + +static int Open (vlc_object_t *); +static void Close (vlc_object_t *); + +vlc_module_begin () + set_shortname (N_("SRC resampler")) + set_description (N_("Secret Rabbit Code (libsamplerate) resampler") ) + set_category (CAT_AUDIO) + set_subcategory (SUBCAT_AUDIO_MISC) + add_integer ("src-converter-type", SRC_SINC_MEDIUM_QUALITY, + SRC_CONV_TYPE_TEXT, SRC_CONV_TYPE_LONGTEXT, true) + change_integer_list (conv_type_values, conv_type_texts) + set_capability ("audio filter", 50) + set_callbacks (Open, Close) +vlc_module_end () + +static block_t *Resample (filter_t *, block_t *); + +static int Open (vlc_object_t *obj) +{ + filter_t *filter = (filter_t *)obj; + + /* Only float->float */ + if (filter->fmt_in.audio.i_format != VLC_CODEC_FL32 + || filter->fmt_out.audio.i_format != VLC_CODEC_FL32 + /* No channels remapping */ + || filter->fmt_in.audio.i_physical_channels + != filter->fmt_out.audio.i_physical_channels + || filter->fmt_in.audio.i_original_channels + != filter->fmt_out.audio.i_original_channels + /* Different sample rate */ + || filter->fmt_in.audio.i_rate == filter->fmt_out.audio.i_rate) + return VLC_EGENERIC; + + int type = var_InheritInteger (obj, "src-converter-type"); + int channels = aout_FormatNbChannels (&filter->fmt_in.audio); + int err; + + SRC_STATE *s = src_new (type, channels, &err); + if (s == NULL) + { + msg_Err (obj, "cannot initialize resampler: %s", src_strerror (err)); + return VLC_EGENERIC; + } + + filter->p_sys = (filter_sys_t *)s; + filter->pf_audio_filter = Resample; + return VLC_SUCCESS; +} + +static void Close (vlc_object_t *obj) +{ + filter_t *filter = (filter_t *)obj; + SRC_STATE *s = (SRC_STATE *)filter->p_sys; + + src_delete (s); +} + +static block_t *Resample (filter_t *filter, block_t *in) +{ + block_t *out = NULL; + const size_t framesize = filter->fmt_out.audio.i_bytes_per_frame; + + SRC_STATE *s = (SRC_STATE *)filter->p_sys; + SRC_DATA src; + + src.src_ratio = (double)filter->fmt_out.audio.i_rate + / (double)filter->fmt_in.audio.i_rate; + + int err = src_set_ratio (s, src.src_ratio); + if (err != 0) + { + msg_Err (filter, "cannot update resampling ratio: %s", + src_strerror (err)); + goto error; + } + + src.input_frames = in->i_nb_samples; + src.output_frames = ceil (src.src_ratio * src.input_frames); + src.end_of_input = 0; + + out = block_Alloc (src.output_frames * framesize); + if (unlikely(out == NULL)) + goto error; + + src.data_in = (float *)in->p_buffer; + src.data_out = (float *)out->p_buffer; + + err = src_process (s, &src); + if (err != 0) + { + msg_Err (filter, "cannot resample: %s", src_strerror (err)); + block_Release (out); + out = NULL; + goto error; + } + + if (src.input_frames_used < src.input_frames) + msg_Warn (filter, "lost %ld of %ld input frames", + src.input_frames - src.input_frames_used, src.input_frames); + + out->i_buffer = src.output_frames_gen * framesize; + out->i_nb_samples = src.output_frames_gen; + out->i_pts = in->i_pts; + out->i_length = src.output_frames_gen * CLOCK_FREQ + / filter->fmt_out.audio.i_rate; +error: + block_Release (in); + return out; +} diff --git a/po/POTFILES.in b/po/POTFILES.in index 84a674f8135c..69ffe9e4c89b 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -301,6 +301,7 @@ modules/audio_filter/normvol.c modules/audio_filter/param_eq.c modules/audio_filter/resampler/bandlimited.c modules/audio_filter/resampler/bandlimited.h +modules/audio_filter/resampler/src.c modules/audio_filter/resampler/ugly.c modules/audio_filter/scaletempo.c modules/audio_filter/spatializer/allpass.cpp -- GitLab