00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "libavutil/libm.h"
00023 #include "libavutil/log.h"
00024 #include "internal.h"
00025 #include "audio_data.h"
00026
00027 #ifdef CONFIG_RESAMPLE_FLT
00028
00029 #define FILTER_SHIFT 0
00030 #define FELEM float
00031 #define FELEM2 float
00032 #define FELEML float
00033 #define WINDOW_TYPE 24
00034 #elifdef CONFIG_RESAMPLE_S32
00035
00036 #define FILTER_SHIFT 30
00037 #define FELEM int32_t
00038 #define FELEM2 int64_t
00039 #define FELEML int64_t
00040 #define FELEM_MAX INT32_MAX
00041 #define FELEM_MIN INT32_MIN
00042 #define WINDOW_TYPE 12
00043 #else
00044
00045 #define FILTER_SHIFT 15
00046 #define FELEM int16_t
00047 #define FELEM2 int32_t
00048 #define FELEML int64_t
00049 #define FELEM_MAX INT16_MAX
00050 #define FELEM_MIN INT16_MIN
00051 #define WINDOW_TYPE 9
00052 #endif
00053
00054 struct ResampleContext {
00055 AVAudioResampleContext *avr;
00056 AudioData *buffer;
00057 FELEM *filter_bank;
00058 int filter_length;
00059 int ideal_dst_incr;
00060 int dst_incr;
00061 int index;
00062 int frac;
00063 int src_incr;
00064 int compensation_distance;
00065 int phase_shift;
00066 int phase_mask;
00067 int linear;
00068 double factor;
00069 };
00070
00074 static double bessel(double x)
00075 {
00076 double v = 1;
00077 double lastv = 0;
00078 double t = 1;
00079 int i;
00080
00081 x = x * x / 4;
00082 for (i = 1; v != lastv; i++) {
00083 lastv = v;
00084 t *= x / (i * i);
00085 v += t;
00086 }
00087 return v;
00088 }
00089
00103 static int build_filter(FELEM *filter, double factor, int tap_count,
00104 int phase_count, int scale, int type)
00105 {
00106 int ph, i;
00107 double x, y, w;
00108 double *tab;
00109 const int center = (tap_count - 1) / 2;
00110
00111 tab = av_malloc(tap_count * sizeof(*tab));
00112 if (!tab)
00113 return AVERROR(ENOMEM);
00114
00115
00116 if (factor > 1.0)
00117 factor = 1.0;
00118
00119 for (ph = 0; ph < phase_count; ph++) {
00120 double norm = 0;
00121 for (i = 0; i < tap_count; i++) {
00122 x = M_PI * ((double)(i - center) - (double)ph / phase_count) * factor;
00123 if (x == 0) y = 1.0;
00124 else y = sin(x) / x;
00125 switch (type) {
00126 case 0: {
00127 const float d = -0.5;
00128 x = fabs(((double)(i - center) - (double)ph / phase_count) * factor);
00129 if (x < 1.0) y = 1 - 3 * x*x + 2 * x*x*x + d * ( -x*x + x*x*x);
00130 else y = d * (-4 + 8 * x - 5 * x*x + x*x*x);
00131 break;
00132 }
00133 case 1:
00134 w = 2.0 * x / (factor * tap_count) + M_PI;
00135 y *= 0.3635819 - 0.4891775 * cos( w) +
00136 0.1365995 * cos(2 * w) -
00137 0.0106411 * cos(3 * w);
00138 break;
00139 default:
00140 w = 2.0 * x / (factor * tap_count * M_PI);
00141 y *= bessel(type * sqrt(FFMAX(1 - w * w, 0)));
00142 break;
00143 }
00144
00145 tab[i] = y;
00146 norm += y;
00147 }
00148
00149
00150 for (i = 0; i < tap_count; i++) {
00151 #ifdef CONFIG_RESAMPLE_FLT
00152 filter[ph * tap_count + i] = tab[i] / norm;
00153 #else
00154 filter[ph * tap_count + i] = av_clip(lrintf(tab[i] * scale / norm),
00155 FELEM_MIN, FELEM_MAX);
00156 #endif
00157 }
00158 }
00159
00160 av_free(tab);
00161 return 0;
00162 }
00163
00164 ResampleContext *ff_audio_resample_init(AVAudioResampleContext *avr)
00165 {
00166 ResampleContext *c;
00167 int out_rate = avr->out_sample_rate;
00168 int in_rate = avr->in_sample_rate;
00169 double factor = FFMIN(out_rate * avr->cutoff / in_rate, 1.0);
00170 int phase_count = 1 << avr->phase_shift;
00171
00172
00173 if (avr->internal_sample_fmt != AV_SAMPLE_FMT_S16P) {
00174 av_log(avr, AV_LOG_ERROR, "Unsupported internal format for "
00175 "resampling: %s\n",
00176 av_get_sample_fmt_name(avr->internal_sample_fmt));
00177 return NULL;
00178 }
00179 c = av_mallocz(sizeof(*c));
00180 if (!c)
00181 return NULL;
00182
00183 c->avr = avr;
00184 c->phase_shift = avr->phase_shift;
00185 c->phase_mask = phase_count - 1;
00186 c->linear = avr->linear_interp;
00187 c->factor = factor;
00188 c->filter_length = FFMAX((int)ceil(avr->filter_size / factor), 1);
00189
00190 c->filter_bank = av_mallocz(c->filter_length * (phase_count + 1) * sizeof(FELEM));
00191 if (!c->filter_bank)
00192 goto error;
00193
00194 if (build_filter(c->filter_bank, factor, c->filter_length, phase_count,
00195 1 << FILTER_SHIFT, WINDOW_TYPE) < 0)
00196 goto error;
00197
00198 memcpy(&c->filter_bank[c->filter_length * phase_count + 1],
00199 c->filter_bank, (c->filter_length - 1) * sizeof(FELEM));
00200 c->filter_bank[c->filter_length * phase_count] = c->filter_bank[c->filter_length - 1];
00201
00202 c->compensation_distance = 0;
00203 if (!av_reduce(&c->src_incr, &c->dst_incr, out_rate,
00204 in_rate * (int64_t)phase_count, INT32_MAX / 2))
00205 goto error;
00206 c->ideal_dst_incr = c->dst_incr;
00207
00208 c->index = -phase_count * ((c->filter_length - 1) / 2);
00209 c->frac = 0;
00210
00211
00212 c->buffer = ff_audio_data_alloc(avr->resample_channels, 0,
00213 avr->internal_sample_fmt,
00214 "resample buffer");
00215 if (!c->buffer)
00216 goto error;
00217
00218 av_log(avr, AV_LOG_DEBUG, "resample: %s from %d Hz to %d Hz\n",
00219 av_get_sample_fmt_name(avr->internal_sample_fmt),
00220 avr->in_sample_rate, avr->out_sample_rate);
00221
00222 return c;
00223
00224 error:
00225 ff_audio_data_free(&c->buffer);
00226 av_free(c->filter_bank);
00227 av_free(c);
00228 return NULL;
00229 }
00230
00231 void ff_audio_resample_free(ResampleContext **c)
00232 {
00233 if (!*c)
00234 return;
00235 ff_audio_data_free(&(*c)->buffer);
00236 av_free((*c)->filter_bank);
00237 av_freep(c);
00238 }
00239
00240 int avresample_set_compensation(AVAudioResampleContext *avr, int sample_delta,
00241 int compensation_distance)
00242 {
00243 ResampleContext *c;
00244 AudioData *fifo_buf = NULL;
00245 int ret = 0;
00246
00247 if (compensation_distance < 0)
00248 return AVERROR(EINVAL);
00249 if (!compensation_distance && sample_delta)
00250 return AVERROR(EINVAL);
00251
00252
00253
00254 if (!avr->resample_needed) {
00255 int fifo_samples;
00256 double matrix[AVRESAMPLE_MAX_CHANNELS * AVRESAMPLE_MAX_CHANNELS] = { 0 };
00257
00258
00259 fifo_samples = av_audio_fifo_size(avr->out_fifo);
00260 if (fifo_samples > 0) {
00261 fifo_buf = ff_audio_data_alloc(avr->out_channels, fifo_samples,
00262 avr->out_sample_fmt, NULL);
00263 if (!fifo_buf)
00264 return AVERROR(EINVAL);
00265 ret = ff_audio_data_read_from_fifo(avr->out_fifo, fifo_buf,
00266 fifo_samples);
00267 if (ret < 0)
00268 goto reinit_fail;
00269 }
00270
00271 ret = avresample_get_matrix(avr, matrix, AVRESAMPLE_MAX_CHANNELS);
00272 if (ret < 0)
00273 goto reinit_fail;
00274
00275
00276 avresample_close(avr);
00277
00278 avr->force_resampling = 1;
00279
00280
00281 ret = avresample_set_matrix(avr, matrix, AVRESAMPLE_MAX_CHANNELS);
00282 if (ret < 0)
00283 goto reinit_fail;
00284
00285
00286 ret = avresample_open(avr);
00287 if (ret < 0)
00288 goto reinit_fail;
00289
00290
00291 if (fifo_samples > 0) {
00292 ret = ff_audio_data_add_to_fifo(avr->out_fifo, fifo_buf, 0,
00293 fifo_samples);
00294 if (ret < 0)
00295 goto reinit_fail;
00296 ff_audio_data_free(&fifo_buf);
00297 }
00298 }
00299 c = avr->resample;
00300 c->compensation_distance = compensation_distance;
00301 if (compensation_distance) {
00302 c->dst_incr = c->ideal_dst_incr - c->ideal_dst_incr *
00303 (int64_t)sample_delta / compensation_distance;
00304 } else {
00305 c->dst_incr = c->ideal_dst_incr;
00306 }
00307 return 0;
00308
00309 reinit_fail:
00310 ff_audio_data_free(&fifo_buf);
00311 return ret;
00312 }
00313
00314 static int resample(ResampleContext *c, int16_t *dst, const int16_t *src,
00315 int *consumed, int src_size, int dst_size, int update_ctx)
00316 {
00317 int dst_index, i;
00318 int index = c->index;
00319 int frac = c->frac;
00320 int dst_incr_frac = c->dst_incr % c->src_incr;
00321 int dst_incr = c->dst_incr / c->src_incr;
00322 int compensation_distance = c->compensation_distance;
00323
00324 if (!dst != !src)
00325 return AVERROR(EINVAL);
00326
00327 if (compensation_distance == 0 && c->filter_length == 1 &&
00328 c->phase_shift == 0) {
00329 int64_t index2 = ((int64_t)index) << 32;
00330 int64_t incr = (1LL << 32) * c->dst_incr / c->src_incr;
00331 dst_size = FFMIN(dst_size,
00332 (src_size-1-index) * (int64_t)c->src_incr /
00333 c->dst_incr);
00334
00335 if (dst) {
00336 for(dst_index = 0; dst_index < dst_size; dst_index++) {
00337 dst[dst_index] = src[index2 >> 32];
00338 index2 += incr;
00339 }
00340 } else {
00341 dst_index = dst_size;
00342 }
00343 index += dst_index * dst_incr;
00344 index += (frac + dst_index * (int64_t)dst_incr_frac) / c->src_incr;
00345 frac = (frac + dst_index * (int64_t)dst_incr_frac) % c->src_incr;
00346 } else {
00347 for (dst_index = 0; dst_index < dst_size; dst_index++) {
00348 FELEM *filter = c->filter_bank +
00349 c->filter_length * (index & c->phase_mask);
00350 int sample_index = index >> c->phase_shift;
00351
00352 if (!dst && (sample_index + c->filter_length > src_size ||
00353 -sample_index >= src_size))
00354 break;
00355
00356 if (dst) {
00357 FELEM2 val = 0;
00358
00359 if (sample_index < 0) {
00360 for (i = 0; i < c->filter_length; i++)
00361 val += src[FFABS(sample_index + i) % src_size] *
00362 (FELEM2)filter[i];
00363 } else if (sample_index + c->filter_length > src_size) {
00364 break;
00365 } else if (c->linear) {
00366 FELEM2 v2 = 0;
00367 for (i = 0; i < c->filter_length; i++) {
00368 val += src[abs(sample_index + i)] * (FELEM2)filter[i];
00369 v2 += src[abs(sample_index + i)] * (FELEM2)filter[i + c->filter_length];
00370 }
00371 val += (v2 - val) * (FELEML)frac / c->src_incr;
00372 } else {
00373 for (i = 0; i < c->filter_length; i++)
00374 val += src[sample_index + i] * (FELEM2)filter[i];
00375 }
00376
00377 #ifdef CONFIG_RESAMPLE_FLT
00378 dst[dst_index] = av_clip_int16(lrintf(val));
00379 #else
00380 val = (val + (1<<(FILTER_SHIFT-1)))>>FILTER_SHIFT;
00381 dst[dst_index] = av_clip_int16(val);
00382 #endif
00383 }
00384
00385 frac += dst_incr_frac;
00386 index += dst_incr;
00387 if (frac >= c->src_incr) {
00388 frac -= c->src_incr;
00389 index++;
00390 }
00391 if (dst_index + 1 == compensation_distance) {
00392 compensation_distance = 0;
00393 dst_incr_frac = c->ideal_dst_incr % c->src_incr;
00394 dst_incr = c->ideal_dst_incr / c->src_incr;
00395 }
00396 }
00397 }
00398 if (consumed)
00399 *consumed = FFMAX(index, 0) >> c->phase_shift;
00400
00401 if (update_ctx) {
00402 if (index >= 0)
00403 index &= c->phase_mask;
00404
00405 if (compensation_distance) {
00406 compensation_distance -= dst_index;
00407 if (compensation_distance <= 0)
00408 return AVERROR_BUG;
00409 }
00410 c->frac = frac;
00411 c->index = index;
00412 c->dst_incr = dst_incr_frac + c->src_incr*dst_incr;
00413 c->compensation_distance = compensation_distance;
00414 }
00415
00416 return dst_index;
00417 }
00418
00419 int ff_audio_resample(ResampleContext *c, AudioData *dst, AudioData *src,
00420 int *consumed)
00421 {
00422 int ch, in_samples, in_leftover, out_samples = 0;
00423 int ret = AVERROR(EINVAL);
00424
00425 in_samples = src ? src->nb_samples : 0;
00426 in_leftover = c->buffer->nb_samples;
00427
00428
00429 if (src) {
00430 ret = ff_audio_data_combine(c->buffer, in_leftover, src, 0, in_samples);
00431 if (ret < 0)
00432 return ret;
00433 } else if (!in_leftover) {
00434
00435 return 0;
00436 } else {
00437
00438 }
00439
00440
00441
00442 if (!dst->read_only && dst->allow_realloc) {
00443 out_samples = resample(c, NULL, NULL, NULL, c->buffer->nb_samples,
00444 INT_MAX, 0);
00445 ret = ff_audio_data_realloc(dst, out_samples);
00446 if (ret < 0) {
00447 av_log(c->avr, AV_LOG_ERROR, "error reallocating output\n");
00448 return ret;
00449 }
00450 }
00451
00452
00453 for (ch = 0; ch < c->buffer->channels; ch++) {
00454 out_samples = resample(c, (int16_t *)dst->data[ch],
00455 (const int16_t *)c->buffer->data[ch], consumed,
00456 c->buffer->nb_samples, dst->allocated_samples,
00457 ch + 1 == c->buffer->channels);
00458 }
00459 if (out_samples < 0) {
00460 av_log(c->avr, AV_LOG_ERROR, "error during resampling\n");
00461 return out_samples;
00462 }
00463
00464
00465 ff_audio_data_drain(c->buffer, *consumed);
00466
00467 av_dlog(c->avr, "resampled %d in + %d leftover to %d out + %d leftover\n",
00468 in_samples, in_leftover, out_samples, c->buffer->nb_samples);
00469
00470 dst->nb_samples = out_samples;
00471 return 0;
00472 }
00473
00474 int avresample_get_delay(AVAudioResampleContext *avr)
00475 {
00476 if (!avr->resample_needed || !avr->resample)
00477 return 0;
00478
00479 return avr->resample->buffer->nb_samples;
00480 }