I’m definitely interested in adding Clouds and Rings to the Pedalboard engine, but yeah there should probably also be a dedicated MI engine that has all the UGens including the VCO-style modules as well (Pedalboard doesn’t really make sense with the oscillators). Pedalboard may have some inspiration for y’all on how to make it possible to patch the separate modules into eachother in a dynamic order, but I’m between laptops right now and won’t be able to do much actual development for a little while. Happy to help in other ways though! I’d also recommend jah’s R engine which is a full-on modular synthesis environment

4 Likes

I suppose I can PR the pedalboard modules for rings/clouds - or make a branch (?) - for testing and see if you or anyone else has implementation suggestions?

@21echoes OK - I forked pedalboard and added a branch for mi-ugens

2 Likes

Elements interface work/experiment and discovering the UI library.

12 Likes

My use-case is quite specific at the moment.

I have 3x MiPlaits setup as Kick, Snare and Hat, with commands for a sub-set of the parameters for each channel.

I’m happy to share what I’ve made, but it may not be especially useful for anyone else.

Has anyone considered making MI modules (or whatever the term is) for R?

1 Like

Here’s an Engine script for a 3-channel (Kick/Snare/Hat) MiPlaits drum kit.


Engine_BEPlaits : CroneEngine {

  var <kick;
  var <snare;
  var <hat;

  *new { arg context, doneCallback;
    ^super.new(context, doneCallback);
  }

  alloc {

	//////////////////
    // DEFINE SYNTH //
    //////////////////

	SynthDef(\MiPlaits, {
		arg out, pitch=60.0, eng=0, harm=0.1, timbre=0.5, morph=0.5, trigger=0.0, level=0, fm_mod=0.0, timb_mod=0.0, morph_mod=0.0, decay=0.5, lpg_colour=0.5, model=0.0, mul=1.0;
		var sound, primarySound, auxSound, mixed;
		sound = MiPlaits.ar(pitch,eng,harm,timbre,morph,trigger,level,fm_mod,timb_mod,morph_mod,lpg_colour,1.0);
		primarySound = sound[0] * mul;
		auxSound = sound[1] * mul;
        mixed = XFade2.ar(primarySound,auxSound,model);
		Out.ar(out, [mixed, mixed]);
	}).add;

    context.server.sync;

	////////////////
	// Kick Synth //
	////////////////

    kick = Synth.new(\MiPlaits, [
		\out, context.out_b.index,
		\pitch, 60.0,
		\eng, 13,
		\harm, 0.1,
		\timbre, 0.5,
		\morph, 0.5,
		\trigger, 0,
		\level, 1,
		\fm_mod, 0.0,
		\timb_mod, 0.0,
		\morph_mod, 0.0,
		\decay, 0.5,
		\lpg_colour, 0.5,
		\mul, 0.6
      ],
    context.xg);

	// Kick Commands
    this.addCommand("trig_kick", "f", {|msg|
      kick.set(\trigger, 1);
      kick.set(\level, msg[1]);
      SystemClock.sched(0.01, {
        kick.set(\trigger, 0);
      });
    });
	this.addCommand("pitch_kick", "i", {|msg|
	  kick.set(\pitch, msg[1]);
	});
	this.addCommand("harm_kick", "f", {|msg|
	  kick.set(\harm, msg[1]);
	});
	this.addCommand("timbre_kick", "f", {|msg|
	  kick.set(\timbre, msg[1]);
	});
	this.addCommand("morph_kick", "f", {|msg|
	  kick.set(\morph, msg[1]);
	});
	this.addCommand("model_kick", "f", {|msg|
	  kick.set(\model, (msg[1]*2)-1);
	});
    this.addCommand("level_kick", "f", {|msg|
	  kick.set(\mul, msg[1]);
	});

	/////////////////
	// Snare Synth //
	/////////////////

    snare = Synth.new(\MiPlaits, [
		\out, context.out_b.index,
		\pitch, 60.0,
		\eng, 14,
		\harm, 0.1,
		\timbre, 0.5,
		\morph, 0.5,
		\trigger, 0,
		\level, 0,
		\fm_mod, 0.0,
		\timb_mod, 0.0,
		\morph_mod, 0.0,
		\decay, 0.5,
		\lpg_colour, 0.5,
		\mul, 1.0
      ],
    context.xg);

	// Snare Commands
    this.addCommand("trig_snare", "f", {|msg|
      snare.set(\trigger, 1);
      snare.set(\level, msg[1]);
      SystemClock.sched(0.01, {
        snare.set(\trigger, 0);
      });
    });
	this.addCommand("pitch_snare", "i", {|msg|
	  snare.set(\pitch, msg[1]);
	});
	this.addCommand("harm_snare", "f", {|msg|
	  snare.set(\harm, msg[1]);
	});
	this.addCommand("timbre_snare", "f", {|msg|
	  snare.set(\timbre, msg[1]);
	});
	this.addCommand("morph_snare", "f", {|msg|
	  snare.set(\morph, msg[1]);
	});
	this.addCommand("model_snare", "f", {|msg|
	  snare.set(\model, (msg[1]*2)-1);
	});
    this.addCommand("level_snare", "f", {|msg|
	  snare.set(\mul, msg[1]);
	});

	///////////////
	// Hat Synth //
	///////////////

    hat = Synth.new(\MiPlaits, [
		\out, context.out_b.index,
		\pitch, 60.0,
		\eng, 15,
		\harm, 0.1,
		\timbre, 0.5,
		\morph, 0.5,
		\trigger, 0,
		\level, 0,
		\fm_mod, 0.0,
		\timb_mod, 0.0,
		\morph_mod, 0.0,
		\decay, 0.5,
		\lpg_colour, 0.5,
		\mul, 0.6
      ],
    context.xg);

	// Hat Commands
    this.addCommand("trig_hat", "f", {|msg|
      hat.set(\trigger, 1);
      hat.set(\level, msg[1]);
      SystemClock.sched(0.01, {
        hat.set(\trigger, 0);
      });
    });
	this.addCommand("pitch_hat", "i", {|msg|
	  hat.set(\pitch, msg[1]);
	});
	this.addCommand("harm_hat", "f", {|msg|
	  hat.set(\harm, msg[1]);
	});
	this.addCommand("timbre_hat", "f", {|msg|
	  hat.set(\timbre, msg[1]);
	});
	this.addCommand("morph_hat", "f", {|msg|
	  hat.set(\morph, msg[1]);
	});
	this.addCommand("model_hat", "f", {|msg|
	  hat.set(\model, (msg[1]*2)-1);
	});
    this.addCommand("level_hat", "f", {|msg|
	  hat.set(\mul, msg[1]);
	});
  }
  
  free {
    kick.free;
    snare.free;
    hat.free;
  }
}

