celt.c 5.93 KB
Newer Older
Jean-Marc Valin's avatar
Jean-Marc Valin committed
1
/* Copyright (c) 2007-2008 CSIRO
Jean-Marc Valin's avatar
Jean-Marc Valin committed
2
   Copyright (c) 2007-2010 Xiph.Org Foundation
3
   Copyright (c) 2008 Gregory Maxwell
Jean-Marc Valin's avatar
Jean-Marc Valin committed
4
   Written by Jean-Marc Valin and Gregory Maxwell */
Jean-Marc Valin's avatar
Jean-Marc Valin committed
5
6
7
8
/*
   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions
   are met:
9

Jean-Marc Valin's avatar
Jean-Marc Valin committed
10
11
   - Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
12

Jean-Marc Valin's avatar
Jean-Marc Valin committed
13
14
15
   - Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.
16

Jean-Marc Valin's avatar
Jean-Marc Valin committed
17
18
19
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20
21
   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
Jean-Marc Valin's avatar
Jean-Marc Valin committed
22
23
24
25
26
27
28
29
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

30
31
32
33
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

34
35
#define CELT_C

Jean-Marc Valin's avatar
Jean-Marc Valin committed
36
#include "os_support.h"
37
38
#include "mdct.h"
#include <math.h>
39
#include "celt.h"
40
#include "pitch.h"
41
#include "bands.h"
42
#include "modes.h"
43
#include "entcode.h"
44
#include "quant_bands.h"
Jean-Marc Valin's avatar
Jean-Marc Valin committed
45
#include "rate.h"
46
#include "stack_alloc.h"
47
#include "mathops.h"
48
#include "float_cast.h"
49
#include <stdarg.h>
50
#include "celt_lpc.h"
51
#include "vq.h"
52

Ron's avatar
Ron committed
53
54
55
56
#ifndef PACKAGE_VERSION
#define PACKAGE_VERSION "unknown"
#endif

57

58
int resampling_factor(opus_int32 rate)
Jean-Marc Valin's avatar
Jean-Marc Valin committed
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
{
   int ret;
   switch (rate)
   {
   case 48000:
      ret = 1;
      break;
   case 24000:
      ret = 2;
      break;
   case 16000:
      ret = 3;
      break;
   case 12000:
      ret = 4;
      break;
   case 8000:
      ret = 6;
      break;
   default:
Jean-Marc Valin's avatar
Jean-Marc Valin committed
79
#ifndef CUSTOM_MODES
80
81
      celt_assert(0);
#endif
Jean-Marc Valin's avatar
Jean-Marc Valin committed
82
83
      ret = 0;
      break;
Jean-Marc Valin's avatar
Jean-Marc Valin committed
84
85
86
87
   }
   return ret;
}

88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#ifndef OVERRIDE_COMB_FILTER_CONST
static void comb_filter_const(opus_val32 *y, opus_val32 *x, int T, int N,
      opus_val16 g10, opus_val16 g11, opus_val16 g12)
{
   opus_val32 x0, x1, x2, x3, x4;
   int i;
   x4 = x[-T-2];
   x3 = x[-T-1];
   x2 = x[-T];
   x1 = x[-T+1];
   for (i=0;i<N;i++)
   {
      x0=x[i-T+2];
      y[i] = x[i]
               + MULT16_32_Q15(g10,x2)
               + MULT16_32_Q15(g11,ADD32(x1,x3))
               + MULT16_32_Q15(g12,ADD32(x0,x4));
      x4=x3;
      x3=x2;
      x2=x1;
      x1=x0;
   }

}
#endif
113

114
void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,
115
116
      opus_val16 g0, opus_val16 g1, int tapset0, int tapset1,
      const opus_val16 *window, int overlap)
117
118
119
{
   int i;
   /* printf ("%d %d %f %f\n", T0, T1, g0, g1); */
120
   opus_val16 g00, g01, g02, g10, g11, g12;
121
   opus_val32 x0, x1, x2, x3, x4;
