예제 #1
0
    // create an instance of the decoder
    //  blocksize is fixed over the lifetime of this object for performance reasons
    decoder_impl(unsigned blocksize=8192): N(blocksize), halfN(blocksize/2) {
#ifdef USE_FFTW3
        // create FFTW buffers
        lt = (float*)fftwf_malloc(sizeof(float)*N);
        rt = (float*)fftwf_malloc(sizeof(float)*N);
        dst = (float*)fftwf_malloc(sizeof(float)*N);
        dftL = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex)*N);
        dftR = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex)*N);
        src = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex)*N);
        loadL = fftwf_plan_dft_r2c_1d(N, lt, dftL,FFTW_MEASURE);
        loadR = fftwf_plan_dft_r2c_1d(N, rt, dftR,FFTW_MEASURE);
        store = fftwf_plan_dft_c2r_1d(N, src, dst,FFTW_MEASURE);    
#else
        // create lavc fft buffers
        lt = (float*)av_malloc(sizeof(FFTSample)*N);
        rt = (float*)av_malloc(sizeof(FFTSample)*N);
        dftL = (FFTComplexArray*)av_malloc(sizeof(FFTComplex)*N*2);
        dftR = (FFTComplexArray*)av_malloc(sizeof(FFTComplex)*N*2);
        src = (FFTComplexArray*)av_malloc(sizeof(FFTComplex)*N*2);
        fftContextForward = (FFTContext*)av_malloc(sizeof(FFTContext));
        memset(fftContextForward, 0, sizeof(FFTContext));
        fftContextReverse = (FFTContext*)av_malloc(sizeof(FFTContext));
        memset(fftContextReverse, 0, sizeof(FFTContext));
        ff_fft_init(fftContextForward, 13, 0);
        ff_fft_init(fftContextReverse, 13, 1);
#endif
        // resize our own buffers
        frontR.resize(N);
        frontL.resize(N);
        avg.resize(N);
        surR.resize(N);
        surL.resize(N);
        trueavg.resize(N);
        xfs.resize(N);
        yfs.resize(N);
        inbuf[0].resize(N);
        inbuf[1].resize(N);
        for (unsigned c=0;c<6;c++) {
            outbuf[c].resize(N);
            filter[c].resize(N);
        }
        sample_rate(48000);
        // generate the window function (square root of hann, b/c it is applied before and after the transform)
        wnd.resize(N);
        for (unsigned k=0;k<N;k++)
            wnd[k] = sqrt(0.5*(1-cos(2*PI*k/N))/N);
        current_buf = 0;
        memset(inbufs, 0, sizeof(inbufs));
        memset(outbufs, 0, sizeof(outbufs));
        // set the default coefficients
        surround_coefficients(0.8165,0.5774);
        phase_mode(0);
        separation(1,1);
        steering_mode(true);
    }
예제 #2
0
/**
 * init MDCT or IMDCT computation.
 */
