🍑 nectarine
Audio synthesis tools for C23
Loading...
Searching...
No Matches
tgwaveforms.h File Reference

Type-generic waveform functions. More...

#include "waveforms.h"

Go to the source code of this file.

Macros

#define nec_wrap(phase)
 Maps an arbitrary phase into the domain [0, 1).
#define nec_fill_wrap(len, phase, output)
 Maps a buffer of arbitrary phases into the domain [0, 1).
#define nec_analog_sawtooth(phase)
 Analog-like sawtooth waveform.
#define nec_fill_analog_sawtooth(len, phase, output)
 Fills a buffer with an analog-like sawtooth waveform.
#define nec_analog_square(phase, duty)
 Analog-like square waveform.
#define nec_fill_analog_square(len, phase, duty, output)
 Fills a buffer with an analog-like square waveform.
#define nec_analog_triangle(phase)
 Analog-like triangle waveform.
#define nec_fill_analog_triangle(len, phase, output)
 Fills a buffer with an analog-like triangle waveform.
#define nec_parabol(phase)
 Fast sine approximation waveform.
#define nec_fill_parabol(len, phase, output)
 Fills a buffer with a fast sine approximation waveform.
#define nec_sin(phase)
 Accurate sine approximation waveform.
#define nec_fill_sin(len, phase, output)
 Fills a buffer with an accurate sine approximation waveform.
#define nec_circle(phase)
 Circle waveform function.
#define nec_fill_circle(len, phase, output)
 Fills a buffer with a circle waveform.
#define nec_sawtooth(phase)
 Basic sawtooth waveform.
#define nec_fill_sawtooth(len, phase, output)
 Fills a buffer with a sawtooth waveform.
#define nec_square(phase, duty)
 Basic square waveform.
#define nec_fill_square(len, phase, duty, output)
 Fills a buffer with a square waveform.
#define nec_triangle(phase)
 Basic triangle waveform.
#define nec_fill_triangle(len, phase, output)
 Fills a buffer with a triangle waveform.

Detailed Description

Type-generic waveform functions.

Macro Definition Documentation

◆ nec_analog_sawtooth

#define nec_analog_sawtooth ( phase)
Value:
_Generic((phase),\
long double : nec_analog_sawtoothl,\
)(phase)
#define nec_analog_sawtooth(phase)
Analog-like sawtooth waveform.
Definition tgwaveforms.h:29
long double nec_analog_sawtoothl(long double phase)
Analog-like sawtooth waveform.
Definition waveforms.h:117
float nec_analog_sawtoothf(float phase)
Analog-like sawtooth waveform.
Definition waveforms.h:131

Analog-like sawtooth waveform.

This sawtooth waveform changes with an exponential curve to emulate a discharging capacitor (or charging, when inverted).

To be more precise, it approximates the exponential curve \(\frac{2e}{e-1}\left(e^{-x}-1\right)+1\) using a rational function.

Parameters
phaseThe input phase of the waveform, in domain [0, 1).
Returns
A sample of a sawtooth waveform, with range [-1, 1].

◆ nec_analog_square

#define nec_analog_square ( phase,
duty )
Value:
_Generic((phase),\
long double : nec_analog_squarel,\
double : nec_analog_square,\
)((phase), (duty))
#define nec_analog_square(phase, duty)
Analog-like square waveform.
Definition tgwaveforms.h:43
float nec_analog_squaref(float phase, float duty)
Analog-like square waveform.
Definition waveforms.h:229
long double nec_analog_squarel(long double phase, long double duty)
Analog-like square waveform.
Definition waveforms.h:211

Analog-like square waveform.

This square waveform decays with an exponential curve to emulate a discharging capacitor.

To be more precise, it approximates the exponential curve \(\frac{e}{2\left(e-1\right)}\left(e^{-x}-1\right)+1\) using a rational function.

Parameters
phaseThe input phase of the waveform, in domain [0, 1).
dutyThe duty cycle of the waveform, in domain [0, 1].
Returns
A sample of a square waveform, with range [-1, 1].

◆ nec_analog_triangle

#define nec_analog_triangle ( phase)
Value:
_Generic((phase),\
long double : nec_analog_trianglel,\
)(phase)
#define nec_analog_triangle(phase)
Analog-like triangle waveform.
Definition tgwaveforms.h:57
long double nec_analog_trianglel(long double phase)
Analog-like triangle waveform.
Definition waveforms.h:317
float nec_analog_trianglef(float phase)
Analog-like triangle waveform.
Definition waveforms.h:331