122
   static const opus_val16 gains[3][3] = {
123
124
125
         {QCONST16(0.3066406250f, 15), QCONST16(0.2170410156f, 15), QCONST16(0.1296386719f, 15)},
         {QCONST16(0.4638671875f, 15), QCONST16(0.2680664062f, 15), QCONST16(0.f, 15)},
         {QCONST16(0.7998046875f, 15), QCONST16(0.1000976562f, 15), QCONST16(0.f, 15)}};
126
127
128
129
130
131
132
133

   if (g0==0 && g1==0)
   {
      /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
      if (x!=y)
         OPUS_MOVE(y, x, N);
      return;
   }
134
135
136
137
138
139
   g00 = MULT16_16_P15(g0, gains[tapset0][0]);
   g01 = MULT16_16_P15(g0, gains[tapset0][1]);
   g02 = MULT16_16_P15(g0, gains[tapset0][2]);
   g10 = MULT16_16_P15(g1, gains[tapset1][0]);
   g11 = MULT16_16_P15(g1, gains[tapset1][1]);
   g12 = MULT16_16_P15(g1, gains[tapset1][2]);
140
141
142
143
   x1 = x[-T1+1];
   x2 = x[-T1  ];
   x3 = x[-T1-1];
   x4 = x[-T1-2];
144
145
   for (i=0;i<overlap;i++)
   {
146
      opus_val16 f;
147
      x0=x[i-T1+2];
148
149
      f = MULT16_16_Q15(window[i],window[i]);
      y[i] = x[i]
150
               + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g00),x[i-T0])
151
152
153
154
155
156
157
158
159
               + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g01),ADD32(x[i-T0+1],x[i-T0-1]))
               + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g02),ADD32(x[i-T0+2],x[i-T0-2]))
               + MULT16_32_Q15(MULT16_16_Q15(f,g10),x2)
               + MULT16_32_Q15(MULT16_16_Q15(f,g11),ADD32(x1,x3))
               + MULT16_32_Q15(MULT16_16_Q15(f,g12),ADD32(x0,x4));
      x4=x3;
      x3=x2;
      x2=x1;
      x1=x0;
160
161

   }
162
163
164
165
166
167
168
   if (g1==0)
   {
      /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
      if (x!=y)
         OPUS_MOVE(y+overlap, x+overlap, N-overlap);
      return;
   }
169
170
171

   /* Compute the part with the constant filter. */
   comb_filter_const(y+i, x+i, T1, N-i, g10, g11, g12);
172
173
}

174
const signed char tf_select_table[4][8] = {
175
      {0, -1, 0, -1,    0,-1, 0,-1},
176
177
      {0, -1, 0, -2,    1, 0, 1,-1},
      {0, -2, 0, -3,    2, 0, 1,-1},
178
      {0, -2, 0, -3,    3, 0, 1,-1},
179
180
};

181

182
void init_caps(const CELTMode *m,int *cap,int LM,int C)
183
184
185
186
187
188
189
190
191
192
{
   int i;
   for (i=0;i<m->nbEBands;i++)
   {
      int N;
      N=(m->eBands[i+1]-m->eBands[i])<<LM;
      cap[i] = (m->cache.caps[m->nbEBands*(2*LM+C-1)+i]+64)*C*N>>2;
   }
}

193
194
195
196


const char *opus_strerror(int error)
{
197
   static const char * const error_strings[8] = {
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
      "success",
      "invalid argument",
      "buffer too small",
      "internal error",
      "corrupted stream",
      "request not implemented",
      "invalid state",
      "memory allocation failed"
   };
   if (error > 0 || error < -7)
      return "unknown error";
   else
      return error_strings[-error];
}

const char *opus_get_version_string(void)
{
Ron's avatar
Ron committed
215
    return "libopus " PACKAGE_VERSION
216
217
218
#ifdef FIXED_POINT
          "-fixed"
#endif
219
220
221
222
223
#ifdef FUZZING
          "-fuzzing"
#endif
          ;
}