And the params definitions to control it.

Note “model” parameter crossfades between the two MiPlaits outputs. If you want, you could just pass the engine 0 or 1 to switch between them.

I might experiment with ControlSpec presets for the Pitch param (does that show the MIDI note # in the params list?).

----------------------
  -- Drum Edit Params --
  ----------------------
  
  params:add_separator("drum edit")
  params:add_control("bdp1","bassdrum pitch",ControlSpec.new(0,127,'lin',1,32))
  params:set_action( "bdp1", function(x) engine.pitch_kick(x) end)
  params:add_control("bdp2","bassdrum harmonics",ControlSpec.new(0,1,'lin',0,0.1))
  params:set_action( "bdp2", function(x) engine.harm_kick(x) end)
  params:add_control("bdp3","bassdrum timbre",ControlSpec.new(0,1,'lin',0,0.5))
  params:set_action( "bdp3", function(x) engine.timbre_kick(x) end)
  params:add_control("bdp4","bassdrum morph",ControlSpec.new(0,1,'lin',0,0.5))
  params:set_action( "bdp4", function(x) engine.morph_kick(x) end)
  params:add_control("bdp5","bassdrum model",ControlSpec.new(0,1,'lin',0,0))
  params:set_action( "bdp5", function(x) engine.model_kick(x) end)
  params:add_control("bdlvl","bassdrum level",ControlSpec.new(0,1,'lin',0,0.6))
  params:set_action( "bdlvl", function(x) engine.level_kick(x) end)
  
  params:add_separator()
  params:add_control("sdp1","snaredrum pitch",ControlSpec.new(0,127,'lin',1,32))
  params:set_action( "sdp1", function(x) engine.pitch_snare(x) end)
  params:add_control("sdp2","snaredrum harmonics",ControlSpec.new(0,1,'lin',0,0.1))
  params:set_action( "sdp2", function(x) engine.harm_snare(x) end)
  params:add_control("sdp3","snaredrum timbre",ControlSpec.new(0,1,'lin',0,0.5))
  params:set_action( "sdp3", function(x) engine.timbre_snare(x) end)
  params:add_control("sdp4","snaredrum morph",ControlSpec.new(0,1,'lin',0,0.5))
  params:set_action( "sdp4", function(x) engine.morph_snare(x) end)
  params:add_control("sdp5","snaredrum model",ControlSpec.new(0,1,'lin',0,0))
  params:set_action( "sdp5", function(x) engine.model_snare(x) end)
  params:add_control("sdlvl","snaredrum level",ControlSpec.new(0,1,'lin',0,1))
  params:set_action( "sdlvl", function(x) engine.level_snare(x) end)
  
  params:add_separator()
  params:add_control("hhp1","hat pitch",ControlSpec.new(0,127,'lin',1,32))
  params:set_action( "hhp1", function(x) engine.pitch_hat(x) end)
  params:add_control("hhp2","hat harmonics",ControlSpec.new(0,1,'lin',0,0.1))
  params:set_action( "hhp2", function(x) engine.harm_hat(x) end)
  params:add_control("hhp3","hat timbre",ControlSpec.new(0,1,'lin',0,0.5))
  params:set_action( "hhp3", function(x) engine.timbre_hat(x) end)
  params:add_control("hhp4","hat morph",ControlSpec.new(0,1,'lin',0,0.5))
  params:set_action( "hhp4", function(x) engine.morph_hat(x) end)
  params:add_control("hhp5","hat model",ControlSpec.new(0,1,'lin',0,0))
  params:set_action( "hhp5", function(x) engine.model_hat(x) end)
  params:add_control("hhlvl","hat level",ControlSpec.new(0,1,'lin',0,0.75))
  params:set_action( "hhlvl", function(x) engine.level_hat(x) end)

Might be useful to someone.

1 Like

Does anyone want to test an install script for the ugens?

I’m curious is this is a reasonable approach to installing these things?

new version (May 7, 2020) mi-ugens-install.lua (1.8 KB)

after you run the script - check /home/we/.local/share/SuperCollider/Extensions for the ugens.

The script ran fine, but after reset i got error: SUPERCOLLIDER FAIL on boot with this in the norns.local error log:

Cannot connect to server request channel
jack server is not running or cannot be started
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
terminate called without an active exception
could not initialize audio.
Server 'localhost' exited with exit code 0.

EDIT: after a proper sleep and boot, things seemed fine. Interesting that System > Reset alone didn’t work as it usually does :woman_shrugging:

huh…

This part I understand to mean that Jack crashed

JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock

Did you reboot… Ah yes.

So yeah - I believe SYSTEM>RESET does not restart Jack, but I could be wrong there.

1 Like

just updated github with some work on plaits - along with previous interface stuff on clouds and elements. https://github.com/okyeron/mi-eng

trying out some UI lib things for interface on the basic scripts. Let me know what you think

Super weird error – whenever I instantiate the MiRings synth, all of norns’s keys stop doing anything. Encoders work fine, just keys stop. All keys: K1, K2, K3. Happens both in the branch you made adding Rings to Pedalboard, and in your mi-eng repo’s rings.lua script. :thinking: no visible errors in maiden, in either lua or SC

more detail?

Like K1 won’t take you back to the menu screen?

OG hardware norns?

Yup: K1 doesn’t take to menu in either Pedalboard or mi-eng/rings. In Pedalboard, on a pedal screen, K2 and K3 no longer navigate between tabs, and on the main page K2 no longer jumps to the pedal’s page nor does K3 confirm a pedal switch. And yes, ~1-month old new norns from monome’s shop.

Baffled here. I don’t see that on my Fates (boots up Shield… gotta run update and then test)

No idea why that would happen - esp in pedalboard since it’s using mostly code copied from your other pedals.

How could the SC stuff kill the buttons?

Yeah the fact that it happens to K1, and happens in both my script and yours… no idea what’s going on. Also probably worth noting that as far as I can tell the sound it makes on mine is also not what I’d expect at all. Much glitchier / weirder (and again – same behavior both in your mi-eng/rings script and Pedalboard)

one of the controlspec calls is hosing something?

(the ugen itself might be wonky as the author said they are work in progress) …Or maybe I did a crap job of setting up the engine?

Did get the jack error just now after installing pedalboard.

can confirm - same behavior on shield. maybe something odd about the compiled binaries on Pi3? (fates is pi4) (although I’m using the binaries I compiled on the shield)

Some kind of lua error goes by when running pedalboard the first time, but it gets lost in the scrollback - something about upvalue pages

Pushed an update to github for the UGens - looks like there was an error in the Rings class file causing norns buttons to go unresponsive.

So - if you want to fix that,

cd ~/.local/share/SuperCollider/Extensions
rm -r Mi*

then re-run the install script

4 Likes

Aw crap - rings is broken. Other stuff behaving badly.

Might wanna hold off on this for the moment while I get it sorted out

everytime you receive these messages, open:
System Preference -> Security & Privacy -> General.
you will find the “MiMu.scx” as shown in the screenshot. then unlock the panel and press “allow”.

2 Likes

I tried intalling them yesterday, but I get “Error loading” message for everything but Rings. Rings loads fine but audio seems indeed broken.
The lua install script is a nice idea :slight_smile:

probably need to restart (SLEEP, power off, power on)?

(or ;restart in both the matron and SC tabs in maiden)