xref: /btstack/3rd-party/lc3-google/src/lc3.c (revision 6897da5c53aac5b1f90f41b5b15d0bd43d61dfff)
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
56*6897da5cSDirk Helbig  * hrmode          High-resolution mode indication
579a19cd78SMatthias Ringwald  * return          Frame duration identifier, or LC3_NUM_DT
589a19cd78SMatthias Ringwald  */
resolve_dt(int us,bool hrmode)59*6897da5cSDirk Helbig static enum lc3_dt resolve_dt(int us, bool hrmode)
609a19cd78SMatthias Ringwald {
61*6897da5cSDirk Helbig     return LC3_PLUS && us ==  2500 ? LC3_DT_2M5 :
62*6897da5cSDirk Helbig            LC3_PLUS && us ==  5000 ? LC3_DT_5M  :
63*6897da5cSDirk Helbig            !hrmode  && us ==  7500 ? LC3_DT_7M5 :
649a19cd78SMatthias Ringwald                        us == 10000 ? LC3_DT_10M : LC3_NUM_DT;
659a19cd78SMatthias Ringwald }
669a19cd78SMatthias Ringwald 
679a19cd78SMatthias Ringwald /**
689a19cd78SMatthias Ringwald  * Resolve samplerate in Hz
699a19cd78SMatthias Ringwald  * hz              Samplerate in Hz
70*6897da5cSDirk Helbig  * hrmode          High-resolution mode indication
719a19cd78SMatthias Ringwald  * return          Sample rate identifier, or LC3_NUM_SRATE
729a19cd78SMatthias Ringwald  */
resolve_srate(int hz,bool hrmode)73*6897da5cSDirk Helbig static enum lc3_srate resolve_srate(int hz, bool hrmode)
749a19cd78SMatthias Ringwald {
75*6897da5cSDirk Helbig     hrmode = LC3_PLUS_HR && hrmode;
76*6897da5cSDirk Helbig 
77*6897da5cSDirk Helbig     return !hrmode && hz ==  8000 ? LC3_SRATE_8K     :
78*6897da5cSDirk Helbig            !hrmode && hz == 16000 ? LC3_SRATE_16K    :
79*6897da5cSDirk Helbig            !hrmode && hz == 24000 ? LC3_SRATE_24K    :
80*6897da5cSDirk Helbig            !hrmode && hz == 32000 ? LC3_SRATE_32K    :
81*6897da5cSDirk Helbig            !hrmode && hz == 48000 ? LC3_SRATE_48K    :
82*6897da5cSDirk Helbig             hrmode && hz == 48000 ? LC3_SRATE_48K_HR :
83*6897da5cSDirk Helbig             hrmode && hz == 96000 ? LC3_SRATE_96K_HR : LC3_NUM_SRATE;
849a19cd78SMatthias Ringwald }
859a19cd78SMatthias Ringwald 
869a19cd78SMatthias Ringwald /**
879a19cd78SMatthias Ringwald  * Return the number of PCM samples in a frame
889a19cd78SMatthias Ringwald  */
lc3_hr_frame_samples(bool hrmode,int dt_us,int sr_hz)89*6897da5cSDirk Helbig LC3_EXPORT int lc3_hr_frame_samples(bool hrmode, int dt_us, int sr_hz)
909a19cd78SMatthias Ringwald {
91*6897da5cSDirk Helbig     enum lc3_dt dt = resolve_dt(dt_us, hrmode);
92*6897da5cSDirk Helbig     enum lc3_srate sr = resolve_srate(sr_hz, hrmode);
939a19cd78SMatthias Ringwald 
949a19cd78SMatthias Ringwald     if (dt >= LC3_NUM_DT || sr >= LC3_NUM_SRATE)
959a19cd78SMatthias Ringwald         return -1;
969a19cd78SMatthias Ringwald 
97*6897da5cSDirk Helbig     return lc3_ns(dt, sr);
98*6897da5cSDirk Helbig }
99*6897da5cSDirk Helbig 
lc3_frame_samples(int dt_us,int sr_hz)100*6897da5cSDirk Helbig LC3_EXPORT int lc3_frame_samples(int dt_us, int sr_hz)
101*6897da5cSDirk Helbig {
102*6897da5cSDirk Helbig     return lc3_hr_frame_samples(false, dt_us, sr_hz);
1039a19cd78SMatthias Ringwald }
1049a19cd78SMatthias Ringwald 
1059a19cd78SMatthias Ringwald /**
106*6897da5cSDirk Helbig  * Return the size of frames or frame blocks, from bitrate
1079a19cd78SMatthias Ringwald  */
lc3_hr_frame_block_bytes(bool hrmode,int dt_us,int sr_hz,int nchannels,int bitrate)108*6897da5cSDirk Helbig LC3_EXPORT int lc3_hr_frame_block_bytes(
109*6897da5cSDirk Helbig     bool hrmode, int dt_us, int sr_hz, int nchannels, int bitrate)
1109a19cd78SMatthias Ringwald {
111*6897da5cSDirk Helbig     enum lc3_dt dt = resolve_dt(dt_us, hrmode);
112*6897da5cSDirk Helbig     enum lc3_srate sr = resolve_srate(sr_hz, hrmode);
113*6897da5cSDirk Helbig 
114*6897da5cSDirk Helbig     if (dt >= LC3_NUM_DT || sr >= LC3_NUM_SRATE
115*6897da5cSDirk Helbig             || nchannels < 1 || nchannels > 8 || bitrate < 0)
1169a19cd78SMatthias Ringwald         return -1;
1179a19cd78SMatthias Ringwald 
118*6897da5cSDirk Helbig     bitrate = LC3_CLIP(bitrate, 0, 8*LC3_HR_MAX_BITRATE);
1199a19cd78SMatthias Ringwald 
120*6897da5cSDirk Helbig     return LC3_CLIP((bitrate * (int)(1 + dt)) / 3200,
121*6897da5cSDirk Helbig         nchannels * lc3_min_frame_bytes(dt, sr),
122*6897da5cSDirk Helbig         nchannels * lc3_max_frame_bytes(dt, sr) );
123*6897da5cSDirk Helbig }
1249a19cd78SMatthias Ringwald 
lc3_frame_bock_bytes(int dt_us,int nchannels,int bitrate)125*6897da5cSDirk Helbig LC3_EXPORT int lc3_frame_bock_bytes(int dt_us, int nchannels, int bitrate)
126*6897da5cSDirk Helbig {
127*6897da5cSDirk Helbig     return lc3_hr_frame_block_bytes(false, dt_us, 8000, nchannels, bitrate);
128*6897da5cSDirk Helbig }
1299a19cd78SMatthias Ringwald 
lc3_hr_frame_bytes(bool hrmode,int dt_us,int sr_hz,int bitrate)130*6897da5cSDirk Helbig LC3_EXPORT int lc3_hr_frame_bytes(
131*6897da5cSDirk Helbig     bool hrmode, int dt_us, int sr_hz, int bitrate)
132*6897da5cSDirk Helbig {
133*6897da5cSDirk Helbig     return lc3_hr_frame_block_bytes(hrmode, dt_us, sr_hz, 1, bitrate);
134*6897da5cSDirk Helbig }
135*6897da5cSDirk Helbig 
lc3_frame_bytes(int dt_us,int bitrate)136*6897da5cSDirk Helbig LC3_EXPORT int lc3_frame_bytes(int dt_us, int bitrate)
137*6897da5cSDirk Helbig {
138*6897da5cSDirk Helbig     return lc3_hr_frame_bytes(false, dt_us, 8000, bitrate);
1399a19cd78SMatthias Ringwald }
1409a19cd78SMatthias Ringwald 
1419a19cd78SMatthias Ringwald /**
142*6897da5cSDirk Helbig  * Resolve the bitrate, from the size of frames or frame blocks
1439a19cd78SMatthias Ringwald  */
lc3_hr_resolve_bitrate(bool hrmode,int dt_us,int sr_hz,int nbytes)144*6897da5cSDirk Helbig LC3_EXPORT int lc3_hr_resolve_bitrate(
145*6897da5cSDirk Helbig     bool hrmode, int dt_us, int sr_hz, int nbytes)
1469a19cd78SMatthias Ringwald {
147*6897da5cSDirk Helbig     enum lc3_dt dt = resolve_dt(dt_us, hrmode);
148*6897da5cSDirk Helbig     enum lc3_srate sr = resolve_srate(sr_hz, hrmode);
149*6897da5cSDirk Helbig 
150*6897da5cSDirk Helbig     if (dt >= LC3_NUM_DT || sr >= LC3_NUM_SRATE || nbytes < 0)
1519a19cd78SMatthias Ringwald         return -1;
1529a19cd78SMatthias Ringwald 
153*6897da5cSDirk Helbig     return LC3_MIN(((int64_t)nbytes * 3200 + dt) / (1 + dt), INT_MAX);
154*6897da5cSDirk Helbig }
1559a19cd78SMatthias Ringwald 
lc3_resolve_bitrate(int dt_us,int nbytes)156*6897da5cSDirk Helbig LC3_EXPORT int lc3_resolve_bitrate(int dt_us, int nbytes)
157*6897da5cSDirk Helbig {
158*6897da5cSDirk Helbig     return lc3_hr_resolve_bitrate(false, dt_us, 8000, nbytes);
1599a19cd78SMatthias Ringwald }
1609a19cd78SMatthias Ringwald 
1619a19cd78SMatthias Ringwald /**
1629a19cd78SMatthias Ringwald  * Return algorithmic delay, as a number of samples
1639a19cd78SMatthias Ringwald  */
lc3_hr_delay_samples(bool hrmode,int dt_us,int sr_hz)164*6897da5cSDirk Helbig LC3_EXPORT int lc3_hr_delay_samples(bool hrmode, int dt_us, int sr_hz)
1659a19cd78SMatthias Ringwald {
166*6897da5cSDirk Helbig     enum lc3_dt dt = resolve_dt(dt_us, hrmode);
167*6897da5cSDirk Helbig     enum lc3_srate sr = resolve_srate(sr_hz, hrmode);
1689a19cd78SMatthias Ringwald 
1699a19cd78SMatthias Ringwald     if (dt >= LC3_NUM_DT || sr >= LC3_NUM_SRATE)
1709a19cd78SMatthias Ringwald         return -1;
1719a19cd78SMatthias Ringwald 
172*6897da5cSDirk Helbig     return 2 * lc3_nd(dt, sr) - lc3_ns(dt, sr);
173*6897da5cSDirk Helbig }
174*6897da5cSDirk Helbig 
lc3_delay_samples(int dt_us,int sr_hz)175*6897da5cSDirk Helbig LC3_EXPORT int lc3_delay_samples(int dt_us, int sr_hz)
176*6897da5cSDirk Helbig {
177*6897da5cSDirk Helbig     return lc3_hr_delay_samples(false, dt_us, sr_hz);
1789a19cd78SMatthias Ringwald }
1799a19cd78SMatthias Ringwald 
1809a19cd78SMatthias Ringwald 
1819a19cd78SMatthias Ringwald /* ----------------------------------------------------------------------------
1829a19cd78SMatthias Ringwald  *  Encoder
1839a19cd78SMatthias Ringwald  * -------------------------------------------------------------------------- */
1849a19cd78SMatthias Ringwald 
1859a19cd78SMatthias Ringwald /**
1869a19cd78SMatthias Ringwald  * Input PCM Samples from signed 16 bits
1879a19cd78SMatthias Ringwald  * encoder         Encoder state
1889a19cd78SMatthias Ringwald  * pcm, stride     Input PCM samples, and count between two consecutives
1899a19cd78SMatthias Ringwald  */
load_s16(struct lc3_encoder * encoder,const void * _pcm,int stride)1909a19cd78SMatthias Ringwald static void load_s16(
1919a19cd78SMatthias Ringwald     struct lc3_encoder *encoder, const void *_pcm, int stride)
1929a19cd78SMatthias Ringwald {
1939a19cd78SMatthias Ringwald     const int16_t *pcm = _pcm;
1949a19cd78SMatthias Ringwald 
1959a19cd78SMatthias Ringwald     enum lc3_dt dt = encoder->dt;
1969a19cd78SMatthias Ringwald     enum lc3_srate sr = encoder->sr_pcm;
1974930cef6SMatthias Ringwald 
198*6897da5cSDirk Helbig     int16_t *xt = (int16_t *)encoder->x + encoder->xt_off;
199*6897da5cSDirk Helbig     float *xs = encoder->x + encoder->xs_off;
200*6897da5cSDirk Helbig     int ns = lc3_ns(dt, sr);
2019a19cd78SMatthias Ringwald 
2024c4eb519SMatthias Ringwald     for (int i = 0; i < ns; i++, pcm += stride)
2034c4eb519SMatthias Ringwald         xt[i] = *pcm, xs[i] = *pcm;
2049a19cd78SMatthias Ringwald }
2059a19cd78SMatthias Ringwald 
2069a19cd78SMatthias Ringwald /**
2079a19cd78SMatthias Ringwald  * Input PCM Samples from signed 24 bits
2089a19cd78SMatthias Ringwald  * encoder         Encoder state
2099a19cd78SMatthias Ringwald  * pcm, stride     Input PCM samples, and count between two consecutives
2109a19cd78SMatthias Ringwald  */
load_s24(struct lc3_encoder * encoder,const void * _pcm,int stride)2119a19cd78SMatthias Ringwald static void load_s24(
2129a19cd78SMatthias Ringwald     struct lc3_encoder *encoder, const void *_pcm, int stride)
2139a19cd78SMatthias Ringwald {
2149a19cd78SMatthias Ringwald     const int32_t *pcm = _pcm;
2159a19cd78SMatthias Ringwald 
2169a19cd78SMatthias Ringwald     enum lc3_dt dt = encoder->dt;
2179a19cd78SMatthias Ringwald     enum lc3_srate sr = encoder->sr_pcm;
2184930cef6SMatthias Ringwald 
219*6897da5cSDirk Helbig     int16_t *xt = (int16_t *)encoder->x + encoder->xt_off;
220*6897da5cSDirk Helbig     float *xs = encoder->x + encoder->xs_off;
221*6897da5cSDirk Helbig     int ns = lc3_ns(dt, sr);
2229a19cd78SMatthias Ringwald 
2234c4eb519SMatthias Ringwald     for (int i = 0; i < ns; i++, pcm += stride) {
2244c4eb519SMatthias Ringwald         xt[i] = *pcm >> 8;
225*6897da5cSDirk Helbig         xs[i] = lc3_ldexpf(*pcm, -8);
2264c4eb519SMatthias Ringwald     }
2274c4eb519SMatthias Ringwald }
2284930cef6SMatthias Ringwald 
2294c4eb519SMatthias Ringwald /**
2304c4eb519SMatthias Ringwald  * Input PCM Samples from signed 24 bits packed
2314c4eb519SMatthias Ringwald  * encoder         Encoder state
2324c4eb519SMatthias Ringwald  * pcm, stride     Input PCM samples, and count between two consecutives
2334c4eb519SMatthias Ringwald  */
load_s24_3le(struct lc3_encoder * encoder,const void * _pcm,int stride)2344c4eb519SMatthias Ringwald static void load_s24_3le(
2354c4eb519SMatthias Ringwald     struct lc3_encoder *encoder, const void *_pcm, int stride)
2364c4eb519SMatthias Ringwald {
2374c4eb519SMatthias Ringwald     const uint8_t *pcm = _pcm;
2384c4eb519SMatthias Ringwald 
2394c4eb519SMatthias Ringwald     enum lc3_dt dt = encoder->dt;
2404c4eb519SMatthias Ringwald     enum lc3_srate sr = encoder->sr_pcm;
2414c4eb519SMatthias Ringwald 
242*6897da5cSDirk Helbig     int16_t *xt = (int16_t *)encoder->x + encoder->xt_off;
243*6897da5cSDirk Helbig     float *xs = encoder->x + encoder->xs_off;
244*6897da5cSDirk Helbig     int ns = lc3_ns(dt, sr);
2454c4eb519SMatthias Ringwald 
2464c4eb519SMatthias Ringwald     for (int i = 0; i < ns; i++, pcm += 3*stride) {
2474c4eb519SMatthias Ringwald         int32_t in = ((uint32_t)pcm[0] <<  8) |
2484c4eb519SMatthias Ringwald                      ((uint32_t)pcm[1] << 16) |
2494c4eb519SMatthias Ringwald                      ((uint32_t)pcm[2] << 24)  ;
2504c4eb519SMatthias Ringwald 
2514c4eb519SMatthias Ringwald         xt[i] = in >> 16;
252*6897da5cSDirk Helbig         xs[i] = lc3_ldexpf(in, -16);
2534c4eb519SMatthias Ringwald     }
2544c4eb519SMatthias Ringwald }
2554c4eb519SMatthias Ringwald 
2564c4eb519SMatthias Ringwald /**
2574c4eb519SMatthias Ringwald  * Input PCM Samples from float 32 bits
2584c4eb519SMatthias Ringwald  * encoder         Encoder state
2594c4eb519SMatthias Ringwald  * pcm, stride     Input PCM samples, and count between two consecutives
2604c4eb519SMatthias Ringwald  */
load_float(struct lc3_encoder * encoder,const void * _pcm,int stride)2614c4eb519SMatthias Ringwald static void load_float(
2624c4eb519SMatthias Ringwald     struct lc3_encoder *encoder, const void *_pcm, int stride)
2634c4eb519SMatthias Ringwald {
2644c4eb519SMatthias Ringwald     const float *pcm = _pcm;
2654c4eb519SMatthias Ringwald 
2664c4eb519SMatthias Ringwald     enum lc3_dt dt = encoder->dt;
2674c4eb519SMatthias Ringwald     enum lc3_srate sr = encoder->sr_pcm;
2684c4eb519SMatthias Ringwald 
269*6897da5cSDirk Helbig     int16_t *xt = (int16_t *)encoder->x + encoder->xt_off;
270*6897da5cSDirk Helbig     float *xs = encoder->x + encoder->xs_off;
271*6897da5cSDirk Helbig     int ns = lc3_ns(dt, sr);
2724c4eb519SMatthias Ringwald 
2734c4eb519SMatthias Ringwald     for (int i = 0; i < ns; i++, pcm += stride) {
274*6897da5cSDirk Helbig         xs[i] = lc3_ldexpf(*pcm, 15);
2754c4eb519SMatthias Ringwald         xt[i] = LC3_SAT16((int32_t)xs[i]);
2764930cef6SMatthias Ringwald     }
2779a19cd78SMatthias Ringwald }
2789a19cd78SMatthias Ringwald 
2799a19cd78SMatthias Ringwald /**
2809a19cd78SMatthias Ringwald  * Frame Analysis
2819a19cd78SMatthias Ringwald  * encoder         Encoder state
2829a19cd78SMatthias Ringwald  * nbytes          Size in bytes of the frame
283*6897da5cSDirk Helbig  * side            Return frame data
2849a19cd78SMatthias Ringwald  */
analyze(struct lc3_encoder * encoder,int nbytes,struct side_data * side)2859a19cd78SMatthias Ringwald static void analyze(struct lc3_encoder *encoder,
286*6897da5cSDirk Helbig     int nbytes, struct side_data *side)
2879a19cd78SMatthias Ringwald {
2889a19cd78SMatthias Ringwald     enum lc3_dt dt = encoder->dt;
2899a19cd78SMatthias Ringwald     enum lc3_srate sr = encoder->sr;
2909a19cd78SMatthias Ringwald     enum lc3_srate sr_pcm = encoder->sr_pcm;
2919a19cd78SMatthias Ringwald 
292*6897da5cSDirk Helbig     int16_t *xt = (int16_t *)encoder->x + encoder->xt_off;
293*6897da5cSDirk Helbig     float *xs = encoder->x + encoder->xs_off;
294*6897da5cSDirk Helbig     int ns = lc3_ns(dt, sr_pcm);
295*6897da5cSDirk Helbig     int nt = lc3_nt(sr_pcm);
296*6897da5cSDirk Helbig 
297*6897da5cSDirk Helbig     float *xd = encoder->x + encoder->xd_off;
2984930cef6SMatthias Ringwald     float *xf = xs;
2999a19cd78SMatthias Ringwald 
3009a19cd78SMatthias Ringwald     /* --- Temporal --- */
3019a19cd78SMatthias Ringwald 
3024930cef6SMatthias Ringwald     bool att = lc3_attdet_run(dt, sr_pcm, nbytes, &encoder->attdet, xt);
3039a19cd78SMatthias Ringwald 
3049a19cd78SMatthias Ringwald     side->pitch_present =
3054930cef6SMatthias Ringwald         lc3_ltpf_analyse(dt, sr_pcm, &encoder->ltpf, xt, &side->ltpf);
3064930cef6SMatthias Ringwald 
3074930cef6SMatthias Ringwald     memmove(xt - nt, xt + (ns-nt), nt * sizeof(*xt));
3089a19cd78SMatthias Ringwald 
3099a19cd78SMatthias Ringwald     /* --- Spectral --- */
3109a19cd78SMatthias Ringwald 
311*6897da5cSDirk Helbig     float e[LC3_MAX_BANDS];
3129a19cd78SMatthias Ringwald 
3134930cef6SMatthias Ringwald     lc3_mdct_forward(dt, sr_pcm, sr, xs, xd, xf);
3149a19cd78SMatthias Ringwald 
3159a19cd78SMatthias Ringwald     bool nn_flag = lc3_energy_compute(dt, sr, xf, e);
3169a19cd78SMatthias Ringwald     if (nn_flag)
3179a19cd78SMatthias Ringwald         lc3_ltpf_disable(&side->ltpf);
3189a19cd78SMatthias Ringwald 
3199a19cd78SMatthias Ringwald     side->bw = lc3_bwdet_run(dt, sr, e);
3209a19cd78SMatthias Ringwald 
321*6897da5cSDirk Helbig     lc3_sns_analyze(dt, sr, nbytes, e, att, &side->sns, xf, xf);
3229a19cd78SMatthias Ringwald 
3239a19cd78SMatthias Ringwald     lc3_tns_analyze(dt, side->bw, nn_flag, nbytes, &side->tns, xf);
3249a19cd78SMatthias Ringwald 
3259a19cd78SMatthias Ringwald     lc3_spec_analyze(dt, sr,
3269a19cd78SMatthias Ringwald         nbytes, side->pitch_present, &side->tns,
327*6897da5cSDirk Helbig         &encoder->spec, xf, &side->spec);
3289a19cd78SMatthias Ringwald }
3299a19cd78SMatthias Ringwald 
3309a19cd78SMatthias Ringwald /**
3319a19cd78SMatthias Ringwald  * Encode bitstream
3329a19cd78SMatthias Ringwald  * encoder         Encoder state
333*6897da5cSDirk Helbig  * side            The frame data
3349a19cd78SMatthias Ringwald  * nbytes          Target size of the frame (20 to 400)
3359a19cd78SMatthias Ringwald  * buffer          Output bitstream buffer of `nbytes` size
3369a19cd78SMatthias Ringwald  */
encode(struct lc3_encoder * encoder,const struct side_data * side,int nbytes,void * buffer)3379a19cd78SMatthias Ringwald static void encode(struct lc3_encoder *encoder,
338*6897da5cSDirk Helbig     const struct side_data *side, int nbytes, void *buffer)
3399a19cd78SMatthias Ringwald {
3409a19cd78SMatthias Ringwald     enum lc3_dt dt = encoder->dt;
3419a19cd78SMatthias Ringwald     enum lc3_srate sr = encoder->sr;
342*6897da5cSDirk Helbig 
343*6897da5cSDirk Helbig     float *xf = encoder->x + encoder->xs_off;
3449a19cd78SMatthias Ringwald     enum lc3_bandwidth bw = side->bw;
3459a19cd78SMatthias Ringwald 
3469a19cd78SMatthias Ringwald     lc3_bits_t bits;
3479a19cd78SMatthias Ringwald 
3489a19cd78SMatthias Ringwald     lc3_setup_bits(&bits, LC3_BITS_MODE_WRITE, buffer, nbytes);
3499a19cd78SMatthias Ringwald 
3509a19cd78SMatthias Ringwald     lc3_bwdet_put_bw(&bits, sr, bw);
3519a19cd78SMatthias Ringwald 
3529a19cd78SMatthias Ringwald     lc3_spec_put_side(&bits, dt, sr, &side->spec);
3539a19cd78SMatthias Ringwald 
3549a19cd78SMatthias Ringwald     lc3_tns_put_data(&bits, &side->tns);
3559a19cd78SMatthias Ringwald 
3569a19cd78SMatthias Ringwald     lc3_put_bit(&bits, side->pitch_present);
3579a19cd78SMatthias Ringwald 
3589a19cd78SMatthias Ringwald     lc3_sns_put_data(&bits, &side->sns);
3599a19cd78SMatthias Ringwald 
3609a19cd78SMatthias Ringwald     if (side->pitch_present)
3619a19cd78SMatthias Ringwald         lc3_ltpf_put_data(&bits, &side->ltpf);
3629a19cd78SMatthias Ringwald 
363*6897da5cSDirk Helbig     lc3_spec_encode(&bits, dt, sr, bw, nbytes, &side->spec, xf);
3649a19cd78SMatthias Ringwald 
3659a19cd78SMatthias Ringwald     lc3_flush_bits(&bits);
3669a19cd78SMatthias Ringwald }
3679a19cd78SMatthias Ringwald 
3689a19cd78SMatthias Ringwald /**
3699a19cd78SMatthias Ringwald  * Return size needed for an encoder
3709a19cd78SMatthias Ringwald  */
lc3_hr_encoder_size(bool hrmode,int dt_us,int sr_hz)371*6897da5cSDirk Helbig LC3_EXPORT unsigned lc3_hr_encoder_size(bool hrmode, int dt_us, int sr_hz)
3729a19cd78SMatthias Ringwald {
373*6897da5cSDirk Helbig     if (resolve_dt(dt_us, hrmode) >= LC3_NUM_DT ||
374*6897da5cSDirk Helbig         resolve_srate(sr_hz, hrmode) >= LC3_NUM_SRATE)
3759a19cd78SMatthias Ringwald         return 0;
3769a19cd78SMatthias Ringwald 
3779a19cd78SMatthias Ringwald     return sizeof(struct lc3_encoder) +
3784c4eb519SMatthias Ringwald         (LC3_ENCODER_BUFFER_COUNT(dt_us, sr_hz)-1) * sizeof(float);
3799a19cd78SMatthias Ringwald }
3809a19cd78SMatthias Ringwald 
lc3_encoder_size(int dt_us,int sr_hz)381*6897da5cSDirk Helbig LC3_EXPORT unsigned lc3_encoder_size(int dt_us, int sr_hz)
382*6897da5cSDirk Helbig {
383*6897da5cSDirk Helbig     return lc3_hr_encoder_size(false, dt_us, sr_hz);
384*6897da5cSDirk Helbig }
385*6897da5cSDirk Helbig 
3869a19cd78SMatthias Ringwald /**
3879a19cd78SMatthias Ringwald  * Setup encoder
3889a19cd78SMatthias Ringwald  */
lc3_hr_setup_encoder(bool hrmode,int dt_us,int sr_hz,int sr_pcm_hz,void * mem)389*6897da5cSDirk Helbig LC3_EXPORT struct lc3_encoder *lc3_hr_setup_encoder(
390*6897da5cSDirk Helbig     bool hrmode, int dt_us, int sr_hz, int sr_pcm_hz, void *mem)
3919a19cd78SMatthias Ringwald {
3929a19cd78SMatthias Ringwald     if (sr_pcm_hz <= 0)
3939a19cd78SMatthias Ringwald         sr_pcm_hz = sr_hz;
3949a19cd78SMatthias Ringwald 
395*6897da5cSDirk Helbig     enum lc3_dt dt = resolve_dt(dt_us, hrmode);
396*6897da5cSDirk Helbig     enum lc3_srate sr = resolve_srate(sr_hz, hrmode);
397*6897da5cSDirk Helbig     enum lc3_srate sr_pcm = resolve_srate(sr_pcm_hz, hrmode);
3989a19cd78SMatthias Ringwald 
3999a19cd78SMatthias Ringwald     if (dt >= LC3_NUM_DT || sr_pcm >= LC3_NUM_SRATE || sr > sr_pcm || !mem)
4009a19cd78SMatthias Ringwald         return NULL;
4019a19cd78SMatthias Ringwald 
4029a19cd78SMatthias Ringwald     struct lc3_encoder *encoder = mem;
403*6897da5cSDirk Helbig     int ns = lc3_ns(dt, sr_pcm);
404*6897da5cSDirk Helbig     int nt = lc3_nt(sr_pcm);
4059a19cd78SMatthias Ringwald 
4069a19cd78SMatthias Ringwald     *encoder = (struct lc3_encoder){
4079a19cd78SMatthias Ringwald         .dt = dt, .sr = sr,
4089a19cd78SMatthias Ringwald         .sr_pcm = sr_pcm,
4094930cef6SMatthias Ringwald 
410*6897da5cSDirk Helbig         .xt_off = nt,
411*6897da5cSDirk Helbig         .xs_off = (nt + ns) / 2,
412*6897da5cSDirk Helbig         .xd_off = (nt + ns) / 2 + ns,
4139a19cd78SMatthias Ringwald     };
4149a19cd78SMatthias Ringwald 
415*6897da5cSDirk Helbig     memset(encoder->x, 0,
4169a19cd78SMatthias Ringwald         LC3_ENCODER_BUFFER_COUNT(dt_us, sr_pcm_hz) * sizeof(float));
4179a19cd78SMatthias Ringwald 
4189a19cd78SMatthias Ringwald     return encoder;
4199a19cd78SMatthias Ringwald }
4209a19cd78SMatthias Ringwald 
lc3_setup_encoder(int dt_us,int sr_hz,int sr_pcm_hz,void * mem)421*6897da5cSDirk Helbig LC3_EXPORT struct lc3_encoder *lc3_setup_encoder(
422*6897da5cSDirk Helbig     int dt_us, int sr_hz, int sr_pcm_hz, void *mem)
423*6897da5cSDirk Helbig {
424*6897da5cSDirk Helbig     return lc3_hr_setup_encoder(false, dt_us, sr_hz, sr_pcm_hz, mem);
425*6897da5cSDirk Helbig }
426*6897da5cSDirk Helbig 
4279a19cd78SMatthias Ringwald /**
4289a19cd78SMatthias Ringwald  * Encode a frame
4299a19cd78SMatthias Ringwald  */
lc3_encode(struct lc3_encoder * encoder,enum lc3_pcm_format fmt,const void * pcm,int stride,int nbytes,void * out)430*6897da5cSDirk Helbig LC3_EXPORT int lc3_encode(struct lc3_encoder *encoder,
431*6897da5cSDirk Helbig     enum lc3_pcm_format fmt, const void *pcm, int stride, int nbytes, void *out)
4329a19cd78SMatthias Ringwald {
4339a19cd78SMatthias Ringwald     static void (* const load[])(struct lc3_encoder *, const void *, int) = {
4349a19cd78SMatthias Ringwald         [LC3_PCM_FORMAT_S16    ] = load_s16,
4359a19cd78SMatthias Ringwald         [LC3_PCM_FORMAT_S24    ] = load_s24,
4364c4eb519SMatthias Ringwald         [LC3_PCM_FORMAT_S24_3LE] = load_s24_3le,
4374c4eb519SMatthias Ringwald         [LC3_PCM_FORMAT_FLOAT  ] = load_float,
4389a19cd78SMatthias Ringwald     };
4399a19cd78SMatthias Ringwald 
4409a19cd78SMatthias Ringwald     /* --- Check parameters --- */
4419a19cd78SMatthias Ringwald 
442*6897da5cSDirk Helbig     if (!encoder || nbytes < lc3_min_frame_bytes(encoder->dt, encoder->sr)
443*6897da5cSDirk Helbig                  || nbytes > lc3_max_frame_bytes(encoder->dt, encoder->sr))
4449a19cd78SMatthias Ringwald         return -1;
4459a19cd78SMatthias Ringwald 
4469a19cd78SMatthias Ringwald     /* --- Processing --- */
4479a19cd78SMatthias Ringwald 
4489a19cd78SMatthias Ringwald     struct side_data side;
4499a19cd78SMatthias Ringwald 
4509a19cd78SMatthias Ringwald     load[fmt](encoder, pcm, stride);
4519a19cd78SMatthias Ringwald 
452*6897da5cSDirk Helbig     analyze(encoder, nbytes, &side);
4539a19cd78SMatthias Ringwald 
454*6897da5cSDirk Helbig     encode(encoder, &side, nbytes, out);
4559a19cd78SMatthias Ringwald 
4569a19cd78SMatthias Ringwald     return 0;
4579a19cd78SMatthias Ringwald }
4589a19cd78SMatthias Ringwald 
4599a19cd78SMatthias Ringwald 
4609a19cd78SMatthias Ringwald /* ----------------------------------------------------------------------------
4619a19cd78SMatthias Ringwald  *  Decoder
4629a19cd78SMatthias Ringwald  * -------------------------------------------------------------------------- */
4639a19cd78SMatthias Ringwald 
4649a19cd78SMatthias Ringwald /**
4659a19cd78SMatthias Ringwald  * Output PCM Samples to signed 16 bits
4669a19cd78SMatthias Ringwald  * decoder         Decoder state
4679a19cd78SMatthias Ringwald  * pcm, stride     Output PCM samples, and count between two consecutives
4689a19cd78SMatthias Ringwald  */
store_s16(struct lc3_decoder * decoder,void * _pcm,int stride)4699a19cd78SMatthias Ringwald static void store_s16(
4709a19cd78SMatthias Ringwald     struct lc3_decoder *decoder, void *_pcm, int stride)
4719a19cd78SMatthias Ringwald {
4729a19cd78SMatthias Ringwald     int16_t *pcm = _pcm;
4739a19cd78SMatthias Ringwald 
4749a19cd78SMatthias Ringwald     enum lc3_dt dt = decoder->dt;
4759a19cd78SMatthias Ringwald     enum lc3_srate sr = decoder->sr_pcm;
4764930cef6SMatthias Ringwald 
477*6897da5cSDirk Helbig     float *xs = decoder->x + decoder->xs_off;
478*6897da5cSDirk Helbig     int ns = lc3_ns(dt, sr);
4799a19cd78SMatthias Ringwald 
4809a19cd78SMatthias Ringwald     for ( ; ns > 0; ns--, xs++, pcm += stride) {
4814930cef6SMatthias Ringwald         int32_t s = *xs >= 0 ? (int)(*xs + 0.5f) : (int)(*xs - 0.5f);
4824930cef6SMatthias Ringwald         *pcm = LC3_SAT16(s);
4839a19cd78SMatthias Ringwald     }
4849a19cd78SMatthias Ringwald }
4859a19cd78SMatthias Ringwald 
4869a19cd78SMatthias Ringwald /**
4879a19cd78SMatthias Ringwald  * Output PCM Samples to signed 24 bits
4889a19cd78SMatthias Ringwald  * decoder         Decoder state
4899a19cd78SMatthias Ringwald  * pcm, stride     Output PCM samples, and count between two consecutives
4909a19cd78SMatthias Ringwald  */
store_s24(struct lc3_decoder * decoder,void * _pcm,int stride)4919a19cd78SMatthias Ringwald static void store_s24(
4929a19cd78SMatthias Ringwald     struct lc3_decoder *decoder, void *_pcm, int stride)
4939a19cd78SMatthias Ringwald {
4949a19cd78SMatthias Ringwald     int32_t *pcm = _pcm;
4959a19cd78SMatthias Ringwald 
4969a19cd78SMatthias Ringwald     enum lc3_dt dt = decoder->dt;
4979a19cd78SMatthias Ringwald     enum lc3_srate sr = decoder->sr_pcm;
4984930cef6SMatthias Ringwald 
499*6897da5cSDirk Helbig     float *xs = decoder->x + decoder->xs_off;
500*6897da5cSDirk Helbig     int ns = lc3_ns(dt, sr);
5019a19cd78SMatthias Ringwald 
5029a19cd78SMatthias Ringwald     for ( ; ns > 0; ns--, xs++, pcm += stride) {
503*6897da5cSDirk Helbig         int32_t s = *xs >= 0 ? (int32_t)(lc3_ldexpf(*xs, 8) + 0.5f)
504*6897da5cSDirk Helbig                              : (int32_t)(lc3_ldexpf(*xs, 8) - 0.5f);
5054930cef6SMatthias Ringwald         *pcm = LC3_SAT24(s);
5069a19cd78SMatthias Ringwald     }
5079a19cd78SMatthias Ringwald }
5089a19cd78SMatthias Ringwald 
5099a19cd78SMatthias Ringwald /**
5104c4eb519SMatthias Ringwald  * Output PCM Samples to signed 24 bits packed
5114c4eb519SMatthias Ringwald  * decoder         Decoder state
5124c4eb519SMatthias Ringwald  * pcm, stride     Output PCM samples, and count between two consecutives
5134c4eb519SMatthias Ringwald  */
store_s24_3le(struct lc3_decoder * decoder,void * _pcm,int stride)5144c4eb519SMatthias Ringwald static void store_s24_3le(
5154c4eb519SMatthias Ringwald     struct lc3_decoder *decoder, void *_pcm, int stride)
5164c4eb519SMatthias Ringwald {
5174c4eb519SMatthias Ringwald     uint8_t *pcm = _pcm;
5184c4eb519SMatthias Ringwald 
5194c4eb519SMatthias Ringwald     enum lc3_dt dt = decoder->dt;
5204c4eb519SMatthias Ringwald     enum lc3_srate sr = decoder->sr_pcm;
5214c4eb519SMatthias Ringwald 
522*6897da5cSDirk Helbig     float *xs = decoder->x + decoder->xs_off;
523*6897da5cSDirk Helbig     int ns = lc3_ns(dt, sr);
5244c4eb519SMatthias Ringwald 
5254c4eb519SMatthias Ringwald     for ( ; ns > 0; ns--, xs++, pcm += 3*stride) {
526*6897da5cSDirk Helbig         int32_t s = *xs >= 0 ? (int32_t)(lc3_ldexpf(*xs, 8) + 0.5f)
527*6897da5cSDirk Helbig                              : (int32_t)(lc3_ldexpf(*xs, 8) - 0.5f);
5284c4eb519SMatthias Ringwald 
5294c4eb519SMatthias Ringwald         s = LC3_SAT24(s);
5304c4eb519SMatthias Ringwald         pcm[0] = (s >>  0) & 0xff;
5314c4eb519SMatthias Ringwald         pcm[1] = (s >>  8) & 0xff;
5324c4eb519SMatthias Ringwald         pcm[2] = (s >> 16) & 0xff;
5334c4eb519SMatthias Ringwald     }
5344c4eb519SMatthias Ringwald }
5354c4eb519SMatthias Ringwald 
5364c4eb519SMatthias Ringwald /**
5374c4eb519SMatthias Ringwald  * Output PCM Samples to float 32 bits
5384c4eb519SMatthias Ringwald  * decoder         Decoder state
5394c4eb519SMatthias Ringwald  * pcm, stride     Output PCM samples, and count between two consecutives
5404c4eb519SMatthias Ringwald  */
store_float(struct lc3_decoder * decoder,void * _pcm,int stride)5414c4eb519SMatthias Ringwald static void store_float(
5424c4eb519SMatthias Ringwald     struct lc3_decoder *decoder, void *_pcm, int stride)
5434c4eb519SMatthias Ringwald {
5444c4eb519SMatthias Ringwald     float *pcm = _pcm;
5454c4eb519SMatthias Ringwald 
5464c4eb519SMatthias Ringwald     enum lc3_dt dt = decoder->dt;
5474c4eb519SMatthias Ringwald     enum lc3_srate sr = decoder->sr_pcm;
5484c4eb519SMatthias Ringwald 
549*6897da5cSDirk Helbig     float *xs = decoder->x + decoder->xs_off;
550*6897da5cSDirk Helbig     int ns = lc3_ns(dt, sr);
5514c4eb519SMatthias Ringwald 
5524c4eb519SMatthias Ringwald     for ( ; ns > 0; ns--, xs++, pcm += stride) {
553*6897da5cSDirk Helbig         float s = lc3_ldexpf(*xs, -15);
5544c4eb519SMatthias Ringwald         *pcm = fminf(fmaxf(s, -1.f), 1.f);
5554c4eb519SMatthias Ringwald     }
5564c4eb519SMatthias Ringwald }
5574c4eb519SMatthias Ringwald 
5584c4eb519SMatthias Ringwald /**
5599a19cd78SMatthias Ringwald  * Decode bitstream
5609a19cd78SMatthias Ringwald  * decoder         Decoder state
5619a19cd78SMatthias Ringwald  * data, nbytes    Input bitstream buffer
5629a19cd78SMatthias Ringwald  * side            Return the side data
5639a19cd78SMatthias Ringwald  * return          0: Ok  < 0: Bitsream error detected
5649a19cd78SMatthias Ringwald  */
decode(struct lc3_decoder * decoder,const void * data,int nbytes,struct side_data * side)5659a19cd78SMatthias Ringwald static int decode(struct lc3_decoder *decoder,
5669a19cd78SMatthias Ringwald     const void *data, int nbytes, struct side_data *side)
5679a19cd78SMatthias Ringwald {
5689a19cd78SMatthias Ringwald     enum lc3_dt dt = decoder->dt;
5699a19cd78SMatthias Ringwald     enum lc3_srate sr = decoder->sr;
5704930cef6SMatthias Ringwald 
571*6897da5cSDirk Helbig     float *xf = decoder->x + decoder->xs_off;
572*6897da5cSDirk Helbig     int ns = lc3_ns(dt, sr);
573*6897da5cSDirk Helbig     int ne = lc3_ne(dt, sr);
5749a19cd78SMatthias Ringwald 
5759a19cd78SMatthias Ringwald     lc3_bits_t bits;
5769a19cd78SMatthias Ringwald     int ret = 0;
5779a19cd78SMatthias Ringwald 
5789a19cd78SMatthias Ringwald     lc3_setup_bits(&bits, LC3_BITS_MODE_READ, (void *)data, nbytes);
5799a19cd78SMatthias Ringwald 
5809a19cd78SMatthias Ringwald     if ((ret = lc3_bwdet_get_bw(&bits, sr, &side->bw)) < 0)
5819a19cd78SMatthias Ringwald         return ret;
5829a19cd78SMatthias Ringwald 
5839a19cd78SMatthias Ringwald     if ((ret = lc3_spec_get_side(&bits, dt, sr, &side->spec)) < 0)
5849a19cd78SMatthias Ringwald         return ret;
5859a19cd78SMatthias Ringwald 
586*6897da5cSDirk Helbig     if ((ret = lc3_tns_get_data(&bits, dt, side->bw, nbytes, &side->tns)) < 0)
587*6897da5cSDirk Helbig         return ret;
5889a19cd78SMatthias Ringwald 
5899a19cd78SMatthias Ringwald     side->pitch_present = lc3_get_bit(&bits);
5909a19cd78SMatthias Ringwald 
5919a19cd78SMatthias Ringwald     if ((ret = lc3_sns_get_data(&bits, &side->sns)) < 0)
5929a19cd78SMatthias Ringwald         return ret;
5939a19cd78SMatthias Ringwald 
5949a19cd78SMatthias Ringwald     if (side->pitch_present)
5959a19cd78SMatthias Ringwald       lc3_ltpf_get_data(&bits, &side->ltpf);
5969a19cd78SMatthias Ringwald 
5979a19cd78SMatthias Ringwald     if ((ret = lc3_spec_decode(&bits, dt, sr,
5989a19cd78SMatthias Ringwald                     side->bw, nbytes, &side->spec, xf)) < 0)
5999a19cd78SMatthias Ringwald         return ret;
6009a19cd78SMatthias Ringwald 
6019a19cd78SMatthias Ringwald     memset(xf + ne, 0, (ns - ne) * sizeof(float));
6029a19cd78SMatthias Ringwald 
6039a19cd78SMatthias Ringwald     return lc3_check_bits(&bits);
6049a19cd78SMatthias Ringwald }
6059a19cd78SMatthias Ringwald 
6069a19cd78SMatthias Ringwald /**
6079a19cd78SMatthias Ringwald  * Frame synthesis
6089a19cd78SMatthias Ringwald  * decoder         Decoder state
6099a19cd78SMatthias Ringwald  * side            Frame data, NULL performs PLC
6109a19cd78SMatthias Ringwald  * nbytes          Size in bytes of the frame
6119a19cd78SMatthias Ringwald  */
synthesize(struct lc3_decoder * decoder,const struct side_data * side,int nbytes)6129a19cd78SMatthias Ringwald static void synthesize(struct lc3_decoder *decoder,
6139a19cd78SMatthias Ringwald     const struct side_data *side, int nbytes)
6149a19cd78SMatthias Ringwald {
6159a19cd78SMatthias Ringwald     enum lc3_dt dt = decoder->dt;
6169a19cd78SMatthias Ringwald     enum lc3_srate sr = decoder->sr;
6179a19cd78SMatthias Ringwald     enum lc3_srate sr_pcm = decoder->sr_pcm;
6189a19cd78SMatthias Ringwald 
619*6897da5cSDirk Helbig     float *xf = decoder->x + decoder->xs_off;
620*6897da5cSDirk Helbig     int ns = lc3_ns(dt, sr_pcm);
621*6897da5cSDirk Helbig     int ne = lc3_ne(dt, sr);
6224930cef6SMatthias Ringwald 
623*6897da5cSDirk Helbig     float *xg = decoder->x + decoder->xg_off;
6249a19cd78SMatthias Ringwald     float *xs = xf;
6259a19cd78SMatthias Ringwald 
626*6897da5cSDirk Helbig     float *xd = decoder->x + decoder->xd_off;
627*6897da5cSDirk Helbig     float *xh = decoder->x + decoder->xh_off;
628*6897da5cSDirk Helbig 
6299a19cd78SMatthias Ringwald     if (side) {
6309a19cd78SMatthias Ringwald         enum lc3_bandwidth bw = side->bw;
6319a19cd78SMatthias Ringwald 
6329a19cd78SMatthias Ringwald         lc3_plc_suspend(&decoder->plc);
6339a19cd78SMatthias Ringwald 
6349a19cd78SMatthias Ringwald         lc3_tns_synthesize(dt, bw, &side->tns, xf);
6359a19cd78SMatthias Ringwald 
6369a19cd78SMatthias Ringwald         lc3_sns_synthesize(dt, sr, &side->sns, xf, xg);
6379a19cd78SMatthias Ringwald 
6389a19cd78SMatthias Ringwald         lc3_mdct_inverse(dt, sr_pcm, sr, xg, xd, xs);
6399a19cd78SMatthias Ringwald 
6409a19cd78SMatthias Ringwald     } else {
6419a19cd78SMatthias Ringwald         lc3_plc_synthesize(dt, sr, &decoder->plc, xg, xf);
6429a19cd78SMatthias Ringwald 
6439a19cd78SMatthias Ringwald         memset(xf + ne, 0, (ns - ne) * sizeof(float));
6449a19cd78SMatthias Ringwald 
6459a19cd78SMatthias Ringwald         lc3_mdct_inverse(dt, sr_pcm, sr, xf, xd, xs);
6469a19cd78SMatthias Ringwald     }
6479a19cd78SMatthias Ringwald 
648*6897da5cSDirk Helbig     if (!lc3_hr(sr))
6499a19cd78SMatthias Ringwald         lc3_ltpf_synthesize(dt, sr_pcm, nbytes, &decoder->ltpf,
650*6897da5cSDirk Helbig             side && side->pitch_present ? &side->ltpf : NULL, xh, xs);
6514930cef6SMatthias Ringwald }
6529a19cd78SMatthias Ringwald 
6534930cef6SMatthias Ringwald /**
6544930cef6SMatthias Ringwald  * Update decoder state on decoding completion
6554930cef6SMatthias Ringwald  * decoder         Decoder state
6564930cef6SMatthias Ringwald  */
complete(struct lc3_decoder * decoder)6574930cef6SMatthias Ringwald static void complete(struct lc3_decoder *decoder)
6584930cef6SMatthias Ringwald {
6594930cef6SMatthias Ringwald     enum lc3_dt dt = decoder->dt;
6604930cef6SMatthias Ringwald     enum lc3_srate sr_pcm = decoder->sr_pcm;
661*6897da5cSDirk Helbig     int nh = lc3_nh(dt, sr_pcm);
662*6897da5cSDirk Helbig     int ns = lc3_ns(dt, sr_pcm);
6634930cef6SMatthias Ringwald 
664*6897da5cSDirk Helbig     decoder->xs_off = decoder->xs_off - decoder->xh_off < nh ?
665*6897da5cSDirk Helbig         decoder->xs_off + ns : decoder->xh_off;
6669a19cd78SMatthias Ringwald }
6679a19cd78SMatthias Ringwald 
6689a19cd78SMatthias Ringwald /**
6699a19cd78SMatthias Ringwald  * Return size needed for a decoder
6709a19cd78SMatthias Ringwald  */
lc3_hr_decoder_size(bool hrmode,int dt_us,int sr_hz)671*6897da5cSDirk Helbig LC3_EXPORT unsigned lc3_hr_decoder_size(bool hrmode, int dt_us, int sr_hz)
6729a19cd78SMatthias Ringwald {
673*6897da5cSDirk Helbig     if (resolve_dt(dt_us, hrmode) >= LC3_NUM_DT ||
674*6897da5cSDirk Helbig         resolve_srate(sr_hz, hrmode) >= LC3_NUM_SRATE)
6759a19cd78SMatthias Ringwald         return 0;
6769a19cd78SMatthias Ringwald 
6779a19cd78SMatthias Ringwald     return sizeof(struct lc3_decoder) +
6784c4eb519SMatthias Ringwald         (LC3_DECODER_BUFFER_COUNT(dt_us, sr_hz)-1) * sizeof(float);
6799a19cd78SMatthias Ringwald }
6809a19cd78SMatthias Ringwald 
lc3_decoder_size(int dt_us,int sr_hz)681*6897da5cSDirk Helbig LC3_EXPORT unsigned lc3_decoder_size(int dt_us, int sr_hz)
682*6897da5cSDirk Helbig {
683*6897da5cSDirk Helbig     return lc3_hr_decoder_size(false, dt_us, sr_hz);
684*6897da5cSDirk Helbig }
685*6897da5cSDirk Helbig 
6869a19cd78SMatthias Ringwald /**
6879a19cd78SMatthias Ringwald  * Setup decoder
6889a19cd78SMatthias Ringwald  */
lc3_hr_setup_decoder(bool hrmode,int dt_us,int sr_hz,int sr_pcm_hz,void * mem)689*6897da5cSDirk Helbig LC3_EXPORT struct lc3_decoder *lc3_hr_setup_decoder(
690*6897da5cSDirk Helbig     bool hrmode, int dt_us, int sr_hz, int sr_pcm_hz, void *mem)
6919a19cd78SMatthias Ringwald {
6929a19cd78SMatthias Ringwald     if (sr_pcm_hz <= 0)
6939a19cd78SMatthias Ringwald         sr_pcm_hz = sr_hz;
6949a19cd78SMatthias Ringwald 
695*6897da5cSDirk Helbig     enum lc3_dt dt = resolve_dt(dt_us, hrmode);
696*6897da5cSDirk Helbig     enum lc3_srate sr = resolve_srate(sr_hz, hrmode);
697*6897da5cSDirk Helbig     enum lc3_srate sr_pcm = resolve_srate(sr_pcm_hz, hrmode);
6989a19cd78SMatthias Ringwald 
6999a19cd78SMatthias Ringwald     if (dt >= LC3_NUM_DT || sr_pcm >= LC3_NUM_SRATE || sr > sr_pcm || !mem)
7009a19cd78SMatthias Ringwald         return NULL;
7019a19cd78SMatthias Ringwald 
7029a19cd78SMatthias Ringwald     struct lc3_decoder *decoder = mem;
703*6897da5cSDirk Helbig     int nh = lc3_nh(dt, sr_pcm);
704*6897da5cSDirk Helbig     int ns = lc3_ns(dt, sr_pcm);
705*6897da5cSDirk Helbig     int nd = lc3_nd(dt, sr_pcm);
7069a19cd78SMatthias Ringwald 
7079a19cd78SMatthias Ringwald     *decoder = (struct lc3_decoder){
7089a19cd78SMatthias Ringwald         .dt = dt, .sr = sr,
7099a19cd78SMatthias Ringwald         .sr_pcm = sr_pcm,
7104930cef6SMatthias Ringwald 
711*6897da5cSDirk Helbig         .xh_off = 0,
712*6897da5cSDirk Helbig         .xs_off = nh,
713*6897da5cSDirk Helbig         .xd_off = nh + ns,
714*6897da5cSDirk Helbig         .xg_off = nh + ns + nd,
7159a19cd78SMatthias Ringwald     };
7169a19cd78SMatthias Ringwald 
7179a19cd78SMatthias Ringwald     lc3_plc_reset(&decoder->plc);
7189a19cd78SMatthias Ringwald 
719*6897da5cSDirk Helbig     memset(decoder->x, 0,
7209a19cd78SMatthias Ringwald         LC3_DECODER_BUFFER_COUNT(dt_us, sr_pcm_hz) * sizeof(float));
7219a19cd78SMatthias Ringwald 
7229a19cd78SMatthias Ringwald     return decoder;
7239a19cd78SMatthias Ringwald }
7249a19cd78SMatthias Ringwald 
lc3_setup_decoder(int dt_us,int sr_hz,int sr_pcm_hz,void * mem)725*6897da5cSDirk Helbig LC3_EXPORT struct lc3_decoder *lc3_setup_decoder(
726*6897da5cSDirk Helbig     int dt_us, int sr_hz, int sr_pcm_hz, void *mem)
727*6897da5cSDirk Helbig {
728*6897da5cSDirk Helbig     return lc3_hr_setup_decoder(false, dt_us, sr_hz, sr_pcm_hz, mem);
729*6897da5cSDirk Helbig }
730*6897da5cSDirk Helbig 
7319a19cd78SMatthias Ringwald /**
7329a19cd78SMatthias Ringwald  * Decode a frame
7339a19cd78SMatthias Ringwald  */
lc3_decode(struct lc3_decoder * decoder,const void * in,int nbytes,enum lc3_pcm_format fmt,void * pcm,int stride)734*6897da5cSDirk Helbig LC3_EXPORT int lc3_decode(struct lc3_decoder *decoder,
735*6897da5cSDirk Helbig     const void *in, int nbytes, enum lc3_pcm_format fmt, void *pcm, int stride)
7369a19cd78SMatthias Ringwald {
7379a19cd78SMatthias Ringwald     static void (* const store[])(struct lc3_decoder *, void *, int) = {
7389a19cd78SMatthias Ringwald         [LC3_PCM_FORMAT_S16    ] = store_s16,
7399a19cd78SMatthias Ringwald         [LC3_PCM_FORMAT_S24    ] = store_s24,
7404c4eb519SMatthias Ringwald         [LC3_PCM_FORMAT_S24_3LE] = store_s24_3le,
7414c4eb519SMatthias Ringwald         [LC3_PCM_FORMAT_FLOAT  ] = store_float,
7429a19cd78SMatthias Ringwald     };
7439a19cd78SMatthias Ringwald 
7449a19cd78SMatthias Ringwald     /* --- Check parameters --- */
7459a19cd78SMatthias Ringwald 
7469a19cd78SMatthias Ringwald     if (!decoder)
7479a19cd78SMatthias Ringwald         return -1;
7489a19cd78SMatthias Ringwald 
7499a19cd78SMatthias Ringwald     if (in && (nbytes < LC3_MIN_FRAME_BYTES ||
750*6897da5cSDirk Helbig                nbytes > lc3_max_frame_bytes(decoder->dt, decoder->sr) ))
7519a19cd78SMatthias Ringwald         return -1;
7529a19cd78SMatthias Ringwald 
7539a19cd78SMatthias Ringwald     /* --- Processing --- */
7549a19cd78SMatthias Ringwald 
7559a19cd78SMatthias Ringwald     struct side_data side;
7569a19cd78SMatthias Ringwald 
7579a19cd78SMatthias Ringwald     int ret = !in || (decode(decoder, in, nbytes, &side) < 0);
7589a19cd78SMatthias Ringwald 
7599a19cd78SMatthias Ringwald     synthesize(decoder, ret ? NULL : &side, nbytes);
7609a19cd78SMatthias Ringwald 
7619a19cd78SMatthias Ringwald     store[fmt](decoder, pcm, stride);
7629a19cd78SMatthias Ringwald 
7634930cef6SMatthias Ringwald     complete(decoder);
7644930cef6SMatthias Ringwald 
7659a19cd78SMatthias Ringwald     return ret;
7669a19cd78SMatthias Ringwald }
767