Sample Swarm

Sometimes too much control stifles creativity. Sometimes you just need to make a mess.

So clasp hands with chaos and sling sounds like Pollock slung paint. Turn a recording of yourself saying “ah” into a chorus of angels…or demons. Turn those found sounds from your kitchen into a clanking nightmare factory. Mash and mangle an entire folder of audio. Automatically cut and collage to your heart’s content – sometimes you just don’t care when or how your sounds are played, you just know you want hundreds of them playing at random times and random pitches!

Scribble on the walls! Bake mud pies! The results aren’t always pretty, but the process is fun.

But what is this module? Is it a looper? A granular device? A sample mangler? A noise maker? A blur effect? A glitchy delay?

Sort of. Well…not really. Well…sometimes.

At its core, JK’s Sample Swarm is an endlessly looping buffer to which you can write audio, with parameters to guide, yet not quite specify, how and when things are written. Potentially, one can write a lot of audio, overlapping itself until the sound sort of averages out into an endless blur. Transients eroded, your monument reduced to rubble. While originally devised for easily turning tonal samples into drones, and non-tonal samples into texture, the controls leave plenty of room for experimentation. Less extreme overlapping, options to only use small segments of source audio, and even ways to randomize the file used as source audio extend the possibilities to numerous other applications.

Quick Start

Here’s the absolute basics of what to do:

  • Click the sample window (where it says “<source sample>”) to choose an audio file to load.

  • Tweak the various knobs in the top section to adjust parameters, then choose processing settings in the middle area, paying particular attention to the copies knob and the length knob.

  • Click the add button to begin the process. Depending on the length of the source sample and certain other settings, it may take a moment. It’s writing copies of the audio to the buffer behind the scenes. Lucky for you there is a nice little progress bar to indicate…well, progress.

  • Adjust the Amp or V/Oct knobs to taste. Enjoy the results. Repeat if desired.

For those who would like to learn more, we will first dive into what is actually going on internally and then work through each of the controls one by one, section by section, to fully explain how everything works and how you can best use this unusual little guy for your own nefarious purposes.

The Swarm Process

We start with an empty buffer. If it helps, you can think of this as a looping piece of blank audio tape. It’s always playing, going around and around endlessly. In the physical world, the tape would travel past a recording head, and it’s only as it passes in real time that you can write a single moment of sound to the tape. In the digital realm, there’s countless examples that mimic this setup (loopers and delays, among others), countless more that make use of modern processing power to read or write many times at once (granular devices, for instance). But why not defer gratification and allow the work to proceed behind the scenes, so as to move beyond even these limitations? We could simulate a large number of writes and smear data all over that innocent little audio buffer.

The trick here – if we can be so bold to call it that, given the unsophisticated brute-force nature of the algorithm – is in the non-realtime process that performs these reading and writing operations without interrupting the otherwise normal behavior of this or any other module in the environment. We start with an audio sample loaded in the window at the top of the module, tweak the parameters to our liking, and then hit the add or replace button. The module then reads data from the selected source sample and begins writing that data at a randomly chosen point in the output buffer, wrapping around as if it truly was one continuous piece of tape. It does this again, and again, mixing in the number of copies requested by the copies knob.

Then the oven dings and your buffer comes out, piping hot and already looping.

Sample Window

This module is useless without some source audio, so with that in mind we’ll first discuss the sample window. This is the black rectangle with cream-colored text found near the top of the module. You can drag and drop a sample (.wav, .mp3, or .aif) into the area to load it or click to bring up a file picker.

Upon loading, the sample data is normalized (amplitude scaled to use maximum available range, i.e. 5 volts) and shifted up or down if necessary to adjust for any obvious overall DC bias. Both operations contribute to a better, more consistent swarming end result.

The window has some extra functionality once a valid file has been loaded:

  • CTRL + Left-click: loads the next sample in the current sample’s directory

  • CTRL + SHIFT + Left-click: loads the previous sample in the current sample’s directory

  • ALT + Left-click: loads a random sample from the current sample’s directory

  • Right-click: previews the source sample, using the current slice settings

  • CTRL + Right-click: previews the entire source sample, ignoring slice settings

Note that preview functionality is meant as a convenient aid in selecting samples; audio is sent directly to the module’s outputs, temporarily overriding playback of the swarm buffer.

Processing Parameters

Beyond the sample window, we find the first set of controls. These define how the source material will be added to the output buffer. The knobs follow a coloring scheme where cream indicates a concrete value and black indicates a variation amount or range of values. Controls are additionally grouped into three subsets according to function.

Slice Parameters

The first subgroup of controls determines what portion of the source sample gets copied into the output buffer. We can refer to this audio segment as a slice.

Start Knob: Sets the start position of the slice.

Start Variation Knob: Sets the range over which the slice start position can randomly vary.

Length Knob: Sets the length of the slice.

Length Variation Knob: Sets the range over which the length of the slice can randomly vary.

