Živa - live coding in SC made easy

Dear all,

I’ve been working on this project for quite a while. I think it’s about time to share it with the community.

Živa is a set of tools to quickly setup a live coding environment and start playing right away with very few lines of code.

Regular SC code can be used anywhere, because Živa is just SC code with a lot of syntax sugar to make things less verbose and faster to type. Instead of using the preInterpreter, and creating a new syntax, it uses SC’s syntax flexibility to make things short.

I’m still documenting it, but I wrote a quick starting guide in the README.

I’ve been greatly inspired by @thor 's Ixilang, @totalgee 's Bacalao, @yaxu ‘s TidalCycles, the Mandelbrots’ many inventions, @jamshark70 's chucklib, and many others. I owe all of them a lot: thank you all Masters of the code.

It was partly developed in a residency at Ljudmila (in Ljubljana, Slovenia) as part of the On-the-fly project. I am grateful to them, too.


This is great! I have few questions.

  1. If its possible, whats best way to use LinkClock?
  2. I am getting similar error (ERROR: Message ‘isSymbol’ not understood) for examples where Ziva.rhythms are used e.g. [0,4,7,0].montuno.pseq.
  3. A little bit different question. Whats best course of action when there is name collision for 2 different quarks. In this case Pmidi in Ziva and GitHub - lvm/SuperUtilities: SuperCollider utilities to ease the job of the everyday coder. ?

Also super cool that .trace works on patterns.

Thanks @qaciwq for trying it out.

I’m not familiar with any other clock than TempoClock.default, but my guess is that you may be able to pass LinkClock as a parameter to .play(), like any other Pdef().play. The [].ziva array is actually a Ppar inside a Pdef(\ziva):

[ ... ].ziva
// is syntax sugar for
[ ... ].pdef(\ziva).play.quant_(1)
// which is syntax sugar for
Pdef(\ziva, Ppar([...])).play.quant_(1)

Maybe try:

[ ... ].pdef(\ziva).play(yourLinkClock)

and see if it works. Let me know either way. I’d like to know if it does!

that should work, the rhythms are just a Dictionary. Could you post the full error stack? Do you have ddwCommon installed? That might be related (I’ll have to check). My intention is to remove all dependencies in a not to distant furure.

Sadly, I don’t think there is any other solution than removing either one. I’m not sure there’s anything similar to namespaces in SuperCollider. If there is I’d love to know and implement it in my classes : )

Looking at lvm’s Pmidi, I think it might work with Živa, too, since it’s just a pattern, very similar to what’s in mine. Try removing my implementation of Pmidi and see if the other one works. The code is quite similar, and – as stated above --, Živa is regular SC code so any other SC should work seamlessly. Please let me know if this works.

The code might look something like this:

~lvmmidi = Pmidi( /*whatever goes here in lvm's code*/ );
// or a regular Pbind
~apbind = Pbind(\type, \midi, \midiout, MIDIOut(0));

  // even this should work -- and so should any other Pbind type
  Pbind(\instrument, \acid).fast.deg([0,4].prand),
1 Like

TempoClock.default is an instance of TempoClock.

A LinkClock.new instance is also an instance of TempoClock. (Go ahead, try it: l = LinkClock.new.latency_(s.latency); l.isKindOf(TempoClock) → true)

Therefore you can simply assign your LinkClock instance to TempoClock.default:

// at startup -- avoid creating multiple LinkClocks!
TempoClock.default = LinkClock.new.latency_(s.latency);

This follows logically from the fact that LinkClock is a subclass of TempoClock – it was always meant to be a drop-in substitute. Everywhere you can use a TempoClock instance, you can use a LinkClock.



@loopier Installing ddwCommons solved Ziva.rhythms rhythms problem. Also LinkClock works nicely. From my understanding patterns default quant is 1? I got 2 more question while experimenting:

  1. Is it possible to run different parameters on different speeds. E.g.
~nala = Psynth(\acid);
[ ~nala.faster.deg([0,2,3].pseq).cutoff([2000,200,1000].pseq).trace ].ziva;
[ ~nala.deg([0,2,3].pseq).faster.cutoff([2000,200,1000].pseq).trace ].ziva;

No matter where I put .faster for above example it runs the same? My intention for second was to run only cutoff faster by putting it after deg.
2. If I put array of parameters e.g. [ ~nala.faster.deg([0,2,3]).cutoff([2000,200,1000]).trace ].ziva; does it spawn all at the same time or goes in order. Like it would create 3 different synths with deg 0 + 2000 cutoff, deg 2 + 200 cutoff and deg 3 + 1000 cutoff? Or 3 with same parameters.

@jamshark70 thanks for advice. It works fine except I had a problem because CmdPeriod killed LinkClock and I am addicted to CmdPeriod. So I added function to recreate Clock every time kill command is used with snippet below

~start_link_clock = {
  TempoClock.default = LinkClock.new(135/60).latency_(s.latency);
  Ndef(\default).proxyspace.clock = TempoClock.default;
  t = TempoClock.default;

// INIT -----------------------------------------------------------------------
  // clock
  // clock

So far it works but can it create some problems doing it this way?

.fast is a shortcut for .dur(1/2), so it affects all the parameters because it’s the same as using Pbind(\dur, ...). Same for its siblings faster, slow, slower, ....
To have different “durations” for different parameters, I’d set the duration for the whole Pbind to the fastest one you need then modify the slower ones. A couple of variants come to mind:

  • ...cutoff([2000,200,1000].pseq.pstutter(2))...
  • ...cutoff([2000,200,1000].dupEach(2).pseq)...
  • ...cutoff(Pstep([2000,200,1000].pseq, 2))... (I think this is the proper one)

I’m not sure, but from other combinations I’ve tried, your mapping seems correct to me: (deg 0 + cutoff 2000); (deg 2 + cutoff 200) + ; ...

1 Like


I think others could please take over on clock questions now…? Yes, I did quite a bit of work on LinkClock but actually this question is not specific to LinkClock at all.

LinkClock is-a TempoClock. The only significant difference is that it uses Ableton’s library to relate beats and seconds. So for questions like this, begin with the TempoClock help file.


1 Like

if it helps i have this my startup.scd

TempoClock.default = LinkClock.new.latency_(s.latency).permanent_(true);

making it permanent will enable it to survive Cmd.period