Playing Tidal live with absolutely no GUI

This is a picture of the algorave held here in the Recoleta Cultural Center of Buenos Aires, the 1st of October:

The event was organized by @irisS.

  • Me, playing with no GUI, live.


I didn't have a functional laptop or notebook until recently. I always had to borrow other livecoders' computers while on live events. While moving out of my previous house into my grandpa's house, I ended up finding an old HP laptop (HP Pavilon Dv4) he used to work with. Problem was this 2007? computer has merely: 250GB storage, 2GB RAM, Dual-core 2GHz processor... so yeah, you get the gist of it. I installed lubuntu and SCIDE + VSCode worked ok, but not as smooth as I wanted it to be. So while thinking about the lightest setup possible, I thought about learning vim. At first I wanted to simply avoid VSCode given its pseudo-IDE capabilities were taking various resources. But I ended up going all in, completely deleting the GUI and coding on CLI mode.


O.S. & Terminal

I'm using Ubuntu and its TTY1-6 terminals (if you're on any Ubuntu flavour rn and don't know what I'm talking about, press Ctrl+Alt+F1, then Alt+F7 to go back to the GUI).
You could still do everything here with a single terminal and tmux tho. Note that you can go into these TTYs without even logging in inside the startup screen, saving even more resources. No log-in tidal!

Code Editor

I decided to use neovim, and installing vim-tidal on terminal mode.

Launching Jack

I launch jack from a terminal, instead of letting SuperCollider do it. This way I can set my own sample rate and bit depth, lowering the resource demand. SuperCollider's defaults are 48 kHz and 32 bits. I lowered this to 44.1 kHz and 16 bits with the following launch:

$ jackd -d alsa -r 44100 -S

Launching SuperCollider

You could use scvim, but I decided not to. I don't really need livecoding supercollider and I didn't want to install ruby just to get it to work. So I wrote my own custom SC boot file and launched it with the following command:

$ QT_QPA_PLATFORM=offscreen sclang ~/Documents/tidal/CCR/CCR-boot.scd 

I'm not sure why, but you need to add the QT option for it to work on a TTY. Although from some other reason SuperCollider (at least version 3.11.2) runs the file and doesn't let you use the interpreter afterwards. I came across this issue.

EDIT: The reason for this is that the SCDoc system relies on generating GUIs when separated from the IDE. The same goes for the plotting functions. So SCLang always tries to load a GUI system.

Zoom-in and zoom out (sort of)

You may want to higher the font size in your terminal. Here's the command you need:

$ sudo dpkg-reconfigure  console-setup

Volume config

I also like to have the alsa audio mixer open in a terminal:

$ alsamixer

Other percs of using neovim for Tidal


It's super useful and time saving having snippets for the code you know you'll end up writing. Or maybe even some patterns. I used UltiSnips as recommended to me by @munshkr (creator of vim-tidal!).

Some examples:

snippet dohush
        all $ id
        setbpm ${1: 130}

snippet dstruct
d0 ${5} $ struct "t" $ note "${3: 0}" # octave ${2: 5} # s "${1}" # legato 1

snippet ukdrums
d1 $ ukswing $ drumM "ukg" [
        "bd ~ [~bd] ~"
        --,"[~hh oh:1 ~]*4"
        ] ${1}

(See my post about tidal-drum-machines to see what drumM is)

Setting up automatic indentation on Vim

Add this to your load file:

set autoindent
set cindent

Changing surrounding mini-notation

I installed the vim-surround plugin to be able to change stuff like [bd sd] to <bd sd>. I also always get confused in the moment and may end up writing stuff like bd("3 5",8) instead of bd([3 5],8), and this allows me to correct myself easily.

Using multiple tabs

You can load neovim with multiple tabs doing:

$ nvim -p file.tidal file2.tidal

And this config can allow you to change tabs doing Shift-H or Shift-L

nnoremap H gT
nnoremap L gt

