/* * 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( INT32 val) { int i; int id, step; if (ga_sf_ldac[0] > val) { return 0; } id = LDAC_NIDSF >> 1; step = LDAC_NIDSF >> 2; for (i = 0; i < LDAC_IDSFBITS-1; i++) { if (ga_sf_ldac[id] > val) { id -= step; } else { id += step; } step >>= 1; } if ((ga_sf_ldac[id] <= val) && (id < LDAC_NIDSF-1)) { id++; } return id; } /*************************************************************************************************** Normalize Spectrum ***************************************************************************************************/ static INT32 sa_val_ldac[LDAC_MAXNSPS] = { /* Q31 */ 0xa0000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }; DECLFUNC void norm_spectrum_ldac( AC *p_ac) { int iqu, isp; int lsp, hsp; int nqus = p_ac->p_ab->nqus; int idsf; INT32 maxspec, tmp; INT32 *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 = abs(p_spec[lsp]); for (isp = lsp+1; isp < hsp; isp++) { tmp = abs(p_spec[isp]); if (maxspec < tmp) { maxspec = tmp; } } idsf = get_scale_factor_id_ldac(maxspec); if (idsf > 0) { for (isp = lsp; isp < hsp; isp++) { p_spec[isp] = sftrnd_ldac(p_spec[isp], idsf-LDAC_Q_NORM); } } else { for (isp = lsp; isp < hsp; isp++) { p_spec[isp] = sa_val_ldac[isp-lsp]; } } p_ac->a_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; INT32 qf = ga_qf_ldac[p_ac->a_idwl1[iqu]]; INT32 *p_nspec = p_ac->p_acsub->a_spec+isp; for (i = 0; i < nsps; i++) { /* Q00 <- Q31 * Q16 */ p_qspec[i] = mul_rsftrnd_ldac(p_nspec[i], qf, LDAC_Q_QUANT1); } 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; INT32 ldqspec, rnspec; INT32 iqf = ga_iqf_ldac[LDAC_MAXIDWL1]; INT32 rqf = ga_qf_ldac[p_ac->a_idwl2[iqu]]; INT32 irsf = ga_irsf_ldac[LDAC_MAXIDWL1]; INT32 *p_nspec = p_ac->p_acsub->a_spec+isp; for (i = 0; i < nsps; i++) { /* Q31 <- Q00 * Q31 */ ldqspec = mul_lsftrnd_ldac(p_qspec[i], iqf, LDAC_Q_QUANT2); /* Q31 <- (Q31 - Q31) * Q15 */ rnspec = mul_rsftrnd_ldac(p_nspec[i]-ldqspec, irsf, LDAC_Q_QUANT3); /* Q00 <- Q31 * Q16 */ p_rspec[i] = mul_rsftrnd_ldac(rnspec, rqf, LDAC_Q_QUANT4); } 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; }