Skip to content

Commit

Permalink
Add ability to clone a SRC_STATE* handle
Browse files Browse the repository at this point in the history
Signed-off-by: Erik de Castro Lopo <erikd@mega-nerd.com>
  • Loading branch information
hoyes authored and erikd committed Nov 28, 2017
1 parent b2f7a32 commit 945b993
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 2 deletions.
3 changes: 3 additions & 0 deletions src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ typedef struct SRC_PRIVATE_tag
/* State reset. */
void (*reset) (struct SRC_PRIVATE_tag *psrc) ;

/* State clone. */
int (*copy) (struct SRC_PRIVATE_tag *from, struct SRC_PRIVATE_tag *to) ;

/* Data specific to SRC_MODE_CALLBACK. */
src_callback_t callback_func ;
void *user_callback_data ;
Expand Down
30 changes: 29 additions & 1 deletion src/samplerate.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,34 @@ src_new (int converter_type, int channels, int *error)
return (SRC_STATE*) psrc ;
} /* src_new */

SRC_STATE*
src_clone (SRC_STATE* orig, int *error)
{
SRC_PRIVATE *psrc ;
int copy_error ;

if (error)
*error = SRC_ERR_NO_ERROR ;

if ((psrc = calloc (1, sizeof (*psrc))) == NULL)
{ if (error)
*error = SRC_ERR_MALLOC_FAILED ;
return NULL ;
} ;

SRC_PRIVATE *orig_priv = (SRC_PRIVATE*) orig ;
memcpy (psrc, orig_priv, sizeof (SRC_PRIVATE)) ;

if ((copy_error = orig_priv->copy (orig_priv, psrc)) != SRC_ERR_NO_ERROR)
{ if (error)
*error = copy_error ;
free (psrc) ;
psrc = NULL ;
} ;

return (SRC_STATE*) psrc ;
}

SRC_STATE*
src_callback_new (src_callback_t func, int converter_type, int channels, int *error, void* cb_data)
{ SRC_STATE *src_state ;
Expand Down Expand Up @@ -245,7 +273,7 @@ src_callback_read (SRC_STATE *state, double src_ratio, long frames, float *data)

if (error != 0)
{ psrc->error = error ;
return 0 ;
return 0 ;
} ;

return output_frames_gen ;
Expand Down
8 changes: 7 additions & 1 deletion src/samplerate.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ typedef struct SRC_STATE_tag SRC_STATE ;
/* SRC_DATA is used to pass data to src_simple() and src_process(). */
typedef struct
{ const float *data_in ;
float *data_out ;
float *data_out ;

long input_frames, output_frames ;
long input_frames_used, output_frames_gen ;
Expand Down Expand Up @@ -54,6 +54,12 @@ typedef long (*src_callback_t) (void *cb_data, float **data) ;

SRC_STATE* src_new (int converter_type, int channels, int *error) ;

/*
** Clone a handle : return an anonymous pointer to a new converter
** containing the same internal state as orig. Error returned in *error.
*/
SRC_STATE* src_clone (SRC_STATE* orig, int *error) ;

/*
** Initilisation for callback based API : return an anonymous pointer to the
** internal state of the converter. Choose a converter from the enums below.
Expand Down
20 changes: 20 additions & 0 deletions src/src_linear.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

static int linear_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ;
static void linear_reset (SRC_PRIVATE *psrc) ;
static int linear_copy (SRC_PRIVATE *from, SRC_PRIVATE *to) ;

/*========================================================================================
*/
Expand Down Expand Up @@ -183,6 +184,7 @@ linear_set_converter (SRC_PRIVATE *psrc, int src_enum)
psrc->const_process = linear_vari_process ;
psrc->vari_process = linear_vari_process ;
psrc->reset = linear_reset ;
psrc->copy = linear_copy ;

linear_reset (psrc) ;

Expand All @@ -207,3 +209,21 @@ linear_reset (SRC_PRIVATE *psrc)
return ;
} /* linear_reset */

static int
linear_copy (SRC_PRIVATE *from, SRC_PRIVATE *to)
{
if (from->private_data == NULL)
return SRC_ERR_NO_PRIVATE ;

LINEAR_DATA *to_priv = NULL ;
LINEAR_DATA* from_priv = (LINEAR_DATA*) from->private_data ;
size_t private_size = sizeof (*to_priv) + from_priv->channels * sizeof (float) ;

if ((to_priv = calloc (1, private_size)) == NULL)
return SRC_ERR_MALLOC_FAILED ;

memcpy (to_priv, from_priv, private_size) ;
to->private_data = to_priv ;

return SRC_ERR_NO_ERROR ;
} /* linear_copy */
21 changes: 21 additions & 0 deletions src/src_sinc.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ static int sinc_mono_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ;
static int prepare_data (SINC_FILTER *filter, SRC_DATA *data, int half_filter_chan_len) WARN_UNUSED ;

static void sinc_reset (SRC_PRIVATE *psrc) ;
static int sinc_copy (SRC_PRIVATE *from, SRC_PRIVATE *to) ;

static inline increment_t
double_to_fp (double x)
Expand Down Expand Up @@ -181,6 +182,7 @@ sinc_set_converter (SRC_PRIVATE *psrc, int src_enum)
psrc->vari_process = sinc_multichan_vari_process ;
} ;
psrc->reset = sinc_reset ;
psrc->copy = sinc_copy ;

switch (src_enum)
{ case SRC_SINC_FASTEST :
Expand Down Expand Up @@ -253,6 +255,25 @@ sinc_reset (SRC_PRIVATE *psrc)
memset (filter->buffer + filter->b_len, 0xAA, filter->channels * sizeof (filter->buffer [0])) ;
} /* sinc_reset */

static int
sinc_copy (SRC_PRIVATE *from, SRC_PRIVATE *to)
{
if (from->private_data == NULL)
return SRC_ERR_NO_PRIVATE ;

SINC_FILTER *to_filter = NULL ;
SINC_FILTER* from_filter = (SINC_FILTER*) from->private_data ;
size_t private_length = sizeof (SINC_FILTER) + sizeof (from_filter->buffer [0]) * (from_filter->b_len + from_filter->channels) ;

if ((to_filter = calloc (1, private_length)) == NULL)
return SRC_ERR_MALLOC_FAILED ;

memcpy (to_filter, from_filter, private_length) ;
to->private_data = to_filter ;

return SRC_ERR_NO_ERROR ;
} /* sinc_copy */

/*========================================================================================
** Beware all ye who dare pass this point. There be dragons here.
*/
Expand Down
20 changes: 20 additions & 0 deletions src/src_zoh.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

static int zoh_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ;
static void zoh_reset (SRC_PRIVATE *psrc) ;
static int zoh_copy (SRC_PRIVATE *from, SRC_PRIVATE *to) ;

/*========================================================================================
*/
Expand Down Expand Up @@ -174,6 +175,7 @@ zoh_set_converter (SRC_PRIVATE *psrc, int src_enum)
psrc->const_process = zoh_vari_process ;
psrc->vari_process = zoh_vari_process ;
psrc->reset = zoh_reset ;
psrc->copy = zoh_copy ;

zoh_reset (psrc) ;

Expand All @@ -198,3 +200,21 @@ zoh_reset (SRC_PRIVATE *psrc)
return ;
} /* zoh_reset */

static int
zoh_copy (SRC_PRIVATE *from, SRC_PRIVATE *to)
{
if (from->private_data == NULL)
return SRC_ERR_NO_PRIVATE ;

ZOH_DATA *to_priv = NULL ;
ZOH_DATA* from_priv = (ZOH_DATA*) from->private_data ;
size_t private_size = sizeof (*to_priv) + from_priv->channels * sizeof (float) ;

if ((to_priv = calloc (1, private_size)) == NULL)
return SRC_ERR_MALLOC_FAILED ;

memcpy (to_priv, from_priv, private_size) ;
to->private_data = to_priv ;

return SRC_ERR_NO_ERROR ;
} /* zoh_copy */

0 comments on commit 945b993

Please sign in to comment.