Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 167bc0a8 authored by Jakub Pawłowski's avatar Jakub Pawłowski Committed by Automerger Merge Worker
Browse files
parents 54446572 bdf25f5c
Loading
Loading
Loading
Loading
+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.
@@ -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'
@@ -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.
 *
@@ -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
@@ -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);
+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.
@@ -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) \
@@ -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) )


/**
@@ -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 {
@@ -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;

@@ -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 { \
@@ -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 {
@@ -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 { \
+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.
@@ -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 --- */

@@ -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;
            }
        }
    }
@@ -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;
    }

+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.
@@ -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 */
+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.
@@ -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)
@@ -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;

@@ -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;

@@ -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;
@@ -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