Unified · Split
| @@ -110,6 +110,9 @@ typedef struct SRC_PRIVATE_tag · 109 unmodified lines | ||
| 110 | 110 | /* State reset. */ |
| 111 | 111 | void (*reset) (struct SRC_PRIVATE_tag *psrc) ; |
| 112 | 112 | |
| 113 | + /* State clone. */ | |
| 114 | + int (*copy) (struct SRC_PRIVATE_tag *from, struct SRC_PRIVATE_tag *to) ; | |
| 115 | + | |
| 113 | 116 | /* Data specific to SRC_MODE_CALLBACK. */ |
| 114 | 117 | src_callback_t callback_func ; |
| 115 | 118 | void *user_callback_data ; |
| @@ -53,6 +53,34 @@ src_new (int converter_type, int channels, int *error) · 52 unmodified lines | ||
| 53 | 53 | return (SRC_STATE*) psrc ; |
| 54 | 54 | } /* src_new */ |
| 55 | 55 | |
| 56 | +SRC_STATE* | |
| 57 | +src_clone (SRC_STATE* orig, int *error) | |
| 58 | +{ | |
| 59 | + SRC_PRIVATE *psrc ; | |
| 60 | + int copy_error ; | |
| 61 | + | |
| 62 | + if (error) | |
| 63 | + *error = SRC_ERR_NO_ERROR ; | |
| 64 | + | |
| 65 | + if ((psrc = calloc (1, sizeof (*psrc))) == NULL) | |
| 66 | + { if (error) | |
| 67 | + *error = SRC_ERR_MALLOC_FAILED ; | |
| 68 | + return NULL ; | |
| 69 | + } ; | |
| 70 | + | |
| 71 | + SRC_PRIVATE *orig_priv = (SRC_PRIVATE*) orig ; | |
| 72 | + memcpy (psrc, orig_priv, sizeof (SRC_PRIVATE)) ; | |
| 73 | + | |
| 74 | + if ((copy_error = orig_priv->copy (orig_priv, psrc)) != SRC_ERR_NO_ERROR) | |
| 75 | + { if (error) | |
| 76 | + *error = copy_error ; | |
| 77 | + free (psrc) ; | |
| 78 | + psrc = NULL ; | |
| 79 | + } ; | |
| 80 | + | |
| 81 | + return (SRC_STATE*) psrc ; | |
| 82 | +} | |
| 83 | + | |
| 56 | 84 | SRC_STATE* |
| 57 | 85 | src_callback_new (src_callback_t func, int converter_type, int channels, int *error, void* cb_data) |
| 58 | 86 | { SRC_STATE *src_state ; |
| @@ -245,7 +273,7 @@ src_callback_read (SRC_STATE *state, double src_ratio, long frames, float *data) · 186 unmodified lines | ||
| 245 | 273 | |
| 246 | 274 | if (error != 0) |
| 247 | 275 | { psrc->error = error ; |
| 248 | − return 0 ; | |
| 276 | + return 0 ; | |
| 249 | 277 | } ; |
| 250 | 278 | |
| 251 | 279 | return output_frames_gen ; |
| @@ -25,7 +25,7 @@ typedef struct SRC_STATE_tag SRC_STATE ; · 24 unmodified lines | ||
| 25 | 25 | /* SRC_DATA is used to pass data to src_simple() and src_process(). */ |
| 26 | 26 | typedef struct |
| 27 | 27 | { const float *data_in ; |
| 28 | − float *data_out ; | |
| 28 | + float *data_out ; | |
| 29 | 29 | |
| 30 | 30 | long input_frames, output_frames ; |
| 31 | 31 | long input_frames_used, output_frames_gen ; |
| @@ -54,6 +54,12 @@ typedef long (*src_callback_t) (void *cb_data, float **data) ; · 22 unmodified lines | ||
| 54 | 54 | |
| 55 | 55 | SRC_STATE* src_new (int converter_type, int channels, int *error) ; |
| 56 | 56 | |
| 57 | +/* | |
| 58 | +** Clone a handle : return an anonymous pointer to a new converter | |
| 59 | +** containing the same internal state as orig. Error returned in *error. | |
| 60 | +*/ | |
| 61 | +SRC_STATE* src_clone (SRC_STATE* orig, int *error) ; | |
| 62 | + | |
| 57 | 63 | /* |
| 58 | 64 | ** Initilisation for callback based API : return an anonymous pointer to the |
| 59 | 65 | ** internal state of the converter. Choose a converter from the enums below. |
| @@ -16,6 +16,7 @@ · 15 unmodified lines | ||
| 16 | 16 | |
| 17 | 17 | static int linear_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ; |
| 18 | 18 | static void linear_reset (SRC_PRIVATE *psrc) ; |
| 19 | +static int linear_copy (SRC_PRIVATE *from, SRC_PRIVATE *to) ; | |
| 19 | 20 | |
| 20 | 21 | /*======================================================================================== |
| 21 | 22 | */ |
| @@ -183,6 +184,7 @@ linear_set_converter (SRC_PRIVATE *psrc, int src_enum) · 161 unmodified lines | ||
| 183 | 184 | psrc->const_process = linear_vari_process ; |
| 184 | 185 | psrc->vari_process = linear_vari_process ; |
| 185 | 186 | psrc->reset = linear_reset ; |
| 187 | + psrc->copy = linear_copy ; | |
| 186 | 188 | |
| 187 | 189 | linear_reset (psrc) ; |
| 188 | 190 | |
| @@ -207,3 +209,21 @@ linear_reset (SRC_PRIVATE *psrc) · 18 unmodified lines | ||
| 207 | 209 | return ; |
| 208 | 210 | } /* linear_reset */ |
| 209 | 211 | |
| 212 | +static int | |
| 213 | +linear_copy (SRC_PRIVATE *from, SRC_PRIVATE *to) | |
| 214 | +{ | |
| 215 | + if (from->private_data == NULL) | |
| 216 | + return SRC_ERR_NO_PRIVATE ; | |
| 217 | + | |
| 218 | + LINEAR_DATA *to_priv = NULL ; | |
| 219 | + LINEAR_DATA* from_priv = (LINEAR_DATA*) from->private_data ; | |
| 220 | + size_t private_size = sizeof (*to_priv) + from_priv->channels * sizeof (float) ; | |
| 221 | + | |
| 222 | + if ((to_priv = calloc (1, private_size)) == NULL) | |
| 223 | + return SRC_ERR_MALLOC_FAILED ; | |
| 224 | + | |
| 225 | + memcpy (to_priv, from_priv, private_size) ; | |
| 226 | + to->private_data = to_priv ; | |
| 227 | + | |
| 228 | + return SRC_ERR_NO_ERROR ; | |
| 229 | +} /* linear_copy */ | |
| @@ -66,6 +66,7 @@ static int sinc_mono_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ; · 65 unmodified lines | ||
| 66 | 66 | static int prepare_data (SINC_FILTER *filter, SRC_DATA *data, int half_filter_chan_len) WARN_UNUSED ; |
| 67 | 67 | |
| 68 | 68 | static void sinc_reset (SRC_PRIVATE *psrc) ; |
| 69 | +static int sinc_copy (SRC_PRIVATE *from, SRC_PRIVATE *to) ; | |
| 69 | 70 | |
| 70 | 71 | static inline increment_t |
| 71 | 72 | double_to_fp (double x) |
| @@ -181,6 +182,7 @@ sinc_set_converter (SRC_PRIVATE *psrc, int src_enum) · 109 unmodified lines | ||
| 181 | 182 | psrc->vari_process = sinc_multichan_vari_process ; |
| 182 | 183 | } ; |
| 183 | 184 | psrc->reset = sinc_reset ; |
| 185 | + psrc->copy = sinc_copy ; | |
| 184 | 186 | |
| 185 | 187 | switch (src_enum) |
| 186 | 188 | { case SRC_SINC_FASTEST : |
| @@ -253,6 +255,25 @@ sinc_reset (SRC_PRIVATE *psrc) · 66 unmodified lines | ||
| 253 | 255 | memset (filter->buffer + filter->b_len, 0xAA, filter->channels * sizeof (filter->buffer [0])) ; |
| 254 | 256 | } /* sinc_reset */ |
| 255 | 257 | |
| 258 | +static int | |
| 259 | +sinc_copy (SRC_PRIVATE *from, SRC_PRIVATE *to) | |
| 260 | +{ | |
| 261 | + if (from->private_data == NULL) | |
| 262 | + return SRC_ERR_NO_PRIVATE ; | |
| 263 | + | |
| 264 | + SINC_FILTER *to_filter = NULL ; | |
| 265 | + SINC_FILTER* from_filter = (SINC_FILTER*) from->private_data ; | |
| 266 | + size_t private_length = sizeof (SINC_FILTER) + sizeof (from_filter->buffer [0]) * (from_filter->b_len + from_filter->channels) ; | |
| 267 | + | |
| 268 | + if ((to_filter = calloc (1, private_length)) == NULL) | |
| 269 | + return SRC_ERR_MALLOC_FAILED ; | |
| 270 | + | |
| 271 | + memcpy (to_filter, from_filter, private_length) ; | |
| 272 | + to->private_data = to_filter ; | |
| 273 | + | |
| 274 | + return SRC_ERR_NO_ERROR ; | |
| 275 | +} /* sinc_copy */ | |
| 276 | + | |
| 256 | 277 | /*======================================================================================== |
| 257 | 278 | ** Beware all ye who dare pass this point. There be dragons here. |
| 258 | 279 | */ |
| @@ -16,6 +16,7 @@ · 15 unmodified lines | ||
| 16 | 16 | |
| 17 | 17 | static int zoh_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ; |
| 18 | 18 | static void zoh_reset (SRC_PRIVATE *psrc) ; |
| 19 | +static int zoh_copy (SRC_PRIVATE *from, SRC_PRIVATE *to) ; | |
| 19 | 20 | |
| 20 | 21 | /*======================================================================================== |
| 21 | 22 | */ |
| @@ -174,6 +175,7 @@ zoh_set_converter (SRC_PRIVATE *psrc, int src_enum) · 152 unmodified lines | ||
| 174 | 175 | psrc->const_process = zoh_vari_process ; |
| 175 | 176 | psrc->vari_process = zoh_vari_process ; |
| 176 | 177 | psrc->reset = zoh_reset ; |
| 178 | + psrc->copy = zoh_copy ; | |
| 177 | 179 | |
| 178 | 180 | zoh_reset (psrc) ; |
| 179 | 181 | |
| @@ -198,3 +200,21 @@ zoh_reset (SRC_PRIVATE *psrc) · 18 unmodified lines | ||
| 198 | 200 | return ; |
| 199 | 201 | } /* zoh_reset */ |
| 200 | 202 | |
| 203 | +static int | |
| 204 | +zoh_copy (SRC_PRIVATE *from, SRC_PRIVATE *to) | |
| 205 | +{ | |
| 206 | + if (from->private_data == NULL) | |
| 207 | + return SRC_ERR_NO_PRIVATE ; | |
| 208 | + | |
| 209 | + ZOH_DATA *to_priv = NULL ; | |
| 210 | + ZOH_DATA* from_priv = (ZOH_DATA*) from->private_data ; | |
| 211 | + size_t private_size = sizeof (*to_priv) + from_priv->channels * sizeof (float) ; | |
| 212 | + | |
| 213 | + if ((to_priv = calloc (1, private_size)) == NULL) | |
| 214 | + return SRC_ERR_MALLOC_FAILED ; | |
| 215 | + | |
| 216 | + memcpy (to_priv, from_priv, private_size) ; | |
| 217 | + to->private_data = to_priv ; | |
| 218 | + | |
| 219 | + return SRC_ERR_NO_ERROR ; | |
| 220 | +} /* zoh_copy */ | |