int dst_index; \
int index= c->index; \
int frac= c->frac; \
- int sample_index = index >> c->phase_shift; \
+ int sample_index = 0; \
int x4_aligned_filter_length = c->filter_length & ~3; \
int x8_aligned_filter_length = c->filter_length & ~7; \
\
- index &= c->phase_mask; \
+ while (index >= c->phase_count) { \
+ sample_index++; \
+ index -= c->phase_count; \
+ } \
+ \
for (dst_index = 0; dst_index < n; dst_index++) { \
FELEM *filter = ((FELEM *) c->filter_bank) + c->filter_alloc * index; \
\
frac -= c->src_incr; \
index++; \
} \
- sample_index += index >> c->phase_shift; \
- index &= c->phase_mask; \
+ \
+ while (index >= c->phase_count) { \
+ sample_index++; \
+ index -= c->phase_count; \
+ } \
} \
\
if(update_ctx){ \
{"filter_size" , "set swr resampling filter size", OFFSET(filter_size) , AV_OPT_TYPE_INT , {.i64=32 }, 0 , INT_MAX , PARAM },
{"phase_shift" , "set swr resampling phase shift", OFFSET(phase_shift) , AV_OPT_TYPE_INT , {.i64=10 }, 0 , 24 , PARAM },
{"linear_interp" , "enable linear interpolation" , OFFSET(linear_interp) , AV_OPT_TYPE_BOOL , {.i64=0 }, 0 , 1 , PARAM },
+{"exact_rational" , "enable exact rational" , OFFSET(exact_rational) , AV_OPT_TYPE_BOOL , {.i64=0 }, 0 , 1 , PARAM },
{"cutoff" , "set cutoff frequency ratio" , OFFSET(cutoff) , AV_OPT_TYPE_DOUBLE,{.dbl=0. }, 0 , 1 , PARAM },
/* duplicate option in order to work with avconv */
static ResampleContext *resample_init(ResampleContext *c, int out_rate, int in_rate, int filter_size, int phase_shift, int linear,
double cutoff0, enum AVSampleFormat format, enum SwrFilterType filter_type, double kaiser_beta,
- double precision, int cheby)
+ double precision, int cheby, int exact_rational)
{
double cutoff = cutoff0? cutoff0 : 0.97;
double factor= FFMIN(out_rate * cutoff / in_rate, 1.0);
int phase_count= 1<<phase_shift;
- if (!c || c->phase_shift != phase_shift || c->linear!=linear || c->factor != factor
+ if (exact_rational) {
+ int phase_count_exact, phase_count_exact_den;
+
+ av_reduce(&phase_count_exact, &phase_count_exact_den, out_rate, in_rate, INT_MAX);
+ /* FIXME this is not required, but build_filter needs even phase_count */
+ if (phase_count_exact & 1 && phase_count_exact > 1 && phase_count_exact < INT_MAX/2)
+ phase_count_exact *= 2;
+
+ if (phase_count_exact <= phase_count) {
+ /* FIXME this is not required when soft compensation is disabled */
+ phase_count_exact *= phase_count / phase_count_exact;
+ phase_count = phase_count_exact;
+ }
+ }
+
+ if (!c || c->phase_count != phase_count || c->linear!=linear || c->factor != factor
|| c->filter_length != FFMAX((int)ceil(filter_size/factor), 1) || c->format != format
|| c->filter_type != filter_type || c->kaiser_beta != kaiser_beta) {
c = av_mallocz(sizeof(*c));
c->phase_shift = phase_shift;
c->phase_mask = phase_count - 1;
+ c->phase_count = phase_count;
c->linear = linear;
c->factor = factor;
c->filter_length = FFMAX((int)ceil(filter_size/factor), 1);
uint8_t *dst, const uint8_t *src, int *consumed,
int src_size, int dst_size, int update_ctx)
{
- if (c->filter_length == 1 && c->phase_shift == 0) {
+ if (c->filter_length == 1 && c->phase_count == 1) {
int index= c->index;
int frac= c->frac;
int64_t index2= (1LL<<32)*c->frac/c->src_incr + (1LL<<32)*index;
c->index = 0;
}
} else {
- int64_t end_index = (1LL + src_size - c->filter_length) << c->phase_shift;
+ int64_t end_index = (1LL + src_size - c->filter_length) * c->phase_count;
int64_t delta_frac = (end_index - c->index) * c->src_incr - c->frac;
int delta_n = (delta_frac + c->dst_incr - 1) / c->dst_incr;
int av_unused mm_flags = av_get_cpu_flags();
int need_emms = c->format == AV_SAMPLE_FMT_S16P && ARCH_X86_32 &&
(mm_flags & (AV_CPU_FLAG_MMX2 | AV_CPU_FLAG_SSE2)) == AV_CPU_FLAG_MMX2;
- int64_t max_src_size = (INT64_MAX >> (c->phase_shift+1)) / c->src_incr;
+ int64_t max_src_size = (INT64_MAX/2 / c->phase_count) / c->src_incr;
if (c->compensation_distance)
dst_size = FFMIN(dst_size, c->compensation_distance);
static int64_t get_delay(struct SwrContext *s, int64_t base){
ResampleContext *c = s->resample;
int64_t num = s->in_buffer_count - (c->filter_length-1)/2;
- num *= 1 << c->phase_shift;
+ num *= c->phase_count;
num -= c->index;
num *= c->src_incr;
num -= c->frac;
- return av_rescale(num, base, s->in_sample_rate*(int64_t)c->src_incr << c->phase_shift);
+ return av_rescale(num, base, s->in_sample_rate*(int64_t)c->src_incr * c->phase_count);
}
static int64_t get_out_samples(struct SwrContext *s, int in_samples) {
// They also make it easier to proof that changes and optimizations do not
// break the upper bound.
int64_t num = s->in_buffer_count + 2LL + in_samples;
- num *= 1 << c->phase_shift;
+ num *= c->phase_count;
num -= c->index;
- num = av_rescale_rnd(num, s->out_sample_rate, ((int64_t)s->in_sample_rate) << c->phase_shift, AV_ROUND_UP) + 2;
+ num = av_rescale_rnd(num, s->out_sample_rate, ((int64_t)s->in_sample_rate) * c->phase_count, AV_ROUND_UP) + 2;
if (c->compensation_distance) {
if (num > INT_MAX)
}
res = num - *out_sz;
- *out_idx = c->filter_length + (c->index >> c->phase_shift);
+ *out_idx = c->filter_length;
+ while (c->index < 0) {
+ --*out_idx;
+ c->index += c->phase_count;
+ }
*out_sz = FFMAX(*out_sz + c->filter_length,
1 + c->filter_length * 2) - *out_idx;
- c->index &= c->phase_mask;
return FFMAX(res, 0);
}
int frac;
int src_incr;
int compensation_distance;
- int phase_shift;
- int phase_mask;
+ /* TODO remove phase_shift and phase_mask */
+ attribute_deprecated int phase_shift;
+ attribute_deprecated int phase_mask;
+ int phase_count;
int linear;
enum SwrFilterType filter_type;
double kaiser_beta;
int dst_index;
int index= c->index;
int frac= c->frac;
- int sample_index = index >> c->phase_shift;
+ int sample_index = 0;
+
+ while (index >= c->phase_count) {
+ sample_index++;
+ index -= c->phase_count;
+ }
- index &= c->phase_mask;
for (dst_index = 0; dst_index < n; dst_index++) {
FELEM *filter = ((FELEM *) c->filter_bank) + c->filter_alloc * index;
frac -= c->src_incr;
index++;
}
- sample_index += index >> c->phase_shift;
- index &= c->phase_mask;
+
+ while (index >= c->phase_count) {
+ sample_index++;
+ index -= c->phase_count;
+ }
}
if(update_ctx){
int dst_index;
int index= c->index;
int frac= c->frac;
- int sample_index = index >> c->phase_shift;
+ int sample_index = 0;
#if FILTER_SHIFT == 0
double inv_src_incr = 1.0 / c->src_incr;
#endif
- index &= c->phase_mask;
+ while (index >= c->phase_count) {
+ sample_index++;
+ index -= c->phase_count;
+ }
+
for (dst_index = 0; dst_index < n; dst_index++) {
FELEM *filter = ((FELEM *) c->filter_bank) + c->filter_alloc * index;
FELEM2 val=0, v2 = 0;
frac -= c->src_incr;
index++;
}
- sample_index += index >> c->phase_shift;
- index &= c->phase_mask;
+
+ while (index >= c->phase_count) {
+ sample_index++;
+ index -= c->phase_count;
+ }
}
if(update_ctx){
#include <soxr.h>
static struct ResampleContext *create(struct ResampleContext *c, int out_rate, int in_rate, int filter_size, int phase_shift, int linear,
- double cutoff, enum AVSampleFormat format, enum SwrFilterType filter_type, double kaiser_beta, double precision, int cheby){
+ double cutoff, enum AVSampleFormat format, enum SwrFilterType filter_type, double kaiser_beta, double precision, int cheby, int exact_rational){
soxr_error_t error;
soxr_datatype_t type =
}
if (s->out_sample_rate!=s->in_sample_rate || (s->flags & SWR_FLAG_RESAMPLE)){
- s->resample = s->resampler->init(s->resample, s->out_sample_rate, s->in_sample_rate, s->filter_size, s->phase_shift, s->linear_interp, s->cutoff, s->int_sample_fmt, s->filter_type, s->kaiser_beta, s->precision, s->cheby);
+ s->resample = s->resampler->init(s->resample, s->out_sample_rate, s->in_sample_rate, s->filter_size, s->phase_shift, s->linear_interp, s->cutoff, s->int_sample_fmt, s->filter_type, s->kaiser_beta, s->precision, s->cheby, s->exact_rational);
if (!s->resample) {
av_log(s, AV_LOG_ERROR, "Failed to initialize resampler\n");
return AVERROR(ENOMEM);
};
typedef struct ResampleContext * (* resample_init_func)(struct ResampleContext *c, int out_rate, int in_rate, int filter_size, int phase_shift, int linear,
- double cutoff, enum AVSampleFormat format, enum SwrFilterType filter_type, double kaiser_beta, double precision, int cheby);
+ double cutoff, enum AVSampleFormat format, enum SwrFilterType filter_type, double kaiser_beta, double precision, int cheby, int exact_rational);
typedef void (* resample_free_func)(struct ResampleContext **c);
typedef int (* multiple_resample_func)(struct ResampleContext *c, AudioData *dst, int dst_size, AudioData *src, int src_size, int *consumed);
typedef int (* resample_flush_func)(struct SwrContext *c);
int filter_size; /**< length of each FIR filter in the resampling filterbank relative to the cutoff frequency */
int phase_shift; /**< log2 of the number of entries in the resampling polyphase filterbank */
int linear_interp; /**< if 1 then the resampling FIR filter will be linearly interpolated */
+ int exact_rational; /**< if 1 then enable non power of 2 phase_count */
double cutoff; /**< resampling cutoff frequency (swr: 6dB point; soxr: 0dB point). 1.0 corresponds to half the output sample rate */
int filter_type; /**< swr resampling filter type */
double kaiser_beta; /**< swr beta value for Kaiser window (only applicable if filter_type == AV_FILTER_TYPE_KAISER) */
#include "libavutil/avutil.h"
#define LIBSWRESAMPLE_VERSION_MAJOR 2
-#define LIBSWRESAMPLE_VERSION_MINOR 0
-#define LIBSWRESAMPLE_VERSION_MICRO 101
+#define LIBSWRESAMPLE_VERSION_MINOR 1
+#define LIBSWRESAMPLE_VERSION_MICRO 100
#define LIBSWRESAMPLE_VERSION_INT AV_VERSION_INT(LIBSWRESAMPLE_VERSION_MAJOR, \
LIBSWRESAMPLE_VERSION_MINOR, \
{
int av_unused mm_flags = av_get_cpu_flags();
+ /* FIXME use phase_count on asm */
+ if (c->phase_count != 1 << c->phase_shift)
+ return;
+
switch(c->format){
case AV_SAMPLE_FMT_S16P:
if (ARCH_X86_32 && EXTERNAL_MMXEXT(mm_flags)) {