paracosms

paracosms

construct imaginary worlds.

image

paracosms is a sampler+tracker that can throw loops, slice loops, write and record loops. main features:

  • can load/record up to 112 stereo or mono samples
  • sample playback is synchronized by default
  • recorded samples have gapless playback by crossfading post-roll
  • imported samples can be automatically warped to current bpm
  • one-shot samples can be sequenced with euclidean sequencer or gestures
  • each sample has filters, pan+amp lfos, timestretching, other fx
  • global tapedeck, greyhole and grains fx with per-sample sends
  • the grid (optional) can record gestures for toggling playback or splicing
  • a keyboard (optional) opens a tracker that can sequence and record external synths

why?

between april and june 2022 I made music primarily with scripts, SuperCollider, sox and random pre-recorded samples from other musicians. this endeavor culminated in an album of 100 songs. (more on that here).

during this time I put together a SuperCollider class I called “paracosms” which is essentially allowed unlimited synchronized turntables that can be switched between one-shots and synchronized loops. I used this to remix songs from the album I had made by performing them. i.e. I took a bunch of samples I collected and threw them into the grid with a thin norns wrapper around this SuperCollider paracosms class. it was very fun.

also during this time I was thinking about recording perfectly seamless loops of audio. I added a new function to do this easily in softcut. but I realized I wanted to do it with SuperCollider too. I ended up making “ouroborus” which allows recording of seamless loops directly to disk by fading in a post-roll to the beginning of a recording.

I realized that I could combine ourborous with paracosms together into sampler/looper. its basically a thing that excels at recording and playing perfect audio loops. norns became the glue for these two supercollider classes which is now this paracosms script.


this script wouldn’t exist without the ceasless inspiration from the likes of @sixolet, @jaseknighter, @tyleretters, @dan_derks, @yams, @license, and others who are all pushing the boundaries of what norns can do. also thanks to Ezra who showed me the art of SuperCollider - namely class-based designs.

Requirements

  • norns
  • grid (optional)
  • crow (optional)
  • keyboard (optional)

Documentation

playing loops

norns

E1 will select sample. K1+E1 will select sample that is loaded.

K3 will play a sample. holding K3 will fade the sample (in or out dependong on whether its playing).

the start/end points can be changed (press K2 to find the menu or use PARAMS). the loops always try to play in sync no matter the length. with the grid you can sequence the loop positions for chopping things (more below).

note: loops appear on the screen as single channel even if they are stereo.

playing one shots

oneshot

loops can be placed into “oneshot” mode. press K2 until you reach the screen with “mode”, “offset”, “start”, and “end”. then hold K1 and turn E2 to modify the mode to “oneshot” or “loop”.

oneshot

K3 plays a sample in oneshot mode. if you hold K3 it will toggle the euclidean sequencer (which can also be toggled by the parameters menu or in one of the K2 parameter screens).

recording

recording

K1+K3 will prime a recording. you always can skip waiting and you can start recording immediately by pressing K1+K3 again.

by default paracosms will wait to record until audio crosses a threshold to start recording. once recording is detected, it records the full length specified by the sample parameters (in beats, plus the crossfade post-roll). paracosms uses a latency term to capture the milliseconds right before recording (because there is an inherent delay in starting recording after detecting it) and this can be changed in the parameters. generally this latency should be really small (<20 ms).

parameters on the go

K2/K1+K2 will cycle through parameters.

E2/E3 or K1+(E2/E3) will modulate the current parameters.

there are a bunch of sample-specific parameters: volume (+lfo), panning (+lfo), sample start/end, filters (low+high), fx sends, timestretching. these are all available in the PARAMS menu, but they are also accessible from the main screen to avoid some menu-diving. us K2 to cycle through them and hold K1 to see the other alt parameters on each screen…

effects

there are three global effects - greyhole, grains and tapedeck. their parameters are editable in the main parameters menu. every parameter for grains is controlled by an LFO. every sample has its own send to the main bus (no fx) and to these two effects.

automatic warping

imported audio is automatically warped when either the guess bpm parameter is activated (i.e. from the startup script), or when “bpmX” occurs in the filename. for example of this latter case: if your sample is called “cool_sound_bpm120.wav” then it will assume a bpm of 120 and automatically stretch it to match the current norns clock in a way that doesn’t affect pitch. note: if you change the norns clock after starting paracosms then the samples will not be warped to fit anymore.

another note: if you include “drum” in the filename, then warping happens without using pitch-compensation.

you can change the warping at any time by going to the sample and editing the warping parameters. a new warped file is automatically generated and loaded when editing any parameter. all the warped files are stored in the data/paracosms folder. this makes subsequent reloads faster.

