Line data Source code
1 : /******************************************************************************************************
2 :
3 : (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
4 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
5 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
6 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
7 : contributors to this repository. All Rights Reserved.
8 :
9 : This software is protected by copyright law and by international treaties.
10 : The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
11 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
12 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
13 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
14 : contributors to this repository retain full ownership rights in their respective contributions in
15 : the software. This notice grants no license of any kind, including but not limited to patent
16 : license, nor is any license granted by implication, estoppel or otherwise.
17 :
18 : Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
19 : contributions.
20 :
21 : This software is provided "AS IS", without any express or implied warranties. The software is in the
22 : development stage. It is intended exclusively for experts who have experience with such software and
23 : solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
24 : and fitness for a particular purpose are hereby disclaimed and excluded.
25 :
26 : Any dispute, controversy or claim arising under or in relation to providing this software shall be
27 : submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
28 : accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
29 : the United Nations Convention on Contracts on the International Sales of Goods.
30 :
31 : *******************************************************************************************************/
32 :
33 : #include <stdio.h>
34 : #include <stdlib.h>
35 : #include <string.h>
36 : #include "options.h"
37 : #include "isar_lc3plus_enc.h"
38 : #include "isar_lc3plus_common.h"
39 : #include "isar_lc3plus_dec.h"
40 : #include "ivas_error_utils.h"
41 : #include "lc3plus.h"
42 :
43 : #define MAX_SAMPLES_PER_CHANNEL 960 / 4
44 : #define DEFAULT_BPS 256000
45 :
46 16 : static int encodeAndDecodeOneStereoFrame( LC3PLUS_CONFIG config, uint32_t bps )
47 : {
48 : ivas_error err;
49 16 : int32_t encDelay = -1;
50 16 : int32_t decDelay = -1;
51 :
52 : ISAR_LC3PLUS_ENC_HANDLE encHandle;
53 16 : err = ISAR_LC3PLUS_ENC_Open( config, bps, &encHandle );
54 16 : if ( IVAS_ERR_OK != err )
55 : {
56 0 : return err;
57 : }
58 :
59 16 : err = ISAR_LC3PLUS_ENC_GetDelay( encHandle, &encDelay );
60 16 : if ( IVAS_ERR_OK != err )
61 : {
62 0 : ISAR_LC3PLUS_ENC_Close( &encHandle );
63 0 : return err;
64 : }
65 16 : if ( encDelay == -1 || encDelay == 0 )
66 : {
67 0 : ISAR_LC3PLUS_ENC_Close( &encHandle );
68 0 : return IVAS_ERROR( IVAS_ERR_INTERNAL, "encDelay is zero or uninitialized\n" );
69 : }
70 :
71 : /* encode one frame */
72 16 : int16_t numSamplesPerChannels = config.samplerate / ( 1000000 / config.isar_frame_duration_us );
73 : float *pcm_in[2];
74 : float pcm_in_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( float )];
75 16 : memset( pcm_in_ch1, 0, numSamplesPerChannels * sizeof( float ) );
76 : float pcm_in_ch2[MAX_SAMPLES_PER_CHANNEL * sizeof( float )];
77 16 : memset( pcm_in_ch2, 0, numSamplesPerChannels * sizeof( float ) );
78 16 : pcm_in[0] = pcm_in_ch1;
79 16 : pcm_in[1] = pcm_in_ch2;
80 :
81 16 : int32_t bitstreamSizePerIvasFrame = 0;
82 16 : err = ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( encHandle, &bitstreamSizePerIvasFrame );
83 16 : if ( IVAS_ERR_OK != err )
84 : {
85 0 : ISAR_LC3PLUS_ENC_Close( &encHandle );
86 0 : return err;
87 : }
88 16 : uint8_t *bitstream_out = malloc( bitstreamSizePerIvasFrame );
89 16 : memset( bitstream_out, 0, bitstreamSizePerIvasFrame );
90 :
91 16 : int perChannelBitrate = lc3plus_enc_get_real_bitrate(encHandle->handles[0]);
92 16 : int perLc3plusFrameDataBlockOctets = encHandle->num_ftds * perChannelBitrate / 8 / (1000*1000/config.lc3plus_frame_duration_us);
93 16 : int targetOctets = bps / 8 / (1000*1000/config.isar_frame_duration_us);
94 16 : printf("IVAS-FS=%i LC3plus-FS=%i ch=%i targetBps=%i targetOctets=%i\n", config.isar_frame_duration_us, config.lc3plus_frame_duration_us, config.channels, bps, targetOctets);
95 16 : printf(" coreBps=%i corePerChBps=%i coreCodecOctets=%i nFtds=%i \n", perChannelBitrate * encHandle->num_encs, perChannelBitrate, perLc3plusFrameDataBlockOctets, encHandle->num_ftds);
96 16 : int pfOctets = bitstreamSizePerIvasFrame - perLc3plusFrameDataBlockOctets;
97 16 : int pfBps = pfOctets * 8 * (1000*1000 / config.isar_frame_duration_us);
98 16 : printf(" payloadFormatBps=%i payloadFormatOctets=%i \n\n", pfBps, pfOctets);
99 16 : if(pfBps <= 0)
100 : {
101 0 : ISAR_LC3PLUS_ENC_Close( &encHandle );
102 0 : return err;
103 : }
104 :
105 16 : err = ISAR_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out, bitstreamSizePerIvasFrame );
106 16 : if ( IVAS_ERR_OK != err )
107 : {
108 0 : ISAR_LC3PLUS_ENC_Close( &encHandle );
109 0 : free( bitstream_out );
110 0 : return err;
111 : }
112 16 : ISAR_LC3PLUS_ENC_Close( &encHandle );
113 :
114 : /* decode one frame */
115 : ISAR_LC3PLUS_DEC_HANDLE decHandle;
116 16 : err = ISAR_LC3PLUS_DEC_Open( config,
117 : #ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING
118 : 1 /*caching enabled*/,
119 : #endif
120 : &decHandle );
121 16 : if ( IVAS_ERR_OK != err )
122 : {
123 0 : free( bitstream_out );
124 0 : return err;
125 : }
126 :
127 16 : err = ISAR_LC3PLUS_DEC_GetDelay( decHandle, &decDelay );
128 16 : if ( IVAS_ERR_OK != err )
129 : {
130 0 : ISAR_LC3PLUS_DEC_Close( &decHandle );
131 0 : free( bitstream_out );
132 0 : return err;
133 : }
134 16 : if ( decDelay == -1 || decDelay == 0 )
135 : {
136 0 : ISAR_LC3PLUS_DEC_Close( &decHandle );
137 0 : free( bitstream_out );
138 0 : return IVAS_ERROR( IVAS_ERR_INTERNAL, "decDelay is zero or uninitialized\n" );
139 : }
140 :
141 16 : uint8_t *bitstream_in = bitstream_out;
142 :
143 : float *pcm_out[2];
144 : float pcm_out_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( float )];
145 16 : memset( pcm_out_ch1, 0, numSamplesPerChannels * sizeof( float ) );
146 : float pcm_out_ch2[MAX_SAMPLES_PER_CHANNEL * sizeof( float )];
147 16 : memset( pcm_out_ch2, 0, numSamplesPerChannels * sizeof( float ) );
148 16 : pcm_out[0] = pcm_out_ch1;
149 16 : pcm_out[1] = pcm_out_ch2;
150 :
151 16 : err = ISAR_LC3PLUS_DEC_Conceal( decHandle, pcm_out );
152 16 : if ( IVAS_ERR_OK != err )
153 : {
154 0 : ISAR_LC3PLUS_DEC_Close( &decHandle );
155 0 : free( bitstream_out );
156 0 : return err;
157 : }
158 :
159 16 : err = ISAR_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstreamSizePerIvasFrame, pcm_out );
160 16 : if ( IVAS_ERR_OK != err )
161 : {
162 0 : ISAR_LC3PLUS_DEC_Close( &decHandle );
163 0 : free( bitstream_out );
164 0 : return err;
165 : }
166 :
167 16 : err = ISAR_LC3PLUS_DEC_Conceal( decHandle, pcm_out );
168 16 : if ( IVAS_ERR_OK != err )
169 : {
170 0 : ISAR_LC3PLUS_DEC_Close( &decHandle );
171 0 : free( bitstream_out );
172 0 : return err;
173 : }
174 :
175 16 : ISAR_LC3PLUS_DEC_Close( &decHandle );
176 16 : free( bitstream_out );
177 :
178 16 : return 0;
179 : }
180 :
181 :
182 1 : static int openCloseEncoder( void )
183 : {
184 : ivas_error err;
185 1 : LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 };
186 1 : uint32_t bps = 128000;
187 :
188 : ISAR_LC3PLUS_ENC_HANDLE encHandle;
189 1 : err = ISAR_LC3PLUS_ENC_Open( config, bps, &encHandle );
190 1 : if ( IVAS_ERR_OK != err )
191 : {
192 0 : return err;
193 : }
194 :
195 1 : ISAR_LC3PLUS_ENC_Close( &encHandle );
196 1 : return 0;
197 : }
198 :
199 1 : static int tryOpenEncoderWithInvalidBitrate( void )
200 : {
201 : ivas_error err;
202 1 : LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 };
203 : /* lc3plus max bitrate is 320000 per channel */
204 1 : uint32_t invalid_high_bps = 700000;
205 1 : uint32_t invalid_low_bps = 8;
206 : uint32_t limitedBitrate;
207 : ISAR_LC3PLUS_ENC_HANDLE encHandle;
208 1 : err = ISAR_LC3PLUS_ENC_Open( config, invalid_high_bps, &encHandle );
209 : /* setting an invalid bitrate should result in a limited bitrate*/
210 1 : if ( IVAS_ERR_OK != err )
211 : {
212 0 : return 1;
213 : }
214 1 : limitedBitrate = lc3plus_enc_get_real_bitrate(encHandle->handles[0]);
215 1 : if(limitedBitrate != 320000)
216 : {
217 0 : return 1;
218 : }
219 1 : ISAR_LC3PLUS_ENC_Close(&encHandle);
220 1 : err = ISAR_LC3PLUS_ENC_Open( config, invalid_low_bps, &encHandle );
221 : /* setting an invalid bitrate should trigger an error - which is what we expect */
222 1 : if ( IVAS_ERR_LC3PLUS_INVALID_BITRATE != err )
223 : {
224 0 : return 1;
225 : }
226 1 : ISAR_LC3PLUS_ENC_Close(&encHandle);
227 1 : return 0;
228 : }
229 :
230 1 : static int tryOpenEncoderWithInvalidFrameDuration( void )
231 : {
232 : ivas_error err;
233 1 : LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 };
234 1 : config.lc3plus_frame_duration_us = 1234; /*unsupported frame duration*/
235 1 : uint32_t bps = 320000;
236 :
237 : ISAR_LC3PLUS_ENC_HANDLE encHandle;
238 1 : err = ISAR_LC3PLUS_ENC_Open( config, bps, &encHandle );
239 : /* setting an invalid fame duration should trigger an error - which is what we expect */
240 1 : if ( IVAS_ERR_OK == err )
241 : {
242 0 : return 1;
243 : }
244 1 : return 0;
245 : }
246 :
247 1 : static int tryOpenEncoderWithInvalidSampleRate( void )
248 : {
249 : ivas_error err;
250 1 : LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 };
251 1 : config.samplerate = 1234; /*unsupported sample rate */
252 1 : uint32_t bps = 320000;
253 :
254 : ISAR_LC3PLUS_ENC_HANDLE encHandle;
255 1 : err = ISAR_LC3PLUS_ENC_Open( config, bps, &encHandle );
256 : /* setting an invalid sample rate should trigger an error - which is what we expect */
257 1 : if ( IVAS_ERR_OK == err )
258 : {
259 0 : return 1;
260 : }
261 1 : return 0;
262 : }
263 :
264 1 : static int tryCallEncoderApiWithInvalidParams( void )
265 : {
266 1 : ISAR_LC3PLUS_ENC_HANDLE invalidEncHandle = NULL;
267 1 : int32_t *invalidBsSize = NULL;
268 : int32_t bsSize;
269 1 : int32_t *invalidDelayInSamples = NULL;
270 : int32_t delayInSamples;
271 1 : float **invalidPcm_in = NULL;
272 1 : void *invalidBitstream_out = NULL;
273 :
274 1 : const int16_t numSamplesPerChannels = MAX_SAMPLES_PER_CHANNEL;
275 : float *pcm_in[1];
276 : float pcm_in_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( float )];
277 1 : memset( pcm_in_ch1, 0, numSamplesPerChannels * sizeof( float ) );
278 1 : pcm_in[0] = pcm_in_ch1;
279 : uint8_t bitstream_out[1200];
280 :
281 1 : if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_GetDelay( invalidEncHandle, invalidDelayInSamples ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_GetDelay( invalidEncHandle, &delayInSamples ) )
282 : {
283 0 : return 1;
284 : }
285 1 : if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( invalidEncHandle, invalidBsSize ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( invalidEncHandle, &bsSize ) )
286 : {
287 0 : return 1;
288 : }
289 1 : ISAR_LC3PLUS_ENC_Close( &invalidEncHandle );
290 1 : if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, invalidPcm_in, invalidBitstream_out, bsSize ) )
291 : {
292 0 : return 1;
293 : }
294 1 : if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, pcm_in, invalidBitstream_out, bsSize ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, invalidPcm_in, bitstream_out, bsSize ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, pcm_in, bitstream_out, bsSize ) )
295 : {
296 0 : return 1;
297 : }
298 1 : return 0;
299 : }
300 :
301 :
302 1 : static int tryCallDecoderApiWithInvalidParams( void )
303 : {
304 1 : ISAR_LC3PLUS_DEC_HANDLE invalidDecHandle = NULL;
305 :
306 1 : int32_t *invalidDelayInSamples = NULL;
307 : int32_t delayInSamples;
308 1 : float **invalidPcm_out = NULL;
309 1 : void *invalidBitstream_in = NULL;
310 1 : int32_t invalidBitstream_in_size = 0;
311 1 : int32_t bitstream_in_size = 100;
312 :
313 1 : const int16_t numSamplesPerChannels = MAX_SAMPLES_PER_CHANNEL;
314 : float *pcm_out[1];
315 : float pcm_out_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( float )];
316 1 : memset( pcm_out_ch1, 0, numSamplesPerChannels * sizeof( float ) );
317 1 : pcm_out[0] = pcm_out_ch1;
318 : uint8_t bitstream_in[1200];
319 :
320 1 : if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_GetDelay( invalidDecHandle, invalidDelayInSamples ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_GetDelay( invalidDecHandle, &delayInSamples ) )
321 : {
322 0 : return 1;
323 : }
324 1 : ISAR_LC3PLUS_DEC_Close( &invalidDecHandle );
325 1 : if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Decode( invalidDecHandle, invalidBitstream_in, invalidBitstream_in_size, invalidPcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Decode( invalidDecHandle, invalidBitstream_in, invalidBitstream_in_size, pcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Decode( invalidDecHandle, invalidBitstream_in, bitstream_in_size, invalidPcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Decode( invalidDecHandle, invalidBitstream_in, bitstream_in_size, pcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Decode( invalidDecHandle, bitstream_in, invalidBitstream_in_size, invalidPcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Decode( invalidDecHandle, bitstream_in, invalidBitstream_in_size, pcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Decode( invalidDecHandle, bitstream_in, bitstream_in_size, pcm_out ) )
326 : {
327 0 : return 1;
328 : }
329 :
330 1 : if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Conceal( invalidDecHandle, invalidPcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Conceal( invalidDecHandle, pcm_out ) )
331 : {
332 0 : return 1;
333 : }
334 1 : return 0;
335 : }
336 :
337 1 : static int openCloseDecoderWithCaching( void )
338 : {
339 : ivas_error err;
340 1 : LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 };
341 : ISAR_LC3PLUS_DEC_HANDLE decHandle;
342 1 : err = ISAR_LC3PLUS_DEC_Open( config,
343 : #ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING
344 : 1 /*caching enabled*/,
345 : #endif
346 : &decHandle );
347 1 : if ( IVAS_ERR_OK != err )
348 : {
349 0 : return err;
350 : }
351 :
352 1 : ISAR_LC3PLUS_DEC_Close( &decHandle );
353 1 : return 0;
354 : }
355 :
356 1 : static int openCloseDecoderWithoutCaching( void )
357 : {
358 : ivas_error err;
359 1 : LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 };
360 : ISAR_LC3PLUS_DEC_HANDLE decHandle;
361 1 : err = ISAR_LC3PLUS_DEC_Open( config,
362 : #ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING
363 : 1 /*caching enabled*/,
364 : #endif
365 : &decHandle );
366 1 : if ( IVAS_ERR_OK != err )
367 : {
368 0 : return err;
369 : }
370 :
371 1 : ISAR_LC3PLUS_DEC_Close( &decHandle );
372 1 : return 0;
373 : }
374 :
375 :
376 1 : static int tryOpenDecoderWithInvalidFrameDuration( void )
377 : {
378 : ivas_error err;
379 1 : LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 };
380 1 : config.lc3plus_frame_duration_us = 1234; /*unsupported frame duration*/
381 :
382 : ISAR_LC3PLUS_DEC_HANDLE decHandle;
383 1 : err = ISAR_LC3PLUS_DEC_Open( config,
384 : #ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING
385 : 1 /*caching enabled*/,
386 : #endif
387 : &decHandle );
388 : /* setting an invalid fame duration should trigger an error - which is what we expect */
389 1 : if ( IVAS_ERR_OK == err )
390 : {
391 0 : return 1;
392 : }
393 1 : return 0;
394 : }
395 :
396 1 : static int tryOpenDecoderWithInvalidSampleRate( void )
397 : {
398 : ivas_error err;
399 1 : LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 };
400 1 : config.samplerate = 1234; /*unsupported sample rate*/
401 :
402 : ISAR_LC3PLUS_DEC_HANDLE decHandle;
403 1 : err = ISAR_LC3PLUS_DEC_Open( config,
404 : #ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING
405 : 1 /*caching enabled*/,
406 : #endif
407 : &decHandle );
408 : /* setting an invalid sample rate should trigger an error - which is what we expect */
409 1 : if ( IVAS_ERR_OK == err )
410 : {
411 0 : return 1;
412 : }
413 1 : return 0;
414 : }
415 :
416 1 : static int encodeOneFrame( void )
417 : {
418 : ivas_error err;
419 1 : LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 };
420 1 : uint32_t bps = 128000;
421 :
422 : ISAR_LC3PLUS_ENC_HANDLE encHandle;
423 1 : err = ISAR_LC3PLUS_ENC_Open( config, bps, &encHandle );
424 1 : if ( IVAS_ERR_OK != err )
425 0 : return err;
426 :
427 1 : int16_t numSamplesPerChannels = config.samplerate / ( 1000000 / config.isar_frame_duration_us );
428 :
429 : float *pcm[1];
430 : float pcm_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( float )];
431 1 : memset( pcm_ch1, 0, numSamplesPerChannels * sizeof( float ) );
432 1 : pcm[0] = pcm_ch1;
433 :
434 1 : int32_t bitstreamSizePerIvasFrame = 0;
435 1 : err = ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( encHandle, &bitstreamSizePerIvasFrame );
436 1 : if ( IVAS_ERR_OK != err )
437 0 : return err;
438 1 : uint8_t *bitstream_out = malloc( bitstreamSizePerIvasFrame );
439 1 : memset( bitstream_out, 0, bitstreamSizePerIvasFrame );
440 1 : err = ISAR_LC3PLUS_ENC_Encode( encHandle, pcm, bitstream_out, bitstreamSizePerIvasFrame );
441 1 : if ( IVAS_ERR_OK != err )
442 0 : return err;
443 :
444 1 : ISAR_LC3PLUS_ENC_Close( &encHandle );
445 1 : free( bitstream_out );
446 1 : return 0;
447 : }
448 :
449 :
450 1 : static int encodeAndDecodeOneMonoFrame( void )
451 : {
452 : ivas_error err;
453 1 : LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 };
454 1 : uint32_t bps = 128000;
455 :
456 : ISAR_LC3PLUS_ENC_HANDLE encHandle;
457 1 : err = ISAR_LC3PLUS_ENC_Open( config, bps, &encHandle );
458 1 : if ( IVAS_ERR_OK != err )
459 : {
460 0 : return err;
461 : }
462 :
463 : /* encode one frame */
464 1 : int16_t numSamplesPerChannels = config.samplerate / ( 1000000 / config.isar_frame_duration_us );
465 : float *pcm_in[1];
466 : float pcm_in_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( float )];
467 1 : memset( pcm_in_ch1, 0, numSamplesPerChannels * sizeof( float ) );
468 1 : pcm_in[0] = pcm_in_ch1;
469 :
470 1 : int32_t bitstreamSizePerIvasFrame = 0;
471 1 : err = ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( encHandle, &bitstreamSizePerIvasFrame );
472 1 : if ( IVAS_ERR_OK != err )
473 0 : return err;
474 :
475 1 : uint8_t *bitstream_out = malloc( bitstreamSizePerIvasFrame );
476 1 : memset( bitstream_out, 0, bitstreamSizePerIvasFrame );
477 1 : err = ISAR_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out, bitstreamSizePerIvasFrame );
478 1 : if ( IVAS_ERR_OK != err )
479 0 : return err;
480 1 : ISAR_LC3PLUS_ENC_Close( &encHandle );
481 :
482 : /* decode one frame */
483 : ISAR_LC3PLUS_DEC_HANDLE decHandle;
484 1 : err = ISAR_LC3PLUS_DEC_Open( config,
485 : #ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING
486 : 1 /*caching enabled*/,
487 : #endif
488 : &decHandle );
489 1 : if ( IVAS_ERR_OK != err )
490 : {
491 0 : return err;
492 : }
493 :
494 1 : uint8_t *bitstream_in = bitstream_out;
495 :
496 : float *pcm_out[1];
497 : float pcm_out_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( float )];
498 1 : memset( pcm_out_ch1, 0, numSamplesPerChannels * sizeof( float ) );
499 1 : pcm_out[0] = pcm_out_ch1;
500 1 : err = ISAR_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstreamSizePerIvasFrame, pcm_out );
501 1 : if ( IVAS_ERR_OK != err )
502 : {
503 0 : return err;
504 : }
505 :
506 1 : err = ISAR_LC3PLUS_DEC_Conceal( decHandle, pcm_out );
507 1 : if ( IVAS_ERR_OK != err )
508 : {
509 0 : return err;
510 : }
511 :
512 1 : ISAR_LC3PLUS_DEC_Close( &decHandle );
513 1 : free( bitstream_out );
514 :
515 1 : return 0;
516 : }
517 :
518 1 : static int encodeAndDecodeOneStereoFrameIvas20msLc3plus10ms_48kHz( void )
519 : {
520 1 : LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 };
521 1 : return encodeAndDecodeOneStereoFrame( config, DEFAULT_BPS );
522 : }
523 :
524 1 : static int encodeAndDecodeOneStereoFrameIvas20msLc3plus10ms_32kHz( void )
525 : {
526 1 : LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 32000 };
527 1 : return encodeAndDecodeOneStereoFrame( config, DEFAULT_BPS );
528 : }
529 :
530 1 : static int encodeAndDecodeOneStereoFrameIvas20msLc3plus10ms_16kHz( void )
531 : {
532 1 : LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 16000 };
533 1 : return encodeAndDecodeOneStereoFrame( config, DEFAULT_BPS );
534 : }
535 :
536 1 : static int encodeAndDecodeOneStereoFrameIvas5msLc3plus5ms_48kHz( void )
537 : {
538 1 : LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 };
539 1 : return encodeAndDecodeOneStereoFrame( config, DEFAULT_BPS );
540 : }
541 :
542 1 : static int encodeAndDecodeOneStereoFrameIvas10msLc3plus10ms_48kHz( void )
543 : {
544 1 : LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 };
545 1 : return encodeAndDecodeOneStereoFrame( config, DEFAULT_BPS );
546 : }
547 :
548 1 : static int encodeAndDecodeOneMonoFrameIvas20msLc3plus10ms_48kHz( void )
549 : {
550 1 : LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 };
551 1 : return encodeAndDecodeOneStereoFrame( config, DEFAULT_BPS );
552 : }
553 :
554 1 : static int encodeAndDecodeOneMonoFrameIvas5msLc3plus5ms_48kHz( void )
555 : {
556 1 : LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 };
557 1 : return encodeAndDecodeOneStereoFrame( config, DEFAULT_BPS );
558 : }
559 :
560 1 : static int encodeAndDecodeOneStereoFrameIvas20msLc3plus2_5ms_48kHz( void )
561 : {
562 1 : LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 2.5 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 };
563 1 : return encodeAndDecodeOneStereoFrame( config, DEFAULT_BPS );
564 : }
565 :
566 :
567 1 : static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_80kbpsPerChannel( void )
568 : {
569 1 : LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 };
570 1 : return encodeAndDecodeOneStereoFrame( config, config.channels * 82*1000 );
571 : }
572 :
573 1 : static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_96kbpsPerChannel( void )
574 : {
575 1 : LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 };
576 1 : return encodeAndDecodeOneStereoFrame( config, config.channels * 98*1000 );
577 : }
578 :
579 : #ifdef LC3PLUS_LEA_COMPAT_BITRATES_48_6
580 : static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_126kbpsPerChannel( void )
581 : #else
582 1 : static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_124kbpsPerChannel( void )
583 : #endif
584 : {
585 1 : LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 };
586 1 : return encodeAndDecodeOneStereoFrame( config, config.channels * 126*1000 );
587 : }
588 :
589 1 : static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_800kbpsPerChannel( void )
590 : {
591 1 : LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 };
592 1 : return encodeAndDecodeOneStereoFrame( config, config.channels * 800*1000 );
593 : }
594 :
595 1 : static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_204800bpsPerChannel( void )
596 : {
597 1 : LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 };
598 1 : return encodeAndDecodeOneStereoFrame( config, config.channels * 204800 );
599 : }
600 :
601 1 : static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_205600bpsPerChannel( void )
602 : {
603 1 : LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 };
604 1 : return encodeAndDecodeOneStereoFrame( config, config.channels * 205600 );
605 : }
606 :
607 1 : static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_206400bpsPerChannel( void )
608 : {
609 1 : LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 };
610 1 : return encodeAndDecodeOneStereoFrame( config, config.channels * 206400 );
611 : }
612 :
613 1 : static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_207200bpsPerChannel( void )
614 : {
615 1 : LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 };
616 1 : return encodeAndDecodeOneStereoFrame( config, config.channels * 207200 );
617 : }
618 :
619 : #include "ivas_lc3plus_unit_test_payload_format.c"
620 :
621 1 : int main(
622 : int argc,
623 : char *argv[] )
624 : {
625 : (void)argc;
626 : (void)argv;
627 1 : int ret = 0;
628 1 : ret = openCloseEncoder();
629 1 : if ( ret != 0 )
630 0 : return 1;
631 1 : ret = tryOpenEncoderWithInvalidBitrate();
632 1 : if ( ret != 0 )
633 0 : return 1;
634 1 : ret = tryOpenEncoderWithInvalidFrameDuration();
635 1 : if ( ret != 0 )
636 0 : return 1;
637 1 : ret = tryOpenEncoderWithInvalidSampleRate();
638 1 : if ( ret != 0 )
639 0 : return 1;
640 1 : ret = tryCallEncoderApiWithInvalidParams();
641 1 : if ( ret != 0 )
642 0 : return 1;
643 1 : ret = openCloseDecoderWithCaching();
644 1 : if ( ret != 0 )
645 0 : return 1;
646 1 : ret = openCloseDecoderWithoutCaching();
647 1 : if ( ret != 0 )
648 0 : return 1;
649 1 : ret = tryOpenDecoderWithInvalidFrameDuration();
650 1 : if ( ret != 0 )
651 0 : return 1;
652 1 : ret = tryOpenDecoderWithInvalidSampleRate();
653 1 : if ( ret != 0 )
654 0 : return 1;
655 1 : ret = tryCallDecoderApiWithInvalidParams();
656 1 : if ( ret != 0 )
657 0 : return 1;
658 1 : ret = encodeOneFrame();
659 1 : if ( ret != 0 )
660 0 : return 1;
661 1 : ret = encodeAndDecodeOneMonoFrame();
662 1 : if ( ret != 0 )
663 0 : return 1;
664 1 : ret = encodeAndDecodeOneStereoFrameIvas20msLc3plus10ms_48kHz();
665 1 : if ( ret != 0 )
666 0 : return 1;
667 1 : ret = encodeAndDecodeOneStereoFrameIvas20msLc3plus10ms_32kHz();
668 1 : if ( ret != 0 )
669 0 : return 1;
670 1 : ret = encodeAndDecodeOneStereoFrameIvas20msLc3plus10ms_16kHz();
671 1 : if ( ret != 0 )
672 0 : return 1;
673 1 : ret = encodeAndDecodeOneStereoFrameIvas5msLc3plus5ms_48kHz();
674 1 : if ( ret != 0 )
675 0 : return 1;
676 1 : ret = encodeAndDecodeOneStereoFrameIvas10msLc3plus10ms_48kHz();
677 1 : if ( ret != 0 )
678 0 : return 1;
679 1 : ret = encodeAndDecodeOneMonoFrameIvas20msLc3plus10ms_48kHz();
680 1 : if ( ret != 0 )
681 0 : return 1;
682 1 : ret = encodeAndDecodeOneMonoFrameIvas5msLc3plus5ms_48kHz();
683 1 : if ( ret != 0 )
684 0 : return 1;
685 1 : ret = encodeAndDecodeOneStereoFrameIvas20msLc3plus2_5ms_48kHz();
686 1 : if ( ret != 0 )
687 0 : return 1;
688 1 : ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_80kbpsPerChannel();
689 1 : if ( ret != 0 )
690 0 : return 1;
691 1 : ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_96kbpsPerChannel();
692 1 : if ( ret != 0 )
693 0 : return 1;
694 : #ifdef LC3PLUS_LEA_COMPAT_BITRATES_48_6
695 : ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_126kbpsPerChannel();
696 : #else
697 1 : ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_124kbpsPerChannel();
698 : #endif
699 1 : if ( ret != 0 )
700 0 : return 1;
701 1 : ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_800kbpsPerChannel();
702 1 : if ( ret != 0 )
703 0 : return 1;
704 : /* start configs around the FDL threshold */
705 1 : ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_204800bpsPerChannel();
706 1 : if ( ret != 0 )
707 0 : return 1;
708 1 : ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_205600bpsPerChannel();
709 1 : if ( ret != 0 )
710 0 : return 1;
711 1 : ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_206400bpsPerChannel();
712 1 : if ( ret != 0 )
713 0 : return 1;
714 1 : ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_207200bpsPerChannel();
715 1 : if ( ret != 0 )
716 0 : return 1;
717 : /* end configs around the FDL threshold */
718 1 : ret = run_all_payload_tests();
719 1 : if ( ret != 0 )
720 0 : return 1;
721 1 : return 0;
722 : }
|