[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

Reply via email to