int av_audio_convert(AVAudioConvert *ctx, void * const out[6], const int out_stride[6], const void * const in[6], const int in_stride[6], int len) { int ch; //FIXME optimize common cases for(ch=0; ch<ctx->out_channels; ch++){ const int is= in_stride[ch]; const int os= out_stride[ch]; const uint8_t *pi= in[ch]; uint8_t *po= out[ch]; uint8_t *end= po + os*len; if(!out[ch]) continue; #define CONV(ofmt, otype, ifmt, expr)\ if(ctx->fmt_pair == ofmt + AV_SAMPLE_FMT_NB*ifmt){\ do{\ *(otype*)po = expr; pi += is; po += os;\ }while(po < end);\ } //FIXME put things below under ifdefs so we do not waste space for cases no codec will need //FIXME rounding ? CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_U8 , *(const uint8_t*)pi) else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)<<8) else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)<<24) else CONV(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0 / (1<<7))) else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0 / (1<<7))) else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_S16, (*(const int16_t*)pi>>8) + 0x80) else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S16, *(const int16_t*)pi) else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S16, *(const int16_t*)pi<<16) else CONV(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_S16, *(const int16_t*)pi*(1.0 / (1<<15))) else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_S16, *(const int16_t*)pi*(1.0 / (1<<15))) else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_S32, (*(const int32_t*)pi>>24) + 0x80) else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S32, *(const int32_t*)pi>>16) else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S32, *(const int32_t*)pi) else CONV(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_S32, *(const int32_t*)pi*(1.0 / (1U<<31))) else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_S32, *(const int32_t*)pi*(1.0 / (1U<<31))) else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8( lrintf(*(const float*)pi * (1<<7)) + 0x80)) else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16( lrintf(*(const float*)pi * (1<<15)))) else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float*)pi * (1U<<31)))) else CONV(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_FLT, *(const float*)pi) else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_FLT, *(const float*)pi) else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8( lrint(*(const double*)pi * (1<<7)) + 0x80)) else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16( lrint(*(const double*)pi * (1<<15)))) else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double*)pi * (1U<<31)))) else CONV(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_DBL, *(const double*)pi) else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_DBL, *(const double*)pi) else return -1; } return 0; }
/** * Decode 32 samples from 18 bytes. * * A 16-bit scalar value is applied to 32 residuals, which then have a * 2nd-order LPC filter applied to it to form the output signal for a single * channel. */ static int adx_decode(ADXContext *c, int16_t *out, const uint8_t *in, int ch) { ADXChannelState *prev = &c->prev[ch]; GetBitContext gb; int scale = AV_RB16(in); int i; int s0, s1, s2, d; /* check if this is an EOF packet */ if (scale & 0x8000) return -1; init_get_bits(&gb, in + 2, (BLOCK_SIZE - 2) * 8); s1 = prev->s1; s2 = prev->s2; for (i = 0; i < BLOCK_SAMPLES; i++) { d = get_sbits(&gb, 4); s0 = ((d << COEFF_BITS) * scale + c->coeff[0] * s1 + c->coeff[1] * s2) >> COEFF_BITS; s2 = s1; s1 = av_clip_int16(s0); *out = s1; out += c->channels; } prev->s1 = s1; prev->s2 = s2; return 0; }
static inline uint8_t adpcm_ms_compress_sample(ADPCMChannelStatus *c, int16_t sample) { int predictor, nibble, bias; predictor = (((c->sample1) * (c->coeff1)) + (( c->sample2) * (c->coeff2))) / 64; nibble = sample - predictor; if (nibble >= 0) bias = c->idelta / 2; else bias = -c->idelta / 2; nibble = (nibble + bias) / c->idelta; nibble = av_clip(nibble, -8, 7) & 0x0F; predictor += ((nibble & 0x08) ? (nibble - 0x10) : nibble) * c->idelta; c->sample2 = c->sample1; c->sample1 = av_clip_int16(predictor); c->idelta = (ff_adpcm_AdaptationTable[nibble] * c->idelta) >> 8; if (c->idelta < 16) c->idelta = 16; return nibble; }
static void decode_audio_s16(int16_t *out, const uint8_t *buf, int buf_size, int channels) { int ch; const uint8_t *buf_end = buf + buf_size; int predictor[2]; int st = channels - 1; /* decode initial raw sample */ for (ch = 0; ch < channels; ch++) { predictor[ch] = (int16_t)AV_RL16(buf); buf += 2; *out++ = predictor[ch]; } /* decode DPCM samples */ ch = 0; while (buf < buf_end) { uint8_t b = *buf++; if (b & 0x80) predictor[ch] -= vmdaudio_table[b & 0x7F]; else predictor[ch] += vmdaudio_table[b]; predictor[ch] = av_clip_int16(predictor[ch]); *out++ = predictor[ch]; ch ^= st; } }
static int cinaudio_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { AVFrame *frame = data; const uint8_t *buf = avpkt->data; CinAudioContext *cin = avctx->priv_data; const uint8_t *buf_end = buf + avpkt->size; int16_t *samples; int delta, ret; /* get output buffer */ frame->nb_samples = avpkt->size - cin->initial_decode_frame; if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; samples = (int16_t *)frame->data[0]; delta = cin->delta; if (cin->initial_decode_frame) { cin->initial_decode_frame = 0; delta = sign_extend(AV_RL16(buf), 16); buf += 2; *samples++ = delta; } while (buf < buf_end) { delta += cinaudio_delta16_table[*buf++]; delta = av_clip_int16(delta); *samples++ = delta; } cin->delta = delta; *got_frame_ptr = 1; return avpkt->size; }
static inline uint8_t adpcm_ima_qt_compress_sample(ADPCMChannelStatus *c, int16_t sample) { int delta = sample - c->prev_sample; int mask, step = ff_adpcm_step_table[c->step_index]; int diff = step >> 3; int nibble = 0; if (delta < 0) { nibble = 8; delta = -delta; } for (mask = 4; mask;) { if (delta >= step) { nibble |= mask; delta -= step; diff += step; } step >>= 1; mask >>= 1; } if (nibble & 8) c->prev_sample -= diff; else c->prev_sample += diff; c->prev_sample = av_clip_int16(c->prev_sample); c->step_index = av_clip(c->step_index + ff_adpcm_index_table[nibble], 0, 88); return nibble; }
/** Uncompress one block (20 bytes -> 160*2 bytes). */ static int ra144_decode_frame(AVCodecContext * avctx, void *vdata, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; static const uint8_t sizes[10] = {6, 5, 5, 4, 4, 3, 3, 3, 3, 2}; unsigned int refl_rms[4]; // RMS of the reflection coefficients uint16_t block_coefs[4][10]; // LPC coefficients of each sub-block unsigned int lpc_refl[10]; // LPC reflection coefficients of the frame int i, j; int16_t *data = vdata; unsigned int energy; RA144Context *ractx = avctx->priv_data; GetBitContext gb; if (*data_size < 2*160) return -1; if(buf_size < 20) { av_log(avctx, AV_LOG_ERROR, "Frame too small (%d bytes). Truncated file?\n", buf_size); *data_size = 0; return buf_size; } init_get_bits(&gb, buf, 20 * 8); for (i=0; i<10; i++) lpc_refl[i] = ff_lpc_refl_cb[i][get_bits(&gb, sizes[i])]; ff_eval_coefs(ractx->lpc_coef[0], lpc_refl); ractx->lpc_refl_rms[0] = ff_rms(lpc_refl); energy = ff_energy_tab[get_bits(&gb, 5)]; refl_rms[0] = ff_interp(ractx, block_coefs[0], 1, 1, ractx->old_energy); refl_rms[1] = ff_interp(ractx, block_coefs[1], 2, energy <= ractx->old_energy, ff_t_sqrt(energy*ractx->old_energy) >> 12); refl_rms[2] = ff_interp(ractx, block_coefs[2], 3, 0, energy); refl_rms[3] = ff_rescale_rms(ractx->lpc_refl_rms[0], energy); ff_int_to_int16(block_coefs[3], ractx->lpc_coef[0]); for (i=0; i < 4; i++) { do_output_subblock(ractx, block_coefs[i], refl_rms[i], &gb); for (j=0; j < BLOCKSIZE; j++) *data++ = av_clip_int16(ractx->curr_sblock[j + 10] << 2); } ractx->old_energy = energy; ractx->lpc_refl_rms[1] = ractx->lpc_refl_rms[0]; FFSWAP(unsigned int *, ractx->lpc_coef[0], ractx->lpc_coef[1]); *data_size = 2*160; return 20; }
static inline unsigned char adpcm_ima_compress_sample(ADPCMChannelStatus *c, short sample) { int delta = sample - c->prev_sample; int nibble = FFMIN(7, abs(delta)*4/ff_adpcm_step_table[c->step_index]) + (delta<0)*8; c->prev_sample += ((ff_adpcm_step_table[c->step_index] * ff_adpcm_yamaha_difflookup[nibble]) / 8); c->prev_sample = av_clip_int16(c->prev_sample); c->step_index = av_clip(c->step_index + ff_adpcm_index_table[nibble], 0, 88); return nibble; }
static int cng_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { AVFrame *frame = data; CNGContext *p = avctx->priv_data; int buf_size = avpkt->size; int ret, i; int16_t *buf_out; float e = 1.0; float scaling; if (avpkt->size) { int dbov = -avpkt->data[0]; p->target_energy = 1081109975 * ff_exp10(dbov / 10.0) * 0.75; memset(p->target_refl_coef, 0, p->order * sizeof(*p->target_refl_coef)); for (i = 0; i < FFMIN(avpkt->size - 1, p->order); i++) { p->target_refl_coef[i] = (avpkt->data[1 + i] - 127) / 128.0; } } if (p->inited) { p->energy = p->energy / 2 + p->target_energy / 2; for (i = 0; i < p->order; i++) p->refl_coef[i] = 0.6 *p->refl_coef[i] + 0.4 * p->target_refl_coef[i]; } else { p->energy = p->target_energy; memcpy(p->refl_coef, p->target_refl_coef, p->order * sizeof(*p->refl_coef)); p->inited = 1; } make_lpc_coefs(p->lpc_coef, p->refl_coef, p->order); for (i = 0; i < p->order; i++) e *= 1.0 - p->refl_coef[i]*p->refl_coef[i]; scaling = sqrt(e * p->energy / 1081109975); for (i = 0; i < avctx->frame_size; i++) { int r = (av_lfg_get(&p->lfg) & 0xffff) - 0x8000; p->excitation[i] = scaling * r; } ff_celp_lp_synthesis_filterf(p->filter_out + p->order, p->lpc_coef, p->excitation, avctx->frame_size, p->order); frame->nb_samples = avctx->frame_size; if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; buf_out = (int16_t *)frame->data[0]; for (i = 0; i < avctx->frame_size; i++) buf_out[i] = av_clip_int16(p->filter_out[i + p->order]); memcpy(p->filter_out, p->filter_out + avctx->frame_size, p->order * sizeof(*p->filter_out)); *got_frame_ptr = 1; return buf_size; }
/** * Saturate the output signal to signed 16bit integers. * * @param q pointer to the COOKContext * @param chan channel to saturate * @param out pointer to the output vector */ static void saturate_output_float (COOKContext *q, int chan, int16_t *out) { int j; float *output = q->mono_mdct_output + q->samples_per_channel; /* Clip and convert floats to 16 bits. */ for (j = 0; j < q->samples_per_channel; j++) { out[chan + q->nb_channels * j] = av_clip_int16(lrintf(output[j])); } }
/**** the following function comes from a52dec */ static inline void float_to_int (float * _f, int16_t * s16, int nchannels) { int i, j, c; int32_t * f = (int32_t *) _f; // XXX assumes IEEE float format j = 0; nchannels *= 256; for (i = 0; i < 256; i++) { for (c = 0; c < nchannels; c += 256) s16[j++] = av_clip_int16(f[i + c] - 0x43c00000); } }
static void quantize_triangular_ns(DitherContext *c, DitherState *state, int16_t *dst, const float *src, int nb_samples) { int i, j; float *dither = &state->noise_buf[state->noise_buf_ptr]; if (state->mute > c->mute_reset_threshold) memset(state->dither_a, 0, sizeof(state->dither_a)); for (i = 0; i < nb_samples; i++) { float err = 0; float sample = src[i] * S16_SCALE; for (j = 0; j < 4; j++) { err += c->ns_coef_b[j] * state->dither_b[j] - c->ns_coef_a[j] * state->dither_a[j]; } for (j = 3; j > 0; j--) { state->dither_a[j] = state->dither_a[j - 1]; state->dither_b[j] = state->dither_b[j - 1]; } state->dither_a[0] = err; sample -= err; if (state->mute > c->mute_dither_threshold) { dst[i] = av_clip_int16(lrintf(sample)); state->dither_b[0] = 0; } else { dst[i] = av_clip_int16(lrintf(sample + dither[i])); state->dither_b[0] = av_clipf(dst[i] - sample, -1.5f, 1.5f); } state->mute++; if (src[i]) state->mute = 0; } }
static void method2_int16(af_volnorm_t *s, af_data_t *c) { register int i = 0; int16_t *data = (int16_t*)c->audio; // Audio data int len = c->len/2; // Number of samples float curavg = 0.0, newavg, avg = 0.0; int tmp, totallen = 0; for (i = 0; i < len; i++) { tmp = data[i]; curavg += tmp * tmp; } curavg = sqrt(curavg / (float) len); // Evaluate an adequate 'mul' coefficient based on previous state, current // samples level, etc for (i = 0; i < NSAMPLES; i++) { avg += s->mem[i].avg * (float)s->mem[i].len; totallen += s->mem[i].len; } if (totallen > MIN_SAMPLE_SIZE) { avg /= (float)totallen; if (avg >= SIL_S16) { s->mul = s->mid_s16 / avg; s->mul = av_clipf(s->mul, MUL_MIN, MUL_MAX); } } // Scale & clamp the samples for (i = 0; i < len; i++) { tmp = s->mul * data[i]; tmp = av_clip_int16(tmp); data[i] = tmp; } // Evaulation of newavg (not 100% accurate because of values clamping) newavg = s->mul * curavg; // Stores computed values for future smoothing s->mem[s->idx].len = len; s->mem[s->idx].avg = newavg; s->idx = (s->idx + 1) % NSAMPLES; }
static inline int conv(int samples, float **pcm, char *buf, int channels) { int i, j; ogg_int16_t *ptr, *data = (ogg_int16_t*)buf ; float *mono ; for(i = 0 ; i < channels ; i++){ ptr = &data[i]; mono = pcm[i] ; for(j = 0 ; j < samples ; j++) { *ptr = av_clip_int16(mono[j] * 32767.f); ptr += channels; } } return 0 ; }
static void set(uint8_t *a[], int ch, int index, int ch_count, enum AVSampleFormat f, double v){ uint8_t *p; if(av_sample_fmt_is_planar(f)){ f= av_get_alt_sample_fmt(f, 0); p= a[ch]; }else{ p= a[0]; index= ch + index*ch_count; } switch(f){ case AV_SAMPLE_FMT_U8 : ((uint8_t*)p)[index]= av_clip_uint8 (lrint((v+1.0)*127)); break; case AV_SAMPLE_FMT_S16: ((int16_t*)p)[index]= av_clip_int16 (lrint(v*32767)); break; case AV_SAMPLE_FMT_S32: ((int32_t*)p)[index]= av_clipl_int32(llrint(v*2147483647)); break; case AV_SAMPLE_FMT_FLT: ((float *)p)[index]= v; break; case AV_SAMPLE_FMT_DBL: ((double *)p)[index]= v; break; default: av_assert2(0); } }
static inline unsigned char adpcm_yamaha_compress_sample(ADPCMChannelStatus *c, short sample) { int nibble, delta; if(!c->step) { c->predictor = 0; c->step = 127; } delta = sample - c->predictor; nibble = FFMIN(7, abs(delta)*4/c->step) + (delta<0)*8; c->predictor += ((c->step * ff_adpcm_yamaha_difflookup[nibble]) / 8); c->predictor = av_clip_int16(c->predictor); c->step = (c->step * ff_adpcm_yamaha_indexscale[nibble]) >> 8; c->step = av_clip(c->step, 127, 24567); return nibble; }
static void method1_int16(af_volnorm_t *s, af_data_t *c) { register int i = 0; int16_t *data = (int16_t*)c->audio; // Audio data int len = c->len/2; // Number of samples float curavg = 0.0, newavg, neededmul; int tmp; for (i = 0; i < len; i++) { tmp = data[i]; curavg += tmp * tmp; } curavg = sqrt(curavg / (float) len); // Evaluate an adequate 'mul' coefficient based on previous state, current // samples level, etc if (curavg > SIL_S16) { neededmul = s->mid_s16 / (curavg * s->mul); s->mul = (1.0 - SMOOTH_MUL) * s->mul + SMOOTH_MUL * neededmul; // clamp the mul coefficient s->mul = av_clipf(s->mul, MUL_MIN, MUL_MAX); } // Scale & clamp the samples for (i = 0; i < len; i++) { tmp = s->mul * data[i]; tmp = av_clip_int16(tmp); data[i] = tmp; } // Evaulation of newavg (not 100% accurate because of values clamping) newavg = s->mul * curavg; // Stores computed values for future smoothing s->lastavg = (1.0 - SMOOTH_LASTAVG) * s->lastavg + SMOOTH_LASTAVG * newavg; }
/** * Decode Smacker audio data */ static int smka_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { SmackerAudioContext *s = avctx->priv_data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; GetBitContext gb; HuffContext h[4] = { { 0 } }; VLC vlc[4] = { { 0 } }; int16_t *samples; uint8_t *samples8; int val; int i, res, ret; int unp_size; int bits, stereo; int pred[2] = {0, 0}; if (buf_size <= 4) { av_log(avctx, AV_LOG_ERROR, "packet is too small\n"); return AVERROR(EINVAL); } unp_size = AV_RL32(buf); init_get_bits(&gb, buf + 4, (buf_size - 4) * 8); if(!get_bits1(&gb)){ av_log(avctx, AV_LOG_INFO, "Sound: no data\n"); *got_frame_ptr = 0; return 1; } stereo = get_bits1(&gb); bits = get_bits1(&gb); if (stereo ^ (avctx->channels != 1)) { av_log(avctx, AV_LOG_ERROR, "channels mismatch\n"); return AVERROR(EINVAL); } if (bits && avctx->sample_fmt == AV_SAMPLE_FMT_U8) { av_log(avctx, AV_LOG_ERROR, "sample format mismatch\n"); return AVERROR(EINVAL); } /* get output buffer */ s->frame.nb_samples = unp_size / (avctx->channels * (bits + 1)); if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } samples = (int16_t *)s->frame.data[0]; samples8 = s->frame.data[0]; // Initialize for(i = 0; i < (1 << (bits + stereo)); i++) { h[i].length = 256; h[i].maxlength = 0; h[i].current = 0; h[i].bits = av_mallocz(256 * 4); h[i].lengths = av_mallocz(256 * sizeof(int)); h[i].values = av_mallocz(256 * sizeof(int)); skip_bits1(&gb); smacker_decode_tree(&gb, &h[i], 0, 0); skip_bits1(&gb); if(h[i].current > 1) { res = init_vlc(&vlc[i], SMKTREE_BITS, h[i].length, h[i].lengths, sizeof(int), sizeof(int), h[i].bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE); if(res < 0) { av_log(avctx, AV_LOG_ERROR, "Cannot build VLC table\n"); return -1; } } } if(bits) { //decode 16-bit data for(i = stereo; i >= 0; i--) pred[i] = sign_extend(av_bswap16(get_bits(&gb, 16)), 16); for(i = 0; i <= stereo; i++) *samples++ = pred[i]; for(; i < unp_size / 2; i++) { if(i & stereo) { if(vlc[2].table) res = get_vlc2(&gb, vlc[2].table, SMKTREE_BITS, 3); else res = 0; val = h[2].values[res]; if(vlc[3].table) res = get_vlc2(&gb, vlc[3].table, SMKTREE_BITS, 3); else res = 0; val |= h[3].values[res] << 8; pred[1] += sign_extend(val, 16); *samples++ = av_clip_int16(pred[1]); } else { if(vlc[0].table) res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3); else res = 0; val = h[0].values[res]; if(vlc[1].table) res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3); else res = 0; val |= h[1].values[res] << 8; pred[0] += sign_extend(val, 16); *samples++ = av_clip_int16(pred[0]); } } } else { //8-bit data for(i = stereo; i >= 0; i--) pred[i] = get_bits(&gb, 8); for(i = 0; i <= stereo; i++) *samples8++ = pred[i]; for(; i < unp_size; i++) { if(i & stereo){ if(vlc[1].table) res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3); else res = 0; pred[1] += sign_extend(h[1].values[res], 8); *samples8++ = av_clip_uint8(pred[1]); } else { if(vlc[0].table) res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3); else res = 0; pred[0] += sign_extend(h[0].values[res], 8); *samples8++ = av_clip_uint8(pred[0]); } } } for(i = 0; i < 4; i++) { if(vlc[i].table) ff_free_vlc(&vlc[i]); av_free(h[i].bits); av_free(h[i].lengths); av_free(h[i].values); } *got_frame_ptr = 1; *(AVFrame *)data = s->frame; return buf_size; }
static void quantize_c(int16_t *dst, const float *src, float *dither, int len) { int i; for (i = 0; i < len; i++) dst[i] = av_clip_int16(lrintf(src[i] * S16_SCALE + dither[i])); }
/* Filter data through filter Two "tricks" are used to compensate the "color" of the KEMAR data: 1. The KEMAR data is refiltered to ensure that the front L, R channels on the same side of the ear are equalized (especially in the high frequencies). 2. A bass compensation is introduced to ensure that 0-200 Hz are not damped (without any real 3D acoustical image, however). */ static struct mp_audio* play(struct af_instance *af, struct mp_audio *data) { af_hrtf_t *s = af->setup; short *in = data->planes[0]; // Input audio data short *out = NULL; // Output audio data short *end = in + data->samples * data->nch; // Loop end float common, left, right, diff, left_b, right_b; const int dblen = s->dlbuflen, hlen = s->hrflen, blen = s->basslen; mp_audio_realloc_min(af->data, data->samples); if(s->print_flag) { s->print_flag = 0; switch (s->decode_mode) { case HRTF_MIX_51: mp_msg(MSGT_AFILTER, MSGL_INFO, "[hrtf] Using HRTF to mix %s discrete surround into " "L, R channels\n", s->matrix_mode ? "5+1" : "5"); break; case HRTF_MIX_STEREO: mp_msg(MSGT_AFILTER, MSGL_INFO, "[hrtf] Using HRTF to mix stereo into " "L, R channels\n"); break; case HRTF_MIX_MATRIX2CH: mp_msg(MSGT_AFILTER, MSGL_INFO, "[hrtf] Using active matrix to decode 2 channel " "input, HRTF to mix %s matrix surround into " "L, R channels\n", "3/2"); break; default: mp_msg(MSGT_AFILTER, MSGL_WARN, "[hrtf] bogus decode_mode: %d\n", s->decode_mode); break; } if(s->matrix_mode) mp_msg(MSGT_AFILTER, MSGL_INFO, "[hrtf] Using active matrix to decode rear center " "channel\n"); } out = af->data->planes[0]; /* MPlayer's 5 channel layout (notation for the variable): * * 0: L (LF), 1: R (RF), 2: Ls (LR), 3: Rs (RR), 4: C (CF), matrix * encoded: Cs (CR) * * or: L = left, C = center, R = right, F = front, R = rear * * Filter notation: * * CF * OF AF * Ear-> * OR AR * CR * * or: C = center, A = same side, O = opposite, F = front, R = rear */ while(in < end) { const int k = s->cyc_pos; update_ch(s, in, k); /* Simulate a 7.5 ms -20 dB echo of the center channel in the front channels (like reflection from a room wall) - a kind of psycho-acoustically "cheating" to focus the center front channel, which is normally hard to be perceived as front */ s->lf[k] += CFECHOAMPL * s->cf[(k + CFECHODELAY) % s->dlbuflen]; s->rf[k] += CFECHOAMPL * s->cf[(k + CFECHODELAY) % s->dlbuflen]; switch (s->decode_mode) { case HRTF_MIX_51: case HRTF_MIX_MATRIX2CH: /* Mixer filter matrix */ common = conv(dblen, hlen, s->cf, s->cf_ir, k + s->cf_o); if(s->matrix_mode) { /* In matrix decoding mode, the rear channel gain must be renormalized, as there is an additional channel. */ matrix_decode(in, k, 2, 3, 0, s->dlbuflen, s->lr_fwr, s->rr_fwr, s->lrprr_fwr, s->lrmrr_fwr, &(s->adapt_lr_gain), &(s->adapt_rr_gain), &(s->adapt_lrprr_gain), &(s->adapt_lrmrr_gain), s->lr, s->rr, NULL, NULL, s->cr); common += conv(dblen, hlen, s->cr, s->cr_ir, k + s->cr_o) * M1_76DB; left = ( conv(dblen, hlen, s->lf, s->af_ir, k + s->af_o) + conv(dblen, hlen, s->rf, s->of_ir, k + s->of_o) + (conv(dblen, hlen, s->lr, s->ar_ir, k + s->ar_o) + conv(dblen, hlen, s->rr, s->or_ir, k + s->or_o)) * M1_76DB + common); right = ( conv(dblen, hlen, s->rf, s->af_ir, k + s->af_o) + conv(dblen, hlen, s->lf, s->of_ir, k + s->of_o) + (conv(dblen, hlen, s->rr, s->ar_ir, k + s->ar_o) + conv(dblen, hlen, s->lr, s->or_ir, k + s->or_o)) * M1_76DB + common); } else { left = ( conv(dblen, hlen, s->lf, s->af_ir, k + s->af_o) + conv(dblen, hlen, s->rf, s->of_ir, k + s->of_o) + conv(dblen, hlen, s->lr, s->ar_ir, k + s->ar_o) + conv(dblen, hlen, s->rr, s->or_ir, k + s->or_o) + common); right = ( conv(dblen, hlen, s->rf, s->af_ir, k + s->af_o) + conv(dblen, hlen, s->lf, s->of_ir, k + s->of_o) + conv(dblen, hlen, s->rr, s->ar_ir, k + s->ar_o) + conv(dblen, hlen, s->lr, s->or_ir, k + s->or_o) + common); } break; case HRTF_MIX_STEREO: left = ( conv(dblen, hlen, s->lf, s->af_ir, k + s->af_o) + conv(dblen, hlen, s->rf, s->of_ir, k + s->of_o)); right = ( conv(dblen, hlen, s->rf, s->af_ir, k + s->af_o) + conv(dblen, hlen, s->lf, s->of_ir, k + s->of_o)); break; default: /* make gcc happy */ left = 0.0; right = 0.0; break; } /* Bass compensation for the lower frequency cut of the HRTF. A cross talk of the left and right channel is introduced to match the directional characteristics of higher frequencies. The bass will not have any real 3D perception, but that is OK (note at 180 Hz, the wavelength is about 2 m, and any spatial perception is impossible). */ left_b = conv(dblen, blen, s->ba_l, s->ba_ir, k); right_b = conv(dblen, blen, s->ba_r, s->ba_ir, k); left += (1 - BASSCROSS) * left_b + BASSCROSS * right_b; right += (1 - BASSCROSS) * right_b + BASSCROSS * left_b; /* Also mix the LFE channel (if available) */ if(data->nch >= 6) { left += in[5] * M3_01DB; right += in[5] * M3_01DB; } /* Amplitude renormalization. */ left *= AMPLNORM; right *= AMPLNORM; switch (s->decode_mode) { case HRTF_MIX_51: case HRTF_MIX_STEREO: /* "Cheating": linear stereo expansion to amplify the 3D perception. Note: Too much will destroy the acoustic space and may even result in headaches. */ diff = STEXPAND2 * (left - right); out[0] = av_clip_int16(left + diff); out[1] = av_clip_int16(right - diff); break; case HRTF_MIX_MATRIX2CH: /* Do attempt any stereo expansion with matrix encoded sources. The L, R channels are already stereo expanded by the steering, any further stereo expansion will sound very unnatural. */ out[0] = av_clip_int16(left); out[1] = av_clip_int16(right); break; } /* Next sample... */ in = &in[data->nch]; out = &out[af->data->nch]; (s->cyc_pos)--; if(s->cyc_pos < 0) s->cyc_pos += dblen; } /* Set output data */ data->planes[0] = af->data->planes[0]; mp_audio_set_num_channels(data, 2); return data; }
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *pkt) { GetBitContext gb; AVFrame *frame = data; int16_t pcm_data[2]; uint32_t samples; int8_t channel_hint[2]; int ret, chan, channels = 1; if (pkt->size < 13) return AVERROR_INVALIDDATA; if ((ret = init_get_bits8(&gb, pkt->data, pkt->size)) < 0) return ret; samples = get_bits_long(&gb, 32); if (samples == 0xffffffff) { skip_bits_long(&gb, 32); samples = get_bits_long(&gb, 32); } if (samples > pkt->size * 2) return AVERROR_INVALIDDATA; channel_hint[0] = get_sbits(&gb, 8); if (channel_hint[0] & 0x80) { channel_hint[0] = ~channel_hint[0]; channels = 2; } avctx->channels = channels; avctx->channel_layout = (channels == 2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO; pcm_data[0] = get_sbits(&gb, 16); if (channels > 1) { channel_hint[1] = get_sbits(&gb, 8); pcm_data[1] = get_sbits(&gb, 16); } frame->nb_samples = samples; if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; for (chan = 0; chan < channels; chan++) { uint16_t *dest = (uint16_t*)frame->data[0] + chan; int step_index = channel_hint[chan]; int output = pcm_data[chan]; int sample; for (sample = 0; sample < samples; sample++) { int lookup_size, lookup, highbit, lowbits; step_index = av_clip(step_index, 0, 88); lookup_size = size_table[step_index]; lookup = get_bits(&gb, lookup_size); highbit = 1 << (lookup_size - 1); lowbits = highbit - 1; if (lookup & highbit) lookup ^= highbit; else highbit = 0; if (lookup == lowbits) { output = get_sbits(&gb, 16); } else { int predict_index, diff; predict_index = (lookup << (7 - lookup_size)) | (step_index << 6); predict_index = av_clip(predict_index, 0, 5785); diff = predict_table[predict_index]; if (lookup) diff += ff_adpcm_step_table[step_index] >> (lookup_size - 1); if (highbit) diff = -diff; output = av_clip_int16(output + diff); } *dest = output; dest += channels; step_index += step_index_tables[lookup_size - 2][lookup]; } } *got_frame_ptr = 1; return pkt->size; }
/** * Decode Smacker audio data */ static int smka_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; GetBitContext gb; HuffContext h[4]; VLC vlc[4]; int16_t *samples = data; uint8_t *samples8 = data; int val; int i, res; int unp_size; int bits, stereo; int pred[2] = {0, 0}; if (buf_size <= 4) { av_log(avctx, AV_LOG_ERROR, "packet is too small\n"); return AVERROR(EINVAL); } unp_size = AV_RL32(buf); init_get_bits(&gb, buf + 4, (buf_size - 4) * 8); if(!get_bits1(&gb)){ av_log(avctx, AV_LOG_INFO, "Sound: no data\n"); *data_size = 0; return 1; } stereo = get_bits1(&gb); bits = get_bits1(&gb); if (unp_size & 0xC0000000 || unp_size > *data_size) { av_log(avctx, AV_LOG_ERROR, "Frame is too large to fit in buffer\n"); return -1; } if (stereo ^ (avctx->channels != 1)) { av_log(avctx, AV_LOG_ERROR, "channels mismatch\n"); return AVERROR(EINVAL); } if (bits && avctx->sample_fmt == AV_SAMPLE_FMT_U8) { av_log(avctx, AV_LOG_ERROR, "sample format mismatch\n"); return AVERROR(EINVAL); } memset(vlc, 0, sizeof(VLC) * 4); memset(h, 0, sizeof(HuffContext) * 4); // Initialize for(i = 0; i < (1 << (bits + stereo)); i++) { h[i].length = 256; h[i].maxlength = 0; h[i].current = 0; h[i].bits = av_mallocz(256 * 4); h[i].lengths = av_mallocz(256 * sizeof(int)); h[i].values = av_mallocz(256 * sizeof(int)); skip_bits1(&gb); smacker_decode_tree(&gb, &h[i], 0, 0); skip_bits1(&gb); if(h[i].current > 1) { res = init_vlc(&vlc[i], SMKTREE_BITS, h[i].length, h[i].lengths, sizeof(int), sizeof(int), h[i].bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE); if(res < 0) { av_log(avctx, AV_LOG_ERROR, "Cannot build VLC table\n"); return -1; } } } if(bits) { //decode 16-bit data for(i = stereo; i >= 0; i--) pred[i] = av_bswap16(get_bits(&gb, 16)); for(i = 0; i <= stereo; i++) *samples++ = pred[i]; for(; i < unp_size / 2; i++) { if(i & stereo) { if(vlc[2].table) res = get_vlc2(&gb, vlc[2].table, SMKTREE_BITS, 3); else res = 0; val = h[2].values[res]; if(vlc[3].table) res = get_vlc2(&gb, vlc[3].table, SMKTREE_BITS, 3); else res = 0; val |= h[3].values[res] << 8; pred[1] += sign_extend(val, 16); *samples++ = av_clip_int16(pred[1]); } else { if(vlc[0].table) res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3); else res = 0; val = h[0].values[res]; if(vlc[1].table) res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3); else res = 0; val |= h[1].values[res] << 8; pred[0] += sign_extend(val, 16); *samples++ = av_clip_int16(pred[0]); } } } else { //8-bit data for(i = stereo; i >= 0; i--) pred[i] = get_bits(&gb, 8); for(i = 0; i <= stereo; i++) *samples8++ = pred[i]; for(; i < unp_size; i++) { if(i & stereo){ if(vlc[1].table) res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3); else res = 0; pred[1] += sign_extend(h[1].values[res], 8); *samples8++ = av_clip_uint8(pred[1]); } else { if(vlc[0].table) res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3); else res = 0; pred[0] += sign_extend(h[0].values[res], 8); *samples8++ = av_clip_uint8(pred[0]); } } } for(i = 0; i < 4; i++) { if(vlc[i].table) free_vlc(&vlc[i]); av_free(h[i].bits); av_free(h[i].lengths); av_free(h[i].values); } *data_size = unp_size; return buf_size; }
static av_always_inline int float_to_int16_one(const float *src){ return av_clip_int16(lrintf(*src)); }
/** * builds a polyphase filterbank. * @param factor resampling factor * @param scale wanted sum of coefficients for each filter * @param filter_type filter type * @param kaiser_beta kaiser window beta * @return 0 on success, negative on error */ static int build_filter(ResampleContext *c, void *filter, double factor, int tap_count, int alloc, int phase_count, int scale, int filter_type, double kaiser_beta){ int ph, i; int ph_nb = phase_count % 2 ? phase_count : phase_count / 2 + 1; double x, y, w, t, s; double *tab = av_malloc_array(tap_count+1, sizeof(*tab)); double *sin_lut = av_malloc_array(ph_nb, sizeof(*sin_lut)); const int center= (tap_count-1)/2; int ret = AVERROR(ENOMEM); if (!tab || !sin_lut) goto fail; /* if upsampling, only need to interpolate, no filter */ if (factor > 1.0) factor = 1.0; if (factor == 1.0) { for (ph = 0; ph < ph_nb; ph++) sin_lut[ph] = sin(M_PI * ph / phase_count); } for(ph = 0; ph < ph_nb; ph++) { double norm = 0; s = sin_lut[ph]; for(i=0;i<=tap_count;i++) { x = M_PI * ((double)(i - center) - (double)ph / phase_count) * factor; if (x == 0) y = 1.0; else if (factor == 1.0) y = s / x; else y = sin(x) / x; switch(filter_type){ case SWR_FILTER_TYPE_CUBIC:{ const float d= -0.5; //first order derivative = -0.5 x = fabs(((double)(i - center) - (double)ph / phase_count) * factor); if(x<1.0) y= 1 - 3*x*x + 2*x*x*x + d*( -x*x + x*x*x); else y= d*(-4 + 8*x - 5*x*x + x*x*x); break;} case SWR_FILTER_TYPE_BLACKMAN_NUTTALL: w = 2.0*x / (factor*tap_count); t = -cos(w); y *= 0.3635819 - 0.4891775 * t + 0.1365995 * (2*t*t-1) - 0.0106411 * (4*t*t*t - 3*t); break; case SWR_FILTER_TYPE_KAISER: w = 2.0*x / (factor*tap_count*M_PI); y *= bessel(kaiser_beta*sqrt(FFMAX(1-w*w, 0))); break; default: av_assert0(0); } tab[i] = y; s = -s; if (i < tap_count) norm += y; } /* normalize so that an uniform color remains the same */ switch(c->format){ case AV_SAMPLE_FMT_S16P: for(i=0;i<tap_count;i++) ((int16_t*)filter)[ph * alloc + i] = av_clip_int16(lrintf(tab[i] * scale / norm)); if (phase_count % 2) break; if (tap_count % 2 == 0 || tap_count == 1) { for (i = 0; i < tap_count; i++) ((int16_t*)filter)[(phase_count-ph) * alloc + tap_count-1-i] = ((int16_t*)filter)[ph * alloc + i]; } else { for (i = 1; i <= tap_count; i++) ((int16_t*)filter)[(phase_count-ph) * alloc + tap_count-i] = av_clip_int16(lrintf(tab[i] * scale / (norm - tab[0] + tab[tap_count]))); } break; case AV_SAMPLE_FMT_S32P: for(i=0;i<tap_count;i++) ((int32_t*)filter)[ph * alloc + i] = av_clipl_int32(llrint(tab[i] * scale / norm)); if (phase_count % 2) break; if (tap_count % 2 == 0 || tap_count == 1) { for (i = 0; i < tap_count; i++) ((int32_t*)filter)[(phase_count-ph) * alloc + tap_count-1-i] = ((int32_t*)filter)[ph * alloc + i]; } else { for (i = 1; i <= tap_count; i++) ((int32_t*)filter)[(phase_count-ph) * alloc + tap_count-i] = av_clipl_int32(llrint(tab[i] * scale / (norm - tab[0] + tab[tap_count]))); } break; case AV_SAMPLE_FMT_FLTP: for(i=0;i<tap_count;i++) ((float*)filter)[ph * alloc + i] = tab[i] * scale / norm; if (phase_count % 2) break; if (tap_count % 2 == 0 || tap_count == 1) { for (i = 0; i < tap_count; i++) ((float*)filter)[(phase_count-ph) * alloc + tap_count-1-i] = ((float*)filter)[ph * alloc + i]; } else { for (i = 1; i <= tap_count; i++) ((float*)filter)[(phase_count-ph) * alloc + tap_count-i] = tab[i] * scale / (norm - tab[0] + tab[tap_count]); } break; case AV_SAMPLE_FMT_DBLP: for(i=0;i<tap_count;i++) ((double*)filter)[ph * alloc + i] = tab[i] * scale / norm; if (phase_count % 2) break; if (tap_count % 2 == 0 || tap_count == 1) { for (i = 0; i < tap_count; i++) ((double*)filter)[(phase_count-ph) * alloc + tap_count-1-i] = ((double*)filter)[ph * alloc + i]; } else { for (i = 1; i <= tap_count; i++) ((double*)filter)[(phase_count-ph) * alloc + tap_count-i] = tab[i] * scale / (norm - tab[0] + tab[tap_count]); } break; } } #if 0 { #define LEN 1024 int j,k; double sine[LEN + tap_count]; double filtered[LEN]; double maxff=-2, minff=2, maxsf=-2, minsf=2; for(i=0; i<LEN; i++){ double ss=0, sf=0, ff=0; for(j=0; j<LEN+tap_count; j++) sine[j]= cos(i*j*M_PI/LEN); for(j=0; j<LEN; j++){ double sum=0; ph=0; for(k=0; k<tap_count; k++) sum += filter[ph * tap_count + k] * sine[k+j]; filtered[j]= sum / (1<<FILTER_SHIFT); ss+= sine[j + center] * sine[j + center]; ff+= filtered[j] * filtered[j]; sf+= sine[j + center] * filtered[j]; } ss= sqrt(2*ss/LEN); ff= sqrt(2*ff/LEN); sf= 2*sf/LEN; maxff= FFMAX(maxff, ff); minff= FFMIN(minff, ff); maxsf= FFMAX(maxsf, sf); minsf= FFMIN(minsf, sf); if(i%11==0){ av_log(NULL, AV_LOG_ERROR, "i:%4d ss:%f ff:%13.6e-%13.6e sf:%13.6e-%13.6e\n", i, ss, maxff, minff, maxsf, minsf); minff=minsf= 2; maxff=maxsf= -2; } } } #endif ret = 0; fail: av_free(tab); av_free(sin_lut); return ret; }
/** Uncompress one block (20 bytes -> 160*2 bytes). */ static int ra144_decode_frame(AVCodecContext * avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { AVFrame *frame = data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; static const uint8_t sizes[LPC_ORDER] = {6, 5, 5, 4, 4, 3, 3, 3, 3, 2}; unsigned int refl_rms[NBLOCKS]; // RMS of the reflection coefficients int16_t block_coefs[NBLOCKS][LPC_ORDER]; // LPC coefficients of each sub-block unsigned int lpc_refl[LPC_ORDER]; // LPC reflection coefficients of the frame int i, j; int ret; int16_t *samples; unsigned int energy; RA144Context *ractx = avctx->priv_data; GetBitContext gb; if (buf_size < FRAME_SIZE) { av_log(avctx, AV_LOG_ERROR, "Frame too small (%d bytes). Truncated file?\n", buf_size); *got_frame_ptr = 0; return AVERROR_INVALIDDATA; } /* get output buffer */ frame->nb_samples = NBLOCKS * BLOCKSIZE; if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; samples = (int16_t *)frame->data[0]; init_get_bits8(&gb, buf, FRAME_SIZE); for (i = 0; i < LPC_ORDER; i++) lpc_refl[i] = ff_lpc_refl_cb[i][get_bits(&gb, sizes[i])]; ff_eval_coefs(ractx->lpc_coef[0], lpc_refl); ractx->lpc_refl_rms[0] = ff_rms(lpc_refl); energy = ff_energy_tab[get_bits(&gb, 5)]; refl_rms[0] = ff_interp(ractx, block_coefs[0], 1, 1, ractx->old_energy); refl_rms[1] = ff_interp(ractx, block_coefs[1], 2, energy <= ractx->old_energy, ff_t_sqrt(energy*ractx->old_energy) >> 12); refl_rms[2] = ff_interp(ractx, block_coefs[2], 3, 0, energy); refl_rms[3] = ff_rescale_rms(ractx->lpc_refl_rms[0], energy); ff_int_to_int16(block_coefs[3], ractx->lpc_coef[0]); for (i=0; i < NBLOCKS; i++) { do_output_subblock(ractx, block_coefs[i], refl_rms[i], &gb); for (j=0; j < BLOCKSIZE; j++) *samples++ = av_clip_int16(ractx->curr_sblock[j + 10] << 2); } ractx->old_energy = energy; ractx->lpc_refl_rms[1] = ractx->lpc_refl_rms[0]; FFSWAP(unsigned int *, ractx->lpc_coef[0], ractx->lpc_coef[1]); *got_frame_ptr = 1; return FRAME_SIZE; }
CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80U)<<8) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80U)<<24) CONV_FUNC(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0f/ (1<<7))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0 / (1<<7))) CONV_FUNC(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_S16, (*(const int16_t*)pi>>8) + 0x80) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S16, *(const int16_t*)pi) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S16, *(const int16_t*)pi<<16) CONV_FUNC(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_S16, *(const int16_t*)pi*(1.0f/ (1<<15))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_S16, *(const int16_t*)pi*(1.0 / (1<<15))) CONV_FUNC(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_S32, (*(const int32_t*)pi>>24) + 0x80) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S32, *(const int32_t*)pi>>16) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S32, *(const int32_t*)pi) CONV_FUNC(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_S32, *(const int32_t*)pi*(1.0f/ (1U<<31))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_S32, *(const int32_t*)pi*(1.0 / (1U<<31))) CONV_FUNC(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8( lrintf(*(const float*)pi * (1<<7)) + 0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16( lrintf(*(const float*)pi * (1<<15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float*)pi * (1U<<31)))) CONV_FUNC(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_FLT, *(const float*)pi) CONV_FUNC(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_FLT, *(const float*)pi) CONV_FUNC(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8( lrint(*(const double*)pi * (1<<7)) + 0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16( lrint(*(const double*)pi * (1<<15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double*)pi * (1U<<31)))) CONV_FUNC(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_DBL, *(const double*)pi) CONV_FUNC(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_DBL, *(const double*)pi) #define FMT_PAIR_FUNC(out, in) [(out) + AV_SAMPLE_FMT_NB*(in)] = CONV_FUNC_NAME(out, in) static conv_func_type * const fmt_pair_to_conv_functions[AV_SAMPLE_FMT_NB*AV_SAMPLE_FMT_NB] = { FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8 , AV_SAMPLE_FMT_U8 ), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_U8 ), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_U8 ),
static int dpcm_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { int buf_size = avpkt->size; DPCMContext *s = avctx->priv_data; int out = 0, ret; int predictor[2]; int ch = 0; int stereo = s->channels - 1; int16_t *output_samples, *samples_end; GetByteContext gb; if (stereo && (buf_size & 1)) buf_size--; bytestream2_init(&gb, avpkt->data, buf_size); /* calculate output size */ switch(avctx->codec->id) { case CODEC_ID_ROQ_DPCM: out = buf_size - 8; break; case CODEC_ID_INTERPLAY_DPCM: out = buf_size - 6 - s->channels; break; case CODEC_ID_XAN_DPCM: out = buf_size - 2 * s->channels; break; case CODEC_ID_SOL_DPCM: if (avctx->codec_tag != 3) out = buf_size * 2; else out = buf_size; break; } if (out <= 0) { av_log(avctx, AV_LOG_ERROR, "packet is too small\n"); return AVERROR(EINVAL); } /* get output buffer */ s->frame.nb_samples = out / s->channels; if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } output_samples = (int16_t *)s->frame.data[0]; samples_end = output_samples + out; switch(avctx->codec->id) { case CODEC_ID_ROQ_DPCM: bytestream2_skipu(&gb, 6); if (stereo) { predictor[1] = sign_extend(bytestream2_get_byteu(&gb) << 8, 16); predictor[0] = sign_extend(bytestream2_get_byteu(&gb) << 8, 16); } else { predictor[0] = sign_extend(bytestream2_get_le16u(&gb), 16); } /* decode the samples */ while (output_samples < samples_end) { predictor[ch] += s->roq_square_array[bytestream2_get_byteu(&gb)]; predictor[ch] = av_clip_int16(predictor[ch]); *output_samples++ = predictor[ch]; /* toggle channel */ ch ^= stereo; } break; case CODEC_ID_INTERPLAY_DPCM: bytestream2_skipu(&gb, 6); /* skip over the stream mask and stream length */ for (ch = 0; ch < s->channels; ch++) { predictor[ch] = sign_extend(bytestream2_get_le16u(&gb), 16); *output_samples++ = predictor[ch]; } ch = 0; while (output_samples < samples_end) { predictor[ch] += interplay_delta_table[bytestream2_get_byteu(&gb)]; predictor[ch] = av_clip_int16(predictor[ch]); *output_samples++ = predictor[ch]; /* toggle channel */ ch ^= stereo; } break; case CODEC_ID_XAN_DPCM: { int shift[2] = { 4, 4 }; for (ch = 0; ch < s->channels; ch++) predictor[ch] = sign_extend(bytestream2_get_le16u(&gb), 16); ch = 0; while (output_samples < samples_end) { int diff = bytestream2_get_byteu(&gb); int n = diff & 3; if (n == 3) shift[ch]++; else shift[ch] -= (2 * n); diff = sign_extend((diff &~ 3) << 8, 16); /* saturate the shifter to a lower limit of 0 */ if (shift[ch] < 0) shift[ch] = 0; diff >>= shift[ch]; predictor[ch] += diff; predictor[ch] = av_clip_int16(predictor[ch]); *output_samples++ = predictor[ch]; /* toggle channel */ ch ^= stereo; } break; } case CODEC_ID_SOL_DPCM: if (avctx->codec_tag != 3) { uint8_t *output_samples_u8 = s->frame.data[0], *samples_end_u8 = output_samples_u8 + out; while (output_samples_u8 < samples_end_u8) { int n = bytestream2_get_byteu(&gb); s->sample[0] += s->sol_table[n >> 4]; s->sample[0] = av_clip_uint8(s->sample[0]); *output_samples_u8++ = s->sample[0]; s->sample[stereo] += s->sol_table[n & 0x0F]; s->sample[stereo] = av_clip_uint8(s->sample[stereo]); *output_samples_u8++ = s->sample[stereo]; } } else { while (output_samples < samples_end) {
static int dpcm_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; const uint8_t *buf_end = buf + buf_size; DPCMContext *s = avctx->priv_data; int out = 0; int predictor[2]; int ch = 0; int stereo = s->channels - 1; int16_t *output_samples = data; /* calculate output size */ switch(avctx->codec->id) { case CODEC_ID_ROQ_DPCM: out = buf_size - 8; break; case CODEC_ID_INTERPLAY_DPCM: out = buf_size - 6 - s->channels; break; case CODEC_ID_XAN_DPCM: out = buf_size - 2 * s->channels; break; case CODEC_ID_SOL_DPCM: if (avctx->codec_tag != 3) out = buf_size * 2; else out = buf_size; break; } out *= av_get_bytes_per_sample(avctx->sample_fmt); if (out <= 0) { av_log(avctx, AV_LOG_ERROR, "packet is too small\n"); return AVERROR(EINVAL); } if (*data_size < out) { av_log(avctx, AV_LOG_ERROR, "output buffer is too small\n"); return AVERROR(EINVAL); } switch(avctx->codec->id) { case CODEC_ID_ROQ_DPCM: buf += 6; if (stereo) { predictor[1] = (int16_t)(bytestream_get_byte(&buf) << 8); predictor[0] = (int16_t)(bytestream_get_byte(&buf) << 8); } else { predictor[0] = (int16_t)bytestream_get_le16(&buf); } /* decode the samples */ while (buf < buf_end) { predictor[ch] += s->roq_square_array[*buf++]; predictor[ch] = av_clip_int16(predictor[ch]); *output_samples++ = predictor[ch]; /* toggle channel */ ch ^= stereo; } break; case CODEC_ID_INTERPLAY_DPCM: buf += 6; /* skip over the stream mask and stream length */ for (ch = 0; ch < s->channels; ch++) { predictor[ch] = (int16_t)bytestream_get_le16(&buf); *output_samples++ = predictor[ch]; } ch = 0; while (buf < buf_end) { predictor[ch] += interplay_delta_table[*buf++]; predictor[ch] = av_clip_int16(predictor[ch]); *output_samples++ = predictor[ch]; /* toggle channel */ ch ^= stereo; } break; case CODEC_ID_XAN_DPCM: { int shift[2] = { 4, 4 }; for (ch = 0; ch < s->channels; ch++) predictor[ch] = (int16_t)bytestream_get_le16(&buf); ch = 0; while (buf < buf_end) { uint8_t n = *buf++; int16_t diff = (n & 0xFC) << 8; if ((n & 0x03) == 3) shift[ch]++; else shift[ch] -= (2 * (n & 3)); /* saturate the shifter to a lower limit of 0 */ if (shift[ch] < 0) shift[ch] = 0; diff >>= shift[ch]; predictor[ch] += diff; predictor[ch] = av_clip_int16(predictor[ch]); *output_samples++ = predictor[ch]; /* toggle channel */ ch ^= stereo; } break; } case CODEC_ID_SOL_DPCM: if (avctx->codec_tag != 3) { uint8_t *output_samples_u8 = data; while (buf < buf_end) { uint8_t n = *buf++; s->sample[0] += s->sol_table[n >> 4]; s->sample[0] = av_clip_uint8(s->sample[0]); *output_samples_u8++ = s->sample[0]; s->sample[stereo] += s->sol_table[n & 0x0F]; s->sample[stereo] = av_clip_uint8(s->sample[stereo]); *output_samples_u8++ = s->sample[stereo]; } } else { while (buf < buf_end) {
int avresample_set_matrix(AVAudioResampleContext *avr, const double *matrix, int stride) { int in_channels, out_channels, i, o; in_channels = av_get_channel_layout_nb_channels(avr->in_channel_layout); out_channels = av_get_channel_layout_nb_channels(avr->out_channel_layout); if ( in_channels <= 0 || in_channels > AVRESAMPLE_MAX_CHANNELS || out_channels <= 0 || out_channels > AVRESAMPLE_MAX_CHANNELS) { av_log(avr, AV_LOG_ERROR, "Invalid channel layouts\n"); return AVERROR(EINVAL); } if (avr->am->matrix) { av_free(avr->am->matrix[0]); avr->am->matrix = NULL; } #define CONVERT_MATRIX(type, expr) \ avr->am->matrix_## type[0] = av_mallocz(out_channels * in_channels * \ sizeof(*avr->am->matrix_## type[0])); \ if (!avr->am->matrix_## type[0]) \ return AVERROR(ENOMEM); \ for (o = 0; o < out_channels; o++) { \ if (o > 0) \ avr->am->matrix_## type[o] = avr->am->matrix_## type[o - 1] + \ in_channels; \ for (i = 0; i < in_channels; i++) { \ double v = matrix[o * stride + i]; \ avr->am->matrix_## type[o][i] = expr; \ } \ } \ avr->am->matrix = (void **)avr->am->matrix_## type; switch (avr->mix_coeff_type) { case AV_MIX_COEFF_TYPE_Q8: CONVERT_MATRIX(q8, av_clip_int16(lrint(256.0 * v))) break; case AV_MIX_COEFF_TYPE_Q15: CONVERT_MATRIX(q15, av_clipl_int32(llrint(32768.0 * v))) break; case AV_MIX_COEFF_TYPE_FLT: CONVERT_MATRIX(flt, v) break; default: av_log(avr, AV_LOG_ERROR, "Invalid mix coeff type\n"); return AVERROR(EINVAL); } /* TODO: detect situations where we can just swap around pointers instead of doing matrix multiplications with 0.0 and 1.0 */ /* set AudioMix params */ avr->am->in_layout = avr->in_channel_layout; avr->am->out_layout = avr->out_channel_layout; avr->am->in_channels = in_channels; avr->am->out_channels = out_channels; return 0; }