Have fun and happy resource saving !



Loading files in CLI SuperCollider

A workaround to the interpreter disappearing when loading a file to sclang from bash can be the next one:

  1. Open sclang with no file. Remember to use the qt config described above when on a tty.
  2. Load the file you want from inside SC with the following:

Thanks to alln4tural who showed me this method after I had totally ignored it and used an unnecesary complex approach, heh


Nice one!

The QT env arg is handy, that might simplify some of my ansible install process, bookmarking :slight_smile:

Those vim snippet examples are handy too - I briefly delved into that setup a while ago but didn't get anywhere, I can revisit with specific examples now :slight_smile:

You probably want to check out Superdirt Lazy Samples Loading - ie you can still specify many gbs of sample dirs, but superdirt only loads the samples you are using (much memory saving!)


I'm having a bit of a dig into this now with auto-launching supercollider from neovim via the vim-tidal plugin, any chance you could share your custom startup file?
At the moment, just running from the standard terminal I'm getting a core dump almost immediately, but I'm not finding a lot of information to work around it.

I suspect it has to do with the SC_QT=ON compile time flags on my default supercollider install (ubuntu) - did you build supercollider from source?

i have the original file on my laptop and i'm on my desktop but it's basically the same as the tidal drum machines boot
that and a couple of synthdefs, nothing special

s = s ? Server.default;

s.waitForBoot {;
	~dirt =, s);
	~numberOfOrbits = 12;


	~drumMachinesDir ="C:\\Users\\Renzo\\Documents\\Tidal\\tidal-drum-machines\\machines");
	~machines = ~drumMachinesDir.folders; //All drum machines
	/*~machines = ['Linn9000','RolandTR909']; //Selected drum machines { arg m,i; ~machines[i]=(~drumMachinesDir+/+m) }*/

			arg machine;
			var folders = machine.folders;
			postln("LOADING DRUM MACHINE: "++machine.folderName);{
				arg folder;
				~dirt.loadSoundFiles(folder.fullPath,namingFunction: { |x| x.basename.replace("-","")});

	~dirt.start(57120, 0!~numberOfOrbits);
1 Like

I'm still getting my core dump - did you build sc from source?

[I know it's risky to be ironic in text-only communication. Still, let me try.]

Programming without a graphical editor .. kids these days! What will they discover next? That ABBA made albums prior to 2021?

Anyway the real "CLI mode" for Tidal is ghci. Editor is for the weak. See also xkcd: Real Programmers

[sarcasm off]

For building an actual non-GUI supercollider, I use cmake -DSC_QT=OFF (full build script: etc/sc/ · master · waldmann / computer-mu · GitLab) See also

And yes, running on "weak" hardware is one of the strong points of GNU/Linux (where GNU: tools like bash, emacs, gcc; Linux: the OS kernel). Good for sustainability (don't throw away computer), but, apparently, bad for (parts of) the economy: don't buy new computer. Which you'd only need for running new bloatware. That includes VSCode ..

1 Like

I rebuilt the debian packages with this flag off yesterday, I've encountered a strange issue where sclang starts fine, I see all my usual mesages with midi detection, and sample registration in superdirt, the JACK ports are configured - ie everything looks "normal"
However, when I try and play any sample, superdirt is unable to "find" it for playback (despite having registered it moments ago) - which it displays as an error log in the sc output

Have you encountered anything like this?

No. - What error, exactly? Or is this the coredump you mentioned earlier? For debugging, try these

Wild guess - the sample is found, but it does not fit in memory? A lot of things can go wrong, e.g., strange characters in the file name, invalid (header) data in the file.

no -

The samples all fit in memory - I replaced an scide installation with this, all the samples work fine in scide, it's only when I'm running sclang via the commandline

The error is the standard:

no synth or sample named 'arpy' could be found.

having literally just registered the sample on startup

Strange. Then I'd next try strace to see what files sclang actually accesses.

1 Like