softcut is a multi-voice sample playback and recording system built into the norns environment. it features level-smoothing, interpolated overdubbing, and matrix mixing. it was written by @zebra.
for an introduction to scripting:
- see/run softcut-studies/1-basic (source)
first, some nomenclature:
- voice — a play/record head. mono. each has its own parameters (ie rate, level, etc). there are 6 voices.
- buffer — digital tape, there are 2 buffers. mono. just about 5 minutes each.
softcut parameters are reset when a script is loaded. to get a looping sound we need at a minimum the following, where the arguments are
softcut.enable(1,1) softcut.buffer(1,1) softcut.level(1,1.0) softcut.loop(1,1) softcut.loop_start(1,1) softcut.loop_end(1,2) softcut.position(1,1) softcut.play(1,1)
the buffers are blank. load a file (wav/aif/etc):
softcut.buffer_read_mono(file, start_src, start_dst, dur, ch_src, ch_dst)
file— the filename, full path required ie
start_src— start of file to read (seconds)
start_dst— start of buffer to write into (seconds)
dur— how much to read/write (seconds, use
-1for entire file)
ch_src— which channel in file to read
ch_dst— which buffer to write
- see/run softcut-studies/2-multi (source)
enable more voices, then set their parameters using the first argument in the various param functions. here are a few more playback parameters:
softcut.pan(voice,position) softcut.level_slew_time(voice,time) softcut.rate_slew_time(voice,time)
- see/run softcut-studies/3-cut (source)
softcut cross-fades nicely when cutting to a new position and looping. specify the fade time:
we can read the playback position of a voice by setting up a poll.
function update_positions(voice,position) print(voice,position) end
and then inside
softcut.phase_quant(voice,time) softcut.event_phase(update_positions) softcut.poll_start_phase()
phase_quant specifies the time quantum of reporting. for example, if voice 1 is set to 0.5, softcut will call the
update_positions function when the playback crosses a multiple of 0.5.
- see/run softcut-studies/4-recdub (source)
first activate record mode for voice 1:
then set up the input source. first we route audio input to softcut, and then set unity levels for each input channel on voice 1:
audio.level_adc_cut(1) softcut.level_input_cut(1,1,1.0) softcut.level_input_cut(2,1,1.0)
finally, set the
rec: how much of the input gets recorded to the buffer
pre: how much of the pre-existing material stays in the buffer
so, full overdub would have both levels set to
1.0. just playback would have
rec set at
1.0. an echo effect can be easily created by setting middle ranges to each.
- see/run softcut-studies/5-filters (source)
softcut can apply filtering pre-record and post-playback.
softcut.pre_filter_dry(voice,value) softcut.pre_filter_lp(voice,value) softcut.pre_filter_hp(voice,value) softcut.pre_filter_bp(voice,value) softcut.pre_filter_br(voice,value)
both are state variable filters with all taps available, so you can freely mix the outputs of dry, low pass, high pass, band pass, and band reject.
to set the filter cutoff and q values:
post filters are the same. just replace
post in the command set.
- see/run softcut-studies/6-routing (source)
the audio routing within softcut is highly configurable.
first we can specify a mix of softcut’s input source:
audio.level_adc_cut( level ) audio.level_eng_cut( level ) audio.level_tape_cut( level )
then assign input levels per voice:
softcut.level_input_cut( ch, voice, level )
we can also cross-patch the output of voices to the input of other voices:
softcut.level_cut_cut( src, dst, value )
each voice can have a separate level for final output:
softcut.level( voice, value )
the example script uses two voices. the first just plays a loop. the second jumps positions, overdub-recording into the same loop using the first playhead as the input for recording. it’s a sort of feedback buffer process that radically restructures sound.
- see/run softcut-studies/7-files (source)
softcut reads files to buffers and writes buffers to files, in mono and stereo.
softcut.buffer_read_mono(file, start_src, start_dst, dur, ch_src, ch_dst) softcut.buffer_read_stereo(file, start_src, start_dst, dur) softcut.buffer_write_mono(file, start, dur, ch) softcut.buffer_write_stereo(file, start, dur)
the example script reads a “backing track” clip when K1 is long-pressed. this sets a loop length, and the playback volume can be changed with E1. a second clip is recorded from the audio input, with configurable rec/pre levels with E2/E3 respectively. the recorded clip can be saved at any time with K3, to
dust/audio/ with a
ss7- prefix along with a random number. this functions as a live “clip grabber” with overdub options.
- see/run softcut-studies/8-copy (source)
sections of a softcut buffer can be copied and pasted, for creative collage or straightforward duplication.
softcut.buffer_copy_mono(src_ch, dst_ch, start_src, start_dst, dur, fade_time, reverse) softcut.buffer_copy_stereo(start_src, start_dst, dur, fade_time, reverse)
buffer content can also be rendered as a series of floats, -1 to +1, for waveform visualization.
to request a numerical snapshot of a section:
softcut.render_buffer(ch, start, dur, samples)
to perform a task after the snapshot, use the
8-copy.lua script for an example of how to turn the -1 to +1 floats to a waveform.
contributions welcome: github/monome/softcut-studies