|
| bool | set_octave (int octave) noexcept |
| | Select one or two octaves below the parent.
|
| int | octave () const noexcept |
| void | set_waveform (SubOscillatorWaveform waveform) noexcept |
| SubOscillatorWaveform | waveform () const noexcept |
| void | reset (std::uint32_t completed_parent_cycles=0) noexcept |
| | Re-anchor the divider to a known completed parent-cycle count.
|
| void | on_parent_cycle () noexcept |
| | Report one completed parent cycle. Call before next(0) on a wrap.
|
| SampleType | next (SampleType parent_phase) noexcept |
| | Render from the parent's current normalized phase in [0, 1).
|
| SampleType | next (SampleType parent_phase, bool parent_cycle_edge) noexcept |
| | Convenience form for a wrap and render in one call.
|
| SampleType | phase () const noexcept |
| | The phase used for the most recently rendered valid sample.
|
template<typename SampleType = float>
class pulp::signal::SubOscillatorT< SampleType >
A one- or two-octave divider derived from an explicit parent phase.
This class deliberately owns no free-running clock. The caller supplies the normalized parent phase for every sample and reports each parent-cycle edge. The sub phase is (completed_parent_cycles + parent_phase) / 2^octave, so a parent reset or phase jump cannot leave a second oscillator drifting beside it. Call reset() when the parent cycle count is reset, and call on_parent_cycle() before rendering the first sample after each wrap.
Every operation is fixed-state, allocation-free, lock-free, and noexcept. The output has normalized amplitude, zero latency, and no tail.