Sig++ is a set of C++ classes intended for use in creating sound synthesis/filtering programs -- primarily using the elegant and sophisticated environment of a Unix shell.
Sig is somewhat similar to cmix, but is designed for use in a real program by someone who has already taken courses in C/C++ -- after the program is written and compiled using sig it should be general-user friendly (see example programs). Eventually I may write an interpreter script to combine signal generators and control them, or maybe not. Sig is also somewhat similar to Perry Cook's Synthesis Toolkit (STK). Another similar project is called spkit from the University of Helsinki Music Research Laboratory.
Computational efficiency is important, but perhaps not as much as readable code and generality. The end goal is to generate nice, simple yet powerful computer-music composition tools that can be used on any type of (Unix) computer as well as support functions in larger programs such as this picture-to-sound converter. See clm if you can't wait around for something more encompassing.
The paradigm for the sig++ signal-processing implementation is to imagine a flowgraph consisting of signal manipulators which are connected to each other to do something interesting. Sig is not graphical, unless someone else writes a graphical interface to do code generation, such as in SynthBuilder.
An example flowgraph could be the following:
The implementation in code of the preceding picture is rendered in the mix.cpp example program as:
leftScale1.connect(insound1); leftScale2.connect(insound2); leftDelay.connect(leftScale2); addLeft.connect(leftScale1); addLeft.connect(leftDelay); outsound.connect(addLeft); if (header.getChannels() == 2) { rightDelay.setDelay(offsetSamples); rightScale1.connect(insound1, 0, 1); rightScale2.connect(insound2, 0, 1); rightDelay.connect(rightScale2); addRight.connect(rightDelay); addRight.connect(rightScale1); outsound.connect(addRight); }
The round objects in the picture above are Signal Generators: objects which accept no input signal, but generate output signals. The rectangular objects in the picture above are Signal Filters: objects which accept both input and output signals. Signal Filters could be replace by Signal Generators by just not giving any inputs to a Signal Filter, but for pedagogical purposes, I split the Signal objects into those two general categories.
All Signal objects can have an arbitrary number of inputs (except Signal Generators, of course) and also an arbitrary number of inputs. In the picture above, the little numbers near the connections refer to the input/output channel that an object is receiving/sending a signal on. Inputs can be connected to outputs of other signals, or they can be set to fixed values. One major advantage of this setup is that input parameters can be either fixed at a constant value, or can be varied in time. See for example the resonator.cpp example program which uses the Resonator class and which can create neat time-varying filtering effects on soundfiles/whitenoise (resonator sound [ .wav]).
Signals traveling between signal filters are in floating point (doubles), and must be normalized between +/- 1.0 for saving to output soundfiles (for now).
Sig is designed to be generalized C++ code as much as possible so that it will port easily to any computer with a C++ compiler with slight modifications only for hardware IO (today, we are in the Dark Ages of sound IO). Currently, sig is working and being tested in these operating systems (see downloads):
The classes for sig++ are grouped into sublibraries which organize classes with similar functions. Also, there are two sublibraries called improv and museinfo which are self-contained subsets of the sig library. The classes for sig++ are described here.
Example programs which use the library classes above are organized by one of the three complete libraries:
Craig Stuart Sapp, craig@ccrma.stanford.edu