Coverage Report

Created: 2026-01-10 06:40

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