int ff_mdct_init(MDCTContext *s, int nbits, int inverse)
{
    int n, n4, i;
    double alpha;

    memset(s, 0, sizeof(*s));
    n = 1 << nbits;
    s->nbits = nbits;
    s->n = n;
    n4 = n >> 2;
    s->tcos = av_malloc(n4 * sizeof(FFTSample));
    if (!s->tcos)
        goto fail;
    s->tsin = av_malloc(n4 * sizeof(FFTSample));
    if (!s->tsin)
        goto fail;

    for(i=0;i<n4;i++) {
        alpha = 2 * M_PI * (i + 1.0 / 8.0) / n;
        s->tcos[i] = -cos(alpha);
        s->tsin[i] = -sin(alpha);
    }
    if (ff_fft_init(&s->fft, s->nbits - 2, inverse) < 0)
        goto fail;
    return 0;
 fail:
    av_freep(&s->tcos);
    av_freep(&s->tsin);
    return -1;
}
예제 #3
0
static int init_cook_mlt(COOKContext *q) {
    int j;
    float alpha;

    /* Allocate the buffers, could be replaced with a static [512]
       array if needed. */
    q->mlt_size = q->samples_per_channel;
    q->mlt_window = av_malloc(sizeof(float)*q->mlt_size);
    q->mlt_precos = av_malloc(sizeof(float)*q->mlt_size/2);
    q->mlt_presin = av_malloc(sizeof(float)*q->mlt_size/2);
    q->mlt_postcos = av_malloc(sizeof(float)*q->mlt_size/2);

    /* Initialize the MLT window: simple sine window. */
    alpha = M_PI / (2.0 * (float)q->mlt_size);
    for(j=0 ; j<q->mlt_size ; j++) {
        q->mlt_window[j] = sin((j + 512.0/(float)q->mlt_size) * alpha);
    }

    /* pre/post twiddle factors */
    for (j=0 ; j<q->mlt_size/2 ; j++){
        q->mlt_precos[j] = cos( ((j+0.25)*M_PI)/q->mlt_size);
        q->mlt_presin[j] = sin( ((j+0.25)*M_PI)/q->mlt_size);
        q->mlt_postcos[j] = (float)sqrt(2.0/(float)q->mlt_size)*cos( ((float)j*M_PI) /q->mlt_size); //sqrt(2/MLT_size) = scalefactor
    }

    /* Initialize the FFT. */
    ff_fft_init(&q->fft_ctx, av_log2(q->mlt_size)-1, 0);
    av_log(NULL,AV_LOG_DEBUG,"FFT initialized, order = %d.\n",
           av_log2(q->samples_per_channel)-1);

    return (int)(q->mlt_window && q->mlt_precos && q->mlt_presin && q->mlt_postcos);
}
예제 #4
0
파일: imc.c 프로젝트: Yelinson/OpenVideoHub
static av_cold int imc_decode_init(AVCodecContext * avctx)
{
    int i, j;
    IMCContext *q = avctx->priv_data;
    double r1, r2;

    q->decoder_reset = 1;

    for(i = 0; i < BANDS; i++)
        q->old_floor[i] = 1.0;

    /* Build mdct window, a simple sine window normalized with sqrt(2) */
    ff_sine_window_init(q->mdct_sine_window, COEFFS);
    for(i = 0; i < COEFFS; i++)
        q->mdct_sine_window[i] *= sqrt(2.0);
    for(i = 0; i < COEFFS/2; i++){
        q->post_cos[i] = cos(i / 256.0 * M_PI);
        q->post_sin[i] = sin(i / 256.0 * M_PI);

        r1 = sin((i * 4.0 + 1.0) / 1024.0 * M_PI);
        r2 = cos((i * 4.0 + 1.0) / 1024.0 * M_PI);

        if (i & 0x1)
        {
            q->pre_coef1[i] =  (r1 + r2) * sqrt(2.0);
            q->pre_coef2[i] = -(r1 - r2) * sqrt(2.0);
        }
        else
        {
            q->pre_coef1[i] = -(r1 + r2) * sqrt(2.0);
            q->pre_coef2[i] =  (r1 - r2) * sqrt(2.0);
        }

        q->last_fft_im[i] = 0;
    }

    /* Generate a square root table */

    for(i = 0; i < 30; i++) {
        q->sqrt_tab[i] = sqrt(i);
    }

    /* initialize the VLC tables */
    for(i = 0; i < 4 ; i++) {
        for(j = 0; j < 4; j++) {
            huffman_vlc[i][j].table = vlc_tables[vlc_offsets[i * 4 + j]];
            huffman_vlc[i][j].table_allocated = vlc_offsets[i * 4 + j + 1] - vlc_offsets[i * 4 + j];
            init_vlc(&huffman_vlc[i][j], 9, imc_huffman_sizes[i],
                     imc_huffman_lens[i][j], 1, 1,
                     imc_huffman_bits[i][j], 2, 2, INIT_VLC_USE_NEW_STATIC);
        }
    }
    q->one_div_log2 = 1/log(2);

    ff_fft_init(&q->fft, 7, 1);
    dsputil_init(&q->dsp, avctx);
    avctx->sample_fmt = SAMPLE_FMT_S16;
    return 0;
}
예제 #5
0
파일: fft.c 프로젝트: 411697643/FFmpeg
static inline void fft_init(FFTContext **s, int nbits, int inverse)
{
#if AVFFT
    *s = av_fft_init(nbits, inverse);
#else
    ff_fft_init(*s, nbits, inverse);
#endif
}
예제 #6
0
파일: avfft.c 프로젝트: 0day-ci/FFmpeg
FFTContext *av_fft_init(int nbits, int inverse)
{
    FFTContext *s = av_mallocz(sizeof(*s));

    if (s && ff_fft_init(s, nbits, inverse))
        av_freep(&s);

    return s;
}
예제 #7
0
파일: avfft.c 프로젝트: Fluffiest/splayer
FFTContext *av_fft_init(int nbits, int inverse)
{
    FFTContext *s = av_malloc(sizeof(*s));

    if (s)
        ff_fft_init(s, nbits, inverse);

    return s;
}
예제 #8
0
파일: imc.c 프로젝트: andryblack/ketlaer
static int imc_decode_init(AVCodecContext * avctx)
{
    int i, j;
    IMCContext *q = avctx->priv_data;
    double r1, r2;

    q->decoder_reset = 1;

    for(i = 0; i < BANDS; i++)
        q->old_floor[i] = 1.0;

    /* Build mdct window, a simple sine window normalized with sqrt(2) */
    for(i = 0; i < COEFFS; i++)
        q->mdct_sine_window[i] = sin((i + 0.5) / 512.0 * M_PI) * sqrt(2.0);
    for(i = 0; i < COEFFS/2; i++){
        q->post_cos[i] = cos(i / 256.0 * M_PI);
        q->post_sin[i] = sin(i / 256.0 * M_PI);

        r1 = sin((i * 4.0 + 1.0) / 1024.0 * M_PI);
        r2 = cos((i * 4.0 + 1.0) / 1024.0 * M_PI);

        if (i & 0x1)
        {
            q->pre_coef1[i] =  (r1 + r2) * sqrt(2.0);
            q->pre_coef2[i] = -(r1 - r2) * sqrt(2.0);
        }
        else
        {
            q->pre_coef1[i] = -(r1 + r2) * sqrt(2.0);
            q->pre_coef2[i] =  (r1 - r2) * sqrt(2.0);
        }

        q->last_fft_im[i] = 0;
    }

    /* Generate a square root table */

    for(i = 0; i < 30; i++) {
        q->sqrt_tab[i] = sqrt(i);
    }

    /* initialize the VLC tables */
    for(i = 0; i < 4 ; i++) {
        for(j = 0; j < 4; j++) {
            init_vlc (&q->huffman_vlc[i][j], 9, imc_huffman_sizes[i],
                     imc_huffman_lens[i][j], 1, 1,
                     imc_huffman_bits[i][j], 2, 2, 1);
        }
    }
    q->one_div_log2 = 1/log(2);

    ff_fft_init(&q->fft, 7, 1);
    dsputil_init(&q->dsp, avctx);
    return 0;
}
예제 #9
0
파일: avfft.c 프로젝트: Erdk/RBDOOM-3-BFG
FFTContext *av_fft_init(int nbits, int inverse)
{
    FFTContext *s = (FFTContext*)malloc(sizeof(*s));

    if (s && ff_fft_init(s, nbits, inverse)) {
        free(s);
        s = 0;
    }

    return s;
}
예제 #10
0
int main (void)
{
#define PRECISION       16
#define FFT_SIZE 1024
#define ftofix32(x)       ((fixed32)((x) * (float)(1 << PRECISION) + ((x) < 0 ? -0.5 : 0.5)))
#define itofix32(x)       ((x) << PRECISION)
#define fixtoi32(x)       ((x) >> PRECISION)

    int             j;
    const long      N = FFT_SIZE;
    double          r[FFT_SIZE] = {0.0}, i[FFT_SIZE] = {0.0};
    long            n;
    double          t;
    double          amp, phase;
    clock_t         start, end;
    double          exec_time = 0;
    FFTContext      s;
    FFTComplex      z[FFT_SIZE];
    memset(z, 0, 64*sizeof(FFTComplex));

    /* Generate saw-tooth test data */
    for (n = 0; n < FFT_SIZE; n++)
    {
        t = (2 * M_PI * n)/N;
        /*z[n].re =  1.1      + sin(      t) +                
                   0.5      * sin(2.0 * t) +
                  (1.0/3.0) * sin(3.0 * t) +
                   0.25     * sin(4.0 * t) +
                   0.2      * sin(5.0 * t) +
                  (1.0/6.0) * sin(6.0 * t) +
                  (1.0/7.0) * sin(7.0 * t) ;*/
        z[n].re  =  ftofix32(cos(2*M_PI*n/64));
        //printf("z[%d] = %f\n", n, z[n].re);
        //getchar();
    }

    ff_fft_init(&s, 10, 1);
//start = clock();
//for(n = 0; n < 1000000; n++)
    ff_fft_permute_c(&s, z);
    ff_fft_calc_c(&s, z);
//end   = clock();
//exec_time = (((double)end-(double)start)/CLOCKS_PER_SEC);
    for(j = 0; j < FFT_SIZE; j++)
    {
        printf("%8.4f\n", sqrt(pow(fixtof32(z[j].re),2)+ pow(fixtof32(z[j].im), 2)));	
        //getchar();
    }
    printf("muls = %d, adds = %d\n", muls, adds);
//printf(" Time elapsed = %f\n", exec_time);
    //ff_fft_end(&s);

}
예제 #11
0
/**
 * init MDCT or IMDCT computation.
 */
