Another sub-control-based prefab, it’s flexible very as an indicator, in that its Hue, Saturation, and Brightness plugs let you adjust any colour dynamically with a small modification to it’s structure.
What’s inside the LED control, and how it works:
An animated Bitmap Image provides the lens, and a Tinted Bitmap Image supplies the colour. When a voltage greater than 5 V arrives at the Signal In plug, this causes the Bitmap image to display the lens image’s second frame. The second image is more transparent than the first, allowing more of the colour from the Tinted Bitmap Image be visible when the LED is in it’s “on” state. For this to work, the Tinted Bitmap Image needs to be behind the Bitmap Image in the z-order by using the “To Back” command on the module’s right-click context menu. The Tinted Bitmap: The Tinted Bitmap Image uses a single-frame bmp image file. The Bitmap: The Bitmap Image uses a two-frame bmp image with a mask. How it works: A Volts to Float and Patch Memory Float Out 3 convert the voltage input to a Float Point value. DC Volts (Fast) is selected for the Volt to Float Responses, and the Update Rate is set to 20 Hz. The value at the Signal In plug drives the lens Bitmap Image’s Animation Position. The Tinted Bitmap Image’s Hue, Saturation, and Brightness inputs require values ranging from 0.0 to 1.0, so we use the Animation Position output to scale them down from SynthEdit’s 0-to-10 volt range.
With a simple modification (below) we can make it easier to adjust the colour of the LED by linking the Hue, Saturation, and Brightness plugs to plugs on the IO Module. Note: These value are all 0 to1.
Introduction: Sub controls provide a more customized user interface than standard controls but require more expertise to use effectively. They provide a lower-level access to the various visual elements on your control panel. There are some basic rules that need to be followed to use them with a minimum of problems.
Controls vs. Sub-Controls- Why have Sub Controls?
Before sub-controls, SynthEdit provided only pre-made controls, like the Slider Control. To understand sub-controls, it’s useful to understand how a control works.
For example the Slider: A slider has several interacting components… Lets have a look at the custom made slider below. The original SE slider control is included as a comparison (this control cannot be opened up-it’s one of the old ones, (so it can’t be modified without C++ coding).
Moving the slider updates the numeric text readout and vice-versa. So there’s a bi-directional connection between the two sub-components. Your computer typically updates its graphics 60 times per second yet the output of the is at audio-rate signal (typically 44,100 or more samples per second). So it follows that there’s a rate-conversion happening inside this module. You can’t open up the original slider to see what’s going on inside, but here’s one I put together to demonstrate what goes on:
The current position of the slider is stored in the patch-memory, and the slider will move automatically to reflect the current patch. We need to find a way of displaying the output value of the control. That’s done with the Float to Text, and the ED Text Entry modules. The Output from the module can take various forms. Here I have included three types of data that I think I’ll find useful: 1) DSP Volts out, 2) DSP Floating Point out, and 3) GUI Floating Point out. So you can already see how we can “personalize” and add functions to our controls in this way..
The focal point is the Patch Memory module. This handles the communication between the graphical (GUI) elements (with blue backgrounds) and the audio-processing (DSP) elements (with grey backgrounds). The Patch Memory module also handles any MIDI Automation of the control and handles switching between any presets (patches).
With the traditional Slider the layout of the elements was fixed. There’s no way, say, to put the numeric readout at the top. But now I have this Sub Control slider I can move the elements around at will. However using the Sub Control I just created then I can modify and move elements around as I like.
The purpose behind Sub-Controls.
The purpose of sub-controls is to split up the control into its constituent parts. As you saw with the slider Sub Control, this is a way of giving far you more flexibility over the appearance of your controls.
The first and focal point is the Patch Memory module. It handles the communication between the graphical elements (on the left with blue backgrounds) and the audio-processing elements (on the right with grey backgrounds). The patch mem module also handles any MIDI Automation of the control and handles switching between presets (patches). The second type of module here is the graphics controls. The Bitmap Image and the Text entry boxes. These accept user input and display the control’s current value. Graphical elements use the Patch-Mem module as a ‘hub’. Input to any object is reflected back to the others, keeping them always in sync. The third type of module here is datatype conversion. For example the Text-to-Float module. It’s purpose is to bridge the Patch-Mem module’s numeric (float) value with the Text-entry module (which otherwise would be used perhaps for entering a file-name).
You can see from the arrow heads in the picture below that the GUI Floating Point pins (blue background) are bi-directional. This ties in with the expected behavior.
Updating the numeric-entry box moves the knob and vice-versa. These signals are not sampled like audio signals but are event-driven. Event driven means that the control only sends data and uses the CPU when being moved, at all other times it does nothing. Compared to an audio (DSP) signal, the knob thus generates data at a much slower rate, and only when actually needed.
The signal leaves the Patch-Memory module via the Value Out plug as an audio connection, but it’s still sending data at the slower rate generated by the PC’s graphics system. This is why we include the next stage the Float To Volts module. The Float-to-Volt smooths out, and up-samples our Floating Point data to a true audio-rate signal suitable for controlling SynthEdit’s various audio modules. In SynthEdit these audio rate signals are called Voltages because SynthEdit is simulating an old-school Voltage controlled Synthesizer. The Float-to-Volts module gives you control over how smooth the conversion should be. Less smoothing uses less CPU, but the resulting audio changes (especially with filters) may sound ‘stepped’ or ‘zippered’. There is another reason this module must be included- without it the data rates will be miss-matched and updates in control position lost resulting in jerky or glitchy changes to the audio modules.
The general structure of a Sub-Control patch is: [Graphical Control]<—>[datatype Converter]<—>[Patch Mem]—>[Audio modules]
Customizing. You can see that the numeric input is optional, just delete it if you don’t need it. Same with the rotating knob image. Also you can now place the elements however you like.
Some of the settings available and what they do: Hint:- Provides for ‘Tooltips’, the popup yellow boxes that appear when you mouse-over the control. Menu Items and Menu Selection:- Provides a context menu (right-click menu). Type the menu items as a comma-separated list. e.g. “Set to Center=1, Randomize”. These will appear on the context menu, along with SynthEdit’s menu entries. The ‘Menu Selection’ pin outputs the user’s selection as an integer. e.g. if the user clicks ‘Set to Center’ the pin goes to 1. After any selection the pin returns quickly to zero. Always number your item list from 1 otherwise the first item will always output 0 (which is no different from ‘no-selection’). Editable:- You can use this with Text Entry boxes to stop uses from changing a label by accident, or to prevent values being entered into a control’s value box. Greyed:- You can use this with a Text Entry box to indicate that control is not currently relevant.
Efficiency. GUI Modules: As you know modules with blue backgrounds are ‘GUI Modules’ (Graphical User Interface Modules). These are designed to process user-input (mouse clicks and text entry etc.). These are not intended to process audio signals. On multicore systems they will usually run on a core separate from the audio processing, this allows the audio modules to take priority when the CPU is under load. Hybrid GUI/DSP modules: Modules with both blue and grey pins (like the Patch Memory Modules) are hybrid modules. Internally they consist of two parts running simultaneously in separate processes. Communication between the two parts is complex and is thus more CPU intensive than between other modules.
Don’t use audio modules to process GUI signals
In general aim to keep your use of hybrid modules to the absolute minimum. For example: Suppose you want to increase a knob’s display to range between 0 and 100, your might think to use the standard Multiplier module. Being an Audio module, this requires an extra conversion via a patch-mem or similar. A much more efficient method is to use a ‘pure‘ GUI solution like the Float-Scaler module. This will: 1) keep your circuit simpler and 2) your CPU usage far lower.
Use caution with GUI connections into Containers
Sub Controls are only active when the control panel window is open. When you close the control panel, the sub-controls immediately become inactive. Not only this but GUI plugs communicate only with modules visible in the same window, so if you are passing controls though another container, you must set that containers properties so with the “Controls on Parent” are visible, otherwise the GUI signals will not pass through the container. This behavior is in support of the new VST3 standards.
Example:- A Knob image is inside a Container, which is connected to a Patch Memory outside the control’s container. Unless the Container is set so that the Panel View is visible the knob cannot not respond to mouse movements and appears ‘frozen’, the Volt Meter and Vector Bar won’t respond to any control movements.
However as soon as we change the relevant settings on the Container – Patch Mem the controls spring into life: (see below)
Note: The structure view will always have this issue, but if the knob’s container has ‘Controls on Parent’ set it will work fine on the Panel view. The reason is:- With ‘Control on Parent’ set, the knob is displayed on it’s parent container’s window, which the same container the PatchMem is in. This is confusing- So if possible, always keep your GUI connections within the same container. If you do need GUI connections into a container, you can often get the structure view working too… For this the container’s ‘Show on Module’ needs to be set. This makes the knob visible in the same window as the Patch Mem which means the data connection works, but there’s still a catch. The right-hand window’s knob still won’t work properly. As it’s effectively a sub-container. There’s no way you can get the Patch Memory module visible in that window.
Summary: Sub controls in a container will work fine on the Panel view provided the container has ‘Show on Parent’ set. They control may not always respond in the structure view but you can often (but not always) fix the problem with the ‘Show on Module’ setting.
GUI modules need to be seen
Sub Controls function only while their Container’s Panel is open. i.e. if you close you synth’s panel, those sub controls become inactive. Therefore never rely on GUI modules to process audio signals. The exception is hybrid modules (Patch Memory) which will continue to provide patch-selection and automation functions via their audio pins.
Avoid splitters Due to a design mistake, SynthEdit 1.0 had the Container’s ‘Control on Parent’ pin on the wrong side. This made it impossible to connect it to a Patch Mem module (needed for save/recall of paged panel settings). The ‘Bool Splitter’ was introduced to fix this problem, but the bool splitter causes problems of it’s own. The bool splitter ‘reflects’ any one input signal back out it’s other inputs, this is a bad design because it is not clear which module is in control of the others. The result is modules ‘fighting’ each other for control. Symptoms include ‘flakey’ inconsistent behavior and patches not saved/recalled correctly. 3rd party module developers have sometimes copied SynthEdit’s example and released modules that rely on the use of splitters. This is not their fault, however if at all possible avoid using splitters.
Prefabs worth studying. SynthEdit’s Insert/Controls menu has several good examples. The Joystick module shows how to make any type of horizontal slider, vertical slider, or two-axis Joystick. Hint: For Sliders – use the resize handles to restrict the area of movement to a narrow strip.
Visual Indicators. The LED2 prefab is a template for any type of indicator or meter. Notable is it’s clever use of a transparent overlay image to dim the light, and the use of the Tinted Image module to provide for any color light.
About the ED Shape Envelope module: How to use it.
This neat little module, with a a few other modules allows you to define your own “ADSR” envelope with as many segments as you like. To use the module it’s as simple as drawing the envelope shape by adding/removing nodes and changing their positions to define your output shape. The envelope output can be; Linear, Curve 1, or Curve 2. This is selected with a drop down list, and sent to the Shape editor as a GUI Integer, and the Shape Envelope as the default DSP List Entry. This is where a little bit of Data conversion is needed… All this adds up to a neat little module that can be a very versatile replacement for the standard ADSR2 module.
Curved or straight line envelopes?
The Shape Envelope module allows us to draw envelopes with straight lines (Linear), and two curves; Curve1, and Curve 2. Curve2 isn’t really very useful in this application, so I have just used Linear and Curve1. We can select the different Interpolation Methods using the usual DSP drop down list, and on the GUI side an Integer. It would be good to be able to select the same ITP methods for both the GUI Shape Editor module, and the DSP Shape Envelope module. We can do this, but we need to do a bit of Data Type conversion. We have two fixed values set; 10 (Linear), and 20 (Curve1). You could include 30 (Mode2), but it’s really not necessary in this application. These are selected via a Switch(Many->1) (Yes they are integer values going to voltage plugs but it will work perfectly well with integer values-although I did add a Volt to Int converter on the output-just in case). This goes from the output of the switch via the Volts to Int converter, into a PatchMemory Int Out module this sends our DSP Integer value to the Shape Editor’s ITP plug. It also splits off and goes to a useful redirection module, the RH Int Redir and from there into the Choice plug of a PatchMemory List 3. The Value Out plug on this module then feeds our choice into the Shape Envelopes ITP plug (No, there’s no mistake in the layout, in this case there is no need for the Item List plug to be connected). This is the simplest way I have found (so far) of connecting the List Entry box to both the Shape Editor and the Shape Envelope’s two different ITP Choice plugs. Using this method we can see accurately what the shape of the Output of the Shape Envelope module will be.
BLOB converter.
This is purely to get the DSP module connected to the GUI module
Envelope duration display (time display).
Aside from the visual Level Bar, and the control knob there’s a time readout too- this is a standard enough layout. A Floating point input taken from the Animation Position plug of the PatchMemory Float3 that the Knob and ED Level Bar are connected to. It’s fed through an ED GUI Multiply float so that we convert the default 0-1 range of the Knob control to the required 0 to 10000 range to give the correct envelope time in mS. The float to text module converts the value to a text readout, with decimal places set to 0.
The complete Shape Envelope structure.
The completed structure (below) does not have a trigger input. The gate input is all it needs. The length of our envelope is determined by the time set using the Duration (mS) plug. So you can equally well connect the Gate plug to either Trigger or Gate-both work equally well here. Don’t forget the duration is in mS so for a duration of 1 Second the controls maximum will need to be 1000, and for 5 Seconds 5000 and so on. Keeping the default range of 0 to 10 on the Patch Memory Float will only give you a brief 10 mS maximum. (it’s a personal choice obviously) but as a start I would suggest a Minimum of 100, and a Maximum of 5000 giving you a range of 100 mS to 5 S. The ED level bar also gives you some visual feedback, plus you can use the level bar to adjust the envelope length too. Overall level controls the maximum output voltage of the Envelope Shape Editor Settings: As I have used the ultra compact version of the Shape Envelope module there are some settings in the Properties panel to be changed: Base Line:- To give an easy to understand envelope shape this should be set to -5. Editable:- Make sure this box is ticked. Lock First/Last Node:- I very strongly suggest that you tick this box. If the first and last nodes are not left at zero, you’ll get some nasty clicks and pops at the start and end of each envelope (due to almost instantaneous rise and fall times of the envelope. Shape Envelope Settings: Sustain Node:- This can be left at -1 if you want a mode “conventional” envelope behaviour. Otherwise it can be changed, setting a node number (Integer) defines where the sustain portion of the envelope begins, in this mode the envelope is held at the sustain level (the level defined by the node selected as the sustain point) the shape envelope then resumes when the key is released on the keyboard. Note: This means that the behaviour of the Envelope duration has been changed as the duration will have had the key down time added to it. Gate:- Leave this property unticked. Clip Shape:- Leave this property unticked. It’s unlikely the curve will exceed the maximum 10V if Curve2 is not used.
Setting a Sustain node.
With a few more modules we can allow for selection of a point where the envelope is put into sustain mode. All that’s needed is a Fixed Values (Int) module, with a Many->1 switch to select our sustain point. The list I have used is; -1 = off (no nodes selected), 2 = node 2, 3 = node 3 and so on. If there are more nodes listed than are in the Shape Envelope, then selecting a number higher than the last node will have no effect.
This is another module that seems to cause some confusion. If you follow a few simple rules it’s fairly simple.
Rules for using the Polyphony Control Module.
Important: Do not connect any Patch Memory Modules to the Polyphony control module for any reason, as it is already a type of Patch Memory- you’ll get some very serious data conflicts! The reasoning behind this is that when you have synthesizer VSTs that support saving and loading patches, you’ll sometimes need to have different settings saved ready to be applied to the Polyphony when the patch is re-loaded (Glide for example) this will be done directly from the Polyphony module rather than having loads of extra Patch Mem modules to add. Important: For backward compatibility (in older versions of SE) the Polyphony control module will not work if your MIDI-CV module has plugs like Mono-mode, Poly Mode, Retrigger, or Mono Note Priority pins connected. MIDI-CV2 should present no problems at all. Note: The Polyphony Control module does not have a properties panel. All parameters are controlled directly from the module’s plugs. Note: There is no point in connecting any GUI fixed values or Patch Memories to the control plugs because it will not work, and as stated previously connecting Patch Memories to the Polyphony Control will cause data conflicts. The only safe “solution” is setting the correct required values in all of your factory presets, including any test or personal presets, and connect a list entry only for you to check that its value remains at the intended one, but do not make it accessible to users (i.e. either remove it when exporting the final plugin or leave it inside a non displayable container).
What the Polyphony Control Module does.
As the name suggests this provides control of Polyphony – how many voices (notes to you and me) the synth can play in one go. The greater your polyphony, the more keys you can hold (and hear) at the same time, the Polyphony is usually deliberately limited to control the amount of CPU your synthesizer can use. A sensible compromise is a level somewhere between 8 and 32 voices.
Plugs: Polyphony:- (Integer/Text) How many notes can sound at one time. This can be anywhere from 1 to 128 voices. Polyphony Reserve:- (Integer/Text) These are some extra voices to be kept in reserve that will usually be unused. Why do this? The point of having these Reserve Voices is to reduce clicking during “voice-stealing”. In the event that all of the regular voices are used up, these temporary extra “reserve” voices allow new some notes to play while SynthEdit quickly fades-out some of voices already in use for recycling. A reserve of 3 to 8 voices will usually be sufficient, depending on how many notes you might trigger at the same instant (how many fingers have you got?). Voice Stealing:- (Integer/Text) This mode setting controls how the voices are recycled, there are three modes: 1) Soft:- Voices are allocated in a ’round robin’ fashion (e.g. 1,2,3...). When you play the same key repeatedly, then the same voice is recycled (e.g. 1,1,1..). Soft-stolen envelopes do not hard-reset to zero but start from current level. This give a feel somewhat like a monophonic synth where repeated notes fade very smoothly into each other. Not suitable for sample-based instruments because it will cause clicks during note-on events. 2) Hard – Voices are always allocated in a ’round robin’ fashion (e.g. 1,2,3…). When you play the same key repeatedly, the previous voice is faded out very quickly. 3) Overlap – Voices are always allocated in a ’round robin’ fashion (e.g. 1,2,3…). When you play the same key repeatedly, the previous voice is faded out slowly. This allows repeated notes to build-up in intensity somewhat like a real piano for example. The disadvantage is that this mode uses more CPU than the others. Not realistic on monophonic instruments like bass, may muddy the sound and cause flanging effects on samples. Mono Mode:– (Boolean) Only one voice is ever used, like a monophonic Synthesizer (like the first Analogue synthesizers) . This works well for traditionally monophonic instruments like Bass synthesizers. Note: This mode is not suitable for sample-based instruments because it will cause clicks during note-on events. However you can use the polyphonic mode with Polyphony set to “1” to restrict your sampler to a single voice. Mono Retrigger:– (Boolean) Controls how a monophonic instrument responds to legato (overlapping) note playing. With the Retrigger mode enabled you will hear envelopes retrigger for a distinct attack on all new notes. In Legato mode, any notes played as legato will now glide smoothly into each other without triggering a new envelope (no new gate or trigger pulses). Mono Note Priority:- (Integer/Text) When in the monophonic mode when two or more notes are held, this controls which of the notes sounds. This has three modes: High, Low , and Last. High plays the highest note, Low plays the Lowest, and Last plays the last note to be held down. Glide:- (Floating Point) The value on this plug controls how fast the pitch changes between the notes played. Glide is often known as portamento. Note: The Glide Control plug has a floating point range of 0 to 10, rather than the expected “default” of 0 to 1 that most Floating Point plugs have. Glide Mode:- (Integer/Text) This has two modes, Legato and Always. It controls what playing style causes notes to glide. “Always” means that there is always a smooth portamento between notes, even if there is a gap between the keys being pressed, whereas “Legato” only uses the portamento effect when notes are played in a legato style. Bender Range:- (Integer/Text) Controls the range of the Pitch Bender wheel. Voice Refresh – (Integer/Text) This has two modes: Enable and Disable . The Voice Refresh periodically ‘wakes’ each voice. The purpose of this is reduce clicks which may occur under the following conditions: You have changed the setting of a filter (or other recursive module) while not playing a voice, then play the voice. The click can happen when the voice ‘wakes up’ and suddenly updates the filter settings (which can cause a click). Note: Under some conditions having the Voice Refresh enabled can consume too much CPU, so this setting allows you to disable it to save on CPU cycles.
OK So all fairly straightforward then…or is it? There are those two Boolean Plugs of the right hand side of the Polyphony Module which makes connection a bit tricky without some re-direction. Don’t attempt to use Patch Memory for this! There are some useful modules online which perform the redirection and GUI/DSP conversion. These are available from here: QTN Modules blog. We can use either the QTNBool2GUIBool, or the QTN Volt2GUIBool, it doesn’t really matter which as most times you can safely connect Bool plugs to a Voltage and vice versa. Likewise the QTNVolts2GUIFloat module makes connecting up a slider to adjust the Glide control so much easier.
Shown below is a typical structure for a synthesizers Polyphony controller. The controller doesn’t need to physically connect to anything in the Synthesizer in order to function, it just sits on it’s own inside the main synthesizer container.