|  | #pragma once
#include "math.hpp"
namespace rack {
namespace dsp {
// Constants
static const float FREQ_C4 = 261.6256f;
static const float FREQ_A4 = 440.0000f;
// Mathematical functions
/** The normalized sinc function
See https://en.wikipedia.org/wiki/Sinc_function
*/
inline float sinc(float x) {
	if (x == 0.f)
		return 1.f;
	x *= M_PI;
	return std::sin(x) / x;
}
// Window functions
/** Hann window function
p: proportion from [0, 1], usually `i / (len - 1)`
https://en.wikipedia.org/wiki/Window_function#Hann_and_Hamming_windows
*/
inline float hann(float p) {
	return 0.5f * (1.f - std::cos(2*M_PI * p));
}
inline void hannWindow(float *x, int len) {
	for (int i = 0; i < len; i++) {
		x[i] *= hann((float) i / (len - 1));
	}
}
/** Blackman window function
https://en.wikipedia.org/wiki/Window_function#Blackman_window
A typical alpha value is 0.16.
*/
inline float blackman(float alpha, float p) {
	return
		+ (1 - alpha) / 2.f
		- 1 / 2.f * std::cos(2*M_PI * p)
		+ alpha / 2.f * std::cos(4*M_PI * p);
}
inline void blackmanWindow(float alpha, float *x, int len) {
	for (int i = 0; i < len; i++) {
		x[i] *= blackman(alpha, (float) i / (len - 1));
	}
}
/** Blackman-Nuttall window function
https://en.wikipedia.org/wiki/Window_function#Blackman%E2%80%93Nuttall_window
*/
inline float blackmanNuttall(float p) {
	return
		+ 0.3635819f
		- 0.4891775f * std::cos(2*M_PI * p)
		+ 0.1365995f * std::cos(4*M_PI * p)
		- 0.0106411f * std::cos(6*M_PI * p);
}
inline void blackmanNuttallWindow(float *x, int len) {
	for (int i = 0; i < len; i++) {
		x[i] *= blackmanNuttall((float) i / (len - 1));
	}
}
/** Blackman-Harris window function
https://en.wikipedia.org/wiki/Window_function#Blackman%E2%80%93Harris_window
*/
inline float blackmanHarris(float p) {
	return
		+ 0.35875f
		- 0.48829f * std::cos(2*M_PI * p)
		+ 0.14128f * std::cos(4*M_PI * p)
		- 0.01168f * std::cos(6*M_PI * p);
}
inline void blackmanHarrisWindow(float *x, int len) {
	for (int i = 0; i < len; i++) {
		x[i] *= blackmanHarris((float) i / (len - 1));
	}
}
// Conversion functions
inline float amplitudeToDb(float amp) {
	return std::log10(amp) * 20.f;
}
inline float dbToAmplitude(float db) {
	return std::pow(10.f, db / 20.f);
}
// Functions for parameter scaling
inline float quadraticBipolar(float x) {
	float x2 = x*x;
	return (x >= 0.f) ? x2 : -x2;
}
inline float cubic(float x) {
	return x*x*x;
}
inline float quarticBipolar(float x) {
	float y = x*x*x*x;
	return (x >= 0.f) ? y : -y;
}
inline float quintic(float x) {
	// optimal with -fassociative-math
	return x*x*x*x*x;
}
inline float sqrtBipolar(float x) {
	return (x >= 0.f) ? std::sqrt(x) : -std::sqrt(-x);
}
/** This is pretty much a scaled sinh */
inline float exponentialBipolar(float b, float x) {
	const float a = b - 1.f / b;
	return (std::pow(b, x) - std::pow(b, -x)) / a;
}
} // namespace dsp
} // namespace rack
 |