Hi,
2011/4/7 Benjamin Larsson <[email protected]>:
> +static inline int32_t mul32(int32_t a, int32_t b)
> +{
> + /* on >=i686, gcc compiles this into a single "imull" instruction */
> + int64_t r = (int64_t)a * b;
> + /* round the result before truncating - improves accuracy */
> + return (r + 0x80000000) >> 32;
> +}
I believe this is what the MUL64() macro is for, then it works on
non-x86 archs also, but that doesn't round...
> +static int32_t cos_table[128];
[..]
> +static void qmf_init(void)
There should probably be a static inited = 0; that you set after
succesful init, since this function only has to run once, not every
time the codec re-inits.
> + int i;
> + int32_t c[17], s[17];
> + s[0] = 0; /* sin(index * PI / 64) * 0x7fffffff */
> + c[0] = 0x7fffffff; /* cos(index * PI / 64) * 0x7fffffff */
> +
> + for (i = 1; i <= 16; i++) {
> + s[i] = 2 * (mul32(c[i-1], 105372028) + mul32(s[i-1], 2144896908));
> + c[i] = 2 * (mul32(c[i-1], 2144896908) - mul32(s[i-1], 105372028));
> + }
> +
> + for (i = 0; i < 16; i++) {
> + cos_table[i] = c[i] >> 3; /* so that the output doesn't overflow */
> + cos_table[i+16] = s[16-i] >> 3;
> + cos_table[i+32] = -s[i] >> 3;
> + cos_table[i+48] = -c[16-i] >> 3;
> + cos_table[i+64] = -c[i] >> 3;
> + cos_table[i+80] = -s[16-i] >> 3;
> + cos_table[i+96] = s[i] >> 3;
> + cos_table[i+112] = c[16-i] >> 3;
> + }
For the cos-table, can you use libavcodec/sinewin.h functions? If not,
does this look like a proper int-implementation of the same thing that
we might want to share? E.g. does acenc_fixed.c have fixed-point cos
table generation also?
(I know, this is minor, ignore for now, not critical.)
> +static void qmf_decompose(DCAContext *c, int32_t in[32], int32_t out[32],
> int channel)
> +{
> + int band, i, j, k;
> + int32_t resp;
> + int32_t accum[DCA_SUBBANDS_32];
> +
> + add_new_samples(c, in, DCA_SUBBANDS_32, channel);
> +
> + /* Calculate the dot product of the signal with the (possibly inverted)
> + reference decoder's response to this vector:
> + (0.0, 0.0, ..., 0.0, -1.0, 1.0, 0.0, ..., 0.0)
> + so that -1.0 cancels 1.0 from the previous step */
> +
> + memset(accum,0,sizeof(accum));
> +
> + for (k = 48, j = 0, i = c->start[channel]; i < 512; k++, j++, i++)
> + accum[(k & 32) ? (31 - (k & 31)) : (k & 31)] +=
> mul32(c->history[channel][i], UnQMF[j]);
> + for (i = 0; i < c->start[channel]; k++, j++, i++)
> + accum[(k & 32) ? (31 - (k & 31)) : (k & 31)] +=
> mul32(c->history[channel][i], UnQMF[j]);
> +
> + resp = 0;
> + /* TODO: implement FFT instead of this naive calculation */
> + for (band = 0; band < DCA_SUBBANDS_32; band++) {
> + for (j = 0; j < 32; j++)
> + resp += mul32(accum[j], band_delta_factor(band, j));
> +
> + out[band] = (band & 2) ? (-resp) : resp;
> + }
> +}
I'll probably sound very naive, but what does this piece of the code do?
> +static void init_lfe_fir(void){
> + static int initialized;
> + int i;
> + if(initialized)
> + return;
> + for(i=0; i<512; i++)
> + lfe_fir_64i[i] = lfe_fir_64[i] * (1<<25); //float -> int32_t
> + initialized = 1;
> +}
This kind of stuff, along with cos tables, FFT etc, raises the
question why this wasn't implemented in float... Realistically, if
!CONFIG_SMALL, the table should be hardcoded.
The bitstream stuff I didn't review because I'm not very familiar with it...
> +static int DCA_encode_init(AVCodecContext *avctx) {
[..]
> + for(i=0; i<16; i++){
> + if(dca_sample_rates[i] == avctx->sample_rate)
> + break;
> + }
> + if(i==16){
> + av_log(avctx, AV_LOG_ERROR, "Sample rate %iHz not supported\n",
> avctx->sample_rate);
> + return -1;
> + }
> + c->sample_rate_code = i;
That is pretty unhelpful. What samplerates _are_ supported? Better
yet, how would the user accomplish the resampling within ffmpeg?
> diff --git a/libavcodec/dcaenc.h b/libavcodec/dcaenc.h
[..]
> +/* This is a scaled version of the response of the reference decoder to
> + this vector of subband samples: ( 1.0 0.0 0.0 ... 0.0 )
> + */
> +
> +static const int32_t UnQMF[512] = {
??? What is that?
Ronald
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel