Skip to content

Commit

Permalink
Introduce single precision float compilation option
Browse files Browse the repository at this point in the history
This patch aims to add possibility for library to be compiled using
single precision floating point numbers. This allows to use this library
on embedded systems, where FPU may not support double precision floating
point math, thus, is resource intensive and to slow for audio processing.
  • Loading branch information
KKopyscinski committed Mar 15, 2024
1 parent 20819b6 commit 1d55401
Show file tree
Hide file tree
Showing 27 changed files with 163 additions and 152 deletions.
4 changes: 2 additions & 2 deletions cmake/ClipMode.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ macro(CLIP_MODE)
"
#include <math.h>
int main (void)
{ double fval ;
{ fp_t fval ;
int k, ival ;
fval = 1.0 * 0x7FFFFFFF ;
Expand All @@ -45,7 +45,7 @@ macro(CLIP_MODE)
"
#include <math.h>
int main (void)
{ double fval ;
{ fp_t fval ;
int k, ival ;
fval = -8.0 * 0x10000000 ;
Expand Down
2 changes: 1 addition & 1 deletion examples/timewarp-file.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

typedef struct
{ sf_count_t index ;
double ratio ;
fp_t ratio ;
} TIMEWARP_FACTOR ;

static void usage_exit (const char *progname) ;
Expand Down
2 changes: 1 addition & 1 deletion examples/varispeed-play.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ varispeed_get_data (SRC_CB_DATA *data, float *samples, int out_frames)
} ;

for (out_frame_count = 0 ; out_frame_count < out_frames ; out_frame_count += VARISPEED_BLOCK_LEN)
{ double src_ratio = 1.0 - 0.5 * sin (data->freq_point * 2 * M_PI / 20000) ;
{ fp_t src_ratio = 1.0 - 0.5 * sin (data->freq_point * 2 * M_PI / 20000) ;

data->freq_point ++ ;

Expand Down
13 changes: 9 additions & 4 deletions include/samplerate.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
extern "C" {
#endif /* __cplusplus */

#ifdef LIBSAMPLERATE_SINGLE_PRECISION
typedef float fp_t;
#else
typedef double fp_t;
#endif

/* Opaque data type SRC_STATE. */
typedef struct SRC_STATE_tag SRC_STATE ;
Expand All @@ -32,7 +37,7 @@ typedef struct

int end_of_input ;

double src_ratio ;
fp_t src_ratio ;
} SRC_DATA ;

/*
Expand Down Expand Up @@ -89,7 +94,7 @@ int src_process (SRC_STATE *state, SRC_DATA *data) ;
** Callback based processing function. Read up to frames worth of data from
** the converter int *data and return frames read or -1 on error.
*/
long src_callback_read (SRC_STATE *state, double src_ratio, long frames, float *data) ;
long src_callback_read (SRC_STATE *state, fp_t src_ratio, long frames, float *data) ;

/*
** Simple interface for performing a single conversion from input buffer to
Expand Down Expand Up @@ -119,7 +124,7 @@ const char *src_get_version (void) ;
** Returns non zero on error.
*/

int src_set_ratio (SRC_STATE *state, double new_ratio) ;
int src_set_ratio (SRC_STATE *state, fp_t new_ratio) ;

/*
** Get the current channel count.
Expand All @@ -142,7 +147,7 @@ int src_reset (SRC_STATE *state) ;
** otherwise.
*/

int src_is_valid_ratio (double ratio) ;
int src_is_valid_ratio (fp_t ratio) ;

/*
** Return an error number.
Expand Down
4 changes: 2 additions & 2 deletions m4/clip_mode.m4
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ if test $ac_cv_c_clip_positive = unknown ; then
#define __USE_ISOC9X 1
#include <math.h>
int main (void)
{ double fval ;
{ fp_t fval ;
int k, ival ;
fval = 1.0 * 0x7FFFFFFF ;
Expand Down Expand Up @@ -66,7 +66,7 @@ if test $ac_cv_c_clip_positive = unknown ; then
#define __USE_ISOC9X 1
#include <math.h>
int main (void)
{ double fval ;
{ fp_t fval ;
int k, ival ;
fval = -8.0 * 0x10000000 ;
Expand Down
14 changes: 7 additions & 7 deletions src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ struct SRC_STATE_tag
{
SRC_STATE_VT *vt ;

double last_ratio, last_position ;
fp_t last_ratio, last_position ;

SRC_ERROR error ;
int channels ;
Expand Down Expand Up @@ -209,7 +209,7 @@ static inline int
#ifdef USE_TARGET_ATTRIBUTE
__attribute__((target("sse2")))
#endif
psf_lrint (double x)
psf_lrint (fp_t x)
{
return _mm_cvtsd_si32 (_mm_load_sd (&x)) ;
}
Expand All @@ -221,7 +221,7 @@ static inline int psf_lrintf (float x)
return lrintf (x) ;
} /* psf_lrintf */

static inline int psf_lrint (double x)
static inline int psf_lrint (fp_t x)
{
return lrint (x) ;
} /* psf_lrint */
Expand All @@ -231,9 +231,9 @@ static inline int psf_lrint (double x)
** Common static inline functions.
*/

static inline double
fmod_one (double x)
{ double res ;
static inline fp_t
fmod_one (fp_t x)
{ fp_t res ;

res = x - psf_lrint (x) ;
if (res < 0.0)
Expand All @@ -243,7 +243,7 @@ fmod_one (double x)
} /* fmod_one */

static inline int
is_bad_src_ratio (double ratio)
is_bad_src_ratio (fp_t ratio)
{ return (ratio < (1.0 / SRC_MAX_RATIO) || ratio > (1.0 * SRC_MAX_RATIO)) ;
} /* is_bad_src_ratio */

Expand Down
8 changes: 4 additions & 4 deletions src/samplerate.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ src_process (SRC_STATE *state, SRC_DATA *data)
} /* src_process */

long
src_callback_read (SRC_STATE *state, double src_ratio, long frames, float *data)
src_callback_read (SRC_STATE *state, fp_t src_ratio, long frames, float *data)
{
SRC_DATA src_data ;

Expand Down Expand Up @@ -238,7 +238,7 @@ src_callback_read (SRC_STATE *state, double src_ratio, long frames, float *data)
*/

int
src_set_ratio (SRC_STATE *state, double new_ratio)
src_set_ratio (SRC_STATE *state, fp_t new_ratio)
{
if (state == NULL)
return SRC_ERR_BAD_STATE ;
Expand Down Expand Up @@ -321,7 +321,7 @@ src_get_version (void)
} /* src_get_version */

int
src_is_valid_ratio (double ratio)
src_is_valid_ratio (fp_t ratio)
{
if (is_bad_src_ratio (ratio))
return SRC_FALSE ;
Expand Down Expand Up @@ -461,7 +461,7 @@ src_int_to_float_array (const int *in, float *out, int len)

void
src_float_to_int_array (const float *in, int *out, int len)
{ double scaled_value ;
{ fp_t scaled_value ;

for (int i = 0 ; i < len ; i++)
{ scaled_value = in [i] * (8.0 * 0x10000000) ;
Expand Down
6 changes: 3 additions & 3 deletions src/src_linear.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ static SRC_STATE_VT linear_state_vt =
static SRC_ERROR
linear_vari_process (SRC_STATE *state, SRC_DATA *data)
{ LINEAR_DATA *priv ;
double src_ratio, input_index, rem ;
fp_t src_ratio, input_index, rem ;
int ch ;

if (data->input_frames <= 0)
Expand Down Expand Up @@ -93,7 +93,7 @@ linear_vari_process (SRC_STATE *state, SRC_DATA *data)

for (ch = 0 ; ch < state->channels ; ch++)
{ data->data_out [priv->out_gen] = (float) (priv->last_value [ch] + input_index *
((double) data->data_in [ch] - priv->last_value [ch])) ;
((fp_t) data->data_in [ch] - priv->last_value [ch])) ;
priv->out_gen ++ ;
} ;

Expand All @@ -120,7 +120,7 @@ linear_vari_process (SRC_STATE *state, SRC_DATA *data)

for (ch = 0 ; ch < state->channels ; ch++)
{ data->data_out [priv->out_gen] = (float) (data->data_in [priv->in_used - state->channels + ch] + input_index *
((double) data->data_in [priv->in_used + ch] - data->data_in [priv->in_used - state->channels + ch])) ;
((fp_t) data->data_in [priv->in_used + ch] - data->data_in [priv->in_used - state->channels + ch])) ;
priv->out_gen ++ ;
} ;

Expand Down
42 changes: 21 additions & 21 deletions src/src_sinc.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#define MAKE_INCREMENT_T(x) ((increment_t) (x))

#define SHIFT_BITS 12
#define FP_ONE ((double) (((increment_t) 1) << SHIFT_BITS))
#define FP_ONE ((fp_t) (((increment_t) 1) << SHIFT_BITS))
#define INV_FP_ONE (1.0 / FP_ONE)

/* Customixe max channls from Kconfig. */
Expand Down Expand Up @@ -61,14 +61,14 @@ typedef struct

int coeff_half_len, index_inc ;

double src_ratio, input_index ;
fp_t src_ratio, input_index ;

coeff_t const *coeffs ;

int b_current, b_end, b_real_end, b_len ;

/* Sure hope noone does more than 128 channels at once. */
double left_calc [MAX_CHANNELS], right_calc [MAX_CHANNELS] ;
fp_t left_calc [MAX_CHANNELS], right_calc [MAX_CHANNELS] ;

float *buffer ;
} SINC_FILTER ;
Expand Down Expand Up @@ -131,7 +131,7 @@ static SRC_STATE_VT sinc_mono_state_vt =
} ;

static inline increment_t
double_to_fp (double x)
double_to_fp (fp_t x)
{ return (increment_t) (psf_lrint ((x) * FP_ONE)) ;
} /* double_to_fp */

Expand All @@ -150,7 +150,7 @@ fp_fraction_part (increment_t x)
{ return ((x) & ((((increment_t) 1) << SHIFT_BITS) - 1)) ;
} /* fp_fraction_part */

static inline double
static inline fp_t
fp_to_double (increment_t x)
{ return fp_fraction_part (x) * INV_FP_ONE ;
} /* fp_to_double */
Expand Down Expand Up @@ -367,9 +367,9 @@ sinc_copy (SRC_STATE *state)
** Beware all ye who dare pass this point. There be dragons here.
*/

static inline double
static inline fp_t
calc_output_single (SINC_FILTER *filter, increment_t increment, increment_t start_filter_index)
{ double fraction, left, right, icoeff ;
{ fp_t fraction, left, right, icoeff ;
increment_t filter_index, max_filter_index ;
int data_index, coeff_count, indx ;

Expand Down Expand Up @@ -430,7 +430,7 @@ calc_output_single (SINC_FILTER *filter, increment_t increment, increment_t star
static SRC_ERROR
sinc_mono_vari_process (SRC_STATE *state, SRC_DATA *data)
{ SINC_FILTER *filter ;
double input_index, src_ratio, count, float_increment, terminate, rem ;
fp_t input_index, src_ratio, count, float_increment, terminate, rem ;
increment_t increment, start_filter_index ;
int half_filter_chan_len, samples_in_hand ;

Expand Down Expand Up @@ -521,8 +521,8 @@ sinc_mono_vari_process (SRC_STATE *state, SRC_DATA *data)
} /* sinc_mono_vari_process */

static inline void
calc_output_stereo (SINC_FILTER *filter, int channels, increment_t increment, increment_t start_filter_index, double scale, float * output)
{ double fraction, left [2], right [2], icoeff ;
calc_output_stereo (SINC_FILTER *filter, int channels, increment_t increment, increment_t start_filter_index, fp_t scale, float * output)
{ fp_t fraction, left [2], right [2], icoeff ;
increment_t filter_index, max_filter_index ;
int data_index, coeff_count, indx ;

Expand Down Expand Up @@ -586,7 +586,7 @@ calc_output_stereo (SINC_FILTER *filter, int channels, increment_t increment, in
SRC_ERROR
sinc_stereo_vari_process (SRC_STATE *state, SRC_DATA *data)
{ SINC_FILTER *filter ;
double input_index, src_ratio, count, float_increment, terminate, rem ;
fp_t input_index, src_ratio, count, float_increment, terminate, rem ;
increment_t increment, start_filter_index ;
int half_filter_chan_len, samples_in_hand ;

Expand Down Expand Up @@ -676,8 +676,8 @@ sinc_stereo_vari_process (SRC_STATE *state, SRC_DATA *data)
} /* sinc_stereo_vari_process */

static inline void
calc_output_quad (SINC_FILTER *filter, int channels, increment_t increment, increment_t start_filter_index, double scale, float * output)
{ double fraction, left [4], right [4], icoeff ;
calc_output_quad (SINC_FILTER *filter, int channels, increment_t increment, increment_t start_filter_index, fp_t scale, float * output)
{ fp_t fraction, left [4], right [4], icoeff ;
increment_t filter_index, max_filter_index ;
int data_index, coeff_count, indx ;

Expand Down Expand Up @@ -742,7 +742,7 @@ calc_output_quad (SINC_FILTER *filter, int channels, increment_t increment, incr
SRC_ERROR
sinc_quad_vari_process (SRC_STATE *state, SRC_DATA *data)
{ SINC_FILTER *filter ;
double input_index, src_ratio, count, float_increment, terminate, rem ;
fp_t input_index, src_ratio, count, float_increment, terminate, rem ;
increment_t increment, start_filter_index ;
int half_filter_chan_len, samples_in_hand ;

Expand Down Expand Up @@ -832,8 +832,8 @@ sinc_quad_vari_process (SRC_STATE *state, SRC_DATA *data)
} /* sinc_quad_vari_process */

static inline void
calc_output_hex (SINC_FILTER *filter, int channels, increment_t increment, increment_t start_filter_index, double scale, float * output)
{ double fraction, left [6], right [6], icoeff ;
calc_output_hex (SINC_FILTER *filter, int channels, increment_t increment, increment_t start_filter_index, fp_t scale, float * output)
{ fp_t fraction, left [6], right [6], icoeff ;
increment_t filter_index, max_filter_index ;
int data_index, coeff_count, indx ;

Expand Down Expand Up @@ -897,7 +897,7 @@ calc_output_hex (SINC_FILTER *filter, int channels, increment_t increment, incre
SRC_ERROR
sinc_hex_vari_process (SRC_STATE *state, SRC_DATA *data)
{ SINC_FILTER *filter ;
double input_index, src_ratio, count, float_increment, terminate, rem ;
fp_t input_index, src_ratio, count, float_increment, terminate, rem ;
increment_t increment, start_filter_index ;
int half_filter_chan_len, samples_in_hand ;

Expand Down Expand Up @@ -987,10 +987,10 @@ sinc_hex_vari_process (SRC_STATE *state, SRC_DATA *data)
} /* sinc_hex_vari_process */

static inline void
calc_output_multi (SINC_FILTER *filter, increment_t increment, increment_t start_filter_index, int channels, double scale, float * output)
{ double fraction, icoeff ;
calc_output_multi (SINC_FILTER *filter, increment_t increment, increment_t start_filter_index, int channels, fp_t scale, float * output)
{ fp_t fraction, icoeff ;
/* The following line is 1999 ISO Standard C. If your compiler complains, get a better compiler. */
double *left, *right ;
fp_t *left, *right ;
increment_t filter_index, max_filter_index ;
int data_index, coeff_count, indx ;

Expand Down Expand Up @@ -1062,7 +1062,7 @@ calc_output_multi (SINC_FILTER *filter, increment_t increment, increment_t start
static SRC_ERROR
sinc_multichan_vari_process (SRC_STATE *state, SRC_DATA *data)
{ SINC_FILTER *filter ;
double input_index, src_ratio, count, float_increment, terminate, rem ;
fp_t input_index, src_ratio, count, float_increment, terminate, rem ;
increment_t increment, start_filter_index ;
int half_filter_chan_len, samples_in_hand ;

Expand Down
2 changes: 1 addition & 1 deletion src/src_zoh.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ static SRC_STATE_VT zoh_state_vt =
static SRC_ERROR
zoh_vari_process (SRC_STATE *state, SRC_DATA *data)
{ ZOH_DATA *priv ;
double src_ratio, input_index, rem ;
fp_t src_ratio, input_index, rem ;
int ch ;

if (data->input_frames <= 0)
Expand Down
Loading

0 comments on commit 1d55401

Please sign in to comment.