17 double freq,
double sample_rate)
22 double phase_step = 2.0 * M_PI * freq / sample_rate;
23 for (
unsigned i = 0; i < N; i++)
24 output[i] = amplitude * sin(phase_step * (
double)i);
35 unsigned long long state = (
unsigned long long)seed;
46 state = state * 6364136223846793005ULL + 1442695040888963407ULL;
47 double u1 = (double)(state >> 11) * 0x1.0p-53;
48 if (u1 < DBL_MIN) u1 = DBL_MIN;
49 state = state * 6364136223846793005ULL + 1442695040888963407ULL;
50 double u2 = (double)(state >> 11) * 0x1.0p-53;
52 double r = sqrt(-2.0 * log(u1));
53 double theta = 2.0 * M_PI * u2;
54 output[i] = amplitude * r * cos(theta);
55 output[i + 1] = amplitude * r * sin(theta);
60 state = state * 6364136223846793005ULL + 1442695040888963407ULL;
61 double u1 = (double)(state >> 11) * 0x1.0p-53;
62 if (u1 < DBL_MIN) u1 = DBL_MIN;
63 state = state * 6364136223846793005ULL + 1442695040888963407ULL;
64 double u2 = (double)(state >> 11) * 0x1.0p-53;
65 output[i] = amplitude * sqrt(-2.0 * log(u1)) * cos(2.0 * M_PI * u2);
69void MD_impulse(
double *output,
unsigned N,
double amplitude,
unsigned position)
74 memset(output, 0, N *
sizeof(
double));
75 output[position] = amplitude;
79 double f_start,
double f_end,
double sample_rate)
90 double T = (double)(N - 1) / sample_rate;
91 double chirp_rate = (f_end - f_start) / T;
93 for (
unsigned i = 0; i < N; i++) {
94 double t = (double)i / sample_rate;
95 double phase = 2.0 * M_PI * (f_start * t + 0.5 * chirp_rate * t * t);
96 output[i] = amplitude * sin(phase);
101 double f_start,
double f_end,
double sample_rate)
115 double T = (double)(N - 1) / sample_rate;
116 double ratio = f_end / f_start;
117 double log_ratio = log(ratio);
119 for (
unsigned i = 0; i < N; i++) {
120 double t = (double)i / sample_rate;
121 double phase = 2.0 * M_PI * f_start * T
122 * (pow(ratio, t / T) - 1.0) / log_ratio;
123 output[i] = amplitude * sin(phase);
128 double freq,
double sample_rate)
133 double phase_step = 2.0 * M_PI * freq / sample_rate;
134 for (
unsigned i = 0; i < N; i++) {
135 double phase = fmod(phase_step * (
double)i, 2.0 * M_PI);
136 if (phase < 0.0) phase += 2.0 * M_PI;
137 if (phase == 0.0 || phase == M_PI)
139 else if (phase < M_PI)
140 output[i] = amplitude;
142 output[i] = -amplitude;
147 double freq,
double sample_rate)
152 double phase_step = 2.0 * M_PI * freq / sample_rate;
153 for (
unsigned i = 0; i < N; i++) {
154 double phase = fmod(phase_step * (
double)i, 2.0 * M_PI);
155 if (phase < 0.0) phase += 2.0 * M_PI;
156 output[i] = amplitude * (phase / M_PI - 1.0);
161 double base_freq,
double sample_rate,
162 double rate_octaves_per_sec,
unsigned num_octaves)
170 double rate = rate_octaves_per_sec;
171 double center = (double)(num_octaves - 1) / 2.0;
172 double sigma = (double)num_octaves / 4.0;
173 double nyquist = sample_rate / 2.0;
174 double margin = 5.0 * sigma;
187 double duration = (N > 1) ? (
double)(N - 1) / sample_rate : 0.0;
188 double drift = rate * duration;
190 int k_min = (int)floor(center - margin - fmax(0.0, drift));
191 int k_max = (int)ceil(center + margin - fmin(0.0, drift));
192 unsigned total_layers = (unsigned)(k_max - k_min + 1);
195 double *phases = calloc(total_layers,
sizeof(
double));
197 memset(output, 0, N *
sizeof(
double));
199 for (
unsigned i = 0; i < N; i++) {
200 double t = (double)i / sample_rate;
201 for (
int k = k_min; k <= k_max; k++) {
203 double d = (double)k - center + rate * t;
206 if (fabs(d) > margin)
continue;
208 double freq = base_freq * pow(2.0, d);
209 unsigned idx = (unsigned)(k - k_min);
210 phases[idx] += 2.0 * M_PI * freq / sample_rate;
213 if (freq >= nyquist || freq < 20.0)
continue;
215 double gauss = exp(-0.5 * d * d / (sigma * sigma));
217 if (phases[idx] > 4.0 * M_PI)
218 phases[idx] = fmod(phases[idx], 2.0 * M_PI);
219 output[i] += gauss * sin(phases[idx]);
227 for (
unsigned i = 0; i < N; i++) {
228 double a = fabs(output[i]);
229 if (a > peak) peak = a;
232 double scale = amplitude / peak;
233 for (
unsigned i = 0; i < N; i++)
A mini library of DSP (Digital Signal Processing) routines.
@ MD_ERR_INVALID_SIZE
A size or count argument is invalid (e.g.
@ MD_ERR_INVALID_RANGE
A range or bound is invalid (e.g.
@ MD_ERR_ALLOC_FAILED
A memory allocation failed.
@ MD_ERR_NULL_POINTER
A required pointer argument is NULL.
void MD_chirp_linear(double *output, unsigned N, double amplitude, double f_start, double f_end, double sample_rate)
Generate a linear chirp (swept sine with linearly increasing frequency).
void MD_white_noise(double *output, unsigned N, double amplitude, unsigned seed)
Generate Gaussian white noise.
void MD_sine_wave(double *output, unsigned N, double amplitude, double freq, double sample_rate)
Generate a sine wave.
void MD_impulse(double *output, unsigned N, double amplitude, unsigned position)
Generate a discrete impulse (Kronecker delta).
void MD_shepard_tone(double *output, unsigned N, double amplitude, double base_freq, double sample_rate, double rate_octaves_per_sec, unsigned num_octaves)
Generate a Shepard tone — the auditory illusion of endlessly rising or falling pitch.
void MD_sawtooth_wave(double *output, unsigned N, double amplitude, double freq, double sample_rate)
Generate a sawtooth wave.
void MD_square_wave(double *output, unsigned N, double amplitude, double freq, double sample_rate)
Generate a square wave.
void MD_chirp_log(double *output, unsigned N, double amplitude, double f_start, double f_end, double sample_rate)
Generate a logarithmic chirp (swept sine with exponentially increasing frequency).
Internal header for cross-file dependencies within the minidsp module.
#define MD_CHECK_VOID(cond, code, msg)
Check a precondition in a void function.