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