Phase generator with portamento and exponential frequency modulation.
It outputs a normalized phase signal (range [0.f, 1.f)).
Version: 1.2.2
License:
Advanced versions:
Requires:
Included in Brickworks, which is:
Here you can download one or more example VST3 plugins for Windows, macOS and Linux. Source code of the audio engine(s) is included in the archive(s).
| Description | Link |
|---|---|
| Ring modulator | Download |
| Monophonic subtractive synth | Download |
| Polyphonic subtractive synth | Download |
| Simple monophonic subtractive synth | Download |

Module type: DSP
typedef struct bw_phase_gen_coeffs bw_phase_gen_coeffs;
Coefficients and related.
typedef struct bw_phase_gen_state bw_phase_gen_state;
Internal state and related.
static inline void bw_phase_gen_init(
bw_phase_gen_coeffs * BW_RESTRICT coeffs);
Initializes input parameter values in coeffs.
static inline void bw_phase_gen_set_sample_rate(
bw_phase_gen_coeffs * BW_RESTRICT coeffs,
float sample_rate);
Sets the sample_rate (Hz) value in coeffs.
static inline void bw_phase_gen_reset_coeffs(
bw_phase_gen_coeffs * BW_RESTRICT coeffs);
Resets coefficients in coeffs to assume their target values.
static inline void bw_phase_gen_reset_state(
const bw_phase_gen_coeffs * BW_RESTRICT coeffs,
bw_phase_gen_state * BW_RESTRICT state,
float phase_0,
float * BW_RESTRICT y_0,
float * BW_RESTRICT y_inc_0);
Resets the given state to its initial values using the given coeffs and the initial phase value phase_0.
The corresponding initial output and phase increment values are put into y_0 and y_inc_0 respectively.
phase_0 must be in [0.f, 1.f).
static inline void bw_phase_gen_reset_state_multi(
const bw_phase_gen_coeffs * BW_RESTRICT coeffs,
bw_phase_gen_state * BW_RESTRICT const * BW_RESTRICT state,
const float * phase_0,
float * y_0,
float * y_inc_0,
size_t n_channels);
Resets each of the n_channels states to its initial values using the given coeffs and the corresponding initial phase value in the phase_0 array.
The corresponding initial output and phase increment values are put into the y_0 and y_inc_0 arrays, respectively, if they are not BW_NULL.
Values in phase_0 must be in [0.f, 1.f).
static inline void bw_phase_gen_update_coeffs_ctrl(
bw_phase_gen_coeffs * BW_RESTRICT coeffs);
Triggers control-rate update of coefficients in coeffs.
static inline void bw_phase_gen_update_coeffs_audio(
bw_phase_gen_coeffs * BW_RESTRICT coeffs);
Triggers audio-rate update of coefficients in coeffs.
static inline void bw_phase_gen_process1(
const bw_phase_gen_coeffs * BW_RESTRICT coeffs,
bw_phase_gen_state * BW_RESTRICT state,
float * BW_RESTRICT y,
float * BW_RESTRICT y_inc);
static inline void bw_phase_gen_process1_mod(
const bw_phase_gen_coeffs * BW_RESTRICT coeffs,
bw_phase_gen_state * BW_RESTRICT state,
float x_mod,
float * BW_RESTRICT y,
float * BW_RESTRICT y_inc);
These functions generate one output sample using coeffs, while using and updating state, putting its value in y and the corresponding phase increment value in y_inc.
In particular:
bw_phase_gen_process1() does not apply frequency modulation;bw_phase_gen_process1_mod() applies exponential frequency modulation using x_mod as modulation input (scale 1.f/octave).static inline void bw_phase_gen_process(
bw_phase_gen_coeffs * BW_RESTRICT coeffs,
bw_phase_gen_state * BW_RESTRICT state,
const float * x_mod,
float * y,
float * y_inc,
size_t n_samples);
Generates and fills the first n_samples of the output buffer y, while using and updating both coeffs and state (control and audio rate).
If x_mod is not BW_NULL, it is used as a source of exponential frequency modulation (scale 1.f/octave).
If y_inc is not BW_NULL, it is filled with phase increment values.
static inline void bw_phase_gen_process_multi(
bw_phase_gen_coeffs * BW_RESTRICT coeffs,
bw_phase_gen_state * BW_RESTRICT const * BW_RESTRICT state,
const float * const * x_mod,
float * const * y,
float * const * y_inc,
size_t n_channels,
size_t n_samples);
Generates and fills the first n_samples of the n_channels output buffers y, while using and updating both the common coeffs and each of the n_channels states (control and audio rate).
If x_mod and the channel-specific element are not BW_NULL, this is used as a source of exponential frequency modulation (scale 1.f/octave) for that channel.
If y_inc and the channel-specific element are not BW_NULL, this is filled with phase increment values for that channel.
static inline void bw_phase_gen_set_frequency(
bw_phase_gen_coeffs * BW_RESTRICT coeffs,
float value);
Sets the base frequency to value (Hz) in coeffs.
value must be finite.
Default value: 1.f.
static inline void bw_phase_gen_set_portamento_tau(
bw_phase_gen_coeffs * BW_RESTRICT coeffs,
float value);
Sets the portamento time constant value (s) in coeffs.
value must be non-negative.
Default value: 0.f.
static inline void bw_phase_gen_set_phase_inc_min(
bw_phase_gen_coeffs * BW_RESTRICT coeffs,
float value);
Sets the minimum phase increment value in coeffs.
The algorithm will limit the actual phase increment accordingly, yet if the magnitude of the resulting phase increment is less than 6e-8f, it will be rounded to 0.f and such value will be reported by processing functions.
Valid range: [-INFINITY, INFINITY).
By the time bw_phase_gen_reset_*(), bw_phase_gen_update_coeffs_*(), or bw_peak_process*() is called, phase_inc_min must be less than phase_inc_max.
Default value: -INFINITY.
static inline void bw_phase_gen_set_phase_inc_max(
bw_phase_gen_coeffs * BW_RESTRICT coeffs,
float value);
Sets the maximum phase increment value in coeffs.
The algorithm will limit the actual phase increment accordingly, yet if the magnitude of the resulting phase increment is less than 6e-8f, it will be rounded to 0.f and such value will be reported by processing functions.
Valid range: (-INFINITY, INFINITY].
By the time bw_phase_gen_reset_*(), bw_phase_gen_update_coeffs_*(), or bw_peak_process*() is called, phase_inc_min must be less than phase_inc_max.
Default value: INFINITY.
static inline char bw_phase_gen_coeffs_is_valid(
const bw_phase_gen_coeffs * BW_RESTRICT coeffs);
Tries to determine whether coeffs is valid and returns non-0 if it seems to be the case and 0 if it is certainly not. False positives are possible, false negatives are not.
coeffs must at least point to a readable memory block of size greater than or equal to that of bw_phase_gen_coeffs.
static inline char bw_phase_gen_state_is_valid(
const bw_phase_gen_coeffs * BW_RESTRICT coeffs,
const bw_phase_gen_state * BW_RESTRICT state);
Tries to determine whether state is valid and returns non-0 if it seems to be the case and 0 if it is certainly not. False positives are possible, false negatives are not.
If coeffs is not BW_NULL extra cross-checks might be performed (state is supposed to be associated to coeffs).
state must at least point to a readable memory block of size greater than or equal to that of bw_phase_gen_state.
template<size_t N_CHANNELS = 1>
class PhaseGen {
public:
PhaseGen();
void setSampleRate(
float sampleRate);
void reset(
float phase0 = 0.f,
float * BW_RESTRICT y0 = BW_NULL,
float * BW_RESTRICT yInc0 = BW_NULL);
# ifndef BW_CXX_NO_ARRAY
void reset(
float phase0,
std::array<float, N_CHANNELS> * BW_RESTRICT y0,
std::array<float, N_CHANNELS> * BW_RESTRICT yInc0);
# endif
void reset(
const float * phase0,
float * y0 = BW_NULL,
float * yInc0 = BW_NULL);
# ifndef BW_CXX_NO_ARRAY
void reset(
std::array<float, N_CHANNELS> phase0,
std::array<float, N_CHANNELS> * BW_RESTRICT y0 = BW_NULL,
std::array<float, N_CHANNELS> * BW_RESTRICT yInc0 = BW_NULL);
# endif
void process(
const float * const * xMod,
float * const * y,
float * const * yInc,
size_t nSamples);
# ifndef BW_CXX_NO_ARRAY
void process(
std::array<const float *, N_CHANNELS> xMod,
std::array<float *, N_CHANNELS> y,
std::array<float *, N_CHANNELS> yInc,
size_t nSamples);
# endif
void setFrequency(
float value);
void setPortamentoTau(
float value);
void setPhaseIncMin(
float value);
void setPhaseIncMax(
float value);
...
}
N_CHANNELS in C++ API.BW_NULL in the C++ API and implementation.BW_INCLUDE_WITH_QUOTES, BW_NO_CXX, and BW_CXX_NO_EXTERN_C.bw_phase_gen_process() to bw_phase_gen_process_multi().bw_phase_reset_state() to ensure that phase_0 is in [0.f, 1.f) and indicated such range in the documentation.bw_phase_gen_process_multi() to ensure that buffers used for both input and output appear at the same channel indices.bw_phase_gen_process_multi() by which debugging code could report false negatives when BW_NULL buffers are used.BW_NULL and BW_CXX_NO_ARRAY.bw_phase_gen_reset_state().bw_phase_gen_reset_state_multi() and updated C++ API in this regard.bw_phase_gen_reset_state() returns the initial output values.reset() functions taking arrays as arguments.bw_phase_gen_process() and bw_phase_gen_process_multi() now use size_t to count samples and channels.const and BW_RESTRICT specifiers to input arguments and implementation.process() function taking C-style arrays as arguments.bw_phase_gen_reset_coeffs().bw_phase_gen_process_multi().BW_RESTRICT to bw_phase_gen_process1*().