[ NODE_VCO_FUNCTION      ]       
      +------------------------+       
      |                        |       
IN00--| FREQ            SIGNAL |--OUT00
IN01--| AMP                    |       
      |                        |       
      +------------------------+       

the oscillator node produces a periodic signal from a selectable function. the frequency FREQ and the amplitude AMP can be adjusted. the node is often used as an oscillator to produce a sinewave, triangle, square or sawtooth shaped signal at an audible frequency ( (V)oltage-(C)ontrolled (O)scillator (VCO) ). however, this node can also be used to manipulate other parameters ( e.g the frequency of another node ) at a lower frequency ( (L)ow (F)requency (O)scillator (LFO) ).

SET_VALUE

  • FREQUENCY_F32
  • AMPLITUDE_F32
  • OFFSET_F32
  • WAVEFORM_I8
/*
 * this example demonstrates how to generate signals from oscillators. note that there are two different types of
 * oscillators:
 *
 * - `NodeVCOFunction` :: computes a signal from a function on the fly. it is more precise especially at very low
 *   frequencies, and uses less memory but requires more compuational resources.
 * - `NodeVCOWavetable` :: computes a signal from a wavetable. it requires more memory and might create artifacts
 *    especially at low frequencies. it however is much faster. note that the wavetable is not generated at
 *    instantiation time, and must always be popluated before use. the wavetable can also be populated with custom
 *    waveforms.
 *
 * press keys 1–4 to switch the waveform of the function oscillators. press keys 5–8 to switch the waveform of the
 * wavetable oscillators. use mouse to change the frequency and the amplitude of the osciallators.
 */

#include "Klangstrom.h"
#include "KlangNodes.hpp"

using namespace klang;
using namespace klangstrom;

NodeVCOFunction  mVCOFunction;
NodeVCOWavetable mVCOWavetable;
NodeDAC          mDAC;

void setup() {
    Klang::connect(mVCOFunction, Node::CH_OUT_SIGNAL, mDAC, NodeDAC::CH_IN_SIGNAL_LEFT);
    Klang::connect(mVCOWavetable, Node::CH_OUT_SIGNAL, mDAC, NodeDAC::CH_IN_SIGNAL_RIGHT);

    mVCOFunction.set_frequency(DEFAULT_FREQUENCY * 2);
    mVCOFunction.set_amplitude(0.5);
    mVCOWavetable.set_frequency(mVCOFunction.get_frequency());
    mVCOWavetable.set_amplitude(mVCOFunction.get_amplitude());
    mVCOWavetable.set_waveform(NodeVCOWavetable::WAVEFORM::SINE);

    mDAC.set_stereo(true);
}

void loop() {}

void audioblock(float** input_signal, float** output_signal) {
    mDAC.process_frame(output_signal[LEFT], output_signal[RIGHT]);
}

void handle_key_pressed(char key) {
    switch (key) {
        case '1':
            mVCOFunction.set_waveform(NodeVCOFunction::WAVEFORM::SINE);
            break;
        case '2':
            mVCOFunction.set_waveform(NodeVCOFunction::WAVEFORM::TRIANGLE);
            break;
        case '3':
            mVCOFunction.set_waveform(NodeVCOFunction::WAVEFORM::SAWTOOTH);
            break;
        case '4':
            mVCOFunction.set_waveform(NodeVCOFunction::WAVEFORM::SQUARE);
            break;
        case '5':
            mVCOWavetable.set_waveform(NodeVCOWavetable::WAVEFORM::SINE);
            break;
        case '6':
            mVCOWavetable.set_waveform(NodeVCOWavetable::WAVEFORM::TRIANGLE);
            break;
        case '7':
            mVCOWavetable.set_waveform(NodeVCOWavetable::WAVEFORM::SAWTOOTH);
            break;
        case '8':
            mVCOWavetable.set_waveform(NodeVCOWavetable::WAVEFORM::SQUARE);
            break;
        case '9':
            mVCOWavetable.set_waveform(NodeVCOWavetable::WAVEFORM::EXPONENT);
            break;
    }
}

void event_receive(const EVENT_TYPE event, const void* data) {
    switch (event) {
        case EVENT_KEY_PRESSED:
            handle_key_pressed(keyboard_event(data).keys[0]);
            break;
        case EVENT_MOUSE_MOVED:
            mVCOFunction.set_frequency(DEFAULT_FREQUENCY / 2 * floor(32 * mouse_event(data).x));
            mVCOFunction.set_amplitude(0.5 * mouse_event(data).y);
            mVCOWavetable.set_frequency(mVCOFunction.get_frequency());
            mVCOWavetable.set_amplitude(mVCOFunction.get_amplitude());
            break;
    }
}

Source Code

NodeVCOFunction.hpp