Analog-like triangle waveform.

This triangle waveform changes with an exponential curve to emulate a charging and discharging capacitor.

To be more precise, it approximates the exponential curve \(\frac{2e}{e-1}\left(e^{-x}-1\right)+1\) using a rational function.

Parameters
phaseThe input phase of the waveform, in domain [0, 1).
Returns
A sample of a triangle waveform, with range [-1, 1].

◆ nec_circle

#define nec_circle ( phase)
Value:
_Generic((phase),\
long double : nec_circlel,\
double : nec_circle,\
float : nec_circlef\
)(phase)
#define nec_circle(phase)
Circle waveform function.
Definition tgwaveforms.h:99
float nec_circlef(float phase)
Circle waveform function.
Definition waveforms.h:613
long double nec_circlel(long double phase)
Circle waveform function.
Definition waveforms.h:599

Circle waveform function.

This waveform looks like an alternating semicircle.

Parameters
phaseThe input phase of the waveform, in domain [0, 1).
Returns
A sample of circle waveform, with range [-1, 1].

◆ nec_fill_analog_sawtooth

#define nec_fill_analog_sawtooth ( len,
phase,
output )
Value:
_Generic((output),\
long double* : nec_fill_analog_sawtoothl,\
)((len), (phase), (output))
#define nec_fill_analog_sawtooth(len, phase, output)
Fills a buffer with an analog-like sawtooth waveform.
Definition tgwaveforms.h:36
void nec_fill_analog_sawtoothl(size_t len, const long double phase[restrict static len], long double output[restrict static len])
Fills a buffer with an analog-like sawtooth waveform.
Definition waveforms.h:144
void nec_fill_analog_sawtoothf(size_t len, const float phase[restrict static len], float output[restrict static len])
Fills a buffer with an analog-like sawtooth waveform.
Definition waveforms.h:181

Fills a buffer with an analog-like sawtooth waveform.

See also
nec_analog_sawtooth()
Parameters
[in]lenThe length of the input and output buffers, phase and output. Must be at least 1.
[in]phaseA buffer full of input phases in domain [0, 1).
[out]outputA buffer to be filled with samples of a sawtooth waveform, with range [-1, 1].

◆ nec_fill_analog_square

#define nec_fill_analog_square ( len,
phase,
duty,
output )
Value:
_Generic((output),\
long double* : nec_fill_analog_squarel,\
)((len), (phase), (duty), (output))
#define nec_fill_analog_square(len, phase, duty, output)
Fills a buffer with an analog-like square waveform.
Definition tgwaveforms.h:50
void nec_fill_analog_squarel(size_t len, const long double phase[restrict static len], const long double duty[restrict static len], long double output[restrict static len])
Fills a buffer with an analog-like square waveform.
Definition waveforms.h:245
void nec_fill_analog_squaref(size_t len, const float phase[restrict static len], const float duty[restrict static len], float output[restrict static len])
Fills a buffer with an analog-like square waveform.
Definition waveforms.h:286

Fills a buffer with an analog-like square waveform.

See also
nec_analog_square()
Parameters
[in]lenThe length of the input and output buffers, phase and output. Must be at least 1.
[in]phaseA buffer full of input phases in domain [0, 1).
[in]dutyA buffer full of duty cycles in domain [0, 1].
[out]outputA buffer to be filled with samples of a square waveform, with range [-1, 1].

◆ nec_fill_analog_triangle

#define nec_fill_analog_triangle ( len,
phase,
output )
Value:
_Generic((output),\
long double* : nec_fill_analog_trianglel,\
)((len), (phase), (output))
#define nec_fill_analog_triangle(len, phase, output)
Fills a buffer with an analog-like triangle waveform.
Definition tgwaveforms.h:64
void nec_fill_analog_trianglef(size_t len, const float phase[restrict static len], float output[restrict static len])
Fills a buffer with an analog-like triangle waveform.
Definition waveforms.h:381
void nec_fill_analog_trianglel(size_t len, const long double phase[restrict static len], long double output[restrict static len])
Fills a buffer with an analog-like triangle waveform.
Definition waveforms.h:344

Fills a buffer with an analog-like triangle waveform.

