shithub: aacenc

Download patch

ref: c1ac168fc988193ef135ef6f6fd7ddf3eb9b6707
parent: b4aec704d01d1f54995031f3aa071b4f62bb8a8d
author: sur <sur>
date: Wed Feb 2 02:50:35 EST 2005

Added interface to kiss_fft library to implement FFT for 960 transform length.

--- a/libfaac/fft.c
+++ b/libfaac/fft.c
@@ -1,6 +1,6 @@
 /*
  * FAAC - Freeware Advanced Audio Coder
- * $Id: fft.c,v 1.11 2004/04/02 14:56:17 danchr Exp $
+ * $Id: fft.c,v 1.12 2005/02/02 07:49:55 sur Exp $
  * Copyright (C) 2002 Krzysztof Nikiel
  *
  * This library is free software; you can redistribute it and/or
@@ -29,8 +29,448 @@
 #define MAXLOGM 9
 #define MAXLOGR 8
 
+#if defined DRM && !defined DRM_1024
+
+#include "kiss_fft/kiss_fft.h"
+#include "kiss_fft/kiss_fftr.h"
+
+static const int logm_to_nfft[] = 
+{
+/*  0       1       2       3       */
+    0,      0,      0,      0,
+/*  4       5       6       7       */
+    0,      0,      60,     0,
+/*  8       9                       */
+    240,    480
+};
+
 void fft_initialize( FFT_Tables *fft_tables )
 {
+    memset( fft_tables->cfg, 0, sizeof( fft_tables->cfg ) );
+}
+void fft_terminate( FFT_Tables *fft_tables )
+{
+    unsigned int i;
+    for ( i = 0; i < sizeof( fft_tables->cfg ) / sizeof( fft_tables->cfg[0] ); i++ )
+    {
+        if ( fft_tables->cfg[i][0] )
+        {
+            free( fft_tables->cfg[i][0] );
+            fft_tables->cfg[i][0] = NULL;
+        }
+        if ( fft_tables->cfg[i][1] )
+        {
+            free( fft_tables->cfg[i][1] );
+            fft_tables->cfg[i][1] = NULL;
+        }
+    }
+}
+
+void rfft( FFT_Tables *fft_tables, double *x, int logm )
+{
+#if 0
+/* sur: do not use real-only optimized FFT */
+    double xi[1 << MAXLOGR];
+
+    int nfft;
+
+    if ( logm > MAXLOGR )
+	{
+		fprintf(stderr, "rfft size too big\n");
+		exit(1);
+	}
+
+    nfft = logm_to_nfft[logm];
+
+    if ( nfft )
+    {
+        //unsigned int i;
+        //for ( i = 0; i < nfft; i++ )
+        //{
+        //    xi[i] = 0.0;
+        //}
+	    memset( xi, 0, nfft * sizeof( xi[0] ) );
+
+	    fft( fft_tables, x, xi, logm );
+
+	    memcpy( x + nfft / 2, xi, ( nfft / 2 ) * sizeof(x[0]) );
+    }
+    else
+    {
+        fprintf( stderr, "bad config for logm = %d\n", logm);
+        exit( 1 );
+    }
+
+#else
+/* sur: use real-only optimized FFT */
+
+    int nfft = 0;
+
+    kiss_fft_scalar fin[1 << MAXLOGR];
+    kiss_fft_cpx    fout[1 << MAXLOGR];
+
+    if ( logm > MAXLOGR )
+	{
+		fprintf(stderr, "fft size too big\n");
+		exit(1);
+	}
+
+    nfft = logm_to_nfft[logm];
+
+    if ( fft_tables->cfg[logm][0] == NULL )
+    {
+        if ( nfft )
+        {
+            fft_tables->cfg[logm][0] = kiss_fftr_alloc( nfft, 0, NULL, NULL );
+        }
+        else
+        {
+	    	fprintf(stderr, "bad logm = %d\n", logm);
+            exit( 1 );
+        }
+    }
+
+    if ( fft_tables->cfg[logm][0] )
+    {
+        unsigned int i;
+        
+        for ( i = 0; i < nfft; i++ )
+        {
+            fin[i] = x[i];    
+        }
+        
+        kiss_fftr( (kiss_fftr_cfg)fft_tables->cfg[logm][0], fin, fout );
+
+        for ( i = 0; i < nfft / 2; i++ )
+        {
+            x[i]            = fout[i].r;
+            x[i + nfft / 2] = fout[i].i;
+        }
+    }
+    else
+    {
+        fprintf( stderr, "bad config for logm = %d\n", logm);
+        exit( 1 );
+    }
+#endif
+}
+
+void fft( FFT_Tables *fft_tables, double *xr, double *xi, int logm )
+{
+    int nfft = 0;
+
+    kiss_fft_cpx    fin[1 << MAXLOGM];
+    kiss_fft_cpx    fout[1 << MAXLOGM];
+
+    if ( logm > MAXLOGM )
+	{
+		fprintf(stderr, "fft size too big\n");
+		exit(1);
+	}
+
+    nfft = logm_to_nfft[logm];
+
+    if ( fft_tables->cfg[logm][0] == NULL )
+    {
+        if ( nfft )
+        {
+            fft_tables->cfg[logm][0] = kiss_fft_alloc( nfft, 0, NULL, NULL );
+        }
+        else
+        {
+	    	fprintf(stderr, "bad logm = %d\n", logm);
+            exit( 1 );
+        }
+    }
+
+    if ( fft_tables->cfg[logm][0] )
+    {
+        unsigned int i;
+        
+        for ( i = 0; i < nfft; i++ )
+        {
+            fin[i].r = xr[i];    
+            fin[i].i = xi[i];
+        }
+        
+        kiss_fft( (kiss_fft_cfg)fft_tables->cfg[logm][0], fin, fout );
+
+        for ( i = 0; i < nfft; i++ )
+        {
+            xr[i]   = fout[i].r;
+            xi[i]   = fout[i].i;
+        }
+    }
+    else
+    {
+        fprintf( stderr, "bad config for logm = %d\n", logm);
+        exit( 1 );
+    }
+}
+
+void ffti( FFT_Tables *fft_tables, double *xr, double *xi, int logm )
+{
+    int nfft = 0;
+
+    kiss_fft_cpx    fin[1 << MAXLOGM];
+    kiss_fft_cpx    fout[1 << MAXLOGM];
+
+    if ( logm > MAXLOGM )
+	{
+		fprintf(stderr, "fft size too big\n");
+		exit(1);
+	}
+
+    nfft = logm_to_nfft[logm];
+
+    if ( fft_tables->cfg[logm][1] == NULL )
+    {
+        if ( nfft )
+        {
+            fft_tables->cfg[logm][1] = kiss_fft_alloc( nfft, 1, NULL, NULL );
+        }
+        else
+        {
+	    	fprintf(stderr, "bad logm = %d\n", logm);
+            exit( 1 );
+        }
+    }
+    
+    if ( fft_tables->cfg[logm][1] )
+    {
+        unsigned int i;
+        double fac = 1.0 / (double)nfft;
+        
+        for ( i = 0; i < nfft; i++ )
+        {
+            fin[i].r = xr[i];    
+            fin[i].i = xi[i];
+        }
+        
+        kiss_fft( (kiss_fft_cfg)fft_tables->cfg[logm][1], fin, fout );
+
+        for ( i = 0; i < nfft; i++ )
+        {
+            xr[i]   = fout[i].r * fac;
+            xi[i]   = fout[i].i * fac;
+        }
+    }
+    else
+    {
+        fprintf( stderr, "bad config for logm = %d\n", logm);
+        exit( 1 );
+    }
+}
+
+/* sur: Trying to use cfft from libfaad2 -- it does not work 'from scratch' */
+//
+//#include "cfft/common.h"
+//
+//void fft_initialize( FFT_Tables *fft_tables )
+//{
+//    memset( fft_tables->cfft, 0, sizeof( fft_tables->cfft ) );
+//}
+//void fft_terminate( FFT_Tables *fft_tables )
+//{
+//    unsigned int i;
+//    for ( i = 0; i < sizeof( fft_tables->cfft ) / sizeof( fft_tables->cfft[0] ); i++ )
+//    {
+//        if ( fft_tables->cfft[i] )
+//        {
+//            cfftu( fft_tables->cfft[i] );
+//            fft_tables->cfft[i] = NULL;
+//        }
+//    }
+//}
+//
+//void rfft( FFT_Tables *fft_tables, double *x, int logm )
+//{
+//	double xi[1 << MAXLOGR];
+//
+//    int nfft;
+//
+//    if ( logm > MAXLOGR )
+//	{
+//		fprintf(stderr, "rfft size too big\n");
+//		exit(1);
+//	}
+//
+//    nfft = logm_to_nfft[logm];
+//
+//    if ( nfft )
+//    {
+//        unsigned int i;
+//
+//        for ( i = 0; i < nfft; i++ )
+//        {
+//            xi[i] = 0.0;
+//        }
+//	    //memset( xi, 0, nfft * sizeof( xi[0] ) );
+//
+//	    fft( fft_tables, x, xi, logm );
+//
+//	    memcpy( x + nfft / 2, xi, ( nfft / 2 ) * sizeof(x[0]) );
+//
+//#ifdef SUR_DEBUG_FFT
+//        {
+//            FILE* f = fopen( "fft.log", "at" );
+//            
+//            fprintf( f, "RFFT(%d)\n", nfft );
+//            
+//            for ( i = 0; i < nfft; i++ )
+//            {
+//                fprintf( f, ";%d;%g;%g\n", i, x[i], xi[i] );
+//            }
+//
+//            fclose( f );
+//        }
+//#endif
+//    }
+//    else
+//    {
+//        fprintf( stderr, "bad config for logm = %d\n", logm);
+//        exit( 1 );
+//    }
+//}
+//
+//void fft( FFT_Tables *fft_tables, double *xr, double *xi, int logm )
+//{
+//    int nfft;
+//
+//    complex_t c[1 << MAXLOGM];
+//
+//    if ( logm > MAXLOGM )
+//	{
+//		fprintf(stderr, "fft size too big\n");
+//		exit(1);
+//	}
+//
+//    nfft = logm_to_nfft[logm];
+//
+//    if ( fft_tables->cfft[logm] == NULL )
+//    {
+//        if ( nfft )
+//        {
+//            fft_tables->cfft[logm] = cffti( nfft );
+//        }
+//        else
+//        {
+//	    	fprintf(stderr, "bad logm = %d\n", logm);
+//            exit( 1 );
+//        }
+//    }
+//
+//    if ( fft_tables->cfft[logm] )
+//    {
+//        unsigned int i;
+//        
+//        for ( i = 0; i < nfft; i++ )
+//        {
+//            RE( c[i] ) = xr[i];    
+//            IM( c[i] ) = xi[i];
+//        }
+//        
+//        cfftf( fft_tables->cfft[logm], c );
+//
+//        for ( i = 0; i < nfft; i++ )
+//        {
+//            xr[i]   = RE( c[i] );
+//            xi[i]   = IM( c[i] );
+//        }
+//
+//#ifdef SUR_DEBUG_FFT
+//        {
+//            FILE* f = fopen( "fft.log", "at" );
+//            
+//            fprintf( f, "FFT(%d)\n", nfft );
+//            
+//            for ( i = 0; i < nfft; i++ )
+//            {
+//                fprintf( f, ";%d;%g;%g\n", i, xr[i], xi[i] );
+//            }
+//
+//            fclose( f );
+//        }
+//#endif
+//    }
+//    else
+//    {
+//        fprintf( stderr, "bad config for logm = %d\n", logm);
+//        exit( 1 );
+//    }
+//}
+//
+//void ffti( FFT_Tables *fft_tables, double *xr, double *xi, int logm )
+//{
+//    int nfft;
+//
+//    complex_t c[1 << MAXLOGM];
+//
+//    if ( logm > MAXLOGM )
+//	{
+//		fprintf(stderr, "fft size too big\n");
+//		exit(1);
+//	}
+//
+//    nfft = logm_to_nfft[logm];
+//
+//    if ( fft_tables->cfft[logm] == NULL )
+//    {
+//        if ( nfft )
+//        {
+//            fft_tables->cfft[logm] = cffti( nfft );
+//        }
+//        else
+//        {
+//	    	fprintf(stderr, "bad logm = %d\n", logm);
+//            exit( 1 );
+//        }
+//    }
+//    
+//    if ( fft_tables->cfft[logm] )
+//    {
+//        unsigned int i;
+//        
+//        for ( i = 0; i < nfft; i++ )
+//        {
+//            RE( c[i] )  = xr[i];    
+//            IM( c[i] )  = xi[i];
+//        }
+//        
+//        cfftb( fft_tables->cfft[logm], c );
+//
+//        for ( i = 0; i < nfft; i++ )
+//        {
+//            xr[i]   = RE( c[i] );
+//            xi[i]   = IM( c[i] );
+//        }
+//
+//#ifdef SUR_DEBUG_FFT
+//        {
+//            FILE* f = fopen( "fft.log", "at" );
+//            
+//            fprintf( f, "FFTI(%d)\n", nfft );
+//            
+//            for ( i = 0; i < nfft; i++ )
+//            {
+//                fprintf( f, ";%d;%g;%g\n", i, xr[i], xi[i] );
+//            }
+//
+//            fclose( f );
+//        }
+//#endif
+//    }
+//    else
+//    {
+//        fprintf( stderr, "bad config for logm = %d\n", logm);
+//        exit( 1 );
+//    }
+//}
+
+#else /* !defined DRM || defined DRM_1024 */
+
+void fft_initialize( FFT_Tables *fft_tables )
+{
 	int i;
 	fft_tables->costbl		= AllocMemory( (MAXLOGM+1) * sizeof( fft_tables->costbl[0] ) );
 	fft_tables->negsintbl	= AllocMemory( (MAXLOGM+1) * sizeof( fft_tables->negsintbl[0] ) );
@@ -236,8 +676,13 @@
 	}
 }
 