gapless playback

recorded samples: gapless playback is achieved in recorded samples by recording post-roll audio and crossfading that back into the beginning. paracosms takes care of this automatically.

imported samples: imported samples are assumed to already have been processed for gapless playback. read the tutorial below to edit your samples for gapless playback:

a tutorial on making audio with gapless playback.

I created a tool to automatically make seamless loops out of audio. to use this tool simply rename your file to include bpmX in the filename (where X is the source bpm of the file). for example, a 120 bpm file, “drums.wav” would be renamed “drums_bpm120.wav”. this tool is included with paracosms - its called seamlessloop. you can run seamlessloop on folders or files. for example:

os.execute("/home/we/dust/code/paracosms/lib/seamlessloop --in-folder ~/dust/audio/loops --out-folder ~/dust/audio/quantized-loops")

this tool does one of two things: if the number of determined beats is greater than a multiple of 4 then those extra beats are used to crossfade and make a seamless sample. otherwise, if the number determined beats is slightly less than a multiple of 4 then a gap of silence is appended to the end and the endpoints are faded by 5 ms to reduce clicks.

the grid

the grid essentially makes it easy to toggle on/off samples. it does give special functionality to create patterns from toggles, and even create patterns from start/stop positions (making it easy to break up samples).

images

keyboard / tracker

tracker

pushing a key on a keyboard opens the tracker. twisting an encoder closes the tracker (but it will still be running if you started it).

the keyboard layout closely follows the renoise layout.

image

the keyboard controls a sequencer. the sequencer has two dimensions. each row is a measure of 4 beats. those 4 beats are subdivided evenly across everything put onto a line. so if you put 8 things onto a line, each of those things will occur each 1/8th note. if you put 4 things, each will occur at each 1/4 note. if you put 7 things each will occur at each 1/7th note (approximately).

there are notes, note offs, and note ties. by default, anytime a note changes it will do a note off since each sequence is monophonic (though you can have as many sequences playing as you want). you can use the note ties and note offs to create syncopation. for example, the following is quarter note tied to an eight note:

C4 - - . . . . .

there are 8 things, so each thing gets 1/8th note. the C4 gets 1/8 note and its tied twice ("- -") and doesn’t get turned off until the 4th 1/8th note hits, so it lasts only 3/8th notes.

customization / loading sample banks

custom

paracosms is ready to be customized. the initial script can be changed to your liking. open up paracosms.lua in maiden, or copy and paste its contents into a new file.

the functions substance() and style() run at the start and at the end of loading, respectively (substance before style as they say). you can use these to trigger certain behaviors or activate parameters once everything is loaded. I like to make a script for each track I’m working on where the substance() sets the clock speed and style() loads specific files into specific banks.

the “blocks” allows you to customize the startup samples. you can load up to 16 samples per line per entry, with 7 entries available. each entry has a folder and all the files in the folder will be loaded. for instance the first line will loaded into slots 1-16. the second line will load into slots 17-32. etc. you can also create parameters that are shared across each block. any parameter that is available can be updated here. for example, say you wanted to load all the 909-samples as one-shots, you could include this line:

{folder="/home/we/dust/audio/x0x/909",params={oneshot=2}}

where oneshot=2 defines the oneshot parameter to be activated for all those samples (as opposed to looping). or you might want to include some loops and have paracosms guess the bpm for them. in this case you can do:

{folder="/home/we/dust/audio/myloops",params={guess=2}}

all the parameter ids are valid. for instance you can load a block of samples and have them all be used for the grains fx:

{folder="/home/we/dust/audio/togranulate",params={send_main=0,send_tape=0,send_grains=100}}

saving / loading

saving and loading is done by writing and reading PSETs. the save will store all the current parameters, patterns and references to audio files. since only the audio file reference is stored, if the file is moved then your save may no longer function properly (there is a way to fix this though if it happens).

todo

future

  • countdown for recording manually
  • tutorial video
  • midi input (for tracker?)
  • rain on a windowpane thing for composing songs from loops
  • more fx (strobe)
  • utilize @sixolet’s more canonical syncing between sc and lua
  • fix: ouroborous buses → sendreply
  • sample repitching

bugs

  • rarely a bug occurs where SuperCollider does not free all the synths when exiting. (fixed, I think)
  • there is a rare bug where the playback position escapes the start/stop points (maybe fixed)
  • the cpu will be overloaded if you play too many samples simultaneously (this limit depends on your cpu) or if you activate all the fx (tape + grains + greyhole, simultaneously).
  • if you change the norns clock then samples will continue to play at the rate according to the clock that they were initialized with. until there is a fix for this, I suggest reloading the script after you change the norns clock, or simply goto the sample individually and modify something in its warping parameters.

