1*49fe348cSAndroid Build Coastguard Worker /******************************************************************************
2*49fe348cSAndroid Build Coastguard Worker *
3*49fe348cSAndroid Build Coastguard Worker * Copyright 2022 Google LLC
4*49fe348cSAndroid Build Coastguard Worker *
5*49fe348cSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
6*49fe348cSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
7*49fe348cSAndroid Build Coastguard Worker * You may obtain a copy of the License at:
8*49fe348cSAndroid Build Coastguard Worker *
9*49fe348cSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
10*49fe348cSAndroid Build Coastguard Worker *
11*49fe348cSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
12*49fe348cSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
13*49fe348cSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*49fe348cSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
15*49fe348cSAndroid Build Coastguard Worker * limitations under the License.
16*49fe348cSAndroid Build Coastguard Worker *
17*49fe348cSAndroid Build Coastguard Worker ******************************************************************************/
18*49fe348cSAndroid Build Coastguard Worker
19*49fe348cSAndroid Build Coastguard Worker #include <lc3.h>
20*49fe348cSAndroid Build Coastguard Worker
21*49fe348cSAndroid Build Coastguard Worker #include "common.h"
22*49fe348cSAndroid Build Coastguard Worker #include "bits.h"
23*49fe348cSAndroid Build Coastguard Worker
24*49fe348cSAndroid Build Coastguard Worker #include "attdet.h"
25*49fe348cSAndroid Build Coastguard Worker #include "bwdet.h"
26*49fe348cSAndroid Build Coastguard Worker #include "ltpf.h"
27*49fe348cSAndroid Build Coastguard Worker #include "mdct.h"
28*49fe348cSAndroid Build Coastguard Worker #include "energy.h"
29*49fe348cSAndroid Build Coastguard Worker #include "sns.h"
30*49fe348cSAndroid Build Coastguard Worker #include "tns.h"
31*49fe348cSAndroid Build Coastguard Worker #include "spec.h"
32*49fe348cSAndroid Build Coastguard Worker #include "plc.h"
33*49fe348cSAndroid Build Coastguard Worker
34*49fe348cSAndroid Build Coastguard Worker
35*49fe348cSAndroid Build Coastguard Worker /**
36*49fe348cSAndroid Build Coastguard Worker * Frame side data
37*49fe348cSAndroid Build Coastguard Worker */
38*49fe348cSAndroid Build Coastguard Worker
39*49fe348cSAndroid Build Coastguard Worker struct side_data {
40*49fe348cSAndroid Build Coastguard Worker enum lc3_bandwidth bw;
41*49fe348cSAndroid Build Coastguard Worker bool pitch_present;
42*49fe348cSAndroid Build Coastguard Worker lc3_ltpf_data_t ltpf;
43*49fe348cSAndroid Build Coastguard Worker lc3_sns_data_t sns;
44*49fe348cSAndroid Build Coastguard Worker lc3_tns_data_t tns;
45*49fe348cSAndroid Build Coastguard Worker lc3_spec_side_t spec;
46*49fe348cSAndroid Build Coastguard Worker };
47*49fe348cSAndroid Build Coastguard Worker
48*49fe348cSAndroid Build Coastguard Worker
49*49fe348cSAndroid Build Coastguard Worker /* ----------------------------------------------------------------------------
50*49fe348cSAndroid Build Coastguard Worker * General
51*49fe348cSAndroid Build Coastguard Worker * -------------------------------------------------------------------------- */
52*49fe348cSAndroid Build Coastguard Worker
53*49fe348cSAndroid Build Coastguard Worker /**
54*49fe348cSAndroid Build Coastguard Worker * Resolve frame duration in us
55*49fe348cSAndroid Build Coastguard Worker * us Frame duration in us
56*49fe348cSAndroid Build Coastguard Worker * hrmode High-resolution mode indication
57*49fe348cSAndroid Build Coastguard Worker * return Frame duration identifier, or LC3_NUM_DT
58*49fe348cSAndroid Build Coastguard Worker */
resolve_dt(int us,bool hrmode)59*49fe348cSAndroid Build Coastguard Worker static enum lc3_dt resolve_dt(int us, bool hrmode)
60*49fe348cSAndroid Build Coastguard Worker {
61*49fe348cSAndroid Build Coastguard Worker return LC3_PLUS && us == 2500 ? LC3_DT_2M5 :
62*49fe348cSAndroid Build Coastguard Worker LC3_PLUS && us == 5000 ? LC3_DT_5M :
63*49fe348cSAndroid Build Coastguard Worker !hrmode && us == 7500 ? LC3_DT_7M5 :
64*49fe348cSAndroid Build Coastguard Worker us == 10000 ? LC3_DT_10M : LC3_NUM_DT;
65*49fe348cSAndroid Build Coastguard Worker }
66*49fe348cSAndroid Build Coastguard Worker
67*49fe348cSAndroid Build Coastguard Worker /**
68*49fe348cSAndroid Build Coastguard Worker * Resolve samplerate in Hz
69*49fe348cSAndroid Build Coastguard Worker * hz Samplerate in Hz
70*49fe348cSAndroid Build Coastguard Worker * hrmode High-resolution mode indication
71*49fe348cSAndroid Build Coastguard Worker * return Sample rate identifier, or LC3_NUM_SRATE
72*49fe348cSAndroid Build Coastguard Worker */
resolve_srate(int hz,bool hrmode)73*49fe348cSAndroid Build Coastguard Worker static enum lc3_srate resolve_srate(int hz, bool hrmode)
74*49fe348cSAndroid Build Coastguard Worker {
75*49fe348cSAndroid Build Coastguard Worker hrmode = LC3_PLUS_HR && hrmode;
76*49fe348cSAndroid Build Coastguard Worker
77*49fe348cSAndroid Build Coastguard Worker return !hrmode && hz == 8000 ? LC3_SRATE_8K :
78*49fe348cSAndroid Build Coastguard Worker !hrmode && hz == 16000 ? LC3_SRATE_16K :
79*49fe348cSAndroid Build Coastguard Worker !hrmode && hz == 24000 ? LC3_SRATE_24K :
80*49fe348cSAndroid Build Coastguard Worker !hrmode && hz == 32000 ? LC3_SRATE_32K :
81*49fe348cSAndroid Build Coastguard Worker !hrmode && hz == 48000 ? LC3_SRATE_48K :
82*49fe348cSAndroid Build Coastguard Worker hrmode && hz == 48000 ? LC3_SRATE_48K_HR :
83*49fe348cSAndroid Build Coastguard Worker hrmode && hz == 96000 ? LC3_SRATE_96K_HR : LC3_NUM_SRATE;
84*49fe348cSAndroid Build Coastguard Worker }
85*49fe348cSAndroid Build Coastguard Worker
86*49fe348cSAndroid Build Coastguard Worker /**
87*49fe348cSAndroid Build Coastguard Worker * Return the number of PCM samples in a frame
88*49fe348cSAndroid Build Coastguard Worker */
lc3_hr_frame_samples(bool hrmode,int dt_us,int sr_hz)89*49fe348cSAndroid Build Coastguard Worker LC3_EXPORT int lc3_hr_frame_samples(bool hrmode, int dt_us, int sr_hz)
90*49fe348cSAndroid Build Coastguard Worker {
91*49fe348cSAndroid Build Coastguard Worker enum lc3_dt dt = resolve_dt(dt_us, hrmode);
92*49fe348cSAndroid Build Coastguard Worker enum lc3_srate sr = resolve_srate(sr_hz, hrmode);
93*49fe348cSAndroid Build Coastguard Worker
94*49fe348cSAndroid Build Coastguard Worker if (dt >= LC3_NUM_DT || sr >= LC3_NUM_SRATE)
95*49fe348cSAndroid Build Coastguard Worker return -1;
96*49fe348cSAndroid Build Coastguard Worker
97*49fe348cSAndroid Build Coastguard Worker return lc3_ns(dt, sr);
98*49fe348cSAndroid Build Coastguard Worker }
99*49fe348cSAndroid Build Coastguard Worker
lc3_frame_samples(int dt_us,int sr_hz)100*49fe348cSAndroid Build Coastguard Worker LC3_EXPORT int lc3_frame_samples(int dt_us, int sr_hz)
101*49fe348cSAndroid Build Coastguard Worker {
102*49fe348cSAndroid Build Coastguard Worker return lc3_hr_frame_samples(false, dt_us, sr_hz);
103*49fe348cSAndroid Build Coastguard Worker }
104*49fe348cSAndroid Build Coastguard Worker
105*49fe348cSAndroid Build Coastguard Worker /**
106*49fe348cSAndroid Build Coastguard Worker * Return the size of frames or frame blocks, from bitrate
107*49fe348cSAndroid Build Coastguard Worker */
lc3_hr_frame_block_bytes(bool hrmode,int dt_us,int sr_hz,int nchannels,int bitrate)108*49fe348cSAndroid Build Coastguard Worker LC3_EXPORT int lc3_hr_frame_block_bytes(
109*49fe348cSAndroid Build Coastguard Worker bool hrmode, int dt_us, int sr_hz, int nchannels, int bitrate)
110*49fe348cSAndroid Build Coastguard Worker {
111*49fe348cSAndroid Build Coastguard Worker enum lc3_dt dt = resolve_dt(dt_us, hrmode);
112*49fe348cSAndroid Build Coastguard Worker enum lc3_srate sr = resolve_srate(sr_hz, hrmode);
113*49fe348cSAndroid Build Coastguard Worker
114*49fe348cSAndroid Build Coastguard Worker if (dt >= LC3_NUM_DT || sr >= LC3_NUM_SRATE
115*49fe348cSAndroid Build Coastguard Worker || nchannels < 1 || nchannels > 8 || bitrate < 0)
116*49fe348cSAndroid Build Coastguard Worker return -1;
117*49fe348cSAndroid Build Coastguard Worker
118*49fe348cSAndroid Build Coastguard Worker bitrate = LC3_CLIP(bitrate, 0, 8*LC3_HR_MAX_BITRATE);
119*49fe348cSAndroid Build Coastguard Worker
120*49fe348cSAndroid Build Coastguard Worker return LC3_CLIP((bitrate * (int)(1 + dt)) / 3200,
121*49fe348cSAndroid Build Coastguard Worker nchannels * lc3_min_frame_bytes(dt, sr),
122*49fe348cSAndroid Build Coastguard Worker nchannels * lc3_max_frame_bytes(dt, sr) );
123*49fe348cSAndroid Build Coastguard Worker }
124*49fe348cSAndroid Build Coastguard Worker
lc3_frame_bock_bytes(int dt_us,int nchannels,int bitrate)125*49fe348cSAndroid Build Coastguard Worker LC3_EXPORT int lc3_frame_bock_bytes(int dt_us, int nchannels, int bitrate)
126*49fe348cSAndroid Build Coastguard Worker {
127*49fe348cSAndroid Build Coastguard Worker return lc3_hr_frame_block_bytes(false, dt_us, 8000, nchannels, bitrate);
128*49fe348cSAndroid Build Coastguard Worker }
129*49fe348cSAndroid Build Coastguard Worker
lc3_hr_frame_bytes(bool hrmode,int dt_us,int sr_hz,int bitrate)130*49fe348cSAndroid Build Coastguard Worker LC3_EXPORT int lc3_hr_frame_bytes(
131*49fe348cSAndroid Build Coastguard Worker bool hrmode, int dt_us, int sr_hz, int bitrate)
132*49fe348cSAndroid Build Coastguard Worker {
133*49fe348cSAndroid Build Coastguard Worker return lc3_hr_frame_block_bytes(hrmode, dt_us, sr_hz, 1, bitrate);
134*49fe348cSAndroid Build Coastguard Worker }
135*49fe348cSAndroid Build Coastguard Worker
lc3_frame_bytes(int dt_us,int bitrate)136*49fe348cSAndroid Build Coastguard Worker LC3_EXPORT int lc3_frame_bytes(int dt_us, int bitrate)
137*49fe348cSAndroid Build Coastguard Worker {
138*49fe348cSAndroid Build Coastguard Worker return lc3_hr_frame_bytes(false, dt_us, 8000, bitrate);
139*49fe348cSAndroid Build Coastguard Worker }
140*49fe348cSAndroid Build Coastguard Worker
141*49fe348cSAndroid Build Coastguard Worker /**
142*49fe348cSAndroid Build Coastguard Worker * Resolve the bitrate, from the size of frames or frame blocks
143*49fe348cSAndroid Build Coastguard Worker */
lc3_hr_resolve_bitrate(bool hrmode,int dt_us,int sr_hz,int nbytes)144*49fe348cSAndroid Build Coastguard Worker LC3_EXPORT int lc3_hr_resolve_bitrate(
145*49fe348cSAndroid Build Coastguard Worker bool hrmode, int dt_us, int sr_hz, int nbytes)
146*49fe348cSAndroid Build Coastguard Worker {
147*49fe348cSAndroid Build Coastguard Worker enum lc3_dt dt = resolve_dt(dt_us, hrmode);
148*49fe348cSAndroid Build Coastguard Worker enum lc3_srate sr = resolve_srate(sr_hz, hrmode);
149*49fe348cSAndroid Build Coastguard Worker
150*49fe348cSAndroid Build Coastguard Worker if (dt >= LC3_NUM_DT || sr >= LC3_NUM_SRATE || nbytes < 0)
151*49fe348cSAndroid Build Coastguard Worker return -1;
152*49fe348cSAndroid Build Coastguard Worker
153*49fe348cSAndroid Build Coastguard Worker return LC3_MIN(((int64_t)nbytes * 3200 + dt) / (1 + dt), INT_MAX);
154*49fe348cSAndroid Build Coastguard Worker }
155*49fe348cSAndroid Build Coastguard Worker
lc3_resolve_bitrate(int dt_us,int nbytes)156*49fe348cSAndroid Build Coastguard Worker LC3_EXPORT int lc3_resolve_bitrate(int dt_us, int nbytes)
157*49fe348cSAndroid Build Coastguard Worker {
158*49fe348cSAndroid Build Coastguard Worker return lc3_hr_resolve_bitrate(false, dt_us, 8000, nbytes);
159*49fe348cSAndroid Build Coastguard Worker }
160*49fe348cSAndroid Build Coastguard Worker
161*49fe348cSAndroid Build Coastguard Worker /**
162*49fe348cSAndroid Build Coastguard Worker * Return algorithmic delay, as a number of samples
163*49fe348cSAndroid Build Coastguard Worker */
lc3_hr_delay_samples(bool hrmode,int dt_us,int sr_hz)164*49fe348cSAndroid Build Coastguard Worker LC3_EXPORT int lc3_hr_delay_samples(bool hrmode, int dt_us, int sr_hz)
165*49fe348cSAndroid Build Coastguard Worker {
166*49fe348cSAndroid Build Coastguard Worker enum lc3_dt dt = resolve_dt(dt_us, hrmode);
167*49fe348cSAndroid Build Coastguard Worker enum lc3_srate sr = resolve_srate(sr_hz, hrmode);
168*49fe348cSAndroid Build Coastguard Worker
169*49fe348cSAndroid Build Coastguard Worker if (dt >= LC3_NUM_DT || sr >= LC3_NUM_SRATE)
170*49fe348cSAndroid Build Coastguard Worker return -1;
171*49fe348cSAndroid Build Coastguard Worker
172*49fe348cSAndroid Build Coastguard Worker return 2 * lc3_nd(dt, sr) - lc3_ns(dt, sr);
173*49fe348cSAndroid Build Coastguard Worker }
174*49fe348cSAndroid Build Coastguard Worker
lc3_delay_samples(int dt_us,int sr_hz)175*49fe348cSAndroid Build Coastguard Worker LC3_EXPORT int lc3_delay_samples(int dt_us, int sr_hz)
176*49fe348cSAndroid Build Coastguard Worker {
177*49fe348cSAndroid Build Coastguard Worker return lc3_hr_delay_samples(false, dt_us, sr_hz);
178*49fe348cSAndroid Build Coastguard Worker }
179*49fe348cSAndroid Build Coastguard Worker
180*49fe348cSAndroid Build Coastguard Worker
181*49fe348cSAndroid Build Coastguard Worker /* ----------------------------------------------------------------------------
182*49fe348cSAndroid Build Coastguard Worker * Encoder
183*49fe348cSAndroid Build Coastguard Worker * -------------------------------------------------------------------------- */
184*49fe348cSAndroid Build Coastguard Worker
185*49fe348cSAndroid Build Coastguard Worker /**
186*49fe348cSAndroid Build Coastguard Worker * Input PCM Samples from signed 16 bits
187*49fe348cSAndroid Build Coastguard Worker * encoder Encoder state
188*49fe348cSAndroid Build Coastguard Worker * pcm, stride Input PCM samples, and count between two consecutives
189*49fe348cSAndroid Build Coastguard Worker */
load_s16(struct lc3_encoder * encoder,const void * _pcm,int stride)190*49fe348cSAndroid Build Coastguard Worker static void load_s16(
191*49fe348cSAndroid Build Coastguard Worker struct lc3_encoder *encoder, const void *_pcm, int stride)
192*49fe348cSAndroid Build Coastguard Worker {
193*49fe348cSAndroid Build Coastguard Worker const int16_t *pcm = _pcm;
194*49fe348cSAndroid Build Coastguard Worker
195*49fe348cSAndroid Build Coastguard Worker enum lc3_dt dt = encoder->dt;
196*49fe348cSAndroid Build Coastguard Worker enum lc3_srate sr = encoder->sr_pcm;
197*49fe348cSAndroid Build Coastguard Worker
198*49fe348cSAndroid Build Coastguard Worker int16_t *xt = (int16_t *)encoder->x + encoder->xt_off;
199*49fe348cSAndroid Build Coastguard Worker float *xs = encoder->x + encoder->xs_off;
200*49fe348cSAndroid Build Coastguard Worker int ns = lc3_ns(dt, sr);
201*49fe348cSAndroid Build Coastguard Worker
202*49fe348cSAndroid Build Coastguard Worker for (int i = 0; i < ns; i++, pcm += stride)
203*49fe348cSAndroid Build Coastguard Worker xt[i] = *pcm, xs[i] = *pcm;
204*49fe348cSAndroid Build Coastguard Worker }
205*49fe348cSAndroid Build Coastguard Worker
206*49fe348cSAndroid Build Coastguard Worker /**
207*49fe348cSAndroid Build Coastguard Worker * Input PCM Samples from signed 24 bits
208*49fe348cSAndroid Build Coastguard Worker * encoder Encoder state
209*49fe348cSAndroid Build Coastguard Worker * pcm, stride Input PCM samples, and count between two consecutives
210*49fe348cSAndroid Build Coastguard Worker */
load_s24(struct lc3_encoder * encoder,const void * _pcm,int stride)211*49fe348cSAndroid Build Coastguard Worker static void load_s24(
212*49fe348cSAndroid Build Coastguard Worker struct lc3_encoder *encoder, const void *_pcm, int stride)
213*49fe348cSAndroid Build Coastguard Worker {
214*49fe348cSAndroid Build Coastguard Worker const int32_t *pcm = _pcm;
215*49fe348cSAndroid Build Coastguard Worker
216*49fe348cSAndroid Build Coastguard Worker enum lc3_dt dt = encoder->dt;
217*49fe348cSAndroid Build Coastguard Worker enum lc3_srate sr = encoder->sr_pcm;
218*49fe348cSAndroid Build Coastguard Worker
219*49fe348cSAndroid Build Coastguard Worker int16_t *xt = (int16_t *)encoder->x + encoder->xt_off;
220*49fe348cSAndroid Build Coastguard Worker float *xs = encoder->x + encoder->xs_off;
221*49fe348cSAndroid Build Coastguard Worker int ns = lc3_ns(dt, sr);
222*49fe348cSAndroid Build Coastguard Worker
223*49fe348cSAndroid Build Coastguard Worker for (int i = 0; i < ns; i++, pcm += stride) {
224*49fe348cSAndroid Build Coastguard Worker xt[i] = *pcm >> 8;
225*49fe348cSAndroid Build Coastguard Worker xs[i] = lc3_ldexpf(*pcm, -8);
226*49fe348cSAndroid Build Coastguard Worker }
227*49fe348cSAndroid Build Coastguard Worker }
228*49fe348cSAndroid Build Coastguard Worker
229*49fe348cSAndroid Build Coastguard Worker /**
230*49fe348cSAndroid Build Coastguard Worker * Input PCM Samples from signed 24 bits packed
231*49fe348cSAndroid Build Coastguard Worker * encoder Encoder state
232*49fe348cSAndroid Build Coastguard Worker * pcm, stride Input PCM samples, and count between two consecutives
233*49fe348cSAndroid Build Coastguard Worker */
load_s24_3le(struct lc3_encoder * encoder,const void * _pcm,int stride)234*49fe348cSAndroid Build Coastguard Worker static void load_s24_3le(
235*49fe348cSAndroid Build Coastguard Worker struct lc3_encoder *encoder, const void *_pcm, int stride)
236*49fe348cSAndroid Build Coastguard Worker {
237*49fe348cSAndroid Build Coastguard Worker const uint8_t *pcm = _pcm;
238*49fe348cSAndroid Build Coastguard Worker
239*49fe348cSAndroid Build Coastguard Worker enum lc3_dt dt = encoder->dt;
240*49fe348cSAndroid Build Coastguard Worker enum lc3_srate sr = encoder->sr_pcm;
241*49fe348cSAndroid Build Coastguard Worker
242*49fe348cSAndroid Build Coastguard Worker int16_t *xt = (int16_t *)encoder->x + encoder->xt_off;
243*49fe348cSAndroid Build Coastguard Worker float *xs = encoder->x + encoder->xs_off;
244*49fe348cSAndroid Build Coastguard Worker int ns = lc3_ns(dt, sr);
245*49fe348cSAndroid Build Coastguard Worker
246*49fe348cSAndroid Build Coastguard Worker for (int i = 0; i < ns; i++, pcm += 3*stride) {
247*49fe348cSAndroid Build Coastguard Worker int32_t in = ((uint32_t)pcm[0] << 8) |
248*49fe348cSAndroid Build Coastguard Worker ((uint32_t)pcm[1] << 16) |
249*49fe348cSAndroid Build Coastguard Worker ((uint32_t)pcm[2] << 24) ;
250*49fe348cSAndroid Build Coastguard Worker
251*49fe348cSAndroid Build Coastguard Worker xt[i] = in >> 16;
252*49fe348cSAndroid Build Coastguard Worker xs[i] = lc3_ldexpf(in, -16);
253*49fe348cSAndroid Build Coastguard Worker }
254*49fe348cSAndroid Build Coastguard Worker }
255*49fe348cSAndroid Build Coastguard Worker
256*49fe348cSAndroid Build Coastguard Worker /**
257*49fe348cSAndroid Build Coastguard Worker * Input PCM Samples from float 32 bits
258*49fe348cSAndroid Build Coastguard Worker * encoder Encoder state
259*49fe348cSAndroid Build Coastguard Worker * pcm, stride Input PCM samples, and count between two consecutives
260*49fe348cSAndroid Build Coastguard Worker */
load_float(struct lc3_encoder * encoder,const void * _pcm,int stride)261*49fe348cSAndroid Build Coastguard Worker static void load_float(
262*49fe348cSAndroid Build Coastguard Worker struct lc3_encoder *encoder, const void *_pcm, int stride)
263*49fe348cSAndroid Build Coastguard Worker {
264*49fe348cSAndroid Build Coastguard Worker const float *pcm = _pcm;
265*49fe348cSAndroid Build Coastguard Worker
266*49fe348cSAndroid Build Coastguard Worker enum lc3_dt dt = encoder->dt;
267*49fe348cSAndroid Build Coastguard Worker enum lc3_srate sr = encoder->sr_pcm;
268*49fe348cSAndroid Build Coastguard Worker
269*49fe348cSAndroid Build Coastguard Worker int16_t *xt = (int16_t *)encoder->x + encoder->xt_off;
270*49fe348cSAndroid Build Coastguard Worker float *xs = encoder->x + encoder->xs_off;
271*49fe348cSAndroid Build Coastguard Worker int ns = lc3_ns(dt, sr);
272*49fe348cSAndroid Build Coastguard Worker
273*49fe348cSAndroid Build Coastguard Worker for (int i = 0; i < ns; i++, pcm += stride) {
274*49fe348cSAndroid Build Coastguard Worker xs[i] = lc3_ldexpf(*pcm, 15);
275*49fe348cSAndroid Build Coastguard Worker xt[i] = LC3_SAT16((int32_t)xs[i]);
276*49fe348cSAndroid Build Coastguard Worker }
277*49fe348cSAndroid Build Coastguard Worker }
278*49fe348cSAndroid Build Coastguard Worker
279*49fe348cSAndroid Build Coastguard Worker /**
280*49fe348cSAndroid Build Coastguard Worker * Frame Analysis
281*49fe348cSAndroid Build Coastguard Worker * encoder Encoder state
282*49fe348cSAndroid Build Coastguard Worker * nbytes Size in bytes of the frame
283*49fe348cSAndroid Build Coastguard Worker * side Return frame data
284*49fe348cSAndroid Build Coastguard Worker */
analyze(struct lc3_encoder * encoder,int nbytes,struct side_data * side)285*49fe348cSAndroid Build Coastguard Worker static void analyze(struct lc3_encoder *encoder,
286*49fe348cSAndroid Build Coastguard Worker int nbytes, struct side_data *side)
287*49fe348cSAndroid Build Coastguard Worker {
288*49fe348cSAndroid Build Coastguard Worker enum lc3_dt dt = encoder->dt;
289*49fe348cSAndroid Build Coastguard Worker enum lc3_srate sr = encoder->sr;
290*49fe348cSAndroid Build Coastguard Worker enum lc3_srate sr_pcm = encoder->sr_pcm;
291*49fe348cSAndroid Build Coastguard Worker
292*49fe348cSAndroid Build Coastguard Worker int16_t *xt = (int16_t *)encoder->x + encoder->xt_off;
293*49fe348cSAndroid Build Coastguard Worker float *xs = encoder->x + encoder->xs_off;
294*49fe348cSAndroid Build Coastguard Worker int ns = lc3_ns(dt, sr_pcm);
295*49fe348cSAndroid Build Coastguard Worker int nt = lc3_nt(sr_pcm);
296*49fe348cSAndroid Build Coastguard Worker
297*49fe348cSAndroid Build Coastguard Worker float *xd = encoder->x + encoder->xd_off;
298*49fe348cSAndroid Build Coastguard Worker float *xf = xs;
299*49fe348cSAndroid Build Coastguard Worker
300*49fe348cSAndroid Build Coastguard Worker /* --- Temporal --- */
301*49fe348cSAndroid Build Coastguard Worker
302*49fe348cSAndroid Build Coastguard Worker bool att = lc3_attdet_run(dt, sr_pcm, nbytes, &encoder->attdet, xt);
303*49fe348cSAndroid Build Coastguard Worker
304*49fe348cSAndroid Build Coastguard Worker side->pitch_present =
305*49fe348cSAndroid Build Coastguard Worker lc3_ltpf_analyse(dt, sr_pcm, &encoder->ltpf, xt, &side->ltpf);
306*49fe348cSAndroid Build Coastguard Worker
307*49fe348cSAndroid Build Coastguard Worker memmove(xt - nt, xt + (ns-nt), nt * sizeof(*xt));
308*49fe348cSAndroid Build Coastguard Worker
309*49fe348cSAndroid Build Coastguard Worker /* --- Spectral --- */
310*49fe348cSAndroid Build Coastguard Worker
311*49fe348cSAndroid Build Coastguard Worker float e[LC3_MAX_BANDS];
312*49fe348cSAndroid Build Coastguard Worker
313*49fe348cSAndroid Build Coastguard Worker lc3_mdct_forward(dt, sr_pcm, sr, xs, xd, xf);
314*49fe348cSAndroid Build Coastguard Worker
315*49fe348cSAndroid Build Coastguard Worker bool nn_flag = lc3_energy_compute(dt, sr, xf, e);
316*49fe348cSAndroid Build Coastguard Worker if (nn_flag)
317*49fe348cSAndroid Build Coastguard Worker lc3_ltpf_disable(&side->ltpf);
318*49fe348cSAndroid Build Coastguard Worker
319*49fe348cSAndroid Build Coastguard Worker side->bw = lc3_bwdet_run(dt, sr, e);
320*49fe348cSAndroid Build Coastguard Worker
321*49fe348cSAndroid Build Coastguard Worker lc3_sns_analyze(dt, sr, nbytes, e, att, &side->sns, xf, xf);
322*49fe348cSAndroid Build Coastguard Worker
323*49fe348cSAndroid Build Coastguard Worker lc3_tns_analyze(dt, side->bw, nn_flag, nbytes, &side->tns, xf);
324*49fe348cSAndroid Build Coastguard Worker
325*49fe348cSAndroid Build Coastguard Worker lc3_spec_analyze(dt, sr,
326*49fe348cSAndroid Build Coastguard Worker nbytes, side->pitch_present, &side->tns,
327*49fe348cSAndroid Build Coastguard Worker &encoder->spec, xf, &side->spec);
328*49fe348cSAndroid Build Coastguard Worker }
329*49fe348cSAndroid Build Coastguard Worker
330*49fe348cSAndroid Build Coastguard Worker /**
331*49fe348cSAndroid Build Coastguard Worker * Encode bitstream
332*49fe348cSAndroid Build Coastguard Worker * encoder Encoder state
333*49fe348cSAndroid Build Coastguard Worker * side The frame data
334*49fe348cSAndroid Build Coastguard Worker * nbytes Target size of the frame (20 to 400)
335*49fe348cSAndroid Build Coastguard Worker * buffer Output bitstream buffer of `nbytes` size
336*49fe348cSAndroid Build Coastguard Worker */
encode(struct lc3_encoder * encoder,const struct side_data * side,int nbytes,void * buffer)337*49fe348cSAndroid Build Coastguard Worker static void encode(struct lc3_encoder *encoder,
338*49fe348cSAndroid Build Coastguard Worker const struct side_data *side, int nbytes, void *buffer)
339*49fe348cSAndroid Build Coastguard Worker {
340*49fe348cSAndroid Build Coastguard Worker enum lc3_dt dt = encoder->dt;
341*49fe348cSAndroid Build Coastguard Worker enum lc3_srate sr = encoder->sr;
342*49fe348cSAndroid Build Coastguard Worker
343*49fe348cSAndroid Build Coastguard Worker float *xf = encoder->x + encoder->xs_off;
344*49fe348cSAndroid Build Coastguard Worker enum lc3_bandwidth bw = side->bw;
345*49fe348cSAndroid Build Coastguard Worker
346*49fe348cSAndroid Build Coastguard Worker lc3_bits_t bits;
347*49fe348cSAndroid Build Coastguard Worker
348*49fe348cSAndroid Build Coastguard Worker lc3_setup_bits(&bits, LC3_BITS_MODE_WRITE, buffer, nbytes);
349*49fe348cSAndroid Build Coastguard Worker
350*49fe348cSAndroid Build Coastguard Worker lc3_bwdet_put_bw(&bits, sr, bw);
351*49fe348cSAndroid Build Coastguard Worker
352*49fe348cSAndroid Build Coastguard Worker lc3_spec_put_side(&bits, dt, sr, &side->spec);
353*49fe348cSAndroid Build Coastguard Worker
354*49fe348cSAndroid Build Coastguard Worker lc3_tns_put_data(&bits, &side->tns);
355*49fe348cSAndroid Build Coastguard Worker
356*49fe348cSAndroid Build Coastguard Worker lc3_put_bit(&bits, side->pitch_present);
357*49fe348cSAndroid Build Coastguard Worker
358*49fe348cSAndroid Build Coastguard Worker lc3_sns_put_data(&bits, &side->sns);
359*49fe348cSAndroid Build Coastguard Worker
360*49fe348cSAndroid Build Coastguard Worker if (side->pitch_present)
361*49fe348cSAndroid Build Coastguard Worker lc3_ltpf_put_data(&bits, &side->ltpf);
362*49fe348cSAndroid Build Coastguard Worker
363*49fe348cSAndroid Build Coastguard Worker lc3_spec_encode(&bits, dt, sr, bw, nbytes, &side->spec, xf);
364*49fe348cSAndroid Build Coastguard Worker
365*49fe348cSAndroid Build Coastguard Worker lc3_flush_bits(&bits);
366*49fe348cSAndroid Build Coastguard Worker }
367*49fe348cSAndroid Build Coastguard Worker
368*49fe348cSAndroid Build Coastguard Worker /**
369*49fe348cSAndroid Build Coastguard Worker * Return size needed for an encoder
370*49fe348cSAndroid Build Coastguard Worker */
lc3_hr_encoder_size(bool hrmode,int dt_us,int sr_hz)371*49fe348cSAndroid Build Coastguard Worker LC3_EXPORT unsigned lc3_hr_encoder_size(bool hrmode, int dt_us, int sr_hz)
372*49fe348cSAndroid Build Coastguard Worker {
373*49fe348cSAndroid Build Coastguard Worker if (resolve_dt(dt_us, hrmode) >= LC3_NUM_DT ||
374*49fe348cSAndroid Build Coastguard Worker resolve_srate(sr_hz, hrmode) >= LC3_NUM_SRATE)
375*49fe348cSAndroid Build Coastguard Worker return 0;
376*49fe348cSAndroid Build Coastguard Worker
377*49fe348cSAndroid Build Coastguard Worker return sizeof(struct lc3_encoder) +
378*49fe348cSAndroid Build Coastguard Worker (LC3_ENCODER_BUFFER_COUNT(dt_us, sr_hz)-1) * sizeof(float);
379*49fe348cSAndroid Build Coastguard Worker }
380*49fe348cSAndroid Build Coastguard Worker
lc3_encoder_size(int dt_us,int sr_hz)381*49fe348cSAndroid Build Coastguard Worker LC3_EXPORT unsigned lc3_encoder_size(int dt_us, int sr_hz)
382*49fe348cSAndroid Build Coastguard Worker {
383*49fe348cSAndroid Build Coastguard Worker return lc3_hr_encoder_size(false, dt_us, sr_hz);
384*49fe348cSAndroid Build Coastguard Worker }
385*49fe348cSAndroid Build Coastguard Worker
386*49fe348cSAndroid Build Coastguard Worker /**
387*49fe348cSAndroid Build Coastguard Worker * Setup encoder
388*49fe348cSAndroid Build Coastguard Worker */
lc3_hr_setup_encoder(bool hrmode,int dt_us,int sr_hz,int sr_pcm_hz,void * mem)389*49fe348cSAndroid Build Coastguard Worker LC3_EXPORT struct lc3_encoder *lc3_hr_setup_encoder(
390*49fe348cSAndroid Build Coastguard Worker bool hrmode, int dt_us, int sr_hz, int sr_pcm_hz, void *mem)
391*49fe348cSAndroid Build Coastguard Worker {
392*49fe348cSAndroid Build Coastguard Worker if (sr_pcm_hz <= 0)
393*49fe348cSAndroid Build Coastguard Worker sr_pcm_hz = sr_hz;
394*49fe348cSAndroid Build Coastguard Worker
395*49fe348cSAndroid Build Coastguard Worker enum lc3_dt dt = resolve_dt(dt_us, hrmode);
396*49fe348cSAndroid Build Coastguard Worker enum lc3_srate sr = resolve_srate(sr_hz, hrmode);
397*49fe348cSAndroid Build Coastguard Worker enum lc3_srate sr_pcm = resolve_srate(sr_pcm_hz, hrmode);
398*49fe348cSAndroid Build Coastguard Worker
399*49fe348cSAndroid Build Coastguard Worker if (dt >= LC3_NUM_DT || sr_pcm >= LC3_NUM_SRATE || sr > sr_pcm || !mem)
400*49fe348cSAndroid Build Coastguard Worker return NULL;
401*49fe348cSAndroid Build Coastguard Worker
402*49fe348cSAndroid Build Coastguard Worker struct lc3_encoder *encoder = mem;
403*49fe348cSAndroid Build Coastguard Worker int ns = lc3_ns(dt, sr_pcm);
404*49fe348cSAndroid Build Coastguard Worker int nt = lc3_nt(sr_pcm);
405*49fe348cSAndroid Build Coastguard Worker
406*49fe348cSAndroid Build Coastguard Worker *encoder = (struct lc3_encoder){
407*49fe348cSAndroid Build Coastguard Worker .dt = dt, .sr = sr,
408*49fe348cSAndroid Build Coastguard Worker .sr_pcm = sr_pcm,
409*49fe348cSAndroid Build Coastguard Worker
410*49fe348cSAndroid Build Coastguard Worker .xt_off = nt,
411*49fe348cSAndroid Build Coastguard Worker .xs_off = (nt + ns) / 2,
412*49fe348cSAndroid Build Coastguard Worker .xd_off = (nt + ns) / 2 + ns,
413*49fe348cSAndroid Build Coastguard Worker };
414*49fe348cSAndroid Build Coastguard Worker
415*49fe348cSAndroid Build Coastguard Worker memset(encoder->x, 0,
416*49fe348cSAndroid Build Coastguard Worker LC3_ENCODER_BUFFER_COUNT(dt_us, sr_pcm_hz) * sizeof(float));
417*49fe348cSAndroid Build Coastguard Worker
418*49fe348cSAndroid Build Coastguard Worker return encoder;
419*49fe348cSAndroid Build Coastguard Worker }
420*49fe348cSAndroid Build Coastguard Worker
lc3_setup_encoder(int dt_us,int sr_hz,int sr_pcm_hz,void * mem)421*49fe348cSAndroid Build Coastguard Worker LC3_EXPORT struct lc3_encoder *lc3_setup_encoder(
422*49fe348cSAndroid Build Coastguard Worker int dt_us, int sr_hz, int sr_pcm_hz, void *mem)
423*49fe348cSAndroid Build Coastguard Worker {
424*49fe348cSAndroid Build Coastguard Worker return lc3_hr_setup_encoder(false, dt_us, sr_hz, sr_pcm_hz, mem);
425*49fe348cSAndroid Build Coastguard Worker }
426*49fe348cSAndroid Build Coastguard Worker
427*49fe348cSAndroid Build Coastguard Worker /**
428*49fe348cSAndroid Build Coastguard Worker * Encode a frame
429*49fe348cSAndroid Build Coastguard Worker */
lc3_encode(struct lc3_encoder * encoder,enum lc3_pcm_format fmt,const void * pcm,int stride,int nbytes,void * out)430*49fe348cSAndroid Build Coastguard Worker LC3_EXPORT int lc3_encode(struct lc3_encoder *encoder,
431*49fe348cSAndroid Build Coastguard Worker enum lc3_pcm_format fmt, const void *pcm, int stride, int nbytes, void *out)
432*49fe348cSAndroid Build Coastguard Worker {
433*49fe348cSAndroid Build Coastguard Worker static void (* const load[])(struct lc3_encoder *, const void *, int) = {
434*49fe348cSAndroid Build Coastguard Worker [LC3_PCM_FORMAT_S16 ] = load_s16,
435*49fe348cSAndroid Build Coastguard Worker [LC3_PCM_FORMAT_S24 ] = load_s24,
436*49fe348cSAndroid Build Coastguard Worker [LC3_PCM_FORMAT_S24_3LE] = load_s24_3le,
437*49fe348cSAndroid Build Coastguard Worker [LC3_PCM_FORMAT_FLOAT ] = load_float,
438*49fe348cSAndroid Build Coastguard Worker };
439*49fe348cSAndroid Build Coastguard Worker
440*49fe348cSAndroid Build Coastguard Worker /* --- Check parameters --- */
441*49fe348cSAndroid Build Coastguard Worker
442*49fe348cSAndroid Build Coastguard Worker if (!encoder || nbytes < lc3_min_frame_bytes(encoder->dt, encoder->sr)
443*49fe348cSAndroid Build Coastguard Worker || nbytes > lc3_max_frame_bytes(encoder->dt, encoder->sr))
444*49fe348cSAndroid Build Coastguard Worker return -1;
445*49fe348cSAndroid Build Coastguard Worker
446*49fe348cSAndroid Build Coastguard Worker /* --- Processing --- */
447*49fe348cSAndroid Build Coastguard Worker
448*49fe348cSAndroid Build Coastguard Worker struct side_data side;
449*49fe348cSAndroid Build Coastguard Worker
450*49fe348cSAndroid Build Coastguard Worker load[fmt](encoder, pcm, stride);
451*49fe348cSAndroid Build Coastguard Worker
452*49fe348cSAndroid Build Coastguard Worker analyze(encoder, nbytes, &side);
453*49fe348cSAndroid Build Coastguard Worker
454*49fe348cSAndroid Build Coastguard Worker encode(encoder, &side, nbytes, out);
455*49fe348cSAndroid Build Coastguard Worker
456*49fe348cSAndroid Build Coastguard Worker return 0;
457*49fe348cSAndroid Build Coastguard Worker }
458*49fe348cSAndroid Build Coastguard Worker
459*49fe348cSAndroid Build Coastguard Worker
460*49fe348cSAndroid Build Coastguard Worker /* ----------------------------------------------------------------------------
461*49fe348cSAndroid Build Coastguard Worker * Decoder
462*49fe348cSAndroid Build Coastguard Worker * -------------------------------------------------------------------------- */
463*49fe348cSAndroid Build Coastguard Worker
464*49fe348cSAndroid Build Coastguard Worker /**
465*49fe348cSAndroid Build Coastguard Worker * Output PCM Samples to signed 16 bits
466*49fe348cSAndroid Build Coastguard Worker * decoder Decoder state
467*49fe348cSAndroid Build Coastguard Worker * pcm, stride Output PCM samples, and count between two consecutives
468*49fe348cSAndroid Build Coastguard Worker */
store_s16(struct lc3_decoder * decoder,void * _pcm,int stride)469*49fe348cSAndroid Build Coastguard Worker static void store_s16(
470*49fe348cSAndroid Build Coastguard Worker struct lc3_decoder *decoder, void *_pcm, int stride)
471*49fe348cSAndroid Build Coastguard Worker {
472*49fe348cSAndroid Build Coastguard Worker int16_t *pcm = _pcm;
473*49fe348cSAndroid Build Coastguard Worker
474*49fe348cSAndroid Build Coastguard Worker enum lc3_dt dt = decoder->dt;
475*49fe348cSAndroid Build Coastguard Worker enum lc3_srate sr = decoder->sr_pcm;
476*49fe348cSAndroid Build Coastguard Worker
477*49fe348cSAndroid Build Coastguard Worker float *xs = decoder->x + decoder->xs_off;
478*49fe348cSAndroid Build Coastguard Worker int ns = lc3_ns(dt, sr);
479*49fe348cSAndroid Build Coastguard Worker
480*49fe348cSAndroid Build Coastguard Worker for ( ; ns > 0; ns--, xs++, pcm += stride) {
481*49fe348cSAndroid Build Coastguard Worker int32_t s = *xs >= 0 ? (int)(*xs + 0.5f) : (int)(*xs - 0.5f);
482*49fe348cSAndroid Build Coastguard Worker *pcm = LC3_SAT16(s);
483*49fe348cSAndroid Build Coastguard Worker }
484*49fe348cSAndroid Build Coastguard Worker }
485*49fe348cSAndroid Build Coastguard Worker
486*49fe348cSAndroid Build Coastguard Worker /**
487*49fe348cSAndroid Build Coastguard Worker * Output PCM Samples to signed 24 bits
488*49fe348cSAndroid Build Coastguard Worker * decoder Decoder state
489*49fe348cSAndroid Build Coastguard Worker * pcm, stride Output PCM samples, and count between two consecutives
490*49fe348cSAndroid Build Coastguard Worker */
store_s24(struct lc3_decoder * decoder,void * _pcm,int stride)491*49fe348cSAndroid Build Coastguard Worker static void store_s24(
492*49fe348cSAndroid Build Coastguard Worker struct lc3_decoder *decoder, void *_pcm, int stride)
493*49fe348cSAndroid Build Coastguard Worker {
494*49fe348cSAndroid Build Coastguard Worker int32_t *pcm = _pcm;
495*49fe348cSAndroid Build Coastguard Worker
496*49fe348cSAndroid Build Coastguard Worker enum lc3_dt dt = decoder->dt;
497*49fe348cSAndroid Build Coastguard Worker enum lc3_srate sr = decoder->sr_pcm;
498*49fe348cSAndroid Build Coastguard Worker
499*49fe348cSAndroid Build Coastguard Worker float *xs = decoder->x + decoder->xs_off;
500*49fe348cSAndroid Build Coastguard Worker int ns = lc3_ns(dt, sr);
501*49fe348cSAndroid Build Coastguard Worker
502*49fe348cSAndroid Build Coastguard Worker for ( ; ns > 0; ns--, xs++, pcm += stride) {
503*49fe348cSAndroid Build Coastguard Worker int32_t s = *xs >= 0 ? (int32_t)(lc3_ldexpf(*xs, 8) + 0.5f)
504*49fe348cSAndroid Build Coastguard Worker : (int32_t)(lc3_ldexpf(*xs, 8) - 0.5f);
505*49fe348cSAndroid Build Coastguard Worker *pcm = LC3_SAT24(s);
506*49fe348cSAndroid Build Coastguard Worker }
507*49fe348cSAndroid Build Coastguard Worker }
508*49fe348cSAndroid Build Coastguard Worker
509*49fe348cSAndroid Build Coastguard Worker /**
510*49fe348cSAndroid Build Coastguard Worker * Output PCM Samples to signed 24 bits packed
511*49fe348cSAndroid Build Coastguard Worker * decoder Decoder state
512*49fe348cSAndroid Build Coastguard Worker * pcm, stride Output PCM samples, and count between two consecutives
513*49fe348cSAndroid Build Coastguard Worker */
store_s24_3le(struct lc3_decoder * decoder,void * _pcm,int stride)514*49fe348cSAndroid Build Coastguard Worker static void store_s24_3le(
515*49fe348cSAndroid Build Coastguard Worker struct lc3_decoder *decoder, void *_pcm, int stride)
516*49fe348cSAndroid Build Coastguard Worker {
517*49fe348cSAndroid Build Coastguard Worker uint8_t *pcm = _pcm;
518*49fe348cSAndroid Build Coastguard Worker
519*49fe348cSAndroid Build Coastguard Worker enum lc3_dt dt = decoder->dt;
520*49fe348cSAndroid Build Coastguard Worker enum lc3_srate sr = decoder->sr_pcm;
521*49fe348cSAndroid Build Coastguard Worker
522*49fe348cSAndroid Build Coastguard Worker float *xs = decoder->x + decoder->xs_off;
523*49fe348cSAndroid Build Coastguard Worker int ns = lc3_ns(dt, sr);
524*49fe348cSAndroid Build Coastguard Worker
525*49fe348cSAndroid Build Coastguard Worker for ( ; ns > 0; ns--, xs++, pcm += 3*stride) {
526*49fe348cSAndroid Build Coastguard Worker int32_t s = *xs >= 0 ? (int32_t)(lc3_ldexpf(*xs, 8) + 0.5f)
527*49fe348cSAndroid Build Coastguard Worker : (int32_t)(lc3_ldexpf(*xs, 8) - 0.5f);
528*49fe348cSAndroid Build Coastguard Worker
529*49fe348cSAndroid Build Coastguard Worker s = LC3_SAT24(s);
530*49fe348cSAndroid Build Coastguard Worker pcm[0] = (s >> 0) & 0xff;
531*49fe348cSAndroid Build Coastguard Worker pcm[1] = (s >> 8) & 0xff;
532*49fe348cSAndroid Build Coastguard Worker pcm[2] = (s >> 16) & 0xff;
533*49fe348cSAndroid Build Coastguard Worker }
534*49fe348cSAndroid Build Coastguard Worker }
535*49fe348cSAndroid Build Coastguard Worker
536*49fe348cSAndroid Build Coastguard Worker /**
537*49fe348cSAndroid Build Coastguard Worker * Output PCM Samples to float 32 bits
538*49fe348cSAndroid Build Coastguard Worker * decoder Decoder state
539*49fe348cSAndroid Build Coastguard Worker * pcm, stride Output PCM samples, and count between two consecutives
540*49fe348cSAndroid Build Coastguard Worker */
store_float(struct lc3_decoder * decoder,void * _pcm,int stride)541*49fe348cSAndroid Build Coastguard Worker static void store_float(
542*49fe348cSAndroid Build Coastguard Worker struct lc3_decoder *decoder, void *_pcm, int stride)
543*49fe348cSAndroid Build Coastguard Worker {
544*49fe348cSAndroid Build Coastguard Worker float *pcm = _pcm;
545*49fe348cSAndroid Build Coastguard Worker
546*49fe348cSAndroid Build Coastguard Worker enum lc3_dt dt = decoder->dt;
547*49fe348cSAndroid Build Coastguard Worker enum lc3_srate sr = decoder->sr_pcm;
548*49fe348cSAndroid Build Coastguard Worker
549*49fe348cSAndroid Build Coastguard Worker float *xs = decoder->x + decoder->xs_off;
550*49fe348cSAndroid Build Coastguard Worker int ns = lc3_ns(dt, sr);
551*49fe348cSAndroid Build Coastguard Worker
552*49fe348cSAndroid Build Coastguard Worker for ( ; ns > 0; ns--, xs++, pcm += stride) {
553*49fe348cSAndroid Build Coastguard Worker float s = lc3_ldexpf(*xs, -15);
554*49fe348cSAndroid Build Coastguard Worker *pcm = fminf(fmaxf(s, -1.f), 1.f);
555*49fe348cSAndroid Build Coastguard Worker }
556*49fe348cSAndroid Build Coastguard Worker }
557*49fe348cSAndroid Build Coastguard Worker
558*49fe348cSAndroid Build Coastguard Worker /**
559*49fe348cSAndroid Build Coastguard Worker * Decode bitstream
560*49fe348cSAndroid Build Coastguard Worker * decoder Decoder state
561*49fe348cSAndroid Build Coastguard Worker * data, nbytes Input bitstream buffer
562*49fe348cSAndroid Build Coastguard Worker * side Return the side data
563*49fe348cSAndroid Build Coastguard Worker * return 0: Ok < 0: Bitsream error detected
564*49fe348cSAndroid Build Coastguard Worker */
decode(struct lc3_decoder * decoder,const void * data,int nbytes,struct side_data * side)565*49fe348cSAndroid Build Coastguard Worker static int decode(struct lc3_decoder *decoder,
566*49fe348cSAndroid Build Coastguard Worker const void *data, int nbytes, struct side_data *side)
567*49fe348cSAndroid Build Coastguard Worker {
568*49fe348cSAndroid Build Coastguard Worker enum lc3_dt dt = decoder->dt;
569*49fe348cSAndroid Build Coastguard Worker enum lc3_srate sr = decoder->sr;
570*49fe348cSAndroid Build Coastguard Worker
571*49fe348cSAndroid Build Coastguard Worker float *xf = decoder->x + decoder->xs_off;
572*49fe348cSAndroid Build Coastguard Worker int ns = lc3_ns(dt, sr);
573*49fe348cSAndroid Build Coastguard Worker int ne = lc3_ne(dt, sr);
574*49fe348cSAndroid Build Coastguard Worker
575*49fe348cSAndroid Build Coastguard Worker lc3_bits_t bits;
576*49fe348cSAndroid Build Coastguard Worker int ret = 0;
577*49fe348cSAndroid Build Coastguard Worker
578*49fe348cSAndroid Build Coastguard Worker lc3_setup_bits(&bits, LC3_BITS_MODE_READ, (void *)data, nbytes);
579*49fe348cSAndroid Build Coastguard Worker
580*49fe348cSAndroid Build Coastguard Worker if ((ret = lc3_bwdet_get_bw(&bits, sr, &side->bw)) < 0)
581*49fe348cSAndroid Build Coastguard Worker return ret;
582*49fe348cSAndroid Build Coastguard Worker
583*49fe348cSAndroid Build Coastguard Worker if ((ret = lc3_spec_get_side(&bits, dt, sr, &side->spec)) < 0)
584*49fe348cSAndroid Build Coastguard Worker return ret;
585*49fe348cSAndroid Build Coastguard Worker
586*49fe348cSAndroid Build Coastguard Worker if ((ret = lc3_tns_get_data(&bits, dt, side->bw, nbytes, &side->tns)) < 0)
587*49fe348cSAndroid Build Coastguard Worker return ret;
588*49fe348cSAndroid Build Coastguard Worker
589*49fe348cSAndroid Build Coastguard Worker side->pitch_present = lc3_get_bit(&bits);
590*49fe348cSAndroid Build Coastguard Worker
591*49fe348cSAndroid Build Coastguard Worker if ((ret = lc3_sns_get_data(&bits, &side->sns)) < 0)
592*49fe348cSAndroid Build Coastguard Worker return ret;
593*49fe348cSAndroid Build Coastguard Worker
594*49fe348cSAndroid Build Coastguard Worker if (side->pitch_present)
595*49fe348cSAndroid Build Coastguard Worker lc3_ltpf_get_data(&bits, &side->ltpf);
596*49fe348cSAndroid Build Coastguard Worker
597*49fe348cSAndroid Build Coastguard Worker if ((ret = lc3_spec_decode(&bits, dt, sr,
598*49fe348cSAndroid Build Coastguard Worker side->bw, nbytes, &side->spec, xf)) < 0)
599*49fe348cSAndroid Build Coastguard Worker return ret;
600*49fe348cSAndroid Build Coastguard Worker
601*49fe348cSAndroid Build Coastguard Worker memset(xf + ne, 0, (ns - ne) * sizeof(float));
602*49fe348cSAndroid Build Coastguard Worker
603*49fe348cSAndroid Build Coastguard Worker return lc3_check_bits(&bits);
604*49fe348cSAndroid Build Coastguard Worker }
605*49fe348cSAndroid Build Coastguard Worker
606*49fe348cSAndroid Build Coastguard Worker /**
607*49fe348cSAndroid Build Coastguard Worker * Frame synthesis
608*49fe348cSAndroid Build Coastguard Worker * decoder Decoder state
609*49fe348cSAndroid Build Coastguard Worker * side Frame data, NULL performs PLC
610*49fe348cSAndroid Build Coastguard Worker * nbytes Size in bytes of the frame
611*49fe348cSAndroid Build Coastguard Worker */
synthesize(struct lc3_decoder * decoder,const struct side_data * side,int nbytes)612*49fe348cSAndroid Build Coastguard Worker static void synthesize(struct lc3_decoder *decoder,
613*49fe348cSAndroid Build Coastguard Worker const struct side_data *side, int nbytes)
614*49fe348cSAndroid Build Coastguard Worker {
615*49fe348cSAndroid Build Coastguard Worker enum lc3_dt dt = decoder->dt;
616*49fe348cSAndroid Build Coastguard Worker enum lc3_srate sr = decoder->sr;
617*49fe348cSAndroid Build Coastguard Worker enum lc3_srate sr_pcm = decoder->sr_pcm;
618*49fe348cSAndroid Build Coastguard Worker
619*49fe348cSAndroid Build Coastguard Worker float *xf = decoder->x + decoder->xs_off;
620*49fe348cSAndroid Build Coastguard Worker int ns = lc3_ns(dt, sr_pcm);
621*49fe348cSAndroid Build Coastguard Worker int ne = lc3_ne(dt, sr);
622*49fe348cSAndroid Build Coastguard Worker
623*49fe348cSAndroid Build Coastguard Worker float *xg = decoder->x + decoder->xg_off;
624*49fe348cSAndroid Build Coastguard Worker float *xs = xf;
625*49fe348cSAndroid Build Coastguard Worker
626*49fe348cSAndroid Build Coastguard Worker float *xd = decoder->x + decoder->xd_off;
627*49fe348cSAndroid Build Coastguard Worker float *xh = decoder->x + decoder->xh_off;
628*49fe348cSAndroid Build Coastguard Worker
629*49fe348cSAndroid Build Coastguard Worker if (side) {
630*49fe348cSAndroid Build Coastguard Worker enum lc3_bandwidth bw = side->bw;
631*49fe348cSAndroid Build Coastguard Worker
632*49fe348cSAndroid Build Coastguard Worker lc3_plc_suspend(&decoder->plc);
633*49fe348cSAndroid Build Coastguard Worker
634*49fe348cSAndroid Build Coastguard Worker lc3_tns_synthesize(dt, bw, &side->tns, xf);
635*49fe348cSAndroid Build Coastguard Worker
636*49fe348cSAndroid Build Coastguard Worker lc3_sns_synthesize(dt, sr, &side->sns, xf, xg);
637*49fe348cSAndroid Build Coastguard Worker
638*49fe348cSAndroid Build Coastguard Worker lc3_mdct_inverse(dt, sr_pcm, sr, xg, xd, xs);
639*49fe348cSAndroid Build Coastguard Worker
640*49fe348cSAndroid Build Coastguard Worker } else {
641*49fe348cSAndroid Build Coastguard Worker lc3_plc_synthesize(dt, sr, &decoder->plc, xg, xf);
642*49fe348cSAndroid Build Coastguard Worker
643*49fe348cSAndroid Build Coastguard Worker memset(xf + ne, 0, (ns - ne) * sizeof(float));
644*49fe348cSAndroid Build Coastguard Worker
645*49fe348cSAndroid Build Coastguard Worker lc3_mdct_inverse(dt, sr_pcm, sr, xf, xd, xs);
646*49fe348cSAndroid Build Coastguard Worker }
647*49fe348cSAndroid Build Coastguard Worker
648*49fe348cSAndroid Build Coastguard Worker if (!lc3_hr(sr))
649*49fe348cSAndroid Build Coastguard Worker lc3_ltpf_synthesize(dt, sr_pcm, nbytes, &decoder->ltpf,
650*49fe348cSAndroid Build Coastguard Worker side && side->pitch_present ? &side->ltpf : NULL, xh, xs);
651*49fe348cSAndroid Build Coastguard Worker }
652*49fe348cSAndroid Build Coastguard Worker
653*49fe348cSAndroid Build Coastguard Worker /**
654*49fe348cSAndroid Build Coastguard Worker * Update decoder state on decoding completion
655*49fe348cSAndroid Build Coastguard Worker * decoder Decoder state
656*49fe348cSAndroid Build Coastguard Worker */
complete(struct lc3_decoder * decoder)657*49fe348cSAndroid Build Coastguard Worker static void complete(struct lc3_decoder *decoder)
658*49fe348cSAndroid Build Coastguard Worker {
659*49fe348cSAndroid Build Coastguard Worker enum lc3_dt dt = decoder->dt;
660*49fe348cSAndroid Build Coastguard Worker enum lc3_srate sr_pcm = decoder->sr_pcm;
661*49fe348cSAndroid Build Coastguard Worker int nh = lc3_nh(dt, sr_pcm);
662*49fe348cSAndroid Build Coastguard Worker int ns = lc3_ns(dt, sr_pcm);
663*49fe348cSAndroid Build Coastguard Worker
664*49fe348cSAndroid Build Coastguard Worker decoder->xs_off = decoder->xs_off - decoder->xh_off < nh ?
665*49fe348cSAndroid Build Coastguard Worker decoder->xs_off + ns : decoder->xh_off;
666*49fe348cSAndroid Build Coastguard Worker }
667*49fe348cSAndroid Build Coastguard Worker
668*49fe348cSAndroid Build Coastguard Worker /**
669*49fe348cSAndroid Build Coastguard Worker * Return size needed for a decoder
670*49fe348cSAndroid Build Coastguard Worker */
lc3_hr_decoder_size(bool hrmode,int dt_us,int sr_hz)671*49fe348cSAndroid Build Coastguard Worker LC3_EXPORT unsigned lc3_hr_decoder_size(bool hrmode, int dt_us, int sr_hz)
672*49fe348cSAndroid Build Coastguard Worker {
673*49fe348cSAndroid Build Coastguard Worker if (resolve_dt(dt_us, hrmode) >= LC3_NUM_DT ||
674*49fe348cSAndroid Build Coastguard Worker resolve_srate(sr_hz, hrmode) >= LC3_NUM_SRATE)
675*49fe348cSAndroid Build Coastguard Worker return 0;
676*49fe348cSAndroid Build Coastguard Worker
677*49fe348cSAndroid Build Coastguard Worker return sizeof(struct lc3_decoder) +
678*49fe348cSAndroid Build Coastguard Worker (LC3_DECODER_BUFFER_COUNT(dt_us, sr_hz)-1) * sizeof(float);
679*49fe348cSAndroid Build Coastguard Worker }
680*49fe348cSAndroid Build Coastguard Worker
lc3_decoder_size(int dt_us,int sr_hz)681*49fe348cSAndroid Build Coastguard Worker LC3_EXPORT unsigned lc3_decoder_size(int dt_us, int sr_hz)
682*49fe348cSAndroid Build Coastguard Worker {
683*49fe348cSAndroid Build Coastguard Worker return lc3_hr_decoder_size(false, dt_us, sr_hz);
684*49fe348cSAndroid Build Coastguard Worker }
685*49fe348cSAndroid Build Coastguard Worker
686*49fe348cSAndroid Build Coastguard Worker /**
687*49fe348cSAndroid Build Coastguard Worker * Setup decoder
688*49fe348cSAndroid Build Coastguard Worker */
lc3_hr_setup_decoder(bool hrmode,int dt_us,int sr_hz,int sr_pcm_hz,void * mem)689*49fe348cSAndroid Build Coastguard Worker LC3_EXPORT struct lc3_decoder *lc3_hr_setup_decoder(
690*49fe348cSAndroid Build Coastguard Worker bool hrmode, int dt_us, int sr_hz, int sr_pcm_hz, void *mem)
691*49fe348cSAndroid Build Coastguard Worker {
692*49fe348cSAndroid Build Coastguard Worker if (sr_pcm_hz <= 0)
693*49fe348cSAndroid Build Coastguard Worker sr_pcm_hz = sr_hz;
694*49fe348cSAndroid Build Coastguard Worker
695*49fe348cSAndroid Build Coastguard Worker enum lc3_dt dt = resolve_dt(dt_us, hrmode);
696*49fe348cSAndroid Build Coastguard Worker enum lc3_srate sr = resolve_srate(sr_hz, hrmode);
697*49fe348cSAndroid Build Coastguard Worker enum lc3_srate sr_pcm = resolve_srate(sr_pcm_hz, hrmode);
698*49fe348cSAndroid Build Coastguard Worker
699*49fe348cSAndroid Build Coastguard Worker if (dt >= LC3_NUM_DT || sr_pcm >= LC3_NUM_SRATE || sr > sr_pcm || !mem)
700*49fe348cSAndroid Build Coastguard Worker return NULL;
701*49fe348cSAndroid Build Coastguard Worker
702*49fe348cSAndroid Build Coastguard Worker struct lc3_decoder *decoder = mem;
703*49fe348cSAndroid Build Coastguard Worker int nh = lc3_nh(dt, sr_pcm);
704*49fe348cSAndroid Build Coastguard Worker int ns = lc3_ns(dt, sr_pcm);
705*49fe348cSAndroid Build Coastguard Worker int nd = lc3_nd(dt, sr_pcm);
706*49fe348cSAndroid Build Coastguard Worker
707*49fe348cSAndroid Build Coastguard Worker *decoder = (struct lc3_decoder){
708*49fe348cSAndroid Build Coastguard Worker .dt = dt, .sr = sr,
709*49fe348cSAndroid Build Coastguard Worker .sr_pcm = sr_pcm,
710*49fe348cSAndroid Build Coastguard Worker
711*49fe348cSAndroid Build Coastguard Worker .xh_off = 0,
712*49fe348cSAndroid Build Coastguard Worker .xs_off = nh,
713*49fe348cSAndroid Build Coastguard Worker .xd_off = nh + ns,
714*49fe348cSAndroid Build Coastguard Worker .xg_off = nh + ns + nd,
715*49fe348cSAndroid Build Coastguard Worker };
716*49fe348cSAndroid Build Coastguard Worker
717*49fe348cSAndroid Build Coastguard Worker lc3_plc_reset(&decoder->plc);
718*49fe348cSAndroid Build Coastguard Worker
719*49fe348cSAndroid Build Coastguard Worker memset(decoder->x, 0,
720*49fe348cSAndroid Build Coastguard Worker LC3_DECODER_BUFFER_COUNT(dt_us, sr_pcm_hz) * sizeof(float));
721*49fe348cSAndroid Build Coastguard Worker
722*49fe348cSAndroid Build Coastguard Worker return decoder;
723*49fe348cSAndroid Build Coastguard Worker }
724*49fe348cSAndroid Build Coastguard Worker
lc3_setup_decoder(int dt_us,int sr_hz,int sr_pcm_hz,void * mem)725*49fe348cSAndroid Build Coastguard Worker LC3_EXPORT struct lc3_decoder *lc3_setup_decoder(
726*49fe348cSAndroid Build Coastguard Worker int dt_us, int sr_hz, int sr_pcm_hz, void *mem)
727*49fe348cSAndroid Build Coastguard Worker {
728*49fe348cSAndroid Build Coastguard Worker return lc3_hr_setup_decoder(false, dt_us, sr_hz, sr_pcm_hz, mem);
729*49fe348cSAndroid Build Coastguard Worker }
730*49fe348cSAndroid Build Coastguard Worker
731*49fe348cSAndroid Build Coastguard Worker /**
732*49fe348cSAndroid Build Coastguard Worker * Decode a frame
733*49fe348cSAndroid Build Coastguard Worker */
lc3_decode(struct lc3_decoder * decoder,const void * in,int nbytes,enum lc3_pcm_format fmt,void * pcm,int stride)734*49fe348cSAndroid Build Coastguard Worker LC3_EXPORT int lc3_decode(struct lc3_decoder *decoder,
735*49fe348cSAndroid Build Coastguard Worker const void *in, int nbytes, enum lc3_pcm_format fmt, void *pcm, int stride)
736*49fe348cSAndroid Build Coastguard Worker {
737*49fe348cSAndroid Build Coastguard Worker static void (* const store[])(struct lc3_decoder *, void *, int) = {
738*49fe348cSAndroid Build Coastguard Worker [LC3_PCM_FORMAT_S16 ] = store_s16,
739*49fe348cSAndroid Build Coastguard Worker [LC3_PCM_FORMAT_S24 ] = store_s24,
740*49fe348cSAndroid Build Coastguard Worker [LC3_PCM_FORMAT_S24_3LE] = store_s24_3le,
741*49fe348cSAndroid Build Coastguard Worker [LC3_PCM_FORMAT_FLOAT ] = store_float,
742*49fe348cSAndroid Build Coastguard Worker };
743*49fe348cSAndroid Build Coastguard Worker
744*49fe348cSAndroid Build Coastguard Worker /* --- Check parameters --- */
745*49fe348cSAndroid Build Coastguard Worker
746*49fe348cSAndroid Build Coastguard Worker if (!decoder)
747*49fe348cSAndroid Build Coastguard Worker return -1;
748*49fe348cSAndroid Build Coastguard Worker
749*49fe348cSAndroid Build Coastguard Worker if (in && (nbytes < LC3_MIN_FRAME_BYTES ||
750*49fe348cSAndroid Build Coastguard Worker nbytes > lc3_max_frame_bytes(decoder->dt, decoder->sr) ))
751*49fe348cSAndroid Build Coastguard Worker return -1;
752*49fe348cSAndroid Build Coastguard Worker
753*49fe348cSAndroid Build Coastguard Worker /* --- Processing --- */
754*49fe348cSAndroid Build Coastguard Worker
755*49fe348cSAndroid Build Coastguard Worker struct side_data side;
756*49fe348cSAndroid Build Coastguard Worker
757*49fe348cSAndroid Build Coastguard Worker int ret = !in || (decode(decoder, in, nbytes, &side) < 0);
758*49fe348cSAndroid Build Coastguard Worker
759*49fe348cSAndroid Build Coastguard Worker synthesize(decoder, ret ? NULL : &side, nbytes);
760*49fe348cSAndroid Build Coastguard Worker
761*49fe348cSAndroid Build Coastguard Worker store[fmt](decoder, pcm, stride);
762*49fe348cSAndroid Build Coastguard Worker
763*49fe348cSAndroid Build Coastguard Worker complete(decoder);
764*49fe348cSAndroid Build Coastguard Worker
765*49fe348cSAndroid Build Coastguard Worker return ret;
766*49fe348cSAndroid Build Coastguard Worker }
767