blob: 846e02186c4ba4766818455c1e166021a6af2e55 [file] [log] [blame]
Benny Prijonoef010c52007-03-30 10:49:46 +00001/* Copyright (C) 2002 Jean-Marc Valin
2 File: speex.c
3
4 Basic Speex functions
5
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
9
10 - Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12
13 - 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.
16
17 - Neither the name of the Xiph.org Foundation nor the names of its
18 contributors may be used to endorse or promote products derived from
19 this software without specific prior written permission.
20
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
25 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
33*/
34
35#ifdef HAVE_CONFIG_H
36#include "config.h"
37#endif
38
39#include "modes.h"
40#include <math.h>
41
42#ifndef NULL
43#define NULL 0
44#endif
45
46#define MAX_IN_SAMPLES 640
47
48
49
50void *speex_encoder_init(const SpeexMode *mode)
51{
52 return mode->enc_init(mode);
53}
54
55void *speex_decoder_init(const SpeexMode *mode)
56{
57 return mode->dec_init(mode);
58}
59
60void speex_encoder_destroy(void *state)
61{
62 (*((SpeexMode**)state))->enc_destroy(state);
63}
64
65void speex_decoder_destroy(void *state)
66{
67 (*((SpeexMode**)state))->dec_destroy(state);
68}
69
70
71
72int speex_encode_native(void *state, spx_word16_t *in, SpeexBits *bits)
73{
74 return (*((SpeexMode**)state))->enc(state, in, bits);
75}
76
77int speex_decode_native(void *state, SpeexBits *bits, spx_word16_t *out)
78{
79 return (*((SpeexMode**)state))->dec(state, bits, out);
80}
81
82
83
84#ifdef FIXED_POINT
85
86int speex_encode(void *state, float *in, SpeexBits *bits)
87{
88 int i;
89 spx_int32_t N;
90 spx_int16_t short_in[MAX_IN_SAMPLES];
91 speex_encoder_ctl(state, SPEEX_GET_FRAME_SIZE, &N);
92 for (i=0;i<N;i++)
93 {
94 if (in[i]>32767.f)
95 short_in[i] = 32767;
96 else if (in[i]<-32768.f)
97 short_in[i] = -32768;
98 else
99 short_in[i] = (spx_int16_t)floor(.5+in[i]);
100 }
101 return (*((SpeexMode**)state))->enc(state, short_in, bits);
102}
103
104int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits)
105{
106 SpeexMode *mode;
107 mode = *(SpeexMode**)state;
108 return (mode)->enc(state, in, bits);
109}
110
111int speex_decode(void *state, SpeexBits *bits, float *out)
112{
113 int i, ret;
114 spx_int32_t N;
115 spx_int16_t short_out[MAX_IN_SAMPLES];
116 speex_decoder_ctl(state, SPEEX_GET_FRAME_SIZE, &N);
117 ret = (*((SpeexMode**)state))->dec(state, bits, short_out);
118 for (i=0;i<N;i++)
119 out[i] = short_out[i];
120 return ret;
121}
122
123int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out)
124{
125 SpeexMode *mode = *(SpeexMode**)state;
126 return (mode)->dec(state, bits, out);
127}
128
129#else
130
131int speex_encode(void *state, float *in, SpeexBits *bits)
132{
133 return (*((SpeexMode**)state))->enc(state, in, bits);
134}
135
136int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits)
137{
138 int i;
139 spx_int32_t N;
140 float float_in[MAX_IN_SAMPLES];
141 speex_encoder_ctl(state, SPEEX_GET_FRAME_SIZE, &N);
142 for (i=0;i<N;i++)
143 float_in[i] = in[i];
144 return (*((SpeexMode**)state))->enc(state, float_in, bits);
145}
146
147int speex_decode(void *state, SpeexBits *bits, float *out)
148{
149 return (*((SpeexMode**)state))->dec(state, bits, out);
150}
151
152int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out)
153{
154 int i;
155 spx_int32_t N;
156 float float_out[MAX_IN_SAMPLES];
157 int ret;
158 speex_decoder_ctl(state, SPEEX_GET_FRAME_SIZE, &N);
159 ret = (*((SpeexMode**)state))->dec(state, bits, float_out);
160 for (i=0;i<N;i++)
161 {
162 if (float_out[i]>32767.f)
163 out[i] = 32767;
164 else if (float_out[i]<-32768.f)
165 out[i] = -32768;
166 else
167 out[i] = (spx_int16_t)floor(.5+float_out[i]);
168 }
169 return ret;
170}
171#endif
172
173
174
175int speex_encoder_ctl(void *state, int request, void *ptr)
176{
177 return (*((SpeexMode**)state))->enc_ctl(state, request, ptr);
178}
179
180int speex_decoder_ctl(void *state, int request, void *ptr)
181{
182 return (*((SpeexMode**)state))->dec_ctl(state, request, ptr);
183}
184
185
186
187int nb_mode_query(const void *mode, int request, void *ptr)
188{
189 const SpeexNBMode *m = (const SpeexNBMode*)mode;
190
191 switch (request)
192 {
193 case SPEEX_MODE_FRAME_SIZE:
194 *((int*)ptr)=m->frameSize;
195 break;
196 case SPEEX_SUBMODE_BITS_PER_FRAME:
197 if (*((int*)ptr)==0)
198 *((int*)ptr) = NB_SUBMODE_BITS+1;
199 else if (m->submodes[*((int*)ptr)]==NULL)
200 *((int*)ptr) = -1;
201 else
202 *((int*)ptr) = m->submodes[*((int*)ptr)]->bits_per_frame;
203 break;
204 default:
205 speex_warning_int("Unknown nb_mode_query request: ", request);
206 return -1;
207 }
208 return 0;
209}
210
211int wb_mode_query(const void *mode, int request, void *ptr)
212{
213 const SpeexSBMode *m = (const SpeexSBMode*)mode;
214
215 switch (request)
216 {
217 case SPEEX_MODE_FRAME_SIZE:
218 *((int*)ptr)=2*m->frameSize;
219 break;
220 case SPEEX_SUBMODE_BITS_PER_FRAME:
221 if (*((int*)ptr)==0)
222 *((int*)ptr) = SB_SUBMODE_BITS+1;
223 else if (m->submodes[*((int*)ptr)]==NULL)
224 *((int*)ptr) = -1;
225 else
226 *((int*)ptr) = m->submodes[*((int*)ptr)]->bits_per_frame;
227 break;
228 default:
229 speex_warning_int("Unknown wb_mode_query request: ", request);
230 return -1;
231 }
232 return 0;
233}
234
235
236int speex_lib_ctl(int request, void *ptr)
237{
238 switch (request)
239 {
240 case SPEEX_LIB_GET_MAJOR_VERSION:
241 *((int*)ptr) = SPEEX_MAJOR_VERSION;
242 break;
243 case SPEEX_LIB_GET_MINOR_VERSION:
244 *((int*)ptr) = SPEEX_MINOR_VERSION;
245 break;
246 case SPEEX_LIB_GET_MICRO_VERSION:
247 *((int*)ptr) = SPEEX_MICRO_VERSION;
248 break;
249 case SPEEX_LIB_GET_EXTRA_VERSION:
250 *((const char**)ptr) = SPEEX_EXTRA_VERSION;
251 break;
252 case SPEEX_LIB_GET_VERSION_STRING:
253 *((const char**)ptr) = SPEEX_VERSION;
254 break;
255 /*case SPEEX_LIB_SET_ALLOC_FUNC:
256 break;
257 case SPEEX_LIB_GET_ALLOC_FUNC:
258 break;
259 case SPEEX_LIB_SET_FREE_FUNC:
260 break;
261 case SPEEX_LIB_GET_FREE_FUNC:
262 break;*/
263 default:
264 speex_warning_int("Unknown wb_mode_query request: ", request);
265 return -1;
266 }
267 return 0;
268}