Once Toggle: By default, a new slice start and length is calculated (assuming variation is greater than 0) for every swarm process iteration (i.e. for each copy). However, if this control is toggled on, slice positions are only calculated once for the entirety of the swarm process, thus reusing the same segment of audio. The process will, of course, randomly calculate a new slice the next time a new process is triggered.

Hold ms Toggle: By default, the four slice knobs operate as percentages of the source sample length (despite displaying their values in milliseconds). When this control is toggled on, the length and length variation knobs will attempt to retain their values in milliseconds, rather than as a percentage, when loading a new sample. This can be especially helpful for maintaining short slices while randomizing source samples of varying length. Note that if the ms value is larger than the length of the sound, it will just be set to the maximum ms value.

Fade Knobs: Sets the length (as a percentage of the slice length) of the linear fades that are applied to each end of the slice before it is written into the buffer. In some cases, fades may be unnecessary or even undesirable. However, given the unpredictable nature of slicing, this becomes invaluable in eliminating sharp discontinuities in the sounds (that result in those lovely digital clicks). Also note that the knobs are self-adjusting: the total value of the two knobs can never exceed 100%.

Finally, some general notes about these slice parameters:

  • As mentioned above, the four main knobs (start, length, and their variations) operate as percentages of the source sample’s length, though they display their values in milliseconds and accept millisecond values if using the right-click menu Edit Value function. Additionally, appending a percent symbol “%” to a value entered in this way will set the knob to that percent of the source length.

  • The four main knobs also have small graphical indicators that overlay the sample window: a vertical bar for each concrete value, and a horizontal extension from each vertical bar to show the variation range.

  • It’s also important to be aware that these knobs cover the entire possible length of the source audio. Care should be taken, then, because it is thus possible to end up with “slices” of zero length. This won’t break anything, but it does result in nothing being copied during that specific iteration.

Pitch Settings

Pitch Knob: Sets an amount to repitch the source audio before adding it to the output. Linear interpolation is used to reduce quantization artifacts. The knob is locked to semitone increments, with usable values up or down by as much as three octaves. While these extremes are often unnecessary (or just plain sound bad) the experimental nature of the module justifies the ability to go to these extremes, if only “just to see what it sounds like.”

Pitch Range Knob (+/-): Randomly shifts the base pitch up or down by up to the set number of semitones (up to two octaves, locked to semitone increments). This value is chosen once at the beginning of a new swarm process and held throughout its iterations – the intention is to allow pitch variation only between subsequent processes (much like using the once toggle for slices above).

Pitch Detune (~): Randomly shifts the pitch of each slice up or down by the chosen amount (up to two octaves, not locked to semitones).

Miscellaneous Settings

Volume variation: This defines the range of volume variation in writing slices to the buffer. More specifically, it defines how low each individual slice’s volume can go. The higher the value set, the lower the resulting amplitude of the written waveforms might be – with 100% allowing for the possibility, however unlikely, of a zero volume copy/slice. Note that while the knob is labeled in straight percent, internally the volume reduction follows a tighter curve that attempts to accentuate the differences in volume (especially low volumes) thus leading to more satisfying results.

Reverse % Knob: This controls the probability that any single slice will be added to the output in reverse. At 0%, each slice is written forward, while at 100% every iteration is mixed in reverse.

Left/Right Distance: This controls the maximum percentage of output buffer length the left and right channels can be shifted from each other when being copied – the actual distance is determined randomly each iteration. At small values, the result is basically a Haas (widening) effect. At somewhat larger values it can feel like a single stereo echo. At the largest values it becomes hard to hear a causal relationship between the channels, thus providing the illusion of similar sounds emerging concurrently, but separately, on either side of the listener.

Note that mono sources will simply use a copy of itself for the right channel, while stereo sources will use their existing left and right channels.

Swarm Process Controls

Length Knob: This determines the length of the swarm output. Internally, the entire 20 seconds of buffer always exists, but using the length knob sets a loop point, effectively ignoring the rest of the buffer both during playback and during the swarming process.

Copies Knob: Controls the number of iterations the process runs through – in other words, this is the number of slices that will be copied into the output buffer, anywhere from a single occurrence to 100 slices. But that’s not enough….

Multiplier Toggle: A 10-times multiplier for the value set above, thus allowing up to 1000 total writes/copies/slices when toggled.

Crossfade Knob: Dictates the length of a linear crossfade applied after any of the three actions described below (clear, replace, add) from old output buffer to new output buffer.

Clear Button: Sends a request to the module to clear the entire output buffer.

Replace Button: Sends a request to completely replace the current output buffer with the result of a new swarm process.

Add Button: Sends a request to add to the existing output buffer, mixing new audio data with existing audio data. In other words, with the add function you can progressively build up a loop, using different settings or even loading different source sounds each time! Let the auto-collaging begin!

Progress Bar: The most glaring omission from the original incarnation of this module was a way to know how long one had to wait to get their output. Now, however, we have a color-coded progress bar, if not to assuage our impatience, at least to assure us that our module is striving for results!

Each color indicates a different internal state:

  • GREEN: Ready. A state of rest, non-processing, non-swarming.

  • RED: Processing. A state of calculation. The swarm grows.

  • ORANGE: Crossfading. The point of no return. The swarm is on the horizon.

