### STK/JUCE Integration with PolyBLEPStk Source: https://context7.com/martinfinke/polyblep/llms.txt Provides an example of using `PolyBLEPStk` as a drop-in `stk::Generator` wrapper for STK and JUCE audio applications. It demonstrates initialization, configuration, and integration into STK processing chains and JUCE `processBlock` methods. ```cpp #include "PolyBLEPStk.h" // Create STK-compatible oscillator PolyBLEPStk osc(44100.0, PolyBLEP::SAWTOOTH, 440.0); // Configure osc.setFrequency(330.0); osc.setPulseWidth(0.5); // Fill an STK frames buffer (1 channel, 512 frames) stk::StkFrames frames(512, 1); osc.tick(frames, 0); // channel 0 // Use with STK processing chain (e.g., through a filter) stk::BiQuad filter; filter.setResonance(800.0, 0.7, true); // 800 Hz resonant low-pass for (size_t i = 0; i < frames.size(); ++i) { frames(i, 0) = filter.tick(frames(i, 0)); } // In a JUCE AudioProcessor::processBlock, integrate like this: // void MyProcessor::processBlock(AudioBuffer& buffer, MidiBuffer&) { // stk::StkFrames stkFrames(buffer.getNumSamples(), 1); // osc.tick(stkFrames, 0); // for (int i = 0; i < buffer.getNumSamples(); ++i) // buffer.setSample(0, i, static_cast(stkFrames(i, 0))); // } ``` -------------------------------- ### Constructor Source: https://context7.com/martinfinke/polyblep/llms.txt Initializes the PolyBLEP oscillator with a sample rate, waveform type, and starting frequency. The sample rate must match the audio context, and the waveform defaults to SINE with an initial frequency of 440 Hz. It includes safety fallbacks for high frequencies. ```APIDOC ## Constructor ### Description Initialize the oscillator with a sample rate, waveform, and starting frequency. The constructor sets up all internal state. The `sampleRate` must match your audio hardware or processing context. The `waveform` defaults to `SINE` and `initialFrequency` defaults to 440 Hz (concert A). Automatically falls back to a pure sine when the requested frequency exceeds one quarter of the sample rate (Nyquist safety). ### Usage Examples ```cpp #include "PolyBLEP.h" // Basic construction — sine wave at 440 Hz, 44100 Hz sample rate PolyBLEP osc(44100.0); // Sawtooth at 110 Hz PolyBLEP sawOsc(44100.0, PolyBLEP::SAWTOOTH, 110.0); // Square wave at 880 Hz, 48 kHz sample rate PolyBLEP sqrOsc(48000.0, PolyBLEP::SQUARE, 880.0); ``` ``` -------------------------------- ### get() const Source: https://context7.com/martinfinke/polyblep/llms.txt Retrieves the current sample value without advancing the oscillator's phase. Returns a double in the approximate range of [-1.0, 1.0]. ```APIDOC ## `get() const` ### Description Return the current sample value without advancing the phase. ### Returns - **double** - The current sample value, approximately in the range `[-1.0, 1.0]`. ### Request Example ```cpp PolyBLEP osc(44100.0, PolyBLEP::SAWTOOTH, 220.0); // Write the same sample to left and right channels double sample = osc.get(); float leftChannel = static_cast(sample); float rightChannel = static_cast(sample); osc.inc(); // advance phase once // Output range check assert(sample >= -1.0 && sample <= 1.0); ``` ``` -------------------------------- ### Hard-Syncing Oscillator Phase with sync() Source: https://context7.com/martinfinke/polyblep/llms.txt Illustrates oscillator hard-sync using the `sync()` function to reset the internal phase. This is applicable for rhythmic synchronization, master-slave oscillator setups, or deterministic testing. The `sync()` function accepts any real number, which is then correctly wrapped into the `[0.0, 1.0)` range. ```cpp PolyBLEP master(44100.0, PolyBLEP::SAWTOOTH, 110.0); PolyBLEP slave(44100.0, PolyBLEP::SQUARE, 330.0); const int bufferSize = 512; float buffer[bufferSize]; for (int i = 0; i < bufferSize; ++i) { double masterSample = master.getAndInc(); // Hard-sync: reset slave when master crosses zero (phase == 0) if (i > 0 && master.getFreqInHz() > 0) { // Detect approximate phase wrap by sign change in raw output // (simplified — production code should track phase explicitly) } buffer[i] = static_cast(slave.getAndInc()); } // Explicit phase reset (e.g., on note-on) slave.sync(0.0); // reset to start of cycle slave.sync(0.25); // start at 90° phase offset slave.sync(0.5); // start at 180° phase offset ``` -------------------------------- ### Get Current Sample Without Advancing Phase Source: https://context7.com/martinfinke/polyblep/llms.txt Retrieve the current audio sample value without altering the oscillator's phase. This is useful for scenarios where the same sample needs to be read multiple times, such as for stereo output from a mono oscillator, before advancing the phase. ```cpp PolyBLEP osc(44100.0, PolyBLEP::SAWTOOTH, 220.0); // Write the same sample to left and right channels double sample = osc.get(); float leftChannel = static_cast(sample); float rightChannel = static_cast(sample); osc.inc(); // advance phase once // Output range check assert(sample >= -1.0 && sample <= 1.0); ``` -------------------------------- ### Advance Oscillator Phase by One Sample Source: https://context7.com/martinfinke/polyblep/llms.txt Increment the oscillator's internal phase by one sample without reading the output. This method is used to skip samples or to advance the phase independently when pairing with `get()` for multi-channel audio generation. ```cpp PolyBLEP osc(44100.0, PolyBLEP::SQUARE, 440.0); // Skip the first 100 samples (warm up / offset) for (int i = 0; i < 100; ++i) { osc.inc(); } // Now render clean audio const int bufferSize = 256; float buffer[bufferSize]; for (int i = 0; i < bufferSize; ++i) { buffer[i] = static_cast(osc.get()); osc.inc(); } ``` -------------------------------- ### Switch Waveform Without Resetting Phase Source: https://context7.com/martinfinke/polyblep/llms.txt Change the oscillator's waveform dynamically. The change takes effect on the next call to `get()` or `getAndInc()`. This is useful for creating evolving sounds or transitioning between different timbres. ```cpp PolyBLEP osc(44100.0, PolyBLEP::SINE, 440.0); // Cycle through waveforms on each note PolyBLEP::Waveform waveforms[] = { PolyBLEP::SAWTOOTH, PolyBLEP::SQUARE, PolyBLEP::TRIANGLE, PolyBLEP::FULL_WAVE_RECTIFIED_SINE }; for (auto wf : waveforms) { osc.setWaveform(wf); // render 512 samples of this waveform for (int i = 0; i < 512; ++i) { double sample = osc.getAndInc(); // ... write to buffer } } ``` -------------------------------- ### setWaveform(Waveform waveform) Source: https://context7.com/martinfinke/polyblep/llms.txt Switches the waveform type of the oscillator without resetting its phase. Accepts any value from the PolyBLEP::Waveform enum. Changes take effect on the next call to get() or getAndInc(). ```APIDOC ## `setWaveform(Waveform waveform)` ### Description Switch the waveform type at any time without resetting phase. ### Parameters #### Path Parameters - **waveform** (PolyBLEP::Waveform) - Required - The desired waveform type from the PolyBLEP::Waveform enum. ### Request Example ```cpp PolyBLEP osc(44100.0, PolyBLEP::SINE, 440.0); // Cycle through waveforms on each note PolyBLEP::Waveform waveforms[] = { PolyBLEP::SAWTOOTH, PolyBLEP::SQUARE, PolyBLEP::TRIANGLE, PolyBLEP::FULL_WAVE_RECTIFIED_SINE }; for (auto wf : waveforms) { osc.setWaveform(wf); // render 512 samples of this waveform for (int i = 0; i < 512; ++i) { double sample = osc.getAndInc(); // ... write to buffer } } ``` ``` -------------------------------- ### Set Oscillator Frequency Source: https://context7.com/martinfinke/polyblep/llms.txt Update the oscillator's output frequency in Hz. Call this when the pitch needs to change, such as for note events or LFO modulation. Ensure thread safety if called from multiple threads. The example shows setting a new frequency and then using it in a loop to generate samples. ```cpp PolyBLEP osc(44100.0, PolyBLEP::TRIANGLE, 440.0); // Retune to middle C osc.setFrequency(261.63); // Sweep frequency in a loop (e.g., for a pitch glide) for (int i = 0; i < 100; ++i) { osc.setFrequency(220.0 + i * 2.0); // 220 Hz → 418 Hz double sample = osc.getAndInc(); // ... send sample to audio buffer } ``` -------------------------------- ### Basic Audio Rendering with getAndInc() Source: https://context7.com/martinfinke/polyblep/llms.txt Demonstrates the typical usage of `getAndInc()` in an audio callback loop to generate audio samples. Ensure PolyBLEP is initialized with the correct sample rate, waveform, and frequency. ```cpp #include "PolyBLEP.h" #include #include int main() { const double sampleRate = 44100.0; const int bufferSize = 1024; PolyBLEP osc(sampleRate, PolyBLEP::TRIANGLE, 440.0); std::vector audioBuffer(bufferSize); // Typical audio callback pattern for (int i = 0; i < bufferSize; ++i) { audioBuffer[i] = static_cast(osc.getAndInc()); } // Print first 8 samples for (int i = 0; i < 8; ++i) { printf("sample[%d] = %f\n", i, audioBuffer[i]); } // Expected output (approximate): // sample[0] = 0.000000 // sample[1] = 0.039955 // sample[2] = 0.079910 // ... return 0; } ``` -------------------------------- ### Querying Oscillator Frequency with getFreqInHz() Source: https://context7.com/martinfinke/polyblep/llms.txt Shows how to retrieve the current oscillator frequency in Hz using `getFreqInHz()`. This is useful for verifying frequency settings after changes or for serialization. The frequency remains constant even if the sample rate is changed. ```cpp PolyBLEP osc(44100.0, PolyBLEP::SINE, 880.0); printf("Frequency: %.2f Hz\n", osc.getFreqInHz()); // 880.00 Hz osc.setSampleRate(48000.0); printf("Frequency after rate change: %.2f Hz\n", osc.getFreqInHz()); // still 880.00 Hz ``` -------------------------------- ### Initialize PolyBLEP Oscillator Source: https://context7.com/martinfinke/polyblep/llms.txt Construct the oscillator with a sample rate, waveform type, and initial frequency. The sample rate must match your audio context. Defaults are sine wave at 440 Hz with a 44100 Hz sample rate. Frequencies exceeding Nyquist/4 will fall back to a pure sine. ```cpp #include "PolyBLEP.h" // Basic construction — sine wave at 440 Hz, 44100 Hz sample rate PolyBLEP osc(44100.0); // Sawtooth at 110 Hz PolyBLEP sawOsc(44100.0, PolyBLEP::SAWTOOTH, 110.0); // Square wave at 880 Hz, 48 kHz sample rate PolyBLEP sqrOsc(48000.0, PolyBLEP::SQUARE, 880.0); ``` -------------------------------- ### PolyBLEPStk Source: https://context7.com/martinfinke/polyblep/llms.txt A drop-in wrapper for STK (Sound Synthesis Toolkit) and JUCE integration. PolyBLEPStk inherits from both stk::Generator and PolyBLEP, allowing it to be used seamlessly within STK and JUCE audio processing chains. ```APIDOC ## `PolyBLEPStk` — STK/JUCE Integration ### Description Drop-in `stk::Generator` wrapper for use in STK and JUCE audio graphs. `PolyBLEPStk` inherits from both `stk::Generator` and `PolyBLEP`, making it usable anywhere an STK generator is expected. The `tick()` method fills an `stk::StkFrames` buffer by calling `getAndInc()` for each frame. `sampleRateChanged()` is overridden to propagate rate changes from the STK framework automatically. Requires `JuceHeader.h` and the [stk_module](https://github.com/drowaudio/stk_module) for JUCE projects. ``` -------------------------------- ### getAndInc() Source: https://context7.com/martinfinke/polyblep/llms.txt Atomically retrieves the current audio sample and advances the oscillator's phase. This is the primary function for generating audio output in real-time applications. ```APIDOC ## `getAndInc()` ### Description Return the current sample and advance the phase atomically. The most common function used in audio render loops. Equivalent to calling `get()` followed by `inc()`. Returns a `double` in approximately `[-1.0, 1.0]`. ``` -------------------------------- ### sync(double phase) Source: https://context7.com/martinfinke/polyblep/llms.txt Hard-synchronizes the oscillator to a specified phase. This function is ideal for implementing oscillator hard-sync, rhythmic resets, or for deterministic testing scenarios. ```APIDOC ## `sync(double phase)` ### Description Hard-sync the oscillator to a specific phase. Resets the internal phase `t` to the given value, wrapping into `[0.0, 1.0)`. Use for oscillator hard-sync (locking a slave oscillator to a master), rhythmic resets, or deterministic testing. `phase` may be any real number; it is always wrapped correctly. ``` -------------------------------- ### setSampleRate Source: https://context7.com/martinfinke/polyblep/llms.txt Updates the oscillator's sample rate without resetting its phase. This method preserves the current frequency in Hz by reading the current frequency before updating the internal rate and recalculating the phase increment. It is useful when the audio engine's sample rate changes. ```APIDOC ## `setSampleRate(double sampleRate)` ### Description Update the sample rate without resetting the oscillator phase. Preserves the current frequency in Hz by reading back `getFreqInHz()` before updating the internal rate, then recalculating the phase increment. Use this when the audio engine's sample rate changes (e.g., device switching or plugin host notification). ### Usage Examples ```cpp PolyBLEP osc(44100.0, PolyBLEP::SINE, 440.0); // Host switches to 48 kHz — update without restarting osc.setSampleRate(48000.0); // Frequency is preserved automatically; verify: double freq = osc.getFreqInHz(); // still 440.0 ``` ``` -------------------------------- ### getFreqInHz() const Source: https://context7.com/martinfinke/polyblep/llms.txt Queries the current oscillator frequency in Hertz. This method is useful for debugging, state verification, or serialization purposes. ```APIDOC ## `getFreqInHz() const` ### Description Query the current oscillator frequency in Hz. Computes `freqInSecondsPerSample * sampleRate`. Useful for verifying state after `setSampleRate()` or for serializing oscillator state. ``` -------------------------------- ### inc() Source: https://context7.com/martinfinke/polyblep/llms.txt Advances the oscillator's phase by one sample without reading the value. This updates the internal phase and wraps it to [0.0, 1.0). ```APIDOC ## `inc()` ### Description Advance the oscillator phase by one sample without reading. ### Request Example ```cpp PolyBLEP osc(44100.0, PolyBLEP::SQUARE, 440.0); // Skip the first 100 samples (warm up / offset) for (int i = 0; i < 100; ++i) { osc.inc(); } // Now render clean audio const int bufferSize = 256; float buffer[bufferSize]; for (int i = 0; i < bufferSize; ++i) { buffer[i] = static_cast(osc.get()); osc.inc(); } ``` ``` -------------------------------- ### setPulseWidth(double pw) Source: https://context7.com/martinfinke/polyblep/llms.txt Sets the pulse width for waveforms that support variable shapes. The 'pw' parameter is a normalized value between 0.0 and 1.0. ```APIDOC ## `setPulseWidth(double pw)` ### Description Set the pulse width for variable-shape waveforms. ### Parameters #### Path Parameters - **pw** (double) - Required - Normalized value in `[0.0, 1.0]`. A value of `0.5` produces a symmetric shape. ### Request Example ```cpp PolyBLEP osc(44100.0, PolyBLEP::RECTANGLE, 440.0); // Narrow pulse (10% duty cycle) — bright, buzzy tone osc.setPulseWidth(0.1); // Wide pulse (80% duty cycle) — hollow, woody tone osc.setPulseWidth(0.8); // Animate pulse width (PWM effect) const int bufferSize = 512; float buffer[bufferSize]; for (int i = 0; i < bufferSize; ++i) { double pw = 0.5 + 0.4 * std::sin(2.0 * M_PI * i / bufferSize); osc.setPulseWidth(pw); buffer[i] = static_cast(osc.getAndInc()); } ``` ``` -------------------------------- ### Update Sample Rate Source: https://context7.com/martinfinke/polyblep/llms.txt Change the oscillator's sample rate without resetting its phase. This preserves the current frequency in Hz by recalculating the phase increment based on the new rate. Use this when the audio engine's sample rate changes dynamically. ```cpp PolyBLEP osc(44100.0, PolyBLEP::SINE, 440.0); // Host switches to 48 kHz — update without restarting osc.setSampleRate(48000.0); // Frequency is preserved automatically; verify: double freq = osc.getFreqInHz(); // still 440.0 ``` -------------------------------- ### setFrequency Source: https://context7.com/martinfinke/polyblep/llms.txt Sets the oscillator's output frequency in Hertz. This method recalculates the internal phase increment and should be called whenever the pitch needs to change, such as during note events or modulation. The caller is responsible for thread safety. ```APIDOC ## `setFrequency(double freqInHz)` ### Description Set the oscillator's output frequency in Hz. Recalculates the internal phase increment (`freqInSecondsPerSample`) as `freq / sampleRate`. Call this whenever pitch changes are needed — e.g., note-on events, LFO modulation, or pitch bend. Thread safety is the caller's responsibility. ### Usage Examples ```cpp PolyBLEP osc(44100.0, PolyBLEP::TRIANGLE, 440.0); // Retune to middle C osc.setFrequency(261.63); // Sweep frequency in a loop (e.g., for a pitch glide) for (int i = 0; i < 100; ++i) { osc.setFrequency(220.0 + i * 2.0); // 220 Hz → 418 Hz double sample = osc.getAndInc(); // ... send sample to audio buffer } ``` ``` -------------------------------- ### Set Pulse Width for Variable Waveforms Source: https://context7.com/martinfinke/polyblep/llms.txt Adjust the pulse width for waveforms like `RECTANGLE`, `MODIFIED_TRIANGLE`, and `MODIFIED_SQUARE`. The `pw` parameter is normalized between 0.0 and 1.0. Animating this value can create a Pulse Width Modulation (PWM) effect. ```cpp PolyBLEP osc(44100.0, PolyBLEP::RECTANGLE, 440.0); // Narrow pulse (10% duty cycle) — bright, buzzy tone osc.setPulseWidth(0.1); // Wide pulse (80% duty cycle) — hollow, woody tone osc.setPulseWidth(0.8); // Animate pulse width (PWM effect) const int bufferSize = 512; float buffer[bufferSize]; for (int i = 0; i < bufferSize; ++i) { double pw = 0.5 + 0.4 * std::sin(2.0 * M_PI * i / bufferSize); osc.setPulseWidth(pw); buffer[i] = static_cast(osc.getAndInc()); } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.