+#endif /* defined DRM && !defined DRM_1024 */
+
 /*
 $Log: fft.c,v $
+Revision 1.12  2005/02/02 07:49:55  sur
+Added interface to kiss_fft library to implement FFT for 960 transform length.
+
 Revision 1.11  2004/04/02 14:56:17  danchr
 fix name clash w/ libavcodec: fft_init -> fft_initialize
 bump version number to 1.24 beta
--- a/libfaac/fft.h
+++ b/libfaac/fft.h
@@ -1,6 +1,6 @@
 /*
  * FAAC - Freeware Advanced Audio Coder
- * $Id: fft.h,v 1.5 2004/04/02 14:56:17 danchr Exp $
+ * $Id: fft.h,v 1.6 2005/02/02 07:50:35 sur Exp $
  * Copyright (C) 2002 Krzysztof Nikiel
  *
  * This library is free software; you can redistribute it and/or
@@ -24,12 +24,26 @@
 
 typedef float fftfloat;
 
+#if defined DRM && !defined DRM_1024
+
+#define MAX_FFT 10
+
 typedef struct
 {
+    /*      cfg[Max FFT][FFT and inverse FFT] */
+    void*   cfg[MAX_FFT][2];
+} FFT_Tables;
+
+#else  /* use own FFT */
+
+typedef struct
+{
     fftfloat **costbl;
     fftfloat **negsintbl;
     unsigned short **reordertbl;
 } FFT_Tables;
+
+#endif /* defined DRM && !defined DRM_1024 */
 
 void fft_initialize		( FFT_Tables *fft_tables );
 void fft_terminate	( FFT_Tables *fft_tables );