1 /*
2 * Copyright (C) 2013 - 2017 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 "ldacBT_internal.h"
18
19
20 /* Get LDAC library version */
21 #define LDACBT_LIB_VER_MAJOR 2
22 #define LDACBT_LIB_VER_MINOR 0
23 #define LDACBT_LIB_VER_BRANCH 2
ldacBT_get_version(void)24 LDACBT_API int ldacBT_get_version( void )
25 {
26 return ((LDACBT_LIB_VER_MAJOR)<<16)|((LDACBT_LIB_VER_MINOR)<<8)|(LDACBT_LIB_VER_BRANCH);
27 }
28
29 /* Get LDAC handle */
ldacBT_get_handle(void)30 LDACBT_API HANDLE_LDAC_BT ldacBT_get_handle( void )
31 {
32 HANDLE_LDAC_BT hLdacBT;
33 hLdacBT = (HANDLE_LDAC_BT)malloc( sizeof(STRUCT_LDACBT_HANDLE) );
34 if( hLdacBT == NULL ){ return NULL; }
35
36 /* Get ldaclib Handler */
37 if( (hLdacBT->hLDAC = ldaclib_get_handle()) == NULL ){
38 ldacBT_free_handle( hLdacBT );
39 return NULL;
40 }
41
42 ldacBT_param_clear( hLdacBT );
43 return hLdacBT;
44 }
45
46 /* Free LDAC handle */
ldacBT_free_handle(HANDLE_LDAC_BT hLdacBT)47 LDACBT_API void ldacBT_free_handle( HANDLE_LDAC_BT hLdacBT )
48 {
49 if( hLdacBT == NULL ){ return; }
50
51 if( hLdacBT->hLDAC != NULL ){
52 /* close ldaclib handle */
53 if( hLdacBT->proc_mode == LDACBT_PROCMODE_ENCODE ){
54 ldaclib_free_encode( hLdacBT->hLDAC );
55 }
56 /* free ldaclib handle */
57 ldaclib_free_handle( hLdacBT->hLDAC );
58 hLdacBT->hLDAC = NULL;
59 }
60 /* free ldacbt handle */
61 free( hLdacBT );
62 }
63
64 /* Close LDAC handle */
ldacBT_close_handle(HANDLE_LDAC_BT hLdacBT)65 LDACBT_API void ldacBT_close_handle( HANDLE_LDAC_BT hLdacBT )
66 {
67 if( hLdacBT == NULL ){ return; }
68
69 if( hLdacBT->hLDAC != NULL ){
70 /* close ldaclib handle */
71 if( hLdacBT->proc_mode == LDACBT_PROCMODE_ENCODE ){
72 ldaclib_free_encode( hLdacBT->hLDAC );
73 }
74 /* clear error code */
75 ldaclib_clear_error_code(hLdacBT->hLDAC);
76 ldaclib_clear_internal_error_code(hLdacBT->hLDAC);
77 }
78 /* clear ldacbt handle */
79 ldacBT_param_clear( hLdacBT );
80 }
81
82
83 /* Get ERROR CODE */
ldacBT_get_error_code(HANDLE_LDAC_BT hLdacBT)84 LDACBT_API int ldacBT_get_error_code( HANDLE_LDAC_BT hLdacBT )
85 {
86 int error_code;
87 if( hLdacBT == NULL ){return LDACBT_ERR_FATAL_HANDLE<<10;}
88 ldacBT_check_ldaclib_error_code( hLdacBT );
89 if( hLdacBT->error_code_api == LDACBT_GET_LDACLIB_ERROR_CODE ){
90 error_code = LDACBT_ERR_FATAL << 20 | hLdacBT->error_code;
91 }else if( hLdacBT->error_code_api != LDACBT_ERR_NONE ){
92 error_code = hLdacBT->error_code_api << 20 | hLdacBT->error_code;
93 }else{
94 error_code = hLdacBT->error_code_api << 20;
95 }
96 return error_code;
97 }
98
99
100 /* Get Configured Sampling frequency */
ldacBT_get_sampling_freq(HANDLE_LDAC_BT hLdacBT)101 LDACBT_API int ldacBT_get_sampling_freq( HANDLE_LDAC_BT hLdacBT )
102 {
103 if( hLdacBT == NULL ){
104 return LDACBT_E_FAIL;
105 }
106 if( hLdacBT->proc_mode != LDACBT_PROCMODE_ENCODE )
107 {
108 hLdacBT->error_code_api = LDACBT_ERR_HANDLE_NOT_INIT;
109 return LDACBT_E_FAIL;
110 }
111 return hLdacBT->pcm.sf;
112 }
113
114 /* Get bitrate */
ldacBT_get_bitrate(HANDLE_LDAC_BT hLdacBT)115 LDACBT_API int ldacBT_get_bitrate( HANDLE_LDAC_BT hLdacBT )
116 {
117 if( hLdacBT == NULL ){
118 return LDACBT_E_FAIL;
119 }
120 if( hLdacBT->proc_mode != LDACBT_PROCMODE_ENCODE )
121 {
122 hLdacBT->error_code_api = LDACBT_ERR_HANDLE_NOT_INIT;
123 return LDACBT_E_FAIL;
124 }
125 return hLdacBT->bitrate;
126 }
127
128 /* Init LDAC handle for ENCODE */
ldacBT_init_handle_encode(HANDLE_LDAC_BT hLdacBT,int mtu,int eqmid,int cm,LDACBT_SMPL_FMT_T fmt,int sf)129 LDACBT_API int ldacBT_init_handle_encode( HANDLE_LDAC_BT hLdacBT, int mtu, int eqmid,
130 int cm, LDACBT_SMPL_FMT_T fmt, int sf )
131 {
132 LDAC_RESULT result;
133 int sfid, frame_samples, cci;
134 int nbasebands, grad_mode, grad_qu_l, grad_qu_h, grad_ofst_l, grad_ofst_h, abc_flag;
135 P_LDACBT_CONFIG pCfg;
136 const int a_cci_nch[] = { 1, 2, 2 };
137
138 /* check arguments */
139 if( hLdacBT == NULL ){ return LDACBT_E_FAIL; }
140 if( (hLdacBT->error_code_api = ldacBT_assert_mtu( mtu )) != LDACBT_ERR_NONE ){
141 return LDACBT_E_FAIL;
142 }
143 if( (hLdacBT->error_code_api = ldacBT_assert_eqmid( eqmid )) != LDACBT_ERR_NONE ){
144 return LDACBT_E_FAIL;
145 }
146 if( (hLdacBT->error_code_api = ldacBT_assert_cm( cm )) != LDACBT_ERR_NONE ){
147 return LDACBT_E_FAIL;
148 }
149 if( (hLdacBT->error_code_api = ldacBT_assert_sample_format( fmt )) != LDACBT_ERR_NONE ){
150 return LDACBT_E_FAIL;
151 }
152 if( (hLdacBT->error_code_api = ldacBT_assert_pcm_sampling_freq( sf )) != LDACBT_ERR_NONE ){
153 return LDACBT_E_FAIL;
154 }
155
156 ldacBT_close_handle( hLdacBT );
157
158 /* initialize handle for encode processing */
159 hLdacBT->proc_mode = LDACBT_PROCMODE_ENCODE;
160 hLdacBT->flg_encode_flushed = FALSE;
161
162 /* transport setting */
163 /* The ldac frame header is REQUIRED for A2DP streaming. */
164 hLdacBT->transport = TRUE;
165 hLdacBT->tx.mtu = mtu;
166 hLdacBT->tx.pkt_hdr_sz = LDACBT_TX_HEADER_SIZE;
167 hLdacBT->tx.tx_size = LDACBT_MTU_REQUIRED;
168 hLdacBT->tx.pkt_type = _2_DH5;
169 /* - BT TRANS HEADER etc */
170 hLdacBT->tx.tx_size -= hLdacBT->tx.pkt_hdr_sz;
171 if( hLdacBT->tx.tx_size > (hLdacBT->tx.mtu - hLdacBT->tx.pkt_hdr_sz) ){
172 /* never happen, mtu must be larger than LDACBT_MTU_REQUIRED(2DH5) */
173 hLdacBT->tx.tx_size = (hLdacBT->tx.mtu - hLdacBT->tx.pkt_hdr_sz);
174 }
175
176 /* channel configration */
177 cci = ldacBT_cm_to_cci(cm);
178 hLdacBT->cm = cm;
179 hLdacBT->cci = cci;
180 /* input pcm configuration */
181 hLdacBT->pcm.ch = a_cci_nch[cci];
182 hLdacBT->pcm.sf = sf;
183 hLdacBT->pcm.fmt = fmt;
184 switch(hLdacBT->pcm.fmt){
185 case LDACBT_SMPL_FMT_S16:
186 hLdacBT->pcm.wl = 2;
187 break;
188 case LDACBT_SMPL_FMT_S24:
189 hLdacBT->pcm.wl = 3;
190 break;
191 case LDACBT_SMPL_FMT_S32:
192 case LDACBT_SMPL_FMT_F32:
193 hLdacBT->pcm.wl = 4;
194 break;
195 default:
196 // must be rejected by ldacBT_assert_sample_format()
197 hLdacBT->pcm.wl = 4;
198 break;
199 }
200
201 /* initilize ldac encode */
202 /* Get sampling frequency index */
203 result = ldaclib_get_sampling_rate_index( hLdacBT->pcm.sf, &sfid );
204 if( LDAC_FAILED ( result ) ){
205 hLdacBT->error_code_api = LDACBT_ERR_ILL_SAMPLING_FREQ;
206 return LDACBT_E_FAIL;
207 }
208 hLdacBT->sfid = sfid;
209
210 /* Get number of frame samples */
211 result = ldaclib_get_frame_samples(sfid, &frame_samples);
212 if (LDAC_FAILED(result)) {
213 hLdacBT->error_code_api = LDACBT_ERR_ILL_SAMPLING_FREQ;
214 return LDACBT_E_FAIL;
215 }
216 hLdacBT->frm_samples = frame_samples;
217
218
219 /* Set Parameters by Encode Quality Mode Index */
220 hLdacBT->eqmid = eqmid;
221 /* get frame_length of EQMID */
222 pCfg = ldacBT_get_config( hLdacBT->eqmid, hLdacBT->tx.pkt_type );
223 /* set frame_length */
224 hLdacBT->frmlen_tx = hLdacBT->pcm.ch * pCfg->frmlen_1ch;
225 hLdacBT->frmlen = hLdacBT->frmlen_tx;
226 if (hLdacBT->transport) {
227 /* Adjust frame_length for Transport Header Data */
228 hLdacBT->frmlen -= LDACBT_FRMHDRBYTES;
229 }
230
231 /* Calculate how many LDAC frames fit into payload packet */
232 hLdacBT->tx.nfrm_in_pkt = hLdacBT->tx.tx_size / hLdacBT->frmlen_tx;
233
234
235 /* Get ldac encode setting */
236 result = ldaclib_get_encode_setting( pCfg->frmlen_1ch, sfid, &nbasebands, &grad_mode,
237 &grad_qu_l, &grad_qu_h, &grad_ofst_l, &grad_ofst_h, &abc_flag);
238 if (LDAC_FAILED(result)) {
239 hLdacBT->error_code_api = LDACBT_ERR_ILL_PARAM;
240 return LDACBT_E_FAIL;
241 }
242
243 /* Set Configuration Information */
244 result = ldaclib_set_config_info( hLdacBT->hLDAC, hLdacBT->sfid, hLdacBT->cci,
245 hLdacBT->frmlen, hLdacBT->frm_status);
246 if (LDAC_FAILED(result)) {
247 hLdacBT->error_code_api = LDACBT_GET_LDACLIB_ERROR_CODE;
248 return LDACBT_E_FAIL;
249 }
250 else if (result != LDAC_S_OK) {
251 hLdacBT->error_code_api = LDACBT_GET_LDACLIB_ERROR_CODE;
252 }
253
254 /* Set Encoding Information */
255 result = ldaclib_set_encode_info(hLdacBT->hLDAC, nbasebands, grad_mode,
256 grad_qu_l, grad_qu_h, grad_ofst_l, grad_ofst_h, abc_flag);
257 if (LDAC_FAILED(result)) {
258 hLdacBT->error_code_api = LDACBT_GET_LDACLIB_ERROR_CODE;
259 return LDACBT_E_FAIL;
260 }
261 else if (result != LDAC_S_OK) {
262 hLdacBT->error_code_api = LDACBT_GET_LDACLIB_ERROR_CODE;
263 }
264
265 /* Initialize ldaclib for Encoding */
266 result = ldaclib_init_encode(hLdacBT->hLDAC);
267 if (LDAC_FAILED(result)) {
268 hLdacBT->error_code_api = LDACBT_GET_LDACLIB_ERROR_CODE;
269 return LDACBT_E_FAIL;
270 }
271 else if (result != LDAC_S_OK) {
272 hLdacBT->error_code_api = LDACBT_GET_LDACLIB_ERROR_CODE;
273 }
274
275 /* reset target eqmid as current setting */
276 hLdacBT->tgt_eqmid = hLdacBT->eqmid;
277 hLdacBT->tgt_nfrm_in_pkt = hLdacBT->tx.nfrm_in_pkt;
278 hLdacBT->tgt_frmlen = hLdacBT->frmlen;
279 hLdacBT->stat_alter_op = LDACBT_ALTER_OP__NON;
280
281 /* get bitrate */
282 hLdacBT->bitrate = ldacBT_frmlen_to_bitrate( hLdacBT->frmlen, hLdacBT->transport,
283 hLdacBT->pcm.sf, hLdacBT->frm_samples );
284
285 return (hLdacBT->error_code_api==LDACBT_ERR_NONE?LDACBT_S_OK:LDACBT_E_FAIL);
286 }
287
288 /* Set Encode Quality Mode index */
ldacBT_set_eqmid(HANDLE_LDAC_BT hLdacBT,int eqmid)289 LDACBT_API int ldacBT_set_eqmid( HANDLE_LDAC_BT hLdacBT, int eqmid )
290 {
291 if( hLdacBT == NULL ){
292 return LDACBT_E_FAIL;
293 }
294 if( hLdacBT->proc_mode != LDACBT_PROCMODE_ENCODE ){
295 hLdacBT->error_code_api = LDACBT_ERR_HANDLE_NOT_INIT;
296 return LDACBT_E_FAIL;
297 }
298
299 if( (hLdacBT->error_code_api = ldacBT_assert_eqmid( eqmid )) != LDACBT_ERR_NONE ){
300 return LDACBT_E_FAIL; /* fatal */
301 }
302 ldacBT_set_eqmid_core( hLdacBT, eqmid );
303
304 return LDACBT_S_OK;
305 }
306
307 /* Get Encode Quality Mode index */
ldacBT_get_eqmid(HANDLE_LDAC_BT hLdacBT)308 LDACBT_API int ldacBT_get_eqmid( HANDLE_LDAC_BT hLdacBT )
309 {
310 if( hLdacBT == NULL ){
311 return LDACBT_E_FAIL;
312 }
313 if( hLdacBT->proc_mode != LDACBT_PROCMODE_ENCODE ){
314 hLdacBT->error_code_api = LDACBT_ERR_HANDLE_NOT_INIT;
315 return LDACBT_E_FAIL;
316 }
317 return hLdacBT->tgt_eqmid;
318 }
319
320 /* Alter encode quality mode index */
ldacBT_alter_eqmid_priority(HANDLE_LDAC_BT hLdacBT,int priority)321 LDACBT_API int ldacBT_alter_eqmid_priority( HANDLE_LDAC_BT hLdacBT, int priority )
322 {
323 int target_eqmid;
324 if( hLdacBT == NULL ){ return LDACBT_E_FAIL; }
325 if( hLdacBT->proc_mode != LDACBT_PROCMODE_ENCODE ){
326 hLdacBT->error_code_api = LDACBT_ERR_HANDLE_NOT_INIT;
327 return LDACBT_E_FAIL;
328 }
329 if( (priority != LDACBT_EQMID_INC_QUALITY) &&
330 (priority != LDACBT_EQMID_INC_CONNECTION )
331 ){
332 hLdacBT->error_code_api = LDACBT_ERR_ILL_PARAM;
333 return LDACBT_E_FAIL;
334 }
335
336 target_eqmid = ldacBT_get_altered_eqmid( hLdacBT, priority);
337 if( target_eqmid < 0 ){
338 hLdacBT->error_code_api = LDACBT_ERR_ALTER_EQMID_LIMITED;
339 return LDACBT_E_FAIL;
340 }
341
342 ldacBT_set_eqmid_core( hLdacBT, target_eqmid );
343 return LDACBT_S_OK;
344 }
345
346 /* LDAC encode proccess */
ldacBT_encode(HANDLE_LDAC_BT hLdacBT,void * p_pcm,int * pcm_used,unsigned char * p_stream,int * stream_sz,int * frame_num)347 LDACBT_API int ldacBT_encode( HANDLE_LDAC_BT hLdacBT, void *p_pcm, int *pcm_used,
348 unsigned char *p_stream, int *stream_sz, int *frame_num )
349 {
350 LDAC_RESULT result;
351 LDACBT_SMPL_FMT_T fmt;
352 LDACBT_TRANSPORT_FRM_BUF *ptfbuf;
353 LDACBT_PCM_RING_BUF *ppcmring;
354 P_LDACBT_CONFIG pCfg;
355 int frmlen, frmlen_wrote, frmlen_adj;
356 int frm_status, flg_Do_Encode;
357 int nFrmToPkt, ch, wl;
358 unsigned char *p_ldac_transport_frame;
359 unsigned char a_frm_header[LDACBT_FRMHDRBYTES + 2];
360 if( hLdacBT == NULL ){
361 return LDACBT_E_FAIL;
362 }
363 if( hLdacBT->hLDAC == NULL ){
364 return LDACBT_E_FAIL;
365 }
366 if( hLdacBT->proc_mode != LDACBT_PROCMODE_ENCODE ){
367 hLdacBT->error_code_api = LDACBT_ERR_HANDLE_NOT_INIT;
368 return LDACBT_E_FAIL;
369 }
370 /* Clear Error Codes */
371 hLdacBT->error_code_api = LDACBT_ERR_NONE;
372 ldaclib_clear_error_code( hLdacBT->hLDAC );
373 ldaclib_clear_internal_error_code( hLdacBT->hLDAC );
374
375 if( ( pcm_used == NULL) ||
376 ( p_stream == NULL ) ||
377 ( stream_sz == NULL ) ||
378 ( frame_num == NULL )
379 ){
380 hLdacBT->error_code_api = LDACBT_ERR_ILL_PARAM;
381 return LDACBT_E_FAIL;
382 }
383 /* reset parameters */
384 *pcm_used = 0;
385 *stream_sz = 0;
386 *frame_num = 0;
387 flg_Do_Encode = 0;
388 fmt = hLdacBT->pcm.fmt;
389 ch = hLdacBT->pcm.ch;
390 wl = hLdacBT->pcm.wl;
391 ptfbuf = &hLdacBT->ldac_trns_frm_buf;
392 ppcmring = &hLdacBT->pcmring;
393
394 /* update input pcm data */
395 if( p_pcm != NULL ){
396 int nByteCpy, sz;
397 nByteCpy = LDACBT_ENC_LSU * wl * ch;
398 sz = ppcmring->nsmpl * wl * ch + nByteCpy;
399 if( sz < LDACBT_ENC_PCM_BUF_SZ ){
400 copy_data_ldac( p_pcm, ppcmring->buf + ppcmring->wp, nByteCpy );
401 ppcmring->wp += nByteCpy;
402 if( ppcmring->wp >= LDACBT_ENC_PCM_BUF_SZ ){
403 ppcmring->wp = 0;
404 }
405 ppcmring->nsmpl += LDACBT_ENC_LSU;
406 *pcm_used = nByteCpy;
407 }else{
408 /* Not enough space to copy.
409 * This will happen when the last encode process failed.
410 */
411 *pcm_used = 0;
412 }
413
414 if( ppcmring->nsmpl >= hLdacBT->frm_samples )
415 {
416 flg_Do_Encode = 1;
417 }
418 }else{
419 if (hLdacBT->flg_encode_flushed != TRUE){
420 flg_Do_Encode = 1;
421 }
422 }
423
424 if( !flg_Do_Encode ){
425 /* nothing to do */
426 return LDACBT_S_OK;
427 }
428
429 /* update frame_length if needed */
430 if( (hLdacBT->tgt_eqmid != UNSET) && (hLdacBT->tgt_eqmid != hLdacBT->eqmid) ){
431 if( ptfbuf->nfrm_in == 0 ){
432 ldacBT_update_frmlen( hLdacBT, hLdacBT->tgt_frmlen );
433 hLdacBT->stat_alter_op = LDACBT_ALTER_OP__NON;
434 }
435 else if( hLdacBT->tgt_nfrm_in_pkt > hLdacBT->tx.nfrm_in_pkt ){
436 /* for better connectivity, apply ASAP */
437 if( !hLdacBT->stat_alter_op ){
438 nFrmToPkt = hLdacBT->tgt_nfrm_in_pkt - ptfbuf->nfrm_in;
439 if( nFrmToPkt > 0 ){
440 pCfg = ldacBT_get_config(LDACBT_EQMID_END, hLdacBT->tx.pkt_type);
441 if( pCfg != NULL ){
442 do{
443 frmlen_adj = (hLdacBT->tx.tx_size - ptfbuf->used) / nFrmToPkt;
444 if( frmlen_adj > hLdacBT->tgt_frmlen ) {
445 frmlen_adj = hLdacBT->tgt_frmlen;
446 }
447 frmlen_adj -= LDACBT_FRMHDRBYTES;
448 if( frmlen_adj >= pCfg->frmlen ){
449 if( ldacBT_update_frmlen( hLdacBT, frmlen_adj ) == LDACBT_S_OK ){
450 hLdacBT->stat_alter_op = LDACBT_ALTER_OP__ACTIVE;
451 break;
452 }
453 }
454 }while( --nFrmToPkt > 0 );
455 }
456 if( !hLdacBT->stat_alter_op ){
457 /* force to flash streams */
458 hLdacBT->stat_alter_op = LDACBT_ALTER_OP__FLASH;
459 }
460 }
461 }
462 }
463 else{
464 /* wait the condition ptfbuf->nfrm_in == 0 for apply new frame_length */
465 hLdacBT->stat_alter_op = LDACBT_ALTER_OP__STANDBY;
466 }
467
468 }
469 else if( hLdacBT->tgt_frmlen != hLdacBT->frmlen ){
470 if( ptfbuf->nfrm_in == 0 ){
471 ldacBT_update_frmlen( hLdacBT, hLdacBT->tgt_frmlen );
472 hLdacBT->stat_alter_op = LDACBT_ALTER_OP__NON;
473 }else{
474 if( hLdacBT->tgt_nfrm_in_pkt == hLdacBT->tx.nfrm_in_pkt ){
475 ldacBT_update_frmlen( hLdacBT, hLdacBT->tgt_frmlen );
476 hLdacBT->stat_alter_op = LDACBT_ALTER_OP__NON;
477 }else{
478 if( hLdacBT->tgt_nfrm_in_pkt > hLdacBT->tx.nfrm_in_pkt ){
479 /* for better connectivity, apply ASAP */
480 if( !hLdacBT->stat_alter_op ){
481 nFrmToPkt = hLdacBT->tgt_nfrm_in_pkt - ptfbuf->nfrm_in;
482 if( nFrmToPkt > 0 ){
483 frmlen_adj = (hLdacBT->tx.tx_size - ptfbuf->used) / nFrmToPkt;
484 if( frmlen_adj > hLdacBT->tgt_frmlen ) {
485 frmlen_adj = hLdacBT->tgt_frmlen;
486 }
487 if( ldacBT_update_frmlen( hLdacBT, frmlen_adj ) == LDACBT_S_OK ){
488 hLdacBT->stat_alter_op = LDACBT_ALTER_OP__ACTIVE;
489 }
490 if( !hLdacBT->stat_alter_op ){
491 /* flash streams */
492 hLdacBT->stat_alter_op = LDACBT_ALTER_OP__FLASH;
493 }
494 }
495 }
496 }else{
497 /* wait the condition ptfbuf->nfrm_in == 0 for apply new frame_length */
498 hLdacBT->stat_alter_op = LDACBT_ALTER_OP__STANDBY;
499 }
500 }
501 }
502 }
503
504 /* check write space for encoded data */
505 ldaclib_get_encode_frame_length( hLdacBT->hLDAC, &frmlen );
506
507 if( (( ptfbuf->used + frmlen + LDACBT_FRMHDRBYTES) > hLdacBT->tx.tx_size) ||
508 (hLdacBT->stat_alter_op == LDACBT_ALTER_OP__FLASH) || /* need to flash streams? */
509 (( ptfbuf->used + frmlen + LDACBT_FRMHDRBYTES) >= LDACBT_ENC_STREAM_BUF_SZ )
510 )
511 {
512 copy_data_ldac( ptfbuf->buf, p_stream, ptfbuf->used );
513 *stream_sz = ptfbuf->used;
514 *frame_num = ptfbuf->nfrm_in;
515 clear_data_ldac( ptfbuf->buf, sizeof(char)*LDACBT_ENC_STREAM_BUF_SZ);
516 ptfbuf->used = 0;
517 ptfbuf->nfrm_in = 0;
518 if( hLdacBT->stat_alter_op != LDACBT_ALTER_OP__NON ){
519 /* update frame length */
520 ldacBT_update_frmlen( hLdacBT, hLdacBT->tgt_frmlen );
521 hLdacBT->stat_alter_op = LDACBT_ALTER_OP__NON;
522 }
523 }
524 p_ldac_transport_frame = ptfbuf->buf + ptfbuf->used;
525
526 /* Encode Frame */
527 if( ppcmring->nsmpl > 0 ){
528 char *p_pcm_ring_r;
529 int nsmpl_to_clr;
530 nsmpl_to_clr = hLdacBT->frm_samples - ppcmring->nsmpl;
531 if( nsmpl_to_clr > 0 ){
532 int pos, nBytesToZero;
533 pos = ppcmring->rp + ppcmring->nsmpl * wl * ch;
534 nBytesToZero = nsmpl_to_clr * wl * ch;
535 while( nBytesToZero > 0 ){
536 int clearBytes;
537 clearBytes = nBytesToZero;
538 if ( pos + clearBytes >= LDACBT_ENC_PCM_BUF_SZ ){
539 clearBytes = (LDACBT_ENC_PCM_BUF_SZ - pos);
540 }
541 clear_data_ldac( ppcmring->buf + pos, clearBytes);
542 nBytesToZero -= clearBytes;
543 if( (pos += clearBytes) >= LDACBT_ENC_PCM_BUF_SZ ){
544 pos = 0;
545 }
546 }
547 }
548 p_pcm_ring_r = ppcmring->buf + ppcmring->rp;
549 ldacBT_prepare_pcm_encode( p_pcm_ring_r, hLdacBT->pp_pcm, hLdacBT->frm_samples, ch, fmt );
550 result = ldaclib_encode(hLdacBT->hLDAC, hLdacBT->pp_pcm, (LDAC_SMPL_FMT_T)fmt,
551 p_ldac_transport_frame+LDACBT_FRMHDRBYTES, &frmlen_wrote);
552 if( !LDAC_FAILED(result) ){
553 ppcmring->rp += hLdacBT->frm_samples * wl * ch;
554 ppcmring->nsmpl -= hLdacBT->frm_samples;
555 if( ppcmring->rp >= LDACBT_ENC_PCM_BUF_SZ ){ ppcmring->rp = 0; }
556 if( ppcmring->nsmpl < 0 ){ ppcmring->nsmpl = 0; }
557 }
558 }else{
559 result = ldaclib_flush_encode(hLdacBT->hLDAC, (LDAC_SMPL_FMT_T)fmt,
560 p_ldac_transport_frame+LDACBT_FRMHDRBYTES, &frmlen_wrote);
561 hLdacBT->flg_encode_flushed = TRUE;
562 }
563
564 if( LDAC_FAILED(result) ){
565 hLdacBT->error_code_api = LDACBT_GET_LDACLIB_ERROR_CODE;
566 return LDACBT_E_FAIL;
567 }
568 else if( result != LDAC_S_OK ){
569 hLdacBT->error_code_api = LDACBT_GET_LDACLIB_ERROR_CODE;
570 }
571
572 if( frmlen_wrote > 0 ){
573 if( hLdacBT->transport == TRUE ){
574 /* Set Frame Header Data */
575 clear_data_ldac( a_frm_header, LDACBT_FRMHDRBYTES+2 );
576 /* Get Frame Header Information */
577 result = ldaclib_get_config_info(hLdacBT->hLDAC, &hLdacBT->sfid, &hLdacBT->cci,
578 &frmlen, &frm_status);
579 if( LDAC_FAILED(result) ){
580 hLdacBT->error_code_api = LDACBT_GET_LDACLIB_ERROR_CODE;
581 return LDACBT_E_FAIL;
582 }
583 else if (result != LDAC_S_OK) {
584 hLdacBT->error_code_api = LDACBT_GET_LDACLIB_ERROR_CODE;
585 }
586
587 /* Set Frame Header */
588 result = ldaclib_set_frame_header(hLdacBT->hLDAC, a_frm_header, hLdacBT->sfid,
589 hLdacBT->cci, frmlen, frm_status);
590 if( LDAC_FAILED(result) ){
591 hLdacBT->error_code_api = LDACBT_GET_LDACLIB_ERROR_CODE;
592 return LDACBT_E_FAIL;
593 }
594 else if (result != LDAC_S_OK) {
595 hLdacBT->error_code_api = LDACBT_GET_LDACLIB_ERROR_CODE;
596 }
597 copy_data_ldac( a_frm_header, p_ldac_transport_frame, LDACBT_FRMHDRBYTES );
598 frmlen_wrote += LDACBT_FRMHDRBYTES;
599 }
600 ptfbuf->used += frmlen_wrote;
601 ptfbuf->nfrm_in ++;
602 }
603
604 /* check for next frame buffer status */
605 if( *stream_sz == 0 ){
606 if( (( ptfbuf->used + frmlen_wrote) > hLdacBT->tx.tx_size) ||
607 ( ptfbuf->nfrm_in >= LDACBT_NFRM_TX_MAX ) ||
608 (( ptfbuf->used + frmlen_wrote) >= LDACBT_ENC_STREAM_BUF_SZ ) ||
609 ( p_pcm == NULL ) /* flush encode */
610 )
611 {
612 copy_data_ldac( ptfbuf->buf, p_stream, ptfbuf->used );
613 *stream_sz = ptfbuf->used;
614 *frame_num = ptfbuf->nfrm_in;
615 clear_data_ldac( ptfbuf->buf, sizeof(char)*LDACBT_ENC_STREAM_BUF_SZ);
616 ptfbuf->used = 0;
617 ptfbuf->nfrm_in = 0;
618 if( hLdacBT->stat_alter_op != LDACBT_ALTER_OP__NON ){
619 ldacBT_update_frmlen( hLdacBT, hLdacBT->tgt_frmlen );
620 hLdacBT->stat_alter_op = LDACBT_ALTER_OP__NON;
621 }
622 }
623 }
624
625 return LDACBT_S_OK;
626 }
627