annotate ffmpeg/libswresample/resample_template.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents f445c3017523
children
rev   line source
yading@11 1 /*
yading@11 2 * audio resampling
yading@11 3 * Copyright (c) 2004-2012 Michael Niedermayer <michaelni@gmx.at>
yading@11 4 *
yading@11 5 * This file is part of FFmpeg.
yading@11 6 *
yading@11 7 * FFmpeg is free software; you can redistribute it and/or
yading@11 8 * modify it under the terms of the GNU Lesser General Public
yading@11 9 * License as published by the Free Software Foundation; either
yading@11 10 * version 2.1 of the License, or (at your option) any later version.
yading@11 11 *
yading@11 12 * FFmpeg is distributed in the hope that it will be useful,
yading@11 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@11 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@11 15 * Lesser General Public License for more details.
yading@11 16 *
yading@11 17 * You should have received a copy of the GNU Lesser General Public
yading@11 18 * License along with FFmpeg; if not, write to the Free Software
yading@11 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@11 20 */
yading@11 21
yading@11 22 /**
yading@11 23 * @file
yading@11 24 * audio resampling
yading@11 25 * @author Michael Niedermayer <michaelni@gmx.at>
yading@11 26 */
yading@11 27
yading@11 28 #if defined(TEMPLATE_RESAMPLE_DBL)
yading@11 29 # define RENAME(N) N ## _double
yading@11 30 # define FILTER_SHIFT 0
yading@11 31 # define DELEM double
yading@11 32 # define FELEM double
yading@11 33 # define FELEM2 double
yading@11 34 # define FELEML double
yading@11 35 # define OUT(d, v) d = v
yading@11 36
yading@11 37 #elif defined(TEMPLATE_RESAMPLE_FLT)
yading@11 38 # define RENAME(N) N ## _float
yading@11 39 # define FILTER_SHIFT 0
yading@11 40 # define DELEM float
yading@11 41 # define FELEM float
yading@11 42 # define FELEM2 float
yading@11 43 # define FELEML float
yading@11 44 # define OUT(d, v) d = v
yading@11 45
yading@11 46 #elif defined(TEMPLATE_RESAMPLE_S32)
yading@11 47 # define RENAME(N) N ## _int32
yading@11 48 # define FILTER_SHIFT 30
yading@11 49 # define DELEM int32_t
yading@11 50 # define FELEM int32_t
yading@11 51 # define FELEM2 int64_t
yading@11 52 # define FELEML int64_t
yading@11 53 # define FELEM_MAX INT32_MAX
yading@11 54 # define FELEM_MIN INT32_MIN
yading@11 55 # define OUT(d, v) v = (v + (1<<(FILTER_SHIFT-1)))>>FILTER_SHIFT;\
yading@11 56 d = (uint64_t)(v + 0x80000000) > 0xFFFFFFFF ? (v>>63) ^ 0x7FFFFFFF : v
yading@11 57
yading@11 58 #elif defined(TEMPLATE_RESAMPLE_S16) \
yading@11 59 || defined(TEMPLATE_RESAMPLE_S16_MMX2) \
yading@11 60 || defined(TEMPLATE_RESAMPLE_S16_SSSE3)
yading@11 61
yading@11 62 # define FILTER_SHIFT 15
yading@11 63 # define DELEM int16_t
yading@11 64 # define FELEM int16_t
yading@11 65 # define FELEM2 int32_t
yading@11 66 # define FELEML int64_t
yading@11 67 # define FELEM_MAX INT16_MAX
yading@11 68 # define FELEM_MIN INT16_MIN
yading@11 69 # define OUT(d, v) v = (v + (1<<(FILTER_SHIFT-1)))>>FILTER_SHIFT;\
yading@11 70 d = (unsigned)(v + 32768) > 65535 ? (v>>31) ^ 32767 : v
yading@11 71
yading@11 72 # if defined(TEMPLATE_RESAMPLE_S16)
yading@11 73 # define RENAME(N) N ## _int16
yading@11 74 # elif defined(TEMPLATE_RESAMPLE_S16_MMX2)
yading@11 75 # define COMMON_CORE COMMON_CORE_INT16_MMX2
yading@11 76 # define RENAME(N) N ## _int16_mmx2
yading@11 77 # elif defined(TEMPLATE_RESAMPLE_S16_SSSE3)
yading@11 78 # define COMMON_CORE COMMON_CORE_INT16_SSSE3
yading@11 79 # define RENAME(N) N ## _int16_ssse3
yading@11 80 # endif
yading@11 81
yading@11 82 #endif
yading@11 83
yading@11 84 int RENAME(swri_resample)(ResampleContext *c, DELEM *dst, const DELEM *src, int *consumed, int src_size, int dst_size, int update_ctx){
yading@11 85 int dst_index, i;
yading@11 86 int index= c->index;
yading@11 87 int frac= c->frac;
yading@11 88 int dst_incr_frac= c->dst_incr % c->src_incr;
yading@11 89 int dst_incr= c->dst_incr / c->src_incr;
yading@11 90 int compensation_distance= c->compensation_distance;
yading@11 91
yading@11 92 av_assert1(c->filter_shift == FILTER_SHIFT);
yading@11 93 av_assert1(c->felem_size == sizeof(FELEM));
yading@11 94
yading@11 95 if(compensation_distance == 0 && c->filter_length == 1 && c->phase_shift==0){
yading@11 96 int64_t index2= ((int64_t)index)<<32;
yading@11 97 int64_t incr= (1LL<<32) * c->dst_incr / c->src_incr;
yading@11 98 dst_size= FFMIN(dst_size, (src_size-1-index) * (int64_t)c->src_incr / c->dst_incr);
yading@11 99
yading@11 100 for(dst_index=0; dst_index < dst_size; dst_index++){
yading@11 101 dst[dst_index] = src[index2>>32];
yading@11 102 index2 += incr;
yading@11 103 }
yading@11 104 index += dst_index * dst_incr;
yading@11 105 index += (frac + dst_index * (int64_t)dst_incr_frac) / c->src_incr;
yading@11 106 frac = (frac + dst_index * (int64_t)dst_incr_frac) % c->src_incr;
yading@11 107 av_assert2(index >= 0);
yading@11 108 *consumed= index >> c->phase_shift;
yading@11 109 index &= c->phase_mask;
yading@11 110 }else if(compensation_distance == 0 && !c->linear && index >= 0){
yading@11 111 int sample_index = 0;
yading@11 112 for(dst_index=0; dst_index < dst_size; dst_index++){
yading@11 113 FELEM *filter;
yading@11 114 sample_index += index >> c->phase_shift;
yading@11 115 index &= c->phase_mask;
yading@11 116 filter= ((FELEM*)c->filter_bank) + c->filter_alloc*index;
yading@11 117
yading@11 118 if(sample_index + c->filter_length > src_size){
yading@11 119 break;
yading@11 120 }else{
yading@11 121 #ifdef COMMON_CORE
yading@11 122 COMMON_CORE
yading@11 123 #else
yading@11 124 FELEM2 val=0;
yading@11 125 for(i=0; i<c->filter_length; i++){
yading@11 126 val += src[sample_index + i] * (FELEM2)filter[i];
yading@11 127 }
yading@11 128 OUT(dst[dst_index], val);
yading@11 129 #endif
yading@11 130 }
yading@11 131
yading@11 132 frac += dst_incr_frac;
yading@11 133 index += dst_incr;
yading@11 134 if(frac >= c->src_incr){
yading@11 135 frac -= c->src_incr;
yading@11 136 index++;
yading@11 137 }
yading@11 138 }
yading@11 139 *consumed = sample_index;
yading@11 140 }else{
yading@11 141 int sample_index = 0;
yading@11 142 for(dst_index=0; dst_index < dst_size; dst_index++){
yading@11 143 FELEM *filter;
yading@11 144 FELEM2 val=0;
yading@11 145
yading@11 146 sample_index += index >> c->phase_shift;
yading@11 147 index &= c->phase_mask;
yading@11 148 filter = ((FELEM*)c->filter_bank) + c->filter_alloc*index;
yading@11 149
yading@11 150 if(sample_index + c->filter_length > src_size || -sample_index >= src_size){
yading@11 151 break;
yading@11 152 }else if(sample_index < 0){
yading@11 153 for(i=0; i<c->filter_length; i++)
yading@11 154 val += src[FFABS(sample_index + i)] * (FELEM2)filter[i];
yading@11 155 }else if(c->linear){
yading@11 156 FELEM2 v2=0;
yading@11 157 for(i=0; i<c->filter_length; i++){
yading@11 158 val += src[sample_index + i] * (FELEM2)filter[i];
yading@11 159 v2 += src[sample_index + i] * (FELEM2)filter[i + c->filter_alloc];
yading@11 160 }
yading@11 161 val+=(v2-val)*(FELEML)frac / c->src_incr;
yading@11 162 }else{
yading@11 163 for(i=0; i<c->filter_length; i++){
yading@11 164 val += src[sample_index + i] * (FELEM2)filter[i];
yading@11 165 }
yading@11 166 }
yading@11 167
yading@11 168 OUT(dst[dst_index], val);
yading@11 169
yading@11 170 frac += dst_incr_frac;
yading@11 171 index += dst_incr;
yading@11 172 if(frac >= c->src_incr){
yading@11 173 frac -= c->src_incr;
yading@11 174 index++;
yading@11 175 }
yading@11 176
yading@11 177 if(dst_index + 1 == compensation_distance){
yading@11 178 compensation_distance= 0;
yading@11 179 dst_incr_frac= c->ideal_dst_incr % c->src_incr;
yading@11 180 dst_incr= c->ideal_dst_incr / c->src_incr;
yading@11 181 }
yading@11 182 }
yading@11 183 *consumed= FFMAX(sample_index, 0);
yading@11 184 index += FFMIN(sample_index, 0) << c->phase_shift;
yading@11 185
yading@11 186 if(compensation_distance){
yading@11 187 compensation_distance -= dst_index;
yading@11 188 av_assert1(compensation_distance > 0);
yading@11 189 }
yading@11 190 }
yading@11 191
yading@11 192 if(update_ctx){
yading@11 193 c->frac= frac;
yading@11 194 c->index= index;
yading@11 195 c->dst_incr= dst_incr_frac + c->src_incr*dst_incr;
yading@11 196 c->compensation_distance= compensation_distance;
yading@11 197 }
yading@11 198
yading@11 199 return dst_index;
yading@11 200 }
yading@11 201
yading@11 202 #undef COMMON_CORE
yading@11 203 #undef RENAME
yading@11 204 #undef FILTER_SHIFT
yading@11 205 #undef DELEM
yading@11 206 #undef FELEM
yading@11 207 #undef FELEM2
yading@11 208 #undef FELEML
yading@11 209 #undef FELEM_MAX
yading@11 210 #undef FELEM_MIN
yading@11 211 #undef OUT