ffmpeg / libavcodec / resample2.c @ da9c9637
History  View  Annotate  Download (7.44 KB)
1 
/*


2 
* audio resampling

3 
* Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>

4 
*

5 
* This library is free software; you can redistribute it and/or

6 
* modify it under the terms of the GNU Lesser General Public

7 
* License as published by the Free Software Foundation; either

8 
* version 2 of the License, or (at your option) any later version.

9 
*

10 
* This library is distributed in the hope that it will be useful,

11 
* but WITHOUT ANY WARRANTY; without even the implied warranty of

12 
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU

13 
* Lesser General Public License for more details.

14 
*

15 
* You should have received a copy of the GNU Lesser General Public

16 
* License along with this library; if not, write to the Free Software

17 
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 021111307 USA

18 
*

19 
*/

20 

21 
/**

22 
* @file resample2.c

23 
* audio resampling

24 
* @author Michael Niedermayer <michaelni@gmx.at>

25 
*/

26  
27 
#include "avcodec.h" 
28 
#include "common.h" 
29 
#include "dsputil.h" 
30  
31 
#define PHASE_SHIFT 10 
32 
#define PHASE_COUNT (1<<PHASE_SHIFT) 
33 
#define PHASE_MASK (PHASE_COUNT1) 
34 
#define FILTER_SHIFT 15 
35  
36 
typedef struct AVResampleContext{ 
37 
short *filter_bank;

38 
int filter_length;

39 
int ideal_dst_incr;

40 
int dst_incr;

41 
int index;

42 
int frac;

43 
int src_incr;

44 
int compensation_distance;

45 
}AVResampleContext; 
46  
47 
/**

48 
* 0th order modified bessel function of the first kind.

49 
*/

50 
double bessel(double x){ 
51 
double v=1; 
52 
double t=1; 
53 
int i;

54 

55 
for(i=1; i<50; i++){ 
56 
t *= i; 
57 
v += pow(x*x/4, i)/(t*t);

58 
} 
59 
return v;

60 
} 
61  
62 
/**

63 
* builds a polyphase filterbank.

64 
* @param factor resampling factor

65 
* @param scale wanted sum of coefficients for each filter

66 
* @param type 0>cubic, 1>blackman nuttall windowed sinc, 2>kaiser windowed sinc beta=16

67 
*/

68 
void av_build_filter(int16_t *filter, double factor, int tap_count, int phase_count, int scale, int type){ 
69 
int ph, i, v;

70 
double x, y, w, tab[tap_count];

71 
const int center= (tap_count1)/2; 
72  
73 
/* if upsampling, only need to interpolate, no filter */

74 
if (factor > 1.0) 
75 
factor = 1.0; 
76  
77 
for(ph=0;ph<phase_count;ph++) { 
78 
double norm = 0; 
79 
double e= 0; 
80 
for(i=0;i<tap_count;i++) { 
81 
x = M_PI * ((double)(i  center)  (double)ph / phase_count) * factor; 
82 
if (x == 0) y = 1.0; 
83 
else y = sin(x) / x;

84 
switch(type){

85 
case 0:{ 
86 
const float d= 0.5; //first order derivative = 0.5 
87 
x = fabs(((double)(i  center)  (double)ph / phase_count) * factor); 
88 
if(x<1.0) y= 1  3*x*x + 2*x*x*x + d*( x*x + x*x*x); 
89 
else y= d*(4 + 8*x  5*x*x + x*x*x); 
90 
break;}

91 
case 1: 
92 
w = 2.0*x / (factor*tap_count) + M_PI; 
93 
y *= 0.3635819  0.4891775 * cos(w) + 0.1365995 * cos(2*w)  0.0106411 * cos(3*w); 
94 
break;

95 
case 2: 
96 
w = 2.0*x / (factor*tap_count*M_PI); 
97 
y *= bessel(16*sqrt(FFMAX(1w*w, 0))); 
98 
break;

99 
} 
100  
101 
tab[i] = y; 
102 
norm += y; 
103 
} 
104  
105 
/* normalize so that an uniform color remains the same */

106 
for(i=0;i<tap_count;i++) { 
107 
v = clip(lrintf(tab[i] * scale / norm + e), 32768, 32767); 
108 
filter[ph * tap_count + i] = v; 
109 
e += tab[i] * scale / norm  v; 
110 
} 
111 
} 
112 
} 
113  
114 
/**

115 
* initalizes a audio resampler.

116 
* note, if either rate is not a integer then simply scale both rates up so they are

117 
*/

