samsloop
samsloop · sourcesLoop-based sample player. Upload an audio file (≤2 MB — wav / mp3 / m4a / ogg / flac / opus) or record from patched audio inputs in place; the clip is decoded to mono and played back from a fractional read-cursor with linear interpolation, so a single rate control covers varispeed including reverse. IDLE-BY-DEFAULT: a freshly loaded sample sits SILENT and does NOT auto-play — and a saved patch reloads idle too. Playback is started by a TRIGGER, which is MODE-AWARE: in one-shot mode (1-SHOT) a trigger plays the sample through once then returns to silence; in loop mode (LOOP) a trigger starts looping (a re-trigger restarts from the window edge). The trigger comes from BOTH the TRIG gate input (a rising edge) AND the faceplate's TRIGGER button (a momentary pulse to the worklet that works whether or not a cable is patched into TRIG). The RATE slider spans −2 (reverse 2×) through +1 (forward unity, the centered no-op) to +2 (forward 2×), and a rate CV input sums on top (±1 V = ±100%). START / END faders set the playback window. Holds exactly one sample at a time — a new upload or recording replaces the previous buffer (no playlist, no slots), which keeps the per-instance memory ceiling deterministic.
the faceplate
inputs
| id | cable | what it does |
|---|---|---|
trig | gate | Rising-edge trigger that STARTS playback per the current MODE: in one-shot mode it plays the cropped window through once; in loop mode it starts the loop (and a re-trigger restarts it from the window edge — START for forward, END for reverse). Works alongside the faceplate's TRIGGER button. While idle (no trigger yet) the module is silent. gate / trigger; trigger — fires once per rising edge |
pitch_cv | cv | 1V/oct pitch input (0 V = C4): multiplies the playback rate by 2^V on top of RATE and rate_cv — a clip note one octave up plays the sample at 2×, one octave down at half; the sign of RATE (direction) is untouched. Unpatched = as recorded. This is the jack a clip-launcher lane auto-patches its PITCH to. control voltage (CV) |
rate_cv | cv | CV that offsets the RATE param (linear): ±1 V swings the playback rate by ±2 units (half the −2..+2 range) on top of the slider, clamped to ±2, so an LFO here does speed wobble, tape-stop, or reverse sweeps. The worklet's own ceiling is [−3, +3]; crossing zero flips playback direction. pitch_cv then multiplies the result by 2^V. control voltage (CV); modulates rate (additive offset — ±1 CV sweeps the full range, centered on the knob) |
start_cv | cv | CV that moves the START of the playback window. Because the window is a FRACTION of the sample rather than a frame count, a full-depth sweep here walks START from the sample's beginning to its far end whatever its length — an LFO scrubs the loop's in-point, an envelope drags it open. It is a BIAS on the knob, not an absolute position: the player sets a window and the CV moves it from there. START is resolved AFTER END (see end_cv), so driving START past END collapses the window onto END rather than pushing it open. control voltage (CV); modulates start (additive offset — ±1 CV sweeps the full range, centered on the knob) |
end_cv | cv | CV that moves the END of the playback window, in the same sample-relative fractions START uses: a full-depth negative sweep walks END back to the sample's beginning, shortening the loop to nothing. END is resolved FIRST and START is then bounded by the result — the two rules read together are not circular, which is exactly why the order is fixed rather than symmetric. Patch both and END decides how much of the sample is in play while START decides where inside it to begin. control voltage (CV); modulates end (additive offset — ±1 CV sweeps the full range, centered on the knob) |
audio_l_in | audio | Left audio RECORD input — patch a source here and arm recording to capture it into the sample buffer (replacing whatever was loaded). Mono sources work with just this jack. audio signal |
audio_r_in | audio | Right audio RECORD input — the second channel for a stereo recording (it's mono-mixed into the single buffer on stop). Normalizes to audio_l_in when left unpatched, so a mono source needs only the left jack. audio signal |
outputs
| id | cable | what it does |
|---|---|---|
out | audio | Mono audio output — the played/looped sample at the current RATE (forward or reversed), cropped to the START..END window. Silent until a trigger starts playback. audio signal |
params
| id | label | range | default | curve |
|---|---|---|---|---|
rate | Rate | ?..? | — | linear |
mode | Mode | 0..1 | 1 | discrete |
start | Start | ?..? | — | linear |
end | End | ?..? | — | linear |
poly | Poly | 0..1 | 0 | discrete |
controls
| control | what it does |
|---|---|
| End | END of the playback window, as a FRACTION of the sample (the right waveform marker). Crops where playback/looping ends, and where reverse playback begins. Together START..END select the slice that plays or loops. ⚠ END is resolved BEFORE START: when both are driven at once END is clamped to the sample and START is then clamped to END, so the pair always describes a real window instead of two rules that each depend on the other. CV via end_cv. |
| Mode | Playback MODE: LOOP (1, default) = a trigger starts a continuous loop that keeps going (re-trigger restarts it); ONE-SHOT (0) = a trigger plays the window through once and returns to idle/silent. |
| Poly | What a trigger does while the module is already sounding. MONO (0, default) restarts the single voice — the historical behaviour, and what a looper usually wants. POLY (1) gives each trigger its own read-cursor so overlapping strikes LAYER instead of interrupting, sharing the same voice budget MIDI LANE allocates and stealing the oldest voice when they are all busy. Voices sum rather than average, so layering gets louder rather than ducking. |
| Rate | Varispeed playback RATE (−2..+2, default +1 = forward unity). Positive plays forward, negative plays in REVERSE; |value| is the speed (2 = 2× / +1 octave, 0.5 = half / −1 octave). Center (+1) is the no-op unity speed. CV via the rate_cv input (summed through the linear LUT, ±2 units, clamped to the range; the worklet's own ceiling is ±3). A patched pitch_cv multiplies the result by 2^V (1V/oct), which is how a clip-launcher note transposes the loop. |
| Samsloop bits {n} | The bit depth a RECORDING is quantized to. 16 is the default and is transparent for most material; 8 halves the bytes per second, doubling the available length at the cost of an audible noise floor — which on a looper is often a sound you want rather than a compromise. |
| Samsloop chan {n} | How many channels a RECORDING captures. MONO halves the bytes per second and so roughly doubles the take length the budget allows; STEREO records both record inputs. It applies to the next take — the settings are frozen for the duration of one, and changing this mid-take ends it cleanly. |
| Samsloop denoise {n} | Removes steady background noise or tape hiss from the sample, in place. The noise profile is learned from the sample itself (the quietest fifth of its frames, per frequency band), then a spectral gate with a −12 dB floor attenuates each band toward that profile — hiss in the gaps drops by up to 12 dB and the tonal body of the voice or instrument on top is left within a dB. What it cannot do is tell a quiet consonant from the hiss: an s, sh, f or breath that sits within about 10 dB of the noise floor is turned down with it (the familiar lisp of a spectral gate, measured at 1–2 dB on a sibilant 10 dB over the hiss), so if the esses matter, record hotter or denoise a louder take. It REFUSES, with a reason under the waveform, when there is no steady floor to find: a pad, a drone, a clean take, or a phrase whose pauses are less than about a sixth of its length (the floor has to stand alone somewhere) is a level change, not a denoise, and is left untouched. A second press on an already-denoised sample refuses too (it would only dull the take). A DC offset is left in place for NORMALIZE to remove and report. The rewrite is NOT UNDOABLE — like REC, export first is the way back — and it lands as mono PCM at the source's own bit depth and rate (an 8-bit take stays 8-bit; a mp3 upload becomes a WAV on export). Run it BEFORE normalize. |
| Samsloop download {n} | Exports the sample to a file: a recording is written as a WAV at the rate, depth and channel count it was captured with, while an uploaded file comes back as its ORIGINAL bytes — an mp3 stays an mp3, losslessly — UNLESS it has been through DENOISE or NORMALIZE: a transform rewrites the sample in place as PCM at the stored rate, so a transformed upload exports as a mono WAV, not the original file. Export BEFORE transforming if you want the original back. Nothing to export means nothing happens. |
| Samsloop normalize {n} | Raises a quiet sample to full scale, in place: the DC offset is removed first (a constant offset eats headroom and is a click at every loop wrap), then the peak is scaled to exactly 0 dBFS — the sampler convention, so a low-volume vocal take fills the range. A single click in a quiet take is the peak and sets the gain; that is what peak-normalize means. It REFUSES, with a reason under the waveform, on a silent sample and on one already at full scale with no offset. The status line reports the gain applied and the offset removed. The rewrite is NOT UNDOABLE — like REC, export first is the way back — and it lands as mono PCM at the source's own bit depth and rate (the CHAN/BITS/RATE switches describe the NEXT recording, not this record; the status line says what was written). |
| Samsloop rate select {n} | The sample rate a RECORDING is decimated to. Lower rates trade bandwidth for length, and the decimation is by an INTEGER factor, so a requested rate that does not divide the audio context's rate lands on the nearest one that does — the faceplate says so rather than claiming a rate it did not produce. |
| Samsloop rec {n} | Starts and stops recording into the sample buffer, capturing whatever is patched to the record inputs at the current CHAN/BITS/RATE. A take REPLACES the loaded sample. It refuses to arm rather than silently shortening when the rack's sample budget cannot fit a usable take, and it stops itself at the length the current settings buy. |
| Samsloop trigger {n} | Fires playback by hand, exactly as a rising edge on the TRIG input would: in one-shot it plays the window through once, in loop it starts (or restarts) the loop. It works whether or not a cable is patched, which makes it the fastest way to audition a sample you have just loaded or recorded. |
| Samsloop wav input {n} | Loads one audio file as THE sample — wav, mp3, m4a/aac, ogg, flac or opus, up to 2 MB. SAMSLOOP holds exactly one sample, so a load REPLACES whatever was there (including a recording), and the window reopens over the whole of the new one. The status and error lines under the button report what was decoded, or why it was refused. |
| Start | START of the playback window, as a FRACTION of the sample (0 = its beginning, 1 = its end) — the left waveform marker. Crops where playback/looping begins, and where reverse playback ends. Being sample-relative rather than a frame index means the same setting means the same musical point on a two-second sample and a sixty-second one, and that a re-loaded patch can never land it on the wrong samples. CV via start_cv. |
source
samsloop.ts on GitHub.