sndc
is a modular, non real time synthesizer that essentially behaves like a
compiler for sound effects.
It turns source files (.sndc
files), which are essentially directed acyclic
graphs of data transferred from generators through various effect modules into a
float buffer which can then be converted to sound files or played with external
tools.
This is supposed to be a programmer/nerd friendly way of quickly hacking together complex sound effects and potentially even music, with source files that can be easily added to a VCS like git, and generation that's build-system friendly when integrated into a complex project such as a video game.
Dependencies:
- libfftw3
$ git clone https://pedantic.software/git/sndc
$ cd sndc
$ make
You can install sndc
and its wrappers with make install
.
A source file is a collection of nodes. Each node is an instance of a particular module. A node is declared like so:
nodeName: moduleName {
/* list of inputs */
}
Each module has a set of inputs, whose type can be either FLOAT
, BUFFER
or
STRING
. Of course this is an ongoing project and further data types will be
added in the future. They are set like so:
inputName: inputValue;
Some inputs are required and some are optional depending on the module.
inputValue
can be either a literal value, or the output of a node above
the current node. Example:
newNode: myModule { /* node named "newNode", instance of "myModule" */
input: n.out; /* "input" is set to an output buffer of a previous node */
freq: 440; /* "freq" is set to a literal float */
interp: "sine"; /* "interp" is set to a literal string */
}
For a better overview, look at the examples in the examples
directory.
You can list all built-in modules with:
$ ./sndc -l
You can list inputs of a particular module, along with their type and whether they are required, with:
$ ./sndc -h moduleName
sndc
follows the UNIX philosophy and as such, delegates the task of playing
and converting the output binary data to external tools.
Linux users will find that tools such as aplay
for playing and sox
for
converting raw output are a good fit.
sndc
will go through the input file, load all modules in memory, perform basic
sanity checks of input types, then print the raw content of the output of the
last module in the stack, either in the specified output file or in stdout
.
A typical invocation of sndc
piped into aplay
for immediate replay of the
sound might look like this:
$ ./sndc file.sndc | aplay -c 1 -t raw -r 44100 -f float_le
Note that the float_le
is specific for little endian machines, big endian
machines should use float_be
instead.
Similarly, to convert the output into whatever audio format the user desires,
one should use sox
with an invocation such as:
$ ./sndc file.sndc | sox -t raw -r 44100 -c 1 -L -e floating-point -b 32 - out.wav
Some convenient wrappers are located in the wrappers
directory, they get
installed along with sndc
when typing make install
.
To play a sndc
file using the wrapper over aplay
:
$ sndc_play <sndcfile>
To export using the wrapper over sox
:
$ sndc_export <sndcfile> <audiofile>
This is an ongoing project with heaps of improvements yet to do, but the basic idea is more or less already there.