From: Miguel F. <mig...@us...> - 2002-08-09 22:36:41
|
Update of /cvsroot/xine/xine-lib/src/libfaad In directory usw-pr-cvs1:/tmp/cvs-serv8337 Modified Files: Makefile.am bits.c bits.h common.h decoder.c filtbank.c mdct.c mdct.h mp4.c syntax.c syntax.h Added Files: cfft.c cfft.h rvlc_scale_factors.c rvlc_scale_factors.h Log Message: sync with faad2 cvs (no more fftw dependency) --- NEW FILE: cfft.c --- /* ** FAAD - Freeware Advanced Audio Decoder ** Copyright (C) 2002 M. Bakker ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** $Id: cfft.c,v 1.1 2002/08/09 22:36:36 miguelfreitas Exp $ **/ /* * Algorithmically based on Fortran-77 FFTPACK * by Paul N. Swarztrauber(Version 4, 1985). */ /* isign is +1 for backward and -1 for forward transforms */ #include "common.h" #include <stdlib.h> #include "cfft.h" /*---------------------------------------------------------------------- passf2, passf3, passf4, passf5, passf. Complex FFT passes fwd and bwd. ----------------------------------------------------------------------*/ static void passf2(uint16_t ido, uint16_t l1, real_t *cc, real_t *ch, real_t *wa1, int8_t isign) { uint16_t i, k, ah, ac; real_t ti2, tr2; if (ido <= 2) { for (k = 0; k < l1; k++) { ah = k*ido; ac = 2*k*ido; ch[ah] = cc[ac] + cc[ac+ido]; ch[ah+ido*l1] = cc[ac] - cc[ac+ido]; ch[ah+1] = cc[ac+1] + cc[ac+ido+1]; ch[ah+ido*l1+1] = cc[ac+1] - cc[ac+ido+1]; } } else { for (k = 0; k < l1; k++) { for(i = 0; i < ido-1; i += 2) { ah = i + k*ido; ac = i + 2*k*ido; ch[ah] = cc[ac] + cc[ac+ido]; tr2 = cc[ac] - cc[ac+ido]; ch[ah+1] = cc[ac+1] + cc[ac+1+ido]; ti2 = cc[ac+1] - cc[ac+1+ido]; ch[ah+l1*ido+1] = wa1[i]*ti2 + isign*wa1[i+1]*tr2; ch[ah+l1*ido] = wa1[i]*tr2 - isign*wa1[i+1]*ti2; } } } } static void passf3(uint16_t ido, uint16_t l1, real_t *cc, real_t *ch, real_t *wa1, real_t *wa2, int8_t isign) { static real_t taur = -0.5; static real_t taui = 0.866025403784439; uint16_t i, k, ac, ah; real_t ci2, ci3, di2, di3, cr2, cr3, dr2, dr3, ti2, tr2; if (ido == 2) { for (k = 1; k <= l1; k++) { ac = (3*k-2) * ido; tr2 = cc[ac] + cc[ac+ido]; cr2 = cc[ac-ido] + taur*tr2; ah = (k-1) * ido; ch[ah] = cc[ac-ido] + tr2; ti2 = cc[ac+1] + cc[ac+ido+1]; ci2 = cc[ac-ido+1] + taur*ti2; ch[ah+1] = cc[ac-ido+1] + ti2; cr3 = isign * taui * (cc[ac] - cc[ac+ido]); ci3 = isign * taui * (cc[ac+1] - cc[ac+ido+1]); ch[ah+l1*ido] = cr2 - ci3; ch[ah+2*l1*ido] = cr2 + ci3; ch[ah+l1*ido+1] = ci2 + cr3; ch[ah+2*l1*ido+1] = ci2 - cr3; } } else { for (k = 1; k <= l1; k++) { for (i = 0; i < ido-1; i += 2) { ac = i + (3*k-2) * ido; tr2 = cc[ac] + cc[ac+ido]; cr2 = cc[ac-ido] + taur*tr2; ah = i + (k-1) * ido; ch[ah] = cc[ac-ido] + tr2; ti2 = cc[ac+1] + cc[ac+ido+1]; ci2 = cc[ac-ido+1] + taur*ti2; ch[ah+1] = cc[ac-ido+1] + ti2; cr3 = isign * taui * (cc[ac] - cc[ac+ido]); ci3 = isign * taui * (cc[ac+1] - cc[ac+ido+1]); dr2 = cr2 - ci3; dr3 = cr2 + ci3; di2 = ci2 + cr3; di3 = ci2 - cr3; ch[ah+l1*ido+1] = wa1[i]*di2 + isign*wa1[i+1]*dr2; ch[ah+l1*ido] = wa1[i]*dr2 - isign*wa1[i+1]*di2; ch[ah+2*l1*ido+1] = wa2[i]*di3 + isign*wa2[i+1]*dr3; ch[ah+2*l1*ido] = wa2[i]*dr3 - isign*wa2[i+1]*di3; } } } } static void passf4(uint16_t ido, uint16_t l1, real_t *cc, real_t *ch, real_t *wa1, real_t *wa2, real_t *wa3, int8_t isign) { uint16_t i, k, ac, ah; real_t ci2, ci3, ci4, cr2, cr3, cr4, ti1, ti2, ti3, ti4, tr1, tr2, tr3, tr4; if (ido == 2) { for (k = 0; k < l1; k++) { ac = 4*k*ido + 1; ti1 = cc[ac] - cc[ac+2*ido]; ti2 = cc[ac] + cc[ac+2*ido]; tr4 = cc[ac+3*ido] - cc[ac+ido]; ti3 = cc[ac+ido] + cc[ac+3*ido]; tr1 = cc[ac-1] - cc[ac+2*ido-1]; tr2 = cc[ac-1] + cc[ac+2*ido-1]; ti4 = cc[ac+ido-1] - cc[ac+3*ido-1]; tr3 = cc[ac+ido-1] + cc[ac+3*ido-1]; ah = k*ido; ch[ah] = tr2 + tr3; ch[ah+2*l1*ido] = tr2 - tr3; ch[ah+1] = ti2 + ti3; ch[ah+2*l1*ido+1] = ti2 - ti3; ch[ah+l1*ido] = tr1 + isign*tr4; ch[ah+3*l1*ido] = tr1 - isign*tr4; ch[ah+l1*ido+1] = ti1 + isign*ti4; ch[ah+3*l1*ido+1] = ti1 - isign*ti4; } } else { for (k = 0; k < l1; k++) { for (i = 0; i < ido-1; i += 2) { ac = i + 1 + 4*k*ido; ti1 = cc[ac] - cc[ac+2*ido]; ti2 = cc[ac] + cc[ac+2*ido]; ti3 = cc[ac+ido] + cc[ac+3*ido]; tr4 = cc[ac+3*ido] - cc[ac+ido]; tr1 = cc[ac-1] - cc[ac+2*ido-1]; tr2 = cc[ac-1] + cc[ac+2*ido-1]; ti4 = cc[ac+ido-1] - cc[ac+3*ido-1]; tr3 = cc[ac+ido-1] + cc[ac+3*ido-1]; ah = i + k*ido; ch[ah] = tr2 + tr3; cr3 = tr2 - tr3; ch[ah+1] = ti2 + ti3; ci3 = ti2 - ti3; cr2 = tr1 + isign*tr4; cr4 = tr1 - isign*tr4; ci2 = ti1 + isign*ti4; ci4 = ti1 - isign*ti4; ch[ah+l1*ido] = wa1[i]*cr2 - isign*wa1[i+1]*ci2; ch[ah+l1*ido+1] = wa1[i]*ci2 + isign*wa1[i+1]*cr2; ch[ah+2*l1*ido] = wa2[i]*cr3 - isign*wa2[i+1]*ci3; ch[ah+2*l1*ido+1] = wa2[i]*ci3 + isign*wa2[i+1]*cr3; ch[ah+3*l1*ido] = wa3[i]*cr4 - isign*wa3[i+1]*ci4; ch[ah+3*l1*ido+1] = wa3[i]*ci4 + isign*wa3[i+1]*cr4; } } } } static void passf5(uint16_t ido, uint16_t l1, real_t *cc, real_t *ch, real_t *wa1, real_t *wa2, real_t *wa3, real_t *wa4, int8_t isign) { static real_t tr11 = 0.309016994374947; static real_t ti11 = 0.951056516295154; static real_t tr12 = -0.809016994374947; static real_t ti12 = 0.587785252292473; uint16_t i, k, ac, ah; real_t ci2, ci3, ci4, ci5, di3, di4, di5, di2, cr2, cr3, cr5, cr4, ti2, ti3, ti4, ti5, dr3, dr4, dr5, dr2, tr2, tr3, tr4, tr5; if (ido == 2) { for (k = 1; k <= l1; ++k) { ac = (5*k-4) * ido + 1; ti5 = cc[ac] - cc[ac+3*ido]; ti2 = cc[ac] + cc[ac+3*ido]; ti4 = cc[ac+ido] - cc[ac+2*ido]; ti3 = cc[ac+ido] + cc[ac+2*ido]; tr5 = cc[ac-1] - cc[ac+3*ido-1]; tr2 = cc[ac-1] + cc[ac+3*ido-1]; tr4 = cc[ac+ido-1] - cc[ac+2*ido-1]; tr3 = cc[ac+ido-1] + cc[ac+2*ido-1]; ah = (k-1) * ido; ch[ah] = cc[ac-ido-1] + tr2 + tr3; ch[ah+1] = cc[ac-ido] + ti2 + ti3; cr2 = cc[ac-ido-1] + tr11*tr2 + tr12*tr3; ci2 = cc[ac-ido] + tr11*ti2 + tr12*ti3; cr3 = cc[ac-ido-1] + tr12*tr2 + tr11*tr3; ci3 = cc[ac-ido] + tr12*ti2 + tr11*ti3; cr5 = isign * (ti11*tr5 + ti12*tr4); ci5 = isign * (ti11*ti5 + ti12*ti4); cr4 = isign * (ti12*tr5 - ti11*tr4); ci4 = isign * (ti12*ti5 - ti11*ti4); ch[ah+l1*ido] = cr2 - ci5; ch[ah+4*l1*ido] = cr2 + ci5; ch[ah+l1*ido+1] = ci2 + cr5; ch[ah+2*l1*ido+1]=ci3 + cr4; ch[ah+2*l1*ido] = cr3 - ci4; ch[ah+3*l1*ido] = cr3 + ci4; ch[ah+3*l1*ido+1] = ci3 - cr4; ch[ah+4*l1*ido+1] = ci2 - cr5; } } else { for (k = 1; k <= l1; k++) { for (i = 0; i < ido-1; i += 2) { ac = i + 1 + (k*5-4) * ido; ti5 = cc[ac] - cc[ac+3*ido]; ti2 = cc[ac] + cc[ac+3*ido]; ti4 = cc[ac+ido] - cc[ac+2*ido]; ti3 = cc[ac+ido] + cc[ac+2*ido]; tr5 = cc[ac-1] - cc[ac+3*ido-1]; tr2 = cc[ac-1] + cc[ac+3*ido-1]; tr4 = cc[ac+ido-1] - cc[ac+2*ido-1]; tr3 = cc[ac+ido-1] + cc[ac+2*ido-1]; ah = i + (k-1) * ido; ch[ah] = cc[ac-ido-1] + tr2 + tr3; ch[ah+1] = cc[ac-ido] + ti2 + ti3; cr2 = cc[ac-ido-1] + tr11*tr2 + tr12*tr3; ci2 = cc[ac-ido] + tr11*ti2 + tr12*ti3; cr3 = cc[ac-ido-1] + tr12*tr2 + tr11*tr3; ci3 = cc[ac-ido] + tr12*ti2 + tr11*ti3; cr5 = isign * (ti11*tr5 + ti12*tr4); ci5 = isign * (ti11*ti5 + ti12*ti4); cr4 = isign * (ti12*tr5 - ti11*tr4); ci4 = isign * (ti12*ti5 - ti11*ti4); dr3 = cr3 - ci4; dr4 = cr3 + ci4; di3 = ci3 + cr4; di4 = ci3 - cr4; dr5 = cr2 + ci5; dr2 = cr2 - ci5; di5 = ci2 - cr5; di2 = ci2 + cr5; ch[ah+l1*ido] = wa1[i]*dr2 - isign*wa1[i+1]*di2; ch[ah+l1*ido+1] = wa1[i]*di2 + isign*wa1[i+1]*dr2; ch[ah+2*l1*ido] = wa2[i]*dr3 - isign*wa2[i+1]*di3; ch[ah+2*l1*ido+1] = wa2[i]*di3 + isign*wa2[i+1]*dr3; ch[ah+3*l1*ido] = wa3[i]*dr4 - isign*wa3[i+1]*di4; ch[ah+3*l1*ido+1] = wa3[i]*di4 + isign*wa3[i+1]*dr4; ch[ah+4*l1*ido] = wa4[i]*dr5 - isign*wa4[i+1]*di5; ch[ah+4*l1*ido+1] = wa4[i]*di5 + isign*wa4[i+1]*dr5; } } } } static void passf(uint16_t *nac, uint16_t ido, uint16_t ip, uint16_t l1, uint16_t idl1, real_t *cc, real_t *ch, real_t *wa, int8_t isign) { uint16_t idij, idlj, idot, ipph, i, j, k, l, jc, lc, ik, nt, idj, idl; uint16_t inc, idp; real_t wai, war; idot = ido / 2; nt = ip*idl1; ipph = (ip+1) / 2; idp = ip*ido; if (ido >= l1) { for (j = 1; j < ipph; j++) { jc = ip - j; for (k = 0; k < l1; k++) { for (i = 0; i < ido; i++) { ch[i+(k+j*l1)*ido] = cc[i+(j+k*ip)*ido] + cc[i+(jc+k*ip)*ido]; ch[i+(k+jc*l1)*ido] = cc[i+(j+k*ip)*ido] - cc[i+(jc+k*ip)*ido]; } } } for (k = 0; k < l1; k++) { for (i = 0; i < ido; i++) ch[i+k*ido] = cc[i+k*ip*ido]; } } else { for (j = 1; j < ipph; j++) { jc = ip - j; for (i = 0; i < ido; i++) { for (k = 0; k < l1; k++) { ch[i+(k+j*l1)*ido] = cc[i+(j+k*ip)*ido] + cc[i+(jc+k*ip)*ido]; ch[i+(k+jc*l1)*ido] = cc[i+(j+k*ip)*ido] - cc[i+(jc+k*ip)*ido]; } } } for (i = 0; i < ido; i++) { for (k = 0; k < l1; k++) ch[i+k*ido] = cc[i+k*ip*ido]; } } idl = 2 - ido; inc = 0; for (l = 1; l < ipph; l++) { lc = ip - l; idl += ido; for (ik = 0; ik < idl1; ik++) { cc[ik+l*idl1] = ch[ik] + wa[idl-2]*ch[ik+idl1]; cc[ik+lc*idl1] = isign*wa[idl-1]*ch[ik+(ip-1)*idl1]; } idlj = idl; inc += ido; for (j = 2; j < ipph; j++) { jc = ip - j; idlj += inc; if (idlj > idp) idlj -= idp; war = wa[idlj-2]; wai = wa[idlj-1]; for (ik = 0; ik < idl1; ik++) { cc[ik+l*idl1] += war*ch[ik+j*idl1]; cc[ik+lc*idl1] += isign*wai*ch[ik+jc*idl1]; } } } for (j = 1; j < ipph; j++) { for (ik = 0; ik < idl1; ik++) ch[ik] += ch[ik+j*idl1]; } for (j = 1; j < ipph; j++) { jc = ip - j; for (ik = 1; ik < idl1; ik += 2) { ch[ik-1+j*idl1] = cc[ik-1+j*idl1] - cc[ik+jc*idl1]; ch[ik-1+jc*idl1] = cc[ik-1+j*idl1] + cc[ik+jc*idl1]; ch[ik+j*idl1] = cc[ik+j*idl1] + cc[ik-1+jc*idl1]; ch[ik+jc*idl1] = cc[ik+j*idl1] - cc[ik-1+jc*idl1]; } } *nac = 1; if (ido == 2) return; *nac = 0; for (ik = 0; ik < idl1; ik++) cc[ik] = ch[ik]; for (j = 1; j < ip; j++) { for (k = 0; k < l1; k++) { cc[(k+j*l1)*ido+0] = ch[(k+j*l1)*ido+0]; cc[(k+j*l1)*ido+1] = ch[(k+j*l1)*ido+1]; } } if (idot <= l1) { idij = 0; for (j = 1; j < ip; j++) { idij += 2; for (i = 3; i < ido; i += 2) { idij += 2; for (k = 0; k < l1; k++) { cc[i-1+(k+j*l1)*ido] = wa[idij-2] * ch[i-1+(k+j*l1)*ido] - isign * wa[idij-1] * ch[i+(k+j*l1)*ido]; cc[i+(k+j*l1)*ido] = wa[idij-2] * ch[i+(k+j*l1)*ido] + isign * wa[idij-1] * ch[i-1+(k+j*l1)*ido]; } } } } else { idj = 2 - ido; for (j = 1; j < ip; j++) { idj += ido; for (k = 0; k < l1; k++) { idij = idj; for (i = 3; i < ido; i += 2) { idij += 2; cc[i-1+(k+j*l1)*ido] = wa[idij-2] * ch[i-1+(k+j*l1)*ido] - isign * wa[idij-1] * ch[i+(k+j*l1)*ido]; cc[i+(k+j*l1)*ido] = wa[idij-2] * ch[i+(k+j*l1)*ido] + isign * wa[idij-1] * ch[i-1+(k+j*l1)*ido]; } } } } } /*---------------------------------------------------------------------- cfftf1, cfftf, cfftb, cffti1, cffti. Complex FFTs. ----------------------------------------------------------------------*/ INLINE void cfftf1(uint16_t n, real_t *c, real_t *ch, real_t *wa, uint16_t *ifac, int8_t isign) { uint16_t idot, i; uint16_t k1, l1, l2; uint16_t na, nf, ip, iw, ix2, ix3, ix4, nac, ido, idl1; nf = ifac[1]; na = 0; l1 = 1; iw = 0; for (k1 = 2; k1 <= nf+1; k1++) { ip = ifac[k1]; l2 = ip*l1; ido = n / l2; idot = ido+ido; idl1 = idot*l1; switch (ip) { case 2: if (na == 0) passf2(idot, l1, c, ch, &wa[iw], isign); else passf2(idot, l1, ch, c, &wa[iw], isign); na = 1 - na; break; case 3: ix2 = iw + idot; if (na == 0) passf3(idot, l1, c, ch, &wa[iw], &wa[ix2], isign); else passf3(idot, l1, ch, c, &wa[iw], &wa[ix2], isign); na = 1 - na; break; case 4: ix2 = iw + idot; ix3 = ix2 + idot; if (na == 0) passf4(idot, l1, c, ch, &wa[iw], &wa[ix2], &wa[ix3], isign); else passf4(idot, l1, ch, c, &wa[iw], &wa[ix2], &wa[ix3], isign); na = 1 - na; break; case 5: ix2 = iw + idot; ix3 = ix2 + idot; ix4 = ix3 + idot; if (na == 0) passf5(idot, l1, c, ch, &wa[iw], &wa[ix2], &wa[ix3], &wa[ix4], isign); else passf5(idot, l1, ch, c, &wa[iw], &wa[ix2], &wa[ix3], &wa[ix4], isign); na = 1 - na; break; default: if (na == 0) passf(&nac, idot, ip, l1, idl1, c, ch, &wa[iw], isign); else passf(&nac, idot, ip, l1, idl1, ch, c, &wa[iw], isign); if (nac != 0) na = 1 - na; break; } l1 = l2; iw += (ip-1) * idot; } if (na == 0) return; for (i = 0; i < 2*n; i++) c[i] = ch[i]; } void cfftf(cfft_info cfft, real_t *c) { cfftf1(cfft.n, c, cfft.work, cfft.tab, cfft.ifac, -1); } void cfftb(cfft_info cfft, real_t *c) { cfftf1(cfft.n, c, cfft.work, cfft.tab, cfft.ifac, +1); } static void cffti1(uint16_t n, real_t *wa, uint16_t *ifac) { static uint16_t ntryh[4] = {3, 4, 2, 5}; real_t arg, argh, argld, fi; uint16_t idot, ntry, i, j; uint16_t i1, k1, l1, l2, ib; uint16_t ld, ii, nf, ip, nl, nq, nr; uint16_t ido, ipm; nl = n; nf = 0; j = 0; startloop: j++; if (j <= 4) ntry = ntryh[j-1]; else ntry += 2; do { nq = nl / ntry; nr = nl - ntry*nq; if (nr != 0) goto startloop; nf++; ifac[nf+1] = ntry; nl = nq; if (ntry == 2 && nf != 1) { for (i = 2; i <= nf; i++) { ib = nf - i + 2; ifac[ib+1] = ifac[ib]; } ifac[2] = 2; } } while (nl != 1); ifac[0] = n; ifac[1] = nf; argh = 2*M_PI / (real_t)n; i = 1; l1 = 1; for (k1 = 1; k1 <= nf; k1++) { ip = ifac[k1+1]; ld = 0; l2 = l1*ip; ido = n / l2; idot = ido + ido + 2; ipm = ip - 1; for (j = 1; j <= ipm; j++) { i1 = i; wa[i-1] = 1; wa[i] = 0; ld += l1; fi = 0; argld = ld*argh; for (ii = 4; ii <= idot; ii += 2) { i += 2; fi += 1; arg = fi*argld; wa[i-1] = cos(arg); wa[i] = sin(arg); } if (ip > 5) { wa[i1-1] = wa[i-1]; wa[i1] = wa[i]; } } l1 = l2; } } cfft_info cffti(uint16_t n) { cfft_info cfft; cfft.n = n; cfft.work = malloc(2*n*sizeof(real_t)); cfft.tab = malloc(2*n*sizeof(real_t)); cffti1(n, cfft.tab, cfft.ifac); return cfft; } void cfftu(cfft_info cfft) { if (cfft.work) free(cfft.work); if (cfft.tab) free(cfft.tab); } --- NEW FILE: cfft.h --- /* ** FAAD - Freeware Advanced Audio Decoder ** Copyright (C) 2002 M. Bakker ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** $Id: cfft.h,v 1.1 2002/08/09 22:36:36 miguelfreitas Exp $ **/ #ifndef __CFFT_H__ #define __CFFT_H__ #ifdef __cplusplus extern "C" { #endif typedef struct { real_t *work; real_t *tab; uint16_t ifac[15]; uint16_t n; } cfft_info; void cfftf(cfft_info cfft, real_t *c); // complex transform void cfftb(cfft_info cfft, real_t *c); // its inverse cfft_info cffti(uint16_t n); // initializer of the above routine pair void cfftu(cfft_info cfft); static void passf2(uint16_t ido, uint16_t l1, real_t *cc, real_t *ch, real_t *wa1, int8_t isign); static void passf3(uint16_t ido, uint16_t l1, real_t *cc, real_t *ch, real_t *wa1, real_t *wa2, int8_t isign); static void passf4(uint16_t ido, uint16_t l1, real_t *cc, real_t *ch, real_t *wa1, real_t *wa2, real_t *wa3, int8_t isign); static void passf5(uint16_t ido, uint16_t l1, real_t *cc, real_t *ch, real_t *wa1, real_t *wa2, real_t *wa3, real_t *wa4, int8_t isign); static void passf(uint16_t *nac, uint16_t ido, uint16_t ip, uint16_t l1, uint16_t idl1, real_t *cc, real_t *ch, real_t *wa, int8_t isign); INLINE void cfftf1(uint16_t n, real_t *c, real_t *ch, real_t *wa, uint16_t *ifac, int8_t isign); static void cffti1(uint16_t n, real_t *wa, uint16_t *ifac); #ifdef __cplusplus } #endif #endif --- NEW FILE: rvlc_scale_factors.c --- /* ** FAAD - Freeware Advanced Audio Decoder ** Copyright (C) 2002 M. Bakker ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** $Id: rvlc_scale_factors.c,v 1.1 2002/08/09 22:36:36 miguelfreitas Exp $ **/ #include "common.h" #include <stdlib.h> #include "syntax.h" #include "bits.h" #include "rvlc_scale_factors.h" #ifdef ERROR_RESILIENCE uint8_t rvlc_scale_factor_data(ic_stream *ics, bitfile *ld) { uint8_t bits = 9; ics->sf_concealment = faad_get1bit(ld DEBUGVAR(1,149,"rvlc_scale_factor_data(): sf_concealment")); ics->rev_global_gain = faad_getbits(ld, 8 DEBUGVAR(1,150,"rvlc_scale_factor_data(): rev_global_gain")); if (ics->window_sequence == EIGHT_SHORT_SEQUENCE) bits = 11; /* the number of bits used for the huffman codewords */ ics->length_of_rvlc_sf = faad_getbits(ld, bits DEBUGVAR(1,151,"rvlc_scale_factor_data(): length_of_rvlc_sf")); if (ics->noise_used) { ics->dpcm_noise_nrg = faad_getbits(ld, 9 DEBUGVAR(1,152,"rvlc_scale_factor_data(): dpcm_noise_nrg")); ics->length_of_rvlc_sf -= 9; } ics->sf_escapes_present = faad_get1bit(ld DEBUGVAR(1,153,"rvlc_scale_factor_data(): sf_escapes_present")); if (ics->sf_escapes_present) { ics->length_of_rvlc_escapes = faad_getbits(ld, 8 DEBUGVAR(1,154,"rvlc_scale_factor_data(): length_of_rvlc_escapes")); } if (ics->noise_used) { ics->dpcm_noise_last_position = faad_getbits(ld, 9 DEBUGVAR(1,155,"rvlc_scale_factor_data(): dpcm_noise_last_position")); } return 0; } uint8_t rvlc_decode_scale_factors(ic_stream *ics, bitfile *ld) { uint8_t result; uint8_t *rvlc_sf_buffer = NULL; uint8_t *rvlc_esc_buffer = NULL; bitfile ld_rvlc_sf; bitfile ld_rvlc_esc; if (ics->length_of_rvlc_sf > 0) { /* We read length_of_rvlc_sf bits here to put it in a seperate bitfile. */ rvlc_sf_buffer = faad_getbitbuffer(ld, ics->length_of_rvlc_sf DEBUGVAR(1,156,"rvlc_decode_scale_factors(): bitbuffer: length_of_rvlc_sf")); faad_initbits(&ld_rvlc_sf, (void*)rvlc_sf_buffer); } if (ics->sf_escapes_present) { /* We read length_of_rvlc_escapes bits here to put it in a seperate bitfile. */ rvlc_esc_buffer = faad_getbitbuffer(ld, ics->length_of_rvlc_escapes DEBUGVAR(1,157,"rvlc_decode_scale_factors(): bitbuffer: length_of_rvlc_escapes")); faad_initbits(&ld_rvlc_esc, (void*)rvlc_esc_buffer); } /* decode the rvlc scale factors and escapes */ result = rvlc_decode_sf_forward(ics, &ld_rvlc_sf, &ld_rvlc_esc); if (rvlc_esc_buffer) free(rvlc_esc_buffer); if (rvlc_sf_buffer) free(rvlc_sf_buffer); return result; } static uint8_t rvlc_decode_sf_forward(ic_stream *ics, bitfile *ld_sf, bitfile *ld_esc) { uint8_t g, sfb; int8_t t = 0; int8_t error = 0; int8_t noise_pcm_flag = 1; int16_t scale_factor = ics->global_gain; int16_t is_position = 0; int16_t noise_energy = ics->global_gain - 90; for (g = 0; g < ics->num_window_groups; g++) { for (sfb = 0; sfb < ics->max_sfb; sfb++) { if (error) { ics->scale_factors[g][sfb] = 0; } else { switch (ics->sfb_cb[g][sfb]) { case ZERO_HCB: /* zero book */ ics->scale_factors[g][sfb] = 0; break; case INTENSITY_HCB: /* intensity books */ case INTENSITY_HCB2: /* decode intensity position */ t = rvlc_huffman_sf(ld_sf, ld_esc); is_position += t; ics->scale_factors[g][sfb] = is_position; break; case NOISE_HCB: /* noise books */ /* decode noise energy */ if (noise_pcm_flag) { int8_t n = ics->dpcm_noise_nrg; noise_pcm_flag = 0; noise_energy += n; } else { t = rvlc_huffman_sf(ld_sf, ld_esc); noise_energy += t; } ics->scale_factors[g][sfb] = noise_energy; break; case BOOKSCL: /* invalid books */ return 3; default: /* spectral books */ /* decode scale factor */ t = rvlc_huffman_sf(ld_sf, ld_esc); scale_factor += t; if (scale_factor < 0) return 4; ics->scale_factors[g][sfb] = scale_factor; break; } if (t == 99) { error = 1; } } } } return 0; } /* index == 99 means not allowed codeword */ static rvlc_huff_table book_rvlc[] = { /*index length codeword */ { 0, 1, 0 }, /* 0 */ { -1, 3, 5 }, /* 101 */ { 1, 3, 7 }, /* 111 */ { -2, 4, 9 }, /* 1001 */ { -3, 5, 17 }, /* 10001 */ { 2, 5, 27 }, /* 11011 */ { -4, 6, 33 }, /* 100001 */ { 99, 6, 50 }, /* 110010 */ { 3, 6, 51 }, /* 110011 */ { 99, 6, 52 }, /* 110100 */ { -7, 7, 65 }, /* 1000001 */ { 99, 7, 96 }, /* 1100000 */ { 99, 7, 98 }, /* 1100010 */ { 7, 7, 99 }, /* 1100011 */ { 4, 7, 107 }, /* 1101011 */ { -5, 8, 129 }, /* 10000001 */ { 99, 8, 194 }, /* 11000010 */ { 5, 8, 195 }, /* 11000011 */ { 99, 8, 212 }, /* 11010100 */ { 99, 9, 256 }, /* 100000000 */ { -6, 9, 257 }, /* 100000001 */ { 99, 9, 426 }, /* 110101010 */ { 6, 9, 427 }, /* 110101011 */ { 99, 10, 0 } /* Shouldn't come this far */ }; static rvlc_huff_table book_escape[] = { /*index length codeword */ { 1, 2, 0 }, { 0, 2, 2 }, { 3, 3, 2 }, { 2, 3, 6 }, { 4, 4, 14 }, { 7, 5, 13 }, { 6, 5, 15 }, { 5, 5, 31 }, { 11, 6, 24 }, { 10, 6, 25 }, { 9, 6, 29 }, { 8, 6, 61 }, { 13, 7, 56 }, { 12, 7, 120 }, { 15, 8, 114 }, { 14, 8, 242 }, { 17, 9, 230 }, { 16, 9, 486 }, { 19, 10, 463 }, { 18, 10, 974 }, { 22, 11, 925 }, { 20, 11, 1950 }, { 21, 11, 1951 }, { 23, 12, 1848 }, { 25, 13, 3698 }, { 24, 14, 7399 }, { 26, 15, 14797 }, { 49, 19, 236736 }, { 50, 19, 236737 }, { 51, 19, 236738 }, { 52, 19, 236739 }, { 53, 19, 236740 }, { 27, 20, 473482 }, { 28, 20, 473483 }, { 29, 20, 473484 }, { 30, 20, 473485 }, { 31, 20, 473486 }, { 32, 20, 473487 }, { 33, 20, 473488 }, { 34, 20, 473489 }, { 35, 20, 473490 }, { 36, 20, 473491 }, { 37, 20, 473492 }, { 38, 20, 473493 }, { 39, 20, 473494 }, { 40, 20, 473495 }, { 41, 20, 473496 }, { 42, 20, 473497 }, { 43, 20, 473498 }, { 44, 20, 473499 }, { 45, 20, 473500 }, { 46, 20, 473501 }, { 47, 20, 473502 }, { 48, 20, 473503 }, { 99, 21, 0 } /* Shouldn't come this far */ }; static int8_t rvlc_huffman_sf(bitfile *ld_sf, bitfile *ld_esc) { uint8_t i, j; int8_t index; uint32_t cw; rvlc_huff_table *h = book_rvlc; i = h->len; cw = faad_getbits(ld_sf, i); while ((cw != h->cw) && (i < 10)) { h++; j = h->len-i; i += j; cw <<= j; cw |= faad_getbits(ld_sf, j); } index = h->index; if (index == +ESC_VAL) { int8_t esc = rvlc_huffman_esc(ld_esc); if (esc == 99) return 99; index += esc; } if (index == -ESC_VAL) { int8_t esc = rvlc_huffman_esc(ld_esc); if (esc == 99) return 99; index -= esc; } return index; } static int8_t rvlc_huffman_esc(bitfile *ld) { uint8_t i, j; uint32_t cw; rvlc_huff_table *h = book_escape; i = h->len; cw = faad_getbits(ld, i); while ((cw != h->cw) && (i < 21)) { h++; j = h->len-i; i += j; cw <<= j; cw |= faad_getbits(ld, j); } return h->index; } #endif --- NEW FILE: rvlc_scale_factors.h --- /* ** FAAD - Freeware Advanced Audio Decoder ** Copyright (C) 2002 M. Bakker ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** $Id: rvlc_scale_factors.h,v 1.1 2002/08/09 22:36:36 miguelfreitas Exp $ **/ #ifndef __RVLC_SCF_H__ #define __RVLC_SCF_H__ #ifdef __cplusplus extern "C" { #endif typedef struct { int8_t index; uint8_t len; uint32_t cw; } rvlc_huff_table; #define ESC_VAL 7 uint8_t rvlc_scale_factor_data(ic_stream *ics, bitfile *ld); uint8_t rvlc_decode_scale_factors(ic_stream *ics, bitfile *ld); static uint8_t rvlc_decode_sf_forward(ic_stream *ics, bitfile *ld_sf, bitfile *ld_esc); static int8_t rvlc_huffman_sf(bitfile *ld_sf, bitfile *ld_esc); static int8_t rvlc_huffman_esc(bitfile *ld_esc); #ifdef __cplusplus } #endif #endif Index: Makefile.am =================================================================== RCS file: /cvsroot/xine/xine-lib/src/libfaad/Makefile.am,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- Makefile.am 21 Jul 2002 01:36:42 -0000 1.6 +++ Makefile.am 9 Aug 2002 22:36:36 -0000 1.7 @@ -2,16 +2,12 @@ ## Process this file with automake to produce Makefile.in ## -SUBDIRS = fftw codebook +SUBDIRS = codebook LIBTOOL = $(SHELL) $(top_builddir)/libtool-nofpic libdir = $(XINE_PLUGINDIR) -CFLAGS = @CFLAGS@ -I$(srcdir)/fftw - -DEBUG_CFLAGS = @DEBUG_CFLAGS@ -I$(srcdir)/fftw - if BUILD_FAAD faad_module = xineplug_decode_faad.la endif @@ -21,20 +17,19 @@ VPATH = @srcdir@:@srcdir@/codebook: xineplug_decode_faad_la_SOURCES = xine_decoder.c \ - bits.c data.c decoder.c drc.c error.c filtbank.c \ + bits.c data.c decoder.c drc.c error.c filtbank.c rvlc_scale_factors.c \ ic_predict.c is.c lt_predict.c mdct.c mp4.c ms.c output.c pns.c \ - pulse.c specrec.c syntax.c tns.c reordered_spectral_data.c \ + pulse.c specrec.c syntax.c tns.c reordered_spectral_data.c cfft.c \ hcb_1.c hcb_2.c hcb_3.c hcb_4.c hcb_5.c hcb_6.c hcb_7.c hcb_8.c \ hcb_9.c hcb_10.c hcb_11.c hcb_sf.c xineplug_decode_faad_la_LDFLAGS = -avoid-version -module -xineplug_decode_faad_la_LIBADD = $(top_builddir)/src/libfaad/fftw/libfftw.la \ - $(top_builddir)/src/xine-utils/libxineutils.la +xineplug_decode_faad_la_LIBADD = $(top_builddir)/src/xine-utils/libxineutils.la noinst_HEADERS = analysis.h bits.h common.h data.h decoder.h drc.h error.h \ - filtbank.h huffman.h ic_predict.h is.h kbd_win.h \ + filtbank.h huffman.h ic_predict.h is.h kbd_win.h cfft.h \ lt_predict.h mdct.h mp4.h ms.h output.h pns.h pulse.h \ - sbr_dec.h sbr_huff.h sbr_qmf.h sbr_syntax.h \ - specrec.h syntax.h tns.h codebook/hcb.h faad.h + sbr_dec.h sbr_huff.h sbr_qmf.h sbr_syntax.h rvlc_scale_factors.h \ + specrec.h syntax.h tns.h codebook/hcb.h faad.h debug: @$(MAKE) CFLAGS="$(DEBUG_CFLAGS)" Index: bits.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/libfaad/bits.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- bits.c 14 Jul 2002 23:43:01 -0000 1.1 +++ bits.c 9 Aug 2002 22:36:36 -0000 1.2 @@ -20,6 +20,7 @@ **/ #include "common.h" +#include <stdlib.h> #include "bits.h" /* initialize buffer, call once before first getbits or showbits */ @@ -60,4 +61,28 @@ return (8 - remainder); } return 0; +} + +uint8_t *faad_getbitbuffer(bitfile *ld, uint16_t bits + DEBUGDEC) +{ + uint16_t i, temp; + uint16_t bytes = bits / 8; + uint8_t remainder = bits % 8; + + uint8_t *buffer = (uint8_t*)malloc((bytes+1)*sizeof(uint8_t)); + + for (i = 0; i < bytes; i++) + { + buffer[i] = faad_getbits(ld, 8 DEBUGVAR(print,var,dbg)); + } + + if (remainder) + { + temp = faad_getbits(ld, remainder DEBUGVAR(print,var,dbg)) << (8-remainder); + + buffer[bytes] = temp; + } + + return buffer; } Index: bits.h =================================================================== RCS file: /cvsroot/xine/xine-lib/src/libfaad/bits.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- bits.h 14 Jul 2002 23:43:01 -0000 1.1 +++ bits.h 9 Aug 2002 22:36:36 -0000 1.2 @@ -58,6 +58,8 @@ void faad_initbits(bitfile *ld, void *buffer); uint8_t faad_byte_align(bitfile *ld); uint32_t faad_get_processed_bits(bitfile *ld); +uint8_t *faad_getbitbuffer(bitfile *ld, uint16_t bits + DEBUGDEC); static INLINE uint32_t faad_showbits(bitfile *ld, uint8_t bits) @@ -94,7 +96,12 @@ /* return next n bits (right adjusted) */ static INLINE uint32_t faad_getbits(bitfile *ld, uint8_t n DEBUGDEC) { - uint32_t ret = faad_showbits(ld, n); + uint32_t ret; + + if (n == 0) + return 0; + + ret = faad_showbits(ld, n); faad_flushbits(ld, n); #ifdef ANALYSIS Index: common.h =================================================================== RCS file: /cvsroot/xine/xine-lib/src/libfaad/common.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- common.h 14 Jul 2002 23:43:01 -0000 1.1 +++ common.h 9 Aug 2002 22:36:36 -0000 1.2 @@ -54,6 +54,9 @@ /* COMPILE TIME DEFINITIONS */ +/* use the somewhat faster, but a lot larger FFTW library */ +//#define USE_FFTW + /* use double precision */ /* #define USE_DOUBLE_PRECISION */ Index: decoder.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/libfaad/decoder.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- decoder.c 14 Jul 2002 23:43:01 -0000 1.1 +++ decoder.c 9 Aug 2002 22:36:36 -0000 1.2 @@ -331,6 +331,7 @@ memset(syntax_elements[ch_ele], 0, sizeof(element)); \ syntax_elements[ch_ele]->ele_id = id_syn_ele; \ syntax_elements[ch_ele]->channel = channels; \ + syntax_elements[ch_ele]->paired_channel = -1; \ \ if ((hInfo->error = single_lfe_channel_element(syntax_elements[ch_ele], \ ld, spec_data[channels], sf_index, object_type, frame_len, \ @@ -353,6 +354,7 @@ memset(syntax_elements[ch_ele], 0, sizeof(element)); \ syntax_elements[ch_ele]->ele_id = id_syn_ele; \ syntax_elements[ch_ele]->channel = channels; \ + syntax_elements[ch_ele]->paired_channel = -1; \ \ if ((hInfo->error = single_lfe_channel_element(syntax_elements[ch_ele], \ ld, spec_data[channels], sf_index, object_type, frame_len)) > 0) \ @@ -623,13 +625,9 @@ for (i = 0; i < ch_ele; i++) { if (syntax_elements[i]->channel == ch) - { ics = &(syntax_elements[i]->ics1); - break; - } else if (syntax_elements[i]->paired_channel == ch) { + else if (syntax_elements[i]->paired_channel == ch) ics = &(syntax_elements[i]->ics2); - break; - } } /* inverse quantization */ @@ -664,12 +662,10 @@ ltp = &(ics->ltp); pch = syntax_elements[i]->paired_channel; right_channel = 0; - break; } else if (syntax_elements[i]->paired_channel == ch) { ics = &(syntax_elements[i]->ics2); ltp = &(ics->ltp2); right_channel = 1; - break; } } Index: filtbank.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/libfaad/filtbank.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- filtbank.c 14 Jul 2002 23:43:01 -0000 1.1 +++ filtbank.c 9 Aug 2002 22:36:36 -0000 1.2 @@ -322,7 +322,7 @@ window_short_prev_ptr = window_short; } - vcopy(obuf_temp, o_buf + 448, nlong*2-nflat_ls); + vcopy(obuf_temp, o_buf + nflat_ls, nlong*2-nflat_ls); vzero(o_buf+2*nlong-1, nflat_ls); free(obuf_temp); Index: mdct.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/libfaad/mdct.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- mdct.c 14 Jul 2002 23:43:01 -0000 1.1 +++ mdct.c 9 Aug 2002 22:36:36 -0000 1.2 @@ -42,13 +42,16 @@ #include <stdlib.h> #include <assert.h> +#ifdef USE_FFTW /* uses fftw (http://www.fftw.org) for very fast arbitrary-n FFT and IFFT */ #include <fftw.h> +#else +#include "cfft.h" +#endif #include "mdct.h" - void faad_mdct_init(mdct_info *mdct, uint16_t N) { uint16_t k; @@ -57,8 +60,13 @@ mdct->N = N; mdct->sincos = (faad_sincos*)malloc(N/4*sizeof(faad_sincos)); +#ifdef USE_FFTW mdct->Z1 = (fftw_complex*)malloc(N/4*sizeof(fftw_complex)); mdct->Z2 = (fftw_complex*)malloc(N/4*sizeof(fftw_complex)); +#else + mdct->Z1 = (real_t*)malloc(N/2*sizeof(real_t)); + mdct->Z2 = (faad_complex*)malloc(N/4*sizeof(faad_complex)); +#endif for (k = 0; k < N/4; k++) { @@ -67,18 +75,27 @@ mdct->sincos[k].cos = -cos(angle); } +#ifdef USE_FFTW mdct->plan_backward = fftw_create_plan(N/4, FFTW_BACKWARD, FFTW_ESTIMATE); #ifdef LTP_DEC mdct->plan_forward = fftw_create_plan(N/4, FFTW_FORWARD, FFTW_ESTIMATE); #endif +#else + /* own implementation */ + mdct->cfft = cffti(N/4); +#endif } void faad_mdct_end(mdct_info *mdct) { +#ifdef USE_FFTW fftw_destroy_plan(mdct->plan_backward); #ifdef LTP_DEC fftw_destroy_plan(mdct->plan_forward); #endif +#else + cfftu(mdct->cfft); +#endif if (mdct->Z2) free(mdct->Z2); if (mdct->Z1) free(mdct->Z1); @@ -89,9 +106,15 @@ { uint16_t k; +#ifdef USE_FFTW fftw_complex *Z1 = mdct->Z1; fftw_complex *Z2 = mdct->Z2; +#else + real_t *Z1 = mdct->Z1; + faad_complex *Z2 = mdct->Z2; +#endif faad_sincos *sincos = mdct->sincos; + real_t fftdata[1024]; uint16_t N = mdct->N; uint16_t N2 = N >> 1; @@ -106,18 +129,32 @@ uint16_t n = k << 1; real_t x0 = X_in[ n]; real_t x1 = X_in[N2 - 1 - n]; +#ifdef USE_FFTW Z1[k].re = MUL(fac, MUL(x1, sincos[k].cos) - MUL(x0, sincos[k].sin)); Z1[k].im = MUL(fac, MUL(x0, sincos[k].cos) + MUL(x1, sincos[k].sin)); +#else + Z1[2*k] = MUL(fac, MUL(x1, sincos[k].cos) - MUL(x0, sincos[k].sin)); + Z1[2*k+1] = MUL(fac, MUL(x0, sincos[k].cos) + MUL(x1, sincos[k].sin)); +#endif } /* complex IFFT */ +#ifdef USE_FFTW fftw_one(mdct->plan_backward, Z1, Z2); +#else + cfftb(mdct->cfft, Z1); +#endif /* post-IFFT complex multiplication */ for (k = 0; k < N4; k++) { +#ifdef USE_FFTW real_t zr = Z2[k].re; real_t zi = Z2[k].im; +#else + real_t zr = Z1[2*k]; + real_t zi = Z1[2*k+1]; +#endif Z2[k].re = MUL(zr, sincos[k].cos) - MUL(zi, sincos[k].sin); Z2[k].im = MUL(zi, sincos[k].cos) + MUL(zr, sincos[k].sin); } @@ -142,8 +179,12 @@ { uint16_t k; +#ifdef USE_FFTW fftw_complex *Z1 = mdct->Z1; fftw_complex *Z2 = mdct->Z2; +#else + real_t *Z1 = mdct->Z1; +#endif faad_sincos *sincos = mdct->sincos; uint16_t N = mdct->N; @@ -159,25 +200,44 @@ real_t zr = X_in[N - N4 - 1 - n] + X_in[N - N4 + n]; real_t zi = X_in[ N4 + n] - X_in[ N4 - 1 - n]; +#ifdef USE_FFTW Z1[k ].re = -MUL(zr, sincos[k ].cos) - MUL(zi, sincos[k ].sin); Z1[k ].im = -MUL(zi, sincos[k ].cos) + MUL(zr, sincos[k ].sin); +#else + Z1[k*2 ] = -MUL(zr, sincos[k ].cos) - MUL(zi, sincos[k ].sin); + Z1[k*2+1 ] = -MUL(zi, sincos[k ].cos) + MUL(zr, sincos[k ].sin); +#endif zr = X_in[ N2 - 1 - n] - X_in[ n]; zi = X_in[ N2 + n] + X_in[N - 1 - n]; +#ifdef USE_FFTW Z1[k + N8].re = -MUL(zr, sincos[k + N8].cos) - MUL(zi, sincos[k + N8].sin); Z1[k + N8].im = -MUL(zi, sincos[k + N8].cos) + MUL(zr, sincos[k + N8].sin); +#else + Z1[k*2 + N8] = -MUL(zr, sincos[k + N8].cos) - MUL(zi, sincos[k + N8].sin); + Z1[k*2+1 + N8] = -MUL(zi, sincos[k + N8].cos) + MUL(zr, sincos[k + N8].sin); +#endif } /* complex FFT */ +#ifdef USE_FFTW fftw_one(mdct->plan_forward, Z1, Z2); +#else + cfftf(mdct->cfft, Z1); +#endif /* post-FFT complex multiplication */ for (k = 0; k < N4; k++) { uint16_t n = k << 1; +#ifdef USE_FFTW real_t zr = MUL(2.0, MUL(Z2[k].re, sincos[k].cos) + MUL(Z2[k].im, sincos[k].sin)); real_t zi = MUL(2.0, MUL(Z2[k].im, sincos[k].cos) - MUL(Z2[k].re, sincos[k].sin)); +#else + real_t zr = MUL(2.0, MUL(Z1[k*2], sincos[k].cos) + MUL(Z1[k*2+1], sincos[k].sin)); + real_t zi = MUL(2.0, MUL(Z1[k*2+1], sincos[k].cos) - MUL(Z1[k*2], sincos[k].sin)); +#endif X_out[ n] = -zr; X_out[N2 - 1 - n] = zi; Index: mdct.h =================================================================== RCS file: /cvsroot/xine/xine-lib/src/libfaad/mdct.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- mdct.h 14 Jul 2002 23:43:01 -0000 1.1 +++ mdct.h 9 Aug 2002 22:36:36 -0000 1.2 @@ -26,20 +26,37 @@ extern "C" { #endif +#ifdef USE_FFTW #include <fftw.h> +#else +#include "cfft.h" +#endif typedef struct { real_t sin; real_t cos; } faad_sincos; +#ifndef USE_FFTW typedef struct { + real_t re; + real_t im; +} faad_complex; +#endif + +typedef struct { + faad_sincos *sincos; +#ifdef USE_FFTW fftw_complex *Z1; fftw_complex *Z2; - faad_sincos *sincos; fftw_plan plan_backward; #ifdef LTP_DEC fftw_plan plan_forward; +#endif +#else + real_t *Z1; + faad_complex *Z2; + cfft_info cfft; #endif uint16_t N; } mdct_info; Index: mp4.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/libfaad/mp4.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- mp4.c 14 Jul 2002 23:43:01 -0000 1.1 +++ mp4.c 9 Aug 2002 22:36:36 -0000 1.2 @@ -27,70 +27,70 @@ /* defines if an object type can be decoded by this library or not */ static uint8_t ObjectTypesTable[32] = { - 0, /* NULL */ + 0, /* 0 NULL */ #ifdef MAIN_DEC - 1, /* AAC Main */ + 1, /* 1 AAC Main */ #else - 0, /* AAC Main */ + 0, /* 1 AAC Main */ #endif - 1, /* AAC LC */ - 0, /* AAC SSR */ + 1, /* 2 AAC LC */ + 0, /* 3 AAC SSR */ #ifdef LTP_DEC - 1, /* AAC LTP */ + 1, /* 4 AAC LTP */ #else - 0, /* AAC LTP */ + 0, /* 4 AAC LTP */ #endif - 0, /* Reserved */ - 0, /* AAC Scalable */ - 0, /* TwinVQ */ - 0, /* CELP */ - 0, /* HVXC */ - 0, /* Reserved */ - 0, /* Reserved */ - 0, /* TTSI */ - 0, /* Main synthetic */ - 0, /* Wavetable synthesis */ - 0, /* General MIDI */ - 0, /* Algorithmic Synthesis and Audio FX */ + 0, /* 5 Reserved */ + 0, /* 6 AAC Scalable */ + 0, /* 7 TwinVQ */ + 0, /* 8 CELP */ + 0, /* 9 HVXC */ + 0, /* 10 Reserved */ + 0, /* 11 Reserved */ + 0, /* 12 TTSI */ + 0, /* 13 Main synthetic */ + 0, /* 14 Wavetable synthesis */ + 0, /* 15 General MIDI */ + 0, /* 16 Algorithmic Synthesis and Audio FX */ /* MPEG-4 Version 2 */ #ifdef ERROR_RESILIENCE - 1, /* ER AAC LC */ - 0, /* (Reserved) */ + 1, /* 17 ER AAC LC */ + 0, /* 18 (Reserved) */ #ifdef LTP_DEC - 1, /* ER AAC LTP */ + 1, /* 19 ER AAC LTP */ #else - 0, /* ER AAC LTP */ + 0, /* 19 ER AAC LTP */ #endif - 0, /* ER AAC scalable */ - 0, /* ER TwinVQ */ - 0, /* ER BSAC */ + 0, /* 20 ER AAC scalable */ + 0, /* 21 ER TwinVQ */ + 0, /* 22 ER BSAC */ #ifdef LD_DEC - 1, /* ER AAC LD */ + 1, /* 23 ER AAC LD */ #else - 0, /* ER AAC LD */ + 0, /* 23 ER AAC LD */ #endif - 0, /* ER CELP */ - 0, /* ER HVXC */ - 0, /* ER HILN */ - 0, /* ER Parametric */ + 0, /* 24 ER CELP */ + 0, /* 25 ER HVXC */ + 0, /* 26 ER HILN */ + 0, /* 27 ER Parametric */ #else /* No ER defined */ - 0, /* ER AAC LC */ - 0, /* (Reserved) */ - 0, /* ER AAC LTP */ - 0, /* ER AAC scalable */ - 0, /* ER TwinVQ */ - 0, /* ER BSAC */ - 0, /* ER AAC LD */ - 0, /* ER CELP */ - 0, /* ER HVXC */ - 0, /* ER HILN */ - 0, /* ER Parametric */ + 0, /* 17 ER AAC LC */ + 0, /* 18 (Reserved) */ + 0, /* 19 ER AAC LTP */ + 0, /* 20 ER AAC scalable */ + 0, /* 21 ER TwinVQ */ + 0, /* 22 ER BSAC */ + 0, /* 23 ER AAC LD */ + 0, /* 24 ER CELP */ + 0, /* 25 ER HVXC */ + 0, /* 26 ER HILN */ + 0, /* 27 ER Parametric */ #endif - 0, /* (Reserved) */ - 0, /* (Reserved) */ - 0, /* (Reserved) */ - 0 /* (Reserved) */ + 0, /* 28 (Reserved) */ + 0, /* 29 (Reserved) */ + 0, /* 30 (Reserved) */ + 0 /* 31 (Reserved) */ }; /* Table 1.6.1 */ @@ -137,7 +137,7 @@ return -2; } - if(ChannelsConfiguration > 7) + if (ChannelsConfiguration > 7) { return -3; } @@ -154,7 +154,7 @@ frameLengthFlag); #ifdef ERROR_RESILIENCE } else if (ObjectTypeIndex >= ER_OBJECT_START) { /* ER */ - uint8_t result = GASpecificConfig(&ld, channels, ObjectTypeIndex, + int8_t result = GASpecificConfig(&ld, channels, ObjectTypeIndex, aacSectionDataResilienceFlag, aacScalefactorDataResilienceFlag, aacSpectralDataResilienceFlag, Index: syntax.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/libfaad/syntax.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- syntax.c 14 Jul 2002 23:43:01 -0000 1.1 +++ syntax.c 9 Aug 2002 22:36:36 -0000 1.2 @@ -40,15 +40,18 @@ #ifdef SBR #include "sbr_syntax.h" #endif +#ifdef ERROR_RESILIENCE +#include "rvlc_scale_factors.h" +#endif /* Table 4.4.1 */ -uint8_t GASpecificConfig(bitfile *ld, uint8_t *channelConfiguration, - uint8_t object_type, - uint8_t *aacSectionDataResilienceFlag, - uint8_t *aacScalefactorDataResilienceFlag, - uint8_t *aacSpectralDataResilienceFlag, - uint8_t *frameLengthFlag) +int8_t GASpecificConfig(bitfile *ld, uint8_t *channelConfiguration, + uint8_t object_type, + uint8_t *aacSectionDataResilienceFlag, + uint8_t *aacScalefactorDataResilienceFlag, + uint8_t *aacSpectralDataResilienceFlag, + uint8_t *frameLengthFlag) { uint8_t dependsOnCoreCoder, extensionFlag; uint16_t coreCoderDelay; @@ -657,12 +660,7 @@ DEBUGVAR(1,69,"individual_channel_stream(): tns_data_present"))) & 1) { #ifdef ERROR_RESILIENCE - /* TODO I don't understand this, but the "rewrite" software moves tns_data away */ - if ((object_type != ER_LC) && (object_type != ER_LTP) -#ifdef DRM - && (object_type != DRM_ER_LC) -#endif - ) + if (object_type < ER_OBJECT_START) #endif tns_data(ics, &(ics->tns), ld); } @@ -671,7 +669,7 @@ if ((ics->gain_control_data_present = faad_get1bit(ld DEBUGVAR(1,70,"individual_channel_stream(): gain_control_data_present"))) & 1) { -#if 0 +#if 1 return 1; #else gain_control_data(ld, ics); @@ -680,26 +678,8 @@ } #ifdef ERROR_RESILIENCE - if (!aacSpectralDataResilienceFlag) + if (aacSpectralDataResilienceFlag) { - /* TODO I don't understand this, but the "rewrite" software - moves tns_data before spectral_data */ - if ( (object_type == ER_LC) || (object_type == ER_LTP) -#ifdef DRM - && (object_type != DRM_ER_LC) -#endif - ) - { - if (ics->tns_data_present) - tns_data(ics, &(ics->tns), ld); - } -#endif - - /* decode the spectral data */ - if ((result = spectral_data(ics, ld, spec_data, frame_len)) > 0) - return result; -#ifdef ERROR_RESILIENCE - } else { ics->length_of_reordered_spectral_data = (uint16_t)faad_getbits(ld, 14 DEBUGVAR(1,147,"individual_channel_stream(): length_of_reordered_spectral_data")); /* TODO: test for >6144/12288, see page 143 */ @@ -707,19 +687,37 @@ DEBUGVAR(1,148,"individual_channel_stream(): length_of_longest_codeword")); if (ics->length_of_longest_codeword >= 49) ics->length_of_longest_codeword = 49; + } - /* TODO I don't understand this, but the "rewrite" software - moves tns_data before spectral_data */ + /* RVLC spectral data is put here */ + if (aacScalefactorDataResilienceFlag) + { + if ((result = rvlc_decode_scale_factors(ics, ld)) > 0) + return result; + } + if (object_type >= ER_OBJECT_START) + { if (ics->tns_data_present) tns_data(ics, &(ics->tns), ld); + } + if (aacSpectralDataResilienceFlag) + { /* error resilient spectral data decoding */ if ((result = reordered_spectral_data(ics, ld, spec_data, frame_len, aacSectionDataResilienceFlag)) > 0) { return result; } + } else { +#endif + /* decode the spectral data */ + if ((result = spectral_data(ics, ld, spec_data, frame_len)) > 0) + { + return result; + } +#ifdef ERROR_RESILIENCE } #endif @@ -729,7 +727,7 @@ if (ics->window_sequence != EIGHT_SHORT_SEQUENCE) pulse_decode(ics, spec_data); else - return 2; /* pulse coding not allowed for long blocks */ + return 2; /* pulse coding not allowed for short blocks */ } return 0; @@ -771,6 +769,9 @@ ics->sect_cb[g][i] = (uint8_t)faad_getbits(ld, sect_cb_bits DEBUGVAR(1,71,"section_data(): sect_cb")); + if (ics->sect_cb[g][i] == NOISE_HCB) + ics->noise_used = 1; + #ifdef ERROR_RESILIENCE if (!aacSectionDataResilienceFlag || (ics->sect_cb[g][i] < 11) || @@ -897,81 +898,11 @@ return decode_scale_factors(ics, ld); #ifdef ERROR_RESILIENCE } else { -#if 0 - uint32_t bits_used, length_of_rvlc_sf; - uint8_t bits = 11; - - sf_concealment = faad_get1bit(ld - DEBUGVAR(1,149,"scale_factor_data(): sf_concealment")); - rev_global_gain = faad_getbits(ld, 8 - DEBUGVAR(1,150,"scale_factor_data(): rev_global_gain")); - - if (ics->window_sequence == EIGHT_SHORT_SEQUENCE) - bits = 9; - - /* the number of bits used for the huffman codewords */ - length_of_rvlc_sf = faad_getbits(ld, bits - DEBUGVAR(1,151,"scale_factor_data(): length_of_rvlc_sf")); - - /* check how many bits are used in decoding the scalefactors - A better solution would be to read length_of_rvlc_sf ahead - in a buffer and use that to decode the scale factors - */ - bits_used = faad_get_processed_bits(ld); - decode_scale_factors(ics, ld); - bits_used = faad_get_processed_bits(ld) - bits_used; - - /* return an error if the number of decoded bits is not correct - FAAD should be able to recover from this, for example by - setting all scalefactors to 0 (e.g. muting the frame) + /* In ER AAC the parameters for RVLC are seperated from the actual + data that holds the scale_factors. + Strangely enough, 2 parameters for HCR are put inbetween them. */ - if (bits_used != length_of_rvlc_sf) - return 8; - - sf_escapes_present; 1 uimsbf - - if (sf_escapes_present) - { - length_of_rvlc_escapes; 8 uimsbf - - for (g = 0; g < num_window_groups; g++) - { - for (sfb = 0; sfb < max_sfb; sfb++) - { - if (sect_cb[g][sfb] != ZERO_HCB) - { - if (is_intensity(g, sfb) && - dpcm_is_position[g][sfb] == ESC_FLAG) - { - rvlc_esc_sf[dpcm_is_position[g][sfb]]; 2..20 vlclbf - } else { - if (is_noise(g, sfb) && - dpcm_noise_nrg[g][sfb] == ESC_FLAG) - { - rvlc_esc_sf[dpcm_noise_nrg[g][sfb]]; 2..20 vlclbf - } else { - if (dpcm_sf[g][sfb] == ESC_FLAG) - { - rvlc_esc_sf[dpcm_sf[g][sfb]]; 2..20 vlclbf - } - } - } - } - } - } - - if (intensity_used && - dpcm_is_position[g][sfb] == ESC_FLAG) - { - rvlc_esc_sf[dpcm_is_last_position]; 2..20 vlclbf - } - } - - if (noise_used) - { - dpcm_noise_last_position; 9 uimsbf - } -#endif + return rvlc_scale_factor_data(ics, ld); } #endif } Index: syntax.h =================================================================== RCS file: /cvsroot/xine/xine-lib/src/libfaad/syntax.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- syntax.h 18 Jul 2002 17:24:37 -0000 1.2 +++ syntax.h 9 Aug 2002 22:36:36 -0000 1.3 @@ -238,6 +238,8 @@ uint8_t ms_mask_present; uint8_t ms_used[MAX_WINDOW_GROUPS][MAX_SFB]; + uint8_t noise_used; + uint8_t pulse_data_present; uint8_t tns_data_present; uint8_t gain_control_data_present; @@ -250,9 +252,17 @@ ltp_info ltp2; #ifdef ERROR_RESILIENCE - /* ER data */ + /* ER HCR data */ uint16_t length_of_reordered_spectral_data; uint8_t length_of_longest_codeword; + /* ER RLVC data */ + uint8_t sf_concealment; + uint8_t rev_global_gain; + uint16_t length_of_rvlc_sf; + uint16_t dpcm_noise_nrg; + uint8_t sf_escapes_present; + uint8_t length_of_rvlc_escapes; + uint16_t dpcm_noise_last_position; #endif } ic_stream; /* individual channel stream */ @@ -271,17 +281,12 @@ } element; /* syntax element (SCE, CPE, LFE) */ -uint8_t GASpecificConfig(bitfile *ld, uint8_t *channelConfiguration, - uint8_t object_type, - uint8_t *aacSectionDataResilienceFlag, - uint8_t *aacScalefactorDataResilienceFlag, - uint8_t *aacSpectralDataResilienceFlag, - uint8_t *frameLengthFlag); -uint8_t raw_data_block(bitfile *ld, int16_t ***spec_data, real_t ***spec_coef, - element ***syntax_elements, - uint8_t *channels, uint8_t *ele, uint8_t *ch_ele, - uint16_t frame_len, uint8_t sf_index, uint8_t object_type, - drc_info *drc); +int8_t GASpecificConfig(bitfile *ld, uint8_t *channelConfiguration, + uint8_t object_type, + uint8_t *aacSectionDataResilienceFlag, + uint8_t *aacScalefactorDataResilienceFlag, + uint8_t *aacSpectralDataResilienceFlag, + uint8_t *frameLengthFlag); uint8_t single_lfe_channel_element(element *sce, bitfile *ld, int16_t *spec_data, uint8_t sf_index, uint8_t object_type, uint16_t frame_len |