| 1 | /* Copyright (C) 2010-2020 The RetroArch team |
| 2 | * |
| 3 | * --------------------------------------------------------------------------------------- |
| 4 | * The following license statement only applies to this file (audio_resampler.h). |
| 5 | * --------------------------------------------------------------------------------------- |
| 6 | * |
| 7 | * Permission is hereby granted, free of charge, |
| 8 | * to any person obtaining a copy of this software and associated documentation files (the "Software"), |
| 9 | * to deal in the Software without restriction, including without limitation the rights to |
| 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, |
| 11 | * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: |
| 12 | * |
| 13 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. |
| 14 | * |
| 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, |
| 16 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
| 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
| 19 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| 21 | */ |
| 22 | |
| 23 | #ifndef __LIBRETRO_SDK_AUDIO_RESAMPLER_DRIVER_H |
| 24 | #define __LIBRETRO_SDK_AUDIO_RESAMPLER_DRIVER_H |
| 25 | |
| 26 | #include <stdint.h> |
| 27 | #include <stddef.h> |
| 28 | |
| 29 | #include <boolean.h> |
| 30 | #include <retro_common_api.h> |
| 31 | |
| 32 | RETRO_BEGIN_DECLS |
| 33 | |
| 34 | #define RESAMPLER_SIMD_SSE (1 << 0) |
| 35 | #define RESAMPLER_SIMD_SSE2 (1 << 1) |
| 36 | #define RESAMPLER_SIMD_VMX (1 << 2) |
| 37 | #define RESAMPLER_SIMD_VMX128 (1 << 3) |
| 38 | #define RESAMPLER_SIMD_AVX (1 << 4) |
| 39 | #define RESAMPLER_SIMD_NEON (1 << 5) |
| 40 | #define RESAMPLER_SIMD_SSE3 (1 << 6) |
| 41 | #define RESAMPLER_SIMD_SSSE3 (1 << 7) |
| 42 | #define RESAMPLER_SIMD_MMX (1 << 8) |
| 43 | #define RESAMPLER_SIMD_MMXEXT (1 << 9) |
| 44 | #define RESAMPLER_SIMD_SSE4 (1 << 10) |
| 45 | #define RESAMPLER_SIMD_SSE42 (1 << 11) |
| 46 | #define RESAMPLER_SIMD_AVX2 (1 << 12) |
| 47 | #define RESAMPLER_SIMD_VFPU (1 << 13) |
| 48 | #define RESAMPLER_SIMD_PS (1 << 14) |
| 49 | |
| 50 | enum resampler_quality |
| 51 | { |
| 52 | RESAMPLER_QUALITY_DONTCARE = 0, |
| 53 | RESAMPLER_QUALITY_LOWEST, |
| 54 | RESAMPLER_QUALITY_LOWER, |
| 55 | RESAMPLER_QUALITY_NORMAL, |
| 56 | RESAMPLER_QUALITY_HIGHER, |
| 57 | RESAMPLER_QUALITY_HIGHEST |
| 58 | }; |
| 59 | |
| 60 | /* A bit-mask of all supported SIMD instruction sets. |
| 61 | * Allows an implementation to pick different |
| 62 | * resampler_implementation structs. |
| 63 | */ |
| 64 | typedef unsigned resampler_simd_mask_t; |
| 65 | |
| 66 | #define RESAMPLER_API_VERSION 1 |
| 67 | |
| 68 | /** |
| 69 | * A struct that groups the input and output of a resampler. |
| 70 | */ |
| 71 | struct resampler_data |
| 72 | { |
| 73 | /** |
| 74 | * The buffer containing the data to be resampled. |
| 75 | */ |
| 76 | const float *data_in; |
| 77 | |
| 78 | /** |
| 79 | * The buffer that will be used to store resampled output. |
| 80 | * Must be allocated in advance, and must not be the same as data_in. |
| 81 | */ |
| 82 | float *data_out; |
| 83 | |
| 84 | /** |
| 85 | * The size of ::data_in, in frames (\em not bytes or samples). |
| 86 | * For example, 32-bit stereo frames would consist of 8 bytes |
| 87 | * (two 4-byte floats per frame). |
| 88 | */ |
| 89 | size_t input_frames; |
| 90 | |
| 91 | /** |
| 92 | * The number of frames (\em not bytes or samples) that the resampler produced. |
| 93 | * This value is set by the resampler. |
| 94 | * The resampler may not provide the same number of frames with each use, |
| 95 | * so be sure to check this value. |
| 96 | */ |
| 97 | size_t output_frames; |
| 98 | |
| 99 | /** |
| 100 | * The desired ratio of output_frames to input_frames. |
| 101 | * This value is used to determine the number of frames written to \c data_out. |
| 102 | * If this value is (almost) equal to 1, |
| 103 | * then resampling may be skipped. |
| 104 | */ |
| 105 | double ratio; |
| 106 | }; |
| 107 | |
| 108 | /* Returns true if config key was found. Otherwise, |
| 109 | * returns false, and sets value to default value. |
| 110 | */ |
| 111 | typedef int (*resampler_config_get_float_t)(void *userdata, |
| 112 | const char *key, float *value, float default_value); |
| 113 | |
| 114 | typedef int (*resampler_config_get_int_t)(void *userdata, |
| 115 | const char *key, int *value, int default_value); |
| 116 | |
| 117 | /* Allocates an array with values. free() with resampler_config_free_t. */ |
| 118 | typedef int (*resampler_config_get_float_array_t)(void *userdata, |
| 119 | const char *key, float **values, unsigned *out_num_values, |
| 120 | const float *default_values, unsigned num_default_values); |
| 121 | |
| 122 | typedef int (*resampler_config_get_int_array_t)(void *userdata, |
| 123 | const char *key, int **values, unsigned *out_num_values, |
| 124 | const int *default_values, unsigned num_default_values); |
| 125 | |
| 126 | typedef int (*resampler_config_get_string_t)(void *userdata, |
| 127 | const char *key, char **output, const char *default_output); |
| 128 | |
| 129 | /* Calls free() in host runtime. Sometimes needed on Windows. |
| 130 | * free() on NULL is fine. */ |
| 131 | typedef void (*resampler_config_free_t)(void *ptr); |
| 132 | |
| 133 | struct resampler_config |
| 134 | { |
| 135 | resampler_config_get_float_t get_float; |
| 136 | resampler_config_get_int_t get_int; |
| 137 | |
| 138 | resampler_config_get_float_array_t get_float_array; |
| 139 | resampler_config_get_int_array_t get_int_array; |
| 140 | |
| 141 | resampler_config_get_string_t get_string; |
| 142 | /* Avoid problems where resampler plug and host are |
| 143 | * linked against different C runtimes. */ |
| 144 | resampler_config_free_t free; |
| 145 | }; |
| 146 | |
| 147 | /* Bandwidth factor. Will be < 1.0 for downsampling, > 1.0 for upsampling. |
| 148 | * Corresponds to expected resampling ratio. */ |
| 149 | typedef void *(*resampler_init_t)(const struct resampler_config *config, |
| 150 | double bandwidth_mod, enum resampler_quality quality, |
| 151 | resampler_simd_mask_t mask); |
| 152 | |
| 153 | /* Frees the handle. */ |
| 154 | typedef void (*resampler_free_t)(void *data); |
| 155 | |
| 156 | /* Processes input data. */ |
| 157 | typedef void (*resampler_process_t)(void *_data, struct resampler_data *data); |
| 158 | |
| 159 | typedef struct retro_resampler |
| 160 | { |
| 161 | resampler_init_t init; |
| 162 | resampler_process_t process; |
| 163 | resampler_free_t free; |
| 164 | |
| 165 | /* Must be RESAMPLER_API_VERSION */ |
| 166 | unsigned api_version; |
| 167 | |
| 168 | /* Human readable identifier of implementation. */ |
| 169 | const char *ident; |
| 170 | |
| 171 | /* Computer-friendly short version of ident. |
| 172 | * Lower case, no spaces and special characters, etc. */ |
| 173 | const char *short_ident; |
| 174 | } retro_resampler_t; |
| 175 | |
| 176 | typedef struct audio_frame_float |
| 177 | { |
| 178 | float l; |
| 179 | float r; |
| 180 | } audio_frame_float_t; |
| 181 | |
| 182 | extern retro_resampler_t sinc_resampler; |
| 183 | #ifdef HAVE_CC_RESAMPLER |
| 184 | extern retro_resampler_t CC_resampler; |
| 185 | #endif |
| 186 | extern retro_resampler_t nearest_resampler; |
| 187 | |
| 188 | /** |
| 189 | * audio_resampler_driver_find_handle: |
| 190 | * @index : index of driver to get handle to. |
| 191 | * |
| 192 | * Returns: handle to audio resampler driver at index. Can be NULL |
| 193 | * if nothing found. |
| 194 | **/ |
| 195 | const void *audio_resampler_driver_find_handle(int index); |
| 196 | |
| 197 | /** |
| 198 | * audio_resampler_driver_find_ident: |
| 199 | * @index : index of driver to get handle to. |
| 200 | * |
| 201 | * Returns: Human-readable identifier of audio resampler driver at index. |
| 202 | * Can be NULL if nothing found. |
| 203 | **/ |
| 204 | const char *audio_resampler_driver_find_ident(int index); |
| 205 | |
| 206 | /** |
| 207 | * retro_resampler_realloc: |
| 208 | * @re : Resampler handle |
| 209 | * @backend : Resampler backend that is about to be set. |
| 210 | * @ident : Identifier name for resampler we want. |
| 211 | * @bw_ratio : Bandwidth ratio. |
| 212 | * |
| 213 | * Reallocates resampler. Will free previous handle before |
| 214 | * allocating a new one. If ident is NULL, first resampler will be used. |
| 215 | * |
| 216 | * Returns: true (1) if successful, otherwise false (0). |
| 217 | **/ |
| 218 | bool retro_resampler_realloc(void **re, const retro_resampler_t **backend, |
| 219 | const char *ident, enum resampler_quality quality, double bw_ratio); |
| 220 | |
| 221 | RETRO_END_DECLS |
| 222 | |
| 223 | #endif |