See also
nec_analog_triangle()
Parameters
[in]lenThe length of the input and output buffers, phase and output. Must be at least 1.
[in]phaseA buffer full of input phases in domain [0, 1).
[out]outputA buffer to be filled with samples of a triangle waveform, with range [-1, 1].

◆ nec_fill_circle

#define nec_fill_circle ( len,
phase,
output )
Value:
_Generic((output),\
long double* : nec_fill_circlel,\
double* : nec_fill_circle,\
float* : nec_fill_circlef\
)((len), (phase), (output))
#define nec_fill_circle(len, phase, output)
Fills a buffer with a circle waveform.
Definition tgwaveforms.h:106
void nec_fill_circlef(size_t len, const float phase[restrict static len], float output[restrict static len])
Fills a buffer with a circle waveform.
Definition waveforms.h:663
void nec_fill_circlel(size_t len, const long double phase[restrict static len], long double output[restrict static len])
Fills a buffer with a circle waveform.
Definition waveforms.h:626

Fills a buffer with a circle waveform.

See also
nec_circle()
Parameters
[in]lenThe length of the input and output buffers, phase and output. Must be at least 1.
[in]phaseA buffer full of input phases in domain [0, 1).
[out]outputA buffer to be filled with samples of a circle waveform, with range [-1, 1].

◆ nec_fill_parabol

#define nec_fill_parabol ( len,
phase,
output )
Value:
_Generic((output),\
long double* : nec_fill_paraboll,\
double* : nec_fill_parabol,\
)((len), (phase), (output))
#define nec_fill_parabol(len, phase, output)
Fills a buffer with a fast sine approximation waveform.
Definition tgwaveforms.h:78
void nec_fill_paraboll(size_t len, const long double phase[restrict static len], long double output[restrict static len])
Fills a buffer with a fast sine approximation waveform.
Definition waveforms.h:439
void nec_fill_parabolf(size_t len, const float phase[restrict static len], float output[restrict static len])
Fills a buffer with a fast sine approximation waveform.
Definition waveforms.h:476

Fills a buffer with a fast sine approximation waveform.

See also
nec_parabol()
Parameters
[in]lenThe length of the input and output buffers, phase and output. Must be at least 1.
[in]phaseA buffer full of input phases in domain [0, 1).
[out]outputA buffer to be filled with samples of an approximated sine waveform, with range [-1, 1].

◆ nec_fill_sawtooth

#define nec_fill_sawtooth ( len,
phase,
output )
Value:
_Generic((output),\
long double* : nec_fill_sawtoothl,\
double* : nec_fill_sawtooth,\
)((len), (phase), (output))
#define nec_fill_sawtooth(len, phase, output)
Fills a buffer with a sawtooth waveform.
Definition tgwaveforms.h:120
void nec_fill_sawtoothl(size_t len, const long double phase[restrict static len], long double output[restrict static len])
Fills a buffer with a sawtooth waveform.
Definition waveforms.h:711
void nec_fill_sawtoothf(size_t len, const float phase[restrict static len], float output[restrict static len])
Fills a buffer with a sawtooth waveform.
Definition waveforms.h:748

Fills a buffer with a sawtooth waveform.

See also
nec_sawtooth()
Parameters
[in]lenThe length of the input and output buffers, phase and output. Must be at least 1.
[in]phaseA buffer full of input phases in domain [0, 1).
[out]outputA buffer to be filled with samples of a sawtooth waveform, with range [-1, 1].

◆ nec_fill_sin

#define nec_fill_sin ( len,
phase,
output )
Value:
_Generic((output),\
long double* : nec_fill_sinl,\
double* : nec_fill_sin,\
float* : nec_fill_sinf\
)((len), (phase), (output))
#define nec_fill_sin(len, phase, output)
Fills a buffer with an accurate sine approximation waveform.
Definition tgwaveforms.h:92
void nec_fill_sinf(size_t len, const float phase[restrict static len], float output[restrict static len])
Fills a buffer with an accurate sine approximation waveform.
Definition waveforms.h:577
void nec_fill_sinl(size_t len, const long double phase[restrict static len], long double output[restrict static len])
Fills a buffer with an accurate sine approximation waveform.
Definition waveforms.h:540

Fills a buffer with an accurate sine approximation waveform.

See also
nec_sin()
Parameters
[in]lenThe length of the input and output buffers, phase and output. Must be at least 1.
[in]phaseA buffer full of input phases in domain [0, 1).
[out]outputA buffer to be filled with samples of a sine waveform, with range [-1, 1].

