1 /*
2 * Copyright (c) 2019-2025 Allwinner Technology Co., Ltd. ALL rights reserved.
3 *
4 * Allwinner is a trademark of Allwinner Technology Co.,Ltd., registered in
5 * the the people's Republic of China and other countries.
6 * All Allwinner Technology Co.,Ltd. trademarks are used with permission.
7 *
8 * DISCLAIMER
9 * THIRD PARTY LICENCES MAY BE REQUIRED TO IMPLEMENT THE SOLUTION/PRODUCT.
10 * IF YOU NEED TO INTEGRATE THIRD PARTY’S TECHNOLOGY (SONY, DTS, DOLBY, AVS OR MPEGLA, ETC.)
11 * IN ALLWINNERS’SDK OR PRODUCTS, YOU SHALL BE SOLELY RESPONSIBLE TO OBTAIN
12 * ALL APPROPRIATELY REQUIRED THIRD PARTY LICENCES.
13 * ALLWINNER SHALL HAVE NO WARRANTY, INDEMNITY OR OTHER OBLIGATIONS WITH RESPECT TO MATTERS
14 * COVERED UNDER ANY REQUIRED THIRD PARTY LICENSE.
15 * YOU ARE SOLELY RESPONSIBLE FOR YOUR USAGE OF THIRD PARTY’S TECHNOLOGY.
16 *
17 *
18 * THIS SOFTWARE IS PROVIDED BY ALLWINNER"AS IS" AND TO THE MAXIMUM EXTENT
19 * PERMITTED BY LAW, ALLWINNER EXPRESSLY DISCLAIMS ALL WARRANTIES OF ANY KIND,
20 * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION REGARDING
21 * THE TITLE, NON-INFRINGEMENT, ACCURACY, CONDITION, COMPLETENESS, PERFORMANCE
22 * OR MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23 * IN NO EVENT SHALL ALLWINNER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS, OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
30 * OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32 
33 
34 #ifndef SPEEX_RESAMPLER_H
35 #define SPEEX_RESAMPLER_H
36 
37 
38 #define spx_int16_t short
39 #define spx_int32_t int
40 #define spx_uint16_t unsigned short
41 #define spx_uint32_t unsigned int
42 
43 
44 #ifdef __cplusplus
45 extern "C" {
46 #endif
47 
48 #define SPEEX_RESAMPLER_QUALITY_MAX 10
49 #define SPEEX_RESAMPLER_QUALITY_MIN 0
50 #define SPEEX_RESAMPLER_QUALITY_DEFAULT 4
51 #define SPEEX_RESAMPLER_QUALITY_VOIP 3
52 #define SPEEX_RESAMPLER_QUALITY_DESKTOP 5
53 
54 enum {
55    RESAMPLER_ERR_SUCCESS         = 0,
56    RESAMPLER_ERR_ALLOC_FAILED    = 1,
57    RESAMPLER_ERR_BAD_STATE       = 2,
58    RESAMPLER_ERR_INVALID_ARG     = 3,
59    RESAMPLER_ERR_PTR_OVERLAP     = 4,
60 
61    RESAMPLER_ERR_MAX_ERROR
62 };
63 
64 struct SpeexResamplerState_;
65 typedef struct SpeexResamplerState_ SpeexResamplerState;
66 
67 /** Create a new resampler with integer input and output rates.
68  * @param nb_channels Number of channels to be processed
69  * @param in_rate Input sampling rate (integer number of Hz).
70  * @param out_rate Output sampling rate (integer number of Hz).
71  * @param quality Resampling quality between 0 and 10, where 0 has poor quality
72  * and 10 has very high quality.
73  * @return Newly created resampler state
74  * @retval NULL Error: not enough memory
75  */
76 SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels,
77                                           spx_uint32_t in_rate,
78                                           spx_uint32_t out_rate,
79                                           int quality,
80                                           int *err);
81 
82 /** Create a new resampler with fractional input/output rates. The sampling
83  * rate ratio is an arbitrary rational number with both the numerator and
84  * denominator being 32-bit integers.
85  * @param nb_channels Number of channels to be processed
86  * @param ratio_num Numerator of the sampling rate ratio
87  * @param ratio_den Denominator of the sampling rate ratio
88  * @param in_rate Input sampling rate rounded to the nearest integer (in Hz).
89  * @param out_rate Output sampling rate rounded to the nearest integer (in Hz).
90  * @param quality Resampling quality between 0 and 10, where 0 has poor quality
91  * and 10 has very high quality.
92  * @return Newly created resampler state
93  * @retval NULL Error: not enough memory
94  */
95 SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels,
96                                                spx_uint32_t ratio_num,
97                                                spx_uint32_t ratio_den,
98                                                spx_uint32_t in_rate,
99                                                spx_uint32_t out_rate,
100                                                int quality,
101                                                int *err);
102 
103 /** Destroy a resampler state.
104  * @param st Resampler state
105  */
106 void speex_resampler_destroy(SpeexResamplerState *st);
107 
108 /** Resample a float array. The input and output buffers must *not* overlap.
109  * @param st Resampler state
110  * @param channel_index Index of the channel to process for the multi-channel
111  * base (0 otherwise)
112  * @param in Input buffer
113  * @param in_len Number of input samples in the input buffer. Returns the
114  * number of samples processed
115  * @param out Output buffer
116  * @param out_len Size of the output buffer. Returns the number of samples written
117  */
118 int speex_resampler_process_float(SpeexResamplerState *st,
119                                    spx_uint32_t channel_index,
120                                    const float *in,
121                                    spx_uint32_t *in_len,
122                                    float *out,
123                                    spx_uint32_t *out_len);
124 
125 /** Resample an int array. The input and output buffers must *not* overlap.
126  * @param st Resampler state
127  * @param channel_index Index of the channel to process for the multi-channel
128  * base (0 otherwise)
129  * @param in Input buffer
130  * @param in_len Number of input samples in the input buffer. Returns the number
131  * of samples processed
132  * @param out Output buffer
133  * @param out_len Size of the output buffer. Returns the number of samples written
134  */
135 int speex_resampler_process_int(SpeexResamplerState *st,
136                                  spx_uint32_t channel_index,
137                                  const spx_int16_t *in,
138                                  spx_uint32_t *in_len,
139                                  spx_int16_t *out,
140                                  spx_uint32_t *out_len);
141 
142 /** Resample an interleaved float array. The input and output buffers must *not* overlap.
143  * @param st Resampler state
144  * @param in Input buffer
145  * @param in_len Number of input samples in the input buffer. Returns the number
146  * of samples processed. This is all per-channel.
147  * @param out Output buffer
148  * @param out_len Size of the output buffer. Returns the number of samples written.
149  * This is all per-channel.
150  */
151 int speex_resampler_process_interleaved_float(SpeexResamplerState *st,
152                                                const float *in,
153                                                spx_uint32_t *in_len,
154                                                float *out,
155                                                spx_uint32_t *out_len);
156 
157 /** Resample an interleaved int array. The input and output buffers must *not* overlap.
158  * @param st Resampler state
159  * @param in Input buffer
160  * @param in_len Number of input samples in the input buffer. Returns the number
161  * of samples processed. This is all per-channel.
162  * @param out Output buffer
163  * @param out_len Size of the output buffer. Returns the number of samples written.
164  * This is all per-channel.
165  */
166 int speex_resampler_process_interleaved_int(SpeexResamplerState *st,
167                                              const spx_int16_t *in,
168                                              spx_uint32_t *in_len,
169                                              spx_int16_t *out,
170                                              spx_uint32_t *out_len);
171 
172 /** Set (change) the input/output sampling rates (integer value).
173  * @param st Resampler state
174  * @param in_rate Input sampling rate (integer number of Hz).
175  * @param out_rate Output sampling rate (integer number of Hz).
176  */
177 int speex_resampler_set_rate(SpeexResamplerState *st,
178                               spx_uint32_t in_rate,
179                               spx_uint32_t out_rate);
180 
181 /** Get the current input/output sampling rates (integer value).
182  * @param st Resampler state
183  * @param in_rate Input sampling rate (integer number of Hz) copied.
184  * @param out_rate Output sampling rate (integer number of Hz) copied.
185  */
186 void speex_resampler_get_rate(SpeexResamplerState *st,
187                               spx_uint32_t *in_rate,
188                               spx_uint32_t *out_rate);
189 
190 /** Set (change) the input/output sampling rates and resampling ratio
191  * (fractional values in Hz supported).
192  * @param st Resampler state
193  * @param ratio_num Numerator of the sampling rate ratio
194  * @param ratio_den Denominator of the sampling rate ratio
195  * @param in_rate Input sampling rate rounded to the nearest integer (in Hz).
196  * @param out_rate Output sampling rate rounded to the nearest integer (in Hz).
197  */
198 int speex_resampler_set_rate_frac(SpeexResamplerState *st,
199                                    spx_uint32_t ratio_num,
200                                    spx_uint32_t ratio_den,
201                                    spx_uint32_t in_rate,
202                                    spx_uint32_t out_rate);
203 
204 /** Get the current resampling ratio. This will be reduced to the least
205  * common denominator.
206  * @param st Resampler state
207  * @param ratio_num Numerator of the sampling rate ratio copied
208  * @param ratio_den Denominator of the sampling rate ratio copied
209  */
210 void speex_resampler_get_ratio(SpeexResamplerState *st,
211                                spx_uint32_t *ratio_num,
212                                spx_uint32_t *ratio_den);
213 
214 /** Set (change) the conversion quality.
215  * @param st Resampler state
216  * @param quality Resampling quality between 0 and 10, where 0 has poor
217  * quality and 10 has very high quality.
218  */
219 int speex_resampler_set_quality(SpeexResamplerState *st,
220                                  int quality);
221 
222 /** Get the conversion quality.
223  * @param st Resampler state
224  * @param quality Resampling quality between 0 and 10, where 0 has poor
225  * quality and 10 has very high quality.
226  */
227 void speex_resampler_get_quality(SpeexResamplerState *st,
228                                  int *quality);
229 
230 /** Set (change) the input stride.
231  * @param st Resampler state
232  * @param stride Input stride
233  */
234 void speex_resampler_set_input_stride(SpeexResamplerState *st,
235                                       spx_uint32_t stride);
236 
237 /** Get the input stride.
238  * @param st Resampler state
239  * @param stride Input stride copied
240  */
241 void speex_resampler_get_input_stride(SpeexResamplerState *st,
242                                       spx_uint32_t *stride);
243 
244 /** Set (change) the output stride.
245  * @param st Resampler state
246  * @param stride Output stride
247  */
248 void speex_resampler_set_output_stride(SpeexResamplerState *st,
249                                       spx_uint32_t stride);
250 
251 /** Get the output stride.
252  * @param st Resampler state copied
253  * @param stride Output stride
254  */
255 void speex_resampler_get_output_stride(SpeexResamplerState *st,
256                                       spx_uint32_t *stride);
257 
258 /** Get the latency introduced by the resampler measured in input samples.
259  * @param st Resampler state
260  */
261 int speex_resampler_get_input_latency(SpeexResamplerState *st);
262 
263 /** Get the latency introduced by the resampler measured in output samples.
264  * @param st Resampler state
265  */
266 int speex_resampler_get_output_latency(SpeexResamplerState *st);
267 
268 /** Make sure that the first samples to go out of the resamplers don't have
269  * leading zeros. This is only useful before starting to use a newly created
270  * resampler. It is recommended to use that when resampling an audio file, as
271  * it will generate a file with the same length. For real-time processing,
272  * it is probably easier not to use this call (so that the output duration
273  * is the same for the first frame).
274  * @param st Resampler state
275  */
276 int speex_resampler_skip_zeros(SpeexResamplerState *st);
277 
278 /** Reset a resampler so a new (unrelated) stream can be processed.
279  * @param st Resampler state
280  */
281 int speex_resampler_reset_mem(SpeexResamplerState *st);
282 
283 /** Returns the English meaning for an error code
284  * @param err Error code
285  * @return English string
286  */
287 const char *speex_resampler_strerror(int err);
288 
289 #ifdef __cplusplus
290 }
291 #endif
292 
293 #endif
294