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

Commit da3b3b7b authored by Antoine Soulier's avatar Antoine Soulier Committed by Jakub Pawlowski
Browse files

Add 24 bits PCM input/output

Test: compilation
Bug: 150670922
Change-Id: Iec549a6462043d3aef629ac53cd2e911e915f265
parent 18ad2a65
Loading
Loading
Loading
Loading
+17 −2
Original line number Diff line number Diff line
@@ -144,6 +144,19 @@ extern "C" {
      ((sr) == 32000) || ((sr) == 48000)                       )


/**
 * PCM Sample Format
 *   S16  Signed 16 bits, in 16 bits words (int16_t)
 *   S24  Signed 24 bits, using low three bytes of 32 bits words (int32_t).
 *        The high byte sign extends the sample value (bits 31..24 set to b23).
 */

enum lc3_pcm_format {
    LC3_PCM_FORMAT_S16,
    LC3_PCM_FORMAT_S24,
};


/**
 * Handle
 */
@@ -231,13 +244,14 @@ lc3_encoder_t lc3_setup_encoder(
/**
 * Encode a frame
 * encoder         Handle of the encoder
 * fmt             PCM input format
 * pcm, pitch      Input PCM samples, and count between two consecutives
 * nbytes          Target size, in bytes, of the frame (20 to 400)
 * out             Output buffer of `nbytes` size
 * return          0: On success  -1: Wrong parameters
 */
int lc3_encode(lc3_encoder_t encoder,
    const int16_t *pcm, int pitch, int nbytes, void *out);
    enum lc3_pcm_format fmt, const void *pcm, int pitch, int nbytes, void *out);

/**
 * Return size needed for an decoder
@@ -271,11 +285,12 @@ lc3_decoder_t lc3_setup_decoder(
 * Decode a frame
 * decoder         Handle of the decoder
 * in, nbytes      Input bitstream, and size in bytes, NULL performs PLC
 * fmt             PCM output format
 * pcm, pitch      Output PCM samples, and count between two consecutives
 * return          0: On success  1: PLC operated  -1: Wrong parameters
 */
int lc3_decode(lc3_decoder_t decoder,
    const void *in, int nbytes, int16_t *pcm, int pitch);
    const void *in, int nbytes, enum lc3_pcm_format fmt, void *pcm, int pitch);


#ifdef __cplusplus
+63 −6
Original line number Diff line number Diff line
@@ -150,8 +150,10 @@ int lc3_delay_samples(int dt_us, int sr_hz)
 * pcm, pitch      Input PCM samples, and count between two consecutives
 */
static void load_s16(
    struct lc3_encoder *encoder, const int16_t *pcm, int pitch)
    struct lc3_encoder *encoder, const void *_pcm, int pitch)
{
    const int16_t *pcm = _pcm;

    enum lc3_dt dt = encoder->dt;
    enum lc3_srate sr = encoder->sr_pcm;
    float *xs = encoder->xs;
@@ -161,6 +163,25 @@ static void load_s16(
        xs[i] = pcm[i*pitch];
}

/**
 * Input PCM Samples from signed 24 bits
 * encoder         Encoder state
 * pcm, pitch      Input PCM samples, and count between two consecutives
 */
static void load_s24(
    struct lc3_encoder *encoder, const void *_pcm, int pitch)
{
    const int32_t *pcm = _pcm;

    enum lc3_dt dt = encoder->dt;
    enum lc3_srate sr = encoder->sr_pcm;
    float *xs = encoder->xs;
    int ns = LC3_NS(dt, sr);

    for (int i = 0; i < ns; i++)
        xs[i] = ldexpf(pcm[i*pitch], -8);
}

/**
 * Frame Analysis
 * encoder         Encoder state
@@ -296,8 +317,13 @@ struct lc3_encoder *lc3_setup_encoder(
 * Encode a frame
 */
int lc3_encode(struct lc3_encoder *encoder,
    const int16_t *pcm, int pitch, int nbytes, void *out)
    enum lc3_pcm_format fmt, const void *pcm, int pitch, int nbytes, void *out)
{
    static void (* const load[])(struct lc3_encoder *, const void *, int) = {
        [LC3_PCM_FORMAT_S16] = load_s16,
        [LC3_PCM_FORMAT_S24] = load_s24,
    };

    /* --- Check parameters --- */

    if (!encoder || nbytes < LC3_MIN_FRAME_BYTES
@@ -309,7 +335,7 @@ int lc3_encode(struct lc3_encoder *encoder,
    struct side_data side;
    int16_t xq[LC3_NE(encoder->dt, encoder->sr)];

    load_s16(encoder, pcm, pitch);
    load[fmt](encoder, pcm, pitch);

    analyze(encoder, nbytes, &side, xq);

@@ -329,8 +355,10 @@ int lc3_encode(struct lc3_encoder *encoder,
 * pcm, pitch      Output PCM samples, and count between two consecutives
 */
static void store_s16(
    struct lc3_decoder *decoder, int16_t *pcm, int pitch)
    struct lc3_decoder *decoder, void *_pcm, int pitch)
{
    int16_t *pcm = _pcm;

    enum lc3_dt dt = decoder->dt;
    enum lc3_srate sr = decoder->sr_pcm;
    float *xs = decoder->xs;
@@ -342,6 +370,30 @@ static void store_s16(
    }
}

/**
 * Output PCM Samples to signed 24 bits
 * decoder         Decoder state
 * pcm, pitch      Output PCM samples, and count between two consecutives
 */
static void store_s24(
    struct lc3_decoder *decoder, void *_pcm, int pitch)
{
    int32_t *pcm = _pcm;
    const int32_t int24_max =  (1 << 23) - 1;
    const int32_t int24_min = -(1 << 23);

    enum lc3_dt dt = decoder->dt;
    enum lc3_srate sr = decoder->sr_pcm;
    float *xs = decoder->xs;
    int ns = LC3_NS(dt, sr);

    for ( ; ns > 0; ns--, xs++, pcm += pitch) {
        int32_t s = *xs >= 0 ? (int32_t)(ldexpf(*xs, 8) + 0.5f)
                             : (int32_t)(ldexpf(*xs, 8) - 0.5f);
        *pcm = LC3_CLIP(s, int24_min, int24_max);
    }
}

/**
 * Decode bitstream
 * decoder         Decoder state
@@ -485,8 +537,13 @@ struct lc3_decoder *lc3_setup_decoder(
 * Decode a frame
 */
int lc3_decode(struct lc3_decoder *decoder,
    const void *in, int nbytes, int16_t *pcm, int pitch)
    const void *in, int nbytes, enum lc3_pcm_format fmt, void *pcm, int pitch)
{
    static void (* const store[])(struct lc3_decoder *, void *, int) = {
        [LC3_PCM_FORMAT_S16] = store_s16,
        [LC3_PCM_FORMAT_S24] = store_s24,
    };

    /* --- Check parameters --- */

    if (!decoder)
@@ -504,7 +561,7 @@ int lc3_decode(struct lc3_decoder *decoder,

    synthesize(decoder, ret ? NULL : &side, nbytes);

    store_s16(decoder, pcm, pitch);
    store[fmt](decoder, pcm, pitch);

    return ret;
}