• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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