av_cold int ff_mdct_init(FFTContext *s, int nbits, int inverse, double scale)
{
    int n, n4, i;
    double alpha, theta;
    int tstep;

    memset(s, 0, sizeof(*s));
    n = 1 << nbits;
    s->mdct_bits = nbits;
    s->mdct_size = n;
    n4 = n >> 2;
    s->mdct_permutation = FF_MDCT_PERM_NONE;

    if (ff_fft_init(s, s->mdct_bits - 2, inverse) < 0)
        goto fail;

    s->tcos = av_malloc_array(n/2, sizeof(FFTSample));
    if (!s->tcos)
        goto fail;

    switch (s->mdct_permutation) {
    case FF_MDCT_PERM_NONE:
        s->tsin = s->tcos + n4;
        tstep = 1;
        break;
    case FF_MDCT_PERM_INTERLEAVE:
        s->tsin = s->tcos + 1;
        tstep = 2;
        break;
    default:
        goto fail;
    }

    theta = 1.0 / 8.0 + (scale < 0 ? n4 : 0);
    scale = sqrt(fabs(scale));
    for(i=0;i<n4;i++) {
        alpha = 2 * M_PI * (i + theta) / n;
#if FFT_FIXED_32
        s->tcos[i*tstep] = lrint(-cos(alpha) * 2147483648.0);
        s->tsin[i*tstep] = lrint(-sin(alpha) * 2147483648.0);
#else
        s->tcos[i*tstep] = FIX15(-cos(alpha) * scale);
        s->tsin[i*tstep] = FIX15(-sin(alpha) * scale);
#endif
    }
    return 0;
 fail:
    ff_mdct_end(s);
    return -1;
}
예제 #12
0
파일: dct.cpp 프로젝트: AlanWasTaken/gemrb
av_cold int ff_dct_init(DCTContext *s, int nbits, int inverse)
{
    int n = 1 << nbits;

    s->nbits    = nbits;
    s->inverse  = inverse;

    s->data = (struct FFTComplex *) av_malloc(sizeof(FFTComplex) * 2 * n);
    if (!s->data)
        return -1;

    if (ff_fft_init(&s->fft, nbits+1, inverse) < 0)
        return -1;

    return 0;
}
예제 #13
0
int main(int argc, char **argv)
{
    FFTComplex *tab, *tab1, *tab_ref;
    FFTSample *tab2;
    int it, i, c;
    int do_speed = 0;
    int do_mdct = 0;
    int do_inverse = 0;
    FFTContext s1, *s = &s1;
    MDCTContext m1, *m = &m1;
    int fft_nbits, fft_size;

    fft_nbits = 9;
    for(;;) {
        c = getopt(argc, argv, "hsimn:");
        if (c == -1)
            break;
        switch(c) {
        case 'h':
            help();
            break;
        case 's':
            do_speed = 1;
            break;
        case 'i':
            do_inverse = 1;
            break;
        case 'm':
            do_mdct = 1;
            break;
        case 'n':
            fft_nbits = atoi(optarg);
            break;
        }
    }

    fft_size = 1 << fft_nbits;
    tab = av_malloc(fft_size * sizeof(FFTComplex));
    tab1 = av_malloc(fft_size * sizeof(FFTComplex));
    tab_ref = av_malloc(fft_size * sizeof(FFTComplex));
    tab2 = av_malloc(fft_size * sizeof(FFTSample));

    if (do_mdct) {
        if (do_inverse)
            av_log(NULL, AV_LOG_INFO,"IMDCT");
        else
            av_log(NULL, AV_LOG_INFO,"MDCT");
        ff_mdct_init(m, fft_nbits, do_inverse);
    } else {
        if (do_inverse)
            av_log(NULL, AV_LOG_INFO,"IFFT");
        else
            av_log(NULL, AV_LOG_INFO,"FFT");
        ff_fft_init(s, fft_nbits, do_inverse);
        fft_ref_init(fft_nbits, do_inverse);
    }
    av_log(NULL, AV_LOG_INFO," %d test\n", fft_size);

    /* generate random data */

    for(i=0;i<fft_size;i++) {
        tab1[i].re = frandom();
        tab1[i].im = frandom();
    }

    /* checking result */
    av_log(NULL, AV_LOG_INFO,"Checking...\n");

    if (do_mdct) {
        if (do_inverse) {
            imdct_ref((float *)tab_ref, (float *)tab1, fft_nbits);
            ff_imdct_calc(m, tab2, (float *)tab1);
            check_diff((float *)tab_ref, tab2, fft_size);
        } else {
            mdct_ref((float *)tab_ref, (float *)tab1, fft_nbits);

            ff_mdct_calc(m, tab2, (float *)tab1);

            check_diff((float *)tab_ref, tab2, fft_size / 2);
        }
    } else {
        memcpy(tab, tab1, fft_size * sizeof(FFTComplex));
        ff_fft_permute(s, tab);
        ff_fft_calc(s, tab);

        fft_ref(tab_ref, tab1, fft_nbits);
        check_diff((float *)tab_ref, (float *)tab, fft_size * 2);
    }

    /* do a speed test */

    if (do_speed) {
        int64_t time_start, duration;
        int nb_its;

        av_log(NULL, AV_LOG_INFO,"Speed test...\n");
        /* we measure during about 1 seconds */
        nb_its = 1;
        for(;;) {
            time_start = gettime();
            for(it=0;it<nb_its;it++) {
                if (do_mdct) {
                    if (do_inverse) {
                        ff_imdct_calc(m, (float *)tab, (float *)tab1);
                    } else {
                        ff_mdct_calc(m, (float *)tab, (float *)tab1);
                    }
                } else {
                    memcpy(tab, tab1, fft_size * sizeof(FFTComplex));
                    ff_fft_calc(s, tab);
                }
            }
            duration = gettime() - time_start;
            if (duration >= 1000000)
                break;
            nb_its *= 2;
        }
        av_log(NULL, AV_LOG_INFO,"time: %0.1f us/transform [total time=%0.2f s its=%d]\n",
               (double)duration / nb_its,
               (double)duration / 1000000.0,
               nb_its);
    }

    if (do_mdct) {
        ff_mdct_end(m);
    } else {
        ff_fft_end(s);
    }
    return 0;
}
예제 #14
0
int main(int argc, char **argv)
{
    FFTComplex *tab, *tab1, *tab_ref;
    FFTSample *tab2;
    int it, i, c;
    int do_speed = 0;
    int err = 1;
    enum tf_transform transform = TRANSFORM_FFT;
    int do_inverse = 0;
    FFTContext s1, *s = &s1;
    FFTContext m1, *m = &m1;
    RDFTContext r1, *r = &r1;
    DCTContext d1, *d = &d1;
    int fft_nbits, fft_size, fft_size_2;
    double scale = 1.0;
    AVLFG prng;
    av_lfg_init(&prng, 1);

    fft_nbits = 9;
    for(;;) {
        c = getopt(argc, argv, "hsimrdn:f:");
        if (c == -1)
            break;
        switch(c) {
        case 'h':
            help();
            break;
        case 's':
            do_speed = 1;
            break;
        case 'i':
            do_inverse = 1;
            break;
        case 'm':
            transform = TRANSFORM_MDCT;
            break;
        case 'r':
            transform = TRANSFORM_RDFT;
            break;
        case 'd':
            transform = TRANSFORM_DCT;
            break;
        case 'n':
            fft_nbits = atoi(optarg);
            break;
        case 'f':
            scale = atof(optarg);
            break;
        }
    }

    fft_size = 1 << fft_nbits;
    fft_size_2 = fft_size >> 1;
    tab = av_malloc(fft_size * sizeof(FFTComplex));
    tab1 = av_malloc(fft_size * sizeof(FFTComplex));
    tab_ref = av_malloc(fft_size * sizeof(FFTComplex));
    tab2 = av_malloc(fft_size * sizeof(FFTSample));

    switch (transform) {
    case TRANSFORM_MDCT:
        av_log(NULL, AV_LOG_INFO,"Scale factor is set to %f\n", scale);
        if (do_inverse)
            av_log(NULL, AV_LOG_INFO,"IMDCT");
        else
            av_log(NULL, AV_LOG_INFO,"MDCT");
        ff_mdct_init(m, fft_nbits, do_inverse, scale);
        break;
    case TRANSFORM_FFT:
        if (do_inverse)
            av_log(NULL, AV_LOG_INFO,"IFFT");
        else
            av_log(NULL, AV_LOG_INFO,"FFT");
        ff_fft_init(s, fft_nbits, do_inverse);
        fft_ref_init(fft_nbits, do_inverse);
        break;
    case TRANSFORM_RDFT:
        if (do_inverse)
            av_log(NULL, AV_LOG_INFO,"IDFT_C2R");
        else
            av_log(NULL, AV_LOG_INFO,"DFT_R2C");
        ff_rdft_init(r, fft_nbits, do_inverse ? IDFT_C2R : DFT_R2C);
        fft_ref_init(fft_nbits, do_inverse);
        break;
    case TRANSFORM_DCT:
        if (do_inverse)
            av_log(NULL, AV_LOG_INFO,"DCT_III");
        else
            av_log(NULL, AV_LOG_INFO,"DCT_II");
        ff_dct_init(d, fft_nbits, do_inverse ? DCT_III : DCT_II);
        break;
    }
    av_log(NULL, AV_LOG_INFO," %d test\n", fft_size);

    /* generate random data */

    for (i = 0; i < fft_size; i++) {
        tab1[i].re = frandom(&prng);
        tab1[i].im = frandom(&prng);
    }

    /* checking result */
    av_log(NULL, AV_LOG_INFO,"Checking...\n");

    switch (transform) {
    case TRANSFORM_MDCT:
        if (do_inverse) {
            imdct_ref((float *)tab_ref, (float *)tab1, fft_nbits);
            ff_imdct_calc(m, tab2, (float *)tab1);
            err = check_diff((float *)tab_ref, tab2, fft_size, scale);
        } else {
            mdct_ref((float *)tab_ref, (float *)tab1, fft_nbits);

            ff_mdct_calc(m, tab2, (float *)tab1);

            err = check_diff((float *)tab_ref, tab2, fft_size / 2, scale);
        }
        break;
    case TRANSFORM_FFT:
        memcpy(tab, tab1, fft_size * sizeof(FFTComplex));
        ff_fft_permute(s, tab);
        ff_fft_calc(s, tab);

        fft_ref(tab_ref, tab1, fft_nbits);
        err = check_diff((float *)tab_ref, (float *)tab, fft_size * 2, 1.0);
        break;
    case TRANSFORM_RDFT:
        if (do_inverse) {
            tab1[         0].im = 0;
            tab1[fft_size_2].im = 0;
            for (i = 1; i < fft_size_2; i++) {
                tab1[fft_size_2+i].re =  tab1[fft_size_2-i].re;
                tab1[fft_size_2+i].im = -tab1[fft_size_2-i].im;
            }

            memcpy(tab2, tab1, fft_size * sizeof(FFTSample));
            tab2[1] = tab1[fft_size_2].re;

            ff_rdft_calc(r, tab2);
            fft_ref(tab_ref, tab1, fft_nbits);
            for (i = 0; i < fft_size; i++) {
                tab[i].re = tab2[i];
                tab[i].im = 0;
            }
            err = check_diff((float *)tab_ref, (float *)tab, fft_size * 2, 0.5);
        } else {
            for (i = 0; i < fft_size; i++) {
                tab2[i]    = tab1[i].re;
                tab1[i].im = 0;
            }
            ff_rdft_calc(r, tab2);
            fft_ref(tab_ref, tab1, fft_nbits);
            tab_ref[0].im = tab_ref[fft_size_2].re;
            err = check_diff((float *)tab_ref, (float *)tab2, fft_size, 1.0);
        }
        break;
    case TRANSFORM_DCT:
        memcpy(tab, tab1, fft_size * sizeof(FFTComplex));
        ff_dct_calc(d, tab);
        if (do_inverse) {
            idct_ref(tab_ref, tab1, fft_nbits);
        } else {
            dct_ref(tab_ref, tab1, fft_nbits);
        }
        err = check_diff((float *)tab_ref, (float *)tab, fft_size, 1.0);
        break;
    }

    /* do a speed test */

    if (do_speed) {
        int64_t time_start, duration;
        int nb_its;

        av_log(NULL, AV_LOG_INFO,"Speed test...\n");
        /* we measure during about 1 seconds */
        nb_its = 1;
        for(;;) {
            time_start = gettime();
            for (it = 0; it < nb_its; it++) {
                switch (transform) {
                case TRANSFORM_MDCT:
                    if (do_inverse) {
                        ff_imdct_calc(m, (float *)tab, (float *)tab1);
                    } else {
                        ff_mdct_calc(m, (float *)tab, (float *)tab1);
                    }
                    break;
                case TRANSFORM_FFT:
                    memcpy(tab, tab1, fft_size * sizeof(FFTComplex));
                    ff_fft_calc(s, tab);
                    break;
                case TRANSFORM_RDFT:
                    memcpy(tab2, tab1, fft_size * sizeof(FFTSample));
                    ff_rdft_calc(r, tab2);
                    break;
                case TRANSFORM_DCT:
                    memcpy(tab2, tab1, fft_size * sizeof(FFTSample));
                    ff_dct_calc(d, tab2);
                    break;
                }
            }
            duration = gettime() - time_start;
            if (duration >= 1000000)
                break;
            nb_its *= 2;
        }
        av_log(NULL, AV_LOG_INFO,"time: %0.1f us/transform [total time=%0.2f s its=%d]\n",
               (double)duration / nb_its,
               (double)duration / 1000000.0,
               nb_its);
    }

    switch (transform) {
    case TRANSFORM_MDCT:
        ff_mdct_end(m);
        break;
    case TRANSFORM_FFT:
        ff_fft_end(s);
        break;
    case TRANSFORM_RDFT:
        ff_rdft_end(r);
        break;
    case TRANSFORM_DCT:
        ff_dct_end(d);
        break;
    }

    av_free(tab);
    av_free(tab1);
    av_free(tab2);
    av_free(tab_ref);
    av_free(exptab);

    return err;
}
예제 #15
0
파일: fft-test.c 프로젝트: gajjanag/FFmpeg
int main(int argc, char **argv)
{
    FFTComplex *tab, *tab1, *tab_ref;
    FFTSample *tab2;
    enum tf_transform transform = TRANSFORM_FFT;
    FFTContext m, s;
#if FFT_FLOAT
    RDFTContext r;
    DCTContext d;
#if CONFIG_LIBFFTW3
    FFTWContext fftw;
    FFTWComplex *tab_fftw, *tab_fftw_copy;
#endif /* CONFIG_LIBFFTW3 */
#endif /* FFT_FLOAT */
    int it, i, err = 1;
    int do_speed = 0, do_inverse = 0;
    int fft_nbits = 9, fft_size;
    double scale = 1.0;
    AVLFG prng;

    av_lfg_init(&prng, 1);

    for (;;) {
        int c = getopt(argc, argv, "hsitmrdn:f:c:");
        if (c == -1)
            break;
        switch (c) {
        case 'h':
            help();
            return 1;
        case 's':
            do_speed = 1;
            break;
        case 'i':
            do_inverse = 1;
            break;
#if CONFIG_LIBFFTW3
        case 't':
            transform = TRANSFORM_FFTW;
            break;
#endif /* CONFIG_LIBFFTW3 */
        case 'm':
            transform = TRANSFORM_MDCT;
            break;
        case 'r':
            transform = TRANSFORM_RDFT;
            break;
        case 'd':
            transform = TRANSFORM_DCT;
            break;
        case 'n':
            fft_nbits = atoi(optarg);
            break;
        case 'f':
            scale = atof(optarg);
            break;
        case 'c':
        {
            unsigned cpuflags = av_get_cpu_flags();

            if (av_parse_cpu_caps(&cpuflags, optarg) < 0)
                return 1;

            av_force_cpu_flags(cpuflags);
            break;
        }
        }
    }

    fft_size = 1 << fft_nbits;
    tab      = av_malloc_array(fft_size, sizeof(FFTComplex));
    tab1     = av_malloc_array(fft_size, sizeof(FFTComplex));
    tab_ref  = av_malloc_array(fft_size, sizeof(FFTComplex));
    tab2     = av_malloc_array(fft_size, sizeof(FFTSample));
#if CONFIG_LIBFFTW3 && FFT_FLOAT
    tab_fftw      = av_malloc_array(fft_size, sizeof(*tab_fftw));
    tab_fftw_copy = av_malloc_array(fft_size, sizeof(*tab_fftw_copy));
    if (!(tab_fftw && tab_fftw_copy))
        goto cleanup_fftw;
#endif /* CONFIG_LIBFFTW3 */

    if (!(tab && tab1 && tab_ref && tab2))
        goto cleanup;

    switch (transform) {
#if CONFIG_MDCT
    case TRANSFORM_MDCT:
        av_log(NULL, AV_LOG_INFO, "Scale factor is set to %f\n", scale);
        if (do_inverse)
            av_log(NULL, AV_LOG_INFO, "IMDCT");
        else
            av_log(NULL, AV_LOG_INFO, "MDCT");
        ff_mdct_init(&m, fft_nbits, do_inverse, scale);
        break;
#endif /* CONFIG_MDCT */
    case TRANSFORM_FFT:
        if (do_inverse)
            av_log(NULL, AV_LOG_INFO, "IFFT");
        else
            av_log(NULL, AV_LOG_INFO, "FFT");
        ff_fft_init(&s, fft_nbits, do_inverse);
        if ((err = fft_ref_init(fft_nbits, do_inverse)) < 0)
            goto cleanup;
        break;
#if CONFIG_LIBFFTW3 && FFT_FLOAT
    case TRANSFORM_FFTW:
        if (do_inverse)
            av_log(NULL, AV_LOG_INFO, "IFFTW");
        else
            av_log(NULL, AV_LOG_INFO, "FFTW");
        ff_fftw_init(&fftw, fft_size, do_inverse);
        if ((err = fft_ref_init(fft_nbits, do_inverse)) < 0)
            goto cleanup;
        break;
#endif /* CONFIG_LIBFFTW3 */
#if FFT_FLOAT
#    if CONFIG_RDFT
    case TRANSFORM_RDFT:
        if (do_inverse)
            av_log(NULL, AV_LOG_INFO, "IDFT_C2R");
        else
            av_log(NULL, AV_LOG_INFO, "DFT_R2C");
        ff_rdft_init(&r, fft_nbits, do_inverse ? IDFT_C2R : DFT_R2C);
        if ((err = fft_ref_init(fft_nbits, do_inverse)) < 0)
            goto cleanup;
        break;
#    endif /* CONFIG_RDFT */
#    if CONFIG_DCT
    case TRANSFORM_DCT:
        if (do_inverse)
            av_log(NULL, AV_LOG_INFO, "DCT_III");
        else
            av_log(NULL, AV_LOG_INFO, "DCT_II");
        ff_dct_init(&d, fft_nbits, do_inverse ? DCT_III : DCT_II);
        break;
#    endif /* CONFIG_DCT */
#endif /* FFT_FLOAT */
    default:
        av_log(NULL, AV_LOG_ERROR, "Requested transform not supported\n");
        goto cleanup;
    }
    av_log(NULL, AV_LOG_INFO, " %d test\n", fft_size);

    /* generate random data */

    for (i = 0; i < fft_size; i++) {
        tab1[i].re = frandom(&prng);
        tab1[i].im = frandom(&prng);
#if CONFIG_LIBFFTW3 && FFT_FLOAT
        tab_fftw[i][0] = tab1[i].re;
        tab_fftw[i][1] = tab1[i].im;
#endif /* CONFIG_LIBFFTW3 */
    }
#if CONFIG_LIBFFTW3 && FFT_FLOAT
    memcpy(tab_fftw_copy, tab_fftw, fft_size * sizeof(*tab_fftw));
#endif

    /* checking result */
    av_log(NULL, AV_LOG_INFO, "Checking...\n");

    switch (transform) {
#if CONFIG_MDCT
    case TRANSFORM_MDCT:
        if (do_inverse) {
            imdct_ref(&tab_ref->re, &tab1->re, fft_nbits);
            m.imdct_calc(&m, tab2, &tab1->re);
            err = check_diff(&tab_ref->re, tab2, fft_size, scale);
        } else {
            mdct_ref(&tab_ref->re, &tab1->re, fft_nbits);
            m.mdct_calc(&m, tab2, &tab1->re);
            err = check_diff(&tab_ref->re, tab2, fft_size / 2, scale);
        }
        break;
#endif /* CONFIG_MDCT */
    case TRANSFORM_FFT:
        memcpy(tab, tab1, fft_size * sizeof(FFTComplex));
        s.fft_permute(&s, tab);
        s.fft_calc(&s, tab);

        fft_ref(tab_ref, tab1, fft_nbits);
        err = check_diff(&tab_ref->re, &tab->re, fft_size * 2, 1.0);
        break;
#if CONFIG_LIBFFTW3 && FFT_FLOAT
    case TRANSFORM_FFTW:
        fftw.fft_calc(&fftw, tab_fftw);
        fft_ref(tab_ref, tab1, fft_nbits);
        for (i = 0; i < fft_size; i++) {
            tab[i].re = tab_fftw[i][0];
            tab[i].im = tab_fftw[i][1];
        }
        err = check_diff(&tab_ref->re, &tab->re, fft_size * 2, 1.0);
        break;
#endif /* CONFIG_LIBFFTW3 */
#if FFT_FLOAT
#if CONFIG_RDFT
    case TRANSFORM_RDFT:
    {
        int fft_size_2 = fft_size >> 1;
        if (do_inverse) {
            tab1[0].im          = 0;
            tab1[fft_size_2].im = 0;
            for (i = 1; i < fft_size_2; i++) {
                tab1[fft_size_2 + i].re =  tab1[fft_size_2 - i].re;
                tab1[fft_size_2 + i].im = -tab1[fft_size_2 - i].im;
            }

            memcpy(tab2, tab1, fft_size * sizeof(FFTSample));
            tab2[1] = tab1[fft_size_2].re;

            r.rdft_calc(&r, tab2);
            fft_ref(tab_ref, tab1, fft_nbits);
            for (i = 0; i < fft_size; i++) {
                tab[i].re = tab2[i];
                tab[i].im = 0;
            }
            err = check_diff(&tab_ref->re, &tab->re, fft_size * 2, 0.5);
        } else {
            for (i = 0; i < fft_size; i++) {
                tab2[i]    = tab1[i].re;
                tab1[i].im = 0;
            }
            r.rdft_calc(&r, tab2);
            fft_ref(tab_ref, tab1, fft_nbits);
            tab_ref[0].im = tab_ref[fft_size_2].re;
            err = check_diff(&tab_ref->re, tab2, fft_size, 1.0);
        }
        break;
    }
#endif /* CONFIG_RDFT */
#if CONFIG_DCT
    case TRANSFORM_DCT:
        memcpy(tab, tab1, fft_size * sizeof(FFTComplex));
        d.dct_calc(&d, &tab->re);
        if (do_inverse)
            idct_ref(&tab_ref->re, &tab1->re, fft_nbits);
        else
            dct_ref(&tab_ref->re, &tab1->re, fft_nbits);
        err = check_diff(&tab_ref->re, &tab->re, fft_size, 1.0);
        break;
#endif /* CONFIG_DCT */
#endif /* FFT_FLOAT */
    }

    /* do a speed test */

    if (do_speed) {
        int64_t time_start, duration;
        int nb_its;

        av_log(NULL, AV_LOG_INFO, "Speed test...\n");
        /* we measure during about 1 seconds */
        nb_its = 1;
        for (;;) {
            time_start = av_gettime_relative();
            for (it = 0; it < nb_its; it++) {
                switch (transform) {
                case TRANSFORM_MDCT:
                    if (do_inverse)
                        m.imdct_calc(&m, &tab->re, &tab1->re);
                    else
                        m.mdct_calc(&m, &tab->re, &tab1->re);
                    break;
                case TRANSFORM_FFT:
                    memcpy(tab, tab1, fft_size * sizeof(FFTComplex));
                    s.fft_permute(&s, tab);
                    s.fft_calc(&s, tab);
                    break;
#if CONFIG_LIBFFTW3 && FFT_FLOAT
                case TRANSFORM_FFTW:
                    memcpy(tab_fftw, tab_fftw_copy, fft_size * sizeof(*tab_fftw));
                    fftw.fft_calc(&fftw, tab_fftw);
                    break;
#endif /* CONFIG_LIBFFTW3 */
#if FFT_FLOAT
                case TRANSFORM_RDFT:
                    memcpy(tab2, tab1, fft_size * sizeof(FFTSample));
                    r.rdft_calc(&r, tab2);
                    break;
                case TRANSFORM_DCT:
                    memcpy(tab2, tab1, fft_size * sizeof(FFTSample));
                    d.dct_calc(&d, tab2);
                    break;
#endif /* FFT_FLOAT */
                }
            }
            duration = av_gettime_relative() - time_start;
            if (duration >= 1000000)
                break;
            nb_its *= 2;
        }
        av_log(NULL, AV_LOG_INFO,
               "time: %0.2f us/transform [total time=%0.2f s its=%d]\n",
               (double) duration / nb_its,
               (double) duration / 1000000.0,
               nb_its);
    }

    switch (transform) {
#if CONFIG_MDCT
    case TRANSFORM_MDCT:
        ff_mdct_end(&m);
        break;
#endif /* CONFIG_MDCT */
    case TRANSFORM_FFT:
        ff_fft_end(&s);
        break;
#if CONFIG_LIBFFTW3 && FFT_FLOAT
    case TRANSFORM_FFTW:
        ff_fftw_deinit(&fftw);
        break;
#endif /* CONFIG_LIBFFTW3 */
#if FFT_FLOAT
#    if CONFIG_RDFT
    case TRANSFORM_RDFT:
        ff_rdft_end(&r);
        break;
#    endif /* CONFIG_RDFT */
#    if CONFIG_DCT
    case TRANSFORM_DCT:
        ff_dct_end(&d);
        break;
#    endif /* CONFIG_DCT */
#endif /* FFT_FLOAT */
    }

#if CONFIG_LIBFFTW3 && FFT_FLOAT
cleanup_fftw:
    av_freep(&tab_fftw);
#endif /* CONFIG_LIBFFTW3 */
cleanup:
    av_freep(&tab);
    av_freep(&tab1);
    av_freep(&tab2);
    av_freep(&tab_ref);
    av_freep(&exptab);

    if (err)
        printf("Error: %d.\n", err);

    return !!err;
}
예제 #16
0
파일: mdct_template.c 프로젝트: AVLeo/libav
/**
 * init MDCT or IMDCT computation.
 */
