Project Eclipse

Project Eclipse is a Flash-based user interface for dynamic patching and control of audio synthesis modules and effects created in the SuperCollider v.3 audio programming language. Communication between Flash and SuperCollider is accomplished transparently via Ben Chun's flosc, a Java-based Flash-to-OSC bridge. A Perl CGI script handles loading and saving of presets to the server in XML format.

The primary design goal was to create an enviroment with a user interface as intuitive and flexible as that of Native Instruments Reaktor, but with the much deeper sound module design possibilities of SuperCollider. In Project Eclipse, audio processing building blocks (synths, samplers, effects, etc) are dragged onto the workspace and connected with virtual patch cables. Clicking on the top-right button of the sound module pops open a virtual control surface with knobs, sliders, buttons, and other controls to custom tailor the sound module's settings. Control surface elements send parameter information to the synthesis server in realtime, or may be rearranged by putting the panel in "edit" mode. Each sound module can save/recall its patches to the server as XML files, and the entire studio's current state can be saved/recalled as XML files as well.

SuperCollider developer info:

While the system can be used by non-developers to quickly make music with the included modules or modules downloaded from others, SuperCollider developers will find it easy to create modules that can be incorporated into the system. This is a two step process: first, the module is programmed in the SuperCollider environment. Then, an XML file is created that informs Project Eclipse about the parameters of the sound module - its name, inputs/outputs, and control types and value ranges. (For now the creation of this XML file is a manual process, but there may eventually be a SuperCollider class to automate this based on a synth definition.)

When the Project Eclipse .swf file is first loaded, it initially establishes a connection to the SuperCollider synthesis server. Then, a query to the CGI script loads any available sound module XML definition files, and a hierarchical module menu is built. The user can then select any module in the menu, and a patchable module is created on the workspace based on the loaded XML definition file. The module's initial control surface is built based on a default preset XML file for that sound module (the user can specify any customized preset as the module's default).

Once more than one sound module has been loaded into the workspace, the modules can be connected with patch cables. Each loaded module represents a SuperCollider "node", and each patch cable is assigned a SuperCollider audio or control bus. Repatching cables sends OSC messages to synthesis nodes in the SuperCollider server telling them to re-route their inputs or outputs to other modules or audio hardware. Adding or deleting modules in the workspace simultaneously sends OSC messages to load or remove nodes in the server.


Project Eclipse is still in a developmental stage. While most of the primary functionality is in place, much work remains to be done. While a basic sound-producing chain may now be created using the Eclipse GUI, certain operations (reordering modules, etc) are buggy. Other major tasks include more GUI elements such as a filebrowser for samplers, an ADSR envelope element with draggable breakpoints, and more knob/slider/button styles and sizes. Basic sequencing or triggering modules are planned as well to reduce reliance on external MIDI control. An eventual design goal is to have the audio from the synthesis server being streamed in MP3 format, so that any computer with a fast connection could have access to the virtual studio.


Project Eclipse will be released under some sort of as yet undetermined open source (free) license.

XML preset examples

The sound module definition XML file and the saved-studio XML file for the 6-channel mixer in the screenshot are below:

