Home | History | Annotate | Download | only in src
      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
     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 */
     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 */
     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 */
     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 */
     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 */
    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 */
    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 */
    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 */
    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 */
    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 */
    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 */
    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