For a monophonic instrument, or a polyphonic instrument with the number of voices set to one, you can use simple tricks to get legato-only portamento to work. Here's one such solution, which temporarily sets the portamento time to its minimum value at the start of non-legato notes:
You start with the Single Trigger Gate module, which creates a gate signal of all keys/voices combined, which means that it doesn't send a new key-on event when playing legato. You set both its minimum and maximum output value to 1, so that every key-on event has a value of 1 whatever the velocity is.
You then use a Separator module to filter out the key-off events, and use the key-on events to trigger a Hold module with a very short time, e.g. 1 millisecond. You then use the output of the Hold module to select between the time setting for the portamento, and a constant time value (indicated in red in the image) that is low enough so that the new pitch is reached within the 1 millisecond that you've set in the Hold module.
The end result is that whenever you play a note after a gap, the portamento time is set to its minimum setting so that the pitch jumps to the new note instantly, and then the portamento time is set back to its original setting.
Depending on how the portamento module or macro is programmed, you may have to adapt the Hold module time and the alternative low time setting for the portamento to get the desired result. If you use a 1-Pole Low-Pass Filter module on the pitch signal as portamento, then a filter pitch of 128 is high enough to jump five octaves without noticeable glide. A higher filter frequency means a shorter portamento time. So that's a number that you might use for the bottom input on the
Selector module (in red, above).
The method described above also works to an extent for polyphonic instruments. You can play monophonic non-legato lines without portamento, and legato lines and chords with portamento. You can also set the Hold module time to something like 100ms, and then you can play non-legato chords without portamento.
Depending on whether you set the Voice Assign in the instrument's properties to "Newest" or "Oldest", you'll get slightly different results.
There are some anomalies, e.g. when you set a long portamento and release time, play a few notes that are still changing pitch during their release phase, and then play another note, the new note will cause all the notes to suddenly jump to their final pitch. This can be fixed with the version below, which combines the Single Trigger Gate module output with each voice's own gate signal:
This still leaves some problems, caused by the Single Trigger Gate, which doesn't function as you'd expect when playing non-legato notes while holding down one or more keys. Of course, as always in Reaktor, we can just build our own, which behaves the way we want it to; combining Selective Note Gate modules, we can make a monophonic gate macro that keeps track of every key on the keyboard, independent of the instrument's polyphony:
The above macro combines twelve Selective Note Gate modules, to keep track of the keys in one octave; combining multiple of these macros gives us a complete all-key gate:
If you replace the Single Trigger Gate module by the above All-Key Gate macro in the version with the combined monophonic and polyphonic Hold modules, with a hold time of around 50 ms, you have a useful polyphonic portamento. As before, setting the instrument's Voice Assign to "oldest" or "newest" will give slightly different results.
When you use the 1-Pole Low-Pass Filter module to create portamento, there is the additional complication that the Pitch signal never quite reaches its target, and all notes are slightly flat or sharp, depending on whether the pitch gradually changed from a lower or a higher note. (In an instrument which requires exact pitches, such as an FM synth with seperate portamento settings per operator, this could be problematic; in other instruments it may be less noticeable.)
This slight pitch offset depends on the filter frequency and the note number. However, if we shift the pitches to the range 128 ~ 255 before the filter and then subtract 128 again after the filter, the offsets are the same for all notes:
48 ±0.0004 (fast)
-48 ±0.1048 (slow)
Below is a portamento macro which compensates this offset, to produce precise pitches. It also incorporates the legato portamento functionality, using the All-Key Gate macro described above.
It has four inputs:
- P (Pitch) in MIDI note numbers: 0 ~ 127 (polyphonic)
- G (Gate) note off: 0, note on: 1 ~ 127 (polyphonic)
- T (Time) portamento time: 0 ~ 127 (monophonic)
- H (Hold) time in ms: 0 ~ 127 (monophonic)
When the portamento time is set to 0, the filter is bypassed, to avoid any hint of portamento. When the Hold time is set to 0, portamento is applied to every note; when Hold time is set to 1, portamento is only applied to legato notes; a higher setting, around 50 or so, allows all notes in a chord to be considered non-legato, even when the keys are not pressed at exactly the same time.
The constant value 60, which is merged with the Pitch input, provides an initial key value; the first notes you play after loading or restarting the instrument will rise or fall from this note number; it can be set to any value from 0 to 127. The constant value 43 sets the time range to approximately 0.01 ~ 10 seconds for a 5-octave glide; increase or decrease this value to have shorter or longer portamento times.
The output of the portamento macro is an audio-rate signal; for the smoothest results, don't convert it to an event-rate signal, but connect it to the F (frequency) input of oscillators (with an Exponential Pitch to Frequency conversion module between them), and connect a constant value of -276.478 (which corresponds to 0 Hz) to the oscillator's P (pitch) input. Note that other pitch modulation (pitch bend wheel, LFO, envelopes, ...) should always be added to the pitch signal after the portamento.