/*
* Copyright (C) 2003 - 2016 Sony Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ldac.h"
/***************************************************************************************************
Subfunction: Get Scale Factor Index
***************************************************************************************************/
__inline static int get_scale_factor_id_ldac(
SCALAR val)
{
int id;
IEEE754_FI fi;
fi.f = val;
id = ((fi.i & 0x7fffffff) >> 23) - 111;
if (id < 0) {
id = 0;
}
if (id > LDAC_NIDSF-1) {
id = LDAC_NIDSF-1;
}
return id;
}
/***************************************************************************************************
Normalize Spectrum
***************************************************************************************************/
static SCALAR sa_val_ldac[LDAC_MAXNSPS] = {
-0.75, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
};
DECLFUNC void norm_spectrum_ldac(
AC *p_ac)
{
int iqu, isp;
int lsp, hsp;
int nqus = p_ac->p_ab->nqus;
int idsf;
int *p_idsf = p_ac->a_idsf;
SCALAR maxspec, tmp;
SCALAR *p_spec = p_ac->p_acsub->a_spec;
for (iqu = 0; iqu < nqus; iqu++) {
lsp = ga_isp_ldac[iqu];
hsp = ga_isp_ldac[iqu+1];
maxspec = fabs(p_spec[lsp]);
for (isp = lsp+1; isp < hsp; isp++) {
tmp = fabs(p_spec[isp]);
if (maxspec < tmp) {
maxspec = tmp;
}
}
idsf = get_scale_factor_id_ldac(maxspec);
if (idsf > 0) {
tmp = ga_isf_ldac[idsf];
for (isp = lsp; isp < hsp; isp++) {
p_spec[isp] *= tmp;
}
}
else {
for (isp = lsp; isp < hsp; isp++) {
p_spec[isp] = sa_val_ldac[isp-lsp];
}
}
p_idsf[iqu] = idsf;
}
return;
}
/***************************************************************************************************
Subfunction: Quantize Spectrum Core
***************************************************************************************************/
__inline static void quant_spectrum_core_ldac(
AC *p_ac,
int iqu)
{
int i;
int isp = ga_isp_ldac[iqu];
int nsps = ga_nsps_ldac[iqu];
int *p_qspec = p_ac->a_qspec+isp;
SCALAR qf = ga_qf_ldac[p_ac->a_idwl1[iqu]];
SCALAR *p_nspec = p_ac->p_acsub->a_spec+isp;
IEEE754_FI fi;
const float fc = (float)((1 << 23) + (1 << 22));
for (i = 0; i < nsps; i++) {
fi.f = p_nspec[i] * qf + fc;
p_qspec[i] = (short)fi.i;
}
return;
}
/***************************************************************************************************
Quantize Spectrum
***************************************************************************************************/
DECLFUNC void quant_spectrum_ldac(
AC *p_ac)
{
int iqu;
int nqus = p_ac->p_ab->nqus;
for (iqu = 0; iqu < nqus; iqu++) {
quant_spectrum_core_ldac(p_ac, iqu);
}
return;
}
/***************************************************************************************************
Subfunction: Quantize Residual Spectrum Core
***************************************************************************************************/
__inline static void quant_residual_core_ldac(
AC *p_ac,
int iqu)
{
int i;
int isp = ga_isp_ldac[iqu];
int nsps = ga_nsps_ldac[iqu];
int *p_qspec = p_ac->a_qspec+isp;
int *p_rspec = p_ac->a_rspec+isp;
SCALAR ldqspec;
SCALAR iqf = ga_iqf_ldac[LDAC_MAXIDWL1];
SCALAR rqsf = ga_qf_ldac[p_ac->a_idwl2[iqu]] * ga_irsf_ldac[LDAC_MAXIDWL1]
* _scalar(0.996093750);
SCALAR *p_nspec = p_ac->p_acsub->a_spec+isp;
IEEE754_FI fi;
const float fc = (float)((1 << 23) + (1 << 22));
for (i = 0; i < nsps; i++) {
ldqspec = p_qspec[i] * iqf;
fi.f = (p_nspec[i] - ldqspec) * rqsf + fc;
p_rspec[i] = (short)fi.i;
}
return;
}
/***************************************************************************************************
Quantize Residual Spectrum
***************************************************************************************************/
DECLFUNC void quant_residual_ldac(
AC *p_ac)
{
int iqu;
int nqus = p_ac->p_ab->nqus;
int *p_idwl2 = p_ac->a_idwl2;
for (iqu = 0; iqu < nqus; iqu++) {
if (p_idwl2[iqu] > 0) {
quant_residual_core_ldac(p_ac, iqu);
}
}
return;
}