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§
- This module provides objects to reason about the processing context. Currently, the only information wrapped is the current audio sample rate.
- This module contains definitions of several different DSP primitives.
- 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, andmidi_const::A4 == 69u8
is A440. - Various utility functions and helpful constants
- This module contains a struct composing various devices together as a single voice unit for a basic subtractive synthesizer.
Constants§
- True if using libm for floating-point math, false if using internal approximation functions
Traits§
- Helper trait to make constraint bounds less painful for floating point types
- A trait encompassing the different sample data types (e.g. 16 bit fixed, 32 bit float, etc).
- Type aliases defining the data types of various internal signals within the synthesizer. This is primariliy to be generic over fixed/floating point
- 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
- A trait encompassing 16 bit fixed point numbers along with a couple of convenience methods for the type.
- Types must implement this trait to instantiate any of the generic devices in this module. Implementations are provided for
f32
andf64
.
Functions§
- Convert a MIDI note number to a frequency in Hz
Type Aliases§
- 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])
- A unsigned 32 bit fixed point number representing a frequency in Hz. This uses 14 integral bits and 18 fractional bits
- A signed value in the range
[-1, 1)
- used where we need a signed version of a ScalarFxP - A frequency parameter for a LFO, in Hertz
- 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.
- 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.
- 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. - 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)
- 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.