blob: 9ce234695ce0d314279022861df15caba5190d83 [file] [log] [blame]
Jean-Marc Valin8b2ff0d2009-10-17 21:40:10 -04001/* Copyright (c) 2007-2008 CSIRO
Jean-Marc Valin190b7822010-08-27 15:03:20 -04002 Copyright (c) 2007-2010 Xiph.Org Foundation
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04003 Copyright (c) 2008 Gregory Maxwell
Jean-Marc Valin8b2ff0d2009-10-17 21:40:10 -04004 Written by Jean-Marc Valin and Gregory Maxwell */
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +11005/*
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04009
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +110010 - Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
Gregory Maxwell71d39ad2011-07-30 00:00:29 -040012
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +110013 - Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
Gregory Maxwell71d39ad2011-07-30 00:00:29 -040016
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +110017 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
Jean-Marc Valincb05e7c2012-04-20 16:40:24 -040020 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +110022 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*/
29
Jean-Marc Valin02fa9132008-02-20 12:09:29 +110030#ifdef HAVE_CONFIG_H
31#include "config.h"
32#endif
33
Jean-Marc Valin8600f692008-02-29 15:14:12 +110034#define CELT_C
35
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +110036#include "os_support.h"
Jean-Marc Valinf02ba112007-11-30 01:10:42 +110037#include "mdct.h"
38#include <math.h>
Jean-Marc Valin013c31d2007-11-30 11:36:46 +110039#include "celt.h"
Jean-Marc Valin14191b32007-11-30 12:15:49 +110040#include "pitch.h"
Jean-Marc Valin991c0f02007-11-30 16:07:46 +110041#include "bands.h"
Jean-Marc Valinecb36a32007-12-05 01:31:49 +110042#include "modes.h"
Jean-Marc Valin6238bc02008-01-28 22:28:54 +110043#include "entcode.h"
Jean-Marc Valin98d2a492007-12-07 22:46:47 +110044#include "quant_bands.h"
Jean-Marc Valin4fbd18d2008-01-17 14:07:55 +110045#include "rate.h"
Jean-Marc Valinc7e0b762008-03-16 07:55:29 +110046#include "stack_alloc.h"
Jean-Marc Valine4aeb472008-06-29 12:06:05 +100047#include "mathops.h"
Jean-Marc Valind9b95652008-08-31 23:34:47 -040048#include "float_cast.h"
Jean-Marc Valinb6f90612008-10-05 22:39:13 -040049#include <stdarg.h>
Jean-Marc Valin2779df72011-10-04 13:26:53 -040050#include "celt_lpc.h"
Jean-Marc Valineafd8a72011-01-23 00:24:45 -050051#include "vq.h"
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -050052
Ron2f2f9d62013-05-11 02:05:24 +093053#ifndef PACKAGE_VERSION
54#define PACKAGE_VERSION "unknown"
55#endif
56
Rhishikesh Agashef133bac2014-06-19 03:40:09 -040057#if defined(MIPSr1_ASM)
58#include "mips/celt_mipsr1.h"
59#endif
60
Ralph Gilesb0f4e902011-09-07 13:16:29 -070061
Jean-Marc Valin69062102012-11-08 09:42:27 -050062int resampling_factor(opus_int32 rate)
Jean-Marc Valin913a1742011-01-29 10:00:20 -050063{
64 int ret;
65 switch (rate)
66 {
67 case 48000:
68 ret = 1;
69 break;
70 case 24000:
71 ret = 2;
72 break;
73 case 16000:
74 ret = 3;
75 break;
76 case 12000:
77 ret = 4;
78 break;
79 case 8000:
80 ret = 6;
81 break;
82 default:
Jean-Marc Valin64ae0a92011-10-29 17:28:51 -040083#ifndef CUSTOM_MODES
Gregory Maxwellfd17eab2011-10-04 03:31:45 -040084 celt_assert(0);
85#endif
Jean-Marc Valin64ae0a92011-10-29 17:28:51 -040086 ret = 0;
87 break;
Jean-Marc Valin913a1742011-01-29 10:00:20 -050088 }
89 return ret;
90}
91
Jonathan Lennox911ddc02015-11-03 14:47:43 +090092#if !defined(OVERRIDE_COMB_FILTER_CONST) || defined(NON_STATIC_COMB_FILTER_CONST_C)
Jean-Marc Valin17b19782014-01-21 11:07:57 -050093/* This version should be faster on ARM */
94#ifdef OPUS_ARM_ASM
Jonathan Lennox43120f02015-08-03 17:04:27 -040095#ifndef NON_STATIC_COMB_FILTER_CONST_C
96static
97#endif
98void comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N,
Jean-Marc Valin17b19782014-01-21 11:07:57 -050099 opus_val16 g10, opus_val16 g11, opus_val16 g12)
100{
101 opus_val32 x0, x1, x2, x3, x4;
102 int i;
103 x4 = SHL32(x[-T-2], 1);
104 x3 = SHL32(x[-T-1], 1);
105 x2 = SHL32(x[-T], 1);
106 x1 = SHL32(x[-T+1], 1);
Jean-Marc Valin9b3a3ad2014-01-21 16:23:24 -0500107 for (i=0;i<N-4;i+=5)
108 {
109 opus_val32 t;
110 x0=SHL32(x[i-T+2],1);
111 t = MAC16_32_Q16(x[i], g10, x2);
112 t = MAC16_32_Q16(t, g11, ADD32(x1,x3));
113 t = MAC16_32_Q16(t, g12, ADD32(x0,x4));
Jean-Marc Valincbceaa82016-07-24 15:30:40 -0400114 t = SATURATE(t, SIG_SAT);
Jean-Marc Valin9b3a3ad2014-01-21 16:23:24 -0500115 y[i] = t;
116 x4=SHL32(x[i-T+3],1);
117 t = MAC16_32_Q16(x[i+1], g10, x1);
118 t = MAC16_32_Q16(t, g11, ADD32(x0,x2));
119 t = MAC16_32_Q16(t, g12, ADD32(x4,x3));
Jean-Marc Valincbceaa82016-07-24 15:30:40 -0400120 t = SATURATE(t, SIG_SAT);
Jean-Marc Valin9b3a3ad2014-01-21 16:23:24 -0500121 y[i+1] = t;
122 x3=SHL32(x[i-T+4],1);
123 t = MAC16_32_Q16(x[i+2], g10, x0);
124 t = MAC16_32_Q16(t, g11, ADD32(x4,x1));
125 t = MAC16_32_Q16(t, g12, ADD32(x3,x2));
Jean-Marc Valincbceaa82016-07-24 15:30:40 -0400126 t = SATURATE(t, SIG_SAT);
Jean-Marc Valin9b3a3ad2014-01-21 16:23:24 -0500127 y[i+2] = t;
128 x2=SHL32(x[i-T+5],1);
129 t = MAC16_32_Q16(x[i+3], g10, x4);
130 t = MAC16_32_Q16(t, g11, ADD32(x3,x0));
131 t = MAC16_32_Q16(t, g12, ADD32(x2,x1));
Jean-Marc Valincbceaa82016-07-24 15:30:40 -0400132 t = SATURATE(t, SIG_SAT);
Jean-Marc Valin9b3a3ad2014-01-21 16:23:24 -0500133 y[i+3] = t;
134 x1=SHL32(x[i-T+6],1);
135 t = MAC16_32_Q16(x[i+4], g10, x3);
136 t = MAC16_32_Q16(t, g11, ADD32(x2,x4));
137 t = MAC16_32_Q16(t, g12, ADD32(x1,x0));
Jean-Marc Valincbceaa82016-07-24 15:30:40 -0400138 t = SATURATE(t, SIG_SAT);
Jean-Marc Valin9b3a3ad2014-01-21 16:23:24 -0500139 y[i+4] = t;
140 }
141#ifdef CUSTOM_MODES
142 for (;i<N;i++)
Jean-Marc Valin17b19782014-01-21 11:07:57 -0500143 {
144 opus_val32 t;
145 x0=SHL32(x[i-T+2],1);
146 t = MAC16_32_Q16(x[i], g10, x2);
147 t = MAC16_32_Q16(t, g11, ADD32(x1,x3));
148 t = MAC16_32_Q16(t, g12, ADD32(x0,x4));
Jean-Marc Valincbceaa82016-07-24 15:30:40 -0400149 t = SATURATE(t, SIG_SAT);
Jean-Marc Valin17b19782014-01-21 11:07:57 -0500150 y[i] = t;
151 x4=x3;
152 x3=x2;
153 x2=x1;
154 x1=x0;
155 }
Jean-Marc Valin9b3a3ad2014-01-21 16:23:24 -0500156#endif
Jean-Marc Valin17b19782014-01-21 11:07:57 -0500157}
158#else
Jonathan Lennox43120f02015-08-03 17:04:27 -0400159#ifndef NON_STATIC_COMB_FILTER_CONST_C
160static
161#endif
162void comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N,
Jean-Marc Valin0d95b3b2013-06-17 03:58:16 -0400163 opus_val16 g10, opus_val16 g11, opus_val16 g12)
164{
165 opus_val32 x0, x1, x2, x3, x4;
166 int i;
167 x4 = x[-T-2];
168 x3 = x[-T-1];
169 x2 = x[-T];
170 x1 = x[-T+1];
171 for (i=0;i<N;i++)
172 {
173 x0=x[i-T+2];
174 y[i] = x[i]
175 + MULT16_32_Q15(g10,x2)
176 + MULT16_32_Q15(g11,ADD32(x1,x3))
177 + MULT16_32_Q15(g12,ADD32(x0,x4));
Jean-Marc Valincbceaa82016-07-24 15:30:40 -0400178 y[i] = SATURATE(y[i], SIG_SAT);
Jean-Marc Valin0d95b3b2013-06-17 03:58:16 -0400179 x4=x3;
180 x3=x2;
181 x2=x1;
182 x1=x0;
183 }
184
185}
186#endif
Jonathan Lennox911ddc02015-11-03 14:47:43 +0900187#endif
Gregory Maxwell71d39ad2011-07-30 00:00:29 -0400188
Rhishikesh Agashef133bac2014-06-19 03:40:09 -0400189#ifndef OVERRIDE_comb_filter
Jean-Marc Valin69062102012-11-08 09:42:27 -0500190void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400191 opus_val16 g0, opus_val16 g1, int tapset0, int tapset1,
Jonathan Lennox43120f02015-08-03 17:04:27 -0400192 const opus_val16 *window, int overlap, int arch)
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400193{
194 int i;
195 /* printf ("%d %d %f %f\n", T0, T1, g0, g1); */
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400196 opus_val16 g00, g01, g02, g10, g11, g12;
Jean-Marc Valincc9f28c2012-10-24 01:49:50 -0400197 opus_val32 x0, x1, x2, x3, x4;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400198 static const opus_val16 gains[3][3] = {
Jean-Marc Valin61f40412011-01-27 17:14:33 -0500199 {QCONST16(0.3066406250f, 15), QCONST16(0.2170410156f, 15), QCONST16(0.1296386719f, 15)},
200 {QCONST16(0.4638671875f, 15), QCONST16(0.2680664062f, 15), QCONST16(0.f, 15)},
201 {QCONST16(0.7998046875f, 15), QCONST16(0.1000976562f, 15), QCONST16(0.f, 15)}};
Jean-Marc Valin5ab07e62012-11-03 11:36:39 -0400202
203 if (g0==0 && g1==0)
204 {
205 /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
206 if (x!=y)
207 OPUS_MOVE(y, x, N);
208 return;
209 }
Jean-Marc Valine32cd272016-07-24 15:37:27 -0400210 /* When the gain is zero, T0 and/or T1 is set to zero. We need
211 to have then be at least 2 to avoid processing garbage data. */
212 T0 = IMAX(T0, COMBFILTER_MINPERIOD);
213 T1 = IMAX(T1, COMBFILTER_MINPERIOD);
Jean-Marc Valin05291fd2013-12-29 18:31:17 -0500214 g00 = MULT16_16_P15(g0, gains[tapset0][0]);
215 g01 = MULT16_16_P15(g0, gains[tapset0][1]);
216 g02 = MULT16_16_P15(g0, gains[tapset0][2]);
217 g10 = MULT16_16_P15(g1, gains[tapset1][0]);
218 g11 = MULT16_16_P15(g1, gains[tapset1][1]);
219 g12 = MULT16_16_P15(g1, gains[tapset1][2]);
Jean-Marc Valincc9f28c2012-10-24 01:49:50 -0400220 x1 = x[-T1+1];
221 x2 = x[-T1 ];
222 x3 = x[-T1-1];
223 x4 = x[-T1-2];
Jean-Marc Valine3187442014-01-31 15:38:27 -0500224 /* If the filter didn't change, we don't need the overlap */
225 if (g0==g1 && T0==T1 && tapset0==tapset1)
226 overlap=0;
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400227 for (i=0;i<overlap;i++)
228 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400229 opus_val16 f;
Jean-Marc Valincc9f28c2012-10-24 01:49:50 -0400230 x0=x[i-T1+2];
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400231 f = MULT16_16_Q15(window[i],window[i]);
232 y[i] = x[i]
Jean-Marc Valindfa847a2011-01-17 11:37:08 -0500233 + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g00),x[i-T0])
Jean-Marc Valincc9f28c2012-10-24 01:49:50 -0400234 + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g01),ADD32(x[i-T0+1],x[i-T0-1]))
235 + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g02),ADD32(x[i-T0+2],x[i-T0-2]))
236 + MULT16_32_Q15(MULT16_16_Q15(f,g10),x2)
237 + MULT16_32_Q15(MULT16_16_Q15(f,g11),ADD32(x1,x3))
238 + MULT16_32_Q15(MULT16_16_Q15(f,g12),ADD32(x0,x4));
Jean-Marc Valincbceaa82016-07-24 15:30:40 -0400239 y[i] = SATURATE(y[i], SIG_SAT);
Jean-Marc Valincc9f28c2012-10-24 01:49:50 -0400240 x4=x3;
241 x3=x2;
242 x2=x1;
243 x1=x0;
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400244
245 }
Jean-Marc Valin5ab07e62012-11-03 11:36:39 -0400246 if (g1==0)
247 {
248 /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
249 if (x!=y)
250 OPUS_MOVE(y+overlap, x+overlap, N-overlap);
251 return;
252 }
Jean-Marc Valin0d95b3b2013-06-17 03:58:16 -0400253
254 /* Compute the part with the constant filter. */
Jonathan Lennox43120f02015-08-03 17:04:27 -0400255 comb_filter_const(y+i, x+i, T1, N-i, g10, g11, g12, arch);
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400256}
Rhishikesh Agashef133bac2014-06-19 03:40:09 -0400257#endif /* OVERRIDE_comb_filter */
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400258
Jean-Marc Valin2ca6df02016-06-08 02:15:21 -0400259/* TF change table. Positive values mean better frequency resolution (longer
260 effective window), whereas negative values mean better time resolution
261 (shorter effective window). The second index is computed as:
262 4*isTransient + 2*tf_select + per_band_flag */
Jean-Marc Valin69062102012-11-08 09:42:27 -0500263const signed char tf_select_table[4][8] = {
Jean-Marc Valin2ca6df02016-06-08 02:15:21 -0400264 /*isTransient=0 isTransient=1 */
265 {0, -1, 0, -1, 0,-1, 0,-1}, /* 2.5 ms */
266 {0, -1, 0, -2, 1, 0, 1,-1}, /* 5 ms */
267 {0, -2, 0, -3, 2, 0, 1,-1}, /* 10 ms */
268 {0, -2, 0, -3, 3, 0, 1,-1}, /* 20 ms */
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400269};
270
Jean-Marc Valin27aea5c2011-11-07 15:32:11 -0500271
Jean-Marc Valin69062102012-11-08 09:42:27 -0500272void init_caps(const CELTMode *m,int *cap,int LM,int C)
Timothy B. Terriberryce6d0902011-02-01 17:41:12 -0800273{
274 int i;
275 for (i=0;i<m->nbEBands;i++)
276 {
277 int N;
278 N=(m->eBands[i+1]-m->eBands[i])<<LM;
279 cap[i] = (m->cache.caps[m->nbEBands*(2*LM+C-1)+i]+64)*C*N>>2;
280 }
281}
282
Jean-Marc Valinf9265dd2011-09-01 13:46:18 -0400283
284
285const char *opus_strerror(int error)
286{
Jean-Marc Valin79a6f4d2012-08-29 09:43:23 -0400287 static const char * const error_strings[8] = {
Jean-Marc Valinf9265dd2011-09-01 13:46:18 -0400288 "success",
289 "invalid argument",
290 "buffer too small",
291 "internal error",
292 "corrupted stream",
293 "request not implemented",
294 "invalid state",
295 "memory allocation failed"
296 };
297 if (error > 0 || error < -7)
298 return "unknown error";
299 else
300 return error_strings[-error];
301}
302
303const char *opus_get_version_string(void)
304{
Ron2f2f9d62013-05-11 02:05:24 +0930305 return "libopus " PACKAGE_VERSION
Timothy B. Terriberry75d81f52015-02-20 12:44:10 -0800306 /* Applications may rely on the presence of this substring in the version
307 string to determine if they have a fixed-point or floating-point build
308 at runtime. */
Gregory Maxwellde9b4372012-06-11 19:19:55 -0400309#ifdef FIXED_POINT
310 "-fixed"
311#endif
Jean-Marc Valinf9265dd2011-09-01 13:46:18 -0400312#ifdef FUZZING
313 "-fuzzing"
314#endif
315 ;
316}