Crate culsynth

Source
Expand description

This crate contains all of the DSP logic for the synthesizer. It is designed to be no_std friendly (though it has not yet been build/tested in this config) and all of the API and algorithms are designed to be implemented using both floating-point logic and fixed point logic. The fixed point logic additionally does not use division and minimizes the use of 32 bit widening multiplies (that is, with a 64 bit result) to the maximum extent possible for speed on embedded platforms without native hardware support for these primitives.

Most of the relevant code for users can be found in the devices module.

This crate uses the (somewhat regrettably hungarian-style) convention of having all fixed-point structs and traits be the same as their floating-point counterparts with the FxP suffix to denote fixed point operation. This is used instead of implementing it as generics implementations on u16 to preserve information about the location of the decimal place within the type system, but does require some duplication of code throughout the crate.

Modules§

context
This module provides objects to reason about the processing context. Currently, the only information wrapped is the current audio sample rate.
devices
This module contains definitions of several different DSP primitives.
midi_const
This module contains u8 constants for MIDI note numbers, using standard musical notation. For example, midi_const::Db4 is the note a semitone above middle C, and midi_const::A4 == 69u8 is A440.
util
Various utility functions and helpful constants
voice
This module contains a struct composing various devices together as a single voice unit for a basic subtractive synthesizer.

Constants§

USE_LIBM
True if using libm for floating-point math, false if using internal approximation functions

Traits§

DspFloat
Helper trait to make constraint bounds less painful for floating point types
DspFormat
A trait encompassing the different sample data types (e.g. 16 bit fixed, 32 bit float, etc).
DspFormatBase
Type aliases defining the data types of various internal signals within the synthesizer. This is primariliy to be generic over fixed/floating point
DspType
A trait to simplify common operations on DSP Types. This is used to maximize the amount of code that can be agnostic to fixed and floating point
Fixed16
A trait encompassing 16 bit fixed point numbers along with a couple of convenience methods for the type.
Float
Types must implement this trait to instantiate any of the generic devices in this module. Implementations are provided for f32 and f64.

Functions§

midi_note_to_frequency
Convert a MIDI note number to a frequency in Hz

Type Aliases§

EnvParamFxP
An envelope rise/fall time parameter, represented in seconds as an unsigned 16 bit fixed point number with 13 fractional bits and 3 integral bits. This yields a range of 0 to 8 seconds - though as implemented this timing is not precisely accurate (see [devices::EnvParamsFxP])
FrequencyFxP
A unsigned 32 bit fixed point number representing a frequency in Hz. This uses 14 integral bits and 18 fractional bits
IScalarFxP
A signed value in the range [-1, 1) - used where we need a signed version of a ScalarFxP
LfoFreqFxP
A frequency parameter for a LFO, in Hertz
NoteFxP
A unsigned 16 bit fixed point number representing a note/pitch, with 7 integral bits and 9 fractional. The integral bits correspond to the MIDI note numbers, i.e. a value of 69.0 represents A440 and tuning is 12 tone equal temprament.
SampleFxP
A fixed point number representing a sample or otherwise generic piece of data within the synthesizer. These are 16 bit signed fixed point numbers with 12 fractional bits. Put another way, our reference (0dB) level is set at an amplitude of 2^12, and we have 3 bits (9dB) of headroom before clipping, since we lose a bit for the sign bit.
ScalarFxP
A unsigned 16 bit fixed point number in the interval [0, 1). Used primarily for “scaling” signals in amplitude, hence the (admittedly not great but useful) name assigned. Note that 0xFFFF is slightly less than 1.0, so we will lose a (very) small amount of signal when maxed out.
SignedNoteFxP
A signed variant of the above. This does not have the precision to represent the entire range of the MIDI note range, but is helpful for small adjustments (e.g. pitch bend)
USampleFxP
A unsigned data type with the same number of fractional bits as a sample. Usually used for internal processing to steal an extra bit of precision when we know a value cannot be negative.