Source Class: Generator

Interactive example

Single Generator demo
100%
All controls are available across their full ranges. This allows for extreme settings which may cause undesirable audio artifacts such as static, distortion or buzzing.

Overview

The Generator creates audio in various waveform shapes. Generators can be chained together to make complex audio sources that power synths, but are also useful as a tool for diagnostics. We're using a Superpowered Generator in our oscillator input stage you might have seen through the other audio effects examples on this site.

The Superpowered Generator supports 7 different shapes, these are stored as constants under the Generator namespace:

Superpowered.Generator.Sine // sine
Superpowered.Generator.Triangle // triangle
Superpowered.Generator.Sawtooth // sawtooth
Superpowered.Generator.PWM // pulse wave with adjustable width
Superpowered.Generator.PinkNoise // pink noise
Superpowered.Generator.WhiteNoise // white noise
Superpowered.Generator.SyncMaster // generates no sound, but sync data to use with generateSyncMaster
Superpowered::Generator::Sine // sine
Superpowered::Generator::Triangle // triangle
Superpowered::Generator::Sawtooth // sawtooth
Superpowered::Generator::PWM // pulse wave with adjustable width
Superpowered::Generator::PinkNoise // pink noise
Superpowered::Generator::WhiteNoise // white noise
Superpowered::Generator::SyncMaster // generates no sound, but sync data to use with generateSyncMaster

Implementation example

Let's start of with the most simple application of a Generator, a simple sine tone oscillator. We set the initial frequency and point to our output buffer in the generate method call. Notice also that this class does not have a process method.

class SuperpoweredSingleGeneratorStageProcessor extends SuperpoweredWebAudio.AudioWorkletProcessor {
// runs after the constructor
onReady() {
this.generator = new this.Superpowered.Generator(
this.samplerate, // The initial sample rate in Hz.
this.Superpowered.Generator.Sine // The initial shape.
);
this.generator.frequency = 440;
// Create an empty buffer o store the ouput of the mono generator. 2048 is the largest buffer size we'll need to deal with
this.genOutputBuffer = new this.Superpowered.Float32Buffer(2048);
}
onDestruct() {
this.generator.destruct();
}
// messages are received from the main scope through this method.
onMessageFromMainScope(message) {
if (typeof message.frequency !== 'undefined') this.generator.frequency = message.frequency;
}
processAudio(inputBuffer, outputBuffer, buffersize, parameters) {
// Ensure the samplerate is in sync on every audio processing callback
this.generator.samplerate = this.samplerate;
// Generate the output buffers
this.generator.generate(
this.genOutputBuffer.pointer, // output, // Pointer to floating point numbers. 32-bit MONO output.
buffersize // number of samples to generate
);
// We now need to convert the mono signal from the generator into he interleaved stereo format that the parent audio context requires.
this.Superpowered.Interleave(
this.genOutputBuffer.pointer, // left mono input
this.genOutputBuffer.pointer, // right mono input
outputBuffer.pointer, // stereo output - this is what is routed to the AudioWorkletProcessor output
buffersize // number of frames
);
}
}
#include "SuperpoweredGenerator.h"
void initGeneratorSource() {
generator = new Superpowered::Generator(48000. Superpowered::Generator::Sine);
generator->frequency = 440;
}
void processAudio(float *interleavedInput, float *interleavedOutput, unsigned int numberOfFrames, unsigned int samplerate) {
// Ensure the samplerate is in sync on every audio processing callback
generator->samplerate = samplerate;
// Generate the output buffers
generator->generate(interleavedOutput, numberOfFrames);
}

Multiple voices

We can create multiple Oscillators and sum the results together.

