Swadge 2024 2.0.0
APIs to develop games for the Magfest Swadge
Loading...
Searching...
No Matches
swSynth.h File Reference

Detailed Description

Design Philosophy

This utility code is provided to run and mix oscillators for DAC output (hdw-dac.h). Each oscillator has a shape, frequency, and amplitude. The oscillators assume the output sample rate is DAC_SAMPLE_RATE_HZ.

When an oscillator's amplitude is changed by swSynthSetVolume(), it will linearly adjust the output volume over time. This avoids clicks and pops caused by discontinuities in the output. Changing the oscillator's frequency will not cause any discontinuities. Changing the oscillator's shape will have a discontinuity and likely have an audible click or pop.

Usage

Initialize an oscillator with swSynthInitOscillator(). Change the oscillator's properties with swSynthSetShape(), swSynthSetFreq(), or swSynthSetVolume().

Call swSynthMixOscillators() to step a set of oscillators, mix their output, and return it for a DAC buffer.

Example

// Create a 440hz triangle wave at max volume
// Create a 576hz sine wave at max volume
swSynthInitOscillator(&osc_sine, SHAPE_SINE, 576, 255);
// Make an array of pointers to the oscillators
synthOscillator_t* oscillators[] = {&osc_tri, &osc_sine};
// Fill up a sample buffer
uint8_t sampleBuf[2048];
for (uint32_t i = 0; i < ARRAY_SIZE(sampleBuf); i++)
{
sampleBuf[i] = swSynthMixOscillators(oscillators, ARRAY_SIZE(oscillators));
}
#define ARRAY_SIZE(arr)
Definition macros.h:66
uint8_t swSynthMixOscillators(synthOscillator_t *oscillators[], uint16_t numOscillators)
Increment a set of oscillators by one step each, mix together the resulting samples,...
Definition swSynth.c:298
void swSynthInitOscillator(synthOscillator_t *osc, oscillatorShape_t shape, uint32_t freq, uint8_t volume)
Initialize a software synthesizer oscillator.
Definition swSynth.c:171
@ SHAPE_SINE
A sine wave.
Definition swSynth.h:66
@ SHAPE_TRIANGLE
A triangle wave.
Definition swSynth.h:68
A software oscillator with controllable frequency, amplitude, and shape.
Definition swSynth.h:107

Go to the source code of this file.

Data Structures

union  oscAccum_t
 An accumulator used to increment through a wave. A value is accumulated in a 32-bit integer and bits 16->23 are used as an index into a 256 point wave. More...
 
struct  synthOscillator_t
 A software oscillator with controllable frequency, amplitude, and shape. More...
 

Macros

#define SPK_MAX_VOLUME   255
 

Typedefs

typedef int8_t(* waveFunc_t) (uint16_t idx, void *data)
 Function typedef to return a sample from a wave.
 

Enumerations

enum  oscillatorShape_t {
  SHAPE_SINE , SHAPE_SAWTOOTH , SHAPE_TRIANGLE , SHAPE_SQUARE ,
  SHAPE_NOISE
}
 The different wave shapes that can be generated. More...
 

Functions

void swSynthInitOscillator (synthOscillator_t *osc, oscillatorShape_t shape, uint32_t freq, uint8_t volume)
 Initialize a software synthesizer oscillator.
 
void swSynthInitOscillatorWave (synthOscillator_t *osc, waveFunc_t waveFunc, void *waveData, uint32_t freq, uint8_t volume)
 Initialize a software synthesizer oscillator.
 
void swSynthSetShape (synthOscillator_t *osc, oscillatorShape_t shape)
 Set a software synthesizer oscillator's shape.
 
void swSynthSetWaveFunc (synthOscillator_t *osc, waveFunc_t waveFunc, void *waveFuncData)
 Set the wave function of an oscillator.
 
void swSynthSetFreq (synthOscillator_t *osc, uint32_t freq)
 Set the frequency of an oscillator.
 
void swSynthSetFreqPrecise (synthOscillator_t *osc, uq16_16 freq)
 Set the frequency of an oscillator with 16 bits of decimal precision.
 
void swSynthSetVolume (synthOscillator_t *osc, uint8_t volume)
 Set the volume (amplitude) of an oscillator.
 
uint8_t swSynthMixOscillators (synthOscillator_t *oscillators[], uint16_t numOscillators)
 Increment a set of oscillators by one step each, mix together the resulting samples, and return the single mixed sample.
 
int32_t swSynthSumOscillators (synthOscillator_t *oscillators[], uint16_t numOscillators)
 Increment and mix together a set of oscillators like swSynthMixOscillators(), but returns the intermediate sample sum rather than the average, to allow mixing in other sources without losing precision.
 
int8_t swSynthSampleWave (oscillatorShape_t shape, uint8_t idx)
 

Data Structure Documentation

◆ oscAccum_t

