3 #ifndef SPECTMORPH_MATH_HH 4 #define SPECTMORPH_MATH_HH 12 #include <xmmintrin.h> 60 template<
class Iterator,
int MODE>
62 internal_fast_vector_sin (
const VectorSinParams& params, Iterator begin, Iterator end)
64 g_return_if_fail (params.
mix_freq > 0 && params.
freq > 0 && params.
phase > -99 && params.
mag > 0);
66 const double phase_inc = params.
freq / params.
mix_freq * 2 * M_PI;
67 const double inc_re = cos (phase_inc);
68 const double inc_im = sin (phase_inc);
74 sincos (params.
phase, &state_im, &state_re);
75 state_re *= params.
mag;
76 state_im *= params.
mag;
78 for (Iterator x = begin; x != end; x++)
84 if ((n++ & 255) == 255)
86 sincos (phase_inc * n + params.
phase, &state_im, &state_re);
87 state_re *= params.
mag;
88 state_im *= params.
mag;
96 const double re = state_re * inc_re - state_im * inc_im;
97 const double im = state_re * inc_im + state_im * inc_re;
104 template<
class Iterator,
int MODE>
106 internal_fast_vector_sincos (
const VectorSinParams& params, Iterator sin_begin, Iterator sin_end, Iterator cos_begin)
108 g_return_if_fail (params.
mix_freq > 0 && params.
freq > 0 && params.
phase > -99 && params.
mag > 0);
110 const double phase_inc = params.
freq / params.
mix_freq * 2 * M_PI;
111 const double inc_re = cos (phase_inc);
112 const double inc_im = sin (phase_inc);
118 sincos (params.
phase, &state_im, &state_re);
119 state_re *= params.
mag;
120 state_im *= params.
mag;
122 for (Iterator x = sin_begin, y = cos_begin; x != sin_end; x++, y++)
134 if ((n++ & 255) == 255)
136 sincos (phase_inc * n + params.
phase, &state_im, &state_re);
137 state_re *= params.
mag;
138 state_im *= params.
mag;
146 const double re = state_re * inc_re - state_im * inc_im;
147 const double im = state_re * inc_im + state_im * inc_re;
154 template<
class Iterator>
156 fast_vector_sin (
const VectorSinParams& params, Iterator sin_begin, Iterator sin_end)
160 internal_fast_vector_sin<Iterator, VectorSinParams::ADD> (params, sin_begin, sin_end);
164 internal_fast_vector_sin<Iterator, VectorSinParams::REPLACE> (params, sin_begin, sin_end);
168 g_assert_not_reached();
172 template<
class Iterator>
174 fast_vector_sincos (
const VectorSinParams& params, Iterator sin_begin, Iterator sin_end, Iterator cos_begin)
178 internal_fast_vector_sincos<Iterator, VectorSinParams::ADD> (params, sin_begin, sin_end, cos_begin);
182 internal_fast_vector_sincos<Iterator, VectorSinParams::REPLACE> (params, sin_begin, sin_end, cos_begin);
186 g_assert_not_reached();
202 template<
bool NEED_COS,
int MODE>
204 internal_fast_vector_sincosf (
const VectorSinParams& params,
float *sin_begin,
float *sin_end,
float *cos_begin)
207 g_return_if_fail (params.
mix_freq > 0 && params.
freq > 0 && params.
phase > -99 && params.
mag > 0);
209 const int TABLE_SIZE = 32;
211 const double phase_inc = params.
freq / params.
mix_freq * 2 * M_PI;
212 const double inc_re16 = cos (phase_inc * TABLE_SIZE * 4);
213 const double inc_im16 = sin (phase_inc * TABLE_SIZE * 4);
219 sincos (params.
phase, &state_im, &state_re);
220 state_re *= params.
mag;
221 state_im *= params.
mag;
223 F4Vector incf_re[TABLE_SIZE];
224 F4Vector incf_im[TABLE_SIZE];
228 table_params.
phase = 0;
229 table_params.
mag = 1;
231 fast_vector_sincos (table_params, incf_im[0].f, incf_im[0].f + (TABLE_SIZE * 4), incf_re[0].f);
234 int todo = sin_end - sin_begin;
235 while (todo >= 4 * TABLE_SIZE)
239 sf_re.f[0] = state_re;
240 sf_re.f[1] = state_re;
241 sf_re.f[2] = state_re;
242 sf_re.f[3] = state_re;
243 sf_im.f[0] = state_im;
244 sf_im.f[1] = state_im;
245 sf_im.f[2] = state_im;
246 sf_im.f[3] = state_im;
254 F4Vector *new_im =
reinterpret_cast<F4Vector *
> (sin_begin + n);
255 F4Vector *new_re =
reinterpret_cast<F4Vector *
> (cos_begin + n);
256 for (
int k = 0; k < TABLE_SIZE; k++)
262 new_re[k].v = _mm_add_ps (new_re[k].v, _mm_sub_ps (_mm_mul_ps (sf_re.v, incf_re[k].v),
263 _mm_mul_ps (sf_im.v, incf_im[k].v)));
265 new_im[k].v = _mm_add_ps (new_im[k].v, _mm_add_ps (_mm_mul_ps (sf_re.v, incf_im[k].v),
266 _mm_mul_ps (sf_im.v, incf_re[k].v)));
272 new_re[k].v = _mm_sub_ps (_mm_mul_ps (sf_re.v, incf_re[k].v),
273 _mm_mul_ps (sf_im.v, incf_im[k].v));
275 new_im[k].v = _mm_add_ps (_mm_mul_ps (sf_re.v, incf_im[k].v),
276 _mm_mul_ps (sf_im.v, incf_re[k].v));
286 const double re = state_re * inc_re16 - state_im * inc_im16;
287 const double im = state_re * inc_im16 + state_im * inc_re16;
291 todo -= 4 * TABLE_SIZE;
296 rest_params.
phase += n * phase_inc;
298 fast_vector_sincos (rest_params, sin_begin + n, sin_end, cos_begin + n);
300 fast_vector_sin (rest_params, sin_begin + n, sin_end);
303 fast_vector_sincos (params, sin_begin, sin_end, cos_begin);
305 fast_vector_sin (params, sin_begin, sin_end);
310 fast_vector_sincosf (
const VectorSinParams& params,
float *sin_begin,
float *sin_end,
float *cos_begin)
314 internal_fast_vector_sincosf<true, VectorSinParams::ADD> (params, sin_begin, sin_end, cos_begin);
318 internal_fast_vector_sincosf<true, VectorSinParams::REPLACE> (params, sin_begin, sin_end, cos_begin);
322 g_assert_not_reached();
327 fast_vector_sinf (
const VectorSinParams& params,
float *sin_begin,
float *sin_end)
331 internal_fast_vector_sincosf<false, VectorSinParams::ADD> (params, sin_begin, sin_end, NULL);
335 internal_fast_vector_sincosf<false, VectorSinParams::REPLACE> (params, sin_begin, sin_end, NULL);
339 g_assert_not_reached();
344 zero_float_block (
size_t n_values,
float *values)
346 memset (values, 0, n_values *
sizeof (
float));
352 extern float *int_sincos_table;
354 return int_sincos_table[i];
360 extern float *int_sincos_table;
363 return int_sincos_table[i];
369 extern float *int_sincos_table;
371 int_sincos_table = (
float *) malloc (
sizeof (
float) * 256);
372 for (
int i = 0; i < 256; i++)
373 int_sincos_table[i] = sin (
double (i / 256.0) * 2 * M_PI);
379 window_cos (
double x)
383 return 0.5 * cos (x * M_PI) + 0.5;
387 window_hamming (
double x)
392 return 0.54 + 0.46 * cos (M_PI * x);
396 window_blackman (
double x)
400 return 0.42 + 0.5 * cos (M_PI * x) + 0.08 * cos (2.0 * M_PI * x);
404 window_blackman_harris_92 (
double x)
409 const double a0 = 0.35875, a1 = 0.48829, a2 = 0.14128, a3 = 0.01168;
411 return a0 + a1 * cos (M_PI * x) + a2 * cos (2.0 * M_PI * x) + a3 * cos (3.0 * M_PI * x);
415 double db_to_factor (
double dB);
416 double db_from_factor (
double factor,
double min_dB);
418 #if defined (__i386__) && defined (__GNUC__) 419 static inline int G_GNUC_CONST
420 sm_ftoi (
register float f)
429 static inline int G_GNUC_CONST
430 sm_dtoi (
register double f)
440 sm_round_positive (
double d)
446 sm_round_positive (
float f)
452 sm_round_positive (
double d)
454 return int (d + 0.5);
458 sm_round_positive (
float f)
460 return int (f + 0.5);
464 int sm_fpu_okround();
468 static float idb2f_high[256];
469 static float idb2f_low[256];
471 static float ifreq2f_high[256];
472 static float ifreq2f_low[256];
475 #define SM_IDB_CONST_M96 uint16_t ((512 - 96) * 64) 477 int sm_factor2delta_idb (
double factor);
478 double sm_idb2factor_slow (uint16_t idb);
482 uint16_t sm_freq2ifreq (
double freq);
483 double sm_ifreq2freq_slow (uint16_t ifreq);
486 sm_idb2factor (uint16_t idb)
488 return MathTables::idb2f_high[idb >> 8] * MathTables::idb2f_low[idb & 0xff];
492 sm_ifreq2freq (uint16_t ifreq)
494 return MathTables::ifreq2f_high[ifreq >> 8] * MathTables::ifreq2f_low[ifreq & 0xff];
498 sm_factor2idb (
double factor)
506 const double db = 20 * log10 (std::max (factor, 1e-25));
508 return sm_round_positive (db * 64 + 512 * 64);
511 double sm_lowpass1_factor (
double mix_freq,
double freq);
512 double sm_xparam (
double x,
double slope);
513 double sm_xparam_inv (
double x,
double slope);
515 double sm_bessel_i0 (
double x);
519 sm_bound (
const T& min_value,
const T& value,
const T& max_value)
521 return std::min (std::max (value, min_value), max_value);
Definition: smmath.hh:466
double freq
the frequency of the sin (and cos) wave to be created
Definition: smmath.hh:40
double phase
the start phase of the wave
Definition: smmath.hh:41
replace values in the output array with computed values
Definition: smmath.hh:47
double mag
the magnitude (amplitude) of the wave
Definition: smmath.hh:42
parameter structure for the various optimized vector sine functions
Definition: smmath.hh:36
Definition: smadsrenvelope.hh:8
double mix_freq
the mix freq (sampling rate) of the sin (and cos) wave to be created
Definition: smmath.hh:39
enum SpectMorph::VectorSinParams::@2 mode
whether to overwrite or add output
add computed values to the values that are in the output array
Definition: smmath.hh:46