[email protected] (Niels Möller) writes: > I think this makes it clear that there should be some decent filter > for the upsampling.
Kostya explained to me that the right way to do the up-sampling is to apply 64-subband qmf decoding rather than 32-subband, when decoding the core channels. As if there were an X96 extension, but will all zeros for the X96 data. I made a first attempt at implementing this. I copied the filter coefficients from the spec (D.9 1024 tap FIR for X96 Synthesis QMF), thanks pdf2txt. (Beware that the table in the pdf has a duplicate row for element 160!). I then tried implementing an unoptimized transform. The spec pseudocode is pretty hard to read, and as far as I can find it only describes the 32 subband case at all. So I looked at the somewhat more readable version in http://multimedia.cx/mirror/dca-transform.pdf (still based on the pseudo code, not the equations), guessing a bit on the changes needed to extend it from 32 to 64 subbands. And I doubled the size of the arrays used for raX and raZ. I now have the below code, which doesn't work. The most obvious error is that it generates some occasional sample values close to 1/-1 (8388607 and -8388608) in 24-bit output, even in the initial almost silent portion of the file. It then sounds horrible in my right ear, and mostly right but low level in my left ear. static QMF64_table *qmf64_precompute(void) { QMF64_table *table = av_malloc (sizeof(*table)); unsigned i, j; if (!table) return NULL; for (i = 0; i < 32; i++) for (j = 0; j < 32; j++) table->dct4_coeff[i][j] = cos((2*i+1)*(2*j+1) * M_PI / 128); for (i = 0; i < 32; i++) for (j = 0; j < 32; j++) table->dct2_coeff[i][j] = cos(j*(2*i+1) * M_PI / 64); /* FIXME: Is the factor 0.125 = 1/8 right? */ for (i = 0; i < 32; i++) table->rcos[i] = 0.125 / cos((2*i+1) * M_PI / 256); for (i = 0; i < 32; i++) table->rsin[i] = -0.125 / sin((2*i+1) * M_PI / 256); return table; } /* FIXME: Totally un-optimized. Based on the reference code and * http://multimedia.cx/mirror/dca-transform.pdf, with guessed tweaks * for doubling the size. */ static void qmf_64_subbands(DCAContext *s, int chans, float samples_in[64][8], float *samples_out, float scale) { float raXin[64]; float A[32], B[32]; float *raX = s->subband_fir_hist[chans]; float *raZ = s->subband_fir_noidea[chans]; unsigned i, j, k, subindex; for (i = s->subband_activity[chans]; i < 64; i++) raXin[i] = 0.0; for (subindex = 0; subindex < 8; subindex++) { for (i = 0; i < s->subband_activity[chans]; i++) raXin[i] = samples_in[i][subindex]; for (k = 0; k < 32; k++) { A[k] = 0.0; for (i = 0; i < 32; i++) A[k] += (raXin[2*i] + raXin[2*i+1]) * s->qmf64_table->dct4_coeff[k][i]; } for (k = 0; k < 32; k++) { B[k] = raXin[0] * s->qmf64_table->dct2_coeff[k][0]; for (i = 1; i < 32; i++) B[k] += (raXin[2*i] + raXin[2*i-1]) * s->qmf64_table->dct2_coeff[k][i]; } for (k = 0; k < 32; k++) { raX[k] = s->qmf64_table->rcos[k] * (A[k] + B[k]); raX[63-k] = s->qmf64_table->rsin[k] * (A[k] - B[k]); } for (i = 0; i < 64; i++) { float out = raZ[i]; for (j = 0; j < 1024; j += 128) out += fir_64bands[j+i] * (raX[j+i] - raX[j+63-i]); *samples_out++ = out * scale; } for (i = 0; i < 64; i++) { float hist = 0.0; for (j = 0; j < 1024; j += 128) hist += fir_64bands[64+j+i] * (-raX[i+j] - raX[j+63-i]); raZ[i] = hist; } /* FIXME: Make buffer circular, to avoid this move. */ memmove (raX+64, raX, (1024 - 64) * sizeof(*raX)); } } Comments appreciated. The complete non-working code also available in my wip repo. Regards, /Niels -- Niels Möller. PGP-encrypted email is preferred. Keyid C0B98E26. Internet email is subject to wholesale government surveillance. _______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