class SuperpoweredMultipleGeneratorStageProcessor extends SuperpoweredWebAudio.AudioWorkletProcessor {
// runs after the constructor
onReady() {
this.generator1 = new this.Superpowered.Generator(
this.samplerate, // The initial sample rate in Hz.
this.Superpowered.Generator.Sine // The initial shape.
);
this.generator2 = new this.Superpowered.Generator(
this.samplerate, // The initial sample rate in Hz.
this.Superpowered.Generator.Sine // The initial shape.
);
this.gen1OutputBuffer = new this.Superpowered.Float32Buffer(2048); // A floating point number is 4 bytes, therefore we allocate length * 4 bytes of memory.
this.gen2OutputBuffer = new this.Superpowered.Float32Buffer(2048);
// An empty buffer to hold the summed generators
this.summedMonoOutputBuffer = new this.Superpowered.Float32Buffer(2048);
this.generator1.frequency = 440;
this.generator2.frequency = 880;
}
onDestruct() {
this.generator1.destruct();
this.generator2.destruct();
}
// messages are received from the main scope (AudioEngine in this case) through this method.
onMessageFromMainScope(message) {
if (typeof message.frequency1 !== 'undefined') this.generator1.frequency = message.frequency1;
if (typeof message.pulsewidth1 !== 'undefined') this.generator1.pulsewidth = message.pulsewidth1;
if (typeof message.shape1 !== 'undefined') this.generator1.shape = this.Superpowered.Generator[message.shape1];
if (typeof message.frequency2 !== 'undefined') this.generator2.frequency = message.frequency2;
if (typeof message.pulsewidth2 !== 'undefined') this.generator2.pulsewidth = message.pulsewidth2;
if (typeof message.shape2 !== 'undefined') this.generator2.shape = this.Superpowered.Generator[message.shape2];
}
processAudio(inputBuffer, outputBuffer, buffersize, parameters) {
// Ensure the samplerate is in sync on every audio processing callback
this.generator1.samplerate = this.samplerate;
this.generator2.samplerate = this.samplerate;
this.generator1.generate(
this.gen1Pointer.pointer, // output, // Pointer to floating point numbers. 32-bit MONO output.
buffersize // we multiple this by two because .generate returns a mono signal whereas the outputBuffer is interleaved stereo.
);
this.generator2.generate(
this.gen2Pointer.pointer, // output, // Pointer to floating point numbers. 32-bit MONO output.
buffersize // we multiple this by two because .generate returns a mono signal whereas the outputBuffer is interleaved stereo.
);
this.Superpowered.Add2(
this.gen1Pointer.pointer, // Pointer to floating point numbers. Mono input for left channel.
this.gen2Pointer.pointer, // Pointer to floating point numbers. Mono input for right channel.
this.monoSumPointer.pointer, // Pointer to floating point numbers. Stereo interleaved output.
buffersize // The number of frames to process.
);
// We now need to convert the mono signal from the generator into he interleaved stereo format that the parent audio context requires.
this.Superpowered.Interleave(
this.monoSumPointer.pointer, // left mono input
this.monoSumPointer.pointer, // right mono input
outputBuffer.pointer, // stereo output - this is what is routed to the AudioWorkletProcessor output
buffersize // number of frames
);
}
#include "SuperpoweredGenerator.h"
void initGeneratorSources() {
generator1 = new Superpowered::Generator(48000. Superpowered::Generator::Sine);
generator2 = new Superpowered::Generator(48000. Superpowered::Generator::Sine);
generator1->frequency = 440;
generator2->frequency = 880;
}
void processAudio(float *interleavedInput, float *interleavedOutput, unsigned int numberOfFrames, unsigned int samplerate) {
// Ensure the samplerate is in sync on every audio processing callback
generator1->samplerate = samplerate;
generator2->samplerate = samplerate
// Create two buffers to store the output of the two generators before summing
float gen1OutputBuffer[numberOfFrames];
float gen2OutputBuffer[numberOfFrames];
float monoSumBuffer[numberOfFrames];
// Generate the output buffers
generator1->generate(gen1OutputBuffer, numberOfFrames);
generator2->generate(gen2OutputBuffer, numberOfFrames);
Superpowered->Add2(
gen1OutputBuffer, // Pointer to floating point numbers.
gen2OutputBuffer, // Pointer to floating point numbers.
monoSumBuffer, // Pointer to floating point numbers.
numberOfFrames // The number of frames to process.
);
Superpowered->Interleave(
monoSumBuffer, // Pointer to floating point numbers. Mono input for left channel.
monoSumBuffer, // Pointer to floating point numbers. Mono input for right channel.
interleavedOutput, // Pointer to floating point numbers. Stereo interleaved output.
buffersize // The number of frames to process.
);
}

Here's how multiple oscillators sound:

Multiple Generators demo
100%
All controls are available across their full ranges. This allows for extreme settings which may cause undesirable audio artifacts such as static, distortion or buzzing.

FM synthesis

We can use the Superpowered synthesizer to create frequency modulated outputs from our Generators. For a guide on Frequency modulation, see the Wikipedia page.

class SuperpoweredFmGeneratorStageProcessor extends SuperpoweredWebAudio.AudioWorkletProcessor {
// Runs after the constructor
onReady() {
this.carrier = new this.Superpowered.Generator(
this.samplerate, // The initial sample rate in Hz.
this.Superpowered.Generator.Sine // The initial shape.
);
this.modulator = new this.Superpowered.Generator(
this.samplerate, // The initial sample rate in Hz.
this.Superpowered.Generator.Sine // The initial shape.
);
this.carrierBuffer = new this.Superpowered.Float32Buffer(2048); // A floating point number is 4 bytes, therefore we allocate length * 4 bytes of memory.
this.modulatorBuffer = new this.Superpowered.Float32Buffer(2048);
this.carrier.frequency = 440
this.modulator.frequency = 1.5;
this.modDepth = 250;
}
onDestruct() {
this.carrier.destruct();
this.modulator.destruct();
}
// Messages are received from the main scope (AudioEngine in this case) through this method.
onMessageFromMainScope(message) {
if (typeof message.frequency1 !== 'undefined') this.carrier.frequency = Number(message.frequency1) ;
if (typeof message.pulsewidth1 !== 'undefined') this.carrier.pulsewidth = Number(message.pulsewidth1);
if (typeof message.shape1 !== 'undefined') this.carrier.shape = this.Superpowered.Generator[message.shape1];
if (typeof message.frequency2 !== 'undefined') this.modulator.frequency = Number(message.frequency2);
if (typeof message.modDepth !== 'undefined') this.modDepth = Number(message.modDepth);
if (typeof message.shape2 !== 'undefined') this.modulator.shape = this.Superpowered.Generator[message.shape2];
}
processAudio(inputBuffer, outputBuffer, buffersize, parameters) {
// Generate the modulator output first
this.modulator.generate(
this.modulatorBuffer.pointer, // output, // Pointer to floating point numbers. 32-bit MONO output.
buffersize // we multiple this by two because .generate returns a mono signal whereas the outputBuffer is interleaved stereo.
);
// Use the modulator output as the FM source of the carrier.
this.carrier.generateFM(
this.carrierBuffer.pointer, // output, // Pointer to floating point numbers. 32-bit MONO output.
buffersize, // we multiple this by two because .generate returns a mono signal whereas the outputBuffer is interleaved stereo.
this.modulatorBuffer.pointer, // The Modulator source,
this.modDepth
);
this.Superpowered.Interleave(
this.carrierBuffer.pointer, // Pointer to floating point numbers. Mono input for left channel.
this.carrierBuffer.pointer, // Pointer to floating point numbers. Mono input for right channel.
outputBuffer.pointer, // Pointer to floating point numbers. Stereo interleaved output.
buffersize // The number of frames to process.
);
}
}
#include "SuperpoweredGenerator.h"
void initGeneratorSources() {
carrier = new Superpowered::Generator(48000. Superpowered::Generator::Sine);
modulator = new Superpowered::Generator(48000. Superpowered::Generator::Sine);
carrier->frequency = 440;
modulator->frequency = 880;
modDeph = 250;
}
void processAudio(float *interleavedInput, float *interleavedOutput, unsigned int numberOfFrames, unsigned int samplerate) {
// Create two buffers to store the output of the two generators before summing
float carrierBuffer[numberOfFrames];
float modulatorBuffer[numberOfFrames];
// Ensure the samplerate is in sync on every audio processing callback
carrier->samplerate = samplerate;
modulator->samplerate = samplerate
// Generate the modulator output first
modulator->generate(modulatorBuffer, numberOfFrames);
// Use the modulator output as the FM source of the carrier.
carrier->generateFM(carrierBuffer, numberOfFrames, modulatorBuffer, modDepth);
// Interleave the left and right channels for the output pointer
Superpowered->Interleave(
carrierBuffer,
carrierBuffer,
interleavedOutput,
numberOfFrames
);
}

Here's how FM synthesis sounds:

FM Synthesis Generators demo
100%
All controls are available across their full ranges. This allows for extreme settings which may cause undesirable audio artifacts such as static, distortion or buzzing.

Shapes

