mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
avcodec: Implementation of AAC_fixed_decoder (SBR-module)
Add fixed poind code. Signed-off-by: Nedeljko Babic <nedeljko.babic@imgtec.com> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
parent
b0414da90d
commit
f85bc147fb
@ -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"
|
||||
|
78
libavcodec/aac_defines.h
Normal file
78
libavcodec/aac_defines.h
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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);
|
||||
|
||||
|
586
libavcodec/aacsbr_fixed.c
Normal file
586
libavcodec/aacsbr_fixed.c
Normal file
@ -0,0 +1,586 @@
|
||||
/*
|
||||
* Copyright (c) 2013
|
||||
* MIPS Technologies, Inc., California.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* AAC Spectral Band Replication decoding functions (fixed-point)
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* AAC Spectral Band Replication decoding functions (fixed-point)
|
||||
* Note: Rounding-to-nearest used unless otherwise stated
|
||||
* @author Robert Swain ( rob opendot cl )
|
||||
* @author Stanislav Ocovaj ( stanislav.ocovaj imgtec com )
|
||||
*/
|
||||
#define USE_FIXED 1
|
||||
|
||||
#include "aac.h"
|
||||
#include "sbr.h"
|
||||
#include "aacsbr.h"
|
||||
#include "aacsbrdata.h"
|
||||
#include "aacsbr_fixed_tablegen.h"
|
||||
#include "fft.h"
|
||||
#include "aacps.h"
|
||||
#include "sbrdsp.h"
|
||||
#include "libavutil/internal.h"
|
||||
#include "libavutil/libm.h"
|
||||
#include "libavutil/avassert.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
|
||||
static VLC vlc_sbr[10];
|
||||
static void aacsbr_func_ptr_init(AACSBRContext *c);
|
||||
static const int CONST_LN2 = Q31(0.6931471806/256); // ln(2)/256
|
||||
static const int CONST_RECIP_LN2 = Q31(0.7213475204); // 0.5/ln(2)
|
||||
static const int CONST_SQRT2 = Q30(0.7071067812); // sqrt(2)/2
|
||||
static const int CONST_076923 = Q31(0.76923076923076923077f);
|
||||
|
||||
int fixed_log_table[10] =
|
||||
{
|
||||
Q31(1.0/2), Q31(1.0/3), Q31(1.0/4), Q31(1.0/5), Q31(1.0/6),
|
||||
Q31(1.0/7), Q31(1.0/8), Q31(1.0/9), Q31(1.0/10), Q31(1.0/11)
|
||||
};
|
||||
|
||||
static int fixed_log(int x)
|
||||
{
|
||||
int i, ret, xpow, tmp;
|
||||
|
||||
ret = x;
|
||||
xpow = x;
|
||||
for (i=0; i<10; i+=2){
|
||||
xpow = (int)(((int64_t)xpow * x + 0x40000000) >> 31);
|
||||
tmp = (int)(((int64_t)xpow * fixed_log_table[i] + 0x40000000) >> 31);
|
||||
ret -= tmp;
|
||||
|
||||
xpow = (int)(((int64_t)xpow * x + 0x40000000) >> 31);
|
||||
tmp = (int)(((int64_t)xpow * fixed_log_table[i+1] + 0x40000000) >> 31);
|
||||
ret += tmp;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int fixed_exp_table[7] =
|
||||
{
|
||||
Q31(1.0/2), Q31(1.0/6), Q31(1.0/24), Q31(1.0/120),
|
||||
Q31(1.0/720), Q31(1.0/5040), Q31(1.0/40320)
|
||||
};
|
||||
|
||||
static int fixed_exp(int x)
|
||||
{
|
||||
int i, ret, xpow, tmp;
|
||||
|
||||
ret = 0x800000 + x;
|
||||
xpow = x;
|
||||
for (i=0; i<7; i++){
|
||||
xpow = (int)(((int64_t)xpow * x + 0x400000) >> 23);
|
||||
tmp = (int)(((int64_t)xpow * fixed_exp_table[i] + 0x40000000) >> 31);
|
||||
ret += tmp;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void make_bands(int16_t* bands, int start, int stop, int num_bands)
|
||||
{
|
||||
int k, previous, present;
|
||||
int base, prod, nz = 0;
|
||||
|
||||
base = (stop << 23) / start;
|
||||
while (base < 0x40000000){
|
||||
base <<= 1;
|
||||
nz++;
|
||||
}
|
||||
base = fixed_log(base - 0x80000000);
|
||||
base = (((base + 0x80) >> 8) + (8-nz)*CONST_LN2) / num_bands;
|
||||
base = fixed_exp(base);
|
||||
|
||||
previous = start;
|
||||
prod = start << 23;
|
||||
|
||||
for (k = 0; k < num_bands-1; k++) {
|
||||
prod = (int)(((int64_t)prod * base + 0x400000) >> 23);
|
||||
present = (prod + 0x400000) >> 23;
|
||||
bands[k] = present - previous;
|
||||
previous = present;
|
||||
}
|
||||
bands[num_bands-1] = stop - previous;
|
||||
}
|
||||
|
||||
/// Dequantization and stereo decoding (14496-3 sp04 p203)
|
||||
static void sbr_dequant(SpectralBandReplication *sbr, int id_aac)
|
||||
{
|
||||
int k, e;
|
||||
int ch;
|
||||
|
||||
if (id_aac == TYPE_CPE && sbr->bs_coupling) {
|
||||
int alpha = sbr->data[0].bs_amp_res ? 2 : 1;
|
||||
int pan_offset = sbr->data[0].bs_amp_res ? 12 : 24;
|
||||
for (e = 1; e <= sbr->data[0].bs_num_env; e++) {
|
||||
for (k = 0; k < sbr->n[sbr->data[0].bs_freq_res[e]]; k++) {
|
||||
SoftFloat temp1, temp2, fac;
|
||||
|
||||
temp1.exp = sbr->data[0].env_facs[e][k].mant * alpha + 14;
|
||||
if (temp1.exp & 1)
|
||||
temp1.mant = 759250125;
|
||||
else
|
||||
temp1.mant = 0x20000000;
|
||||
temp1.exp = (temp1.exp >> 1) + 1;
|
||||
|
||||
temp2.exp = (pan_offset - sbr->data[1].env_facs[e][k].mant) * alpha;
|
||||
if (temp2.exp & 1)
|
||||
temp2.mant = 759250125;
|
||||
else
|
||||
temp2.mant = 0x20000000;
|
||||
temp2.exp = (temp2.exp >> 1) + 1;
|
||||
fac = av_div_sf(temp1, av_add_sf(FLOAT_1, temp2));
|
||||
sbr->data[0].env_facs[e][k] = fac;
|
||||
sbr->data[1].env_facs[e][k] = av_mul_sf(fac, temp2);
|
||||
}
|
||||
}
|
||||
for (e = 1; e <= sbr->data[0].bs_num_noise; e++) {
|
||||
for (k = 0; k < sbr->n_q; k++) {
|
||||
SoftFloat temp1, temp2, fac;
|
||||
|
||||
temp1.exp = NOISE_FLOOR_OFFSET - \
|
||||
sbr->data[0].noise_facs[e][k].mant + 2;
|
||||
temp1.mant = 0x20000000;
|
||||
temp2.exp = 12 - sbr->data[1].noise_facs[e][k].mant + 1;
|
||||
temp2.mant = 0x20000000;
|
||||
fac = av_div_sf(temp1, av_add_sf(FLOAT_1, temp2));
|
||||
sbr->data[0].noise_facs[e][k] = fac;
|
||||
sbr->data[1].noise_facs[e][k] = av_mul_sf(fac, temp2);
|
||||
}
|
||||
}
|
||||
} else { // SCE or one non-coupled CPE
|
||||
for (ch = 0; ch < (id_aac == TYPE_CPE) + 1; ch++) {
|
||||
int alpha = sbr->data[ch].bs_amp_res ? 2 : 1;
|
||||
for (e = 1; e <= sbr->data[ch].bs_num_env; e++)
|
||||
for (k = 0; k < sbr->n[sbr->data[ch].bs_freq_res[e]]; k++){
|
||||
SoftFloat temp1;
|
||||
|
||||
temp1.exp = alpha * sbr->data[ch].env_facs[e][k].mant + 12;
|
||||
if (temp1.exp & 1)
|
||||
temp1.mant = 759250125;
|
||||
else
|
||||
temp1.mant = 0x20000000;
|
||||
temp1.exp = (temp1.exp >> 1) + 1;
|
||||
|
||||
sbr->data[ch].env_facs[e][k] = temp1;
|
||||
}
|
||||
for (e = 1; e <= sbr->data[ch].bs_num_noise; e++)
|
||||
for (k = 0; k < sbr->n_q; k++){
|
||||
sbr->data[ch].noise_facs[e][k].exp = NOISE_FLOOR_OFFSET - \
|
||||
sbr->data[ch].noise_facs[e][k].mant + 1;
|
||||
sbr->data[ch].noise_facs[e][k].mant = 0x20000000;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** High Frequency Generation (14496-3 sp04 p214+) and Inverse Filtering
|
||||
* (14496-3 sp04 p214)
|
||||
* Warning: This routine does not seem numerically stable.
|
||||
*/
|
||||
static void sbr_hf_inverse_filter(SBRDSPContext *dsp,
|
||||
int (*alpha0)[2], int (*alpha1)[2],
|
||||
const int X_low[32][40][2], int k0)
|
||||
{
|
||||
int k;
|
||||
int shift, round;
|
||||
|
||||
for (k = 0; k < k0; k++) {
|
||||
SoftFloat phi[3][2][2];
|
||||
SoftFloat a00, a01, a10, a11;
|
||||
SoftFloat dk;
|
||||
|
||||
dsp->autocorrelate(X_low[k], phi);
|
||||
|
||||
dk = av_sub_sf(av_mul_sf(phi[2][1][0], phi[1][0][0]),
|
||||
av_mul_sf(av_add_sf(av_mul_sf(phi[1][1][0], phi[1][1][0]),
|
||||
av_mul_sf(phi[1][1][1], phi[1][1][1])), FLOAT_0999999));
|
||||
|
||||
if (!dk.mant) {
|
||||
a10 = FLOAT_0;
|
||||
a11 = FLOAT_0;
|
||||
} else {
|
||||
SoftFloat temp_real, temp_im;
|
||||
temp_real = av_sub_sf(av_sub_sf(av_mul_sf(phi[0][0][0], phi[1][1][0]),
|
||||
av_mul_sf(phi[0][0][1], phi[1][1][1])),
|
||||
av_mul_sf(phi[0][1][0], phi[1][0][0]));
|
||||
temp_im = av_sub_sf(av_add_sf(av_mul_sf(phi[0][0][0], phi[1][1][1]),
|
||||
av_mul_sf(phi[0][0][1], phi[1][1][0])),
|
||||
av_mul_sf(phi[0][1][1], phi[1][0][0]));
|
||||
|
||||
a10 = av_div_sf(temp_real, dk);
|
||||
a11 = av_div_sf(temp_im, dk);
|
||||
}
|
||||
|
||||
if (!phi[1][0][0].mant) {
|
||||
a00 = FLOAT_0;
|
||||
a01 = FLOAT_0;
|
||||
} else {
|
||||
SoftFloat temp_real, temp_im;
|
||||
temp_real = av_add_sf(phi[0][0][0],
|
||||
av_add_sf(av_mul_sf(a10, phi[1][1][0]),
|
||||
av_mul_sf(a11, phi[1][1][1])));
|
||||
temp_im = av_add_sf(phi[0][0][1],
|
||||
av_sub_sf(av_mul_sf(a11, phi[1][1][0]),
|
||||
av_mul_sf(a10, phi[1][1][1])));
|
||||
|
||||
temp_real.mant = -temp_real.mant;
|
||||
temp_im.mant = -temp_im.mant;
|
||||
a00 = av_div_sf(temp_real, phi[1][0][0]);
|
||||
a01 = av_div_sf(temp_im, phi[1][0][0]);
|
||||
}
|
||||
|
||||
shift = a00.exp;
|
||||
if (shift >= 3)
|
||||
alpha0[k][0] = 0x7fffffff;
|
||||
else {
|
||||
a00.mant <<= 1;
|
||||
shift = 2-shift;
|
||||
if (shift == 0)
|
||||
alpha0[k][0] = a00.mant;
|
||||
else {
|
||||
round = 1 << (shift-1);
|
||||
alpha0[k][0] = (a00.mant + round) >> shift;
|
||||
}
|
||||
}
|
||||
|
||||
shift = a01.exp;
|
||||
if (shift >= 3)
|
||||
alpha0[k][1] = 0x7fffffff;
|
||||
else {
|
||||
a01.mant <<= 1;
|
||||
shift = 2-shift;
|
||||
if (shift == 0)
|
||||
alpha0[k][1] = a01.mant;
|
||||
else {
|
||||
round = 1 << (shift-1);
|
||||
alpha0[k][1] = (a01.mant + round) >> shift;
|
||||
}
|
||||
}
|
||||
shift = a10.exp;
|
||||
if (shift >= 3)
|
||||
alpha1[k][0] = 0x7fffffff;
|
||||
else {
|
||||
a10.mant <<= 1;
|
||||
shift = 2-shift;
|
||||
if (shift == 0)
|
||||
alpha1[k][0] = a10.mant;
|
||||
else {
|
||||
round = 1 << (shift-1);
|
||||
alpha1[k][0] = (a10.mant + round) >> shift;
|
||||
}
|
||||
}
|
||||
|
||||
shift = a11.exp;
|
||||
if (shift >= 3)
|
||||
alpha1[k][1] = 0x7fffffff;
|
||||
else {
|
||||
a11.mant <<= 1;
|
||||
shift = 2-shift;
|
||||
if (shift == 0)
|
||||
alpha1[k][1] = a11.mant;
|
||||
else {
|
||||
round = 1 << (shift-1);
|
||||
alpha1[k][1] = (a11.mant + round) >> shift;
|
||||
}
|
||||
}
|
||||
|
||||
shift = (int)(((int64_t)(alpha1[k][0]>>1) * (alpha1[k][0]>>1) + \
|
||||
(int64_t)(alpha1[k][1]>>1) * (alpha1[k][1]>>1) + \
|
||||
0x40000000) >> 31);
|
||||
if (shift >= 0x20000000){
|
||||
alpha1[k][0] = 0;
|
||||
alpha1[k][1] = 0;
|
||||
alpha0[k][0] = 0;
|
||||
alpha0[k][1] = 0;
|
||||
}
|
||||
|
||||
shift = (int)(((int64_t)(alpha0[k][0]>>1) * (alpha0[k][0]>>1) + \
|
||||
(int64_t)(alpha0[k][1]>>1) * (alpha0[k][1]>>1) + \
|
||||
0x40000000) >> 31);
|
||||
if (shift >= 0x20000000){
|
||||
alpha1[k][0] = 0;
|
||||
alpha1[k][1] = 0;
|
||||
alpha0[k][0] = 0;
|
||||
alpha0[k][1] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Chirp Factors (14496-3 sp04 p214)
|
||||
static void sbr_chirp(SpectralBandReplication *sbr, SBRData *ch_data)
|
||||
{
|
||||
int i;
|
||||
int new_bw;
|
||||
static const int bw_tab[] = { 0, 1610612736, 1932735283, 2104533975 };
|
||||
int64_t accu;
|
||||
|
||||
for (i = 0; i < sbr->n_q; i++) {
|
||||
if (ch_data->bs_invf_mode[0][i] + ch_data->bs_invf_mode[1][i] == 1)
|
||||
new_bw = 1288490189;
|
||||
else
|
||||
new_bw = bw_tab[ch_data->bs_invf_mode[0][i]];
|
||||
|
||||
if (new_bw < ch_data->bw_array[i]){
|
||||
accu = (int64_t)new_bw * 1610612736;
|
||||
accu += (int64_t)ch_data->bw_array[i] * 0x20000000;
|
||||
new_bw = (int)((accu + 0x40000000) >> 31);
|
||||
} else {
|
||||
accu = (int64_t)new_bw * 1946157056;
|
||||
accu += (int64_t)ch_data->bw_array[i] * 201326592;
|
||||
new_bw = (int)((accu + 0x40000000) >> 31);
|
||||
}
|
||||
ch_data->bw_array[i] = new_bw < 0x2000000 ? 0 : new_bw;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculation of levels of additional HF signal components (14496-3 sp04 p219)
|
||||
* and Calculation of gain (14496-3 sp04 p219)
|
||||
*/
|
||||
static void sbr_gain_calc(AACContext *ac, SpectralBandReplication *sbr,
|
||||
SBRData *ch_data, const int e_a[2])
|
||||
{
|
||||
int e, k, m;
|
||||
// max gain limits : -3dB, 0dB, 3dB, inf dB (limiter off)
|
||||
static const SoftFloat limgain[4] = { { 760155524, 0 }, { 0x20000000, 1 },
|
||||
{ 758351638, 1 }, { 625000000, 34 } };
|
||||
|
||||
for (e = 0; e < ch_data->bs_num_env; e++) {
|
||||
int delta = !((e == e_a[1]) || (e == e_a[0]));
|
||||
for (k = 0; k < sbr->n_lim; k++) {
|
||||
SoftFloat gain_boost, gain_max;
|
||||
SoftFloat sum[2] = { { 0, 0}, { 0, 0 } };
|
||||
for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) {
|
||||
const SoftFloat temp = av_div_sf(sbr->e_origmapped[e][m],
|
||||
av_add_sf(FLOAT_1, sbr->q_mapped[e][m]));
|
||||
sbr->q_m[e][m] = av_sqrt_sf(av_mul_sf(temp, sbr->q_mapped[e][m]));
|
||||
sbr->s_m[e][m] = av_sqrt_sf(av_mul_sf(temp, av_int2sf(ch_data->s_indexmapped[e + 1][m], 0)));
|
||||
if (!sbr->s_mapped[e][m]) {
|
||||
if (delta) {
|
||||
sbr->gain[e][m] = av_sqrt_sf(av_div_sf(sbr->e_origmapped[e][m],
|
||||
av_mul_sf(av_add_sf(FLOAT_1, sbr->e_curr[e][m]),
|
||||
av_add_sf(FLOAT_1, sbr->q_mapped[e][m]))));
|
||||
} else {
|
||||
sbr->gain[e][m] = av_sqrt_sf(av_div_sf(sbr->e_origmapped[e][m],
|
||||
av_add_sf(FLOAT_1, sbr->e_curr[e][m])));
|
||||
}
|
||||
} else {
|
||||
sbr->gain[e][m] = av_sqrt_sf(
|
||||
av_div_sf(
|
||||
av_mul_sf(sbr->e_origmapped[e][m], sbr->q_mapped[e][m]),
|
||||
av_mul_sf(
|
||||
av_add_sf(FLOAT_1, sbr->e_curr[e][m]),
|
||||
av_add_sf(FLOAT_1, sbr->q_mapped[e][m]))));
|
||||
}
|
||||
}
|
||||
for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) {
|
||||
sum[0] = av_add_sf(sum[0], sbr->e_origmapped[e][m]);
|
||||
sum[1] = av_add_sf(sum[1], sbr->e_curr[e][m]);
|
||||
}
|
||||
gain_max = av_mul_sf(limgain[sbr->bs_limiter_gains],
|
||||
av_sqrt_sf(
|
||||
av_div_sf(
|
||||
av_add_sf(FLOAT_EPSILON, sum[0]),
|
||||
av_add_sf(FLOAT_EPSILON, sum[1]))));
|
||||
if (av_gt_sf(gain_max, FLOAT_100000))
|
||||
gain_max = FLOAT_100000;
|
||||
for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) {
|
||||
SoftFloat q_m_max = av_div_sf(
|
||||
av_mul_sf(sbr->q_m[e][m], gain_max),
|
||||
sbr->gain[e][m]);
|
||||
if (av_gt_sf(sbr->q_m[e][m], q_m_max))
|
||||
sbr->q_m[e][m] = q_m_max;
|
||||
if (av_gt_sf(sbr->gain[e][m], gain_max))
|
||||
sbr->gain[e][m] = gain_max;
|
||||
}
|
||||
sum[0] = sum[1] = FLOAT_0;
|
||||
for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) {
|
||||
sum[0] = av_add_sf(sum[0], sbr->e_origmapped[e][m]);
|
||||
sum[1] = av_add_sf(sum[1],
|
||||
av_mul_sf(
|
||||
av_mul_sf(sbr->e_curr[e][m],
|
||||
sbr->gain[e][m]),
|
||||
sbr->gain[e][m]));
|
||||
sum[1] = av_add_sf(sum[1],
|
||||
av_mul_sf(sbr->s_m[e][m], sbr->s_m[e][m]));
|
||||
if (delta && !sbr->s_m[e][m].mant)
|
||||
sum[1] = av_add_sf(sum[1],
|
||||
av_mul_sf(sbr->q_m[e][m], sbr->q_m[e][m]));
|
||||
}
|
||||
gain_boost = av_sqrt_sf(
|
||||
av_div_sf(
|
||||
av_add_sf(FLOAT_EPSILON, sum[0]),
|
||||
av_add_sf(FLOAT_EPSILON, sum[1])));
|
||||
if (av_gt_sf(gain_boost, FLOAT_1584893192))
|
||||
gain_boost = FLOAT_1584893192;
|
||||
|
||||
for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) {
|
||||
sbr->gain[e][m] = av_mul_sf(sbr->gain[e][m], gain_boost);
|
||||
sbr->q_m[e][m] = av_mul_sf(sbr->q_m[e][m], gain_boost);
|
||||
sbr->s_m[e][m] = av_mul_sf(sbr->s_m[e][m], gain_boost);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Assembling HF Signals (14496-3 sp04 p220)
|
||||
static void sbr_hf_assemble(int Y1[38][64][2],
|
||||
const int X_high[64][40][2],
|
||||
SpectralBandReplication *sbr, SBRData *ch_data,
|
||||
const int e_a[2])
|
||||
{
|
||||
int e, i, j, m;
|
||||
const int h_SL = 4 * !sbr->bs_smoothing_mode;
|
||||
const int kx = sbr->kx[1];
|
||||
const int m_max = sbr->m[1];
|
||||
static const SoftFloat h_smooth[5] = {
|
||||
{ 715827883, -1 },
|
||||
{ 647472402, -1 },
|
||||
{ 937030863, -2 },
|
||||
{ 989249804, -3 },
|
||||
{ 546843842, -4 },
|
||||
};
|
||||
SoftFloat (*g_temp)[48] = ch_data->g_temp, (*q_temp)[48] = ch_data->q_temp;
|
||||
int indexnoise = ch_data->f_indexnoise;
|
||||
int indexsine = ch_data->f_indexsine;
|
||||
|
||||
if (sbr->reset) {
|
||||
for (i = 0; i < h_SL; i++) {
|
||||
memcpy(g_temp[i + 2*ch_data->t_env[0]], sbr->gain[0], m_max * sizeof(sbr->gain[0][0]));
|
||||
memcpy(q_temp[i + 2*ch_data->t_env[0]], sbr->q_m[0], m_max * sizeof(sbr->q_m[0][0]));
|
||||
}
|
||||
} else if (h_SL) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
memcpy(g_temp[i + 2 * ch_data->t_env[0]],
|
||||
g_temp[i + 2 * ch_data->t_env_num_env_old],
|
||||
sizeof(g_temp[0]));
|
||||
memcpy(q_temp[i + 2 * ch_data->t_env[0]],
|
||||
q_temp[i + 2 * ch_data->t_env_num_env_old],
|
||||
sizeof(q_temp[0]));
|
||||
}
|
||||
}
|
||||
|
||||
for (e = 0; e < ch_data->bs_num_env; e++) {
|
||||
for (i = 2 * ch_data->t_env[e]; i < 2 * ch_data->t_env[e + 1]; i++) {
|
||||
memcpy(g_temp[h_SL + i], sbr->gain[e], m_max * sizeof(sbr->gain[0][0]));
|
||||
memcpy(q_temp[h_SL + i], sbr->q_m[e], m_max * sizeof(sbr->q_m[0][0]));
|
||||
}
|
||||
}
|
||||
|
||||
for (e = 0; e < ch_data->bs_num_env; e++) {
|
||||
for (i = 2 * ch_data->t_env[e]; i < 2 * ch_data->t_env[e + 1]; i++) {
|
||||
SoftFloat g_filt_tab[48];
|
||||
SoftFloat q_filt_tab[48];
|
||||
SoftFloat *g_filt, *q_filt;
|
||||
|
||||
if (h_SL && e != e_a[0] && e != e_a[1]) {
|
||||
g_filt = g_filt_tab;
|
||||
q_filt = q_filt_tab;
|
||||
for (m = 0; m < m_max; m++) {
|
||||
const int idx1 = i + h_SL;
|
||||
g_filt[m].mant = g_filt[m].exp = 0;
|
||||
q_filt[m].mant = q_filt[m].exp = 0;
|
||||
for (j = 0; j <= h_SL; j++) {
|
||||
g_filt[m] = av_add_sf(g_filt[m],
|
||||
av_mul_sf(g_temp[idx1 - j][m],
|
||||
h_smooth[j]));
|
||||
q_filt[m] = av_add_sf(q_filt[m],
|
||||
av_mul_sf(q_temp[idx1 - j][m],
|
||||
h_smooth[j]));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
g_filt = g_temp[i + h_SL];
|
||||
q_filt = q_temp[i];
|
||||
}
|
||||
|
||||
sbr->dsp.hf_g_filt(Y1[i] + kx, X_high + kx, g_filt, m_max,
|
||||
i + ENVELOPE_ADJUSTMENT_OFFSET);
|
||||
|
||||
if (e != e_a[0] && e != e_a[1]) {
|
||||
sbr->dsp.hf_apply_noise[indexsine](Y1[i] + kx, sbr->s_m[e],
|
||||
q_filt, indexnoise,
|
||||
kx, m_max);
|
||||
} else {
|
||||
int idx = indexsine&1;
|
||||
int A = (1-((indexsine+(kx & 1))&2));
|
||||
int B = (A^(-idx)) + idx;
|
||||
int *out = &Y1[i][kx][idx];
|
||||
int shift, round;
|
||||
|
||||
SoftFloat *in = sbr->s_m[e];
|
||||
for (m = 0; m+1 < m_max; m+=2) {
|
||||
shift = 22 - in[m ].exp;
|
||||
round = 1 << (shift-1);
|
||||
out[2*m ] += (in[m ].mant * A + round) >> shift;
|
||||
|
||||
shift = 22 - in[m+1].exp;
|
||||
round = 1 << (shift-1);
|
||||
out[2*m+2] += (in[m+1].mant * B + round) >> shift;
|
||||
}
|
||||
if(m_max&1)
|
||||
{
|
||||
shift = 22 - in[m ].exp;
|
||||
round = 1 << (shift-1);
|
||||
|
||||
out[2*m ] += (in[m ].mant * A + round) >> shift;
|
||||
}
|
||||
}
|
||||
indexnoise = (indexnoise + m_max) & 0x1ff;
|
||||
indexsine = (indexsine + 1) & 3;
|
||||
}
|
||||
}
|
||||
ch_data->f_indexnoise = indexnoise;
|
||||
ch_data->f_indexsine = indexsine;
|
||||
}
|
||||
|
||||
#include "aacsbr_template.c"
|
@ -3,6 +3,10 @@
|
||||
* Copyright (c) 2008-2009 Robert Swain ( rob opendot cl )
|
||||
* Copyright (c) 2009-2010 Alex Converse <alex.converse@gmail.com>
|
||||
*
|
||||
* Fixed point code
|
||||
* Copyright (c) 2013
|
||||
* MIPS Technologies, Inc., California.
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
@ -24,9 +28,11 @@
|
||||
* @file
|
||||
* AAC Spectral Band Replication decoding functions
|
||||
* @author Robert Swain ( rob opendot cl )
|
||||
* @author Stanislav Ocovaj ( stanislav.ocovaj@imgtec.com )
|
||||
* @author Zoran Basaric ( zoran.basaric@imgtec.com )
|
||||
*/
|
||||
|
||||
av_cold void ff_aac_sbr_init(void)
|
||||
av_cold void AAC_RENAME(ff_aac_sbr_init)(void)
|
||||
{
|
||||
static const struct {
|
||||
const void *sbr_codes, *sbr_bits;
|
||||
@ -72,7 +78,7 @@ static void sbr_turnoff(SpectralBandReplication *sbr) {
|
||||
memset(&sbr->spectrum_params, -1, sizeof(SpectrumParameters));
|
||||
}
|
||||
|
||||
av_cold void ff_aac_sbr_ctx_init(AACContext *ac, SpectralBandReplication *sbr)
|
||||
av_cold void AAC_RENAME(ff_aac_sbr_ctx_init)(AACContext *ac, SpectralBandReplication *sbr)
|
||||
{
|
||||
if(sbr->mdct.mdct_bits)
|
||||
return;
|
||||
@ -83,17 +89,17 @@ av_cold void ff_aac_sbr_ctx_init(AACContext *ac, SpectralBandReplication *sbr)
|
||||
/* SBR requires samples to be scaled to +/-32768.0 to work correctly.
|
||||
* mdct scale factors are adjusted to scale up from +/-1.0 at analysis
|
||||
* and scale back down at synthesis. */
|
||||
ff_mdct_init(&sbr->mdct, 7, 1, 1.0 / (64 * 32768.0));
|
||||
ff_mdct_init(&sbr->mdct_ana, 7, 1, -2.0 * 32768.0);
|
||||
AAC_RENAME_32(ff_mdct_init)(&sbr->mdct, 7, 1, 1.0 / (64 * 32768.0));
|
||||
AAC_RENAME_32(ff_mdct_init)(&sbr->mdct_ana, 7, 1, -2.0 * 32768.0);
|
||||
ff_ps_ctx_init(&sbr->ps);
|
||||
ff_sbrdsp_init(&sbr->dsp);
|
||||
AAC_RENAME(ff_sbrdsp_init)(&sbr->dsp);
|
||||
aacsbr_func_ptr_init(&sbr->c);
|
||||
}
|
||||
|
||||
av_cold void ff_aac_sbr_ctx_close(SpectralBandReplication *sbr)
|
||||
av_cold void AAC_RENAME(ff_aac_sbr_ctx_close)(SpectralBandReplication *sbr)
|
||||
{
|
||||
ff_mdct_end(&sbr->mdct);
|
||||
ff_mdct_end(&sbr->mdct_ana);
|
||||
AAC_RENAME_32(ff_mdct_end)(&sbr->mdct);
|
||||
AAC_RENAME_32(ff_mdct_end)(&sbr->mdct_ana);
|
||||
}
|
||||
|
||||
static int qsort_comparison_function_int16(const void *a, const void *b)
|
||||
@ -115,10 +121,10 @@ static void sbr_make_f_tablelim(SpectralBandReplication *sbr)
|
||||
{
|
||||
int k;
|
||||
if (sbr->bs_limiter_bands > 0) {
|
||||
static const float bands_warped[3] = { 1.32715174233856803909f, //2^(0.49/1.2)
|
||||
1.18509277094158210129f, //2^(0.49/2)
|
||||
1.11987160404675912501f }; //2^(0.49/3)
|
||||
const float lim_bands_per_octave_warped = bands_warped[sbr->bs_limiter_bands - 1];
|
||||
static const INTFLOAT bands_warped[3] = { Q23(1.32715174233856803909f), //2^(0.49/1.2)
|
||||
Q23(1.18509277094158210129f), //2^(0.49/2)
|
||||
Q23(1.11987160404675912501f) }; //2^(0.49/3)
|
||||
const INTFLOAT lim_bands_per_octave_warped = bands_warped[sbr->bs_limiter_bands - 1];
|
||||
int16_t patch_borders[7];
|
||||
uint16_t *in = sbr->f_tablelim + 1, *out = sbr->f_tablelim;
|
||||
|
||||
@ -138,7 +144,11 @@ static void sbr_make_f_tablelim(SpectralBandReplication *sbr)
|
||||
|
||||
sbr->n_lim = sbr->n[0] + sbr->num_patches - 1;
|
||||
while (out < sbr->f_tablelim + sbr->n_lim) {
|
||||
#if USE_FIXED
|
||||
if ((*in << 23) >= *out * lim_bands_per_octave_warped) {
|
||||
#else
|
||||
if (*in >= *out * lim_bands_per_octave_warped) {
|
||||
#endif /* USE_FIXED */
|
||||
*++out = *in++;
|
||||
} else if (*in == *out ||
|
||||
!in_table_int16(patch_borders, sbr->num_patches, *in)) {
|
||||
@ -344,6 +354,9 @@ static int sbr_make_f_master(AACContext *ac, SpectralBandReplication *sbr,
|
||||
int two_regions, num_bands_0;
|
||||
int vdk0_max, vdk1_min;
|
||||
int16_t vk0[49];
|
||||
#if USE_FIXED
|
||||
int tmp, nz = 0;
|
||||
#endif /* USE_FIXED */
|
||||
|
||||
if (49 * sbr->k[2] > 110 * sbr->k[0]) {
|
||||
two_regions = 1;
|
||||
@ -353,7 +366,19 @@ static int sbr_make_f_master(AACContext *ac, SpectralBandReplication *sbr,
|
||||
sbr->k[1] = sbr->k[2];
|
||||
}
|
||||
|
||||
#if USE_FIXED
|
||||
tmp = (sbr->k[1] << 23) / sbr->k[0];
|
||||
while (tmp < 0x40000000) {
|
||||
tmp <<= 1;
|
||||
nz++;
|
||||
}
|
||||
tmp = fixed_log(tmp - 0x80000000);
|
||||
tmp = (int)(((int64_t)tmp * CONST_RECIP_LN2 + 0x20000000) >> 30);
|
||||
tmp = (((tmp + 0x80) >> 8) + ((8 - nz) << 23)) * half_bands;
|
||||
num_bands_0 = ((tmp + 0x400000) >> 23) * 2;
|
||||
#else
|
||||
num_bands_0 = lrintf(half_bands * log2f(sbr->k[1] / (float)sbr->k[0])) * 2;
|
||||
#endif /* USE_FIXED */
|
||||
|
||||
if (num_bands_0 <= 0) { // Requirements (14496-3 sp04 p205)
|
||||
av_log(ac->avctx, AV_LOG_ERROR, "Invalid num_bands_0: %d\n", num_bands_0);
|
||||
@ -378,11 +403,27 @@ static int sbr_make_f_master(AACContext *ac, SpectralBandReplication *sbr,
|
||||
|
||||
if (two_regions) {
|
||||
int16_t vk1[49];
|
||||
#if USE_FIXED
|
||||
int num_bands_1;
|
||||
|
||||
tmp = (sbr->k[2] << 23) / sbr->k[1];
|
||||
nz = 0;
|
||||
while (tmp < 0x40000000) {
|
||||
tmp <<= 1;
|
||||
nz++;
|
||||
}
|
||||
tmp = fixed_log(tmp - 0x80000000);
|
||||
tmp = (int)(((int64_t)tmp * CONST_RECIP_LN2 + 0x20000000) >> 30);
|
||||
tmp = (((tmp + 0x80) >> 8) + ((8 - nz) << 23)) * half_bands;
|
||||
if (spectrum->bs_alter_scale)
|
||||
tmp = (int)(((int64_t)tmp * CONST_076923 + 0x40000000) >> 31);
|
||||
num_bands_1 = ((tmp + 0x400000) >> 23) * 2;
|
||||
#else
|
||||
float invwarp = spectrum->bs_alter_scale ? 0.76923076923076923077f
|
||||
: 1.0f; // bs_alter_scale = {0,1}
|
||||
int num_bands_1 = lrintf(half_bands * invwarp *
|
||||
log2f(sbr->k[2] / (float)sbr->k[1])) * 2;
|
||||
|
||||
#endif /* USE_FIXED */
|
||||
make_bands(vk1+1, sbr->k[1], sbr->k[2], num_bands_1);
|
||||
|
||||
vdk1_min = array_min_int16(vk1 + 1, num_bands_1);
|
||||
@ -487,6 +528,9 @@ static int sbr_hf_calc_npatches(AACContext *ac, SpectralBandReplication *sbr)
|
||||
static int sbr_make_f_derived(AACContext *ac, SpectralBandReplication *sbr)
|
||||
{
|
||||
int k, temp;
|
||||
#if USE_FIXED
|
||||
int nz = 0;
|
||||
#endif /* USE_FIXED */
|
||||
|
||||
sbr->n[1] = sbr->n_master - sbr->spectrum_params.bs_xover_band;
|
||||
sbr->n[0] = (sbr->n[1] + 1) >> 1;
|
||||
@ -511,9 +555,24 @@ static int sbr_make_f_derived(AACContext *ac, SpectralBandReplication *sbr)
|
||||
temp = sbr->n[1] & 1;
|
||||
for (k = 1; k <= sbr->n[0]; k++)
|
||||
sbr->f_tablelow[k] = sbr->f_tablehigh[2 * k - temp];
|
||||
#if USE_FIXED
|
||||
temp = (sbr->k[2] << 23) / sbr->kx[1];
|
||||
while (temp < 0x40000000) {
|
||||
temp <<= 1;
|
||||
nz++;
|
||||
}
|
||||
temp = fixed_log(temp - 0x80000000);
|
||||
temp = (int)(((int64_t)temp * CONST_RECIP_LN2 + 0x20000000) >> 30);
|
||||
temp = (((temp + 0x80) >> 8) + ((8 - nz) << 23)) * sbr->spectrum_params.bs_noise_bands;
|
||||
|
||||
sbr->n_q = (temp + 0x400000) >> 23;
|
||||
if (sbr->n_q < 1)
|
||||
sbr->n_q = 1;
|
||||
#else
|
||||
sbr->n_q = FFMAX(1, lrintf(sbr->spectrum_params.bs_noise_bands *
|
||||
log2f(sbr->k[2] / (float)sbr->kx[1]))); // 0 <= bs_noise_bands <= 3
|
||||
#endif /* USE_FIXED */
|
||||
|
||||
if (sbr->n_q > 5) {
|
||||
av_log(ac->avctx, AV_LOG_ERROR, "Too many noise floor scale factors: %d\n", sbr->n_q);
|
||||
return -1;
|
||||
@ -770,6 +829,31 @@ static void read_sbr_envelope(SpectralBandReplication *sbr, GetBitContext *gb,
|
||||
}
|
||||
}
|
||||
|
||||
#if USE_FIXED
|
||||
for (i = 0; i < ch_data->bs_num_env; i++) {
|
||||
if (ch_data->bs_df_env[i]) {
|
||||
// bs_freq_res[0] == bs_freq_res[bs_num_env] from prev frame
|
||||
if (ch_data->bs_freq_res[i + 1] == ch_data->bs_freq_res[i]) {
|
||||
for (j = 0; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++)
|
||||
ch_data->env_facs[i + 1][j].mant = ch_data->env_facs[i][j].mant + delta * (get_vlc2(gb, t_huff, 9, 3) - t_lav);
|
||||
} else if (ch_data->bs_freq_res[i + 1]) {
|
||||
for (j = 0; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++) {
|
||||
k = (j + odd) >> 1; // find k such that f_tablelow[k] <= f_tablehigh[j] < f_tablelow[k + 1]
|
||||
ch_data->env_facs[i + 1][j].mant = ch_data->env_facs[i][k].mant + delta * (get_vlc2(gb, t_huff, 9, 3) - t_lav);
|
||||
}
|
||||
} else {
|
||||
for (j = 0; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++) {
|
||||
k = j ? 2*j - odd : 0; // find k such that f_tablehigh[k] == f_tablelow[j]
|
||||
ch_data->env_facs[i + 1][j].mant = ch_data->env_facs[i][k].mant + delta * (get_vlc2(gb, t_huff, 9, 3) - t_lav);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ch_data->env_facs[i + 1][0].mant = delta * get_bits(gb, bits); // bs_env_start_value_balance
|
||||
for (j = 1; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++)
|
||||
ch_data->env_facs[i + 1][j].mant = ch_data->env_facs[i + 1][j - 1].mant + delta * (get_vlc2(gb, f_huff, 9, 3) - f_lav);
|
||||
}
|
||||
}
|
||||
#else
|
||||
for (i = 0; i < ch_data->bs_num_env; i++) {
|
||||
if (ch_data->bs_df_env[i]) {
|
||||
// bs_freq_res[0] == bs_freq_res[bs_num_env] from prev frame
|
||||
@ -793,6 +877,7 @@ static void read_sbr_envelope(SpectralBandReplication *sbr, GetBitContext *gb,
|
||||
ch_data->env_facs[i + 1][j] = ch_data->env_facs[i + 1][j - 1] + delta * (get_vlc2(gb, f_huff, 9, 3) - f_lav);
|
||||
}
|
||||
}
|
||||
#endif /* USE_FIXED */
|
||||
|
||||
//assign 0th elements of env_facs from last elements
|
||||
memcpy(ch_data->env_facs[0], ch_data->env_facs[ch_data->bs_num_env],
|
||||
@ -819,6 +904,18 @@ static void read_sbr_noise(SpectralBandReplication *sbr, GetBitContext *gb,
|
||||
f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_3_0DB];
|
||||
}
|
||||
|
||||
#if USE_FIXED
|
||||
for (i = 0; i < ch_data->bs_num_noise; i++) {
|
||||
if (ch_data->bs_df_noise[i]) {
|
||||
for (j = 0; j < sbr->n_q; j++)
|
||||
ch_data->noise_facs[i + 1][j].mant = ch_data->noise_facs[i][j].mant + delta * (get_vlc2(gb, t_huff, 9, 2) - t_lav);
|
||||
} else {
|
||||
ch_data->noise_facs[i + 1][0].mant = delta * get_bits(gb, 5); // bs_noise_start_value_balance or bs_noise_start_value_level
|
||||
for (j = 1; j < sbr->n_q; j++)
|
||||
ch_data->noise_facs[i + 1][j].mant = ch_data->noise_facs[i + 1][j - 1].mant + delta * (get_vlc2(gb, f_huff, 9, 3) - f_lav);
|
||||
}
|
||||
}
|
||||
#else
|
||||
for (i = 0; i < ch_data->bs_num_noise; i++) {
|
||||
if (ch_data->bs_df_noise[i]) {
|
||||
for (j = 0; j < sbr->n_q; j++)
|
||||
@ -829,6 +926,7 @@ static void read_sbr_noise(SpectralBandReplication *sbr, GetBitContext *gb,
|
||||
ch_data->noise_facs[i + 1][j] = ch_data->noise_facs[i + 1][j - 1] + delta * (get_vlc2(gb, f_huff, 9, 3) - f_lav);
|
||||
}
|
||||
}
|
||||
#endif /* USE_FIXED */
|
||||
|
||||
//assign 0th elements of noise_facs from last elements
|
||||
memcpy(ch_data->noise_facs[0], ch_data->noise_facs[ch_data->bs_num_noise],
|
||||
@ -992,7 +1090,7 @@ static void sbr_reset(AACContext *ac, SpectralBandReplication *sbr)
|
||||
*
|
||||
* @return Returns number of bytes consumed from the TYPE_FIL element.
|
||||
*/
|
||||
int ff_decode_sbr_extension(AACContext *ac, SpectralBandReplication *sbr,
|
||||
int AAC_RENAME(ff_decode_sbr_extension)(AACContext *ac, SpectralBandReplication *sbr,
|
||||
GetBitContext *gb_host, int crc, int cnt, int id_aac)
|
||||
{
|
||||
unsigned int num_sbr_bits = 0, num_align_bits;
|
||||
@ -1044,9 +1142,13 @@ int ff_decode_sbr_extension(AACContext *ac, SpectralBandReplication *sbr,
|
||||
* @param W array of complex-valued samples split into subbands
|
||||
*/
|
||||
#ifndef sbr_qmf_analysis
|
||||
#if USE_FIXED
|
||||
static void sbr_qmf_analysis(AVFixedDSPContext *dsp, FFTContext *mdct,
|
||||
#else
|
||||
static void sbr_qmf_analysis(AVFloatDSPContext *dsp, FFTContext *mdct,
|
||||
SBRDSPContext *sbrdsp, const float *in, float *x,
|
||||
float z[320], float W[2][32][32][2], int buf_idx)
|
||||
#endif /* USE_FIXED */
|
||||
SBRDSPContext *sbrdsp, const INTFLOAT *in, INTFLOAT *x,
|
||||
INTFLOAT z[320], INTFLOAT W[2][32][32][2], int buf_idx)
|
||||
{
|
||||
int i;
|
||||
memcpy(x , x+1024, (320-32)*sizeof(x[0]));
|
||||
@ -1069,19 +1171,23 @@ static void sbr_qmf_analysis(AVFloatDSPContext *dsp, FFTContext *mdct,
|
||||
*/
|
||||
#ifndef sbr_qmf_synthesis
|
||||
static void sbr_qmf_synthesis(FFTContext *mdct,
|
||||
#if USE_FIXED
|
||||
SBRDSPContext *sbrdsp, AVFixedDSPContext *dsp,
|
||||
#else
|
||||
SBRDSPContext *sbrdsp, AVFloatDSPContext *dsp,
|
||||
float *out, float X[2][38][64],
|
||||
float mdct_buf[2][64],
|
||||
float *v0, int *v_off, const unsigned int div)
|
||||
#endif /* USE_FIXED */
|
||||
INTFLOAT *out, INTFLOAT X[2][38][64],
|
||||
INTFLOAT mdct_buf[2][64],
|
||||
INTFLOAT *v0, int *v_off, const unsigned int div)
|
||||
{
|
||||
int i, n;
|
||||
const float *sbr_qmf_window = div ? sbr_qmf_window_ds : sbr_qmf_window_us;
|
||||
const INTFLOAT *sbr_qmf_window = div ? sbr_qmf_window_ds : sbr_qmf_window_us;
|
||||
const int step = 128 >> div;
|
||||
float *v;
|
||||
INTFLOAT *v;
|
||||
for (i = 0; i < 32; i++) {
|
||||
if (*v_off < step) {
|
||||
int saved_samples = (1280 - 128) >> div;
|
||||
memcpy(&v0[SBR_SYNTHESIS_BUF_SIZE - saved_samples], v0, saved_samples * sizeof(float));
|
||||
memcpy(&v0[SBR_SYNTHESIS_BUF_SIZE - saved_samples], v0, saved_samples * sizeof(INTFLOAT));
|
||||
*v_off = SBR_SYNTHESIS_BUF_SIZE - saved_samples - step;
|
||||
} else {
|
||||
*v_off -= step;
|
||||
@ -1117,7 +1223,7 @@ static void sbr_qmf_synthesis(FFTContext *mdct,
|
||||
|
||||
/// Generate the subband filtered lowband
|
||||
static 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)
|
||||
{
|
||||
int i, k;
|
||||
@ -1142,9 +1248,9 @@ static int sbr_lf_gen(AACContext *ac, SpectralBandReplication *sbr,
|
||||
|
||||
/// High Frequency Generator (14496-3 sp04 p215)
|
||||
static int sbr_hf_gen(AACContext *ac, SpectralBandReplication *sbr,
|
||||
float X_high[64][40][2], const float X_low[32][40][2],
|
||||
const float (*alpha0)[2], const float (*alpha1)[2],
|
||||
const float bw_array[5], const uint8_t *t_env,
|
||||
INTFLOAT X_high[64][40][2], const INTFLOAT X_low[32][40][2],
|
||||
const INTFLOAT (*alpha0)[2], const INTFLOAT (*alpha1)[2],
|
||||
const INTFLOAT bw_array[5], const uint8_t *t_env,
|
||||
int bs_num_env)
|
||||
{
|
||||
int j, x;
|
||||
@ -1176,9 +1282,9 @@ static int sbr_hf_gen(AACContext *ac, SpectralBandReplication *sbr,
|
||||
}
|
||||
|
||||
/// Generate the subband filtered lowband
|
||||
static 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)
|
||||
static 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)
|
||||
{
|
||||
int k, i;
|
||||
const int i_f = 32;
|
||||
@ -1270,7 +1376,7 @@ static int sbr_mapping(AACContext *ac, SpectralBandReplication *sbr,
|
||||
}
|
||||
|
||||
/// Estimation of current envelope (14496-3 sp04 p218)
|
||||
static void sbr_env_estimate(float (*e_curr)[48], float X_high[64][40][2],
|
||||
static void sbr_env_estimate(AAC_FLOAT (*e_curr)[48], INTFLOAT X_high[64][40][2],
|
||||
SpectralBandReplication *sbr, SBRData *ch_data)
|
||||
{
|
||||
int e, m;
|
||||
@ -1278,13 +1384,21 @@ static void sbr_env_estimate(float (*e_curr)[48], float X_high[64][40][2],
|
||||
|
||||
if (sbr->bs_interpol_freq) {
|
||||
for (e = 0; e < ch_data->bs_num_env; e++) {
|
||||
#if USE_FIXED
|
||||
const SoftFloat recip_env_size = av_int2sf(0x20000000 / (ch_data->t_env[e + 1] - ch_data->t_env[e]), 30);
|
||||
#else
|
||||
const float recip_env_size = 0.5f / (ch_data->t_env[e + 1] - ch_data->t_env[e]);
|
||||
#endif /* USE_FIXED */
|
||||
int ilb = ch_data->t_env[e] * 2 + ENVELOPE_ADJUSTMENT_OFFSET;
|
||||
int iub = ch_data->t_env[e + 1] * 2 + ENVELOPE_ADJUSTMENT_OFFSET;
|
||||
|
||||
for (m = 0; m < sbr->m[1]; m++) {
|
||||
float sum = sbr->dsp.sum_square(X_high[m+kx1] + ilb, iub - ilb);
|
||||
AAC_FLOAT sum = sbr->dsp.sum_square(X_high[m+kx1] + ilb, iub - ilb);
|
||||
#if USE_FIXED
|
||||
e_curr[e][m] = av_mul_sf(sum, recip_env_size);
|
||||
#else
|
||||
e_curr[e][m] = sum * recip_env_size;
|
||||
#endif /* USE_FIXED */
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -1297,6 +1411,14 @@ static void sbr_env_estimate(float (*e_curr)[48], float X_high[64][40][2],
|
||||
const uint16_t *table = ch_data->bs_freq_res[e + 1] ? sbr->f_tablehigh : sbr->f_tablelow;
|
||||
|
||||
for (p = 0; p < sbr->n[ch_data->bs_freq_res[e + 1]]; p++) {
|
||||
#if USE_FIXED
|
||||
SoftFloat sum = { 0, 0 };
|
||||
const SoftFloat den = av_int2sf(0x20000000 / (env_size * (table[p + 1] - table[p])), 29);
|
||||
for (k = table[p]; k < table[p + 1]; k++) {
|
||||
sum = av_add_sf(sum, sbr->dsp.sum_square(X_high[k] + ilb, iub - ilb));
|
||||
}
|
||||
sum = av_mul_sf(sum, den);
|
||||
#else
|
||||
float sum = 0.0f;
|
||||
const int den = env_size * (table[p + 1] - table[p]);
|
||||
|
||||
@ -1304,6 +1426,7 @@ static void sbr_env_estimate(float (*e_curr)[48], float X_high[64][40][2],
|
||||
sum += sbr->dsp.sum_square(X_high[k] + ilb, iub - ilb);
|
||||
}
|
||||
sum /= den;
|
||||
#endif /* USE_FIXED */
|
||||
for (k = table[p]; k < table[p + 1]; k++) {
|
||||
e_curr[e][k - kx1] = sum;
|
||||
}
|
||||
@ -1312,8 +1435,8 @@ static void sbr_env_estimate(float (*e_curr)[48], float X_high[64][40][2],
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
int downsampled = ac->oc[1].m4ac.ext_sample_rate < sbr->sample_rate;
|
||||
int ch;
|
||||
@ -1339,21 +1462,21 @@ void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac,
|
||||
for (ch = 0; ch < nch; ch++) {
|
||||
/* decode channel */
|
||||
sbr_qmf_analysis(ac->fdsp, &sbr->mdct_ana, &sbr->dsp, ch ? R : L, sbr->data[ch].analysis_filterbank_samples,
|
||||
(float*)sbr->qmf_filter_scratch,
|
||||
(INTFLOAT*)sbr->qmf_filter_scratch,
|
||||
sbr->data[ch].W, sbr->data[ch].Ypos);
|
||||
sbr->c.sbr_lf_gen(ac, sbr, sbr->X_low,
|
||||
(const float (*)[32][32][2]) sbr->data[ch].W,
|
||||
(const INTFLOAT (*)[32][32][2]) sbr->data[ch].W,
|
||||
sbr->data[ch].Ypos);
|
||||
sbr->data[ch].Ypos ^= 1;
|
||||
if (sbr->start) {
|
||||
sbr->c.sbr_hf_inverse_filter(&sbr->dsp, sbr->alpha0, sbr->alpha1,
|
||||
(const float (*)[40][2]) sbr->X_low, sbr->k[0]);
|
||||
(const INTFLOAT (*)[40][2]) sbr->X_low, sbr->k[0]);
|
||||
sbr_chirp(sbr, &sbr->data[ch]);
|
||||
av_assert0(sbr->data[ch].bs_num_env > 0);
|
||||
sbr_hf_gen(ac, sbr, sbr->X_high,
|
||||
(const float (*)[40][2]) sbr->X_low,
|
||||
(const float (*)[2]) sbr->alpha0,
|
||||
(const float (*)[2]) sbr->alpha1,
|
||||
(const INTFLOAT (*)[40][2]) sbr->X_low,
|
||||
(const INTFLOAT (*)[2]) sbr->alpha0,
|
||||
(const INTFLOAT (*)[2]) sbr->alpha1,
|
||||
sbr->data[ch].bw_array, sbr->data[ch].t_env,
|
||||
sbr->data[ch].bs_num_env);
|
||||
|
||||
@ -1363,7 +1486,7 @@ void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac,
|
||||
sbr_env_estimate(sbr->e_curr, sbr->X_high, sbr, &sbr->data[ch]);
|
||||
sbr_gain_calc(ac, sbr, &sbr->data[ch], sbr->data[ch].e_a);
|
||||
sbr->c.sbr_hf_assemble(sbr->data[ch].Y[sbr->data[ch].Ypos],
|
||||
(const float (*)[40][2]) sbr->X_high,
|
||||
(const INTFLOAT (*)[40][2]) sbr->X_high,
|
||||
sbr, &sbr->data[ch],
|
||||
sbr->data[ch].e_a);
|
||||
}
|
||||
@ -1371,9 +1494,9 @@ void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac,
|
||||
|
||||
/* synthesis */
|
||||
sbr->c.sbr_x_gen(sbr, sbr->X[ch],
|
||||
(const float (*)[64][2]) sbr->data[ch].Y[1-sbr->data[ch].Ypos],
|
||||
(const float (*)[64][2]) sbr->data[ch].Y[ sbr->data[ch].Ypos],
|
||||
(const float (*)[40][2]) sbr->X_low, ch);
|
||||
(const INTFLOAT (*)[64][2]) sbr->data[ch].Y[1-sbr->data[ch].Ypos],
|
||||
(const INTFLOAT (*)[64][2]) sbr->data[ch].Y[ sbr->data[ch].Ypos],
|
||||
(const INTFLOAT (*)[40][2]) sbr->X_low, ch);
|
||||
}
|
||||
|
||||
if (ac->oc[1].m4ac.ps == 1) {
|
||||
@ -1405,6 +1528,8 @@ static void aacsbr_func_ptr_init(AACSBRContext *c)
|
||||
c->sbr_x_gen = sbr_x_gen;
|
||||
c->sbr_hf_inverse_filter = sbr_hf_inverse_filter;
|
||||
|
||||
#if !USE_FIXED
|
||||
if(ARCH_MIPS)
|
||||
ff_aacsbr_func_ptr_init_mips(c);
|
||||
#endif
|
||||
}
|
||||
|
@ -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);
|
||||
|
286
libavcodec/sbrdsp_fixed.c
Normal file
286
libavcodec/sbrdsp_fixed.c
Normal file
@ -0,0 +1,286 @@
|
||||
/*
|
||||
* 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);
|
||||
|
Loading…
Reference in New Issue
Block a user