zachwieja / 2LiftStudios

2LiftStudios VCVRack Modules
GNU General Public License v3.0
2 stars 0 forks source link
vcvrack

2LiftStudios

2LiftStudios VCVRack Modules

About

First of all I want to say thank you to VCVRack and the VCV community. I love the platform and how everyone can experiment and share. When I first discovered VCV, December of 2021, I mostly tried to figure out what it was, what it did, and how to replicate what other people had done. Eventually I was having ideas of my own and learning how to make (what I think are) musically interesting ambient patches. I found that my patches while interesting at any point in time, tended to sound the same across longer periods of time and I was looking for ways to randomly vary the patch without deliberately sequencing sections (e.g. part A, B, A, B, C, D, A, B). I started thinking about how I could link logic modules together to turn things on and off, and things would get complex and I couldn't really wrap my head around all the logic and cabling.

I decided to see if writing some modules that combined some of the function I was looking for would help. And so I started down a different journey. The first few modules I wrote were really just to see if I could build a working module at all. I started simple - with Split and Merge - which of course already exists. But one of the things I always wanted was to pull the low or high note out of a series of notes. So my Merge and Split have a sorting capability - just enough to call it different. My sample and hold has mutliple tracking modes (always, low and high). Not special but different enough that I haven't deleted it. I then started playing arpeggiators thinking I could do something really cool there. Alberti bass anyone? I still haven't gotten that working they way I want, but I made a couple stops along the way to my goal of randomly turning things on and off. I created two modules to help me with that (e.g. Comps, Steps - see below)

The catalyst for finally going public was one of @OmriCohen's patreon videos (March 2023 at 49:18). Someone asked for a probabilistic sequence of notes taken from a set distribution, where each randomly chosen value affected the outcome of subsequent values - similar to pulling items from a basket, and not putting them back in the basket until the basket is empty. As it turns out I had mostly written that (only the other way around - I was putting every item back in the basket right away). So now I have a better version that has two modes - one with dependent probability and one without. And so I have now released it - because I know there is at least one customer (@CryptoTecky).

If you find any of these interesting or useful, then please let me know. If you find bugs or performance issues then please let me know. If you find the function difficult and have ideas on how to improve, then please ... let me know. If you have other ideas, especially in the random probability space, and want to see a module with some new behavior, then consider sending me a note. And with that said, here is a list of the current modules in the plug-in.

Modules for VCV Rack, an open-source Eurorack-style virtual modular synthesizer:

Builds/Releases

Mac, Linux and Windows builds of the latest version are available through the VCV Rack Library. Find release notes on the releases page.

Building

You'll need to be set up to build VCV Rack itself. The main branch of this module currently builds against Rack 2.1.2. Under the Rack build directory, switch to plugins/, and then:

  git clone https://github.com/zachwieja/2LiftStudios.git
  cd 2LiftStudios
  make dist

Then copy the ./dist/2LiftStudios directory to your Rack plugins directory

Inkscape

You need to install Inkscape to build the .svg files found in the ./src/res directories. All of the .svg files are pre-built and in the ./res subdirectories. However, after cloning the repository, they may appear older than the source files and make might try to rebuild them. Then, if you do not have Inkscape installed, and/or do not have the $(INKSCAPE) variable defined, then the build will fail. An easy workaround is to simply touch all the .svg files in the ./res subdirectories.

If you make updates to any of the .svg files, then there is no avoiding the installation of Inkscape.

Modules

Comps

COMPS is comprised of seven voltage parameter knobs and seven corresponding GATE ports. A GATE port is high when the IN voltage is strictly greater than (not equal) to the corresponding THRESH (threshold) voltage parameter / knob. Gates are inverted if the invert button for the corresponding gate is depressed. Note that inversion is intentionally imperfect. Negating a > comparision typically results in a <= comparison. In this case, inversion is simply a < comparison. Gates for thresholds that are equal to the input value are never high. A low gate is always 0.0V. High gates default to 10.0V but can be configured via a popup menu to be 1.0V or 5.0V.

The LOGIC gate goes high when the logic condition is met. The condition is configured by (repeatedly) pressing the button next to the LOGIC gate. The three logic conditions are None, Any and _All.

Merge

