1/* 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#include "os_support.h"
42
43#ifndef NULL
44#define NULL 0
45#endif
46
47#define MAX_IN_SAMPLES 640
48
49
50
51EXPORT void *speex_encoder_init(const SpeexMode *mode)
52{
53   return mode->enc_init(mode);
54}
55
56EXPORT void *speex_decoder_init(const SpeexMode *mode)
57{
58   return mode->dec_init(mode);
59}
60
61EXPORT void speex_encoder_destroy(void *state)
62{
63   (*((SpeexMode**)state))->enc_destroy(state);
64}
65
66EXPORT void speex_decoder_destroy(void *state)
67{
68   (*((SpeexMode**)state))->dec_destroy(state);
69}
70
71
72
73int speex_encode_native(void *state, spx_word16_t *in, SpeexBits *bits)
74{
75   return (*((SpeexMode**)state))->enc(state, in, bits);
76}
77
78int speex_decode_native(void *state, SpeexBits *bits, spx_word16_t *out)
79{
80   return (*((SpeexMode**)state))->dec(state, bits, out);
81}
82
83
84
85#ifdef FIXED_POINT
86
87#ifndef DISABLE_FLOAT_API
88EXPORT int speex_encode(void *state, float *in, SpeexBits *bits)
89{
90   int i;
91   spx_int32_t N;
92   spx_int16_t short_in[MAX_IN_SAMPLES];
93   speex_encoder_ctl(state, SPEEX_GET_FRAME_SIZE, &N);
94   for (i=0;i<N;i++)
95   {
96      if (in[i]>32767.f)
97         short_in[i] = 32767;
98      else if (in[i]<-32768.f)
99         short_in[i] = -32768;
100      else
101         short_in[i] = (spx_int16_t)floor(.5+in[i]);
102   }
103   return (*((SpeexMode**)state))->enc(state, short_in, bits);
104}
105#endif /* #ifndef DISABLE_FLOAT_API */
106
107EXPORT int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits)
108{
109   SpeexMode *mode;
110   mode = *(SpeexMode**)state;
111   return (mode)->enc(state, in, bits);
112}
113
114#ifndef DISABLE_FLOAT_API
115EXPORT int speex_decode(void *state, SpeexBits *bits, float *out)
116{
117   int i, ret;
118   spx_int32_t N;
119   spx_int16_t short_out[MAX_IN_SAMPLES];
120   speex_decoder_ctl(state, SPEEX_GET_FRAME_SIZE, &N);
121   ret = (*((SpeexMode**)state))->dec(state, bits, short_out);
122   for (i=0;i<N;i++)
123      out[i] = short_out[i];
124   return ret;
125}
126#endif /* #ifndef DISABLE_FLOAT_API */
127
128EXPORT int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out)
129{
130   SpeexMode *mode = *(SpeexMode**)state;
131   return (mode)->dec(state, bits, out);
132}
133
134#else
135
136EXPORT int speex_encode(void *state, float *in, SpeexBits *bits)
137{
138   return (*((SpeexMode**)state))->enc(state, in, bits);
139}
140
141EXPORT int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits)
142{
143   int i;
144   spx_int32_t N;
145   float float_in[MAX_IN_SAMPLES];
146   speex_encoder_ctl(state, SPEEX_GET_FRAME_SIZE, &N);
147   for (i=0;i<N;i++)
148      float_in[i] = in[i];
149   return (*((SpeexMode**)state))->enc(state, float_in, bits);
150}
151
152EXPORT int speex_decode(void *state, SpeexBits *bits, float *out)
153{
154   return (*((SpeexMode**)state))->dec(state, bits, out);
155}
156
157EXPORT int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out)
158{
159   int i;
160   spx_int32_t N;
161   float float_out[MAX_IN_SAMPLES];
162   int ret;
163   speex_decoder_ctl(state, SPEEX_GET_FRAME_SIZE, &N);
164   ret = (*((SpeexMode**)state))->dec(state, bits, float_out);
165   for (i=0;i<N;i++)
166   {
167      if (float_out[i]>32767.f)
168         out[i] = 32767;
169      else if (float_out[i]<-32768.f)
170         out[i] = -32768;
171      else
172         out[i] = (spx_int16_t)floor(.5+float_out[i]);
173   }
174   return ret;
175}
176#endif
177
178
179
180EXPORT int speex_encoder_ctl(void *state, int request, void *ptr)
181{
182   return (*((SpeexMode**)state))->enc_ctl(state, request, ptr);
183}
184
185EXPORT int speex_decoder_ctl(void *state, int request, void *ptr)
186{
187   return (*((SpeexMode**)state))->dec_ctl(state, request, ptr);
188}
189
190
191
192int nb_mode_query(const void *mode, int request, void *ptr)
193{
194   const SpeexNBMode *m = (const SpeexNBMode*)mode;
195
196   switch (request)
197   {
198   case SPEEX_MODE_FRAME_SIZE:
199      *((int*)ptr)=m->frameSize;
200      break;
201   case SPEEX_SUBMODE_BITS_PER_FRAME:
202      if (*((int*)ptr)==0)
203         *((int*)ptr) = NB_SUBMODE_BITS+1;
204      else if (m->submodes[*((int*)ptr)]==NULL)
205         *((int*)ptr) = -1;
206      else
207         *((int*)ptr) = m->submodes[*((int*)ptr)]->bits_per_frame;
208      break;
209   default:
210      speex_warning_int("Unknown nb_mode_query request: ", request);
211      return -1;
212   }
213   return 0;
214}
215
216
217
218EXPORT int speex_lib_ctl(int request, void *ptr)
219{
220   switch (request)
221   {
222      case SPEEX_LIB_GET_MAJOR_VERSION:
223         *((int*)ptr) = SPEEX_MAJOR_VERSION;
224         break;
225      case SPEEX_LIB_GET_MINOR_VERSION:
226         *((int*)ptr) = SPEEX_MINOR_VERSION;
227         break;
228      case SPEEX_LIB_GET_MICRO_VERSION:
229         *((int*)ptr) = SPEEX_MICRO_VERSION;
230         break;
231      case SPEEX_LIB_GET_EXTRA_VERSION:
232         *((const char**)ptr) = SPEEX_EXTRA_VERSION;
233         break;
234      case SPEEX_LIB_GET_VERSION_STRING:
235         *((const char**)ptr) = SPEEX_VERSION;
236         break;
237      /*case SPEEX_LIB_SET_ALLOC_FUNC:
238         break;
239      case SPEEX_LIB_GET_ALLOC_FUNC:
240         break;
241      case SPEEX_LIB_SET_FREE_FUNC:
242         break;
243      case SPEEX_LIB_GET_FREE_FUNC:
244         break;*/
245      default:
246         speex_warning_int("Unknown wb_mode_query request: ", request);
247         return -1;
248   }
249   return 0;
250}
251