  • Superpowered.Generator.GeneratorShape

    CONSTANTS
    Superpowered generator shapes.
    ValueDescription
    Sinesine wave
    Triangletriangle wave
    Sawtoothsawtooth wave
    PWMpulse wave with adjustable width
    PinkNoisepink noise
    WhiteNoisewhite noise
    SyncMastergenerates no sound, but sync data to use with generateSyncMaster
  • Superpowered::Generator::GeneratorShape

    CONSTANTS
    Superpowered generator shapes.
    ValueDescription
    Sinesine wave
    Triangletriangle wave
    Sawtoothsawtooth wave
    PWMpulse wave with adjustable width
    PinkNoisepink noise
    WhiteNoisewhite noise
    SyncMastergenerates no sound, but sync data to use with generateSyncMaster

Properties

frequency

PROPERTY
Frequency of generator output in Hz.
TypeMinMaxDefault
Number
0.0001sample rate / 2440

frequency

PROPERTY
Frequency of generator output in Hz.
TypeMinMaxDefault
float
0.0001sample rate / 2440

pulsewidth

PROPERTY
Pulse Width for PWM shape. 0.5 results in a square wave.
TypeMinMaxDefault
Number
0.00010.99990.5

pulsewidth

PROPERTY
Pulse Width for PWM shape. 0.5 results in a square wave.
TypeMinMaxDefault
float
0.00010.99990.5

samplerate

PROPERTY
The sample rate of the audio context inHz, you must update if it changes.
TypeMinMaxDefault
Number

samplerate

PROPERTY
The sample rate of the audio context inHz, you must update if it changes.
TypeMinMaxDefault
unsigned int

shape

PROPERTY
Waveform shape of generator.
TypeMinMaxDefault
Number

shape

PROPERTY
Waveform shape of generator.
TypeMinMaxDefault
Superpowered::Generator::shape

Methods

