xref: /btstack/3rd-party/lc3-google/src/lc3.c (revision 4c4eb519208b4224604d94b3ed1931841ddd93bb)
19a19cd78SMatthias Ringwald /******************************************************************************
29a19cd78SMatthias Ringwald  *
34930cef6SMatthias Ringwald  *  Copyright 2022 Google LLC
49a19cd78SMatthias Ringwald  *
59a19cd78SMatthias Ringwald  *  Licensed under the Apache License, Version 2.0 (the "License");
69a19cd78SMatthias Ringwald  *  you may not use this file except in compliance with the License.
79a19cd78SMatthias Ringwald  *  You may obtain a copy of the License at:
89a19cd78SMatthias Ringwald  *
99a19cd78SMatthias Ringwald  *  http://www.apache.org/licenses/LICENSE-2.0
109a19cd78SMatthias Ringwald  *
119a19cd78SMatthias Ringwald  *  Unless required by applicable law or agreed to in writing, software
129a19cd78SMatthias Ringwald  *  distributed under the License is distributed on an "AS IS" BASIS,
139a19cd78SMatthias Ringwald  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
149a19cd78SMatthias Ringwald  *  See the License for the specific language governing permissions and
159a19cd78SMatthias Ringwald  *  limitations under the License.
169a19cd78SMatthias Ringwald  *
179a19cd78SMatthias Ringwald  ******************************************************************************/
189a19cd78SMatthias Ringwald 
199a19cd78SMatthias Ringwald #include <lc3.h>
209a19cd78SMatthias Ringwald 
219a19cd78SMatthias Ringwald #include "common.h"
229a19cd78SMatthias Ringwald #include "bits.h"
239a19cd78SMatthias Ringwald 
249a19cd78SMatthias Ringwald #include "attdet.h"
259a19cd78SMatthias Ringwald #include "bwdet.h"
269a19cd78SMatthias Ringwald #include "ltpf.h"
279a19cd78SMatthias Ringwald #include "mdct.h"
289a19cd78SMatthias Ringwald #include "energy.h"
299a19cd78SMatthias Ringwald #include "sns.h"
309a19cd78SMatthias Ringwald #include "tns.h"
319a19cd78SMatthias Ringwald #include "spec.h"
329a19cd78SMatthias Ringwald #include "plc.h"
339a19cd78SMatthias Ringwald 
349a19cd78SMatthias Ringwald 
359a19cd78SMatthias Ringwald /**
369a19cd78SMatthias Ringwald  * Frame side data
379a19cd78SMatthias Ringwald  */
389a19cd78SMatthias Ringwald 
399a19cd78SMatthias Ringwald struct side_data {
409a19cd78SMatthias Ringwald     enum lc3_bandwidth bw;
419a19cd78SMatthias Ringwald     bool pitch_present;
429a19cd78SMatthias Ringwald     lc3_ltpf_data_t ltpf;
439a19cd78SMatthias Ringwald     lc3_sns_data_t sns;
449a19cd78SMatthias Ringwald     lc3_tns_data_t tns;
459a19cd78SMatthias Ringwald     lc3_spec_side_t spec;
469a19cd78SMatthias Ringwald };
479a19cd78SMatthias Ringwald 
489a19cd78SMatthias Ringwald 
499a19cd78SMatthias Ringwald /* ----------------------------------------------------------------------------
509a19cd78SMatthias Ringwald  *  General
519a19cd78SMatthias Ringwald  * -------------------------------------------------------------------------- */
529a19cd78SMatthias Ringwald 
539a19cd78SMatthias Ringwald /**
549a19cd78SMatthias Ringwald  * Resolve frame duration in us
559a19cd78SMatthias Ringwald  * us              Frame duration in us
569a19cd78SMatthias Ringwald  * return          Frame duration identifier, or LC3_NUM_DT
579a19cd78SMatthias Ringwald  */
589a19cd78SMatthias Ringwald static enum lc3_dt resolve_dt(int us)
599a19cd78SMatthias Ringwald {
609a19cd78SMatthias Ringwald     return us ==  7500 ? LC3_DT_7M5 :
619a19cd78SMatthias Ringwald            us == 10000 ? LC3_DT_10M : LC3_NUM_DT;
629a19cd78SMatthias Ringwald }
639a19cd78SMatthias Ringwald 
649a19cd78SMatthias Ringwald /**
659a19cd78SMatthias Ringwald  * Resolve samplerate in Hz
669a19cd78SMatthias Ringwald  * hz              Samplerate in Hz
679a19cd78SMatthias Ringwald  * return          Sample rate identifier, or LC3_NUM_SRATE
689a19cd78SMatthias Ringwald  */
699a19cd78SMatthias Ringwald static enum lc3_srate resolve_sr(int hz)
709a19cd78SMatthias Ringwald {
719a19cd78SMatthias Ringwald     return hz ==  8000 ? LC3_SRATE_8K  : hz == 16000 ? LC3_SRATE_16K :
729a19cd78SMatthias Ringwald            hz == 24000 ? LC3_SRATE_24K : hz == 32000 ? LC3_SRATE_32K :
739a19cd78SMatthias Ringwald            hz == 48000 ? LC3_SRATE_48K : LC3_NUM_SRATE;
749a19cd78SMatthias Ringwald }
759a19cd78SMatthias Ringwald 
769a19cd78SMatthias Ringwald /**
779a19cd78SMatthias Ringwald  * Return the number of PCM samples in a frame
789a19cd78SMatthias Ringwald  */
799a19cd78SMatthias Ringwald int lc3_frame_samples(int dt_us, int sr_hz)
809a19cd78SMatthias Ringwald {
819a19cd78SMatthias Ringwald     enum lc3_dt dt = resolve_dt(dt_us);
829a19cd78SMatthias Ringwald     enum lc3_srate sr = resolve_sr(sr_hz);
839a19cd78SMatthias Ringwald 
849a19cd78SMatthias Ringwald     if (dt >= LC3_NUM_DT || sr >= LC3_NUM_SRATE)
859a19cd78SMatthias Ringwald         return -1;
869a19cd78SMatthias Ringwald 
879a19cd78SMatthias Ringwald     return LC3_NS(dt, sr);
889a19cd78SMatthias Ringwald }
899a19cd78SMatthias Ringwald 
909a19cd78SMatthias Ringwald /**
919a19cd78SMatthias Ringwald  * Return the size of frames, from bitrate
929a19cd78SMatthias Ringwald  */
939a19cd78SMatthias Ringwald int lc3_frame_bytes(int dt_us, int bitrate)
949a19cd78SMatthias Ringwald {
959a19cd78SMatthias Ringwald     if (resolve_dt(dt_us) >= LC3_NUM_DT)
969a19cd78SMatthias Ringwald         return -1;
979a19cd78SMatthias Ringwald 
989a19cd78SMatthias Ringwald     if (bitrate < LC3_MIN_BITRATE)
999a19cd78SMatthias Ringwald         return LC3_MIN_FRAME_BYTES;
1009a19cd78SMatthias Ringwald 
1019a19cd78SMatthias Ringwald     if (bitrate > LC3_MAX_BITRATE)
1029a19cd78SMatthias Ringwald         return LC3_MAX_FRAME_BYTES;
1039a19cd78SMatthias Ringwald 
1049a19cd78SMatthias Ringwald     int nbytes = ((unsigned)bitrate * dt_us) / (1000*1000*8);
1059a19cd78SMatthias Ringwald 
1069a19cd78SMatthias Ringwald     return LC3_CLIP(nbytes, LC3_MIN_FRAME_BYTES, LC3_MAX_FRAME_BYTES);
1079a19cd78SMatthias Ringwald }
1089a19cd78SMatthias Ringwald 
1099a19cd78SMatthias Ringwald /**
1109a19cd78SMatthias Ringwald  * Resolve the bitrate, from the size of frames
1119a19cd78SMatthias Ringwald  */
1129a19cd78SMatthias Ringwald int lc3_resolve_bitrate(int dt_us, int nbytes)
1139a19cd78SMatthias Ringwald {
1149a19cd78SMatthias Ringwald     if (resolve_dt(dt_us) >= LC3_NUM_DT)
1159a19cd78SMatthias Ringwald         return -1;
1169a19cd78SMatthias Ringwald 
1179a19cd78SMatthias Ringwald     if (nbytes < LC3_MIN_FRAME_BYTES)
1189a19cd78SMatthias Ringwald         return LC3_MIN_BITRATE;
1199a19cd78SMatthias Ringwald 
1209a19cd78SMatthias Ringwald     if (nbytes > LC3_MAX_FRAME_BYTES)
1219a19cd78SMatthias Ringwald         return LC3_MAX_BITRATE;
1229a19cd78SMatthias Ringwald 
1239a19cd78SMatthias Ringwald     int bitrate = ((unsigned)nbytes * (1000*1000*8) + dt_us/2) / dt_us;
1249a19cd78SMatthias Ringwald 
1259a19cd78SMatthias Ringwald     return LC3_CLIP(bitrate, LC3_MIN_BITRATE, LC3_MAX_BITRATE);
1269a19cd78SMatthias Ringwald }
1279a19cd78SMatthias Ringwald 
1289a19cd78SMatthias Ringwald /**
1299a19cd78SMatthias Ringwald  * Return algorithmic delay, as a number of samples
1309a19cd78SMatthias Ringwald  */
1319a19cd78SMatthias Ringwald int lc3_delay_samples(int dt_us, int sr_hz)
1329a19cd78SMatthias Ringwald {
1339a19cd78SMatthias Ringwald     enum lc3_dt dt = resolve_dt(dt_us);
1349a19cd78SMatthias Ringwald     enum lc3_srate sr = resolve_sr(sr_hz);
1359a19cd78SMatthias Ringwald 
1369a19cd78SMatthias Ringwald     if (dt >= LC3_NUM_DT || sr >= LC3_NUM_SRATE)
1379a19cd78SMatthias Ringwald         return -1;
1389a19cd78SMatthias Ringwald 
1399a19cd78SMatthias Ringwald     return (dt == LC3_DT_7M5 ? 8 : 5) * (LC3_SRATE_KHZ(sr) / 2);
1409a19cd78SMatthias Ringwald }
1419a19cd78SMatthias Ringwald 
1429a19cd78SMatthias Ringwald 
1439a19cd78SMatthias Ringwald /* ----------------------------------------------------------------------------
1449a19cd78SMatthias Ringwald  *  Encoder
1459a19cd78SMatthias Ringwald  * -------------------------------------------------------------------------- */
1469a19cd78SMatthias Ringwald 
1479a19cd78SMatthias Ringwald /**
1489a19cd78SMatthias Ringwald  * Input PCM Samples from signed 16 bits
1499a19cd78SMatthias Ringwald  * encoder         Encoder state
1509a19cd78SMatthias Ringwald  * pcm, stride     Input PCM samples, and count between two consecutives
1519a19cd78SMatthias Ringwald  */
1529a19cd78SMatthias Ringwald static void load_s16(
1539a19cd78SMatthias Ringwald     struct lc3_encoder *encoder, const void *_pcm, int stride)
1549a19cd78SMatthias Ringwald {
1559a19cd78SMatthias Ringwald     const int16_t *pcm = _pcm;
1569a19cd78SMatthias Ringwald 
1579a19cd78SMatthias Ringwald     enum lc3_dt dt = encoder->dt;
1589a19cd78SMatthias Ringwald     enum lc3_srate sr = encoder->sr_pcm;
1594930cef6SMatthias Ringwald 
1604930cef6SMatthias Ringwald     int16_t *xt = encoder->xt;
1619a19cd78SMatthias Ringwald     float *xs = encoder->xs;
1629a19cd78SMatthias Ringwald     int ns = LC3_NS(dt, sr);
1639a19cd78SMatthias Ringwald 
164*4c4eb519SMatthias Ringwald     for (int i = 0; i < ns; i++, pcm += stride)
165*4c4eb519SMatthias Ringwald         xt[i] = *pcm, xs[i] = *pcm;
1669a19cd78SMatthias Ringwald }
1679a19cd78SMatthias Ringwald 
1689a19cd78SMatthias Ringwald /**
1699a19cd78SMatthias Ringwald  * Input PCM Samples from signed 24 bits
1709a19cd78SMatthias Ringwald  * encoder         Encoder state
1719a19cd78SMatthias Ringwald  * pcm, stride     Input PCM samples, and count between two consecutives
1729a19cd78SMatthias Ringwald  */
1739a19cd78SMatthias Ringwald static void load_s24(
1749a19cd78SMatthias Ringwald     struct lc3_encoder *encoder, const void *_pcm, int stride)
1759a19cd78SMatthias Ringwald {
1769a19cd78SMatthias Ringwald     const int32_t *pcm = _pcm;
1779a19cd78SMatthias Ringwald 
1789a19cd78SMatthias Ringwald     enum lc3_dt dt = encoder->dt;
1799a19cd78SMatthias Ringwald     enum lc3_srate sr = encoder->sr_pcm;
1804930cef6SMatthias Ringwald 
1814930cef6SMatthias Ringwald     int16_t *xt = encoder->xt;
1829a19cd78SMatthias Ringwald     float *xs = encoder->xs;
1839a19cd78SMatthias Ringwald     int ns = LC3_NS(dt, sr);
1849a19cd78SMatthias Ringwald 
185*4c4eb519SMatthias Ringwald     for (int i = 0; i < ns; i++, pcm += stride) {
186*4c4eb519SMatthias Ringwald         xt[i] = *pcm >> 8;
187*4c4eb519SMatthias Ringwald         xs[i] = ldexpf(*pcm, -8);
188*4c4eb519SMatthias Ringwald     }
189*4c4eb519SMatthias Ringwald }
1904930cef6SMatthias Ringwald 
191*4c4eb519SMatthias Ringwald /**
192*4c4eb519SMatthias Ringwald  * Input PCM Samples from signed 24 bits packed
193*4c4eb519SMatthias Ringwald  * encoder         Encoder state
194*4c4eb519SMatthias Ringwald  * pcm, stride     Input PCM samples, and count between two consecutives
195*4c4eb519SMatthias Ringwald  */
196*4c4eb519SMatthias Ringwald static void load_s24_3le(
197*4c4eb519SMatthias Ringwald     struct lc3_encoder *encoder, const void *_pcm, int stride)
198*4c4eb519SMatthias Ringwald {
199*4c4eb519SMatthias Ringwald     const uint8_t *pcm = _pcm;
200*4c4eb519SMatthias Ringwald 
201*4c4eb519SMatthias Ringwald     enum lc3_dt dt = encoder->dt;
202*4c4eb519SMatthias Ringwald     enum lc3_srate sr = encoder->sr_pcm;
203*4c4eb519SMatthias Ringwald 
204*4c4eb519SMatthias Ringwald     int16_t *xt = encoder->xt;
205*4c4eb519SMatthias Ringwald     float *xs = encoder->xs;
206*4c4eb519SMatthias Ringwald     int ns = LC3_NS(dt, sr);
207*4c4eb519SMatthias Ringwald 
208*4c4eb519SMatthias Ringwald     for (int i = 0; i < ns; i++, pcm += 3*stride) {
209*4c4eb519SMatthias Ringwald         int32_t in = ((uint32_t)pcm[0] <<  8) |
210*4c4eb519SMatthias Ringwald                      ((uint32_t)pcm[1] << 16) |
211*4c4eb519SMatthias Ringwald                      ((uint32_t)pcm[2] << 24)  ;
212*4c4eb519SMatthias Ringwald 
213*4c4eb519SMatthias Ringwald         xt[i] = in >> 16;
214*4c4eb519SMatthias Ringwald         xs[i] = ldexpf(in, -16);
215*4c4eb519SMatthias Ringwald     }
216*4c4eb519SMatthias Ringwald }
217*4c4eb519SMatthias Ringwald 
218*4c4eb519SMatthias Ringwald /**
219*4c4eb519SMatthias Ringwald  * Input PCM Samples from float 32 bits
220*4c4eb519SMatthias Ringwald  * encoder         Encoder state
221*4c4eb519SMatthias Ringwald  * pcm, stride     Input PCM samples, and count between two consecutives
222*4c4eb519SMatthias Ringwald  */
223*4c4eb519SMatthias Ringwald static void load_float(
224*4c4eb519SMatthias Ringwald     struct lc3_encoder *encoder, const void *_pcm, int stride)
225*4c4eb519SMatthias Ringwald {
226*4c4eb519SMatthias Ringwald     const float *pcm = _pcm;
227*4c4eb519SMatthias Ringwald 
228*4c4eb519SMatthias Ringwald     enum lc3_dt dt = encoder->dt;
229*4c4eb519SMatthias Ringwald     enum lc3_srate sr = encoder->sr_pcm;
230*4c4eb519SMatthias Ringwald 
231*4c4eb519SMatthias Ringwald     int16_t *xt = encoder->xt;
232*4c4eb519SMatthias Ringwald     float *xs = encoder->xs;
233*4c4eb519SMatthias Ringwald     int ns = LC3_NS(dt, sr);
234*4c4eb519SMatthias Ringwald 
235*4c4eb519SMatthias Ringwald     for (int i = 0; i < ns; i++, pcm += stride) {
236*4c4eb519SMatthias Ringwald         xs[i] = ldexpf(*pcm, 15);
237*4c4eb519SMatthias Ringwald         xt[i] = LC3_SAT16((int32_t)xs[i]);
2384930cef6SMatthias Ringwald     }
2399a19cd78SMatthias Ringwald }
2409a19cd78SMatthias Ringwald 
2419a19cd78SMatthias Ringwald /**
2429a19cd78SMatthias Ringwald  * Frame Analysis
2439a19cd78SMatthias Ringwald  * encoder         Encoder state
2449a19cd78SMatthias Ringwald  * nbytes          Size in bytes of the frame
2459a19cd78SMatthias Ringwald  * side, xq        Return frame data
2469a19cd78SMatthias Ringwald  */
2479a19cd78SMatthias Ringwald static void analyze(struct lc3_encoder *encoder,
2484930cef6SMatthias Ringwald     int nbytes, struct side_data *side, uint16_t *xq)
2499a19cd78SMatthias Ringwald {
2509a19cd78SMatthias Ringwald     enum lc3_dt dt = encoder->dt;
2519a19cd78SMatthias Ringwald     enum lc3_srate sr = encoder->sr;
2529a19cd78SMatthias Ringwald     enum lc3_srate sr_pcm = encoder->sr_pcm;
2539a19cd78SMatthias Ringwald     int ns = LC3_NS(dt, sr_pcm);
2544930cef6SMatthias Ringwald     int nt = LC3_NT(sr_pcm);
2559a19cd78SMatthias Ringwald 
2564930cef6SMatthias Ringwald     int16_t *xt = encoder->xt;
2579a19cd78SMatthias Ringwald     float *xs = encoder->xs;
2584930cef6SMatthias Ringwald     float *xd = encoder->xd;
2594930cef6SMatthias Ringwald     float *xf = xs;
2609a19cd78SMatthias Ringwald 
2619a19cd78SMatthias Ringwald     /* --- Temporal --- */
2629a19cd78SMatthias Ringwald 
2634930cef6SMatthias Ringwald     bool att = lc3_attdet_run(dt, sr_pcm, nbytes, &encoder->attdet, xt);
2649a19cd78SMatthias Ringwald 
2659a19cd78SMatthias Ringwald     side->pitch_present =
2664930cef6SMatthias Ringwald         lc3_ltpf_analyse(dt, sr_pcm, &encoder->ltpf, xt, &side->ltpf);
2674930cef6SMatthias Ringwald 
2684930cef6SMatthias Ringwald     memmove(xt - nt, xt + (ns-nt), nt * sizeof(*xt));
2699a19cd78SMatthias Ringwald 
2709a19cd78SMatthias Ringwald     /* --- Spectral --- */
2719a19cd78SMatthias Ringwald 
2729a19cd78SMatthias Ringwald     float e[LC3_NUM_BANDS];
2739a19cd78SMatthias Ringwald 
2744930cef6SMatthias Ringwald     lc3_mdct_forward(dt, sr_pcm, sr, xs, xd, xf);
2759a19cd78SMatthias Ringwald 
2769a19cd78SMatthias Ringwald     bool nn_flag = lc3_energy_compute(dt, sr, xf, e);
2779a19cd78SMatthias Ringwald     if (nn_flag)
2789a19cd78SMatthias Ringwald         lc3_ltpf_disable(&side->ltpf);
2799a19cd78SMatthias Ringwald 
2809a19cd78SMatthias Ringwald     side->bw = lc3_bwdet_run(dt, sr, e);
2819a19cd78SMatthias Ringwald 
2829a19cd78SMatthias Ringwald     lc3_sns_analyze(dt, sr, e, att, &side->sns, xf, xf);
2839a19cd78SMatthias Ringwald 
2849a19cd78SMatthias Ringwald     lc3_tns_analyze(dt, side->bw, nn_flag, nbytes, &side->tns, xf);
2859a19cd78SMatthias Ringwald 
2869a19cd78SMatthias Ringwald     lc3_spec_analyze(dt, sr,
2879a19cd78SMatthias Ringwald         nbytes, side->pitch_present, &side->tns,
2889a19cd78SMatthias Ringwald         &encoder->spec, xf, xq, &side->spec);
2899a19cd78SMatthias Ringwald }
2909a19cd78SMatthias Ringwald 
2919a19cd78SMatthias Ringwald /**
2929a19cd78SMatthias Ringwald  * Encode bitstream
2939a19cd78SMatthias Ringwald  * encoder         Encoder state
2949a19cd78SMatthias Ringwald  * side, xq        The frame data
2959a19cd78SMatthias Ringwald  * nbytes          Target size of the frame (20 to 400)
2969a19cd78SMatthias Ringwald  * buffer          Output bitstream buffer of `nbytes` size
2979a19cd78SMatthias Ringwald  */
2989a19cd78SMatthias Ringwald static void encode(struct lc3_encoder *encoder,
2994930cef6SMatthias Ringwald     const struct side_data *side, uint16_t *xq, int nbytes, void *buffer)
3009a19cd78SMatthias Ringwald {
3019a19cd78SMatthias Ringwald     enum lc3_dt dt = encoder->dt;
3029a19cd78SMatthias Ringwald     enum lc3_srate sr = encoder->sr;
3039a19cd78SMatthias Ringwald     enum lc3_bandwidth bw = side->bw;
3044930cef6SMatthias Ringwald     float *xf = encoder->xs;
3059a19cd78SMatthias Ringwald 
3069a19cd78SMatthias Ringwald     lc3_bits_t bits;
3079a19cd78SMatthias Ringwald 
3089a19cd78SMatthias Ringwald     lc3_setup_bits(&bits, LC3_BITS_MODE_WRITE, buffer, nbytes);
3099a19cd78SMatthias Ringwald 
3109a19cd78SMatthias Ringwald     lc3_bwdet_put_bw(&bits, sr, bw);
3119a19cd78SMatthias Ringwald 
3129a19cd78SMatthias Ringwald     lc3_spec_put_side(&bits, dt, sr, &side->spec);
3139a19cd78SMatthias Ringwald 
3149a19cd78SMatthias Ringwald     lc3_tns_put_data(&bits, &side->tns);
3159a19cd78SMatthias Ringwald 
3169a19cd78SMatthias Ringwald     lc3_put_bit(&bits, side->pitch_present);
3179a19cd78SMatthias Ringwald 
3189a19cd78SMatthias Ringwald     lc3_sns_put_data(&bits, &side->sns);
3199a19cd78SMatthias Ringwald 
3209a19cd78SMatthias Ringwald     if (side->pitch_present)
3219a19cd78SMatthias Ringwald         lc3_ltpf_put_data(&bits, &side->ltpf);
3229a19cd78SMatthias Ringwald 
3239a19cd78SMatthias Ringwald     lc3_spec_encode(&bits,
3249a19cd78SMatthias Ringwald         dt, sr, bw, nbytes, xq, &side->spec, xf);
3259a19cd78SMatthias Ringwald 
3269a19cd78SMatthias Ringwald     lc3_flush_bits(&bits);
3279a19cd78SMatthias Ringwald }
3289a19cd78SMatthias Ringwald 
3299a19cd78SMatthias Ringwald /**
3309a19cd78SMatthias Ringwald  * Return size needed for an encoder
3319a19cd78SMatthias Ringwald  */
3329a19cd78SMatthias Ringwald unsigned lc3_encoder_size(int dt_us, int sr_hz)
3339a19cd78SMatthias Ringwald {
3349a19cd78SMatthias Ringwald     if (resolve_dt(dt_us) >= LC3_NUM_DT ||
3359a19cd78SMatthias Ringwald         resolve_sr(sr_hz) >= LC3_NUM_SRATE)
3369a19cd78SMatthias Ringwald         return 0;
3379a19cd78SMatthias Ringwald 
3389a19cd78SMatthias Ringwald     return sizeof(struct lc3_encoder) +
339*4c4eb519SMatthias Ringwald         (LC3_ENCODER_BUFFER_COUNT(dt_us, sr_hz)-1) * sizeof(float);
3409a19cd78SMatthias Ringwald }
3419a19cd78SMatthias Ringwald 
3429a19cd78SMatthias Ringwald /**
3439a19cd78SMatthias Ringwald  * Setup encoder
3449a19cd78SMatthias Ringwald  */
3459a19cd78SMatthias Ringwald struct lc3_encoder *lc3_setup_encoder(
3469a19cd78SMatthias Ringwald     int dt_us, int sr_hz, int sr_pcm_hz, void *mem)
3479a19cd78SMatthias Ringwald {
3489a19cd78SMatthias Ringwald     if (sr_pcm_hz <= 0)
3499a19cd78SMatthias Ringwald         sr_pcm_hz = sr_hz;
3509a19cd78SMatthias Ringwald 
3519a19cd78SMatthias Ringwald     enum lc3_dt dt = resolve_dt(dt_us);
3529a19cd78SMatthias Ringwald     enum lc3_srate sr = resolve_sr(sr_hz);
3539a19cd78SMatthias Ringwald     enum lc3_srate sr_pcm = resolve_sr(sr_pcm_hz);
3549a19cd78SMatthias Ringwald 
3559a19cd78SMatthias Ringwald     if (dt >= LC3_NUM_DT || sr_pcm >= LC3_NUM_SRATE || sr > sr_pcm || !mem)
3569a19cd78SMatthias Ringwald         return NULL;
3579a19cd78SMatthias Ringwald 
3589a19cd78SMatthias Ringwald     struct lc3_encoder *encoder = mem;
3599a19cd78SMatthias Ringwald     int ns = LC3_NS(dt, sr_pcm);
3604930cef6SMatthias Ringwald     int nt = LC3_NT(sr_pcm);
3619a19cd78SMatthias Ringwald 
3629a19cd78SMatthias Ringwald     *encoder = (struct lc3_encoder){
3639a19cd78SMatthias Ringwald         .dt = dt, .sr = sr,
3649a19cd78SMatthias Ringwald         .sr_pcm = sr_pcm,
3654930cef6SMatthias Ringwald 
3664930cef6SMatthias Ringwald         .xt = (int16_t *)encoder->s + nt,
3674930cef6SMatthias Ringwald         .xs = encoder->s + (nt+ns)/2,
3684930cef6SMatthias Ringwald         .xd = encoder->s + (nt+ns)/2 + ns,
3699a19cd78SMatthias Ringwald     };
3709a19cd78SMatthias Ringwald 
3719a19cd78SMatthias Ringwald     memset(encoder->s, 0,
3729a19cd78SMatthias Ringwald         LC3_ENCODER_BUFFER_COUNT(dt_us, sr_pcm_hz) * sizeof(float));
3739a19cd78SMatthias Ringwald 
3749a19cd78SMatthias Ringwald     return encoder;
3759a19cd78SMatthias Ringwald }
3769a19cd78SMatthias Ringwald 
3779a19cd78SMatthias Ringwald /**
3789a19cd78SMatthias Ringwald  * Encode a frame
3799a19cd78SMatthias Ringwald  */
3809a19cd78SMatthias Ringwald int lc3_encode(struct lc3_encoder *encoder, enum lc3_pcm_format fmt,
3819a19cd78SMatthias Ringwald     const void *pcm, int stride, int nbytes, void *out)
3829a19cd78SMatthias Ringwald {
3839a19cd78SMatthias Ringwald     static void (* const load[])(struct lc3_encoder *, const void *, int) = {
3849a19cd78SMatthias Ringwald         [LC3_PCM_FORMAT_S16    ] = load_s16,
3859a19cd78SMatthias Ringwald         [LC3_PCM_FORMAT_S24    ] = load_s24,
386*4c4eb519SMatthias Ringwald         [LC3_PCM_FORMAT_S24_3LE] = load_s24_3le,
387*4c4eb519SMatthias Ringwald         [LC3_PCM_FORMAT_FLOAT  ] = load_float,
3889a19cd78SMatthias Ringwald     };
3899a19cd78SMatthias Ringwald 
3909a19cd78SMatthias Ringwald     /* --- Check parameters --- */
3919a19cd78SMatthias Ringwald 
3929a19cd78SMatthias Ringwald     if (!encoder || nbytes < LC3_MIN_FRAME_BYTES
3939a19cd78SMatthias Ringwald                  || nbytes > LC3_MAX_FRAME_BYTES)
3949a19cd78SMatthias Ringwald         return -1;
3959a19cd78SMatthias Ringwald 
3969a19cd78SMatthias Ringwald     /* --- Processing --- */
3979a19cd78SMatthias Ringwald 
3989a19cd78SMatthias Ringwald     struct side_data side;
3994930cef6SMatthias Ringwald     uint16_t xq[LC3_NE(encoder->dt, encoder->sr)];
4009a19cd78SMatthias Ringwald 
4019a19cd78SMatthias Ringwald     load[fmt](encoder, pcm, stride);
4029a19cd78SMatthias Ringwald 
4039a19cd78SMatthias Ringwald     analyze(encoder, nbytes, &side, xq);
4049a19cd78SMatthias Ringwald 
4059a19cd78SMatthias Ringwald     encode(encoder, &side, xq, nbytes, out);
4069a19cd78SMatthias Ringwald 
4079a19cd78SMatthias Ringwald     return 0;
4089a19cd78SMatthias Ringwald }
4099a19cd78SMatthias Ringwald 
4109a19cd78SMatthias Ringwald 
4119a19cd78SMatthias Ringwald /* ----------------------------------------------------------------------------
4129a19cd78SMatthias Ringwald  *  Decoder
4139a19cd78SMatthias Ringwald  * -------------------------------------------------------------------------- */
4149a19cd78SMatthias Ringwald 
4159a19cd78SMatthias Ringwald /**
4169a19cd78SMatthias Ringwald  * Output PCM Samples to signed 16 bits
4179a19cd78SMatthias Ringwald  * decoder         Decoder state
4189a19cd78SMatthias Ringwald  * pcm, stride     Output PCM samples, and count between two consecutives
4199a19cd78SMatthias Ringwald  */
4209a19cd78SMatthias Ringwald static void store_s16(
4219a19cd78SMatthias Ringwald     struct lc3_decoder *decoder, void *_pcm, int stride)
4229a19cd78SMatthias Ringwald {
4239a19cd78SMatthias Ringwald     int16_t *pcm = _pcm;
4249a19cd78SMatthias Ringwald 
4259a19cd78SMatthias Ringwald     enum lc3_dt dt = decoder->dt;
4269a19cd78SMatthias Ringwald     enum lc3_srate sr = decoder->sr_pcm;
4274930cef6SMatthias Ringwald 
4289a19cd78SMatthias Ringwald     float *xs = decoder->xs;
4299a19cd78SMatthias Ringwald     int ns = LC3_NS(dt, sr);
4309a19cd78SMatthias Ringwald 
4319a19cd78SMatthias Ringwald     for ( ; ns > 0; ns--, xs++, pcm += stride) {
4324930cef6SMatthias Ringwald         int32_t s = *xs >= 0 ? (int)(*xs + 0.5f) : (int)(*xs - 0.5f);
4334930cef6SMatthias Ringwald         *pcm = LC3_SAT16(s);
4349a19cd78SMatthias Ringwald     }
4359a19cd78SMatthias Ringwald }
4369a19cd78SMatthias Ringwald 
4379a19cd78SMatthias Ringwald /**
4389a19cd78SMatthias Ringwald  * Output PCM Samples to signed 24 bits
4399a19cd78SMatthias Ringwald  * decoder         Decoder state
4409a19cd78SMatthias Ringwald  * pcm, stride     Output PCM samples, and count between two consecutives
4419a19cd78SMatthias Ringwald  */
4429a19cd78SMatthias Ringwald static void store_s24(
4439a19cd78SMatthias Ringwald     struct lc3_decoder *decoder, void *_pcm, int stride)
4449a19cd78SMatthias Ringwald {
4459a19cd78SMatthias Ringwald     int32_t *pcm = _pcm;
4469a19cd78SMatthias Ringwald 
4479a19cd78SMatthias Ringwald     enum lc3_dt dt = decoder->dt;
4489a19cd78SMatthias Ringwald     enum lc3_srate sr = decoder->sr_pcm;
4494930cef6SMatthias Ringwald 
4509a19cd78SMatthias Ringwald     float *xs = decoder->xs;
4519a19cd78SMatthias Ringwald     int ns = LC3_NS(dt, sr);
4529a19cd78SMatthias Ringwald 
4539a19cd78SMatthias Ringwald     for ( ; ns > 0; ns--, xs++, pcm += stride) {
4549a19cd78SMatthias Ringwald         int32_t s = *xs >= 0 ? (int32_t)(ldexpf(*xs, 8) + 0.5f)
4559a19cd78SMatthias Ringwald                              : (int32_t)(ldexpf(*xs, 8) - 0.5f);
4564930cef6SMatthias Ringwald         *pcm = LC3_SAT24(s);
4579a19cd78SMatthias Ringwald     }
4589a19cd78SMatthias Ringwald }
4599a19cd78SMatthias Ringwald 
4609a19cd78SMatthias Ringwald /**
461*4c4eb519SMatthias Ringwald  * Output PCM Samples to signed 24 bits packed
462*4c4eb519SMatthias Ringwald  * decoder         Decoder state
463*4c4eb519SMatthias Ringwald  * pcm, stride     Output PCM samples, and count between two consecutives
464*4c4eb519SMatthias Ringwald  */
465*4c4eb519SMatthias Ringwald static void store_s24_3le(
466*4c4eb519SMatthias Ringwald     struct lc3_decoder *decoder, void *_pcm, int stride)
467*4c4eb519SMatthias Ringwald {
468*4c4eb519SMatthias Ringwald     uint8_t *pcm = _pcm;
469*4c4eb519SMatthias Ringwald 
470*4c4eb519SMatthias Ringwald     enum lc3_dt dt = decoder->dt;
471*4c4eb519SMatthias Ringwald     enum lc3_srate sr = decoder->sr_pcm;
472*4c4eb519SMatthias Ringwald 
473*4c4eb519SMatthias Ringwald     float *xs = decoder->xs;
474*4c4eb519SMatthias Ringwald     int ns = LC3_NS(dt, sr);
475*4c4eb519SMatthias Ringwald 
476*4c4eb519SMatthias Ringwald     for ( ; ns > 0; ns--, xs++, pcm += 3*stride) {
477*4c4eb519SMatthias Ringwald         int32_t s = *xs >= 0 ? (int32_t)(ldexpf(*xs, 8) + 0.5f)
478*4c4eb519SMatthias Ringwald                              : (int32_t)(ldexpf(*xs, 8) - 0.5f);
479*4c4eb519SMatthias Ringwald 
480*4c4eb519SMatthias Ringwald         s = LC3_SAT24(s);
481*4c4eb519SMatthias Ringwald         pcm[0] = (s >>  0) & 0xff;
482*4c4eb519SMatthias Ringwald         pcm[1] = (s >>  8) & 0xff;
483*4c4eb519SMatthias Ringwald         pcm[2] = (s >> 16) & 0xff;
484*4c4eb519SMatthias Ringwald     }
485*4c4eb519SMatthias Ringwald }
486*4c4eb519SMatthias Ringwald 
487*4c4eb519SMatthias Ringwald /**
488*4c4eb519SMatthias Ringwald  * Output PCM Samples to float 32 bits
489*4c4eb519SMatthias Ringwald  * decoder         Decoder state
490*4c4eb519SMatthias Ringwald  * pcm, stride     Output PCM samples, and count between two consecutives
491*4c4eb519SMatthias Ringwald  */
492*4c4eb519SMatthias Ringwald static void store_float(
493*4c4eb519SMatthias Ringwald     struct lc3_decoder *decoder, void *_pcm, int stride)
494*4c4eb519SMatthias Ringwald {
495*4c4eb519SMatthias Ringwald     float *pcm = _pcm;
496*4c4eb519SMatthias Ringwald 
497*4c4eb519SMatthias Ringwald     enum lc3_dt dt = decoder->dt;
498*4c4eb519SMatthias Ringwald     enum lc3_srate sr = decoder->sr_pcm;
499*4c4eb519SMatthias Ringwald 
500*4c4eb519SMatthias Ringwald     float *xs = decoder->xs;
501*4c4eb519SMatthias Ringwald     int ns = LC3_NS(dt, sr);
502*4c4eb519SMatthias Ringwald 
503*4c4eb519SMatthias Ringwald     for ( ; ns > 0; ns--, xs++, pcm += stride) {
504*4c4eb519SMatthias Ringwald         float s = ldexpf(*xs, -15);
505*4c4eb519SMatthias Ringwald         *pcm = fminf(fmaxf(s, -1.f), 1.f);
506*4c4eb519SMatthias Ringwald     }
507*4c4eb519SMatthias Ringwald }
508*4c4eb519SMatthias Ringwald 
509*4c4eb519SMatthias Ringwald /**
5109a19cd78SMatthias Ringwald  * Decode bitstream
5119a19cd78SMatthias Ringwald  * decoder         Decoder state
5129a19cd78SMatthias Ringwald  * data, nbytes    Input bitstream buffer
5139a19cd78SMatthias Ringwald  * side            Return the side data
5149a19cd78SMatthias Ringwald  * return          0: Ok  < 0: Bitsream error detected
5159a19cd78SMatthias Ringwald  */
5169a19cd78SMatthias Ringwald static int decode(struct lc3_decoder *decoder,
5179a19cd78SMatthias Ringwald     const void *data, int nbytes, struct side_data *side)
5189a19cd78SMatthias Ringwald {
5199a19cd78SMatthias Ringwald     enum lc3_dt dt = decoder->dt;
5209a19cd78SMatthias Ringwald     enum lc3_srate sr = decoder->sr;
5214930cef6SMatthias Ringwald 
5229a19cd78SMatthias Ringwald     float *xf = decoder->xs;
5239a19cd78SMatthias Ringwald     int ns = LC3_NS(dt, sr);
5249a19cd78SMatthias Ringwald     int ne = LC3_NE(dt, sr);
5259a19cd78SMatthias Ringwald 
5269a19cd78SMatthias Ringwald     lc3_bits_t bits;
5279a19cd78SMatthias Ringwald     int ret = 0;
5289a19cd78SMatthias Ringwald 
5299a19cd78SMatthias Ringwald     lc3_setup_bits(&bits, LC3_BITS_MODE_READ, (void *)data, nbytes);
5309a19cd78SMatthias Ringwald 
5319a19cd78SMatthias Ringwald     if ((ret = lc3_bwdet_get_bw(&bits, sr, &side->bw)) < 0)
5329a19cd78SMatthias Ringwald         return ret;
5339a19cd78SMatthias Ringwald 
5349a19cd78SMatthias Ringwald     if ((ret = lc3_spec_get_side(&bits, dt, sr, &side->spec)) < 0)
5359a19cd78SMatthias Ringwald         return ret;
5369a19cd78SMatthias Ringwald 
5379a19cd78SMatthias Ringwald     lc3_tns_get_data(&bits, dt, side->bw, nbytes, &side->tns);
5389a19cd78SMatthias Ringwald 
5399a19cd78SMatthias Ringwald     side->pitch_present = lc3_get_bit(&bits);
5409a19cd78SMatthias Ringwald 
5419a19cd78SMatthias Ringwald     if ((ret = lc3_sns_get_data(&bits, &side->sns)) < 0)
5429a19cd78SMatthias Ringwald         return ret;
5439a19cd78SMatthias Ringwald 
5449a19cd78SMatthias Ringwald     if (side->pitch_present)
5459a19cd78SMatthias Ringwald         lc3_ltpf_get_data(&bits, &side->ltpf);
5469a19cd78SMatthias Ringwald 
5479a19cd78SMatthias Ringwald     if ((ret = lc3_spec_decode(&bits, dt, sr,
5489a19cd78SMatthias Ringwald                     side->bw, nbytes, &side->spec, xf)) < 0)
5499a19cd78SMatthias Ringwald         return ret;
5509a19cd78SMatthias Ringwald 
5519a19cd78SMatthias Ringwald     memset(xf + ne, 0, (ns - ne) * sizeof(float));
5529a19cd78SMatthias Ringwald 
5539a19cd78SMatthias Ringwald     return lc3_check_bits(&bits);
5549a19cd78SMatthias Ringwald }
5559a19cd78SMatthias Ringwald 
5569a19cd78SMatthias Ringwald /**
5579a19cd78SMatthias Ringwald  * Frame synthesis
5589a19cd78SMatthias Ringwald  * decoder         Decoder state
5599a19cd78SMatthias Ringwald  * side            Frame data, NULL performs PLC
5609a19cd78SMatthias Ringwald  * nbytes          Size in bytes of the frame
5619a19cd78SMatthias Ringwald  */
5629a19cd78SMatthias Ringwald static void synthesize(struct lc3_decoder *decoder,
5639a19cd78SMatthias Ringwald     const struct side_data *side, int nbytes)
5649a19cd78SMatthias Ringwald {
5659a19cd78SMatthias Ringwald     enum lc3_dt dt = decoder->dt;
5669a19cd78SMatthias Ringwald     enum lc3_srate sr = decoder->sr;
5679a19cd78SMatthias Ringwald     enum lc3_srate sr_pcm = decoder->sr_pcm;
5689a19cd78SMatthias Ringwald 
5699a19cd78SMatthias Ringwald     float *xf = decoder->xs;
5704930cef6SMatthias Ringwald     int ns = LC3_NS(dt, sr_pcm);
5714930cef6SMatthias Ringwald     int ne = LC3_NE(dt, sr);
5724930cef6SMatthias Ringwald 
5739a19cd78SMatthias Ringwald     float *xg = decoder->xg;
5749a19cd78SMatthias Ringwald     float *xd = decoder->xd;
5759a19cd78SMatthias Ringwald     float *xs = xf;
5769a19cd78SMatthias Ringwald 
5779a19cd78SMatthias Ringwald     if (side) {
5789a19cd78SMatthias Ringwald         enum lc3_bandwidth bw = side->bw;
5799a19cd78SMatthias Ringwald 
5809a19cd78SMatthias Ringwald         lc3_plc_suspend(&decoder->plc);
5819a19cd78SMatthias Ringwald 
5829a19cd78SMatthias Ringwald         lc3_tns_synthesize(dt, bw, &side->tns, xf);
5839a19cd78SMatthias Ringwald 
5849a19cd78SMatthias Ringwald         lc3_sns_synthesize(dt, sr, &side->sns, xf, xg);
5859a19cd78SMatthias Ringwald 
5869a19cd78SMatthias Ringwald         lc3_mdct_inverse(dt, sr_pcm, sr, xg, xd, xs);
5879a19cd78SMatthias Ringwald 
5889a19cd78SMatthias Ringwald     } else {
5899a19cd78SMatthias Ringwald         lc3_plc_synthesize(dt, sr, &decoder->plc, xg, xf);
5909a19cd78SMatthias Ringwald 
5919a19cd78SMatthias Ringwald         memset(xf + ne, 0, (ns - ne) * sizeof(float));
5929a19cd78SMatthias Ringwald 
5939a19cd78SMatthias Ringwald         lc3_mdct_inverse(dt, sr_pcm, sr, xf, xd, xs);
5949a19cd78SMatthias Ringwald     }
5959a19cd78SMatthias Ringwald 
5969a19cd78SMatthias Ringwald     lc3_ltpf_synthesize(dt, sr_pcm, nbytes, &decoder->ltpf,
5974930cef6SMatthias Ringwald         side && side->pitch_present ? &side->ltpf : NULL, decoder->xh, xs);
5984930cef6SMatthias Ringwald }
5999a19cd78SMatthias Ringwald 
6004930cef6SMatthias Ringwald /**
6014930cef6SMatthias Ringwald  * Update decoder state on decoding completion
6024930cef6SMatthias Ringwald  * decoder         Decoder state
6034930cef6SMatthias Ringwald  */
6044930cef6SMatthias Ringwald static void complete(struct lc3_decoder *decoder)
6054930cef6SMatthias Ringwald {
6064930cef6SMatthias Ringwald     enum lc3_dt dt = decoder->dt;
6074930cef6SMatthias Ringwald     enum lc3_srate sr_pcm = decoder->sr_pcm;
6084930cef6SMatthias Ringwald     int nh = LC3_NH(dt, sr_pcm);
6094930cef6SMatthias Ringwald     int ns = LC3_NS(dt, sr_pcm);
6104930cef6SMatthias Ringwald 
6114930cef6SMatthias Ringwald     decoder->xs = decoder->xs - decoder->xh < nh - ns ?
6124930cef6SMatthias Ringwald         decoder->xs + ns : decoder->xh;
6139a19cd78SMatthias Ringwald }
6149a19cd78SMatthias Ringwald 
6159a19cd78SMatthias Ringwald /**
6169a19cd78SMatthias Ringwald  * Return size needed for a decoder
6179a19cd78SMatthias Ringwald  */
6189a19cd78SMatthias Ringwald unsigned lc3_decoder_size(int dt_us, int sr_hz)
6199a19cd78SMatthias Ringwald {
6209a19cd78SMatthias Ringwald     if (resolve_dt(dt_us) >= LC3_NUM_DT ||
6219a19cd78SMatthias Ringwald         resolve_sr(sr_hz) >= LC3_NUM_SRATE)
6229a19cd78SMatthias Ringwald         return 0;
6239a19cd78SMatthias Ringwald 
6249a19cd78SMatthias Ringwald     return sizeof(struct lc3_decoder) +
625*4c4eb519SMatthias Ringwald         (LC3_DECODER_BUFFER_COUNT(dt_us, sr_hz)-1) * sizeof(float);
6269a19cd78SMatthias Ringwald }
6279a19cd78SMatthias Ringwald 
6289a19cd78SMatthias Ringwald /**
6299a19cd78SMatthias Ringwald  * Setup decoder
6309a19cd78SMatthias Ringwald  */
6319a19cd78SMatthias Ringwald struct lc3_decoder *lc3_setup_decoder(
6329a19cd78SMatthias Ringwald     int dt_us, int sr_hz, int sr_pcm_hz, void *mem)
6339a19cd78SMatthias Ringwald {
6349a19cd78SMatthias Ringwald     if (sr_pcm_hz <= 0)
6359a19cd78SMatthias Ringwald         sr_pcm_hz = sr_hz;
6369a19cd78SMatthias Ringwald 
6379a19cd78SMatthias Ringwald     enum lc3_dt dt = resolve_dt(dt_us);
6389a19cd78SMatthias Ringwald     enum lc3_srate sr = resolve_sr(sr_hz);
6399a19cd78SMatthias Ringwald     enum lc3_srate sr_pcm = resolve_sr(sr_pcm_hz);
6409a19cd78SMatthias Ringwald 
6419a19cd78SMatthias Ringwald     if (dt >= LC3_NUM_DT || sr_pcm >= LC3_NUM_SRATE || sr > sr_pcm || !mem)
6429a19cd78SMatthias Ringwald         return NULL;
6439a19cd78SMatthias Ringwald 
6449a19cd78SMatthias Ringwald     struct lc3_decoder *decoder = mem;
6454930cef6SMatthias Ringwald     int nh = LC3_NH(dt, sr_pcm);
6469a19cd78SMatthias Ringwald     int ns = LC3_NS(dt, sr_pcm);
6479a19cd78SMatthias Ringwald     int nd = LC3_ND(dt, sr_pcm);
6489a19cd78SMatthias Ringwald 
6499a19cd78SMatthias Ringwald     *decoder = (struct lc3_decoder){
6509a19cd78SMatthias Ringwald         .dt = dt, .sr = sr,
6519a19cd78SMatthias Ringwald         .sr_pcm = sr_pcm,
6524930cef6SMatthias Ringwald 
6534930cef6SMatthias Ringwald         .xh = decoder->s,
6544930cef6SMatthias Ringwald         .xs = decoder->s + nh-ns,
6554930cef6SMatthias Ringwald         .xd = decoder->s + nh,
6564930cef6SMatthias Ringwald         .xg = decoder->s + nh+nd,
6579a19cd78SMatthias Ringwald     };
6589a19cd78SMatthias Ringwald 
6599a19cd78SMatthias Ringwald     lc3_plc_reset(&decoder->plc);
6609a19cd78SMatthias Ringwald 
6619a19cd78SMatthias Ringwald     memset(decoder->s, 0,
6629a19cd78SMatthias Ringwald         LC3_DECODER_BUFFER_COUNT(dt_us, sr_pcm_hz) * sizeof(float));
6639a19cd78SMatthias Ringwald 
6649a19cd78SMatthias Ringwald     return decoder;
6659a19cd78SMatthias Ringwald }
6669a19cd78SMatthias Ringwald 
6679a19cd78SMatthias Ringwald /**
6689a19cd78SMatthias Ringwald  * Decode a frame
6699a19cd78SMatthias Ringwald  */
6709a19cd78SMatthias Ringwald int lc3_decode(struct lc3_decoder *decoder, const void *in, int nbytes,
6719a19cd78SMatthias Ringwald     enum lc3_pcm_format fmt, void *pcm, int stride)
6729a19cd78SMatthias Ringwald {
6739a19cd78SMatthias Ringwald     static void (* const store[])(struct lc3_decoder *, void *, int) = {
6749a19cd78SMatthias Ringwald         [LC3_PCM_FORMAT_S16    ] = store_s16,
6759a19cd78SMatthias Ringwald         [LC3_PCM_FORMAT_S24    ] = store_s24,
676*4c4eb519SMatthias Ringwald         [LC3_PCM_FORMAT_S24_3LE] = store_s24_3le,
677*4c4eb519SMatthias Ringwald         [LC3_PCM_FORMAT_FLOAT  ] = store_float,
6789a19cd78SMatthias Ringwald     };
6799a19cd78SMatthias Ringwald 
6809a19cd78SMatthias Ringwald     /* --- Check parameters --- */
6819a19cd78SMatthias Ringwald 
6829a19cd78SMatthias Ringwald     if (!decoder)
6839a19cd78SMatthias Ringwald         return -1;
6849a19cd78SMatthias Ringwald 
6859a19cd78SMatthias Ringwald     if (in && (nbytes < LC3_MIN_FRAME_BYTES ||
6869a19cd78SMatthias Ringwald                nbytes > LC3_MAX_FRAME_BYTES   ))
6879a19cd78SMatthias Ringwald         return -1;
6889a19cd78SMatthias Ringwald 
6899a19cd78SMatthias Ringwald     /* --- Processing --- */
6909a19cd78SMatthias Ringwald 
6919a19cd78SMatthias Ringwald     struct side_data side;
6929a19cd78SMatthias Ringwald 
6939a19cd78SMatthias Ringwald     int ret = !in || (decode(decoder, in, nbytes, &side) < 0);
6949a19cd78SMatthias Ringwald 
6959a19cd78SMatthias Ringwald     synthesize(decoder, ret ? NULL : &side, nbytes);
6969a19cd78SMatthias Ringwald 
6979a19cd78SMatthias Ringwald     store[fmt](decoder, pcm, stride);
6989a19cd78SMatthias Ringwald 
6994930cef6SMatthias Ringwald     complete(decoder);
7004930cef6SMatthias Ringwald 
7019a19cd78SMatthias Ringwald     return ret;
7029a19cd78SMatthias Ringwald }
703