Takes up to 8 monophonic inputs and produces a single polyphonic output. A context menu allows setting the polyphony of the output. Setting the polyphony to a specific number will take the signals from the first N inputs (top to bottom) regardless of connectivity. Unconnected inputs yield 0.0V outputs. There are two automatic/dynamic polyphony modes. Setting the polyphony to "Highest #" sets the polyphony to the highest (bottommost) connected input. Setting the polyphony to "# Connected" sets the polyphony to the number of connected inputs and outputs a polyphonic signal with no gaps (no 0.0V signals for unconnected inputs).

Sort

Sorting, if enabled, is done as a function of the polyphony. All included polyphonic channels, as described above, are sorted before sending them to the output. The default order is None and no sorting occurs. The other two sort orders are Ascending and Descending. Channels are sorted and assigned channels starting from zero. Pressing the sort button multiple times toggles the sort order.

Sorting is useful for finding the highest or lowest V/OCT and as input to arpeggiators. Sorting polyphonic audio rate signals is possible - though perhaps less useful.

PolyQ

Is comprised of two polyphonic quantizers. Each quantizer takes a polyphonic input chord, and a second polyphonic input representing values that are quantized to the values in the input chord. The quantized values are emitted on the polyphonic output.

Mode

The module supports four modes: CLOSEST_DOWN, DOWN, CLOSEST_UP, and UP. The CLOSEST modes quantizes to the closest pitch from the input chord. In the case where the input value lands precisely between two values, then the its takes the lower or higher value depending on the mode, CLOSEST_DOWN or CLOSEST_UP respectively. For instance, if the input chord contains the notes C4 and E4, and the input to be quantized is D4, then the _DOWN or _UP designation determines the result. The DOWN and UP modes, quantize to the next lowest or next highest value respectively. For instance, if the polyphonic chord contains the values C4 and G4, and the mode is DOWN, then the values C4 through F#4 all quantize to C4, and the values G4 through B4 all quantize to G4. The default mode is CLOSEST_DOWN.

Octave

Each quantizer in the module has its own OCTAVE parameter. The value can be in the range -5 to +5, and is added to the quantized value.

ProbS

ProbS produces a random sequence of notes based on a weighted distribution. ProbS allows setting of up to six WEIGHT values that define a probability distribution. For instance, setting four WEIGHT values to 1, 2, 3, and 4 results in a total weight of 10 and a probability of 1/10th, 2/10ths, 3/10ths and 4/10ths respectively. At each CLOCK, a random number is generated, and a corresponding OFFSET value is chosen based on the probabilty distribution. ProbS has two modes which can be set using the MODE parameter.

Mode

In Stochastic mode, the generated OFFSET values will approach the specified weighted distribution. This is much like flipping a coin. The outcome of previous coin flips do not affect subsequent coin flips. You can receive the same result over and over again, but in the long run you expect the outcome to approach the distrubution - 50/50 for coin flips.

In Frequency mode, previous outcomes do affect subsequent outcomes. This is similar to drawing items from a basket and setting them aside until the entire basket is empty - then putting everything back in the basket.

Clock

OFFSET values are generated whenever the combined CLOCK input and MANUAL clock button generate a leading edge - when the previous state was off/low for both, and at least one of them is now high.

Offset

OFFSET values can be set in the range [-10V .. 10V]. They are typically set to voltages representing pitch, but can be set to any voltage and used to probabalistically drive scenes and other module parameters. For any given CLOCK, the light next to the chosen OFFSET value is illuminated.

Changing the OFFSET value while it is currently selected (light is illuminated) will have immediate affect (before the next CLOCK)

Weight

WEIGHT values are integers in the range [0, 100]. If a given WEIGHT value is set to zero, then the corresponding OFFSET value will never be chosen. The probability of any single OFFSET value being chosen is equal to the WEIGHT of the corresponding OFFSET divided by the sum of the weights.

Reset

The RESET input has no effect in Stochastic mode. In Frequency mode, it restores all the WEIGHTS values to the currently set distribution (i.e. puts all the items "back in the basket").

Interactions

When in Stochastic mode, changing the WEIGHT of any OFFSET has immediate affect - changes the probability on the next CLOCK. When in Frequency mode, adding WEIGHT is always added to the set of already generated values. Added WEIGHT affects the probability once all the values have been generated - or on the next RESET. When subtracting weight in Frequency mode, the module will first attempt to remove the weight from already generated values (so as not to affect the current cycle). If an insufficient number of values have been generated in the current cycle, then values are removed from the remaining ungenerated values.

SandH

SandH is comprised of two polyphonic sample and hold sub-modules. The sub-modules are completely independent and can each operate in one of four different modes.

Gate

