static av_cold int init_mdct_win(TwinContext *tctx)
{
    int i, j, ret;
    const ModeTab *mtab = tctx->mtab;
    int size_s = mtab->size / mtab->fmode[FT_SHORT].sub;
    int size_m = mtab->size / mtab->fmode[FT_MEDIUM].sub;
    int channels = tctx->avctx->channels;
    float norm = channels == 1 ? 2. : 1.;

    for (i = 0; i < 3; i++) {
        int bsize = tctx->mtab->size/tctx->mtab->fmode[i].sub;
        if ((ret = ff_mdct_init(&tctx->mdct_ctx[i], av_log2(bsize) + 1, 1,
                                -sqrt(norm/bsize) / (1<<15))))
            return ret;
    }

    FF_ALLOC_OR_GOTO(tctx->avctx, tctx->tmp_buf,
                     mtab->size * sizeof(*tctx->tmp_buf), alloc_fail);

    FF_ALLOC_OR_GOTO(tctx->avctx, tctx->spectrum,
                     2 * mtab->size * channels * sizeof(*tctx->spectrum),
                     alloc_fail);
    FF_ALLOC_OR_GOTO(tctx->avctx, tctx->curr_frame,
                     2 * mtab->size * channels * sizeof(*tctx->curr_frame),
                     alloc_fail);
    FF_ALLOC_OR_GOTO(tctx->avctx, tctx->prev_frame,
                     2 * mtab->size * channels * sizeof(*tctx->prev_frame),
                     alloc_fail);

    for (i = 0; i < 3; i++) {
        int m = 4*mtab->size/mtab->fmode[i].sub;
        double freq = 2*M_PI/m;
        FF_ALLOC_OR_GOTO(tctx->avctx, tctx->cos_tabs[i],
                         (m / 4) * sizeof(*tctx->cos_tabs[i]), alloc_fail);

        for (j = 0; j <= m/8; j++)
            tctx->cos_tabs[i][j] = cos((2*j + 1)*freq);
        for (j = 1; j <  m/8; j++)
            tctx->cos_tabs[i][m/4-j] = tctx->cos_tabs[i][j];
    }


    ff_init_ff_sine_windows(av_log2(size_m));
    ff_init_ff_sine_windows(av_log2(size_s/2));
    ff_init_ff_sine_windows(av_log2(mtab->size));

    return 0;
alloc_fail:
    return AVERROR(ENOMEM);
}