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