You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
339 lines
9.9 KiB
339 lines
9.9 KiB
https://bugs.gentoo.org/539680
|
|
|
|
From: Luca Barbato <lu_zero@gentoo.org>
|
|
Description: lavr: Add a libavresample based rate plugin
|
|
Date: Mon, 14 Apr 2014 10:01:07 +0200
|
|
|
|
Provide lavcrate compatibility.
|
|
|
|
Index: alsa-plugins-1.0.28/configure.ac
|
|
===================================================================
|
|
--- alsa-plugins-1.0.28.orig/configure.ac
|
|
+++ alsa-plugins-1.0.28/configure.ac
|
|
@@ -66,7 +66,7 @@ if test "$use_maemo_rm" = "yes"; then
|
|
fi
|
|
|
|
AC_ARG_ENABLE([avcodec],
|
|
- AS_HELP_STRING([--disable-avcodec], [Don't build plugins depending on avcodec (a52)]))
|
|
+ AS_HELP_STRING([--disable-avcodec], [Do not build plugins depending on avcodec (a52)]))
|
|
|
|
if test "x$enable_avcodec" != "xno"; then
|
|
PKG_CHECK_MODULES(AVCODEC, [libavcodec libavutil], [HAVE_AVCODEC=yes], [HAVE_AVCODEC=no])
|
|
@@ -101,6 +101,10 @@ if test $HAVE_AVCODEC = yes; then
|
|
if test -z "$AVCODEC_HEADER"; then
|
|
HAVE_AVCODEC=no
|
|
fi
|
|
+ SAVE_LIBS=$LIBS
|
|
+ LIBS="$LIBS $AVCODEC_LIBS"
|
|
+ AC_CHECK_FUNCS([av_resample_init])
|
|
+ LIBS=$SAVE_LIBS
|
|
fi
|
|
|
|
AM_CONDITIONAL(HAVE_AVCODEC, test x$HAVE_AVCODEC = xyes)
|
|
@@ -108,6 +112,18 @@ AC_SUBST(AVCODEC_CFLAGS)
|
|
AC_SUBST(AVCODEC_LIBS)
|
|
AC_SUBST(AVCODEC_HEADER)
|
|
|
|
+AC_ARG_ENABLE([avresample],
|
|
+ AS_HELP_STRING([--disable-avresample], [Do not build plugins depending on avcodec (lavrate)]))
|
|
+
|
|
+if test "x$enable_avresample" != "xno"; then
|
|
+ PKG_CHECK_MODULES(AVRESAMPLE, [libavresample libavutil], [HAVE_AVRESAMPLE=yes], [HAVE_AVRESAMPLE=no])
|
|
+fi
|
|
+
|
|
+AM_CONDITIONAL(HAVE_AVRESAMPLE, test x$HAVE_AVCODEC = xyes)
|
|
+AC_SUBST(AVRESAMPLE_CFLAGS)
|
|
+AC_SUBST(AVRESAMPLE_LIBS)
|
|
+AC_SUBST(AVRESAMPLE_HEADER)
|
|
+
|
|
PKG_CHECK_MODULES(speexdsp, [speexdsp >= 1.2], [HAVE_SPEEXDSP="yes"], [HAVE_SPEEXDSP=""])
|
|
AM_CONDITIONAL(HAVE_SPEEXDSP, test "$HAVE_SPEEXDSP" = "yes")
|
|
|
|
@@ -181,7 +197,7 @@ AC_OUTPUT([
|
|
mix/Makefile
|
|
rate/Makefile
|
|
a52/Makefile
|
|
- rate-lavc/Makefile
|
|
+ rate-lavr/Makefile
|
|
maemo/Makefile
|
|
doc/Makefile
|
|
usb_stream/Makefile
|
|
Index: alsa-plugins-1.0.28/Makefile.am
|
|
===================================================================
|
|
--- alsa-plugins-1.0.28.orig/Makefile.am
|
|
+++ alsa-plugins-1.0.28/Makefile.am
|
|
@@ -9,8 +9,14 @@ if HAVE_SAMPLERATE
|
|
SUBDIRS += rate
|
|
endif
|
|
if HAVE_AVCODEC
|
|
+SUBDIRS += a52
|
|
+if !HAVE_AVRESAMPLE
|
|
SUBDIRS += a52 rate-lavc
|
|
endif
|
|
+endif
|
|
+if HAVE_AVRESAMPLE
|
|
+SUBDIRS += rate-lavr
|
|
+endif
|
|
if HAVE_MAEMO_PLUGIN
|
|
SUBDIRS += maemo
|
|
endif
|
|
Index: alsa-plugins-1.0.28/rate-lavr/Makefile.am
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ alsa-plugins-1.0.28/rate-lavr/Makefile.am
|
|
@@ -0,0 +1,22 @@
|
|
+asound_module_rate_lavr_LTLIBRARIES = libasound_module_rate_lavr.la
|
|
+
|
|
+asound_module_rate_lavrdir = @ALSA_PLUGIN_DIR@
|
|
+
|
|
+AM_CFLAGS = -Wall -g @ALSA_CFLAGS@ @AVRESAMPLE_CFLAGS@
|
|
+AM_LDFLAGS = -module -avoid-version -export-dynamic -no-undefined $(LDFLAGS_NOUNDEFINED)
|
|
+
|
|
+libasound_module_rate_lavr_la_SOURCES = rate_lavr.c
|
|
+libasound_module_rate_lavr_la_LIBADD = @ALSA_LIBS@ @AVRESAMPLE_LIBS@
|
|
+
|
|
+
|
|
+install-exec-hook:
|
|
+ rm -f $(DESTDIR)@ALSA_PLUGIN_DIR@/libasound_module_rate_lavcrate*.so
|
|
+ $(LN_S) libasound_module_rate_lavr.so $(DESTDIR)@ALSA_PLUGIN_DIR@/libasound_module_rate_lavcrate.so
|
|
+ $(LN_S) libasound_module_rate_lavr.so $(DESTDIR)@ALSA_PLUGIN_DIR@/libasound_module_rate_lavcrate_higher.so
|
|
+ $(LN_S) libasound_module_rate_lavr.so $(DESTDIR)@ALSA_PLUGIN_DIR@/libasound_module_rate_lavcrate_high.so
|
|
+ $(LN_S) libasound_module_rate_lavr.so $(DESTDIR)@ALSA_PLUGIN_DIR@/libasound_module_rate_lavcrate_fast.so
|
|
+ $(LN_S) libasound_module_rate_lavr.so $(DESTDIR)@ALSA_PLUGIN_DIR@/libasound_module_rate_lavcrate_faster.so
|
|
+
|
|
+uninstall-hook:
|
|
+ rm -f $(DESTDIR)@ALSA_PLUGIN_DIR@/libasound_module_rate_lavcrate*.so
|
|
+ rm -f $(DESTDIR)@ALSA_PLUGIN_DIR@/libasound_module_rate_lavr*.so
|
|
Index: alsa-plugins-1.0.28/rate-lavr/rate_lavr.c
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ alsa-plugins-1.0.28/rate-lavr/rate_lavr.c
|
|
@@ -0,0 +1,227 @@
|
|
+/*
|
|
+ * Rate converter plugin using libavresample
|
|
+ * Copyright (c) 2014 by Anton Khirnov
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or
|
|
+ * modify it under the terms of the GNU Lesser General Public
|
|
+ * License as published by the Free Software Foundation; either
|
|
+ * version 2.1 of the License, or (at your option) any later version.
|
|
+ *
|
|
+ * This library 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
|
|
+ * Lesser General Public License for more details.
|
|
+ */
|
|
+
|
|
+#include <stdio.h>
|
|
+#include <alsa/asoundlib.h>
|
|
+#include <alsa/pcm_rate.h>
|
|
+
|
|
+#include <libavresample/avresample.h>
|
|
+#include <libavutil/channel_layout.h>
|
|
+#include <libavutil/opt.h>
|
|
+#include <libavutil/mathematics.h>
|
|
+#include <libavutil/samplefmt.h>
|
|
+
|
|
+
|
|
+static int filter_size = 16;
|
|
+static int phase_shift = 10; /* auto-adjusts */
|
|
+static double cutoff = 0; /* auto-adjusts */
|
|
+
|
|
+struct rate_src {
|
|
+ AVAudioResampleContext *avr;
|
|
+
|
|
+ int in_rate;
|
|
+ int out_rate;
|
|
+ unsigned int channels;
|
|
+};
|
|
+
|
|
+static snd_pcm_uframes_t input_frames(void *obj, snd_pcm_uframes_t frames)
|
|
+{
|
|
+ return frames;
|
|
+}
|
|
+
|
|
+static snd_pcm_uframes_t output_frames(void *obj, snd_pcm_uframes_t frames)
|
|
+{
|
|
+ return frames;
|
|
+}
|
|
+
|
|
+static void pcm_src_free(void *obj)
|
|
+{
|
|
+ struct rate_src *rate = obj;
|
|
+ avresample_free(&rate->avr);
|
|
+}
|
|
+
|
|
+static int pcm_src_init(void *obj, snd_pcm_rate_info_t *info)
|
|
+{
|
|
+ struct rate_src *rate = obj;
|
|
+ int i, ir, or;
|
|
+
|
|
+ if (!rate->avr || rate->channels != info->channels) {
|
|
+ int ret;
|
|
+
|
|
+ pcm_src_free(rate);
|
|
+ rate->channels = info->channels;
|
|
+ ir = rate->in_rate = info->in.rate;
|
|
+ or = rate->out_rate = info->out.rate;
|
|
+ i = av_gcd(or, ir);
|
|
+ if (or > ir) {
|
|
+ phase_shift = or/i;
|
|
+ } else {
|
|
+ phase_shift = ir/i;
|
|
+ }
|
|
+ if (cutoff <= 0.0) {
|
|
+ cutoff = 1.0 - 1.0/filter_size;
|
|
+ if (cutoff < 0.80)
|
|
+ cutoff = 0.80;
|
|
+ }
|
|
+
|
|
+ rate->avr = avresample_alloc_context();
|
|
+ if (!rate->avr)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ av_opt_set_int(rate->avr, "in_sample_rate", info->in.rate, 0);
|
|
+ av_opt_set_int(rate->avr, "out_sample_rate", info->out.rate, 0);
|
|
+ av_opt_set_int(rate->avr, "in_sample_format", AV_SAMPLE_FMT_S16, 0);
|
|
+ av_opt_set_int(rate->avr, "out_sample_format", AV_SAMPLE_FMT_S16, 0);
|
|
+ av_opt_set_int(rate->avr, "in_channel_layout", av_get_default_channel_layout(rate->channels), 0);
|
|
+ av_opt_set_int(rate->avr, "out_channel_layout", av_get_default_channel_layout(rate->channels), 0);
|
|
+
|
|
+ av_opt_set_int(rate->avr, "filter_size", filter_size, 0);
|
|
+ av_opt_set_int(rate->avr, "phase_shift", phase_shift, 0);
|
|
+ av_opt_set_double(rate->avr, "cutoff", cutoff, 0);
|
|
+
|
|
+ ret = avresample_open(rate->avr);
|
|
+ if (ret < 0) {
|
|
+ avresample_free(&rate->avr);
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int pcm_src_adjust_pitch(void *obj, snd_pcm_rate_info_t *info)
|
|
+{
|
|
+ struct rate_src *rate = obj;
|
|
+
|
|
+ if (info->out.rate != rate->out_rate || info->in.rate != rate->in_rate)
|
|
+ pcm_src_init(obj, info);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void pcm_src_reset(void *obj)
|
|
+{
|
|
+ struct rate_src *rate = obj;
|
|
+
|
|
+ if (rate->avr) {
|
|
+ avresample_close(rate->avr);
|
|
+ avresample_open(rate->avr);
|
|
+ }
|
|
+}
|
|
+
|
|
+static void pcm_src_convert_s16(void *obj, int16_t *dst, unsigned int
|
|
+ dst_frames, const int16_t *src, unsigned int src_frames)
|
|
+{
|
|
+ struct rate_src *rate = obj;
|
|
+ int consumed = 0, chans=rate->channels, ret=0, i;
|
|
+ int total_in = avresample_get_delay(rate->avr) + src_frames;
|
|
+
|
|
+ ret = avresample_convert(rate->avr, &dst, dst_frames * chans * 2, dst_frames,
|
|
+ &src, src_frames * chans * 2, src_frames);
|
|
+
|
|
+ avresample_set_compensation(rate->avr,
|
|
+ total_in - src_frames > filter_size ? 0 : 1, src_frames);
|
|
+}
|
|
+
|
|
+static void pcm_src_close(void *obj)
|
|
+{
|
|
+ pcm_src_free(obj);
|
|
+}
|
|
+
|
|
+#if SND_PCM_RATE_PLUGIN_VERSION >= 0x010002
|
|
+static int get_supported_rates(void *obj, unsigned int *rate_min,
|
|
+ unsigned int *rate_max)
|
|
+{
|
|
+ *rate_min = *rate_max = 0; /* both unlimited */
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void dump(void *obj, snd_output_t *out)
|
|
+{
|
|
+ snd_output_printf(out, "Converter: libavr\n");
|
|
+}
|
|
+#endif
|
|
+
|
|
+static snd_pcm_rate_ops_t pcm_src_ops = {
|
|
+ .close = pcm_src_close,
|
|
+ .init = pcm_src_init,
|
|
+ .free = pcm_src_free,
|
|
+ .adjust_pitch = pcm_src_adjust_pitch,
|
|
+ .convert_s16 = pcm_src_convert_s16,
|
|
+ .input_frames = input_frames,
|
|
+ .output_frames = output_frames,
|
|
+#if SND_PCM_RATE_PLUGIN_VERSION >= 0x010002
|
|
+ .version = SND_PCM_RATE_PLUGIN_VERSION,
|
|
+ .get_supported_rates = get_supported_rates,
|
|
+ .dump = dump,
|
|
+#endif
|
|
+};
|
|
+
|
|
+int pcm_src_open(unsigned int version, void **objp, snd_pcm_rate_ops_t *ops)
|
|
+
|
|
+{
|
|
+ struct rate_src *rate;
|
|
+
|
|
+#if SND_PCM_RATE_PLUGIN_VERSION < 0x010002
|
|
+ if (version != SND_PCM_RATE_PLUGIN_VERSION) {
|
|
+ fprintf(stderr, "Invalid rate plugin version %x\n", version);
|
|
+ return -EINVAL;
|
|
+ }
|
|
+#endif
|
|
+ rate = calloc(1, sizeof(*rate));
|
|
+ if (!rate)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ *objp = rate;
|
|
+ rate->avr = NULL;
|
|
+#if SND_PCM_RATE_PLUGIN_VERSION >= 0x010002
|
|
+ if (version == 0x010001)
|
|
+ memcpy(ops, &pcm_src_ops, sizeof(snd_pcm_rate_old_ops_t));
|
|
+ else
|
|
+#endif
|
|
+ *ops = pcm_src_ops;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int SND_PCM_RATE_PLUGIN_ENTRY(lavcrate)(unsigned int version, void **objp,
|
|
+ snd_pcm_rate_ops_t *ops)
|
|
+{
|
|
+ return pcm_src_open(version, objp, ops);
|
|
+}
|
|
+int SND_PCM_RATE_PLUGIN_ENTRY(lavcrate_higher)(unsigned int version,
|
|
+ void **objp, snd_pcm_rate_ops_t *ops)
|
|
+{
|
|
+ filter_size = 64;
|
|
+ return pcm_src_open(version, objp, ops);
|
|
+}
|
|
+int SND_PCM_RATE_PLUGIN_ENTRY(lavcrate_high)(unsigned int version,
|
|
+ void **objp, snd_pcm_rate_ops_t *ops)
|
|
+{
|
|
+ filter_size = 32;
|
|
+ return pcm_src_open(version, objp, ops);
|
|
+}
|
|
+int SND_PCM_RATE_PLUGIN_ENTRY(lavcrate_fast)(unsigned int version,
|
|
+ void **objp, snd_pcm_rate_ops_t *ops)
|
|
+{
|
|
+ filter_size = 8;
|
|
+ return pcm_src_open(version, objp, ops);
|
|
+}
|
|
+int SND_PCM_RATE_PLUGIN_ENTRY(lavcrate_faster)(unsigned int version,
|
|
+ void **objp, snd_pcm_rate_ops_t *ops)
|
|
+{
|
|
+ filter_size = 4;
|
|
+ return pcm_src_open(version, objp, ops);
|
|
+}
|
|
+
|
|
+
|