Unified · Split
| @@ -110,6 +110,9 @@ typedef struct SRC_PRIVATE_tag · 109 unmodified lines | |||
| 110 | /* State reset. */ | 110 | /* State reset. */ |
| 111 | void (*reset) (struct SRC_PRIVATE_tag *psrc) ; | 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 | /* Data specific to SRC_MODE_CALLBACK. */ | 116 | /* Data specific to SRC_MODE_CALLBACK. */ |
| 114 | src_callback_t callback_func ; | 117 | src_callback_t callback_func ; |
| 115 | void *user_callback_data ; | 118 | void *user_callback_data ; |
| @@ -53,6 +53,34 @@ src_new (int converter_type, int channels, int *error) · 52 unmodified lines | |||
| 53 | return (SRC_STATE*) psrc ; | 53 | return (SRC_STATE*) psrc ; |
| 54 | } /* src_new */ | 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 | SRC_STATE* | 84 | SRC_STATE* |
| 57 | src_callback_new (src_callback_t func, int converter_type, int channels, int *error, void* cb_data) | 85 | src_callback_new (src_callback_t func, int converter_type, int channels, int *error, void* cb_data) |
| 58 | { SRC_STATE *src_state ; | 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 | if (error != 0) | 274 | if (error != 0) |
| 247 | { psrc->error = error ; | 275 | { psrc->error = error ; |
| 248 | return 0 ; | 276 | return 0 ; |
| 249 | } ; | 277 | } ; |
| 250 | 278 | ||
| 251 | return output_frames_gen ; | 279 | return output_frames_gen ; |
| @@ -25,7 +25,7 @@ typedef struct SRC_STATE_tag SRC_STATE ; · 24 unmodified lines | |||
| 25 | /* SRC_DATA is used to pass data to src_simple() and src_process(). */ | 25 | /* SRC_DATA is used to pass data to src_simple() and src_process(). */ |
| 26 | typedef struct | 26 | typedef struct |
| 27 | { const float *data_in ; | 27 | { const float *data_in ; |
| 28 | float *data_out ; | 28 | float *data_out ; |
| 29 | 29 | ||
| 30 | long input_frames, output_frames ; | 30 | long input_frames, output_frames ; |
| 31 | long input_frames_used, output_frames_gen ; | 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 | SRC_STATE* src_new (int converter_type, int channels, int *error) ; | 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 | ** Initilisation for callback based API : return an anonymous pointer to the | 64 | ** Initilisation for callback based API : return an anonymous pointer to the |
| 59 | ** internal state of the converter. Choose a converter from the enums below. | 65 | ** internal state of the converter. Choose a converter from the enums below. |
| @@ -16,6 +16,7 @@ · 15 unmodified lines | |||
| 16 | 16 | ||
| 17 | static int linear_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ; | 17 | static int linear_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ; |
| 18 | static void linear_reset (SRC_PRIVATE *psrc) ; | 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 | psrc->const_process = linear_vari_process ; | 184 | psrc->const_process = linear_vari_process ; |
| 184 | psrc->vari_process = linear_vari_process ; | 185 | psrc->vari_process = linear_vari_process ; |
| 185 | psrc->reset = linear_reset ; | 186 | psrc->reset = linear_reset ; |
| 187 | psrc->copy = linear_copy ; | ||
| 186 | 188 | ||
| 187 | linear_reset (psrc) ; | 189 | linear_reset (psrc) ; |
| 188 | 190 | ||
| @@ -207,3 +209,21 @@ linear_reset (SRC_PRIVATE *psrc) · 18 unmodified lines | |||
| 207 | return ; | 209 | return ; |
| 208 | } /* linear_reset */ | 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 | static int prepare_data (SINC_FILTER *filter, SRC_DATA *data, int half_filter_chan_len) WARN_UNUSED ; | 66 | static int prepare_data (SINC_FILTER *filter, SRC_DATA *data, int half_filter_chan_len) WARN_UNUSED ; |
| 67 | 67 | ||
| 68 | static void sinc_reset (SRC_PRIVATE *psrc) ; | 68 | static void sinc_reset (SRC_PRIVATE *psrc) ; |
| 69 | static int sinc_copy (SRC_PRIVATE *from, SRC_PRIVATE *to) ; | ||
| 69 | 70 | ||
| 70 | static inline increment_t | 71 | static inline increment_t |
| 71 | double_to_fp (double x) | 72 | double_to_fp (double x) |
| @@ -181,6 +182,7 @@ sinc_set_converter (SRC_PRIVATE *psrc, int src_enum) · 109 unmodified lines | |||
| 181 | psrc->vari_process = sinc_multichan_vari_process ; | 182 | psrc->vari_process = sinc_multichan_vari_process ; |
| 182 | } ; | 183 | } ; |
| 183 | psrc->reset = sinc_reset ; | 184 | psrc->reset = sinc_reset ; |
| 185 | psrc->copy = sinc_copy ; | ||
| 184 | 186 | ||
| 185 | switch (src_enum) | 187 | switch (src_enum) |
| 186 | { case SRC_SINC_FASTEST : | 188 | { case SRC_SINC_FASTEST : |
| @@ -253,6 +255,25 @@ sinc_reset (SRC_PRIVATE *psrc) · 66 unmodified lines | |||
| 253 | memset (filter->buffer + filter->b_len, 0xAA, filter->channels * sizeof (filter->buffer [0])) ; | 255 | memset (filter->buffer + filter->b_len, 0xAA, filter->channels * sizeof (filter->buffer [0])) ; |
| 254 | } /* sinc_reset */ | 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 | ** Beware all ye who dare pass this point. There be dragons here. | 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 | static int zoh_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ; | 17 | static int zoh_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ; |
| 18 | static void zoh_reset (SRC_PRIVATE *psrc) ; | 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 | psrc->const_process = zoh_vari_process ; | 175 | psrc->const_process = zoh_vari_process ; |
| 175 | psrc->vari_process = zoh_vari_process ; | 176 | psrc->vari_process = zoh_vari_process ; |
| 176 | psrc->reset = zoh_reset ; | 177 | psrc->reset = zoh_reset ; |
| 178 | psrc->copy = zoh_copy ; | ||
| 177 | 179 | ||
| 178 | zoh_reset (psrc) ; | 180 | zoh_reset (psrc) ; |
| 179 | 181 | ||
| @@ -198,3 +200,21 @@ zoh_reset (SRC_PRIVATE *psrc) · 18 unmodified lines | |||
| 198 | return ; | 200 | return ; |
| 199 | } /* zoh_reset */ | 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 */ | ||