A GATE is high when either the channel input is high or the MANUAL gate button is held down. The GATE is low when the channel input is low and the MANUAL button is not held down.

A leading edge (needed for SampleAndHold) occurs when either the GATE is high or the MANUAL button is held down, but neither were high/held down before. For instance, assume a GATE is low, and the MANUAL button is not held down. If the MANUAL button is now pressed and held down, then that generates a leading edge. While the button is held down, if the one or more channels for the GATE go from low to high, then no leading edge is detected (since the MANUAL button is still being held down).

Noise

There are two different types of noise Random and Gaussian. Random noise is simply a random value in the specified voltage range. There are no guarantees as to constant power, etc. Gaussian is implemented as white noise (with power guarantees). The default is set to Random, because it is consumes less CPU. Running 16 gates into both sub-modules with no input would generate 32 separate noise values (which consumes alot of CPU).

Interactions

If there are more IN channels than GATE channels, then the last gate is used for the IN channels without a corresponding GATE. If there are more GATE channels than IN channels, then a noise value is generated for the GATE channels that have no corresponding IN channel. This effectively means, if no input is connected, then a noise value is generated for the input.

If there is no IN or GATE connected, then a single noise value is emitted. This value is still goverened by the tracking mode. That is, with no GATE connected, the GATE input is always low. If the MODE is set to Track, or TrackLow, then a single continuously changing noise value will be sent to the OUT. If the MODE is set to TrackHigh, then a continously changing value will be sent to the OUT when the MANUAL gate button is depressed. If the MODE is set to SampleAndHold, then the last sampled value (from the last gate (either from the GATE input or the MANUAL button)) is sent to the OUT.

The MANUAL gate button affects all channels.

Split

Takes a single polyphonic input and spreads the first 8 channels across the first N outputs. Outputs with a signal have a small green light next to them.

Sort

Sorting, if enabled, is done as a function of the polyphony. All included polyphonic channels, as described above, are sorted before sending them to the output. The default order is None and no sorting occurs. The other two sort orders are Ascending and Descending. Channels are sorted and assigned channels starting from zero. Pressing the sort button multiple times toggles the sort order.

Steps

Produces a set of stepped voltages starting from a root voltage and then changing the voltage, based on the MODE, each time the module receives a CLOCK (or a RESET). There are five modes: Increment, Decrement, Exclusive, Inclusive and Random.

Clock

The leading edge of a clock signal is defined as any non-positive voltage going positive. Any positive value, no matter how small, will trigger the CLOCK and step the OUT voltage toward its next value.

Length

The LENGTH can be anything between 2 and 100 inclusive. A LENGTH of 1 would play the same note over and over again which would be better served by a different / simpler module.

Reset

For all modes this resets the sequence and moves the output voltage back to the starting voltage - For Increment, Exclusive and Inclusive this is the ROOT voltage. For Decrement this is the ROOT voltage + STEP voltage * LENGTH.

Step

This is the voltage change at each step. The value can be positive or negative. Both initially move away from the ROOT voltage for Increment, Inclusive, and Exclusive modes (before snapping or moving back toward the ROOT voltage). Decrement starts the furthest from the ROOT voltage and then moves toward the ROOT. Random mode returns values that are multiples of the STEP voltage offset from the ROOT voltage.

Sort

Sorting, if enabled, is done across all incoming channels. If the polyphony on the cable is N and the actual number of signals is < N, then the zeroes coming in on those unused channels will be included in the sort. The default sorting order is None and channels are routed to the outputs as you would expect. The other two orders are Ascending an Descending.

Interactions

When the LENGTH value is reduced between successive CLOCK signals and the current step is beyond the new LENGTH, the next step is adjusted - depending on the mode. For Increment mode the current step is set to 0 (the first step). For Decrement, Inclusive, and Exclusive, the value is set to LENGTH - 1.

Quant

DO NOT USE THIS - It is a work in progress and buggy (memory corruption and will crash VCV Rack)

Takes a single polyphonic input, quantizes each channel to the closest note within an evenly tempered scale, and copies the quantized values to the output. This module does not support non-symmetric scales (different values on they way down). There are three separate sets of controls for the the scale, root and octave parameters.

Scale

The scale can be set to any of 44 preconfigued scales. The names of the scales will appear in the hover text when spinning the knob. If the CV input is connected, it completely overrides the knob. That is, it is not additive. Valid CV values start at 0.0V and each 0.1V will change to the next scale. This allows for up to 100 scales and allows for backward compatibility when adding scales. Values below or above the range of scales result in selection of the first or last scale respectively. The supported scales are documented here here