◆ nec_fill_square

#define nec_fill_square ( len,
phase,
duty,
output )
Value:
_Generic((output),\
long double* : nec_fill_squarel,\
double* : nec_fill_square,\
float* : nec_fill_squaref\
)((len), (phase), (duty), (output))
#define nec_fill_square(len, phase, duty, output)
Fills a buffer with a square waveform.
Definition tgwaveforms.h:134
void nec_fill_squarel(size_t len, const long double phase[restrict static len], const long double duty[restrict static len], long double output[restrict static len])
Fills a buffer with a square waveform.
Definition waveforms.h:801
void nec_fill_squaref(size_t len, const float phase[restrict static len], const float duty[restrict static len], float output[restrict static len])
Fills a buffer with a square waveform.
Definition waveforms.h:842

Fills a buffer with a square waveform.

See also
nec_square()
Parameters
[in]lenThe length of the input and output buffers, phase and output. Must be at least 1.
[in]phaseA buffer full of input phases in domain [0, 1).
[in]dutyA buffer full of duty cycles in domain [0, 1].
[out]outputA buffer to be filled with samples of a square waveform, with range [-1, 1].

◆ nec_fill_triangle

#define nec_fill_triangle ( len,
phase,
output )
Value:
_Generic((output),\
long double* : nec_fill_trianglel,\
double* : nec_fill_triangle,\
)((len), (phase), (output))
#define nec_fill_triangle(len, phase, output)
Fills a buffer with a triangle waveform.
Definition tgwaveforms.h:148
void nec_fill_trianglel(size_t len, const long double phase[restrict static len], long double output[restrict static len])
Fills a buffer with a triangle waveform.
Definition waveforms.h:892
void nec_fill_trianglef(size_t len, const float phase[restrict static len], float output[restrict static len])
Fills a buffer with a triangle waveform.
Definition waveforms.h:929

Fills a buffer with a triangle waveform.

See also
nec_triangle()
Parameters
[in]lenThe length of the input and output buffers, phase and output. Must be at least 1.
[in]phaseA buffer full of input phases in domain [0, 1).
[out]outputA buffer to be filled with samples of a triangle waveform, with range [-1, 1].

◆ nec_fill_wrap

#define nec_fill_wrap ( len,
phase,
output )
Value:
_Generic((output),\
long double* : nec_fill_wrapl,\
double* : nec_fill_wrap,\
float* : nec_fill_wrapf\
)((len), (phase), (output))
#define nec_fill_wrap(len, phase, output)
Maps a buffer of arbitrary phases into the domain [0, 1).
Definition tgwaveforms.h:22
void nec_fill_wrapf(size_t len, const float phase[restrict static len], float output[restrict static len])
Maps a buffer of arbitrary phases into the domain [0, 1).
Definition waveforms.h:88
void nec_fill_wrapl(size_t len, const long double phase[restrict static len], long double output[restrict static len])
Maps a buffer of arbitrary phases into the domain [0, 1).
Definition waveforms.h:51

Maps a buffer of arbitrary phases into the domain [0, 1).

See also
nec_wrap()
Parameters
[in]lenThe length of the input and output buffers, phase and output. Must be at least 1.
[in]phaseA buffer full of arbitrary input phases.
[out]outputA buffer to be filled with equivalent phases to the contents of phase, but within the domain [0, 1).

◆ nec_parabol

#define nec_parabol ( phase)
Value:
_Generic((phase),\
long double : nec_paraboll,\
double : nec_parabol,\
float : nec_parabolf\
)(phase)
#define nec_parabol(phase)
Fast sine approximation waveform.
Definition tgwaveforms.h:71
long double nec_paraboll(long double phase)
Fast sine approximation waveform.
Definition waveforms.h:409
float nec_parabolf(float phase)
Fast sine approximation waveform.
Definition waveforms.h:425

Fast sine approximation waveform.

This function generates a fast approximation of a sine waveform. It has a maximum absolute error of ±0.05601, which is quite large and produces audible harmonics, so it is intended for use in oscillators where these harmonics are desirable or LFOs where they aren't perceptible.

Parameters
phaseThe input phase of the waveform, in domain [0, 1).
Returns
A sample of an approximated sine waveform, with range [-1, 1].

◆ nec_sawtooth

