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

the wavetable node produces a periodic signal from a chunk of memory ( wavetable ). the speed at which the signal is produced from the wavetable can be adjusted by the changing its frequency FREQ and the amplitude by changing AMP. 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

NodeVCOWavetable.hpp