118 
AVResampleContext *av_resample_init(int out_rate, int in_rate){ 
119 
AVResampleContext *c= av_mallocz(sizeof(AVResampleContext));

120 
double factor= FFMIN(out_rate / (double)in_rate, 1.0); 
121  
122 
memset(c, 0, sizeof(AVResampleContext)); 
123  
124 
c>filter_length= ceil(16.0/factor); 
125 
c>filter_bank= av_mallocz(c>filter_length*(PHASE_COUNT+1)*sizeof(short)); 
126 
av_build_filter(c>filter_bank, factor, c>filter_length, PHASE_COUNT, 1<<FILTER_SHIFT, 1); 
127 
c>filter_bank[c>filter_length*PHASE_COUNT + (c>filter_length1)/2 + 1]= (1<<FILTER_SHIFT)1; 
128 
c>filter_bank[c>filter_length*PHASE_COUNT + (c>filter_length1)/2 + 2]= 1; 
129  
130 
c>src_incr= out_rate; 
131 
c>ideal_dst_incr= c>dst_incr= in_rate * PHASE_COUNT; 
132 
c>index= PHASE_COUNT*((c>filter_length1)/2); 
133  
134 
return c;

135 
} 
136  
137 
void av_resample_close(AVResampleContext *c){

138 
av_freep(&c>filter_bank); 
139 
av_freep(&c); 
140 
} 
141  
142 
void av_resample_compensate(AVResampleContext *c, int sample_delta, int compensation_distance){ 
143 
// sample_delta += (c>ideal_dst_incr  c>dst_incr)*(int64_t)c>compensation_distance / c>ideal_dst_incr;

144 
c>compensation_distance= compensation_distance; 
145 
c>dst_incr = c>ideal_dst_incr  c>ideal_dst_incr * (int64_t)sample_delta / compensation_distance; 
146 
} 
147  
148 
/**

149 
* resamples.

150 
* @param src an array of unconsumed samples

151 
* @param consumed the number of samples of src which have been consumed are returned here

152 
* @param src_size the number of unconsumed samples available

153 
* @param dst_size the amount of space in samples available in dst

154 
* @param update_ctx if this is 0 then the context wont be modified, that way several channels can be resampled with the same context

155 
* @return the number of samples written in dst or 1 if an error occured

156 
*/

157 
int av_resample(AVResampleContext *c, short *dst, short *src, int *consumed, int src_size, int dst_size, int update_ctx){ 
158 
int dst_index, i;

159 
int index= c>index;

160 
int frac= c>frac;

161 
int dst_incr_frac= c>dst_incr % c>src_incr;

162 
int dst_incr= c>dst_incr / c>src_incr;

163 

164 
if(c>compensation_distance && c>compensation_distance < dst_size)

165 
dst_size= c>compensation_distance; 
166 

167 
for(dst_index=0; dst_index < dst_size; dst_index++){ 
168 
short *filter= c>filter_bank + c>filter_length*(index & PHASE_MASK);

169 
int sample_index= index >> PHASE_SHIFT;

170 
int val=0; 
171 

172 
if(sample_index < 0){ 
173 
for(i=0; i<c>filter_length; i++) 
174 
val += src[ABS(sample_index + i) % src_size] * filter[i]; 
175 
}else if(sample_index + c>filter_length > src_size){ 
176 
break;

177 
}else{

178 
#if 0

179 
int64_t v=0;

180 
int sub_phase= (frac<<12) / c>src_incr;

181 
for(i=0; i<c>filter_length; i++){

182 
int64_t coeff= filter[i]*(4096  sub_phase) + filter[i + c>filter_length]*sub_phase;

183 
v += src[sample_index + i] * coeff;

184 
}

185 
val= v>>12;

186 
#else

187 
for(i=0; i<c>filter_length; i++){ 
188 
val += src[sample_index + i] * filter[i]; 
189 
} 
190 
#endif

191 
} 
192  
193 
val = (val + (1<<(FILTER_SHIFT1)))>>FILTER_SHIFT; 
194 
dst[dst_index] = (unsigned)(val + 32768) > 65535 ? (val>>31) ^ 32767 : val; 
195  
196 
frac += dst_incr_frac; 
197 
index += dst_incr; 
198 
if(frac >= c>src_incr){

199 
frac = c>src_incr; 
200 
index++; 
201 
} 
202 
} 
203 
*consumed= FFMAX(index, 0) >> PHASE_SHIFT;

204 
index= FFMIN(index, 0);

205  
206 
if(update_ctx){

207 
if(c>compensation_distance){

208 
c>compensation_distance = dst_index; 
209 
if(!c>compensation_distance)

210 
c>dst_incr= c>ideal_dst_incr; 
211 
} 
212 
c>frac= frac; 
213 
c>index= index; 
214 
} 
215 
#if 0

216 
if(update_ctx && !c>compensation_distance){

217 
#undef rand

218 
av_resample_compensate(c, rand() % (8000*2)  8000, 8000*2);

219 
av_log(NULL, AV_LOG_DEBUG, "%d %d %d\n", c>dst_incr, c>ideal_dst_incr, c>compensation_distance);

220 
}

221 
#endif

222 

223 
return dst_index;

224 
} 