Root

The root knob raises or lowers the voltage of the root note by 0 to N-1 steps. For instance, in a typical 12 step scale, each step represents 1/12 volts, yielding an overall range of [-11/12, +11/12] volts. A quartertone scale yields a range of [-23/24, +23/24] volts. Connecting the CV input is additive. The combined values are clamped at [-(N-1)/N, (N-1)/N] volts, where N is the number of steps in the scale (12 for most scales). The CV value is treated as monophonic. The value of the first channel is used across all channels of the IN input.

Octave

The octave note adds from -5V to +5V in 1V increments to the output signal to raise or lower the pitch by an equivalent number of octaves. If the CV input is connected, the voltage is added to the value from the knob and then the floor of the resultant value is clamped to the range [-5V, +5V]. For instance, a knob value of +1V added to a CV input of 1.333V results in an overall +2V (or 2 octaves). Subtracting 1.333V from 1V yields -0.333V which is then floored to -1V. The CV value is treated as monophonic. The value of the first channel is used across all channels of the IN input.

In

The input can be polyphonic. Each channel is clamped to [-5V, +5V]. All channels are affected equally by the scale, root and octave parameters.

Out

The output has the same number of channels as the input. Each channel is clamped to [-5V, +5V].

Parameter Interaction

If the root knob (and or combined root CV) is non-zero, and the scale is changed to one with a different number of steps (for instance between any 12 step scale to the 24 step quartertone scale), the the root value is adjusted to snap to the closest root within that scale. For instance, root offsets for a 12 step scale are in the range [1/12V, 11/12V]. If the root is set to 6/12V, and the scale is changed to a 53 step evenly tempered scale, then the root is recalibrated to the closest step in that scale - which is 26/53V.

Maths

All notes are quantized to the closest numerical/mathematical note in the scale. For instance, the C major scale is modeled as 7 notes over an evenly tempered 12 step scale with intervals of 2, 2, 1, 2, 2, 2 and 1 steps. The values for those 7 notes are equivalent to 0, 2/12, 4/12, 5/12, 7/12, 9/12 and 11/12 volts. The root and octave offsets are added to the input value and then the decimal portion of the voltage is snapped to one of those voltages. Any decimal portion in the range [-23/24V, 1/12V) snaps to 0V. Anything in the range [1/12V, 3/12V) snaps to 2/12V. Anything in the range [3/12V, 9/24V) snaps to 4/12V and so forth. Anything in the range [23/24V, 26/24V) snaps to 1V. Note the use of range notation. Open square brackets indicate inclusive values, and closing parenthesis indicate exclusive values.

VCASR

The VCASR module is a combined polyphonic VCA and Attack, Sustain, Release envelope generator. It takes a polyphonic IN and varies the signal(s) sent to the OUT based on the corresponding GATE signal(s) and the currently defined envelope parameters.

Input

The IN input is polyphonic. The number of channels on the IN will be copied to the OUT, EOC and ENV outputs.

Gate

The GATE input is polyphonic. If the number of GATE channels is less than the number of IN channels, then the last gate is used for the higher IN channels. In Gated mode, a new ASR cycle starts each time a GATE goes high (leading edge). In Triggered mode a new ASR cycle starts every other time the GATE goes high. The MANUAL gate button affects all channels.

Attack, Sustain, Release

The ATTACK, and RELEASE parameters are expressed in seconds. The maximum is 60 seconds. The default is 10 seconds. The SUSTAIN parameter is expressed as a percentage of the input signal. This module currently only supports a linear attack and release.

Output, EOC, Env

THe OUT, EOC (end-of-cycle), and ENV outputs are all polyphonic based on IN channels. The EOC emits a trigger at the end of the release cycle. If a new attack cycle starts before the end of the release, then no EOC trigger is generated for that cycle.

Mode

There are two modes which can be set using the context menu.

Themes

All of the modules are themed. There are two official themes: Light and _Dark. You can switch the theme of any module using the context menu for that module. You can also switch the default theme - which affects any newly instantiated modules.

If you are source code savvy and are willing to build the modules from scratch, then you will note in the ./scripts directory that there are several sed scripts that generate additional themes to match some of my favorite module collections. Each script does a global substitution of the 8 different colors used in the source .svg files.

You can add themes to the file ./src/common/Themes.cpp, simply cut and paste an existing theme, and then change the theme name. Then go to the ./Makefile and add the rules for the theme - instructions are in the Makefile.