Commit f85bc147 authored by Djordje Pesut's avatar Djordje Pesut Committed by Michael Niedermayer

avcodec: Implementation of AAC_fixed_decoder (SBR-module)

Add fixed poind code.
Signed-off-by: 's avatarNedeljko Babic <nedeljko.babic@imgtec.com>
Signed-off-by: 's avatarMichael Niedermayer <michael@niedermayer.cc>
parent b0414da9
......@@ -126,8 +126,9 @@ OBJS-$(CONFIG_A64MULTI5_ENCODER) += a64multienc.o elbg.o
OBJS-$(CONFIG_AAC_DECODER) += aacdec.o aactab.o aacsbr.o aacps.o \
aacadtsdec.o mpeg4audio.o kbdwin.o \
sbrdsp.o aacpsdsp.o
OBJS-$(CONFIG_AAC_FIXED_DECODER) += aacdec_fixed.o aactab.o \
aacadtsdec.o mpeg4audio.o kbdwin.o
OBJS-$(CONFIG_AAC_FIXED_DECODER) += aacdec_fixed.o aactab.o aacsbr_fixed.o \
aacadtsdec.o mpeg4audio.o kbdwin.o \
sbrdsp_fixed.o
OBJS-$(CONFIG_AAC_ENCODER) += aacenc.o aaccoder.o \
aacpsy.o aactab.o \
psymodel.o mpeg4audio.o kbdwin.o
......
......@@ -30,58 +30,8 @@
#ifndef AVCODEC_AAC_H
#define AVCODEC_AAC_H
#ifndef USE_FIXED
#define USE_FIXED 0
#endif
#if USE_FIXED
#include "libavutil/softfloat.h"
#define FFT_FLOAT 0
#define FFT_FIXED_32 1
#define AAC_RENAME(x) x ## _fixed
#define AAC_RENAME_32(x) x ## _fixed_32
#define AAC_FLOAT SoftFloat
#define INTFLOAT int
#define SHORTFLOAT int16_t
#define AAC_SIGNE int
#define FIXR(a) ((int)((a) * 1 + 0.5))
#define FIXR10(a) ((int)((a) * 1024.0 + 0.5))
#define Q23(a) (int)((a) * 8388608.0 + 0.5)
#define Q30(x) (int)((x)*1073741824.0 + 0.5)
#define Q31(x) (int)((x)*2147483648.0 + 0.5)
#define RANGE15(x) x
#define GET_GAIN(x, y) (-(y) << (x)) + 1024
#define AAC_MUL26(x, y) (int)(((int64_t)(x) * (y) + 0x2000000) >> 26)
#define AAC_MUL30(x, y) (int)(((int64_t)(x) * (y) + 0x20000000) >> 30)
#define AAC_MUL31(x, y) (int)(((int64_t)(x) * (y) + 0x40000000) >> 31)
#else
#define FFT_FLOAT 1
#define FFT_FIXED_32 0
#define AAC_RENAME(x) x
#define AAC_RENAME_32(x) x
#define AAC_FLOAT float
#define INTFLOAT float
#define SHORTFLOAT float
#define AAC_SIGNE unsigned
#define FIXR(x) ((float)(x))
#define FIXR10(x) ((float)(x))
#define Q23(x) x
#define Q30(x) x
#define Q31(x) x
#define RANGE15(x) (32768.0 * (x))
#define GET_GAIN(x, y) powf((x), -(y))
#define AAC_MUL26(x, y) ((x) * (y))
#define AAC_MUL30(x, y) ((x) * (y))
#define AAC_MUL31(x, y) ((x) * (y))
#endif /* USE_FIXED */
#include "aac_defines.h"
#include "libavutil/float_dsp.h"
#include "libavutil/fixed_dsp.h"
#include "avcodec.h"
......
/*
* AAC defines
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_AAC_DEFINES_H
#define AVCODEC_AAC_DEFINES_H
#ifndef USE_FIXED
#define USE_FIXED 0
#endif
#if USE_FIXED
#include "libavutil/softfloat.h"
#define FFT_FLOAT 0
#define FFT_FIXED_32 1
#define AAC_RENAME(x) x ## _fixed
#define AAC_RENAME_32(x) x ## _fixed_32
#define INTFLOAT int
#define SHORTFLOAT int16_t
#define AAC_FLOAT SoftFloat
#define AAC_SIGNE int
#define FIXR(a) ((int)((a) * 1 + 0.5))
#define FIXR10(a) ((int)((a) * 1024.0 + 0.5))
#define Q23(a) (int)((a) * 8388608.0 + 0.5)
#define Q30(x) (int)((x)*1073741824.0 + 0.5)
#define Q31(x) (int)((x)*2147483648.0 + 0.5)
#define RANGE15(x) x
#define GET_GAIN(x, y) (-(y) << (x)) + 1024
#define AAC_MUL26(x, y) (int)(((int64_t)(x) * (y) + 0x2000000) >> 26)
#define AAC_MUL30(x, y) (int)(((int64_t)(x) * (y) + 0x20000000) >> 30)
#define AAC_MUL31(x, y) (int)(((int64_t)(x) * (y) + 0x40000000) >> 31)
#define AAC_SRA_R(x, y) (int)(((x) + (1 << ((y) - 1))) >> (y))
#else
#define FFT_FLOAT 1
#define FFT_FIXED_32 0
#define AAC_RENAME(x) x
#define AAC_RENAME_32(x) x
#define INTFLOAT float
#define SHORTFLOAT float
#define AAC_FLOAT float
#define AAC_SIGNE unsigned
#define FIXR(x) ((float)(x))
#define FIXR10(x) ((float)(x))
#define Q23(x) x
#define Q30(x) x
#define Q31(x) x
#define RANGE15(x) (32768.0 * (x))
#define GET_GAIN(x, y) powf((x), -(y))
#define AAC_MUL26(x, y) ((x) * (y))
#define AAC_MUL30(x, y) ((x) * (y))
#define AAC_MUL31(x, y) ((x) * (y))
#define AAC_SRA_R(x, y) (x)
#endif /* USE_FIXED */
#endif /* AVCODEC_AAC_DEFINES_H */
......@@ -132,7 +132,7 @@ static av_cold int che_configure(AACContext *ac,
if (!ac->che[type][id]) {
if (!(ac->che[type][id] = av_mallocz(sizeof(ChannelElement))))
return AVERROR(ENOMEM);
ff_aac_sbr_ctx_init(ac, &ac->che[type][id]->sbr);
AAC_RENAME(ff_aac_sbr_ctx_init)(ac, &ac->che[type][id]->sbr);
}
if (type != TYPE_CCE) {
if (*channels >= MAX_CHANNELS - (type == TYPE_CPE || (type == TYPE_SCE && ac->oc[1].m4ac.ps == 1))) {
......@@ -147,7 +147,7 @@ static av_cold int che_configure(AACContext *ac,
}
} else {
if (ac->che[type][id])
ff_aac_sbr_ctx_close(&ac->che[type][id]->sbr);
AAC_RENAME(ff_aac_sbr_ctx_close)(&ac->che[type][id]->sbr);
av_freep(&ac->che[type][id]);
}
return 0;
......@@ -1126,7 +1126,7 @@ static av_cold int aac_decode_init(AVCodecContext *avctx)
AAC_INIT_VLC_STATIC( 9, 366);
AAC_INIT_VLC_STATIC(10, 462);
ff_aac_sbr_init();
AAC_RENAME(ff_aac_sbr_init)();
#if USE_FIXED
ac->fdsp = avpriv_alloc_fixed_dsp(avctx->flags & CODEC_FLAG_BITEXACT);
......@@ -2315,7 +2315,7 @@ static int decode_extension_payload(AACContext *ac, GetBitContext *gb, int cnt,
ac->oc[1].m4ac.sbr = 1;
ac->avctx->profile = FF_PROFILE_AAC_HE;
}
res = ff_decode_sbr_extension(ac, &che->sbr, gb, crc_flag, cnt, elem_type);
res = AAC_RENAME(ff_decode_sbr_extension)(ac, &che->sbr, gb, crc_flag, cnt, elem_type);
break;
case EXT_DYNAMIC_RANGE:
res = decode_dynamic_range(&ac->che_drc, gb);
......@@ -2357,7 +2357,7 @@ static void apply_tns(INTFLOAT coef[1024], TemporalNoiseShaping *tns,
continue;
// tns_decode_coef
compute_lpc_coefs(tns->coef[w][filt], order, lpc, 0, 0, 0);
AAC_RENAME(compute_lpc_coefs)(tns->coef[w][filt], order, lpc, 0, 0, 0);
start = ics->swb_offset[FFMIN(bottom, mmm)];
end = ics->swb_offset[FFMIN( top, mmm)];
......@@ -2738,7 +2738,7 @@ static void spectral_to_sample(AACContext *ac)
ac->update_ltp(ac, &che->ch[1]);
}
if (ac->oc[1].m4ac.sbr > 0) {
ff_sbr_apply(ac, &che->sbr, type, che->ch[0].ret, che->ch[1].ret);
AAC_RENAME(ff_sbr_apply)(ac, &che->sbr, type, che->ch[0].ret, che->ch[1].ret);
}
}
if (type <= TYPE_CCE)
......@@ -3153,7 +3153,7 @@ static av_cold int aac_decode_close(AVCodecContext *avctx)
for (i = 0; i < MAX_ELEM_ID; i++) {
for (type = 0; type < 4; type++) {
if (ac->che[type][i])
ff_aac_sbr_ctx_close(&ac->che[type][i]->sbr);
AAC_RENAME(ff_aac_sbr_ctx_close)(&ac->che[type][i]->sbr);
av_freep(&ac->che[type][i]);
}
}
......
......@@ -25,6 +25,7 @@
* AAC Spectral Band Replication decoding functions
* @author Robert Swain ( rob opendot cl )
*/
#define USE_FIXED 0
#include "aac.h"
#include "sbr.h"
......
......@@ -79,17 +79,17 @@ static const int8_t vlc_sbr_lav[10] =
{ name ## _codes, name ## _bits, sizeof(name ## _codes), sizeof(name ## _codes[0]) }
/** Initialize SBR. */
void ff_aac_sbr_init(void);
void AAC_RENAME(ff_aac_sbr_init)(void);
/** Initialize one SBR context. */
void ff_aac_sbr_ctx_init(AACContext *ac, SpectralBandReplication *sbr);
void AAC_RENAME(ff_aac_sbr_ctx_init)(AACContext *ac, SpectralBandReplication *sbr);
/** Close one SBR context. */
void ff_aac_sbr_ctx_close(SpectralBandReplication *sbr);
void AAC_RENAME(ff_aac_sbr_ctx_close)(SpectralBandReplication *sbr);
/** Decode one SBR element. */
int ff_decode_sbr_extension(AACContext *ac, SpectralBandReplication *sbr,
int AAC_RENAME(ff_decode_sbr_extension)(AACContext *ac, SpectralBandReplication *sbr,
GetBitContext *gb, int crc, int cnt, int id_aac);
/** Apply one SBR element to one AAC element. */
void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac,
float* L, float *R);
void AAC_RENAME(ff_sbr_apply)(AACContext *ac, SpectralBandReplication *sbr, int id_aac,
INTFLOAT* L, INTFLOAT *R);
void ff_aacsbr_func_ptr_init_mips(AACSBRContext *c);
......
This diff is collapsed.
This diff is collapsed.
......@@ -25,6 +25,7 @@
#include <stdint.h>
#include "libavutil/avassert.h"
#include "libavutil/lls.h"
#include "aac_defines.h"
#define ORDER_METHOD_EST 0
#define ORDER_METHOD_2LEVEL 1
......@@ -111,11 +112,15 @@ void ff_lpc_init_x86(LPCContext *s);
*/
void ff_lpc_end(LPCContext *s);
#if USE_FIXED
#define LPC_TYPE int
#else
#ifdef LPC_USE_DOUBLE
#define LPC_TYPE double
#else
#define LPC_TYPE float
#endif
#endif // USE_FIXED
/**
* Schur recursion.
......@@ -152,7 +157,7 @@ static inline void compute_ref_coefs(const LPC_TYPE *autoc, int max_order,
* Levinson-Durbin recursion.
* Produce LPC coefficients from autocorrelation data.
*/
static inline int compute_lpc_coefs(const LPC_TYPE *autoc, int max_order,
static inline int AAC_RENAME(compute_lpc_coefs)(const LPC_TYPE *autoc, int max_order,
LPC_TYPE *lpc, int lpc_stride, int fail,
int normalize)
{
......@@ -169,14 +174,14 @@ static inline int compute_lpc_coefs(const LPC_TYPE *autoc, int max_order,
return -1;
for(i=0; i<max_order; i++) {
LPC_TYPE r = -autoc[i];
LPC_TYPE r = AAC_SRA_R(-autoc[i], 5);
if (normalize) {
for(j=0; j<i; j++)
r -= lpc_last[j] * autoc[i-j-1];
r /= err;
err *= 1.0 - (r * r);
err *= FIXR(1.0) - (r * r);
}
lpc[i] = r;
......@@ -184,8 +189,8 @@ static inline int compute_lpc_coefs(const LPC_TYPE *autoc, int max_order,
for(j=0; j < (i+1)>>1; j++) {
LPC_TYPE f = lpc_last[ j];
LPC_TYPE b = lpc_last[i-1-j];
lpc[ j] = f + r * b;
lpc[i-1-j] = b + r * f;
lpc[ j] = f + AAC_MUL26(r, b);
lpc[i-1-j] = b + AAC_MUL26(r, f);
}
if (fail && err < 0)
......
......@@ -66,9 +66,9 @@ typedef struct SBRData {
*/
unsigned bs_frame_class;
unsigned bs_add_harmonic_flag;
unsigned bs_num_env;
AAC_SIGNE bs_num_env;
uint8_t bs_freq_res[7];
unsigned bs_num_noise;
AAC_SIGNE bs_num_noise;
uint8_t bs_df_env[5];
uint8_t bs_df_noise[2];
uint8_t bs_invf_mode[2][5];
......@@ -80,25 +80,25 @@ typedef struct SBRData {
* @name State variables
* @{
*/
DECLARE_ALIGNED(32, float, synthesis_filterbank_samples)[SBR_SYNTHESIS_BUF_SIZE];
DECLARE_ALIGNED(32, float, analysis_filterbank_samples) [1312];
DECLARE_ALIGNED(32, INTFLOAT, synthesis_filterbank_samples)[SBR_SYNTHESIS_BUF_SIZE];
DECLARE_ALIGNED(32, INTFLOAT, analysis_filterbank_samples) [1312];
int synthesis_filterbank_samples_offset;
///l_APrev and l_A
int e_a[2];
///Chirp factors
float bw_array[5];
INTFLOAT bw_array[5];
///QMF values of the original signal
float W[2][32][32][2];
INTFLOAT W[2][32][32][2];
///QMF output of the HF adjustor
int Ypos;
DECLARE_ALIGNED(16, float, Y)[2][38][64][2];
DECLARE_ALIGNED(16, float, g_temp)[42][48];
float q_temp[42][48];
DECLARE_ALIGNED(16, INTFLOAT, Y)[2][38][64][2];
DECLARE_ALIGNED(16, AAC_FLOAT, g_temp)[42][48];
AAC_FLOAT q_temp[42][48];
uint8_t s_indexmapped[8][48];
///Envelope scalefactors
float env_facs[6][48];
AAC_FLOAT env_facs[6][48];
///Noise scalefactors
float noise_facs[3][5];
AAC_FLOAT noise_facs[3][5];
///Envelope time borders
uint8_t t_env[8];
///Envelope time border of the last envelope of the previous frame
......@@ -117,18 +117,18 @@ typedef struct SpectralBandReplication SpectralBandReplication;
*/
typedef struct AACSBRContext {
int (*sbr_lf_gen)(AACContext *ac, SpectralBandReplication *sbr,
float X_low[32][40][2], const float W[2][32][32][2],
INTFLOAT X_low[32][40][2], const INTFLOAT W[2][32][32][2],
int buf_idx);
void (*sbr_hf_assemble)(float Y1[38][64][2],
const float X_high[64][40][2],
void (*sbr_hf_assemble)(INTFLOAT Y1[38][64][2],
const INTFLOAT X_high[64][40][2],
SpectralBandReplication *sbr, SBRData *ch_data,
const int e_a[2]);
int (*sbr_x_gen)(SpectralBandReplication *sbr, float X[2][38][64],
const float Y0[38][64][2], const float Y1[38][64][2],
const float X_low[32][40][2], int ch);
int (*sbr_x_gen)(SpectralBandReplication *sbr, INTFLOAT X[2][38][64],
const INTFLOAT Y0[38][64][2], const INTFLOAT Y1[38][64][2],
const INTFLOAT X_low[32][40][2], int ch);
void (*sbr_hf_inverse_filter)(SBRDSPContext *dsp,
float (*alpha0)[2], float (*alpha1)[2],
const float X_low[32][40][2], int k0);
INTFLOAT (*alpha0)[2], INTFLOAT (*alpha1)[2],
const INTFLOAT X_low[32][40][2], int k0);
} AACSBRContext;
/**
......@@ -151,23 +151,23 @@ struct SpectralBandReplication {
unsigned bs_smoothing_mode;
/** @} */
unsigned bs_coupling;
unsigned k[5]; ///< k0, k1, k2
AAC_SIGNE k[5]; ///< k0, k1, k2
///kx', and kx respectively, kx is the first QMF subband where SBR is used.
///kx' is its value from the previous frame
unsigned kx[2];
AAC_SIGNE kx[2];
///M' and M respectively, M is the number of QMF subbands that use SBR.
unsigned m[2];
AAC_SIGNE m[2];
unsigned kx_and_m_pushed;
///The number of frequency bands in f_master
unsigned n_master;
AAC_SIGNE n_master;
SBRData data[2];
PSContext ps;
///N_Low and N_High respectively, the number of frequency bands for low and high resolution
unsigned n[2];
AAC_SIGNE n[2];
///Number of noise floor bands
unsigned n_q;
AAC_SIGNE n_q;
///Number of limiter bands
unsigned n_lim;
AAC_SIGNE n_lim;
///The master QMF frequency grouping
uint16_t f_master[49];
///Frequency borders for low resolution SBR
......@@ -178,33 +178,33 @@ struct SpectralBandReplication {
uint16_t f_tablenoise[6];
///Frequency borders for the limiter
uint16_t f_tablelim[30];
unsigned num_patches;
AAC_SIGNE num_patches;
uint8_t patch_num_subbands[6];
uint8_t patch_start_subband[6];
///QMF low frequency input to the HF generator
DECLARE_ALIGNED(16, float, X_low)[32][40][2];
DECLARE_ALIGNED(16, INTFLOAT, X_low)[32][40][2];
///QMF output of the HF generator
DECLARE_ALIGNED(16, float, X_high)[64][40][2];
DECLARE_ALIGNED(16, INTFLOAT, X_high)[64][40][2];
///QMF values of the reconstructed signal
DECLARE_ALIGNED(16, float, X)[2][2][38][64];
DECLARE_ALIGNED(16, INTFLOAT, X)[2][2][38][64];
///Zeroth coefficient used to filter the subband signals
DECLARE_ALIGNED(16, float, alpha0)[64][2];
DECLARE_ALIGNED(16, INTFLOAT, alpha0)[64][2];
///First coefficient used to filter the subband signals
DECLARE_ALIGNED(16, float, alpha1)[64][2];
DECLARE_ALIGNED(16, INTFLOAT, alpha1)[64][2];
///Dequantized envelope scalefactors, remapped
float e_origmapped[7][48];
AAC_FLOAT e_origmapped[7][48];
///Dequantized noise scalefactors, remapped
float q_mapped[7][48];
AAC_FLOAT q_mapped[7][48];
///Sinusoidal presence, remapped
uint8_t s_mapped[7][48];
///Estimated envelope
float e_curr[7][48];
AAC_FLOAT e_curr[7][48];
///Amplitude adjusted noise scalefactors
float q_m[7][48];
AAC_FLOAT q_m[7][48];
///Sinusoidal levels
float s_m[7][48];
float gain[7][48];
DECLARE_ALIGNED(32, float, qmf_filter_scratch)[5][64];
AAC_FLOAT s_m[7][48];
AAC_FLOAT gain[7][48];
DECLARE_ALIGNED(32, INTFLOAT, qmf_filter_scratch)[5][64];
FFTContext mdct_ana;
FFTContext mdct;
SBRDSPContext dsp;
......
......@@ -20,6 +20,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define USE_FIXED 0
#include "aac.h"
#include "config.h"
#include "libavutil/attributes.h"
#include "libavutil/intfloat.h"
......
......@@ -22,29 +22,31 @@
#define AVCODEC_SBRDSP_H
#include <stdint.h>
#include "aac_defines.h"
#include "libavutil/softfloat.h"
typedef struct SBRDSPContext {
void (*sum64x5)(float *z);
float (*sum_square)(float (*x)[2], int n);
void (*neg_odd_64)(float *x);
void (*qmf_pre_shuffle)(float *z);
void (*qmf_post_shuffle)(float W[32][2], const float *z);
void (*qmf_deint_neg)(float *v, const float *src);
void (*qmf_deint_bfly)(float *v, const float *src0, const float *src1);
void (*autocorrelate)(const float x[40][2], float phi[3][2][2]);
void (*hf_gen)(float (*X_high)[2], const float (*X_low)[2],
const float alpha0[2], const float alpha1[2],
float bw, int start, int end);
void (*hf_g_filt)(float (*Y)[2], const float (*X_high)[40][2],
const float *g_filt, int m_max, intptr_t ixh);
void (*hf_apply_noise[4])(float (*Y)[2], const float *s_m,
const float *q_filt, int noise,
void (*sum64x5)(INTFLOAT *z);
AAC_FLOAT (*sum_square)(INTFLOAT (*x)[2], int n);
void (*neg_odd_64)(INTFLOAT *x);
void (*qmf_pre_shuffle)(INTFLOAT *z);
void (*qmf_post_shuffle)(INTFLOAT W[32][2], const INTFLOAT *z);
void (*qmf_deint_neg)(INTFLOAT *v, const INTFLOAT *src);
void (*qmf_deint_bfly)(INTFLOAT *v, const INTFLOAT *src0, const INTFLOAT *src1);
void (*autocorrelate)(const INTFLOAT x[40][2], AAC_FLOAT phi[3][2][2]);
void (*hf_gen)(INTFLOAT (*X_high)[2], const INTFLOAT (*X_low)[2],
const INTFLOAT alpha0[2], const INTFLOAT alpha1[2],
INTFLOAT bw, int start, int end);
void (*hf_g_filt)(INTFLOAT (*Y)[2], const INTFLOAT (*X_high)[40][2],
const AAC_FLOAT *g_filt, int m_max, intptr_t ixh);
void (*hf_apply_noise[4])(INTFLOAT (*Y)[2], const AAC_FLOAT *s_m,
const AAC_FLOAT *q_filt, int noise,
int kx, int m_max);
} SBRDSPContext;
extern const float ff_sbr_noise_table[][2];
extern const INTFLOAT AAC_RENAME(ff_sbr_noise_table)[][2];
void ff_sbrdsp_init(SBRDSPContext *s);
void AAC_RENAME(ff_sbrdsp_init)(SBRDSPContext *s);
void ff_sbrdsp_init_arm(SBRDSPContext *s);
void ff_sbrdsp_init_x86(SBRDSPContext *s);
void ff_sbrdsp_init_mips(SBRDSPContext *s);
......
/*
* AAC Spectral Band Replication decoding functions
* Copyright (c) 2008-2009 Robert Swain ( rob opendot cl )
* Copyright (c) 2009-2010 Alex Converse <alex.converse@gmail.com>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Note: Rounding-to-nearest used unless otherwise stated
*
*/
#define USE_FIXED 1
#include "aac.h"
#include "config.h"
#include "libavutil/attributes.h"
#include "libavutil/intfloat.h"
#include "sbrdsp.h"
static SoftFloat sbr_sum_square_c(int (*x)[2], int n)
{
SoftFloat ret;
int64_t accu = 0;
int i, nz, round;
for (i = 0; i < n; i += 2) {
accu += (int64_t)x[i + 0][0] * x[i + 0][0];
accu += (int64_t)x[i + 0][1] * x[i + 0][1];
accu += (int64_t)x[i + 1][0] * x[i + 1][0];
accu += (int64_t)x[i + 1][1] * x[i + 1][1];
}
i = (int)(accu >> 32);
if (i == 0) {
nz = 1;
} else {
nz = 0;
while (FFABS(i) < 0x40000000) {
i <<= 1;
nz++;
}
nz = 32 - nz;
}
round = 1 << (nz-1);
i = (int)((accu + round) >> nz);
i >>= 1;
ret = av_int2sf(i, 15 - nz);
return ret;
}
static void sbr_neg_odd_64_c(int *x)
{
int i;
for (i = 1; i < 64; i += 2)
x[i] = -x[i];
}
static void sbr_qmf_pre_shuffle_c(int *z)
{
int k;
z[64] = z[0];
z[65] = z[1];
for (k = 1; k < 32; k++) {
z[64+2*k ] = -z[64 - k];
z[64+2*k+1] = z[ k + 1];
}
}
static void sbr_qmf_post_shuffle_c(int W[32][2], const int *z)
{
int k;
for (k = 0; k < 32; k++) {
W[k][0] = -z[63-k];
W[k][1] = z[k];
}
}
static void sbr_qmf_deint_neg_c(int *v, const int *src)
{
int i;
for (i = 0; i < 32; i++) {
v[ i] = ( src[63 - 2*i ] + 0x10) >> 5;
v[63 - i] = (-src[63 - 2*i - 1] + 0x10) >> 5;
}
}
static av_always_inline SoftFloat autocorr_calc(int64_t accu)
{
int nz, mant, expo, round;
int i = (int)(accu >> 32);
if (i == 0) {
nz = 1;
} else {
nz = 0;
while (FFABS(i) < 0x40000000) {
i <<= 1;
nz++;
}
nz = 32-nz;
}
round = 1 << (nz-1);
mant = (int)((accu + round) >> nz);
mant = (mant + 0x40)>>7;
mant <<= 6;
expo = nz + 15;
return av_int2sf(mant, 30 - expo);
}
static av_always_inline void autocorrelate(const int x[40][2], SoftFloat phi[3][2][2], int lag)
{
int i;
int64_t real_sum, imag_sum;
int64_t accu_re = 0, accu_im = 0;
if (lag) {
for (i = 1; i < 38; i++) {
accu_re += (int64_t)x[i][0] * x[i+lag][0];
accu_re += (int64_t)x[i][1] * x[i+lag][1];
accu_im += (int64_t)x[i][0] * x[i+lag][1];
accu_im -= (int64_t)x[i][1] * x[i+lag][0];
}
real_sum = accu_re;
imag_sum = accu_im;
accu_re += (int64_t)x[ 0][0] * x[lag][0];
accu_re += (int64_t)x[ 0][1] * x[lag][1];
accu_im += (int64_t)x[ 0][0] * x[lag][1];
accu_im -= (int64_t)x[ 0][1] * x[lag][0];
phi[2-lag][1][0] = autocorr_calc(accu_re);
phi[2-lag][1][1] = autocorr_calc(accu_im);
if (lag == 1) {
accu_re = real_sum;
accu_im = imag_sum;
accu_re += (int64_t)x[38][0] * x[39][0];
accu_re += (int64_t)x[38][1] * x[39][1];
accu_im += (int64_t)x[38][0] * x[39][1];
accu_im -= (int64_t)x[38][1] * x[39][0];
phi[0][0][0] = autocorr_calc(accu_re);
phi[0][0][1] = autocorr_calc(accu_im);
}
} else {
for (i = 1; i < 38; i++) {
accu_re += (int64_t)x[i][0] * x[i][0];
accu_re += (int64_t)x[i][1] * x[i][1];
}
real_sum = accu_re;
accu_re += (int64_t)x[ 0][0] * x[ 0][0];
accu_re += (int64_t)x[ 0][1] * x[ 0][1];
phi[2][1][0] = autocorr_calc(accu_re);
accu_re = real_sum;
accu_re += (int64_t)x[38][0] * x[38][0];
accu_re += (int64_t)x[38][1] * x[38][1];
phi[1][0][0] = autocorr_calc(accu_re);
}
}
static void sbr_autocorrelate_c(const int x[40][2], SoftFloat phi[3][2][2])
{
autocorrelate(x, phi, 0);
autocorrelate(x, phi, 1);
autocorrelate(x, phi, 2);
}
static void sbr_hf_gen_c(int (*X_high)[2], const int (*X_low)[2],
const int alpha0[2], const int alpha1[2],
int bw, int start, int end)
{
int alpha[4];
int i;
int64_t accu;
accu = (int64_t)alpha0[0] * bw;
alpha[2] = (int)((accu + 0x40000000) >> 31);
accu = (int64_t)alpha0[1] * bw;
alpha[3] = (int)((accu + 0x40000000) >> 31);
accu = (int64_t)bw * bw;
bw = (int)((accu + 0x40000000) >> 31);
accu = (int64_t)alpha1[0] * bw;
alpha[0] = (int)((accu + 0x40000000) >> 31);
accu = (int64_t)alpha1[1] * bw;
alpha[1] = (int)((accu + 0x40000000) >> 31);
for (i = start; i < end; i++) {
accu = (int64_t)X_low[i][0] * 0x20000000;
accu += (int64_t)X_low[i - 2][0] * alpha[0];
accu -= (int64_t)X_low[i - 2][1] * alpha[1];
accu += (int64_t)X_low[i - 1][0] * alpha[2];
accu -= (int64_t)X_low[i - 1][1] * alpha[3];
X_high[i][0] = (int)((accu + 0x10000000) >> 29);
accu = (int64_t)X_low[i][1] * 0x20000000;
accu += (int64_t)X_low[i - 2][1] * alpha[0];
accu += (int64_t)X_low[i - 2][0] * alpha[1];
accu += (int64_t)X_low[i - 1][1] * alpha[2];
accu += (int64_t)X_low[i - 1][0] * alpha[3];
X_high[i][1] = (int)((accu + 0x10000000) >> 29);
}
}
static void sbr_hf_g_filt_c(int (*Y)[2], const int (*X_high)[40][2],
const SoftFloat *g_filt, int m_max, intptr_t ixh)
{
int m, r;
int64_t accu;
for (m = 0; m < m_max; m++) {
r = 1 << (22-g_filt[m].exp);
accu = (int64_t)X_high[m][ixh][0] * ((g_filt[m].mant + 0x40)>>7);
Y[m][0] = (int)((accu + r) >> (23-g_filt[m].exp));
accu = (int64_t)X_high[m][ixh][1] * ((g_filt[m].mant + 0x40)>>7);
Y[m][1] = (int)((accu + r) >> (23-g_filt[m].exp));
}
}
static av_always_inline void sbr_hf_apply_noise(int (*Y)[2],
const SoftFloat *s_m,
const SoftFloat *q_filt,
int noise,
int phi_sign0,
int phi_sign1,
int m_max)
{
int m;
for (m = 0; m < m_max; m++) {
int y0 = Y[m][0];
int y1 = Y[m][1];
noise = (noise + 1) & 0x1ff;
if (s_m[m].mant) {
int shift, round;
shift = 22 - s_m[m].exp;
if (shift < 30) {
round = 1 << (shift-1);
y0 += (s_m[m].mant * phi_sign0 + round) >> shift;
y1 += (s_m[m].mant * phi_sign1 + round) >> shift;
}
} else {
int shift, round, tmp;
int64_t accu;
shift = 22 - q_filt[m].exp;
if (shift < 30) {
round = 1 << (shift-1);
accu = (int64_t)q_filt[m].mant * ff_sbr_noise_table_fixed[noise][0];
tmp = (int)((accu + 0x40000000) >> 31);
y0 += (tmp + round) >> shift;
accu = (int64_t)q_filt[m].mant * ff_sbr_noise_table_fixed[noise][1];
tmp = (int)((accu + 0x40000000) >> 31);
y1 += (tmp + round) >> shift;
}
}
Y[m][0] = y0;
Y[m][1] = y1;
phi_sign1 = -phi_sign1;
}
}
#include "sbrdsp_template.c"
......@@ -20,55 +20,55 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
static void sbr_sum64x5_c(float *z)
static void sbr_sum64x5_c(INTFLOAT *z)
{
int k;
for (k = 0; k < 64; k++) {
float f = z[k] + z[k + 64] + z[k + 128] + z[k + 192] + z[k + 256];
INTFLOAT f = z[k] + z[k + 64] + z[k + 128] + z[k + 192] + z[k + 256];
z[k] = f;
}
}
static void sbr_qmf_deint_bfly_c(float *v, const float *src0, const float *src1)
static void sbr_qmf_deint_bfly_c(INTFLOAT *v, const INTFLOAT *src0, const INTFLOAT *src1)
{
int i;
for (i = 0; i < 64; i++) {
v[ i] = src0[i] - src1[63 - i];
v[127 - i] = src0[i] + src1[63 - i];
v[ i] = AAC_SRA_R((src0[i] - src1[63 - i]), 5);
v[127 - i] = AAC_SRA_R((src0[i] + src1[63 - i]), 5);
}
}
static void sbr_hf_apply_noise_0(float (*Y)[2], const float *s_m,
const float *q_filt, int noise,
static void sbr_hf_apply_noise_0(INTFLOAT (*Y)[2], const AAC_FLOAT *s_m,
const AAC_FLOAT *q_filt, int noise,
int kx, int m_max)
{
sbr_hf_apply_noise(Y, s_m, q_filt, noise, 1.0, 0.0, m_max);
sbr_hf_apply_noise(Y, s_m, q_filt, noise, (INTFLOAT)1.0, (INTFLOAT)0.0, m_max);
}
static void sbr_hf_apply_noise_1(float (*Y)[2], const float *s_m,
const float *q_filt, int noise,
static void sbr_hf_apply_noise_1(INTFLOAT (*Y)[2], const AAC_FLOAT *s_m,
const AAC_FLOAT *q_filt, int noise,
int kx, int m_max)
{
float phi_sign = 1 - 2 * (kx & 1);
sbr_hf_apply_noise(Y, s_m, q_filt, noise, 0.0, phi_sign, m_max);
INTFLOAT phi_sign = 1 - 2 * (kx & 1);
sbr_hf_apply_noise(Y, s_m, q_filt, noise, (INTFLOAT)0.0, phi_sign, m_max);
}
static void sbr_hf_apply_noise_2(float (*Y)[2], const float *s_m,
const float *q_filt, int noise,
static void sbr_hf_apply_noise_2(INTFLOAT (*Y)[2], const AAC_FLOAT *s_m,
const AAC_FLOAT *q_filt, int noise,
int kx, int m_max)
{
sbr_hf_apply_noise(Y, s_m, q_filt, noise, -1.0, 0.0, m_max);
sbr_hf_apply_noise(Y, s_m, q_filt, noise, (INTFLOAT)-1.0, (INTFLOAT)0.0, m_max);
}
static void sbr_hf_apply_noise_3(float (*Y)[2], const float *s_m,
const float *q_filt, int noise,
static void sbr_hf_apply_noise_3(INTFLOAT (*Y)[2], const AAC_FLOAT *s_m,
const AAC_FLOAT *q_filt, int noise,
int kx, int m_max)
{
float phi_sign = 1 - 2 * (kx & 1);
sbr_hf_apply_noise(Y, s_m, q_filt, noise, 0.0, -phi_sign, m_max);
INTFLOAT phi_sign = 1 - 2 * (kx & 1);
sbr_hf_apply_noise(Y, s_m, q_filt, noise, (INTFLOAT)0.0, -phi_sign, m_max);
}
av_cold void ff_sbrdsp_init(SBRDSPContext *s)
av_cold void AAC_RENAME(ff_sbrdsp_init)(SBRDSPContext *s)
{
s->sum64x5 = sbr_sum64x5_c;
s->sum_square = sbr_sum_square_c;
......@@ -86,10 +86,12 @@ av_cold void ff_sbrdsp_init(SBRDSPContext *s)
s->hf_apply_noise[2] = sbr_hf_apply_noise_2;
s->hf_apply_noise[3] = sbr_hf_apply_noise_3;
#if !USE_FIXED
if (ARCH_ARM)
ff_sbrdsp_init_arm(s);
if (ARCH_X86)
ff_sbrdsp_init_x86(s);
if (ARCH_MIPS)
ff_sbrdsp_init_mips(s);
#endif /* !USE_FIXED */
}
......@@ -36,6 +36,14 @@ typedef struct SoftFloat{
int32_t exp;
}SoftFloat;
static const SoftFloat FLOAT_0 = { 0, 0};
static const SoftFloat FLOAT_05 = { 0x20000000, 0};
static const SoftFloat FLOAT_1 = { 0x20000000, 1};
static const SoftFloat FLOAT_EPSILON = { 0x29F16B12, -16};
static const SoftFloat FLOAT_1584893192 = { 0x32B771ED, 1};
static const SoftFloat FLOAT_100000 = { 0x30D40000, 17};
static const SoftFloat FLOAT_0999999 = { 0x3FFFFBCE, 0};
static inline av_const double av_sf2double(SoftFloat v) {
v.exp -= ONE_BITS +1;
if(v.exp > 0) return (double)v.mant * (double)(1 << v.exp);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment