Loading system/embdrv/lc3/include/lc3.h +14 −9 Original line number Diff line number Diff line /****************************************************************************** * * Copyright 2021 Google, Inc. * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. Loading Loading @@ -39,17 +39,17 @@ * it can follow a temporary bandwidth increase or reduction. * * - Unlike classic codecs, the LC3 codecs does not run on fixed amount * of samples as input. It operate only on fixed frame duration, for * any supported samplerates (8 to 48 KHz). Two frame duration are * of samples as input. It operates only on fixed frame duration, for * any supported samplerates (8 to 48 KHz). Two frames duration are * available 7.5ms and 10ms. * * * --- About 44.1 KHz samplerate --- * * The Bluetooth specification oddly add the 44.1 KHz samplerate. Although * there is NO SUPPORT in the core algorithm of the codec of 44.1 KHz. * The Bluetooth specification reference the 44.1 KHz samplerate, although * there is no support in the core algorithm of the codec of 44.1 KHz. * We can summarize the 44.1 KHz support by "you can put any samplerate * around the base defined samplerates". But be concerned by : * around the defined base samplerates". Please mind the following items : * * 1. The frame size will not be 7.5 ms or 10 ms, but is scaled * by 'supported samplerate' / 'input samplerate' Loading @@ -68,7 +68,7 @@ * * --- How to encode / decode --- * * An encoder / decoder context need to be setup. This context keep states * An encoder / decoder context needs to be setup. This context keeps states * on the current stream to proceed, and samples that overlapped across * frames. * Loading Loading @@ -96,12 +96,17 @@ * * Next, call the `lc3_encode()` encoding procedure, for each frames. * To handle multichannel streams (Stereo or more), you can proceed with * inerleaved channels PCM stream like this : * interleaved channels PCM stream like this : * * | for(int ich = 0; ich < nch: ich++) * | lc3_encode(encoder[ich], pcm + ich, nch, ...); * * with `nch` as the number of channels in the PCM stream * * --- * * Antoine SOULIER, Tempow / Google LLC * */ #ifndef __LC3_H Loading Loading @@ -192,7 +197,7 @@ int lc3_frame_samples(int dt_us, int sr_hz); /** * Return the size of frames, from bitrate * dt_us Frame duration in us, 7500 or 10000 * bitrate Target bitrate in bit per seconds * bitrate Target bitrate in bit per second * return The floor size in bytes of the frames, -1 on bad parameters */ int lc3_frame_bytes(int dt_us, int bitrate); Loading system/embdrv/lc3/include/lc3_private.h +21 −15 Original line number Diff line number Diff line /****************************************************************************** * * Copyright 2015 Google, Inc. * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. Loading @@ -26,7 +26,8 @@ /** * Return number of samples, delayed samples and * encoded spectrum coefficients within a frame * For decoding, add number of samples of 18 ms history * - For encoding, keep 1.25 ms of temporal winodw * - For decoding, keep 18 ms of history, aligned on frames, and a frame */ #define __LC3_NS(dt_us, sr_hz) \ Loading @@ -36,8 +37,11 @@ ( (dt_us) == 7500 ? 23 * __LC3_NS(dt_us, sr_hz) / 30 \ : 5 * __LC3_NS(dt_us, sr_hz) / 8 ) #define __LC3_NH(sr_hz) \ ( (18 * sr_hz) / 1000 ) #define __LC3_NT(sr_hz) \ ( (5 * sr_hz) / 4000 ) #define __LC3_NH(dt_us, sr_hz) \ ( ((3 - ((dt_us) >= 10000)) + 1) * __LC3_NS(dt_us, sr_hz) ) /** Loading Loading @@ -71,12 +75,12 @@ enum lc3_srate { */ typedef struct lc3_attdet_analysis { float en1, an1; int32_t en1, an1; int p_att; } lc3_attdet_analysis_t; struct lc3_ltpf_hp50_state { float s1, s2; int64_t s1, s2; }; typedef struct lc3_ltpf_analysis { Loading @@ -85,8 +89,8 @@ typedef struct lc3_ltpf_analysis { float nc[2]; struct lc3_ltpf_hp50_state hp50; float x_12k8[384]; float x_6k4[178]; int16_t x_12k8[384]; int16_t x_6k4[178]; int tc; } lc3_ltpf_analysis_t; Loading @@ -103,11 +107,13 @@ struct lc3_encoder { lc3_ltpf_analysis_t ltpf; lc3_spec_analysis_t spec; float *xs, *xf, s[0]; int16_t *xt; float *xs, *xd, s[0]; }; #define LC3_ENCODER_BUFFER_COUNT(dt_us, sr_hz) \ ( 2*__LC3_NS(dt_us, sr_hz) + __LC3_ND(dt_us, sr_hz) ) ( ( __LC3_NS(dt_us, sr_hz) + __LC3_NT(sr_hz) ) / 2 + \ __LC3_NS(dt_us, sr_hz) + __LC3_ND(dt_us, sr_hz) ) #define LC3_ENCODER_MEM_T(dt_us, sr_hz) \ struct { \ Loading @@ -123,7 +129,7 @@ struct lc3_encoder { typedef struct lc3_ltpf_synthesis { bool active; int pitch; float c[12][2], x[12]; float c[2*12], x[12]; } lc3_ltpf_synthesis_t; typedef struct lc3_plc_state { Loading @@ -139,12 +145,12 @@ struct lc3_decoder { lc3_ltpf_synthesis_t ltpf; lc3_plc_state_t plc; float *xs, *xd, *xg, s[0]; float *xh, *xs, *xd, *xg, s[0]; }; #define LC3_DECODER_BUFFER_COUNT(dt_us, sr_hz) \ ( __LC3_NH(sr_hz) + __LC3_NS(dt_us, sr_hz) + \ __LC3_ND(dt_us, sr_hz) + __LC3_NS(dt_us, sr_hz) ) ( __LC3_NH(dt_us, sr_hz) + __LC3_ND(dt_us, sr_hz) + \ __LC3_NS(dt_us, sr_hz) ) #define LC3_DECODER_MEM_T(dt_us, sr_hz) \ struct { \ Loading system/embdrv/lc3/src/attdet.c +18 −18 Original line number Diff line number Diff line /****************************************************************************** * * Copyright 2021 Google, Inc. * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. Loading @@ -23,7 +23,7 @@ * Time domain attack detector */ bool lc3_attdet_run(enum lc3_dt dt, enum lc3_srate sr, int nbytes, struct lc3_attdet_analysis *attdet, const float *x) int nbytes, struct lc3_attdet_analysis *attdet, const int16_t *x) { /* --- Check enabling --- */ Loading @@ -40,32 +40,32 @@ bool lc3_attdet_run(enum lc3_dt dt, enum lc3_srate sr, /* --- Filtering & Energy calculation --- */ int nblk = 4 - (dt == LC3_DT_7M5); float e[4]; int32_t e[4]; for (int i = 0; i < nblk; i++) { e[i] = 0; if (sr == LC3_SRATE_32K) { float xn2 = x[-4] + x[-3]; float xn1 = x[-2] + x[-1]; float xn, xf; int16_t xn2 = (x[-4] + x[-3]) >> 1; int16_t xn1 = (x[-2] + x[-1]) >> 1; int16_t xn, xf; for (int j = 0; j < 40; j++, x += 2, xn2 = xn1, xn1 = xn) { xn = x[0] + x[1]; xf = 0.375 * xn - 0.5 * xn1 + 0.125 * xn2; e[i] += xf * xf; xn = (x[0] + x[1]) >> 1; xf = (3 * xn - 4 * xn1 + 1 * xn2) >> 3; e[i] += (xf * xf) >> 5; } } else { float xn2 = x[-6] + x[-5] + x[-4]; float xn1 = x[-3] + x[-2] + x[-1]; float xn, xf; int16_t xn2 = (x[-6] + x[-5] + x[-4]) >> 2; int16_t xn1 = (x[-3] + x[-2] + x[-1]) >> 2; int16_t xn, xf; for (int j = 0; j < 40; j++, x += 3, xn2 = xn1, xn1 = xn) { xn = x[0] + x[1] + x[2]; xf = 0.375 * xn - 0.5 * xn1 + 0.125 * xn2; e[i] += xf * xf; xn = (x[0] + x[1] + x[2]) >> 2; xf = (3 * xn - 4 * xn1 + 1 * xn2) >> 3; e[i] += (xf * xf) >> 5; } } } Loading @@ -75,13 +75,13 @@ bool lc3_attdet_run(enum lc3_dt dt, enum lc3_srate sr, * in such way, it will be initialized to 0 */ int p_att = 0; float a[4]; int32_t a[4]; for (int i = 0; i < nblk; i++) { a[i] = fmaxf(0.25 * attdet->an1, attdet->en1); a[i] = LC3_MAX(attdet->an1 >> 2, attdet->en1); attdet->en1 = e[i], attdet->an1 = a[i]; if (e[i] > 8.5 * a[i]) if ((e[i] >> 3) > a[i] + (a[i] >> 4)) p_att = i + 1; } Loading system/embdrv/lc3/src/attdet.h +2 −2 Original line number Diff line number Diff line /****************************************************************************** * * Copyright 2021 Google, Inc. * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. Loading Loading @@ -38,7 +38,7 @@ * return 1: Attack detected 0: Otherwise */ bool lc3_attdet_run(enum lc3_dt dt, enum lc3_srate sr, int nbytes, lc3_attdet_analysis_t *attdet, const float *x); int nbytes, lc3_attdet_analysis_t *attdet, const int16_t *x); #endif /* __LC3_ATTDET_H */ system/embdrv/lc3/src/bits.c +6 −6 Original line number Diff line number Diff line /****************************************************************************** * * Copyright 2021 Google, Inc. * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. Loading Loading @@ -167,7 +167,7 @@ static inline void ac_put(struct lc3_bits_buffer *buffer, int byte) * ac Arithmetic coder * buffer Bitstream buffer */ static inline void ac_shift( LC3_HOT static inline void ac_shift( struct lc3_bits_ac *ac, struct lc3_bits_buffer *buffer) { if (ac->low < 0xff0000 || ac->carry) Loading Loading @@ -262,7 +262,7 @@ void lc3_flush_bits(struct lc3_bits *bits) * Write from 1 to 32 bits, * exceeding the capacity of the accumulator */ void lc3_put_bits_generic(struct lc3_bits *bits, unsigned v, int n) LC3_HOT void lc3_put_bits_generic(struct lc3_bits *bits, unsigned v, int n) { struct lc3_bits_accu *accu = &bits->accu; Loading @@ -285,7 +285,7 @@ void lc3_put_bits_generic(struct lc3_bits *bits, unsigned v, int n) /** * Arithmetic coder renormalization */ void lc3_ac_write_renorm(struct lc3_bits *bits) LC3_HOT void lc3_ac_write_renorm(struct lc3_bits *bits) { struct lc3_bits_ac *ac = &bits->ac; Loading Loading @@ -336,7 +336,7 @@ static inline void accu_load(struct lc3_bits_accu *accu, * Read from 1 to 32 bits, * exceeding the capacity of the accumulator */ unsigned lc3_get_bits_generic(struct lc3_bits *bits, int n) LC3_HOT unsigned lc3_get_bits_generic(struct lc3_bits *bits, int n) { struct lc3_bits_accu *accu = &bits->accu; struct lc3_bits_buffer *buffer = &bits->buffer; Loading Loading @@ -366,7 +366,7 @@ unsigned lc3_get_bits_generic(struct lc3_bits *bits, int n) /** * Arithmetic coder renormalization */ void lc3_ac_read_renorm(struct lc3_bits *bits) LC3_HOT void lc3_ac_read_renorm(struct lc3_bits *bits) { struct lc3_bits_ac *ac = &bits->ac; Loading Loading
system/embdrv/lc3/include/lc3.h +14 −9 Original line number Diff line number Diff line /****************************************************************************** * * Copyright 2021 Google, Inc. * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. Loading Loading @@ -39,17 +39,17 @@ * it can follow a temporary bandwidth increase or reduction. * * - Unlike classic codecs, the LC3 codecs does not run on fixed amount * of samples as input. It operate only on fixed frame duration, for * any supported samplerates (8 to 48 KHz). Two frame duration are * of samples as input. It operates only on fixed frame duration, for * any supported samplerates (8 to 48 KHz). Two frames duration are * available 7.5ms and 10ms. * * * --- About 44.1 KHz samplerate --- * * The Bluetooth specification oddly add the 44.1 KHz samplerate. Although * there is NO SUPPORT in the core algorithm of the codec of 44.1 KHz. * The Bluetooth specification reference the 44.1 KHz samplerate, although * there is no support in the core algorithm of the codec of 44.1 KHz. * We can summarize the 44.1 KHz support by "you can put any samplerate * around the base defined samplerates". But be concerned by : * around the defined base samplerates". Please mind the following items : * * 1. The frame size will not be 7.5 ms or 10 ms, but is scaled * by 'supported samplerate' / 'input samplerate' Loading @@ -68,7 +68,7 @@ * * --- How to encode / decode --- * * An encoder / decoder context need to be setup. This context keep states * An encoder / decoder context needs to be setup. This context keeps states * on the current stream to proceed, and samples that overlapped across * frames. * Loading Loading @@ -96,12 +96,17 @@ * * Next, call the `lc3_encode()` encoding procedure, for each frames. * To handle multichannel streams (Stereo or more), you can proceed with * inerleaved channels PCM stream like this : * interleaved channels PCM stream like this : * * | for(int ich = 0; ich < nch: ich++) * | lc3_encode(encoder[ich], pcm + ich, nch, ...); * * with `nch` as the number of channels in the PCM stream * * --- * * Antoine SOULIER, Tempow / Google LLC * */ #ifndef __LC3_H Loading Loading @@ -192,7 +197,7 @@ int lc3_frame_samples(int dt_us, int sr_hz); /** * Return the size of frames, from bitrate * dt_us Frame duration in us, 7500 or 10000 * bitrate Target bitrate in bit per seconds * bitrate Target bitrate in bit per second * return The floor size in bytes of the frames, -1 on bad parameters */ int lc3_frame_bytes(int dt_us, int bitrate); Loading
system/embdrv/lc3/include/lc3_private.h +21 −15 Original line number Diff line number Diff line /****************************************************************************** * * Copyright 2015 Google, Inc. * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. Loading @@ -26,7 +26,8 @@ /** * Return number of samples, delayed samples and * encoded spectrum coefficients within a frame * For decoding, add number of samples of 18 ms history * - For encoding, keep 1.25 ms of temporal winodw * - For decoding, keep 18 ms of history, aligned on frames, and a frame */ #define __LC3_NS(dt_us, sr_hz) \ Loading @@ -36,8 +37,11 @@ ( (dt_us) == 7500 ? 23 * __LC3_NS(dt_us, sr_hz) / 30 \ : 5 * __LC3_NS(dt_us, sr_hz) / 8 ) #define __LC3_NH(sr_hz) \ ( (18 * sr_hz) / 1000 ) #define __LC3_NT(sr_hz) \ ( (5 * sr_hz) / 4000 ) #define __LC3_NH(dt_us, sr_hz) \ ( ((3 - ((dt_us) >= 10000)) + 1) * __LC3_NS(dt_us, sr_hz) ) /** Loading Loading @@ -71,12 +75,12 @@ enum lc3_srate { */ typedef struct lc3_attdet_analysis { float en1, an1; int32_t en1, an1; int p_att; } lc3_attdet_analysis_t; struct lc3_ltpf_hp50_state { float s1, s2; int64_t s1, s2; }; typedef struct lc3_ltpf_analysis { Loading @@ -85,8 +89,8 @@ typedef struct lc3_ltpf_analysis { float nc[2]; struct lc3_ltpf_hp50_state hp50; float x_12k8[384]; float x_6k4[178]; int16_t x_12k8[384]; int16_t x_6k4[178]; int tc; } lc3_ltpf_analysis_t; Loading @@ -103,11 +107,13 @@ struct lc3_encoder { lc3_ltpf_analysis_t ltpf; lc3_spec_analysis_t spec; float *xs, *xf, s[0]; int16_t *xt; float *xs, *xd, s[0]; }; #define LC3_ENCODER_BUFFER_COUNT(dt_us, sr_hz) \ ( 2*__LC3_NS(dt_us, sr_hz) + __LC3_ND(dt_us, sr_hz) ) ( ( __LC3_NS(dt_us, sr_hz) + __LC3_NT(sr_hz) ) / 2 + \ __LC3_NS(dt_us, sr_hz) + __LC3_ND(dt_us, sr_hz) ) #define LC3_ENCODER_MEM_T(dt_us, sr_hz) \ struct { \ Loading @@ -123,7 +129,7 @@ struct lc3_encoder { typedef struct lc3_ltpf_synthesis { bool active; int pitch; float c[12][2], x[12]; float c[2*12], x[12]; } lc3_ltpf_synthesis_t; typedef struct lc3_plc_state { Loading @@ -139,12 +145,12 @@ struct lc3_decoder { lc3_ltpf_synthesis_t ltpf; lc3_plc_state_t plc; float *xs, *xd, *xg, s[0]; float *xh, *xs, *xd, *xg, s[0]; }; #define LC3_DECODER_BUFFER_COUNT(dt_us, sr_hz) \ ( __LC3_NH(sr_hz) + __LC3_NS(dt_us, sr_hz) + \ __LC3_ND(dt_us, sr_hz) + __LC3_NS(dt_us, sr_hz) ) ( __LC3_NH(dt_us, sr_hz) + __LC3_ND(dt_us, sr_hz) + \ __LC3_NS(dt_us, sr_hz) ) #define LC3_DECODER_MEM_T(dt_us, sr_hz) \ struct { \ Loading
system/embdrv/lc3/src/attdet.c +18 −18 Original line number Diff line number Diff line /****************************************************************************** * * Copyright 2021 Google, Inc. * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. Loading @@ -23,7 +23,7 @@ * Time domain attack detector */ bool lc3_attdet_run(enum lc3_dt dt, enum lc3_srate sr, int nbytes, struct lc3_attdet_analysis *attdet, const float *x) int nbytes, struct lc3_attdet_analysis *attdet, const int16_t *x) { /* --- Check enabling --- */ Loading @@ -40,32 +40,32 @@ bool lc3_attdet_run(enum lc3_dt dt, enum lc3_srate sr, /* --- Filtering & Energy calculation --- */ int nblk = 4 - (dt == LC3_DT_7M5); float e[4]; int32_t e[4]; for (int i = 0; i < nblk; i++) { e[i] = 0; if (sr == LC3_SRATE_32K) { float xn2 = x[-4] + x[-3]; float xn1 = x[-2] + x[-1]; float xn, xf; int16_t xn2 = (x[-4] + x[-3]) >> 1; int16_t xn1 = (x[-2] + x[-1]) >> 1; int16_t xn, xf; for (int j = 0; j < 40; j++, x += 2, xn2 = xn1, xn1 = xn) { xn = x[0] + x[1]; xf = 0.375 * xn - 0.5 * xn1 + 0.125 * xn2; e[i] += xf * xf; xn = (x[0] + x[1]) >> 1; xf = (3 * xn - 4 * xn1 + 1 * xn2) >> 3; e[i] += (xf * xf) >> 5; } } else { float xn2 = x[-6] + x[-5] + x[-4]; float xn1 = x[-3] + x[-2] + x[-1]; float xn, xf; int16_t xn2 = (x[-6] + x[-5] + x[-4]) >> 2; int16_t xn1 = (x[-3] + x[-2] + x[-1]) >> 2; int16_t xn, xf; for (int j = 0; j < 40; j++, x += 3, xn2 = xn1, xn1 = xn) { xn = x[0] + x[1] + x[2]; xf = 0.375 * xn - 0.5 * xn1 + 0.125 * xn2; e[i] += xf * xf; xn = (x[0] + x[1] + x[2]) >> 2; xf = (3 * xn - 4 * xn1 + 1 * xn2) >> 3; e[i] += (xf * xf) >> 5; } } } Loading @@ -75,13 +75,13 @@ bool lc3_attdet_run(enum lc3_dt dt, enum lc3_srate sr, * in such way, it will be initialized to 0 */ int p_att = 0; float a[4]; int32_t a[4]; for (int i = 0; i < nblk; i++) { a[i] = fmaxf(0.25 * attdet->an1, attdet->en1); a[i] = LC3_MAX(attdet->an1 >> 2, attdet->en1); attdet->en1 = e[i], attdet->an1 = a[i]; if (e[i] > 8.5 * a[i]) if ((e[i] >> 3) > a[i] + (a[i] >> 4)) p_att = i + 1; } Loading
system/embdrv/lc3/src/attdet.h +2 −2 Original line number Diff line number Diff line /****************************************************************************** * * Copyright 2021 Google, Inc. * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. Loading Loading @@ -38,7 +38,7 @@ * return 1: Attack detected 0: Otherwise */ bool lc3_attdet_run(enum lc3_dt dt, enum lc3_srate sr, int nbytes, lc3_attdet_analysis_t *attdet, const float *x); int nbytes, lc3_attdet_analysis_t *attdet, const int16_t *x); #endif /* __LC3_ATTDET_H */
system/embdrv/lc3/src/bits.c +6 −6 Original line number Diff line number Diff line /****************************************************************************** * * Copyright 2021 Google, Inc. * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. Loading Loading @@ -167,7 +167,7 @@ static inline void ac_put(struct lc3_bits_buffer *buffer, int byte) * ac Arithmetic coder * buffer Bitstream buffer */ static inline void ac_shift( LC3_HOT static inline void ac_shift( struct lc3_bits_ac *ac, struct lc3_bits_buffer *buffer) { if (ac->low < 0xff0000 || ac->carry) Loading Loading @@ -262,7 +262,7 @@ void lc3_flush_bits(struct lc3_bits *bits) * Write from 1 to 32 bits, * exceeding the capacity of the accumulator */ void lc3_put_bits_generic(struct lc3_bits *bits, unsigned v, int n) LC3_HOT void lc3_put_bits_generic(struct lc3_bits *bits, unsigned v, int n) { struct lc3_bits_accu *accu = &bits->accu; Loading @@ -285,7 +285,7 @@ void lc3_put_bits_generic(struct lc3_bits *bits, unsigned v, int n) /** * Arithmetic coder renormalization */ void lc3_ac_write_renorm(struct lc3_bits *bits) LC3_HOT void lc3_ac_write_renorm(struct lc3_bits *bits) { struct lc3_bits_ac *ac = &bits->ac; Loading Loading @@ -336,7 +336,7 @@ static inline void accu_load(struct lc3_bits_accu *accu, * Read from 1 to 32 bits, * exceeding the capacity of the accumulator */ unsigned lc3_get_bits_generic(struct lc3_bits *bits, int n) LC3_HOT unsigned lc3_get_bits_generic(struct lc3_bits *bits, int n) { struct lc3_bits_accu *accu = &bits->accu; struct lc3_bits_buffer *buffer = &bits->buffer; Loading Loading @@ -366,7 +366,7 @@ unsigned lc3_get_bits_generic(struct lc3_bits *bits, int n) /** * Arithmetic coder renormalization */ void lc3_ac_read_renorm(struct lc3_bits *bits) LC3_HOT void lc3_ac_read_renorm(struct lc3_bits *bits) { struct lc3_bits_ac *ac = &bits->ac; Loading