Install

;install https://github.com/schollz/paracosms

the first time you open the script it will ask to install the rest of paracosms.

Update

update the script by deleting and reinstalling or just running this in maiden:

os.execute("cd /home/we/dust/code/paracosms && git fetch --all && git reset --hard origin/paracosms
")
98 Likes

It’s the re:mix for norns I’ve been dreaming of.

9 Likes

what else can we say zach??

i’m impressed by how new it feels despite being somewhat iterative (there’s a solid thread connecting several of your previous song building/mangling scripts)

it looks reined in and under control with just enough included to let a user deviate from the path

THANK YOU

9 Likes

Both bitters and this thing provide PulsePTR and TrianglePTR.

hence `error: Duplicate engines`

On the Lua side of Maiden

DUPLICATE ENGINES:
/home/we/dust/code/bitters/bin/PulsePTR/PulsePTR.sc PulsePTR.sc
/home/we/dust/code/paracosms/ignore/PulsePTR/PulsePTR/Classes/PulsePTR.sc PulsePTR.sc
/home/we/dust/code/bitters/bin/TrianglePTR/TrianglePTR.sc TrianglePTR.sc
/home/we/dust/code/paracosms/ignore/TrianglePTR/TrianglePTR/Classes/TrianglePTR.sc TrianglePTR.sc
### SCRIPT ERROR: DUPLICATE ENGINES

and on the SuperCollider side

ERROR: duplicate Class found: 'PulsePTR' 
/home/we/.local/share/SuperCollider/Extensions/supercollider-plugins/PulsePTR/PulsePTR/Classes/PulsePTR.sc
/home/we/dust/code/bitters/bin/PulsePTR/PulsePTR.sc
ERROR: duplicate Class found: 'TrianglePTR' 
/home/we/.local/share/SuperCollider/Extensions/supercollider-plugins/TrianglePTR/TrianglePTR/Classes/TrianglePTR.sc
/home/we/dust/code/bitters/bin/TrianglePTR/TrianglePTR.sc

Those paths look funky with ignore and double the engine names in them. Would that be the cause? :thinking: :thought_balloon:

What would be the smoothest way around this? Would this be best addressed on bitters which ships with the classes under dust, or paracosms which installs them in the user SuperCollider location in ~/.local?

Cool idea with the :keyboard: keyboard not :musical_keyboard: keyboard, looking forward to trying out that UI modality.

2 Likes

thanks @glia for the kind words!

and yes its true - every new script has a bit of the dna from previous scripts :dna:

this one especially: the sox stuff comes from bits of makebreakbeat and sampswap (though those both do their own things, which are useful for this script too), I took the amp/pan lfos and recording detection from oooooo, tapedeck is ported here, another unreleased script called “zxcvbn” which is a full-fledged tracker is ported here as a lite-version, amen stuff is ported here, grid controls/view is based on the timber fork I worked on for @instantjuggler , the tracker sequencing is based off tmi, …

ah I didn’t realize PulsePTR and TrianglePTR were installed into ~/dust!

the state of 3rd party plugins for SuperCollider is tricky. there are many ways to install them and they are installed in various locations. this script works by checking the canonical installation directory: ~/.local/share/SuperCollider/Extension and looking for duplicates and avoiding them. I didn’t think to check ~/dust too. I think I can fix it pretty easily by adding it to the path to check EDIT: fixed!.

in general though, I’m hoping to get traction for this repository somehow: GitHub - schollz/supercollider-plugins I basically keep a up-to-date compilation of every 3rd part plugin I can find which can be installed into ~/.local/share/SuperCollider/Extensions. this is a new thing and I haven’t figured out how to incoporate into the nornsphere but it would likely alleviate these errors…

as a quick fix though - you can delete either one of those duplicates.

12 Likes

This is almost too much. I feel like we don’t deserve this :pleading_face:

Can’t wait to dig into this :heart::heart:

Big big love to @infinitedigits

2 Likes

geeeeze what an absolute triumph. another magnum opus from professor digits. bravo.

your passion and courage is contagious. thank you for sharing.

13 Likes

Holy crap, what a script!
It works, it syncs with my old ass MFB 503, and I can’t wait to build my own sample rows :slight_smile:
I’m maxing out the CPU almost immediatly though, unless I turn tapedeck off for all the samples.

Currently running two loops an a single oneshot, with tapedeck on for the loops, it starts to crackle an pop.
5 loops without effects, it’s the same.
I’m on a shield, so this could be the fault of the older Pi inside.

Immediately I wanted a way to record mono to stereo, since I have couple of things (like the Double Knot) where things a dual mono. Maybe just a parameter for each sample slot.

EDIT: I noticed that I’m hitting 60 degrees on the CPU, which is where the 3b+ throttled down to 1.2 Ghz, so maybe I just need to get some more airflow. Damn summer.

2 Likes

This is insanity, Zach! Looking forward to loading this and playing with it!!

1 Like

Fates raspi4b: supercollider error . every script in the library no longer starts. tried installation even with new virgin iso

1 Like

I tamped down the tapedeck oversampling so it will be less intensive. I’ll share some strategies for keeping cpu usage down later. certain things like modifying start/stop sample positions will use more cpu because it will utilize the dual-readhead instead of the single-readhead.

try to revert paracosms by removing the installed engines which are likely blocking Fates:

os.execute("rm -rf /home/we/.local/share/SuperCollider/Extensions/supercollider-plugins")

and restart. if that doesn’t fix it let me know.

unfortunately I have no idea* why it wouldn’t work on a Fates but does on others. so I will need some more troubleshooting information for Fates (like maiden errors when restarting). I don’t own one so can’t test it.

*my one idea is that maybe Fates is using the older Extensions lib located at /usr/local/.....?

2 Likes

Do you even sleep dude?!? This look amazing and can’t wait to test this crazy thing out!

9 Likes

Wooooh. So cool, cant wait to try and hope i understand the concept right in that i can also be free played (the samples)?

I almost dont dare to ask, but midi is supported as input?

This worked for me @infinitedigits, SuperCollider breaks on installing Paracosms on a Fates build of the latest Norns OS it seems.

Maiden doesn’t provide much info, on boot up you get this.

script clear

calling: passthrough post cleanup
norns.startup_status.timeout

SCRIPT ERROR: SUPERCOLLIDER FAIL

I’ve sent @okyeron a PM to let him know, hopefully we’ll get to the bottom of it.

Thanks again!

Matt

2 Likes

So this might be a hint…

(still poking around at it tho)

*** Welcome to SuperCollider 3.13.0-dev. *** For help type ctrl-c ctrl-h (Emacs) or :SChelp (vim) or ctrl-U (sced/gedit).
Booting server 'localhost' on address 127.0.0.1:57110.
Found 0 LADSPA plugins
*** ERROR: dlopen '/home/we/.local/share/SuperCollider/Extensions/supercollider-plugins/f0plugins/SID6581f/linux/SID6581f_scsynth.so' err '/lib/arm-linux-gnueabihf/libm.so.6: version `GLIBC_2.29' not found (required by /home/we/.local/share/SuperCollider/Extensions/supercollider-plugins/f0plugins/SID6581f/linux/SID6581f_scsynth.so)'
Server 'localhost' exited with exit code 0.

2 Likes

Beautiful demo! Thank you. Looking forward to trying.

@mattallison , @matteo.ini , and Fates folks - it should be fixed now thanks to @okyeron ! turns out Fates had a different GLIBC which prevented all the precompiled things from working. they are now compiled and ready to go.

restart your paracosms install by deleting what you already have:

os.execute("rm -rf ~/dust/data/paracosms ~/dust/audio/paracosms ~/dust/code/paracosms")

then try to install again with the

;install https://github.com/schollz/paracosms

and run the script again. once it installs you need to restart and run the script again and you should see a waveform and “WELCOME”. if you don’t, let me know and we will turn back to the troubleshoots.

3 Likes

Works ace @infinitedigits! Up and running and look forward to exploring it later!

Thanks to both you and @okyeron

3 Likes

Is it possible to further implement the features of raw into paracosms? Or perhaps the next iteration. Such as the loading samples into the five different types of pools and a feature to randomise and bounce out a tracks?

2 Likes

@infinitedigits
this is crazy WOW! :dizzy_face:

had a wee bit of issue after the install…
on norns #1 it started up and asked for the download…no problem.
when it was done it asked for the same task again to hit K3 and download again.
since i wasn’t sure if there was more to the process i hit K3 again…ooooh wee…it did NOT like that.
i had to use the Vulcan Death Grip on it to get out of it.

when it rebooted it started up ok but i may have hit an extra button and it did not do the loading of the demo files.
it just asks for K1+K3 to start recording.

so…on norns #2 and #3 i ignored the second download message and did the restart.
both #2 and #3 startup with the Welcome and auto load the demo files.

1 Like