union oscAccum_t
Data Fields
uint32_t accum32 The oscillator value is accumulated in a 32 bit integer.
uint8_t bytes[4] The index into the sine table is accessed as a single byte.

◆ synthOscillator_t

struct synthOscillator_t
Data Fields
waveFunc_t waveFunc A pointer to the function which generates samples.
void * waveFuncData A pointer to pass to the wave function.
oscAccum_t accumulator An accumulator to increment the wave sample.
int32_t stepSize The step that should be added to the accumulator each sample, dependent on frequency.
uint32_t tVol The target volume (amplitude)
uint32_t cVol The current volume which smoothly transitions to the target volume.
uint8_t chorus The number of offset samples to return.

Macro Definition Documentation

◆ SPK_MAX_VOLUME

#define SPK_MAX_VOLUME   255

The maximum speaker volume

Typedef Documentation

◆ waveFunc_t

typedef int8_t(* waveFunc_t) (uint16_t idx, void *data)

Function typedef to return a sample from a wave.

Parameters
idxThe index of the wave to get a sample from
Returns
A signed 8-bit sample

Enumeration Type Documentation

◆ oscillatorShape_t

The different wave shapes that can be generated.

Enumerator
SHAPE_SINE 

A sine wave.

SHAPE_SAWTOOTH 

A sawtooth wave.

SHAPE_TRIANGLE 

A triangle wave.

SHAPE_SQUARE 

A square wave.

SHAPE_NOISE 

Random noise from a linear feedback shift register.

Function Documentation

◆ swSynthInitOscillator()

void swSynthInitOscillator ( synthOscillator_t * osc,
oscillatorShape_t shape,
uint32_t freq,
uint8_t volume )

Initialize a software synthesizer oscillator.

Parameters
oscThe oscillator to initialize
shapeThe shape of the wave to generate
freqThe frequency of the wave to generate, in hertz
volumeThe volume (amplitude) of the wave to generate

◆ swSynthInitOscillatorWave()

void swSynthInitOscillatorWave ( synthOscillator_t * osc,
waveFunc_t waveFunc,
void * waveData,
uint32_t freq,
uint8_t volume )

Initialize a software synthesizer oscillator.

Parameters
oscThe oscillator to initialize
waveFuncThe wave function to use
waveDataCustom data to pass into the wave function
freqThe frequency of the wave to generate, in hertz
volumeThe volume (amplitude) of the wave to generate

◆ swSynthSetShape()

void swSynthSetShape ( synthOscillator_t * osc,
oscillatorShape_t shape )

Set a software synthesizer oscillator's shape.

Parameters
oscThe oscillator to set the shape for
shapeThe shape to set (sine, square, sawtooth, triangle, or noise)

◆ swSynthSetWaveFunc()

void swSynthSetWaveFunc ( synthOscillator_t * osc,
waveFunc_t waveFunc,
void * waveFuncData )

Set the wave function of an oscillator.

Parameters
oscThe oscillator to set the wave function of
waveFuncThe wave function to use
waveFuncDataData to be passed to the wave function

◆ swSynthSetFreq()

void swSynthSetFreq ( synthOscillator_t * osc,
uint32_t freq )

Set the frequency of an oscillator.

Parameters
oscThe oscillator to set the frequency for
freqThe frequency to set

◆ swSynthSetFreqPrecise()

void swSynthSetFreqPrecise ( synthOscillator_t * osc,
uq16_16 freq )

Set the frequency of an oscillator with 16 bits of decimal precision.

Parameters
oscThe oscillator to set the frequency for
freqThe frequency to set, as a fixed-point value with 16 bits of decimal precision

◆ swSynthSetVolume()

void swSynthSetVolume ( synthOscillator_t * osc,
uint8_t volume )

Set the volume (amplitude) of an oscillator.

Parameters
oscThe oscillator to set the volume for
volumeThe volume, 255 is loudest, 0 is off

◆ swSynthMixOscillators()

uint8_t swSynthMixOscillators ( synthOscillator_t * oscillators[],
uint16_t numOscillators )

Increment a set of oscillators by one step each, mix together the resulting samples, and return the single mixed sample.

Parameters
oscillatorsAn array of pointers to oscillators to step and mix together
numOscillatorsThe number of oscillators to step and mix
Returns
The mixed unsigned 8-bit output sample

◆ swSynthSumOscillators()

int32_t swSynthSumOscillators ( synthOscillator_t * oscillators[],
uint16_t numOscillators )

Increment and mix together a set of oscillators like swSynthMixOscillators(), but returns the intermediate sample sum rather than the average, to allow mixing in other sources without losing precision.

The caller must divide this value by the number of oscillators (plus the number of other sources) then add 128 to the result to convert it to an unsigned 8-bit value.

Parameters
oscillatorsAn array of oscillator pointers
numOscillatorsThe number of members in oscillators
Returns
int32_t The signed sum of all oscillator samples

◆ swSynthSampleWave()

int8_t swSynthSampleWave ( oscillatorShape_t shape,
uint8_t idx )