Some final notes on the above swarm controls:

  • During processing (but not crossfading), the add and replace buttons double as cancel/panic buttons, halting the swarm process and throwing out any new data. In many cases, the process happens too fast for this to be usable, but for those circumstances of deep regret sometimes caused by using the full length of a 10 minute sample with swarming set to 1000 copies, it’s nice to have an escape hatch.

  • The buttons (as well as their corresponding jacks, discussed further on) don’t necessarily initiate the desired actions: they merely send requests. There are rules governing when certain actions are allowed to trigger. Any unused requests are flushed/reset. Further details can be found in the subsequent section on external triggers.

  • The crossfading period, though technically occurring after the bulk of the swarm process, is still considered to be an incomplete state thus both showing its progress as the final stretch of the progress bar, and denying any conflicting requests. But it’s too late at this point to cancel. An erroneously too-long crossfade can be shortened simply by turning the knob down – the crossfade will respond in real-time.

And some final notes about the process itself:

  • After mixing all copies of a new swarm, the result is normalized.

  • Keep in mind how the settings interact, both in terms of processing time and final results. For instance, a ten second sample written only once to a one second buffer will wrap and thus overlap itself ten times.

  • Also, while it may be obvious that longer slices and longer source samples, coupled with higher numbers of copies would result in longer processing time, it’s important to note that pitch plays a role as well: every octave down doubles the number of samples needed to be written – thus slowing the process – while every octave up halves the number of samples and speeds things up.

External Control Section

As we travel down the module we come to a row of four mono input jacks. These detect and act upon incoming trigger signals (defined here as a current sample value equal to or above 2.5 volts with a previous value less than 2.5 volts). The first three jacks allow external activation of any of the above three swarm buffer operations – clear, replace, and add – while the fourth one – source – mimics the ALT + Left-click functionality of the sample window in that it loads (when possible) a new randomly chosen sample from the currently loaded sample’s directory.

Thus we come to a moment where we must stop and sort out the ways in which the various aspects of buffer, process, triggers, requests, and whatnot interact and manage to coexist peacefully. Some restrictions exist so as to not lead to contradicting internal states, while other restrictions are artificially enacted to prevent excessive CPU or disk usage.

  • While processing or crossfading, buffer operations cannot be triggered (though recall that add/replace buttons act as cancel).

  • While loading a new source, clear can be triggered, but not add or replace.

  • The module checks for requests every 50ms.

  • Add and replace requests cancel each other. This only really matters in instances where each receives a request within the 50ms window.

  • If triggered on the same tick, replace takes precedence over add, and clear takes precedence over both.

  • If the source jack is triggered, it can't be triggered again until the loaded sample is used at least once in a process. This only affects the jack, not any normal sample window operations. This just stops a repeating trigger from automatically loading one file after another without using them.

  • Requests are cleared at the end of a request check if they are not used.

  • All knobs can be adjusted during processing and most (except length and copies) will update in realtime within the process itself. This is not typically useful or even usable (with short processes), but it’s there.

Output Section

The final section is pretty basic and doesn’t merit extensive discussion. Aside from a left and right output, there are also components that provide control of the final volume and pitch of the output.

Amp Knob: Sets the relative amplitude of the output to a value between 0% and 200%.

Amp Jack: Allows external control of the output’s amplitude. Allows for through-zero amplitude modulation where 5 volts equals 100% of the signal and -5 volts equals -100% of the signal (i.e. inverted). These are just provided here as reference, as there is no actual voltage limit imposed on this jack’s input.

V/Oct Knob: Sets the playback rate of the output buffer, up or down up to three octaves, labeled in semitones. Again, the large range is meant for experimental purposes as it will often not sound good, especially at higher pitches, due to potentially extreme aliasing.

V/Oct Jack: Accepts standard 1 volt per octave input for pitched control of buffer playback rate.

Finally, a DC filter is applied before sending values to the output jacks as a final precaution against any DC offset that could have potentially accumulated during processing.

Changes - Version 2 - Jan 7, 2023

  • Samples normalized and offset on input/load

  • Replaced status LEDs with progress bar

  • Pitch, pitch range, pitch detune parameters

  • Volume variation parameter

  • Normal/wide changed to stereo distance parameter

  • Source slicing - start position, start variation, length, length variation, fade in, fade out

  • ONCE and HOLD MS options for slicing (see manual)

  • PROCESS button evolves into clear, replace, and add buttons

    • Replace creates new output

    • Add mixes new audio with existing buffer audio

  • Input jacks to trigger add, replace, clear…and source randomization!

  • Output length adjusted to be .1 to 20 seconds and can change even after process

  • Crossfading old output into new output, 0 to 10 seconds

  • Preview source sample slice with right-click

  • Preview entire source sample with ctrl + right-click

  • Amp jack now through-zero

  • Arbitrary constraint on V/Oct input removed

  • DC Filter on output

  • Fixed clicking at loop point!

  • Lots of other tweaks and internal stuff