av_cold int ff_mdct_init(FFTContext *s, int nbits, int inverse, double scale)
{
    int n, n4, i;
    double alpha, theta;
    int tstep;

    memset(s, 0, sizeof(*s));
    n = 1 << nbits;
    s->mdct_bits = nbits;
    s->mdct_size = n;
    n4 = n >> 2;
    s->mdct_permutation = FF_MDCT_PERM_NONE;

    if (ff_fft_init(s, s->mdct_bits - 2, inverse) < 0)
        goto fail;

    s->imdct_calc  = ff_imdct_calc_c;
    s->imdct_half  = ff_imdct_half_c;
    s->mdct_calc   = ff_mdct_calc_c;

#if FFT_FLOAT
    if (ARCH_AARCH64)
        ff_mdct_init_aarch64(s);
    if (ARCH_ARM)
        ff_mdct_init_arm(s);
    if (ARCH_PPC)
        ff_mdct_init_ppc(s);
    if (ARCH_X86)
        ff_mdct_init_x86(s);
    s->mdct_calcw  = s->mdct_calc;
#else
    s->mdct_calcw  = ff_mdct_calcw_c;
    if (ARCH_ARM)
        ff_mdct_fixed_init_arm(s);
#endif

    s->tcos = av_malloc(n/2 * sizeof(FFTSample));
    if (!s->tcos)
        goto fail;

    switch (s->mdct_permutation) {
    case FF_MDCT_PERM_NONE:
        s->tsin = s->tcos + n4;
        tstep = 1;
        break;
    case FF_MDCT_PERM_INTERLEAVE:
        s->tsin = s->tcos + 1;
        tstep = 2;
        break;
    default:
        goto fail;
    }

    theta = 1.0 / 8.0 + (scale < 0 ? n4 : 0);
    scale = sqrt(fabs(scale));
    for(i=0;i<n4;i++) {
        alpha = 2 * M_PI * (i + theta) / n;
        s->tcos[i*tstep] = FIX15(-cos(alpha) * scale);
        s->tsin[i*tstep] = FIX15(-sin(alpha) * scale);
    }
    return 0;
 fail:
    ff_mdct_end(s);
    return -1;
}
예제 #17
0
av_cold int ff_mdct15_init(MDCT15Context **ps, int inverse, int N, double scale)
{
    MDCT15Context *s;
    double alpha, theta;
    int len2 = 15 * (1 << N);
    int len  = 2 * len2;
    int i;

    /* Tested and verified to work on everything in between */
    if ((N < 2) || (N > 13))
        return AVERROR(EINVAL);

    s = av_mallocz(sizeof(*s));
    if (!s)
        return AVERROR(ENOMEM);

    s->fft_n      = N - 1;
    s->len4       = len2 / 2;
    s->len2       = len2;
    s->inverse    = inverse;
    s->fft15      = fft15_c;
    s->mdct       = mdct15;
    s->imdct_half = imdct15_half;

    if (ff_fft_init(&s->ptwo_fft, N - 1, s->inverse) < 0)
        goto fail;

    if (init_pfa_reindex_tabs(s))
        goto fail;

    s->tmp  = av_malloc_array(len, 2 * sizeof(*s->tmp));
    if (!s->tmp)
        goto fail;

    s->twiddle_exptab  = av_malloc_array(s->len4, sizeof(*s->twiddle_exptab));
    if (!s->twiddle_exptab)
        goto fail;

    theta = 0.125f + (scale < 0 ? s->len4 : 0);
    scale = sqrt(fabs(scale));
    for (i = 0; i < s->len4; i++) {
        alpha = 2 * M_PI * (i + theta) / len;
        s->twiddle_exptab[i].re = cosf(alpha) * scale;
        s->twiddle_exptab[i].im = sinf(alpha) * scale;
    }

    /* 15-point FFT exptab */
    for (i = 0; i < 19; i++) {
        if (i < 15) {
            double theta = (2.0f * M_PI * i) / 15.0f;
            if (!s->inverse)
                theta *= -1;
            s->exptab[i].re = cosf(theta);
            s->exptab[i].im = sinf(theta);
        } else { /* Wrap around to simplify fft15 */
            s->exptab[i] = s->exptab[i - 15];
        }
    }

    /* 5-point FFT exptab */
    s->exptab[19].re = cosf(2.0f * M_PI / 5.0f);
    s->exptab[19].im = sinf(2.0f * M_PI / 5.0f);
    s->exptab[20].re = cosf(1.0f * M_PI / 5.0f);
    s->exptab[20].im = sinf(1.0f * M_PI / 5.0f);

    /* Invert the phase for an inverse transform, do nothing for a forward transform */
    if (s->inverse) {
        s->exptab[19].im *= -1;
        s->exptab[20].im *= -1;
    }

    if (ARCH_X86)
        ff_mdct15_init_x86(s);

    *ps = s;

    return 0;

fail:
    ff_mdct15_uninit(&s);
    return AVERROR(ENOMEM);
}