AlsaModularSynth, POV-Ray image by Jörg Anders.
Modular synthesis is one of the most flexible and fascinating ways of making electronic music. The principles of voltage-controlled modular synthesis have been stated in the famous paper Voltage-Controlled Electronic Music Modules by Robert A. Moog , presented in 1964 at the Annual Convention of the Audio Engineering Society .
AlsaModularSynth is a digital implementation of a classical analog modular synthesizer system. It uses virtual control voltages to control the parameters of the modules. The control voltages which control the frequency e.g. of the VCO (Voltage Controlled Oscillator) and VCF (Voltage Controlled Filter) modules follow the convention of 1V / Octave. Read the first two pages of the Moog paper to understand why this logarithmic scale is so important.
A real analog synthesizer has a lot of knobs and switches which give immediate access to all important parameters of the generated sound. AlsaModularSynth can be controlled by MIDI controller boxes, like e.g. the Doepfer Pocket Dial . MIDI events can be assigned to module parameters in a very flexible way by using the Control Center dialog of AlsaModularSynth.
For the examples presented in this section it is assumed that you have installed the Kaconnect patchbay for the ALSA MIDI sequencer. If you don't have a MIDI masterkeyboard with pitch- and modulationwheels, you can use the virtual keyboard vkeybd to play AlsaModularSynth. To start AlsaModularSynth just type "ams". If it complains about periodsize or periods settings, you might have to change the number of periods by using the --frag option. Some soundcards require 3 periods. You might also have to change the periodsize using the --periodsize option. To get an overview about other command line options just type "ams --help".
AlsaModularSynth can be started in JACK mode by specifying the -j or --jack parameter. This works only, if the JACK demon is running. It is recommended that you use the QJackConnect patchbay to connect JACK ports. In JACK mode, any PCM I/O module is automatically converted into its JACK counterpart (and vice versa). So you can load any patch no matter whether it has been saved in JACK mode or uses PCM Out modules.
As a first example you can load the patch "example_ams_demo.ams" which generates an impressive random music. If you like to have some graphics as well, load "example_ams_demo_scope_spectrum.ams". The scope and spectrum viewers are opened by right-clicking on the respective modules located in the upper left corner of the patch. You can still have more fun by loading "example_ams_demo_scope_spectrum_drums.ams". To hear the percussion you have to connect the first readable MIDI port of AlsaModularSynth with a GM compatible sound source by using e.g. the Kaconnect MIDI patchbay. The patch "example_wind.ams" gives an idea about the wide range of sounds that can be produced with a modular synthesizer system.
AlsaModularSynth can also be used as a realtime multieffect processor. If you are only interested in this feature you can skip the following and jump to the section on how to use LADSPA plugins with AlsaModularSynth.
To play with your masterkeyboard or vkeybd on AlsaModularSynth, you have to connect the external MIDI port of your soundcard or vkeybd with the writeable MIDI port of AlsaModularSynth. It is recommended that you first try the basic patches "example_basic_*" and read the comments of the patches. AlsaModularSynth is monophonic per default since the classical analog modular synthesizer have been monophonic. You can change the polyphony by supplying the --poly parameter when you start the program.
Let's build some basic patches with AlsaModularSynth. First create a PCM Out (or JACK Out if you are using JACK mode) module, a Scope View module and a VCO module. You find all these modules in the menu "Module"-->"New". Then connect one of the five output ports (e.g. "Rectangle") on the right side of the VCO module with the input ports "In 0" of the Scope View and PCM Out modules. Ports are connected by left-clicking on them. If you right-click on an input port, you can disconnect it. To see the scope, you have to open the configuration dialog of the Scope View module by right-clicking on the module. The waveform will be moving until you set the refresh mode to "Triggered". In this mode, the scope is triggered when the signal of "In 0" crosses the trigger level. If you want to see the scope while you change its parameters, it is recommended that you open the Control Center dialog of AlsaModularSynth from which you can access any parameter of any module. Probably you will find the constant waveform sound annoying after a while. In this case just reduce the gain of the PCM Out module.
Now let's have a look at the ports and parameters of the VCO (Voltage Controlled Oscillator) module.
|Freq||Freqency control voltage (1V / Octave)|
|Exp. FM||This is added to the frequency CV|
|Lin. FM||For linear frequency modulation|
|PW||For pulse width modulation (only for rectangle waveform)|
|Tune||Here you can e.g. sligthly detune VCOs to get a chorus effect|
|Harmonic||The frequency is multiplied by this number|
|Subharmonic||The frequency is divided by this number|
|PW||Pulse width, only effective for the rectangle waveform|
|PW Gain||Gain of the PW input port|
|Phi0||Phase constant of the VCO. Here you can modify the relative phase of two VCOs which can give interesting stereo effects.|
|Exp./Lin. FM Gain||Gain of the Exp./Lin. FM input ports|
Now you might want to play music with AlsaModularSynth. For this you need a MCV module which converts the MIDI note events into (virtual) control voltages.
|Gate||Gate = 1 while note is pressed|
|Freq||Freqency control voltage (1V / Octave)|
|Velocity||The velocity value of the NOTEON event is mapped into the interval 0..1|
|MIDI channel||If set to OMNI, MCV will receive MIDI events on all channels.|
|Note Offset||Determines which note corresponds to the control voltage 0V. Since negative voltages are not allowed, notes below this value can not be played.|
|Pitch||To this you can bind the pitchbend MIDI event|
If you connect the "Freq" ports of the MCV and VCO, the pitch of the VCO will follow the notes which you play on your MIDI masterkeyboard or vkeybd. Usually we don't want to hear sound if we don't press a key. As you might guess, we therefore have to employ the gate signal of the MCV. But where to connect it ? To answer this question we need two additional modules, a VCA (Voltage Controlled Amplifier) and an ENV (Envelope) module. There are two types of VCA: Exp. VCA and Lin. VCA. The first one has a linear gain input to output gain relationship whereas the latter has an exponential gain curve. Both VCAs are useful and the question of which one is more appropriate is answered by the desired envelope effect.
|Gain 0/1||Gain control voltages|
|In 0/1||Signal input|
|Gain||This is an offset for the amplification of the VCA. It is added to the input of the "Gain 0" port.|
|Gain 1||The input of the "Gain 1" port is multiplied by this number and added to the sum of "Gain" and the "Gain 0" input.|
|In 0/1||Constant volume level for signal input 0/1|
|Output Level||Constant output volume|
The VCA is inserted between the VCO and the PCM Out modules. As a first experiment you can connect the "Gate" output of the MCV with the "Gain 0" input of the VCA. This works, but the abrupt jumps of the VCA gain do not sound very well. The gain curve of the VCA can be shaped with an ENV module. Envelope modules are sometimes also called "ADSR" (Attack Decay Sustain Release).
|Gate||On the rising edge of the gate signal, the envelope will start. Once the attack and decay times are elapsed, the output of the envelope will be equal to the sustain value as long as the gate signal is larger than 0.5.|
|Retrigger||This will retrigger the envelope while gate is > 0.5|
|Delay||Delay time (attack cycle)|
|Hold||Hold time (attack cycle)|
|Time Scale||Global time scale|
The ENV module is inserted between the MCV and the VCA modules. Now you should have a patch like "example_basic.ams" which is the most basic patch. If you connect the "Trigger" output of the MCV with the "Retrigger" input of the ENV, you get "Multitriggering", i.e. the envelope is restarted on each NOTEON. To modify the sound, three different techniques are employed: subtractive synthesis, FM synthesis and additive synthesis. These synthesis techniques can be combined of course. Historically, additive synthesis is the oldest method to synthesize sound. It has been used in pipe organs centuries before the invention of electronic oscillators. Subtractice synthesis generates the typical analog synthesizer sound which most commonly uses a low pass filter to modify the broad sound spectrum of a saw or square wave. FM synthesis is the most difficult technique since the impact of the parameters involved can not be associated to the desired characteristics of the sound in an easy way.
The main purpose of the Control Center is to provide an overview over the available MIDI controllers and bind them to module parameters. In addition to that, ranges and logarithmic scale can be specified for continuous parameters.
Any module parameter can be either accessed in the configuration dialog of the module itself or in the Control Center dialog. The module parameters are selected in the right listview. If the option "Follow Configuration Dialog" is activated, the last parameter which has been modified in a configuration dialog of a module is automatically highlighted.
If you connect a MIDI controller box with the writeable MIDI port of AlsaModularSynth, any controller event sent by this device will show up in the left listview of the Control Center. A MIDI binding is established by selecting a MIDI controller in the left listview and a parameter in the right listview and clicking "Bind". The parameter and module will then show up in the columns "MIDI Controller / Parameter" and "Module" of the left listview. You clear a binding by selecting such an entry in the left listview and click "Clear Binding". "Clear All" will clear the complete MIDI controller list and all bindings. If the option "Follow MIDI" is active, the last MIDI controller that has sent data will automatically be highlighted. The first of its MIDI bindings (if there is one) will be selected in the right listview as well. If you select a parameter in the right listview and click on "Toggle MIDI Sign", the MIDI sign for this parameter is reversed. The slider will then move in the opposite direction of the controller.
To avoid parameter jumps, MIDI controller events will be ignored until the MIDI value coincides with the current parameter value. The MIDI controller is then "snapping in" and moves the parameter. This will also be the case if parameter ranges are changed with the "Set Min", "Set Max" and "Clear Min/Max" buttons.
As long as the option "Enable note events" is active, note events which are sent to AlsaModularSynth will be listed in the left listview. There is a different event for NOTEON and NOTEOFF. Both events can be bound to parameters as well. NOTEON will set the parameter to the velocity value of the note. NOTEOFF will set the parameter to 0. Usually you have to bind both note events to the same parameter. Don't forget to deactivate "Enable note events" when you start playing music.
A new and very useful feature of AlsaModularSynth 1.5.12 is the Parameter View dialog. You open this dialog with "View"-->"Parameter View". This dialog makes it much more easy to use AlsaModularSynth in live performances. Any parameter from any module can be added to this dialog. This is done from the Control Center where you add the parameter currently highlighted in the right ListView by just pressing "Add to Parameter View". Parameters are grouped in frames, such as "Oscillators", "Envelopes", "Filter".
You can define presets for a given parameter configuration. Note that currently the presets can only be defined for a fixed configuration of the Parameter View. If you later add parameters to this configuration, the presets will be lost. The presets can be accessed via MIDI program change messages. Parameter View configuration and presets are stored in the patch file.
When you start AlsaModularSynth, it automatically scans the directories
specified in the LADPSA_PATH environment variable for
LADSPA shared object
files. If LADPSA_PATH is not set, the directories
/usr/local/lib/ladspa are scanned. The plugins found on your
system are listed in the Ladspa Browser which you can open with
"Module"-->"Show Ladspa Browser". Each shared object file has a root
entry. The plugins implemented in the shared object are listed below this
root item. There does not yet exist a possibility to build classes of
plugins, therefore sorting the plugins by their shared object file appears
to be the only solution to structure the list. You can however easily
search for plugins by typing their name (or part of it) and click
"Search". This search is case insensitive.
With AlsaModularSynth you can create LADSPA plugins in two different modes. If you click on "Create Plugin" only one instance of the plugin is generated. If you create the plugin with "Create Poly Plugin", a plugin instance is created for each of the polyphonic "sound pipelines" of AlsaModularSynth. The difference is only there, if you have specified a polyphony > 1 by supplying the --poly parameter when starting the program. It does not always make sense to use LADSPA plugins in polyphonic mode, even if you started AlsaModularSynth with polyphony > 1. The polyphonic mode is useful for effects that should be applied to individual waveforms. However many effects are usually applied to the sum of the polyphonic signal. You would e.g. never want to have a polyphonic reverb effect.
To control the dynamics of parameters which do not provide an audio rate input port, you can use a MIDI Out module and bind its controller events to the desired parameters of the LADSPA module. This implies that you have connected the readable MIDI ports of AlsaModularSynth with its writeable MIDI port by e.g. using the Kaconnect MIDI patchbay.
Subtractice synthesis is the technique most commonly employed with an analog modular synthesizer. The rich sound spectrum of a saw or square wave is filtered by one or several voltage controlled fiters (VCF). The filter subtracts certain parts of the sound spectrum and therefore modifies the sound. The most important parameters are the cutoff frequency and resonance of the filter.
You can visualize the effect of the filter with the Scope and Spectrum Viewer modules. Just create these modules and a VCO, VCF and PCM Out. Then connect the saw output of the VCO to the first input of the Scope and Spectrum Viewers. To hear and see the filter output, connect it to the PCM Out and the second input of the Scope and Spectrum Viewers.
Usually a VCF is used in "VCF tracking" mode. In this mode, the pitch control voltage of the MCV is applied also to the VCF and therefore the cutoff frequency moves in parallel to the VCO pitch. An often used effect is to apply also the output of an envelope module to the VCF. You can try this by connecting either the ENV "Out" or "Inverse Out" ports to the "Exp. FM" or "Lin. FM" input ports of the VCF.
Of the synthesis techniques described here, FM (Frequency Modulation) synthesis is the newest one. It has been patented by Yamaha until 1994 and has built the basis for the sound generation in the famous DX-7 synthesizer and early digital pianos like PF2000. Many soundcards have used FM synthesis (e.g. OPL2 and OPL3 chips) for playback of MIDI data before wavetable synthesis of sampled sounds became feasible for the consumer market. FM synthesis has the advantage of creating a wide range of sounds with relatively simple hardware. It has the disadvantage that there is no simple and direct way of associating the parameters involved to the desired sound spectrum. Mathematically it is possible, but you have to write a relatively complex software for it. So all you can do is try it out and experiment with the parameters.
To start experimenting with frequency modulation, you can first attach the "Sine" output port of a LFO module to both FM input ports of a VCO. If the parameter "Exp. FM Gain" of the VCO is not zero, this will introduce a vibrato effect. For exponential FM, the frequency amplitude of the vibrato does not depend on the absolute pitch of the VCO. This is very different for linear FM. A value for the "Lin. FM Gain" which causes a tiny vibrato at high frequencies of the VCO will result in a tremendous vibrato at lower VCO frequencies. Just try it out !
Now you would probably expect that for FM synthesis one commonly uses the "Exp. FM" input port of a VCO, but in fact the opposite is true. A basic FM synthsis patch consists of two VCOs where the output of one VCO is wired to the "Lin. FM" input port of the other (see e.g. example_fm.ams). The interesting parameters are then the amount of modulation (parameter "Lin. FM Gain" of the carrier VCO) and the relative frequencies of the modulator and carrier VCOs. The parameters "Harmonic" and "Subharmonic" are very useful for frequency adjustment, because they provide rational frequency ratios.
In 1822, by the time when Beethoven composed his late piano sonatas, the french mathematician J.B. Fourier showed that any period function can be decomposed into a weighted sum of sine and cosine functions with the frequencies of the sine and cosine terms being an integer multiple of the fundamental frequency of the function to be approximated. If we have a periodic function f with period time T = 1/frequency, i.e. f(t) = f(t+T), then we can decompose this into a sum of terms a_n * cos(n * w * t +phi_n) and b_n * sin(n * w * t +psi_n) where the integer n starts at 0 (or 1 for the sine terms) and w = 2 * PI * frequency.
Additive synthesis has already been used in pipe organs centuries before the discovery of Fourier. The cmt set of LADSPA plugins contains a marvelous pipe organ plugin by David A. Bartold. Since this plugin has a linear frequency scale and does not use the frequency convention 1V / Octave it can not be used with the newer versions of AlsaModularSynth. It can be used until version 1.3.3 (this version however still needs to be fixed for gcc 3.x).
In principle you could just create several VCO plugins and a Mixer module to experiment with additive synthesis. The module VC Organ is more convenient than that because it offers up to 8 oscillators in one single module. Per default, the parameter "Harmonic" increases with the number of the oscillator. This way you can weight the harmonics in the mixer tab of the configuration dialog. If you like, you can also use other harmonics in your sound or even create inharmonic sounds by detuning the oscillators with the "Tune" parameter.
The module "Dynamic Waves" is probably the most advanced one in AlsaModularSynth. It is similar to the VC Organ, but lets you control the envelope of each oscillator. Have a look at "example_dynamicwaves_8.ams". Since this module has built-in envelopes, it does not require an ENV / VCA pair. If you connect the "Trigger" output of the MCV with the "Retrigger" input of the Dynamic Waves module , you get "Multitriggering", i.e. the envelopes are restarted on each NOTEON.
The module WAV Out writes its input to a 16 Bit WAV file. It uses the same rate as specified with the --rate parameter or 44.1 kHz per default. To ensure correct timing, you can not use a WAV Out module as only output module. There has to be at least one PCM Out or JACK Out module in the setup. The same is true for the MIDI Out module.
Let's have a look at the configuration dialog of the WAV Out module. "New File" opens a file browser where you can select a file name for the WAV file to be written. If you provide a valid file name, the file will be created (or truncated, if it already exists) and opened. The file shown in the "File" lineedit is truncated (or created) when you click on "Overwrite Current File". The selection of a valid file is indicated by the "Record" and "Stop" buttons changing from disabled to enabled state. The gain settings are similar to the PCM Out and JACK Out modules. Note that all buttons of the configurations dialog can be bound to MIDI events. If you bind e.g. "Record" and "Stop" to the NOTEON event of some unused high or low keys, you get a MIDI controlled harddiskrecording device.
The MIDI Out module converts the signal of its "In 0/1" ports into either MIDI controller events or note events. If the trigger port is not connected, a MIDI event is emitted whenever the input signal changes so that a new MIDI value is attained. If there is a trigger signal, MIDI events will be generated on the rising edge of this signal. The MIDI events are sent to the readable MIDI ports of AlsaModularSynth. In 0 is sent to the first MIDI port, In 1 to the second MIDI port. If the parameter "MIDI Event Type" is set to "Note / Velocity", there is only one note event at a time and this is sent to the first MIDI port.
Of course you can connect the readable MIDI ports of AlsaModularSynth with its writeable MIDI port using e.g. the Kaconnect MIDI patchbay. This way you can use the MIDI events generated by the MIDI Out module to control any parameter of any module. Have a look at "example_midiout_controller.ams" and open the configuration dialog of the ENV module to see how this works (don't forget to establish the MIDI connection with Kaconnect). This feature is very useful because it gives access to parameters that can not be directly controlled via audio rate signal ports.
Before the input signal of the MIDI Out module is converted, it is multiplied with the "Gain 0/1" parameter. After this, the "Offset 0/1" parameter is added. These two parameters therefore determine offset and amplitude of the generated MIDI events. The parameter "Controller 0/1" specifies the controller number for MIDI controller events. Each MIDI Out module can send on a different MIDI channel. Try out the other "example_midiout" patches and have a lot of fun !
As you would expect from its name, the Quantizer module quantises the input signal. It has only the parameter "Quantization" which can be set to different scales and chords. If the trigger input is unconnected, the "Trigger Out" emits a short trigger signal whenever the input signal changes so that a new quantization level is attained. If the "Trigger" input port is connected, quantization only takes place when a trigger signal is received. This acts like a quantized Sample & Hold module. The trigger input is emitted at the "Trigger Output" port as well.
The signal sent to the "Transpose" input port is quantized to semitones and added to the quantized signal of the "In" port. This is useful when you have several Quantizer modules playing different scales or chords.
The Quantizer module is especially useful for creating networks that play random music, like e.g. in "example_ams_demo.ams". The quantization to the pentatonic scale is best suited for generating random melodies. Try out what happens if you change the quantization of the Quantizer ID 7 in the patch "example_ams_demo.ams" from "Pentatonic" to "1/6" !
The Noise / Random module offers white and pink noise with amplitude 2.0 (from -1.0 to 1.0). The amplitude of the Random output port can be adjusted with the "Random Level" parameter. The "Random Rate" parameter determines the speed of the random number generation. Note that smaller numbers mean higher speed. The random output acts like a White Noise / LFO Sample & Hold combination, where the LFO triggers the Sample & Hold which gets its data input from the white noise source.
To understand the effect of aliasing in digital synthesis it is useful to first have a look on how a digital signal is obtained from an analog one. Mathematically, the sampled signal d(n) is the product of the continuos analog signal a(t) and the sample function s(t) which is a comb function with spikes spaced at the sample interval (e.g. 1/44100 s). The Fourier transform S(w) of the sample function is a comb function with spikes spaced at the sampling frequency. The convolution theorem states for periodic functions that the Fourier transform of their product in the time domain is equal to the convolution of their Fourier transforms in the frequency domain. This means that the spectrum of the sampled signal is the convolution of the analog spectrum A(w) and the comb function S(w). If A(w) = 0 for w_max=2*pi*f_max=pi*f_sample (the Nyquist frequency), the periodic spectra will not overlap. Otherwise the frequencies beyond f_sample/2 will be wrapped around into the lower frequency area. This effect is called aliasing. To avoid aliasing when sampling an analog signal it is therefore necessary to apply a lowpass filter to the signal that eliminates all frequencies higher than half the sample frequency.
Now what happens if there is no analog signal that could be lowpass filtered ? In digital synthesis the signal is generated on a sample grid. First one could think that there should not be any problem because the digital signal can be directly modelled. Yet this is not true, since the typical waveforms used in analog synths deliberately have a broad spectrum with considerable high frequency content. The broad spectrum is important for subtractive synthesis because you can only subtract what is present in the signal. If you use rectangular and sawtooth waveforms at high frequencies, you can clearly observe in the spectrum viewer module, that the higher harmonics are aliased into lower frequencies. There are methods for band limitation of computer generated waveforms. They have not been applied in the oscillators of AlsaModularSynth for reaons of efficiency and sound quality. The simple waveforms with fixed rise time sound quite powerful and analog at low and medium frequencies. At high frequencies it is recommended to use triangle and sine waves.
AlsaModularSynth offers two command line parameters that affect aliasing: --rate is the sample rate. If you use the plug layer of ALSA (e.g. plughw:0), you can specify rates like 96000 or even 192000 even if your hardware does not support them. This reduces aliasing. --edge specifies the rise time of the VCO waveforms "Saw" and "Rectangle". The scope and spectrum viewer modules will be helpful when experimenting with these parameters.