xref: /aosp_15_r20/external/libldac/src/ldacBT_internal.c (revision aef9bcd9217ad2365ebc8e70efaf94b64e04df14)
1*aef9bcd9SKiyoung Kim /*
2*aef9bcd9SKiyoung Kim  * Copyright (C) 2013 - 2016 Sony Corporation
3*aef9bcd9SKiyoung Kim  *
4*aef9bcd9SKiyoung Kim  * Licensed under the Apache License, Version 2.0 (the "License");
5*aef9bcd9SKiyoung Kim  * you may not use this file except in compliance with the License.
6*aef9bcd9SKiyoung Kim  * You may obtain a copy of the License at
7*aef9bcd9SKiyoung Kim  *
8*aef9bcd9SKiyoung Kim  *      http://www.apache.org/licenses/LICENSE-2.0
9*aef9bcd9SKiyoung Kim  *
10*aef9bcd9SKiyoung Kim  * Unless required by applicable law or agreed to in writing, software
11*aef9bcd9SKiyoung Kim  * distributed under the License is distributed on an "AS IS" BASIS,
12*aef9bcd9SKiyoung Kim  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*aef9bcd9SKiyoung Kim  * See the License for the specific language governing permissions and
14*aef9bcd9SKiyoung Kim  * limitations under the License.
15*aef9bcd9SKiyoung Kim  */
16*aef9bcd9SKiyoung Kim 
17*aef9bcd9SKiyoung Kim #include "ldacBT_internal.h"
18*aef9bcd9SKiyoung Kim 
19*aef9bcd9SKiyoung Kim 
20*aef9bcd9SKiyoung Kim 
21*aef9bcd9SKiyoung Kim enum {
22*aef9bcd9SKiyoung Kim     /* 2-DH5 */
23*aef9bcd9SKiyoung Kim                      LDACBT_2DH5_02,  LDACBT_2DH5_03,  LDACBT_2DH5_04,  LDACBT_2DH5_05,
24*aef9bcd9SKiyoung Kim     LDACBT_2DH5_06,  LDACBT_2DH5_07,  LDACBT_2DH5_08,  LDACBT_2DH5_09,  LDACBT_2DH5_10,
25*aef9bcd9SKiyoung Kim     LDACBT_2DH5_11,  LDACBT_2DH5_12,  LDACBT_2DH5_13,  LDACBT_2DH5_14,
26*aef9bcd9SKiyoung Kim };
27*aef9bcd9SKiyoung Kim 
28*aef9bcd9SKiyoung Kim #define LDACBT_NO_DEF_ -1
29*aef9bcd9SKiyoung Kim DECLFUNC const LDACBT_EQMID_PROPERTY tbl_ldacbt_eqmid_property[] = {
30*aef9bcd9SKiyoung Kim     /* kbps,    ID               , label, ID for 2DH5     */
31*aef9bcd9SKiyoung Kim     /* 990 */ { LDACBT_EQMID_HQ, "HQ" , LDACBT_2DH5_02 },
32*aef9bcd9SKiyoung Kim     /* 660 */ { LDACBT_EQMID_SQ, "SQ" , LDACBT_2DH5_03 },
33*aef9bcd9SKiyoung Kim     /* 492 */ { LDACBT_EQMID_Q0, "Q0" , LDACBT_2DH5_04 },
34*aef9bcd9SKiyoung Kim     /* 396 */ { LDACBT_EQMID_Q1, "Q1" , LDACBT_2DH5_05 },
35*aef9bcd9SKiyoung Kim     /* 330 */ { LDACBT_EQMID_MQ, "MQ" , LDACBT_2DH5_06 },
36*aef9bcd9SKiyoung Kim     /* 282 */ { LDACBT_EQMID_Q2, "Q2" , LDACBT_2DH5_07 },
37*aef9bcd9SKiyoung Kim     /* 246 */ { LDACBT_EQMID_Q3, "Q3" , LDACBT_2DH5_08 },
38*aef9bcd9SKiyoung Kim     /* 216 */ { LDACBT_EQMID_Q4, "Q4" , LDACBT_2DH5_09 },
39*aef9bcd9SKiyoung Kim     /* 198 */ { LDACBT_EQMID_Q5, "Q5" , LDACBT_2DH5_10 },
40*aef9bcd9SKiyoung Kim     /* 180 */ { LDACBT_EQMID_Q6, "Q6" , LDACBT_2DH5_11 },
41*aef9bcd9SKiyoung Kim     /* 162 */ { LDACBT_EQMID_Q7, "Q7" , LDACBT_2DH5_12 },
42*aef9bcd9SKiyoung Kim     /* 150 */ { LDACBT_EQMID_Q8, "Q8" , LDACBT_2DH5_13 },
43*aef9bcd9SKiyoung Kim     /* 138 */ { LDACBT_EQMID_END, "Q9" , LDACBT_2DH5_14 },
44*aef9bcd9SKiyoung Kim };
45*aef9bcd9SKiyoung Kim 
46*aef9bcd9SKiyoung Kim /* LDAC config table
47*aef9bcd9SKiyoung Kim  *  - NFRM/PCKT must be less than 16.
48*aef9bcd9SKiyoung Kim  */
49*aef9bcd9SKiyoung Kim DECLFUNC const LDACBT_CONFIG tbl_ldacbt_config[] = {
50*aef9bcd9SKiyoung Kim /*
51*aef9bcd9SKiyoung Kim  *   index          , NFRM , LDAC  , FRM
52*aef9bcd9SKiyoung Kim  *                  , ---- ,  FRM  ,  LEN
53*aef9bcd9SKiyoung Kim  *                  , PCKT ,   LEN ,    /CH
54*aef9bcd9SKiyoung Kim  *                  ,      , [byte], [byte]
55*aef9bcd9SKiyoung Kim  */
56*aef9bcd9SKiyoung Kim     { LDACBT_2DH5_02,     2,    330,   165},
57*aef9bcd9SKiyoung Kim     { LDACBT_2DH5_03,     3,    220,   110},
58*aef9bcd9SKiyoung Kim     { LDACBT_2DH5_04,     4,    164,    82},
59*aef9bcd9SKiyoung Kim     { LDACBT_2DH5_05,     5,    132,    66},
60*aef9bcd9SKiyoung Kim     { LDACBT_2DH5_06,     6,    110,    55},
61*aef9bcd9SKiyoung Kim     { LDACBT_2DH5_07,     7,     94,    47},
62*aef9bcd9SKiyoung Kim     { LDACBT_2DH5_08,     8,     82,    41},
63*aef9bcd9SKiyoung Kim     { LDACBT_2DH5_09,     9,     72,    36},
64*aef9bcd9SKiyoung Kim     { LDACBT_2DH5_10,    10,     66,    33},
65*aef9bcd9SKiyoung Kim     { LDACBT_2DH5_11,    11,     60,    30},
66*aef9bcd9SKiyoung Kim     { LDACBT_2DH5_12,    12,     54,    27},
67*aef9bcd9SKiyoung Kim     { LDACBT_2DH5_13,    13,     50,    25},
68*aef9bcd9SKiyoung Kim     { LDACBT_2DH5_14,    14,     46,    23},
69*aef9bcd9SKiyoung Kim };
70*aef9bcd9SKiyoung Kim 
71*aef9bcd9SKiyoung Kim 
72*aef9bcd9SKiyoung Kim /* Clear LDAC handle parameters */
ldacBT_param_clear(HANDLE_LDAC_BT hLdacBT)73*aef9bcd9SKiyoung Kim DECLFUNC void ldacBT_param_clear(HANDLE_LDAC_BT hLdacBT)
74*aef9bcd9SKiyoung Kim {
75*aef9bcd9SKiyoung Kim     int ich;
76*aef9bcd9SKiyoung Kim     if( hLdacBT == NULL ) { return ; }
77*aef9bcd9SKiyoung Kim     hLdacBT->proc_mode = LDACBT_PROCMODE_UNSET;
78*aef9bcd9SKiyoung Kim     hLdacBT->error_code = LDACBT_ERR_NONE;
79*aef9bcd9SKiyoung Kim     hLdacBT->error_code_api = LDACBT_ERR_NONE;
80*aef9bcd9SKiyoung Kim 
81*aef9bcd9SKiyoung Kim     hLdacBT->frm_samples = 0;
82*aef9bcd9SKiyoung Kim     hLdacBT->sfid = UNSET;
83*aef9bcd9SKiyoung Kim     hLdacBT->pcm.sf = UNSET;
84*aef9bcd9SKiyoung Kim     hLdacBT->tx.mtu = UNSET;
85*aef9bcd9SKiyoung Kim     hLdacBT->tx.tx_size = UNSET;
86*aef9bcd9SKiyoung Kim     hLdacBT->tx.pkt_hdr_sz = UNSET;
87*aef9bcd9SKiyoung Kim     hLdacBT->frmlen_tx = UNSET;
88*aef9bcd9SKiyoung Kim     hLdacBT->tx.nfrm_in_pkt = UNSET;
89*aef9bcd9SKiyoung Kim     hLdacBT->pcm.ch = 0;
90*aef9bcd9SKiyoung Kim     hLdacBT->pcm.fmt = LDACBT_SMPL_FMT_S24;
91*aef9bcd9SKiyoung Kim     hLdacBT->nshift = 0;
92*aef9bcd9SKiyoung Kim     hLdacBT->frmlen = UNSET;
93*aef9bcd9SKiyoung Kim     hLdacBT->frm_status = 0;
94*aef9bcd9SKiyoung Kim     hLdacBT->bitrate = 0;
95*aef9bcd9SKiyoung Kim     /* for alter frame length */
96*aef9bcd9SKiyoung Kim     hLdacBT->tgt_nfrm_in_pkt = UNSET;
97*aef9bcd9SKiyoung Kim     hLdacBT->tgt_frmlen = UNSET;
98*aef9bcd9SKiyoung Kim     hLdacBT->tgt_eqmid = UNSET;
99*aef9bcd9SKiyoung Kim     hLdacBT->stat_alter_op = LDACBT_ALTER_OP__NON;
100*aef9bcd9SKiyoung Kim 
101*aef9bcd9SKiyoung Kim     hLdacBT->cm = UNSET;
102*aef9bcd9SKiyoung Kim     hLdacBT->cci = UNSET;
103*aef9bcd9SKiyoung Kim     hLdacBT->eqmid = UNSET;
104*aef9bcd9SKiyoung Kim     hLdacBT->transport = UNSET;
105*aef9bcd9SKiyoung Kim 
106*aef9bcd9SKiyoung Kim     clear_data_ldac( hLdacBT->ldac_trns_frm_buf.buf, sizeof(hLdacBT->ldac_trns_frm_buf.buf));
107*aef9bcd9SKiyoung Kim     hLdacBT->ldac_trns_frm_buf.used = 0;
108*aef9bcd9SKiyoung Kim     hLdacBT->ldac_trns_frm_buf.nfrm_in = 0;
109*aef9bcd9SKiyoung Kim 
110*aef9bcd9SKiyoung Kim     clear_data_ldac( hLdacBT->pcmring.buf, sizeof(hLdacBT->pcmring.buf));
111*aef9bcd9SKiyoung Kim     hLdacBT->pcmring.wp = 0;
112*aef9bcd9SKiyoung Kim     hLdacBT->pcmring.rp = 0;
113*aef9bcd9SKiyoung Kim     hLdacBT->pcmring.nsmpl = 0;
114*aef9bcd9SKiyoung Kim /* work buffer for I/O */
115*aef9bcd9SKiyoung Kim     for( ich = 0; ich < LDAC_PRCNCH; ich++ ){
116*aef9bcd9SKiyoung Kim         hLdacBT->ap_pcm[ich] = &hLdacBT->a_pcm[ ich * LDACBT_MAX_LSU * LDACBT_PCM_WLEN_MAX ];
117*aef9bcd9SKiyoung Kim     }
118*aef9bcd9SKiyoung Kim     hLdacBT->pp_pcm = hLdacBT->ap_pcm;
119*aef9bcd9SKiyoung Kim     clear_data_ldac( hLdacBT->a_pcm, LDAC_PRCNCH * LDACBT_MAX_LSU * LDACBT_PCM_WLEN_MAX );
120*aef9bcd9SKiyoung Kim 
121*aef9bcd9SKiyoung Kim }
122*aef9bcd9SKiyoung Kim 
123*aef9bcd9SKiyoung Kim /* get ldaclib error code */
ldacBT_check_ldaclib_error_code(HANDLE_LDAC_BT hLdacBT)124*aef9bcd9SKiyoung Kim DECLFUNC int ldacBT_check_ldaclib_error_code(HANDLE_LDAC_BT hLdacBT)
125*aef9bcd9SKiyoung Kim {
126*aef9bcd9SKiyoung Kim     HANDLE_LDAC hData;
127*aef9bcd9SKiyoung Kim     int error_code, internal_error_code;
128*aef9bcd9SKiyoung Kim 
129*aef9bcd9SKiyoung Kim     if( hLdacBT == NULL ){ return LDACBT_E_FAIL; }
130*aef9bcd9SKiyoung Kim     if( (hData = hLdacBT->hLDAC) == NULL ){ return LDACBT_E_FAIL; }
131*aef9bcd9SKiyoung Kim 
132*aef9bcd9SKiyoung Kim     ldaclib_get_error_code(hData, &error_code);
133*aef9bcd9SKiyoung Kim 
134*aef9bcd9SKiyoung Kim     ldaclib_get_internal_error_code(hData, &internal_error_code);
135*aef9bcd9SKiyoung Kim 
136*aef9bcd9SKiyoung Kim     hLdacBT->error_code = error_code << 10 | internal_error_code;
137*aef9bcd9SKiyoung Kim 
138*aef9bcd9SKiyoung Kim     return LDACBT_S_OK;
139*aef9bcd9SKiyoung Kim }
140*aef9bcd9SKiyoung Kim 
141*aef9bcd9SKiyoung Kim /* Assertions. */
ldacBT_assert_cm(int cm)142*aef9bcd9SKiyoung Kim DECLFUNC int ldacBT_assert_cm( int cm )
143*aef9bcd9SKiyoung Kim {
144*aef9bcd9SKiyoung Kim     if( (cm != LDACBT_CHANNEL_MODE_STEREO )
145*aef9bcd9SKiyoung Kim         && (cm != LDACBT_CHANNEL_MODE_DUAL_CHANNEL )
146*aef9bcd9SKiyoung Kim         && (cm != LDACBT_CHANNEL_MODE_MONO )
147*aef9bcd9SKiyoung Kim     ){
148*aef9bcd9SKiyoung Kim         return LDACBT_ERR_ASSERT_CHANNEL_MODE;
149*aef9bcd9SKiyoung Kim     }
150*aef9bcd9SKiyoung Kim     return LDACBT_ERR_NONE;
151*aef9bcd9SKiyoung Kim }
ldacBT_assert_cci(int cci)152*aef9bcd9SKiyoung Kim UNUSED_ATTR DECLFUNC int ldacBT_assert_cci( int cci )
153*aef9bcd9SKiyoung Kim {
154*aef9bcd9SKiyoung Kim     if( (cci != LDAC_CCI_STEREO )
155*aef9bcd9SKiyoung Kim         && (cci != LDAC_CCI_DUAL_CHANNEL )
156*aef9bcd9SKiyoung Kim         && (cci != LDAC_CCI_MONO )
157*aef9bcd9SKiyoung Kim     ){
158*aef9bcd9SKiyoung Kim         return LDACBT_ERR_ASSERT_CHANNEL_CONFIG;
159*aef9bcd9SKiyoung Kim     }
160*aef9bcd9SKiyoung Kim     return LDACBT_ERR_NONE;
161*aef9bcd9SKiyoung Kim }
ldacBT_assert_sample_format(LDACBT_SMPL_FMT_T fmt)162*aef9bcd9SKiyoung Kim DECLFUNC int ldacBT_assert_sample_format( LDACBT_SMPL_FMT_T fmt )
163*aef9bcd9SKiyoung Kim {
164*aef9bcd9SKiyoung Kim #ifndef _32BIT_FIXED_POINT
165*aef9bcd9SKiyoung Kim     if( (fmt != LDACBT_SMPL_FMT_S16)
166*aef9bcd9SKiyoung Kim         && (fmt != LDACBT_SMPL_FMT_S24)
167*aef9bcd9SKiyoung Kim         && (fmt != LDACBT_SMPL_FMT_S32)
168*aef9bcd9SKiyoung Kim         && (fmt != LDACBT_SMPL_FMT_F32)
169*aef9bcd9SKiyoung Kim     ){
170*aef9bcd9SKiyoung Kim #else /* _32BIT_FIXED_POINT */
171*aef9bcd9SKiyoung Kim     if( (fmt != LDACBT_SMPL_FMT_S16)
172*aef9bcd9SKiyoung Kim         && (fmt != LDACBT_SMPL_FMT_S24)
173*aef9bcd9SKiyoung Kim         && (fmt != LDACBT_SMPL_FMT_S32)
174*aef9bcd9SKiyoung Kim     ){
175*aef9bcd9SKiyoung Kim #endif /* _32BIT_FIXED_POINT */
176*aef9bcd9SKiyoung Kim         return LDACBT_ERR_ILL_SMPL_FORMAT;
177*aef9bcd9SKiyoung Kim     }
178*aef9bcd9SKiyoung Kim     return LDACBT_ERR_NONE;
179*aef9bcd9SKiyoung Kim }
180*aef9bcd9SKiyoung Kim DECLFUNC int ldacBT_assert_pcm_sampling_freq( int sampling_freq )
181*aef9bcd9SKiyoung Kim {
182*aef9bcd9SKiyoung Kim     if( (sampling_freq != 1*44100) && (sampling_freq != 1*48000)
183*aef9bcd9SKiyoung Kim         && (sampling_freq != 2*44100) && (sampling_freq != 2*48000)
184*aef9bcd9SKiyoung Kim     ){
185*aef9bcd9SKiyoung Kim         return LDACBT_ERR_ILL_SAMPLING_FREQ;
186*aef9bcd9SKiyoung Kim     }
187*aef9bcd9SKiyoung Kim     return LDACBT_ERR_NONE;
188*aef9bcd9SKiyoung Kim }
189*aef9bcd9SKiyoung Kim DECLFUNC int ldacBT_assert_mtu( int mtu )
190*aef9bcd9SKiyoung Kim {
191*aef9bcd9SKiyoung Kim     if( mtu < LDACBT_MTU_REQUIRED ){
192*aef9bcd9SKiyoung Kim         return LDACBT_ERR_ILL_MTU_SIZE;
193*aef9bcd9SKiyoung Kim     }
194*aef9bcd9SKiyoung Kim     return LDACBT_ERR_NONE;
195*aef9bcd9SKiyoung Kim }
196*aef9bcd9SKiyoung Kim DECLFUNC int ldacBT_assert_eqmid( int eqmid )
197*aef9bcd9SKiyoung Kim {
198*aef9bcd9SKiyoung Kim     if( (eqmid == LDACBT_EQMID_HQ) || (eqmid == LDACBT_EQMID_SQ) || (eqmid == LDACBT_EQMID_MQ)){
199*aef9bcd9SKiyoung Kim         return LDACBT_ERR_NONE;
200*aef9bcd9SKiyoung Kim     }
201*aef9bcd9SKiyoung Kim 
202*aef9bcd9SKiyoung Kim     return LDACBT_ERR_ILL_EQMID;
203*aef9bcd9SKiyoung Kim }
204*aef9bcd9SKiyoung Kim 
205*aef9bcd9SKiyoung Kim /* LDAC set Encode Quality Mode index core */
206*aef9bcd9SKiyoung Kim DECLFUNC void ldacBT_set_eqmid_core( HANDLE_LDAC_BT hLdacBT, int eqmid )
207*aef9bcd9SKiyoung Kim {
208*aef9bcd9SKiyoung Kim     /* "eqmid" must be checked before calling this function. */
209*aef9bcd9SKiyoung Kim     /* just update tgt_eqmid */
210*aef9bcd9SKiyoung Kim     P_LDACBT_CONFIG pCfg;
211*aef9bcd9SKiyoung Kim     pCfg = ldacBT_get_config( eqmid, hLdacBT->tx.pkt_type );
212*aef9bcd9SKiyoung Kim     hLdacBT->tgt_eqmid = eqmid;
213*aef9bcd9SKiyoung Kim     hLdacBT->tgt_frmlen = hLdacBT->pcm.ch * pCfg->frmlen_1ch;
214*aef9bcd9SKiyoung Kim     hLdacBT->tgt_frmlen -= LDACBT_FRMHDRBYTES;
215*aef9bcd9SKiyoung Kim     hLdacBT->tgt_nfrm_in_pkt = pCfg->nfrm_in_pkt;
216*aef9bcd9SKiyoung Kim 
217*aef9bcd9SKiyoung Kim }
218*aef9bcd9SKiyoung Kim 
219*aef9bcd9SKiyoung Kim /* Split LR interleaved PCM into buffer that for LDAC encode. */
220*aef9bcd9SKiyoung Kim DECLFUNC void ldacBT_prepare_pcm_encode( void *pbuff, char **ap_pcm, int nsmpl, int nch,
221*aef9bcd9SKiyoung Kim                      LDACBT_SMPL_FMT_T fmt )
222*aef9bcd9SKiyoung Kim {
223*aef9bcd9SKiyoung Kim     int i;
224*aef9bcd9SKiyoung Kim     if( nch == 2 ){
225*aef9bcd9SKiyoung Kim         if( fmt == LDACBT_SMPL_FMT_S16 ){
226*aef9bcd9SKiyoung Kim             short *p_pcm_16 = (short *)pbuff;
227*aef9bcd9SKiyoung Kim             short *p_lch_16 = (short *)ap_pcm[0];
228*aef9bcd9SKiyoung Kim             short *p_rch_16 = (short *)ap_pcm[1];
229*aef9bcd9SKiyoung Kim             for (i = 0; i < nsmpl; i++) {
230*aef9bcd9SKiyoung Kim                 *p_lch_16++ = p_pcm_16[0];
231*aef9bcd9SKiyoung Kim                 *p_rch_16++ = p_pcm_16[1];
232*aef9bcd9SKiyoung Kim                 p_pcm_16+=2;
233*aef9bcd9SKiyoung Kim             }
234*aef9bcd9SKiyoung Kim         }
235*aef9bcd9SKiyoung Kim         else if( fmt == LDACBT_SMPL_FMT_S24 ){
236*aef9bcd9SKiyoung Kim             char *p_pcm_8 = (char *)pbuff;
237*aef9bcd9SKiyoung Kim             char *p_lch_8 = (char *)ap_pcm[0];
238*aef9bcd9SKiyoung Kim             char *p_rch_8 = (char *)ap_pcm[1];
239*aef9bcd9SKiyoung Kim #if __BYTE_ORDER == __LITTLE_ENDIAN
240*aef9bcd9SKiyoung Kim             for (i = 0; i < nsmpl; i++) {
241*aef9bcd9SKiyoung Kim                 *p_lch_8++ = p_pcm_8[0];
242*aef9bcd9SKiyoung Kim                 *p_lch_8++ = p_pcm_8[1];
243*aef9bcd9SKiyoung Kim                 *p_lch_8++ = p_pcm_8[2];
244*aef9bcd9SKiyoung Kim                 p_pcm_8+=3;
245*aef9bcd9SKiyoung Kim                 *p_rch_8++ = p_pcm_8[0];
246*aef9bcd9SKiyoung Kim                 *p_rch_8++ = p_pcm_8[1];
247*aef9bcd9SKiyoung Kim                 *p_rch_8++ = p_pcm_8[2];
248*aef9bcd9SKiyoung Kim                 p_pcm_8+=3;
249*aef9bcd9SKiyoung Kim             }
250*aef9bcd9SKiyoung Kim #else   /* __BYTE_ORDER */
251*aef9bcd9SKiyoung Kim #error unsupported byte order
252*aef9bcd9SKiyoung Kim #endif  /* #if __BYTE_ORDER == __LITTLE_ENDIAN */
253*aef9bcd9SKiyoung Kim         }
254*aef9bcd9SKiyoung Kim         else if ( fmt == LDACBT_SMPL_FMT_S32 ){
255*aef9bcd9SKiyoung Kim             char *p_pcm_8 = (char *)pbuff;
256*aef9bcd9SKiyoung Kim             char *p_lch_8 = (char *)ap_pcm[0];
257*aef9bcd9SKiyoung Kim             char *p_rch_8 = (char *)ap_pcm[1];
258*aef9bcd9SKiyoung Kim #if __BYTE_ORDER == __LITTLE_ENDIAN
259*aef9bcd9SKiyoung Kim             for (i = 0; i < nsmpl; i++) {
260*aef9bcd9SKiyoung Kim                 *p_lch_8++ = p_pcm_8[0]; *p_lch_8++ = p_pcm_8[1]; *p_lch_8++ = p_pcm_8[2]; *p_lch_8++ = p_pcm_8[3];
261*aef9bcd9SKiyoung Kim                 p_pcm_8+=4;
262*aef9bcd9SKiyoung Kim                 *p_rch_8++ = p_pcm_8[0]; *p_rch_8++ = p_pcm_8[1]; *p_rch_8++ = p_pcm_8[2]; *p_rch_8++ = p_pcm_8[3];
263*aef9bcd9SKiyoung Kim                 p_pcm_8+=4;
264*aef9bcd9SKiyoung Kim             }
265*aef9bcd9SKiyoung Kim #else   /* __BYTE_ORDER */
266*aef9bcd9SKiyoung Kim #error unsupported byte order
267*aef9bcd9SKiyoung Kim #endif  /* #if __BYTE_ORDER == __LITTLE_ENDIAN */
268*aef9bcd9SKiyoung Kim         }
269*aef9bcd9SKiyoung Kim         else if ( fmt == LDACBT_SMPL_FMT_F32 ){
270*aef9bcd9SKiyoung Kim             float *p_pcm = (float *)pbuff;
271*aef9bcd9SKiyoung Kim             float *p_lch = (float *)ap_pcm[0];
272*aef9bcd9SKiyoung Kim             float *p_rch = (float *)ap_pcm[1];
273*aef9bcd9SKiyoung Kim             for (i = 0; i < nsmpl; i++) {
274*aef9bcd9SKiyoung Kim                 *p_lch++ = p_pcm[0];
275*aef9bcd9SKiyoung Kim                 p_pcm++;
276*aef9bcd9SKiyoung Kim                 *p_rch++ = p_pcm[0];
277*aef9bcd9SKiyoung Kim                 p_pcm++;
278*aef9bcd9SKiyoung Kim             }
279*aef9bcd9SKiyoung Kim         }
280*aef9bcd9SKiyoung Kim         else{;} /* never be happend */
281*aef9bcd9SKiyoung Kim     }
282*aef9bcd9SKiyoung Kim     else if( nch == 1 ){
283*aef9bcd9SKiyoung Kim         switch(fmt){
284*aef9bcd9SKiyoung Kim           case LDACBT_SMPL_FMT_S16:
285*aef9bcd9SKiyoung Kim             copy_data_ldac( pbuff, ap_pcm[0], 2*nsmpl );
286*aef9bcd9SKiyoung Kim             break;
287*aef9bcd9SKiyoung Kim           case LDACBT_SMPL_FMT_S24:
288*aef9bcd9SKiyoung Kim             copy_data_ldac( pbuff, ap_pcm[0], 3*nsmpl );
289*aef9bcd9SKiyoung Kim             break;
290*aef9bcd9SKiyoung Kim           case LDACBT_SMPL_FMT_S32:
291*aef9bcd9SKiyoung Kim           case LDACBT_SMPL_FMT_F32:
292*aef9bcd9SKiyoung Kim             copy_data_ldac( pbuff, ap_pcm[0], 4*nsmpl );
293*aef9bcd9SKiyoung Kim             break;
294*aef9bcd9SKiyoung Kim           default:
295*aef9bcd9SKiyoung Kim             break;
296*aef9bcd9SKiyoung Kim         }
297*aef9bcd9SKiyoung Kim     }
298*aef9bcd9SKiyoung Kim }
299*aef9bcd9SKiyoung Kim 
300*aef9bcd9SKiyoung Kim 
301*aef9bcd9SKiyoung Kim /* update framelength */
302*aef9bcd9SKiyoung Kim DECLFUNC int ldacBT_update_frmlen(HANDLE_LDAC_BT hLdacBT, int frmlen)
303*aef9bcd9SKiyoung Kim {
304*aef9bcd9SKiyoung Kim     int status, sf, ch, fl, fl_per_ch;
305*aef9bcd9SKiyoung Kim     int nbasebands, grad_mode, grad_qu_l, grad_qu_h, grad_ofst_l, grad_ofst_h, abc_flag;
306*aef9bcd9SKiyoung Kim     LDACBT_TX_INFO *ptx;
307*aef9bcd9SKiyoung Kim     LDAC_RESULT result;
308*aef9bcd9SKiyoung Kim     status = LDACBT_E_FAIL;
309*aef9bcd9SKiyoung Kim 
310*aef9bcd9SKiyoung Kim     if( hLdacBT == NULL ){
311*aef9bcd9SKiyoung Kim         return LDACBT_E_FAIL;
312*aef9bcd9SKiyoung Kim     }
313*aef9bcd9SKiyoung Kim     sf = hLdacBT->pcm.sf; /* sampling frequency */
314*aef9bcd9SKiyoung Kim     ch = hLdacBT->pcm.ch; /* number of channels */
315*aef9bcd9SKiyoung Kim     ptx = &hLdacBT->tx;
316*aef9bcd9SKiyoung Kim 
317*aef9bcd9SKiyoung Kim ldac_setup_AGAIN:
318*aef9bcd9SKiyoung Kim     /* update LDAC parameters. */
319*aef9bcd9SKiyoung Kim 
320*aef9bcd9SKiyoung Kim 
321*aef9bcd9SKiyoung Kim     if( frmlen == UNSET ){
322*aef9bcd9SKiyoung Kim         goto ldac_setup_END;
323*aef9bcd9SKiyoung Kim     }
324*aef9bcd9SKiyoung Kim 
325*aef9bcd9SKiyoung Kim     /* check & update frameLength */
326*aef9bcd9SKiyoung Kim     ldaclib_get_encode_frame_length( hLdacBT->hLDAC, &fl );
327*aef9bcd9SKiyoung Kim     if( fl == 0 ){ // This meens that the handle was not initialized yet. Shall not happen.
328*aef9bcd9SKiyoung Kim 
329*aef9bcd9SKiyoung Kim         goto ldac_setup_END;
330*aef9bcd9SKiyoung Kim     }
331*aef9bcd9SKiyoung Kim     else if( frmlen == fl ){
332*aef9bcd9SKiyoung Kim         /* No need to update frame length. Just update bitrate information. */
333*aef9bcd9SKiyoung Kim         status = LDACBT_S_OK;
334*aef9bcd9SKiyoung Kim         hLdacBT->bitrate = ldacBT_frmlen_to_bitrate( fl, 1, sf, hLdacBT->frm_samples );
335*aef9bcd9SKiyoung Kim         goto ldac_setup_END;
336*aef9bcd9SKiyoung Kim     }
337*aef9bcd9SKiyoung Kim 
338*aef9bcd9SKiyoung Kim     /* Time to update the frame_length. */
339*aef9bcd9SKiyoung Kim     /* Get ldac encoding information for frame_length. */
340*aef9bcd9SKiyoung Kim     fl_per_ch = (frmlen+LDACBT_FRMHDRBYTES) / ch;
341*aef9bcd9SKiyoung Kim     result = ldaclib_get_encode_setting( fl_per_ch, hLdacBT->sfid, &nbasebands,
342*aef9bcd9SKiyoung Kim                      &grad_mode, &grad_qu_l, &grad_qu_h, &grad_ofst_l, &grad_ofst_h, &abc_flag);
343*aef9bcd9SKiyoung Kim     if (LDAC_FAILED(result)) {
344*aef9bcd9SKiyoung Kim         goto ldac_setup_END;
345*aef9bcd9SKiyoung Kim     }
346*aef9bcd9SKiyoung Kim     /* Set Encoding Information */
347*aef9bcd9SKiyoung Kim     result = ldaclib_set_encode_info( hLdacBT->hLDAC, nbasebands, grad_mode,
348*aef9bcd9SKiyoung Kim                                grad_qu_l, grad_qu_h, grad_ofst_l, grad_ofst_h, abc_flag);
349*aef9bcd9SKiyoung Kim     if (LDAC_FAILED(result)) {
350*aef9bcd9SKiyoung Kim         ldacBT_check_ldaclib_error_code(hLdacBT);
351*aef9bcd9SKiyoung Kim         goto ldac_setup_END;
352*aef9bcd9SKiyoung Kim     }
353*aef9bcd9SKiyoung Kim 
354*aef9bcd9SKiyoung Kim     if( !LDAC_SUCCEEDED(ldaclib_set_encode_frame_length( hLdacBT->hLDAC, frmlen ))){
355*aef9bcd9SKiyoung Kim         goto ldac_setup_END;
356*aef9bcd9SKiyoung Kim     }
357*aef9bcd9SKiyoung Kim 
358*aef9bcd9SKiyoung Kim     /* Update parameters in handle. */
359*aef9bcd9SKiyoung Kim     hLdacBT->frmlen = frmlen;
360*aef9bcd9SKiyoung Kim     hLdacBT->frmlen_tx = LDACBT_FRMHDRBYTES + frmlen;
361*aef9bcd9SKiyoung Kim     ptx->nfrm_in_pkt = ptx->tx_size / hLdacBT->frmlen_tx;
362*aef9bcd9SKiyoung Kim     if( ptx->nfrm_in_pkt > LDACBT_NFRM_TX_MAX ){
363*aef9bcd9SKiyoung Kim         ptx->nfrm_in_pkt = LDACBT_NFRM_TX_MAX;
364*aef9bcd9SKiyoung Kim     }
365*aef9bcd9SKiyoung Kim     else if( ptx->nfrm_in_pkt < 2 ){
366*aef9bcd9SKiyoung Kim         /* Not allowed 1frame/packet transportation for current version of LDAC A2DP */
367*aef9bcd9SKiyoung Kim         if( frmlen <= (ptx->tx_size / 2 - LDACBT_FRMHDRBYTES)){
368*aef9bcd9SKiyoung Kim             goto ldac_setup_END;
369*aef9bcd9SKiyoung Kim         }
370*aef9bcd9SKiyoung Kim         frmlen = ptx->tx_size / 2 - LDACBT_FRMHDRBYTES;
371*aef9bcd9SKiyoung Kim         goto ldac_setup_AGAIN;
372*aef9bcd9SKiyoung Kim     }
373*aef9bcd9SKiyoung Kim     /* Update bitrate and EQMID. */
374*aef9bcd9SKiyoung Kim     hLdacBT->bitrate = ldacBT_frmlen_to_bitrate( frmlen, 1, sf, hLdacBT->frm_samples );
375*aef9bcd9SKiyoung Kim     hLdacBT->eqmid = ldacBT_get_eqmid_from_frmlen( frmlen, ch, hLdacBT->transport, ptx->pkt_type );
376*aef9bcd9SKiyoung Kim     if( hLdacBT->tgt_eqmid == UNSET){
377*aef9bcd9SKiyoung Kim         hLdacBT->eqmid = UNSET;
378*aef9bcd9SKiyoung Kim     }
379*aef9bcd9SKiyoung Kim     status = LDACBT_S_OK;
380*aef9bcd9SKiyoung Kim 
381*aef9bcd9SKiyoung Kim ldac_setup_END:
382*aef9bcd9SKiyoung Kim     return status;
383*aef9bcd9SKiyoung Kim }
384*aef9bcd9SKiyoung Kim 
385*aef9bcd9SKiyoung Kim /* Get channel_config_index from channel_mode.
386*aef9bcd9SKiyoung Kim  * The argument cm, channel_mode, must be checked by function ldacBT_assert_cm() before calling this
387*aef9bcd9SKiyoung Kim  * function.
388*aef9bcd9SKiyoung Kim  */
389*aef9bcd9SKiyoung Kim DECLFUNC int  ldacBT_cm_to_cci( int cm )
390*aef9bcd9SKiyoung Kim {
391*aef9bcd9SKiyoung Kim     if( cm == LDACBT_CHANNEL_MODE_STEREO ){
392*aef9bcd9SKiyoung Kim         return LDAC_CCI_STEREO;
393*aef9bcd9SKiyoung Kim     }
394*aef9bcd9SKiyoung Kim     else if( cm == LDACBT_CHANNEL_MODE_DUAL_CHANNEL ){
395*aef9bcd9SKiyoung Kim         return LDAC_CCI_DUAL_CHANNEL;
396*aef9bcd9SKiyoung Kim     }
397*aef9bcd9SKiyoung Kim     else/* if( cm == LDACBT_CHANNEL_MODE_MONO )*/{
398*aef9bcd9SKiyoung Kim         return LDAC_CCI_MONO;
399*aef9bcd9SKiyoung Kim     }
400*aef9bcd9SKiyoung Kim }
401*aef9bcd9SKiyoung Kim 
402*aef9bcd9SKiyoung Kim /* Get channel_mode from channel_config_index.
403*aef9bcd9SKiyoung Kim  * The argument cci, channel_config_index, must be checked by the function ldacBT_assert_cci() before
404*aef9bcd9SKiyoung Kim  * calling this function.
405*aef9bcd9SKiyoung Kim  */
406*aef9bcd9SKiyoung Kim UNUSED_ATTR DECLFUNC int  ldacBT_cci_to_cm( int cci )
407*aef9bcd9SKiyoung Kim {
408*aef9bcd9SKiyoung Kim     if( cci == LDAC_CCI_STEREO ){
409*aef9bcd9SKiyoung Kim         return LDACBT_CHANNEL_MODE_STEREO;
410*aef9bcd9SKiyoung Kim     }
411*aef9bcd9SKiyoung Kim     else if( cci == LDAC_CCI_DUAL_CHANNEL ){
412*aef9bcd9SKiyoung Kim         return LDACBT_CHANNEL_MODE_DUAL_CHANNEL;
413*aef9bcd9SKiyoung Kim     }
414*aef9bcd9SKiyoung Kim     else/* if( cci == LDAC_CCI_MONO )*/{
415*aef9bcd9SKiyoung Kim         return LDACBT_CHANNEL_MODE_MONO;
416*aef9bcd9SKiyoung Kim     }
417*aef9bcd9SKiyoung Kim }
418*aef9bcd9SKiyoung Kim 
419*aef9bcd9SKiyoung Kim /* Get bitrate from frame length */
420*aef9bcd9SKiyoung Kim DECLFUNC int ldacBT_frmlen_to_bitrate( int frmlen, int flgFrmHdr, int sf, int frame_samples )
421*aef9bcd9SKiyoung Kim {
422*aef9bcd9SKiyoung Kim     int bitrate;
423*aef9bcd9SKiyoung Kim     if( (frmlen == UNSET) || (flgFrmHdr == UNSET) || (sf == UNSET) || (frame_samples == UNSET) ){
424*aef9bcd9SKiyoung Kim         return LDACBT_E_FAIL;
425*aef9bcd9SKiyoung Kim     }
426*aef9bcd9SKiyoung Kim     if( flgFrmHdr ){
427*aef9bcd9SKiyoung Kim         frmlen += LDACBT_FRMHDRBYTES;
428*aef9bcd9SKiyoung Kim     }
429*aef9bcd9SKiyoung Kim     bitrate  = frmlen * sf / frame_samples / (1000 / 8);
430*aef9bcd9SKiyoung Kim     return bitrate;
431*aef9bcd9SKiyoung Kim }
432*aef9bcd9SKiyoung Kim 
433*aef9bcd9SKiyoung Kim /* Get Encode Quality Mode index property */
434*aef9bcd9SKiyoung Kim DECLFUNC P_LDACBT_EQMID_PROPERTY ldacBT_get_eqmid_conv_tbl ( int eqmid )
435*aef9bcd9SKiyoung Kim {
436*aef9bcd9SKiyoung Kim     int i, tbl_size;
437*aef9bcd9SKiyoung Kim     P_LDACBT_EQMID_PROPERTY pEqmIdProp;
438*aef9bcd9SKiyoung Kim 
439*aef9bcd9SKiyoung Kim     pEqmIdProp = (P_LDACBT_EQMID_PROPERTY)tbl_ldacbt_eqmid_property;
440*aef9bcd9SKiyoung Kim     tbl_size = (int)(sizeof(tbl_ldacbt_eqmid_property)/sizeof(tbl_ldacbt_eqmid_property[0]));
441*aef9bcd9SKiyoung Kim     /* Search current eqmid */
442*aef9bcd9SKiyoung Kim     for( i = 0; i < tbl_size; ++i, ++pEqmIdProp ){
443*aef9bcd9SKiyoung Kim         if( pEqmIdProp->eqmid == eqmid ){
444*aef9bcd9SKiyoung Kim             return pEqmIdProp;
445*aef9bcd9SKiyoung Kim         }
446*aef9bcd9SKiyoung Kim     }
447*aef9bcd9SKiyoung Kim     return NULL;
448*aef9bcd9SKiyoung Kim }
449*aef9bcd9SKiyoung Kim 
450*aef9bcd9SKiyoung Kim /* Get altered Encode Quality Mode index */
451*aef9bcd9SKiyoung Kim DECLFUNC int ldacBT_get_altered_eqmid ( HANDLE_LDAC_BT hLdacBT, int priority )
452*aef9bcd9SKiyoung Kim {
453*aef9bcd9SKiyoung Kim     int i, eqmid_0, eqmid_1, eqmid_new, tbl_size;
454*aef9bcd9SKiyoung Kim     if( priority == 0 ){ return LDACBT_E_FAIL; }
455*aef9bcd9SKiyoung Kim     switch( hLdacBT->tx.pkt_type ){
456*aef9bcd9SKiyoung Kim       case _2_DH5:
457*aef9bcd9SKiyoung Kim         break;
458*aef9bcd9SKiyoung Kim       default:
459*aef9bcd9SKiyoung Kim         return LDACBT_E_FAIL;
460*aef9bcd9SKiyoung Kim     }
461*aef9bcd9SKiyoung Kim     tbl_size = (int)(sizeof(tbl_ldacbt_eqmid_property)/sizeof(tbl_ldacbt_eqmid_property[0]));
462*aef9bcd9SKiyoung Kim     /* Search target eqmid */
463*aef9bcd9SKiyoung Kim     for( i = 0; i < tbl_size; ++i ){
464*aef9bcd9SKiyoung Kim         if( tbl_ldacbt_eqmid_property[i].eqmid == hLdacBT->tgt_eqmid ){
465*aef9bcd9SKiyoung Kim             break;
466*aef9bcd9SKiyoung Kim         }
467*aef9bcd9SKiyoung Kim     }
468*aef9bcd9SKiyoung Kim     eqmid_0 = i;
469*aef9bcd9SKiyoung Kim     eqmid_1 = eqmid_0 - priority;
470*aef9bcd9SKiyoung Kim     if( eqmid_1 < 0 ){ return LDACBT_E_FAIL; }
471*aef9bcd9SKiyoung Kim     if( eqmid_1 >= tbl_size ){ return LDACBT_E_FAIL; }
472*aef9bcd9SKiyoung Kim 
473*aef9bcd9SKiyoung Kim     eqmid_new = tbl_ldacbt_eqmid_property[eqmid_1].eqmid;
474*aef9bcd9SKiyoung Kim     for( i = 0; i < tbl_size; ++i ){
475*aef9bcd9SKiyoung Kim         if( tbl_ldacbt_eqmid_property[i].eqmid == LDACBT_LIMIT_ALTER_EQMID_PRIORITY ){
476*aef9bcd9SKiyoung Kim             break;
477*aef9bcd9SKiyoung Kim         }
478*aef9bcd9SKiyoung Kim     }
479*aef9bcd9SKiyoung Kim     if( eqmid_1 > i ){ return LDACBT_E_FAIL; }
480*aef9bcd9SKiyoung Kim     return eqmid_new;
481*aef9bcd9SKiyoung Kim 
482*aef9bcd9SKiyoung Kim }
483*aef9bcd9SKiyoung Kim 
484*aef9bcd9SKiyoung Kim /* Get LDAC bitrate info from Encode Quality Mode Index */
485*aef9bcd9SKiyoung Kim DECLFUNC P_LDACBT_CONFIG ldacBT_get_config( int ldac_bt_mode, int pkt_type )
486*aef9bcd9SKiyoung Kim {
487*aef9bcd9SKiyoung Kim     int i, tbl_size, ldac_mode_id;
488*aef9bcd9SKiyoung Kim     P_LDACBT_EQMID_PROPERTY pEqmIdProp;
489*aef9bcd9SKiyoung Kim     P_LDACBT_CONFIG pCfg;
490*aef9bcd9SKiyoung Kim 
491*aef9bcd9SKiyoung Kim     if( (pEqmIdProp = ldacBT_get_eqmid_conv_tbl( ldac_bt_mode )) == NULL ){
492*aef9bcd9SKiyoung Kim         return NULL;
493*aef9bcd9SKiyoung Kim     }
494*aef9bcd9SKiyoung Kim 
495*aef9bcd9SKiyoung Kim     if( pkt_type == _2_DH5 ){ ldac_mode_id = pEqmIdProp->id_for_2DH5;}
496*aef9bcd9SKiyoung Kim     else{
497*aef9bcd9SKiyoung Kim         return NULL;
498*aef9bcd9SKiyoung Kim     }
499*aef9bcd9SKiyoung Kim 
500*aef9bcd9SKiyoung Kim     pCfg = (P_LDACBT_CONFIG)tbl_ldacbt_config;
501*aef9bcd9SKiyoung Kim     tbl_size = (int)(sizeof(tbl_ldacbt_config)/sizeof(tbl_ldacbt_config[0]));
502*aef9bcd9SKiyoung Kim     for( i = 0; i < tbl_size; ++i, ++pCfg ){
503*aef9bcd9SKiyoung Kim         if( ldac_mode_id == pCfg->id ){
504*aef9bcd9SKiyoung Kim             return pCfg;
505*aef9bcd9SKiyoung Kim         }
506*aef9bcd9SKiyoung Kim     }
507*aef9bcd9SKiyoung Kim     return NULL; /* not found */
508*aef9bcd9SKiyoung Kim }
509*aef9bcd9SKiyoung Kim 
510*aef9bcd9SKiyoung Kim /* Get Encode Quality Mode Index from framelength */
511*aef9bcd9SKiyoung Kim DECLFUNC int ldacBT_get_eqmid_from_frmlen( int frmlen, int nch, int flgFrmHdr, int pktType )
512*aef9bcd9SKiyoung Kim {
513*aef9bcd9SKiyoung Kim     int i, n, eqmid;
514*aef9bcd9SKiyoung Kim     P_LDACBT_CONFIG pCfg;
515*aef9bcd9SKiyoung Kim 
516*aef9bcd9SKiyoung Kim     if( flgFrmHdr ){
517*aef9bcd9SKiyoung Kim         frmlen += LDACBT_FRMHDRBYTES;
518*aef9bcd9SKiyoung Kim     }
519*aef9bcd9SKiyoung Kim     if( nch > 0 ){
520*aef9bcd9SKiyoung Kim         frmlen /= nch;
521*aef9bcd9SKiyoung Kim     }
522*aef9bcd9SKiyoung Kim 
523*aef9bcd9SKiyoung Kim     eqmid = LDACBT_EQMID_END;
524*aef9bcd9SKiyoung Kim     n = (int)(sizeof(tbl_ldacbt_eqmid_property)/sizeof(tbl_ldacbt_eqmid_property[0]));
525*aef9bcd9SKiyoung Kim     for( i = 0; i < n; ++i ){
526*aef9bcd9SKiyoung Kim         if( (pCfg = ldacBT_get_config( tbl_ldacbt_eqmid_property[i].eqmid, pktType )) != NULL ){
527*aef9bcd9SKiyoung Kim             if( frmlen >= pCfg->frmlen_1ch){
528*aef9bcd9SKiyoung Kim                 eqmid = tbl_ldacbt_eqmid_property[i].eqmid;
529*aef9bcd9SKiyoung Kim                 break;
530*aef9bcd9SKiyoung Kim             }
531*aef9bcd9SKiyoung Kim         }
532*aef9bcd9SKiyoung Kim     }
533*aef9bcd9SKiyoung Kim     return eqmid;
534*aef9bcd9SKiyoung Kim }
535*aef9bcd9SKiyoung Kim 
536