/*
- * Rate converter plugin using libavresample
+ * Rate converter plugin using libswresample
* Copyright (c) 2014 by Anton Khirnov
*
* This library is free software; you can redistribute it and/or
#include <alsa/asoundlib.h>
#include <alsa/pcm_rate.h>
-#include <libavresample/avresample.h>
+#include <libswresample/swresample.h>
#include <libavutil/channel_layout.h>
#include <libavutil/opt.h>
#include <libavutil/mathematics.h>
static unsigned int filter_size = 16;
-static unsigned int phase_shift = 10; /* auto-adjusts */
-static double cutoff = 0; /* auto-adjusts */
struct rate_src {
- AVAudioResampleContext *avr;
+ SwrContext *avr;
unsigned int in_rate;
unsigned int out_rate;
static void pcm_src_free(void *obj)
{
struct rate_src *rate = obj;
- avresample_free(&rate->avr);
+ swr_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->in_rate = info->in.rate;
+ rate->out_rate = info->out.rate;
- rate->avr = avresample_alloc_context();
+ rate->avr = swr_alloc();
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_channel_layout(rate->avr, "in_channel_layout",
+ av_get_default_channel_layout(rate->channels), 0);
+ av_opt_set_channel_layout(rate->avr, "out_channel_layout",
+ av_get_default_channel_layout(rate->channels), 0);
+ av_opt_set_int(rate->avr, "in_sample_rate", rate->in_rate, 0);
+ av_opt_set_int(rate->avr, "out_sample_rate", rate->out_rate, 0);
+ av_opt_set_sample_fmt(rate->avr, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
+ av_opt_set_sample_fmt(rate->avr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 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);
+ ret = swr_init(rate->avr);
if (ret < 0) {
- avresample_free(&rate->avr);
+ SNDERR("sw_init() error %d\n", ret);
+ swr_free(&rate->avr);
return -EINVAL;
}
}
if (rate->avr) {
#if 0
- avresample_close(rate->avr);
- avresample_open(rate->avr);
+ swr_free(rate->avr);
+ swr_init(rate->avr);
#endif
}
}
unsigned int src_frames)
{
struct rate_src *rate = obj;
- int chans = rate->channels;
- unsigned int total_in = avresample_get_delay(rate->avr) + src_frames;
+ unsigned int total_in = swr_get_delay(rate->avr, rate->in_rate) + src_frames;
- avresample_convert(rate->avr, (uint8_t **)&dst, dst_frames * chans * 2, dst_frames,
- (uint8_t **)&src, src_frames * chans * 2, src_frames);
+ swr_convert(rate->avr, (uint8_t **)&dst, dst_frames,
+ (const uint8_t **)&src, src_frames);
- avresample_set_compensation(rate->avr,
- total_in - src_frames > filter_size ? 0 : 1, src_frames);
+ swr_set_compensation(rate->avr,
+ total_in - src_frames > filter_size ? 0 : 1,
+ src_frames);
}
static void pcm_src_close(void *obj)
static void dump(void *obj ATTRIBUTE_UNUSED, snd_output_t *out)
{
- snd_output_printf(out, "Converter: libavr\n");
+ snd_output_printf(out, "Converter: libswresample\n");
}
#endif
};
int pcm_src_open(unsigned int version, void **objp, snd_pcm_rate_ops_t *ops)
-
{
struct rate_src *rate;