  • constructor

    METHOD
    Creates a Generator instance.
    Parameters
    NameTypeDescription
    samplerateNumberThe initial sample rate in Hz.
    GeneratorShapeGenerator.GeneratorShapeThe initial shape.
    Returns
    TypeDescription
    Superpowered.Superpowered::GeneratorThe constructed instance.
  • constructor

    METHOD
    Creates a Generator instance.
    Parameters
    NameTypeDefaultDescription
    samplerateunsigned intThe initial sample rate in Hz.
    GeneratorShapeGenerator::GeneratorShapeThe initial shape.
    Returns
    TypeDescription
    Superpowered::Superpowered::GeneratorThe constructed instance.
  • generate

    METHOD
    Generates (outputs) audio. It's never blocking for real-time usage. You can change all properties on any thread, concurrently with this function.
    Parameters
    NameTypeDescription
    outputNumber (pointer in Linear Memory)32-bit MONO output
    numberOfSamplesNumberNumber of samples to produce.
    Returns
    None
  • generate

    METHOD
    Generates (outputs) audio. It's never blocking for real-time usage. You can change all properties on any thread, concurrently with this function.
    Parameters
    NameTypeDefaultDescription
    outputfloat *32-bit MONO output
    numberOfSamplesunsigned intNumber of samples to produce.
    Returns
    None
  • generateAndCreateSync