#define nec_sawtooth ( phase)
Value:
_Generic((phase),\
long double : nec_sawtoothl,\
double : nec_sawtooth,\
float : nec_sawtoothf\
)(phase)
#define nec_sawtooth(phase)
Basic sawtooth waveform.
Definition tgwaveforms.h:113
long double nec_sawtoothl(long double phase)
Basic sawtooth waveform.
Definition waveforms.h:684
float nec_sawtoothf(float phase)
Basic sawtooth waveform.
Definition waveforms.h:698

Basic sawtooth waveform.

Parameters
phaseThe input phase of the waveform, in domain [0, 1).
Returns
A sample of a sawtooth waveform, with range [-1, 1].

◆ nec_sin

#define nec_sin ( phase)
Value:
_Generic((phase),\
long double : nec_sinl,\
double : nec_sin,\
float : nec_sinf\
)(phase)
#define nec_sin(phase)
Accurate sine approximation waveform.
Definition tgwaveforms.h:85
long double nec_sinl(long double phase)
Accurate sine approximation waveform.
Definition waveforms.h:513
float nec_sinf(float phase)
Accurate sine approximation waveform.
Definition waveforms.h:527

Accurate sine approximation waveform.

This function generates a sine approximation. It has a maximum absolute error of ±0.0010903. This error does produce harmonics, but they are very quiet.

A 2004 DevMaster.net forum thread by a user named "Nick" titled “Fast and accurate sine/cosine” first presents a fast but inaccurate sine/cosine approximation, then demonstrates an error correction method to drastically improve the accuracy. The fast-but-inaccurate version happens to be mathematically identical to nec_parabol() once the range of [0, τ) is remapped to [0, 1).

nec_sin() Uses the error correction method presented in Nick's forum post to greatly refine the accuracy of nec_parabol().

Parameters
phaseThe input phase of the waveform, in domain [0, 1).
Returns
A sample of sine waveform, with range [-1, 1].

◆ nec_square

#define nec_square ( phase,
duty )
Value:
_Generic((phase),\
long double : nec_squarel,\
double : nec_square,\
float : nec_squaref\
)((phase), (duty))
#define nec_square(phase, duty)
Basic square waveform.
Definition tgwaveforms.h:127
float nec_squaref(float phase, float duty)
Basic square waveform.
Definition waveforms.h:786
long double nec_squarel(long double phase, long double duty)
Basic square waveform.
Definition waveforms.h:770

Basic square waveform.

Parameters
phaseThe input phase of the waveform, in domain [0, 1).
dutyThe duty cycle of the waveform, in domain [0, 1].
Returns
A sample of a square waveform, with range [-1, 1].

◆ nec_triangle

#define nec_triangle ( phase)
Value:
_Generic((phase),\
long double : nec_trianglel,\
double : nec_triangle,\
float : nec_trianglef\
)(phase)
#define nec_triangle(phase)
Basic triangle waveform.
Definition tgwaveforms.h:141
long double nec_trianglel(long double phase)
Basic triangle waveform.
Definition waveforms.h:865
float nec_trianglef(float phase)
Basic triangle waveform.
Definition waveforms.h:879

Basic triangle waveform.

Parameters
phaseThe input phase of the waveform, in domain [0, 1).
Returns
A sample of a triangle waveform, with range [-1, 1].

◆ nec_wrap

#define nec_wrap ( phase)
Value:
_Generic((phase),\
long double : nec_wrapl,\
double : nec_wrap,\
float : nec_wrapf\
)(phase)
#define nec_wrap(phase)
Maps an arbitrary phase into the domain [0, 1).
Definition tgwaveforms.h:15
long double nec_wrapl(long double phase)
Maps an arbitrary phase into the domain [0, 1).
Definition waveforms.h:27
float nec_wrapf(float phase)
Maps an arbitrary phase into the domain [0, 1).
Definition waveforms.h:39

Maps an arbitrary phase into the domain [0, 1).

All of nectarine's waveform functions require an input phase within the domain [0, 1) and misbehave outside that domain. This function can be used to produce an equivalent input phase within that domain.

This is desirable when storing an oscillator's phase also, since long-running oscillators can accumulate floating point precision error as the phase increases further and further away from zero. Wrapping an oscillator's stored phase periodically can help prevent this.

Parameters
phaseAn arbitrary input phase.
Returns
An equivalent phase to phase, but within the domain [0, 1).