1/*
2 * Copyright (C) 2003 - 2016 Sony Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "ldac.h"
18
19/***************************************************************************************************
20    Subfunction: Get Scale Factor Index
21***************************************************************************************************/
22__inline static int get_scale_factor_id_ldac(
23SCALAR val)
24{
25    int id;
26    IEEE754_FI fi;
27
28    fi.f = val;
29    id = ((fi.i & 0x7fffffff) >> 23) - 111;
30
31    if (id < 0) {
32        id = 0;
33    }
34    if (id > LDAC_NIDSF-1) {
35        id = LDAC_NIDSF-1;
36    }
37
38    return id;
39}
40
41/***************************************************************************************************
42    Normalize Spectrum
43***************************************************************************************************/
44static SCALAR sa_val_ldac[LDAC_MAXNSPS] = {
45    -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,
46};
47
48DECLFUNC void norm_spectrum_ldac(
49AC *p_ac)
50{
51    int iqu, isp;
52    int lsp, hsp;
53    int nqus = p_ac->p_ab->nqus;
54    int idsf;
55    int *p_idsf = p_ac->a_idsf;
56    SCALAR maxspec, tmp;
57    SCALAR *p_spec = p_ac->p_acsub->a_spec;
58
59    for (iqu = 0; iqu < nqus; iqu++) {
60        lsp = ga_isp_ldac[iqu];
61        hsp = ga_isp_ldac[iqu+1];
62
63        maxspec = fabs(p_spec[lsp]);
64        for (isp = lsp+1; isp < hsp; isp++) {
65            tmp = fabs(p_spec[isp]);
66            if (maxspec < tmp) {
67                maxspec = tmp;
68            }
69        }
70        idsf = get_scale_factor_id_ldac(maxspec);
71
72        if (idsf > 0) {
73            tmp = ga_isf_ldac[idsf];
74            for (isp = lsp; isp < hsp; isp++) {
75                p_spec[isp] *= tmp;
76            }
77        }
78        else {
79            for (isp = lsp; isp < hsp; isp++) {
80                p_spec[isp] = sa_val_ldac[isp-lsp];
81            }
82        }
83
84        p_idsf[iqu] = idsf;
85    }
86
87    return;
88}
89
90/***************************************************************************************************
91    Subfunction: Quantize Spectrum Core
92***************************************************************************************************/
93__inline static void quant_spectrum_core_ldac(
94AC *p_ac,
95int iqu)
96{
97    int i;
98    int isp = ga_isp_ldac[iqu];
99    int nsps = ga_nsps_ldac[iqu];
100    int *p_qspec = p_ac->a_qspec+isp;
101    SCALAR qf = ga_qf_ldac[p_ac->a_idwl1[iqu]];
102    SCALAR *p_nspec = p_ac->p_acsub->a_spec+isp;
103
104    IEEE754_FI fi;
105    const float fc = (float)((1 << 23) + (1 << 22));
106
107    for (i = 0; i < nsps; i++) {
108        fi.f = p_nspec[i] * qf + fc;
109        p_qspec[i] = (short)fi.i;
110    }
111
112    return;
113}
114
115/***************************************************************************************************
116    Quantize Spectrum
117***************************************************************************************************/
118DECLFUNC void quant_spectrum_ldac(
119AC *p_ac)
120{
121    int iqu;
122    int nqus = p_ac->p_ab->nqus;
123
124    for (iqu = 0; iqu < nqus; iqu++) {
125        quant_spectrum_core_ldac(p_ac, iqu);
126    }
127
128    return;
129}
130
131/***************************************************************************************************
132    Subfunction: Quantize Residual Spectrum Core
133***************************************************************************************************/
134__inline static void quant_residual_core_ldac(
135AC *p_ac,
136int iqu)
137{
138    int i;
139    int isp = ga_isp_ldac[iqu];
140    int nsps = ga_nsps_ldac[iqu];
141    int *p_qspec = p_ac->a_qspec+isp;
142    int *p_rspec = p_ac->a_rspec+isp;
143    SCALAR ldqspec;
144    SCALAR iqf = ga_iqf_ldac[LDAC_MAXIDWL1];
145    SCALAR rqsf = ga_qf_ldac[p_ac->a_idwl2[iqu]] * ga_irsf_ldac[LDAC_MAXIDWL1]
146            * _scalar(0.996093750);
147    SCALAR *p_nspec = p_ac->p_acsub->a_spec+isp;
148
149    IEEE754_FI fi;
150    const float fc = (float)((1 << 23) + (1 << 22));
151
152    for (i = 0; i < nsps; i++) {
153        ldqspec = p_qspec[i] * iqf;
154        fi.f = (p_nspec[i] - ldqspec) * rqsf + fc;
155        p_rspec[i] = (short)fi.i;
156    }
157
158    return;
159}
160
161/***************************************************************************************************
162    Quantize Residual Spectrum
163***************************************************************************************************/
164DECLFUNC void quant_residual_ldac(
165AC *p_ac)
166{
167    int iqu;
168    int nqus = p_ac->p_ab->nqus;
169    int *p_idwl2 = p_ac->a_idwl2;
170
171    for (iqu = 0; iqu < nqus; iqu++) {
172        if (p_idwl2[iqu] > 0) {
173            quant_residual_core_ldac(p_ac, iqu);
174        }
175    }
176
177    return;
178}
179
180