    METHOD
    Generates audio for an oscillator that also serves as synchronization source for another oscillator. It's never blocking for real-time usage. You can change all properties on any thread, concurrently with this function.
    Parameters
    NameTypeDescription
    outputNumber (pointer in Linear Memory)32-bit MONO output
    syncdataNumber (pointer in Linear Memory)A buffer to receive hard sync information for syncing oscillators. Should be numberOfSamples + 1 floats big minimum.
    numberOfSamplesNumberNumber of samples to produce.
    Returns
    None
  • generateAndCreateSync

    METHOD
    Generates audio for an oscillator that also serves as synchronization source for another oscillator. It's never blocking for real-time usage. You can change all properties on any thread, concurrently with this function.
    Parameters
    NameTypeDefaultDescription
    outputfloat *32-bit MONO output
    syncdatafloat *A buffer to receive hard sync information for syncing oscillators. Should be numberOfSamples + 1 floats big minimum.
    numberOfSamplesunsigned intNumber of samples to produce.
    Returns
    None
  • generateFM

    METHOD
    Generates (outputs) audio for a frequency modulated (FM) oscillator. It's never blocking for real-time usage. You can change all properties on any thread, concurrently with this function.
    Parameters
    NameTypeDescription
    outputNumber (pointer in Linear Memory)32-bit MONO output
    numberOfSamplesNumberNumber of samples to produce.
    fmsourceNumber (pointer in Linear Memory)Source for FM modulation containing numberOfSamples samples, usually from a previous call to generate().
    fmdepthNumberFrequency modulation depth. 0 means no modulation, 1000 is a reasonable upper limit.
    Returns
    None
  • generateFM

    METHOD
    Generates (outputs) audio for a frequency modulated (FM) oscillator. It's never blocking for real-time usage. You can change all properties on any thread, concurrently with this function.
    Parameters
    NameTypeDefaultDescription
    outputfloat *32-bit MONO output
    numberOfSamplesunsigned intNumber of samples to produce.
    fmsourcefloat *Source for FM modulation containing numberOfSamples samples, usually from a previous call to generate().
    fmdepthfloatFrequency modulation depth. 0 means no modulation, 1000 is a reasonable upper limit.
    Returns
    None
  • generateSynchronized

    METHOD
    Generates audio for an oscillator that is hard-synced to another oscillator. It's never blocking for real-time usage. You can change all properties on any thread, concurrently with this function.
    Parameters
    NameTypeDescription
    outputNumber (pointer in Linear Memory)32-bit MONO output
    syncdataNumber (pointer in Linear Memory)A buffer to receive hard sync information for syncing oscillators. Should be numberOfSamples + 1 floats big minimum.
    numberOfSamplesNumberNumber of samples to produce.
    Returns
    None
  • generateSynchronized

    METHOD
    Generates audio for an oscillator that is hard-synced to another oscillator. It's never blocking for real-time usage. You can change all properties on any thread, concurrently with this function.
    Parameters
    NameTypeDefaultDescription
    outputfloat *32-bit MONO output
    syncdatafloat *A buffer to receive hard sync information for syncing oscillators. Should be numberOfSamples + 1 floats big minimum.
    numberOfSamplesunsigned intNumber of samples to produce.
    Returns
    None
  • reset

    METHOD
    Start oscillator with given phase angle. In a synthesizer, this should be called whenever a voice starts.
    Parameters
    NameTypeDescription
    phaseNumberStart phase of the oscillator between 0.0 (0 degree) and 1.0 (180 degrees).
    Returns
    None
  • reset

    METHOD
    Start oscillator with given phase angle. In a synthesizer, this should be called whenever a voice starts.
    Parameters
    NameTypeDefaultDescription
    phasefloatStart phase of the oscillator between 0.0 (0 degree) and 1.0 (180 degrees).
    Returns
    None

v1.0.6