<MODULE DISP="6-Channel Mixer" CATEGORY="Mixers" SUBCATEGORY="6-Channel">
		<in1 TYPE="AUDIO" />
		<in2 TYPE="AUDIO" />
		<in3 TYPE="AUDIO" />
		<in4 TYPE="AUDIO" />
		<in5 TYPE="AUDIO" />
		<in6 TYPE="AUDIO" />
		<outL TYPE="AUDIO" />
		<outR TYPE="AUDIO" />
		<pan01 TYPE="KNOB" MIN="-1" MAX="1" DISP="pan1" />
		<pan02 TYPE="KNOB" MIN="-1" MAX="1" DISP="pan2" />
		<pan03 TYPE="KNOB" MIN="-1" MAX="1" DISP="pan3" />
		<pan04 TYPE="KNOB" MIN="-1" MAX="1" DISP="pan4" />
		<pan05 TYPE="KNOB" MIN="-1" MAX="1" DISP="pan5" />
		<pan06 TYPE="KNOB" MIN="-1" MAX="1" DISP="pan6" />
		<vol01 TYPE="SLIDER" MIN="0" MAX="1" DISP="vol1" />
		<vol02 TYPE="SLIDER" MIN="0" MAX="1" DISP="vol2" />
		<vol03 TYPE="SLIDER" MIN="0" MAX="1" DISP="vol3" />
		<vol04 TYPE="SLIDER" MIN="0" MAX="1" DISP="vol4" />
		<vol05 TYPE="SLIDER" MIN="0" MAX="1" DISP="vol5" />
		<vol06 TYPE="SLIDER" MIN="0" MAX="1" DISP="vol6" />
		<mute01 TYPE="BUTTON" MIN="0" MAX="1" BEHAVIOR="toggle" DISP="mute1" />
		<mute02 TYPE="BUTTON" MIN="0" MAX="1" BEHAVIOR="toggle" DISP="mute2" />
		<mute03 TYPE="BUTTON" MIN="0" MAX="1" BEHAVIOR="toggle" DISP="mute3" />
		<mute04 TYPE="BUTTON" MIN="0" MAX="1" BEHAVIOR="toggle" DISP="mute4" />
		<mute05 TYPE="BUTTON" MIN="0" MAX="1" BEHAVIOR="toggle" DISP="mute5" />
		<mute06 TYPE="BUTTON" MIN="0" MAX="1" BEHAVIOR="toggle" DISP="mute6" />
		<eq DISP="EQ">
				<eqOn TYPE="BUTTON" MIN="0" MAX="1" BEHAVIOR="toggle" DISP="on/off" />
				<eqFreq TYPE="KNOB" MIN="0" MAX="1" DISP="freq" />
				<eqWidth TYPE="KNOB" MIN="0" MAX="1" DISP="width" />
				<eqRes TYPE="KNOB" MIN="0" MAX="1" DISP="res" />
		<compression DISP="Compression">
				<compOn TYPE="BUTTON" MIN="0" MAX="1" BEHAVIOR="toggle" DISP="on/off" />
				<compAttack TYPE="KNOB" MIN="0" MAX="50" DISP="attack" />
				<compRelease TYPE="KNOB" MIN="0" MAX="50" DISP="release" />
				<compRatio TYPE="KNOB" MIN="0" MAX="24" DISP="ratio" />

The contents of the saved studio state XML file for the screenshot:

<studio modulesvisible="true" panelsvisible="true">
		<module1007 disp="audio in delay" h="86.35" w="140.4" visible="true" y="344" x="524" instancename="module1007">
				<cutoff value="0.285" y="50" x="30" />
				<decaytime value="0.76" y="50" x="70" />
				<delaytime value="0.32025" y="50" x="110" />
			<subgroups />
		<module1012 disp="Ring Modulator" h="79.35" w="122.2" visible="false" y="201" x="151" instancename="module1012">
				<depth value="0.055" y="50" x="20" />
				<freq value="0.17" y="50" x="70" />
			<subgroups />
		<module1006 disp="Analog Bass" h="92.35" w="156.4" visible="false" y="33" x="606" instancename="module1006">
				<lfo value="0.975" y="50" x="20" />
				<filtercutoff value="100" y="50" x="70" />
				<volume value="0.57" y="50" x="120" />
			<subgroups />
		<module1009 disp="bass delay" h="84.35" w="130.4" visible="true" y="382" x="598.95" instancename="module1009">
				<cutoff value="1" y="50" x="20" />
				<decaytime value="0.605" y="50" x="60" />
				<delaytime value="1" y="50" x="100" />
			<subgroups />
		<module1010 disp="Audio Output" h="149" w="213.95" visible="false" y="0" x="0" instancename="module1010">
				<level value="" y="0" x="0" />
			<subgroups />
		<module1011 disp="6-Channel Mixer" h="267" w="453.95" visible="true" y="154" x="339" instancename="module1011">
				<filtenv value="" y="" x="" />
				<volenv value="" y="" x="" />
				<mute06 value="0" y="240" x="230" />
				<mute05 value="0" y="240" x="190" />
				<mute04 value="0" y="240" x="150" />
				<mute03 value="0" y="240" x="110" />
				<mute02 value="0" y="240" x="70" />
				<mute01 value="0" y="240" x="30" />
				<vol06 value="0.7025" y="40" x="230" />
				<vol05 value="1" y="40" x="190" />
				<vol04 value="0.64" y="40" x="150" />
				<vol03 value="0.24" y="40" x="110" />
				<vol02 value="0.4" y="40" x="70" />
				<vol01 value="0.17" y="40" x="30" />
				<pan06 value="-0.29" y="190" x="230" />
				<pan05 value="-0.04" y="190" x="190" />
				<pan04 value="0.18" y="190" x="150" />
				<pan03 value="0.11" y="190" x="110" />
				<pan02 value="-0.26" y="190" x="70" />
				<pan01 value="0.16" y="190" x="30" />
				<compression h="70" w="170" y="121" x="271">
						<compratio value="5.874" y="40" x="100" />
						<comprelease value="9.4875" y="40" x="60" />
						<compattack value="15.7375" y="40" x="20" />
						<compon value="1" y="40" x="140" />
				<eq h="70" w="170" y="31" x="271">
						<eqres value="0.1" y="40" x="100" />
						<eqwidth value="0.27" y="40" x="60" />
						<eqfreq value="0.315" y="40" x="20" />
						<eqon value="0" y="40" x="140" />
		<module1008 disp="Audio Input" h="149" w="213.95" visible="false" y="0" x="0" instancename="module1008">
				<level value="" y="0" x="0" />
			<subgroups />
		<module1010 node="1010" module="audioOut" category="IO" visible="true" y="507" x="655" instancename="module1010" />
		<module1009 node="1009" module="delayLowpass" category="Effects" visible="true" y="421" x="267" instancename="module1009" />
		<module1011 node="1011" module="mixer6channel" category="Mixers" visible="true" y="500" x="512" instancename="module1011" />
		<module1012 node="1012" module="ringMod" category="Effects" visible="true" y="524" x="357" instancename="module1012" />
		<module1006 node="1006" module="analogBass" category="Synths" visible="true" y="396" x="75" instancename="module1006" />
		<module1007 node="1007" module="delayLowpass" category="Effects" visible="true" y="550" x="202" instancename="module1007" />
		<module1008 node="1008" module="audioIn" category="IO" visible="true" y="499" x="39" instancename="module1008" />
		<cable118 bus="24" outport="in2" inport="outR" outobj="module1011" inobj="module1009" />
		<cable117 bus="23" outport="in1" inport="outL" outobj="module1011" inobj="module1009" />
		<cable113 bus="34" outport="in3" inport="outL" outobj="module1011" inobj="module1012" />
		<cable112 bus="33" outport="in4" inport="outR" outobj="module1011" inobj="module1012" />
		<cable111 bus="28" outport="inL" inport="outL" outobj="module1012" inobj="module1007" />
		<cable110 bus="27" outport="inR" inport="outR" outobj="module1012" inobj="module1007" />
		<cable109 bus="30" outport="inL" inport="inL" outobj="module1007" inobj="module1008" />
		<cable108 bus="29" outport="inR" inport="inR" outobj="module1007" inobj="module1008" />
		<cable105 bus="26" outport="inL" inport="outL" outobj="module1010" inobj="module1011" />
		<cable104 bus="25" outport="inR" inport="outR" outobj="module1010" inobj="module1011" />
		<cable101 bus="22" outport="inL" inport="outL" outobj="module1009" inobj="module1006" />
		<cable100 bus="21" outport="inR" inport="outR" outobj="module1009" inobj="module1006" />

Copyright ©2002 James Reynolds (