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    Pack and Store from MSB
21***************************************************************************************************/
22static void pack_store_ldac(
23int idata,
24int nbits,
25STREAM *p_block,
26int *p_loc)
27{
28    STREAM *p_bufptr;
29    register int bpos;
30    register unsigned int tmp;
31
32    p_bufptr = p_block + (*p_loc >> LDAC_LOC_SHIFT);
33    bpos = *p_loc & LDAC_LOC_MASK;
34
35    tmp = (idata << (24-nbits)) & 0xffffff;
36    tmp >>= bpos;
37    *p_bufptr++ |= (tmp>>16);
38    *p_bufptr++ = (tmp>>8) & 0xff;
39    *p_bufptr = tmp & 0xff;
40
41    *p_loc += nbits;
42
43    return;
44}
45
46
47/***************************************************************************************************
48    Pack Frame Header
49***************************************************************************************************/
50DECLFUNC void pack_frame_header_ldac(
51int smplrate_id,
52int chconfig_id,
53int frame_length,
54int frame_status,
55STREAM *p_stream)
56{
57    int loc = 0;
58
59    pack_store_ldac(LDAC_SYNCWORD, LDAC_SYNCWORDBITS, p_stream, &loc);
60
61    pack_store_ldac(smplrate_id, LDAC_SMPLRATEBITS, p_stream, &loc);
62
63    pack_store_ldac(chconfig_id, LDAC_CHCONFIG2BITS, p_stream, &loc);
64
65    pack_store_ldac(frame_length-1, LDAC_FRAMELEN2BITS, p_stream, &loc);
66
67    pack_store_ldac(frame_status, LDAC_FRAMESTATBITS, p_stream, &loc);
68
69    return;
70}
71
72/***************************************************************************************************
73    Pack Frame Alignment
74***************************************************************************************************/
75static void pack_frame_alignment_ldac(
76STREAM *p_stream,
77int *p_loc,
78int nbytes_frame)
79{
80    int i;
81    int nbytes_filled;
82
83    nbytes_filled = nbytes_frame - *p_loc / LDAC_BYTESIZE;
84
85    for (i = 0; i < nbytes_filled; i++) {
86        pack_store_ldac(LDAC_FILLCODE, LDAC_BYTESIZE, p_stream, p_loc);
87    }
88
89    return;
90}
91
92/***************************************************************************************************
93    Pack Byte Alignment
94***************************************************************************************************/
95#define pack_block_alignment_ldac(p_stream, p_loc) pack_byte_alignment_ldac((p_stream), (p_loc))
96
97static void pack_byte_alignment_ldac(
98STREAM *p_stream,
99int *p_loc)
100{
101    int nbits_padding;
102
103    nbits_padding = ((*p_loc + LDAC_BYTESIZE - 1) / LDAC_BYTESIZE) * LDAC_BYTESIZE - *p_loc;
104
105    if (nbits_padding > 0) {
106        pack_store_ldac(0, nbits_padding, p_stream, p_loc);
107    }
108
109    return;
110}
111
112/***************************************************************************************************
113    Pack Band Info
114***************************************************************************************************/
115static void pack_band_info_ldac(
116AB *p_ab,
117STREAM *p_stream,
118int *p_loc)
119{
120    pack_store_ldac(p_ab->nbands-LDAC_BAND_OFFSET, LDAC_NBANDBITS, p_stream, p_loc);
121
122    pack_store_ldac(LDAC_FALSE, LDAC_FLAGBITS, p_stream, p_loc);
123
124    return;
125}
126
127/***************************************************************************************************
128    Pack Gradient Data
129***************************************************************************************************/
130static void pack_gradient_ldac(
131AB *p_ab,
132STREAM *p_stream,
133int *p_loc)
134{
135    pack_store_ldac(p_ab->grad_mode, LDAC_GRADMODEBITS, p_stream, p_loc);
136
137    if (p_ab->grad_mode == LDAC_MODE_0) {
138        pack_store_ldac(p_ab->grad_qu_l, LDAC_GRADQU0BITS, p_stream, p_loc);
139
140        pack_store_ldac(p_ab->grad_qu_h-1, LDAC_GRADQU0BITS, p_stream, p_loc);
141
142        pack_store_ldac(p_ab->grad_os_l, LDAC_GRADOSBITS, p_stream, p_loc);
143
144        pack_store_ldac(p_ab->grad_os_h, LDAC_GRADOSBITS, p_stream, p_loc);
145    }
146    else {
147        pack_store_ldac(p_ab->grad_qu_l, LDAC_GRADQU1BITS, p_stream, p_loc);
148
149        pack_store_ldac(p_ab->grad_os_l, LDAC_GRADOSBITS, p_stream, p_loc);
150    }
151
152    pack_store_ldac(p_ab->nadjqus, LDAC_NADJQUBITS, p_stream, p_loc);
153
154    return;
155}
156
157/***************************************************************************************************
158    Subfunction: Pack Scale Factor Data - Mode 0
159***************************************************************************************************/
160static void pack_scale_factor_0_ldac(
161AC *p_ac,
162STREAM *p_stream,
163int *p_loc)
164{
165    HCENC *p_hcsf;
166    int iqu;
167    int nqus = p_ac->p_ab->nqus;
168    int dif, val0, val1;
169    const unsigned char *p_tbl;
170
171    pack_store_ldac(p_ac->sfc_bitlen-LDAC_MINSFCBLEN_0, LDAC_SFCBLENBITS, p_stream, p_loc);
172
173    pack_store_ldac(p_ac->sfc_offset, LDAC_IDSFBITS, p_stream, p_loc);
174
175    pack_store_ldac(p_ac->sfc_weight, LDAC_SFCWTBLBITS, p_stream, p_loc);
176
177    p_tbl = gaa_sfcwgt_ldac[p_ac->sfc_weight];
178    val0 = p_ac->a_idsf[0] + p_tbl[0];
179
180    pack_store_ldac(val0-p_ac->sfc_offset, p_ac->sfc_bitlen, p_stream, p_loc);
181
182    p_hcsf = ga_hcenc_sf0_ldac + (p_ac->sfc_bitlen-LDAC_MINSFCBLEN_0);
183    for (iqu = 1; iqu < nqus; iqu++) {
184        val1 = p_ac->a_idsf[iqu] + p_tbl[iqu];
185        dif = (val1 - val0) & p_hcsf->mask;
186        pack_store_ldac(hc_word_ldac(p_hcsf->p_tbl+dif), hc_len_ldac(p_hcsf->p_tbl+dif), p_stream, p_loc);
187        val0 = val1;
188    }
189
190    return;
191}
192
193/***************************************************************************************************
194    Subfunction: Pack Scale Factor Data - Mode 1
195***************************************************************************************************/
196static void pack_scale_factor_1_ldac(
197AC *p_ac,
198STREAM *p_stream,
199int *p_loc)
200{
201    int iqu;
202    int nqus = p_ac->p_ab->nqus;
203    const unsigned char *p_tbl;
204
205    pack_store_ldac(p_ac->sfc_bitlen-LDAC_MINSFCBLEN_1, LDAC_SFCBLENBITS, p_stream, p_loc);
206
207    if (p_ac->sfc_bitlen > 4) {
208        for (iqu = 0; iqu < nqus; iqu++) {
209            pack_store_ldac(p_ac->a_idsf[iqu], LDAC_IDSFBITS, p_stream, p_loc);
210        }
211    }
212    else {
213        pack_store_ldac(p_ac->sfc_offset, LDAC_IDSFBITS, p_stream, p_loc);
214
215        pack_store_ldac(p_ac->sfc_weight, LDAC_SFCWTBLBITS, p_stream, p_loc);
216
217        p_tbl = gaa_sfcwgt_ldac[p_ac->sfc_weight];
218        for (iqu = 0; iqu < nqus; iqu++) {
219            pack_store_ldac(p_ac->a_idsf[iqu]+p_tbl[iqu]-p_ac->sfc_offset, p_ac->sfc_bitlen, p_stream, p_loc);
220        }
221    }
222
223    return;
224}
225
226/***************************************************************************************************
227    Subfunction: Pack Scale Factor Data - Mode 2
228***************************************************************************************************/
229static void pack_scale_factor_2_ldac(
230AC *p_ac,
231STREAM *p_stream,
232int *p_loc)
233{
234    HCENC *p_hcsf;
235    int iqu;
236    int nqus = p_ac->p_ab->nqus;
237    int dif;
238
239    pack_store_ldac(p_ac->sfc_bitlen-LDAC_MINSFCBLEN_2, LDAC_SFCBLENBITS, p_stream, p_loc);
240
241    p_hcsf = ga_hcenc_sf1_ldac + (p_ac->sfc_bitlen-LDAC_MINSFCBLEN_2);
242    for (iqu = 0; iqu < nqus; iqu++) {
243        dif = (p_ac->a_idsf[iqu] - p_ac->p_ab->ap_ac[0]->a_idsf[iqu]) & p_hcsf->mask;
244        pack_store_ldac(hc_word_ldac(p_hcsf->p_tbl+dif), hc_len_ldac(p_hcsf->p_tbl+dif), p_stream, p_loc);
245    }
246
247    return;
248}
249
250/***************************************************************************************************
251    Pack Scale Factor Data
252***************************************************************************************************/
253static void pack_scale_factor_ldac(
254AC *p_ac,
255STREAM *p_stream,
256int *p_loc)
257{
258    int sfc_mode = p_ac->sfc_mode;
259
260    pack_store_ldac(sfc_mode, LDAC_SFCMODEBITS, p_stream, p_loc);
261
262    if (p_ac->ich == 0) {
263        if (sfc_mode == LDAC_MODE_0) {
264            pack_scale_factor_0_ldac(p_ac, p_stream, p_loc);
265        }
266        else {
267            pack_scale_factor_1_ldac(p_ac, p_stream, p_loc);
268        }
269    }
270    else {
271        if (sfc_mode == LDAC_MODE_0) {
272            pack_scale_factor_0_ldac(p_ac, p_stream, p_loc);
273        }
274        else {
275            pack_scale_factor_2_ldac(p_ac, p_stream, p_loc);
276        }
277    }
278
279    return;
280}
281
282/***************************************************************************************************
283    Pack Spectrum Data
284***************************************************************************************************/
285static void pack_spectrum_ldac(
286AC *p_ac,
287STREAM *p_stream,
288int *p_loc)
289{
290    int iqu, isp, i;
291    int lsp, hsp;
292    int nqus = p_ac->p_ab->nqus;
293    int nsps, idwl1, wl, val;
294
295    for (iqu = 0; iqu < nqus; iqu++) {
296        lsp = ga_isp_ldac[iqu];
297        hsp = ga_isp_ldac[iqu+1];
298        nsps = ga_nsps_ldac[iqu];
299        idwl1 = p_ac->a_idwl1[iqu];
300        wl = ga_wl_ldac[idwl1];
301
302        if (idwl1 == 1) {
303            isp = lsp;
304
305            if (nsps == 2) {
306                val  = (p_ac->a_qspec[isp  ]+1) << 2;
307                val += (p_ac->a_qspec[isp+1]+1);
308                pack_store_ldac(ga_2dimenc_spec_ldac[val], LDAC_2DIMSPECBITS, p_stream, p_loc);
309            }
310            else {
311                for (i = 0; i < nsps>>2; i++, isp+=4) {
312                    val  = (p_ac->a_qspec[isp  ]+1) << 6;
313                    val += (p_ac->a_qspec[isp+1]+1) << 4;
314                    val += (p_ac->a_qspec[isp+2]+1) << 2;
315                    val += (p_ac->a_qspec[isp+3]+1);
316                    pack_store_ldac(ga_4dimenc_spec_ldac[val], LDAC_4DIMSPECBITS, p_stream, p_loc);
317                }
318            }
319        }
320        else {
321            for (isp = lsp; isp < hsp; isp++) {
322                pack_store_ldac(p_ac->a_qspec[isp], wl, p_stream, p_loc);
323            }
324        }
325    }
326
327    return;
328}
329
330/***************************************************************************************************
331    Pack Residual Data
332***************************************************************************************************/
333static void pack_residual_ldac(
334AC *p_ac,
335STREAM *p_stream,
336int *p_loc)
337{
338    int iqu, isp;
339    int lsp, hsp;
340    int nqus = p_ac->p_ab->nqus;
341    int idwl2, wl;
342
343    for (iqu = 0; iqu < nqus; iqu++) {
344        idwl2 = p_ac->a_idwl2[iqu];
345
346        if (idwl2 > 0) {
347            lsp = ga_isp_ldac[iqu];
348            hsp = ga_isp_ldac[iqu+1];
349            wl = ga_wl_ldac[idwl2];
350
351            for (isp = lsp; isp < hsp; isp++) {
352                pack_store_ldac(p_ac->a_rspec[isp], wl, p_stream, p_loc);
353            }
354        }
355    }
356
357    return;
358}
359
360/***************************************************************************************************
361    Pack Audio Block
362***************************************************************************************************/
363static int pack_audio_block_ldac(
364AB *p_ab,
365STREAM *p_stream,
366int *p_loc)
367{
368    AC *p_ac;
369    int ich;
370    int nchs = p_ab->blk_nchs;
371    int nbits_band, nbits_grad, a_nbits_scfc[2], a_nbits_spec[2], nbits_used;
372    int loc;
373
374    for (ich = 0; ich < 2; ich++) {
375        a_nbits_scfc[ich] = 0;
376        a_nbits_spec[ich] = 0;
377    }
378
379    loc = *p_loc;
380    pack_band_info_ldac(p_ab, p_stream, p_loc);
381    nbits_band = *p_loc - loc;
382
383    loc = *p_loc;
384    pack_gradient_ldac(p_ab, p_stream, p_loc);
385    nbits_grad = *p_loc - loc;
386
387    nbits_used = nbits_band + nbits_grad;
388
389    for (ich = 0; ich < nchs; ich++) {
390        p_ac = p_ab->ap_ac[ich];
391
392        loc = *p_loc;
393        pack_scale_factor_ldac(p_ac, p_stream, p_loc);
394        a_nbits_scfc[ich] = *p_loc - loc;
395
396        loc = *p_loc;
397        pack_spectrum_ldac(p_ac, p_stream, p_loc);
398        a_nbits_spec[ich] = *p_loc - loc;
399
400        loc = *p_loc;
401        pack_residual_ldac(p_ac, p_stream, p_loc);
402        a_nbits_spec[ich] += *p_loc - loc;
403
404        nbits_used += a_nbits_scfc[ich] + a_nbits_spec[ich];
405    }
406
407    if (nbits_used > p_ab->nbits_used) {
408        *p_ab->p_error_code = LDAC_ERR_BIT_PACKING;
409        return LDAC_FALSE;
410    }
411    else if (nbits_used < p_ab->nbits_used) {
412        *p_ab->p_error_code = LDAC_ERR_BIT_PACKING;
413        return LDAC_FALSE;
414    }
415
416    return LDAC_TRUE;
417}
418
419/***************************************************************************************************
420    Pack Raw Data Frame
421***************************************************************************************************/
422DECLFUNC int pack_raw_data_frame_ldac(
423SFINFO *p_sfinfo,
424STREAM *p_stream,
425int *p_loc,
426int *p_nbytes_used)
427{
428    CFG *p_cfg = &p_sfinfo->cfg;
429    AB *p_ab = p_sfinfo->p_ab;
430    int ibk;
431    int nbks = gaa_block_setting_ldac[p_cfg->chconfig_id][1];
432
433    for (ibk = 0; ibk < nbks; ibk++) {
434        if (!pack_audio_block_ldac(p_ab, p_stream, p_loc)) {
435            return LDAC_ERR_PACK_BLOCK_FAILED;
436        }
437
438        pack_block_alignment_ldac(p_stream, p_loc);
439
440        p_ab++;
441    }
442
443    pack_frame_alignment_ldac(p_stream, p_loc, p_cfg->frame_length);
444
445    *p_nbytes_used = *p_loc / LDAC_BYTESIZE;
446
447    return LDAC_ERR_NONE;
448}
449
450/***************************************************************************************************
451    Pack Null Data Frame
452***************************************************************************************************/
453static const int sa_null_data_size_ldac[2] = {
454    11, 15,
455};
456static const STREAM saa_null_data_ldac[2][15] = {
457    {0x07, 0xa0, 0x16, 0x00, 0x20, 0xad, 0x51, 0x45, 0x14, 0x50, 0x49},
458    {0x07, 0xa0, 0x0a, 0x00, 0x20, 0xad, 0x51, 0x41, 0x24, 0x93, 0x00, 0x28, 0xa0, 0x92, 0x49},
459};
460
461DECLFUNC int pack_null_data_frame_ldac(
462SFINFO *p_sfinfo,
463STREAM *p_stream,
464int *p_loc,
465int *p_nbytes_used)
466{
467    CFG *p_cfg = &p_sfinfo->cfg;
468    AB *p_ab = p_sfinfo->p_ab;
469    int ibk;
470    int nbks = gaa_block_setting_ldac[p_cfg->chconfig_id][1];
471    int blk_type, size, offset = 0;
472
473    for (ibk = 0; ibk < nbks; ibk++) {
474        blk_type = p_ab->blk_type;
475        size = sa_null_data_size_ldac[blk_type];
476
477        copy_data_ldac(saa_null_data_ldac[blk_type], p_stream+offset, size*sizeof(STREAM));
478        *p_loc += size*LDAC_BYTESIZE;
479
480        offset += size;
481        p_ab++;
482    }
483    if (p_cfg->frame_length < offset) {
484        return LDAC_ERR_PACK_BLOCK_FAILED;
485    }
486
487    pack_frame_alignment_ldac(p_stream, p_loc, p_cfg->frame_length);
488
489    *p_nbytes_used = *p_loc / LDAC_BYTESIZE;
490
491    return LDAC_ERR_NONE;
492}
493
494