1/* 2 * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at> 3 * 4 * This file is part of FFmpeg. 5 * 6 * FFmpeg is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * FFmpeg is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with FFmpeg; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21#include <math.h> 22#include <stdint.h> 23 24#include "libavutil/common.h" 25#include "internal.h" 26 27#if defined(CONFIG_RESAMPLE_DBL) 28#define SET_TYPE(func) func ## _dbl 29#define FELEM double 30#define FELEM2 double 31#define FELEML double 32#define OUT(d, v) d = v 33#define DBL_TO_FELEM(d, v) d = v 34#elif defined(CONFIG_RESAMPLE_FLT) 35#define SET_TYPE(func) func ## _flt 36#define FELEM float 37#define FELEM2 float 38#define FELEML float 39#define OUT(d, v) d = v 40#define DBL_TO_FELEM(d, v) d = v 41#elif defined(CONFIG_RESAMPLE_S32) 42#define SET_TYPE(func) func ## _s32 43#define FELEM int32_t 44#define FELEM2 int64_t 45#define FELEML int64_t 46#define OUT(d, v) d = av_clipl_int32((v + (1 << 29)) >> 30) 47#define DBL_TO_FELEM(d, v) d = av_clipl_int32(llrint(v * (1 << 30))); 48#else 49#define SET_TYPE(func) func ## _s16 50#define FELEM int16_t 51#define FELEM2 int32_t 52#define FELEML int64_t 53#define OUT(d, v) d = av_clip_int16((v + (1 << 14)) >> 15) 54#define DBL_TO_FELEM(d, v) d = av_clip_int16(lrint(v * (1 << 15))) 55#endif 56 57static void SET_TYPE(resample_nearest)(void *dst0, int dst_index, const void *src0, unsigned int index) 58{ 59 FELEM *dst = dst0; 60 const FELEM *src = src0; 61 dst[dst_index] = src[index]; 62} 63 64static void SET_TYPE(resample_linear)(ResampleContext *c, void *dst0, int dst_index, 65 const void *src0, unsigned int index, int frac) 66{ 67 FELEM *dst = dst0; 68 const FELEM *src = src0; 69 int i; 70 unsigned int sample_index = index >> c->phase_shift; 71 FELEM2 val = 0; 72 FELEM *filter = ((FELEM *)c->filter_bank) + 73 c->filter_length * (index & c->phase_mask); 74 FELEM2 v2 = 0; 75 76 for (i = 0; i < c->filter_length; i++) { 77 val += src[sample_index + i] * (FELEM2)filter[i]; 78 v2 += src[sample_index + i] * (FELEM2)filter[i + c->filter_length]; 79 } 80 val += (v2 - val) * (FELEML)frac / c->src_incr; 81 82 OUT(dst[dst_index], val); 83} 84 85static void SET_TYPE(resample_one)(ResampleContext *c, 86 void *dst0, int dst_index, const void *src0, 87 unsigned int index, int frac) 88{ 89 FELEM *dst = dst0; 90 const FELEM *src = src0; 91 int i; 92 unsigned int sample_index = index >> c->phase_shift; 93 FELEM2 val = 0; 94 FELEM *filter = ((FELEM *)c->filter_bank) + 95 c->filter_length * (index & c->phase_mask); 96 97 for (i = 0; i < c->filter_length; i++) 98 val += src[sample_index + i] * (FELEM2)filter[i]; 99 100 OUT(dst[dst_index], val); 101} 102 103static void SET_TYPE(set_filter)(void *filter0, double *tab, int phase, 104 int tap_count) 105{ 106 int i; 107 FELEM *filter = ((FELEM *)filter0) + phase * tap_count; 108 for (i = 0; i < tap_count; i++) { 109 DBL_TO_FELEM(filter[i], tab[i]); 110 } 111} 112 113#undef SET_TYPE 114#undef FELEM 115#undef FELEM2 116#undef FELEML 117#undef OUT 118#undef DBL_TO_FELEM 119