/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 | } |