1 /* Copyright (C) 2007 Jean-Marc Valin
2 
3    File: speex_resampler.h
4    Resampling code
5 
6    The design goals of this code are:
7       - Very fast algorithm
8       - Low memory requirement
9       - Good *perceptual* quality (and not best SNR)
10 
11    Redistribution and use in source and binary forms, with or without
12    modification, are permitted provided that the following conditions are
13    met:
14 
15    1. Redistributions of source code must retain the above copyright notice,
16    this list of conditions and the following disclaimer.
17 
18    2. Redistributions in binary form must reproduce the above copyright
19    notice, this list of conditions and the following disclaimer in the
20    documentation and/or other materials provided with the distribution.
21 
22    3. The name of the author may not be used to endorse or promote products
23    derived from this software without specific prior written permission.
24 
25    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
26    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28    DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
29    INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
33    STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35    POSSIBILITY OF SUCH DAMAGE.
36 */
37 
38 /* Begin Mednafen modifications */
39 
40 #define RANDOM_PREFIX MDFN
41 
42 #define OUTSIDE_SPEEX
43 
44 /* End Mednafen modifications */
45 
46 #ifndef SPEEX_RESAMPLER_H
47 #define SPEEX_RESAMPLER_H
48 
49 #ifdef OUTSIDE_SPEEX
50 
51 /********* WARNING: MENTAL SANITY ENDS HERE *************/
52 
53 /* If the resampler is defined outside of Speex, we change the symbol names so that
54    there won't be any clash if linking with Speex later on. */
55 
56 /* #define RANDOM_PREFIX your software name here */
57 #ifndef RANDOM_PREFIX
58 #error "Please define RANDOM_PREFIX (above) to something specific to your project to prevent symbol name clashes"
59 #endif
60 
61 #define CAT_PREFIX2(a,b) a ## b
62 #define CAT_PREFIX(a,b) CAT_PREFIX2(a, b)
63 
64 #define speex_resampler_init CAT_PREFIX(RANDOM_PREFIX,_resampler_init)
65 #define speex_resampler_init_frac CAT_PREFIX(RANDOM_PREFIX,_resampler_init_frac)
66 #define speex_resampler_destroy CAT_PREFIX(RANDOM_PREFIX,_resampler_destroy)
67 #define speex_resampler_process_float CAT_PREFIX(RANDOM_PREFIX,_resampler_process_float)
68 #define speex_resampler_process_int CAT_PREFIX(RANDOM_PREFIX,_resampler_process_int)
69 #define speex_resampler_process_interleaved_float CAT_PREFIX(RANDOM_PREFIX,_resampler_process_interleaved_float)
70 #define speex_resampler_process_interleaved_int CAT_PREFIX(RANDOM_PREFIX,_resampler_process_interleaved_int)
71 #define speex_resampler_set_rate CAT_PREFIX(RANDOM_PREFIX,_resampler_set_rate)
72 #define speex_resampler_get_rate CAT_PREFIX(RANDOM_PREFIX,_resampler_get_rate)
73 #define speex_resampler_set_rate_frac CAT_PREFIX(RANDOM_PREFIX,_resampler_set_rate_frac)
74 #define speex_resampler_get_ratio CAT_PREFIX(RANDOM_PREFIX,_resampler_get_ratio)
75 #define speex_resampler_set_quality CAT_PREFIX(RANDOM_PREFIX,_resampler_set_quality)
76 #define speex_resampler_get_quality CAT_PREFIX(RANDOM_PREFIX,_resampler_get_quality)
77 #define speex_resampler_set_input_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_set_input_stride)
78 #define speex_resampler_get_input_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_input_stride)
79 #define speex_resampler_set_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_set_output_stride)
80 #define speex_resampler_get_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_output_stride)
81 #define speex_resampler_get_input_latency CAT_PREFIX(RANDOM_PREFIX,_resampler_get_input_latency)
82 #define speex_resampler_get_output_latency CAT_PREFIX(RANDOM_PREFIX,_resampler_get_output_latency)
83 #define speex_resampler_skip_zeros CAT_PREFIX(RANDOM_PREFIX,_resampler_skip_zeros)
84 #define speex_resampler_reset_mem CAT_PREFIX(RANDOM_PREFIX,_resampler_reset_mem)
85 #define speex_resampler_strerror CAT_PREFIX(RANDOM_PREFIX,_resampler_strerror)
86 
87 #define spx_int16_t short
88 #define spx_int32_t int
89 #define spx_uint16_t unsigned short
90 #define spx_uint32_t unsigned int
91 
92 #else /* OUTSIDE_SPEEX */
93 
94 #include "speex/speex_types.h"
95 
96 #endif /* OUTSIDE_SPEEX */
97 
98 #ifdef __cplusplus
99 extern "C" {
100 #endif
101 
102 #define SPEEX_RESAMPLER_QUALITY_MAX 10
103 #define SPEEX_RESAMPLER_QUALITY_MIN 0
104 #define SPEEX_RESAMPLER_QUALITY_DEFAULT 4
105 #define SPEEX_RESAMPLER_QUALITY_VOIP 3
106 #define SPEEX_RESAMPLER_QUALITY_DESKTOP 5
107 
108 enum {
109    RESAMPLER_ERR_SUCCESS         = 0,
110    RESAMPLER_ERR_ALLOC_FAILED    = 1,
111    RESAMPLER_ERR_BAD_STATE       = 2,
112    RESAMPLER_ERR_INVALID_ARG     = 3,
113    RESAMPLER_ERR_PTR_OVERLAP     = 4,
114 
115    RESAMPLER_ERR_MAX_ERROR
116 };
117 
118 struct SpeexResamplerState_;
119 typedef struct SpeexResamplerState_ SpeexResamplerState;
120 
121 /** Create a new resampler with integer input and output rates.
122  * @param nb_channels Number of channels to be processed
123  * @param in_rate Input sampling rate (integer number of Hz).
124  * @param out_rate Output sampling rate (integer number of Hz).
125  * @param quality Resampling quality between 0 and 10, where 0 has poor quality
126  * and 10 has very high quality.
127  * @return Newly created resampler state
128  * @retval NULL Error: not enough memory
129  */
130 SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels,
131                                           spx_uint32_t in_rate,
132                                           spx_uint32_t out_rate,
133                                           int quality,
134                                           int *err);
135 
136 /** Create a new resampler with fractional input/output rates. The sampling
137  * rate ratio is an arbitrary rational number with both the numerator and
138  * denominator being 32-bit integers.
139  * @param nb_channels Number of channels to be processed
140  * @param ratio_num Numerator of the sampling rate ratio
141  * @param ratio_den Denominator of the sampling rate ratio
142  * @param in_rate Input sampling rate rounded to the nearest integer (in Hz).
143  * @param out_rate Output sampling rate rounded to the nearest integer (in Hz).
144  * @param quality Resampling quality between 0 and 10, where 0 has poor quality
145  * and 10 has very high quality.
146  * @return Newly created resampler state
147  * @retval NULL Error: not enough memory
148  */
149 SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels,
150                                                spx_uint32_t ratio_num,
151                                                spx_uint32_t ratio_den,
152                                                spx_uint32_t in_rate,
153                                                spx_uint32_t out_rate,
154                                                int quality,
155                                                int *err);
156 
157 /** Destroy a resampler state.
158  * @param st Resampler state
159  */
160 void speex_resampler_destroy(SpeexResamplerState *st);
161 
162 /** Resample a float array. The input and output buffers must *not* overlap.
163  * @param st Resampler state
164  * @param channel_index Index of the channel to process for the multi-channel
165  * base (0 otherwise)
166  * @param in Input buffer
167  * @param in_len Number of input samples in the input buffer. Returns the
168  * number of samples processed
169  * @param out Output buffer
170  * @param out_len Size of the output buffer. Returns the number of samples written
171  */
172 int speex_resampler_process_float(SpeexResamplerState *st,
173                                    spx_uint32_t channel_index,
174                                    const float *in,
175                                    spx_uint32_t *in_len,
176                                    float *out,
177                                    spx_uint32_t *out_len);
178 
179 /** Resample an int array. The input and output buffers must *not* overlap.
180  * @param st Resampler state
181  * @param channel_index Index of the channel to process for the multi-channel
182  * base (0 otherwise)
183  * @param in Input buffer
184  * @param in_len Number of input samples in the input buffer. Returns the number
185  * of samples processed
186  * @param out Output buffer
187  * @param out_len Size of the output buffer. Returns the number of samples written
188  */
189 int speex_resampler_process_int(SpeexResamplerState *st,
190                                  spx_uint32_t channel_index,
191                                  const spx_int16_t *in,
192                                  spx_uint32_t *in_len,
193                                  spx_int16_t *out,
194                                  spx_uint32_t *out_len);
195 
196 /** Resample an interleaved float array. The input and output buffers must *not* overlap.
197  * @param st Resampler state
198  * @param in Input buffer
199  * @param in_len Number of input samples in the input buffer. Returns the number
200  * of samples processed. This is all per-channel.
201  * @param out Output buffer
202  * @param out_len Size of the output buffer. Returns the number of samples written.
203  * This is all per-channel.
204  */
205 int speex_resampler_process_interleaved_float(SpeexResamplerState *st,
206                                                const float *in,
207                                                spx_uint32_t *in_len,
208                                                float *out,
209                                                spx_uint32_t *out_len);
210 
211 /** Resample an interleaved int array. The input and output buffers must *not* overlap.
212  * @param st Resampler state
213  * @param in Input buffer
214  * @param in_len Number of input samples in the input buffer. Returns the number
215  * of samples processed. This is all per-channel.
216  * @param out Output buffer
217  * @param out_len Size of the output buffer. Returns the number of samples written.
218  * This is all per-channel.
219  */
220 int speex_resampler_process_interleaved_int(SpeexResamplerState *st,
221                                              const spx_int16_t *in,
222                                              spx_uint32_t *in_len,
223                                              spx_int16_t *out,
224                                              spx_uint32_t *out_len);
225 
226 /** Set (change) the input/output sampling rates (integer value).
227  * @param st Resampler state
228  * @param in_rate Input sampling rate (integer number of Hz).
229  * @param out_rate Output sampling rate (integer number of Hz).
230  */
231 int speex_resampler_set_rate(SpeexResamplerState *st,
232                               spx_uint32_t in_rate,
233                               spx_uint32_t out_rate);
234 
235 /** Get the current input/output sampling rates (integer value).
236  * @param st Resampler state
237  * @param in_rate Input sampling rate (integer number of Hz) copied.
238  * @param out_rate Output sampling rate (integer number of Hz) copied.
239  */
240 void speex_resampler_get_rate(SpeexResamplerState *st,
241                               spx_uint32_t *in_rate,
242                               spx_uint32_t *out_rate);
243 
244 /** Set (change) the input/output sampling rates and resampling ratio
245  * (fractional values in Hz supported).
246  * @param st Resampler state
247  * @param ratio_num Numerator of the sampling rate ratio
248  * @param ratio_den Denominator of the sampling rate ratio
249  * @param in_rate Input sampling rate rounded to the nearest integer (in Hz).
250  * @param out_rate Output sampling rate rounded to the nearest integer (in Hz).
251  */
252 int speex_resampler_set_rate_frac(SpeexResamplerState *st,
253                                    spx_uint32_t ratio_num,
254                                    spx_uint32_t ratio_den,
255                                    spx_uint32_t in_rate,
256                                    spx_uint32_t out_rate);
257 
258 /** Get the current resampling ratio. This will be reduced to the least
259  * common denominator.
260  * @param st Resampler state
261  * @param ratio_num Numerator of the sampling rate ratio copied
262  * @param ratio_den Denominator of the sampling rate ratio copied
263  */
264 void speex_resampler_get_ratio(SpeexResamplerState *st,
265                                spx_uint32_t *ratio_num,
266                                spx_uint32_t *ratio_den);
267 
268 /** Set (change) the conversion quality.
269  * @param st Resampler state
270  * @param quality Resampling quality between 0 and 10, where 0 has poor
271  * quality and 10 has very high quality.
272  */
273 int speex_resampler_set_quality(SpeexResamplerState *st,
274                                  int quality);
275 
276 /** Get the conversion quality.
277  * @param st Resampler state
278  * @param quality Resampling quality between 0 and 10, where 0 has poor
279  * quality and 10 has very high quality.
280  */
281 void speex_resampler_get_quality(SpeexResamplerState *st,
282                                  int *quality);
283 
284 /** Set (change) the input stride.
285  * @param st Resampler state
286  * @param stride Input stride
287  */
288 void speex_resampler_set_input_stride(SpeexResamplerState *st,
289                                       spx_uint32_t stride);
290 
291 /** Get the input stride.
292  * @param st Resampler state
293  * @param stride Input stride copied
294  */
295 void speex_resampler_get_input_stride(SpeexResamplerState *st,
296                                       spx_uint32_t *stride);
297 
298 /** Set (change) the output stride.
299  * @param st Resampler state
300  * @param stride Output stride
301  */
302 void speex_resampler_set_output_stride(SpeexResamplerState *st,
303                                       spx_uint32_t stride);
304 
305 /** Get the output stride.
306  * @param st Resampler state copied
307  * @param stride Output stride
308  */
309 void speex_resampler_get_output_stride(SpeexResamplerState *st,
310                                       spx_uint32_t *stride);
311 
312 /** Get the latency in input samples introduced by the resampler.
313  * @param st Resampler state
314  */
315 int speex_resampler_get_input_latency(SpeexResamplerState *st);
316 
317 /** Get the latency in output samples introduced by the resampler.
318  * @param st Resampler state
319  */
320 int speex_resampler_get_output_latency(SpeexResamplerState *st);
321 
322 /** Make sure that the first samples to go out of the resamplers don't have
323  * leading zeros. This is only useful before starting to use a newly created
324  * resampler. It is recommended to use that when resampling an audio file, as
325  * it will generate a file with the same length. For real-time processing,
326  * it is probably easier not to use this call (so that the output duration
327  * is the same for the first frame).
328  * @param st Resampler state
329  */
330 int speex_resampler_skip_zeros(SpeexResamplerState *st);
331 
332 /** Reset a resampler so a new (unrelated) stream can be processed.
333  * @param st Resampler state
334  */
335 int speex_resampler_reset_mem(SpeexResamplerState *st);
336 
337 /** Returns the English meaning for an error code
338  * @param err Error code
339  * @return English string
340  */
341 const char *speex_resampler_strerror(int err);
342 
343 #ifdef __cplusplus
344 }
345 #endif
346 
347 #endif
348 
349 
350