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 
39 #ifndef SPEEX_RESAMPLER_H
40 #define SPEEX_RESAMPLER_H
41 
42 
43 /********* WARNING: MENTAL SANITY ENDS HERE *************/
44 
45 /* If the resampler is defined outside of Speex, we change the symbol names so that
46    there won't be any clash if linking with Speex later on. */
47 
48 /* #define RANDOM_PREFIX your software name here */
49 #define RANDOM_PREFIX f_a
50 #ifndef RANDOM_PREFIX
51 #error "Please define RANDOM_PREFIX (above) to something specific to your project to prevent symbol name clashes"
52 #endif
53 
54 #define CAT_PREFIX2(a,b) a ## b
55 #define CAT_PREFIX(a,b) CAT_PREFIX2(a, b)
56 
57 #define speex_resampler_init CAT_PREFIX(RANDOM_PREFIX,_resampler_init)
58 #define speex_resampler_init_frac CAT_PREFIX(RANDOM_PREFIX,_resampler_init_frac)
59 #define speex_resampler_destroy CAT_PREFIX(RANDOM_PREFIX,_resampler_destroy)
60 #define speex_resampler_process_float CAT_PREFIX(RANDOM_PREFIX,_resampler_process_float)
61 #define speex_resampler_process_int CAT_PREFIX(RANDOM_PREFIX,_resampler_process_int)
62 #define speex_resampler_process_interleaved_float CAT_PREFIX(RANDOM_PREFIX,_resampler_process_interleaved_float)
63 #define speex_resampler_process_interleaved_int CAT_PREFIX(RANDOM_PREFIX,_resampler_process_interleaved_int)
64 #define speex_resampler_set_rate CAT_PREFIX(RANDOM_PREFIX,_resampler_set_rate)
65 #define speex_resampler_get_rate CAT_PREFIX(RANDOM_PREFIX,_resampler_get_rate)
66 #define speex_resampler_set_rate_frac CAT_PREFIX(RANDOM_PREFIX,_resampler_set_rate_frac)
67 #define speex_resampler_get_ratio CAT_PREFIX(RANDOM_PREFIX,_resampler_get_ratio)
68 #define speex_resampler_set_quality CAT_PREFIX(RANDOM_PREFIX,_resampler_set_quality)
69 #define speex_resampler_get_quality CAT_PREFIX(RANDOM_PREFIX,_resampler_get_quality)
70 #define speex_resampler_set_input_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_set_input_stride)
71 #define speex_resampler_get_input_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_input_stride)
72 #define speex_resampler_set_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_set_output_stride)
73 #define speex_resampler_get_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_output_stride)
74 #define speex_resampler_get_input_latency CAT_PREFIX(RANDOM_PREFIX,_resampler_get_input_latency)
75 #define speex_resampler_get_output_latency CAT_PREFIX(RANDOM_PREFIX,_resampler_get_output_latency)
76 #define speex_resampler_skip_zeros CAT_PREFIX(RANDOM_PREFIX,_resampler_skip_zeros)
77 #define speex_resampler_reset_mem CAT_PREFIX(RANDOM_PREFIX,_resampler_reset_mem)
78 #define speex_resampler_strerror CAT_PREFIX(RANDOM_PREFIX,_resampler_strerror)
79 
80 #define spx_int16_t short
81 #define spx_int32_t int
82 #define spx_uint16_t unsigned short
83 #define spx_uint32_t unsigned int
84 
85 #ifdef __cplusplus
86 extern "C" {
87 #endif
88 
89 #define SPEEX_RESAMPLER_QUALITY_MAX 10
90 #define SPEEX_RESAMPLER_QUALITY_MIN 0
91 #define SPEEX_RESAMPLER_QUALITY_DEFAULT 4
92 #define SPEEX_RESAMPLER_QUALITY_VOIP 3
93 #define SPEEX_RESAMPLER_QUALITY_DESKTOP 5
94 
95 enum {
96    RESAMPLER_ERR_SUCCESS         = 0,
97    RESAMPLER_ERR_ALLOC_FAILED    = 1,
98    RESAMPLER_ERR_BAD_STATE       = 2,
99    RESAMPLER_ERR_INVALID_ARG     = 3,
100    RESAMPLER_ERR_PTR_OVERLAP     = 4,
101 
102    RESAMPLER_ERR_MAX_ERROR
103 };
104 
105 struct SpeexResamplerState_;
106 typedef struct SpeexResamplerState_ SpeexResamplerState;
107 
108 /** Create a new resampler with integer input and output rates.
109  * @param nb_channels Number of channels to be processed
110  * @param in_rate Input sampling rate (integer number of Hz).
111  * @param out_rate Output sampling rate (integer number of Hz).
112  * @param quality Resampling quality between 0 and 10, where 0 has poor quality
113  * and 10 has very high quality.
114  * @return Newly created resampler state
115  * @retval NULL Error: not enough memory
116  */
117 SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels,
118                                           spx_uint32_t in_rate,
119                                           spx_uint32_t out_rate,
120                                           int quality,
121                                           int *err);
122 
123 /** Create a new resampler with fractional input/output rates. The sampling
124  * rate ratio is an arbitrary rational number with both the numerator and
125  * denominator being 32-bit integers.
126  * @param nb_channels Number of channels to be processed
127  * @param ratio_num Numerator of the sampling rate ratio
128  * @param ratio_den Denominator of the sampling rate ratio
129  * @param in_rate Input sampling rate rounded to the nearest integer (in Hz).
130  * @param out_rate Output sampling rate rounded to the nearest integer (in Hz).
131  * @param quality Resampling quality between 0 and 10, where 0 has poor quality
132  * and 10 has very high quality.
133  * @return Newly created resampler state
134  * @retval NULL Error: not enough memory
135  */
136 SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels,
137                                                spx_uint32_t ratio_num,
138                                                spx_uint32_t ratio_den,
139                                                spx_uint32_t in_rate,
140                                                spx_uint32_t out_rate,
141                                                int quality,
142                                                int *err);
143 
144 /** Destroy a resampler state.
145  * @param st Resampler state
146  */
147 void speex_resampler_destroy(SpeexResamplerState *st);
148 
149 /** Resample a float array. The input and output buffers must *not* overlap.
150  * @param st Resampler state
151  * @param channel_index Index of the channel to process for the multi-channel
152  * base (0 otherwise)
153  * @param in Input buffer
154  * @param in_len Number of input samples in the input buffer. Returns the
155  * number of samples processed
156  * @param out Output buffer
157  * @param out_len Size of the output buffer. Returns the number of samples written
158  */
159 int speex_resampler_process_float(SpeexResamplerState *st,
160                                    spx_uint32_t channel_index,
161                                    const float *in,
162                                    spx_uint32_t *in_len,
163                                    float *out,
164                                    spx_uint32_t *out_len);
165 
166 /** Resample an int array. The input and output buffers must *not* overlap.
167  * @param st Resampler state
168  * @param channel_index Index of the channel to process for the multi-channel
169  * base (0 otherwise)
170  * @param in Input buffer
171  * @param in_len Number of input samples in the input buffer. Returns the number
172  * of samples processed
173  * @param out Output buffer
174  * @param out_len Size of the output buffer. Returns the number of samples written
175  */
176 int speex_resampler_process_int(SpeexResamplerState *st,
177                                  spx_uint32_t channel_index,
178                                  const spx_int16_t *in,
179                                  spx_uint32_t *in_len,
180                                  spx_int16_t *out,
181                                  spx_uint32_t *out_len);
182 
183 /** Resample an interleaved float array. The input and output buffers must *not* overlap.
184  * @param st Resampler state
185  * @param in Input buffer
186  * @param in_len Number of input samples in the input buffer. Returns the number
187  * of samples processed. This is all per-channel.
188  * @param out Output buffer
189  * @param out_len Size of the output buffer. Returns the number of samples written.
190  * This is all per-channel.
191  */
192 int speex_resampler_process_interleaved_float(SpeexResamplerState *st,
193                                                const float *in,
194                                                spx_uint32_t *in_len,
195                                                float *out,
196                                                spx_uint32_t *out_len);
197 
198 /** Resample an interleaved int array. The input and output buffers must *not* overlap.
199  * @param st Resampler state
200  * @param in Input buffer
201  * @param in_len Number of input samples in the input buffer. Returns the number
202  * of samples processed. This is all per-channel.
203  * @param out Output buffer
204  * @param out_len Size of the output buffer. Returns the number of samples written.
205  * This is all per-channel.
206  */
207 int speex_resampler_process_interleaved_int(SpeexResamplerState *st,
208                                              const spx_int16_t *in,
209                                              spx_uint32_t *in_len,
210                                              spx_int16_t *out,
211                                              spx_uint32_t *out_len);
212 
213 /** Set (change) the input/output sampling rates (integer value).
214  * @param st Resampler state
215  * @param in_rate Input sampling rate (integer number of Hz).
216  * @param out_rate Output sampling rate (integer number of Hz).
217  */
218 int speex_resampler_set_rate(SpeexResamplerState *st,
219                               spx_uint32_t in_rate,
220                               spx_uint32_t out_rate);
221 
222 /** Get the current input/output sampling rates (integer value).
223  * @param st Resampler state
224  * @param in_rate Input sampling rate (integer number of Hz) copied.
225  * @param out_rate Output sampling rate (integer number of Hz) copied.
226  */
227 void speex_resampler_get_rate(SpeexResamplerState *st,
228                               spx_uint32_t *in_rate,
229                               spx_uint32_t *out_rate);
230 
231 /** Set (change) the input/output sampling rates and resampling ratio
232  * (fractional values in Hz supported).
233  * @param st Resampler state
234  * @param ratio_num Numerator of the sampling rate ratio
235  * @param ratio_den Denominator of the sampling rate ratio
236  * @param in_rate Input sampling rate rounded to the nearest integer (in Hz).
237  * @param out_rate Output sampling rate rounded to the nearest integer (in Hz).
238  */
239 int speex_resampler_set_rate_frac(SpeexResamplerState *st,
240                                    spx_uint32_t ratio_num,
241                                    spx_uint32_t ratio_den,
242                                    spx_uint32_t in_rate,
243                                    spx_uint32_t out_rate);
244 
245 /** Get the current resampling ratio. This will be reduced to the least
246  * common denominator.
247  * @param st Resampler state
248  * @param ratio_num Numerator of the sampling rate ratio copied
249  * @param ratio_den Denominator of the sampling rate ratio copied
250  */
251 void speex_resampler_get_ratio(SpeexResamplerState *st,
252                                spx_uint32_t *ratio_num,
253                                spx_uint32_t *ratio_den);
254 
255 /** Set (change) the conversion quality.
256  * @param st Resampler state
257  * @param quality Resampling quality between 0 and 10, where 0 has poor
258  * quality and 10 has very high quality.
259  */
260 int speex_resampler_set_quality(SpeexResamplerState *st,
261                                  int quality);
262 
263 /** Get the conversion quality.
264  * @param st Resampler state
265  * @param quality Resampling quality between 0 and 10, where 0 has poor
266  * quality and 10 has very high quality.
267  */
268 void speex_resampler_get_quality(SpeexResamplerState *st,
269                                  int *quality);
270 
271 /** Set (change) the input stride.
272  * @param st Resampler state
273  * @param stride Input stride
274  */
275 void speex_resampler_set_input_stride(SpeexResamplerState *st,
276                                       spx_uint32_t stride);
277 
278 /** Get the input stride.
279  * @param st Resampler state
280  * @param stride Input stride copied
281  */
282 void speex_resampler_get_input_stride(SpeexResamplerState *st,
283                                       spx_uint32_t *stride);
284 
285 /** Set (change) the output stride.
286  * @param st Resampler state
287  * @param stride Output stride
288  */
289 void speex_resampler_set_output_stride(SpeexResamplerState *st,
290                                       spx_uint32_t stride);
291 
292 /** Get the output stride.
293  * @param st Resampler state copied
294  * @param stride Output stride
295  */
296 void speex_resampler_get_output_stride(SpeexResamplerState *st,
297                                       spx_uint32_t *stride);
298 
299 /** Get the latency introduced by the resampler measured in input samples.
300  * @param st Resampler state
301  */
302 int speex_resampler_get_input_latency(SpeexResamplerState *st);
303 
304 /** Get the latency introduced by the resampler measured in output samples.
305  * @param st Resampler state
306  */
307 int speex_resampler_get_output_latency(SpeexResamplerState *st);
308 
309 /** Make sure that the first samples to go out of the resamplers don't have
310  * leading zeros. This is only useful before starting to use a newly created
311  * resampler. It is recommended to use that when resampling an audio file, as
312  * it will generate a file with the same length. For real-time processing,
313  * it is probably easier not to use this call (so that the output duration
314  * is the same for the first frame).
315  * @param st Resampler state
316  */
317 int speex_resampler_skip_zeros(SpeexResamplerState *st);
318 
319 /** Reset a resampler so a new (unrelated) stream can be processed.
320  * @param st Resampler state
321  */
322 int speex_resampler_reset_mem(SpeexResamplerState *st);
323 
324 /** Returns the English meaning for an error code
325  * @param err Error code
326  * @return English string
327  */
328 const char *speex_resampler_strerror(int err);
329 
330 #ifdef __cplusplus
331 }
332 #endif
333 
334 #endif
335