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 24LDACBT_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 */ 30LDACBT_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 */ 47LDACBT_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 */ 65LDACBT_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 */ 84LDACBT_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 */ 101LDACBT_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 */ 115LDACBT_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 */ 129LDACBT_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 */ 289LDACBT_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 */ 308LDACBT_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 */ 321LDACBT_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 */ 347LDACBT_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