1/* 2 * Copyright (c) 2011 Mans Rullgard 3 * 4 * This file is part of FFmpeg. 5 * 6 * FFmpeg is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * FFmpeg is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with FFmpeg; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21#include "config.h" 22#include "libavutil/attributes.h" 23#include "libavutil/thread.h" 24#include "mpegaudio.h" 25#include "mpegaudiodsp.h" 26#include "dct.h" 27#include "dct32.h" 28 29static AVOnce mpadsp_table_init = AV_ONCE_INIT; 30 31static av_cold void mpadsp_init_tabs(void) 32{ 33 int i, j; 34 /* compute mdct windows */ 35 for (i = 0; i < 36; i++) { 36 for (j = 0; j < 4; j++) { 37 double d; 38 39 if (j == 2 && i % 3 != 1) 40 continue; 41 42 d = sin(M_PI * (i + 0.5) / 36.0); 43 if (j == 1) { 44 if (i >= 30) d = 0; 45 else if (i >= 24) d = sin(M_PI * (i - 18 + 0.5) / 12.0); 46 else if (i >= 18) d = 1; 47 } else if (j == 3) { 48 if (i < 6) d = 0; 49 else if (i < 12) d = sin(M_PI * (i - 6 + 0.5) / 12.0); 50 else if (i < 18) d = 1; 51 } 52 //merge last stage of imdct into the window coefficients 53 d *= 0.5 * IMDCT_SCALAR / cos(M_PI * (2 * i + 19) / 72); 54 55 if (j == 2) { 56 ff_mdct_win_float[j][i/3] = d / (1 << 5); 57 ff_mdct_win_fixed[j][i/3] = d / (1 << 5) * (1LL << 32) + 0.5; 58 } else { 59 int idx = i < 18 ? i : i + (MDCT_BUF_SIZE/2 - 18); 60 ff_mdct_win_float[j][idx] = d / (1 << 5); 61 ff_mdct_win_fixed[j][idx] = d / (1 << 5) * (1LL << 32) + 0.5; 62 } 63 } 64 } 65 66 /* NOTE: we do frequency inversion after the MDCT by changing 67 the sign of the right window coefs */ 68 for (j = 0; j < 4; j++) { 69 for (i = 0; i < MDCT_BUF_SIZE; i += 2) { 70 ff_mdct_win_float[j + 4][i ] = ff_mdct_win_float[j][i ]; 71 ff_mdct_win_float[j + 4][i + 1] = -ff_mdct_win_float[j][i + 1]; 72 ff_mdct_win_fixed[j + 4][i ] = ff_mdct_win_fixed[j][i ]; 73 ff_mdct_win_fixed[j + 4][i + 1] = -ff_mdct_win_fixed[j][i + 1]; 74 } 75 } 76 77#if ARCH_X86 78 ff_mpadsp_init_x86_tabs(); 79#endif 80} 81 82av_cold void ff_mpadsp_init(MPADSPContext *s) 83{ 84 DCTContext dct; 85 86 ff_dct_init(&dct, 5, DCT_II); 87 ff_thread_once(&mpadsp_table_init, &mpadsp_init_tabs); 88 89 s->apply_window_float = ff_mpadsp_apply_window_float; 90 s->apply_window_fixed = ff_mpadsp_apply_window_fixed; 91 92 s->dct32_float = dct.dct32; 93 s->dct32_fixed = ff_dct32_fixed; 94 95 s->imdct36_blocks_float = ff_imdct36_blocks_float; 96 s->imdct36_blocks_fixed = ff_imdct36_blocks_fixed; 97 98#if ARCH_AARCH64 99 ff_mpadsp_init_aarch64(s); 100#elif ARCH_ARM 101 ff_mpadsp_init_arm(s); 102#elif ARCH_PPC 103 ff_mpadsp_init_ppc(s); 104#elif ARCH_X86 105 ff_mpadsp_init_x86(s); 106#endif 107#if HAVE_MIPSFPU 108 ff_mpadsp_init_mipsfpu(s); 109#endif 110#if HAVE_MIPSDSP 111 ff_mpadsp_init_mipsdsp(s); 112#endif 113} 114