On 04/08/2011 03:58 AM, Ronald S. Bultje wrote:
> 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...
Ok
>> +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.
Ok
>> + 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;ut
>> + 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.)
The costable is custom. And there is a float based transform in the
decoder already.
>> +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?
Decomposes the signal into bands. Time domain -> frequency domain.
>> +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.
Don't really know but I'd like to keep the fixed-point code path for reg
test purposes.
> 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?
It's the same as with every other libav encoder. But I guess it could
print all the 16 supported sample rates.
>> 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?
The decomposition filter.
> Ronald
MvH
Benjamin Larsson
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel