The Zebra Scripting Thread

Official support for: u-he.com
Post Reply New Topic
RELATED
PRODUCTS

Post

I guess as Urs is planning to be doing some scripting docs at this point in time, I'll put in a request for a little pre-documentation scripting help for when he gets back...

Basically, I want to do a script that will randomise select parameters for Osc1 each time you run it, as a quick way of generating random different tone ideas. Including stuff like waveforms, wave knob, osc FX, phase, sync settings that kind of stuff. The few scripts already out there don't really contain enough info to reverse engineer this stuff yet.

So you could say load a 2-osc pad sound from the presets, you could flip through random osc scripts which would give you the same pad sound but just modify the osc parameters for some quick different tone settings.

Obviously, in time we're going to get some more sophisticated randomiser scripts and so on (I'm not too keen on *random* randomisers, but more intelligent ones can be very cool) but for now, this would be fun.

So if Urs can get us started on how to access some of the Osc1 parameters from a script, and maybe the names of how they are referenced, that'd be appreciated. If not, I'll wait for the docs, no probs.

Is there a way to get Z2 to dump out all the internal parameter names and data structures to a text file already?

Other scripts that would be cool include (some of these might not be possible from scripting alone, but I'll mention them anyway):

- "Lock" all parameters except certain modules so you could browse the presets but only be loading in the unlocked modules - so for example, you could lock all parameters except the FX so you could select the different presets and only load their effects settings into the current patch.

- Randomise All Oscillators

- Randomise Filters

- Randomise Grid Order

- "Evolve" patches

- Crossbreed two different patches (I know these things are a bit more tricky because of differences in patch architecture)

- "Pad-ify" (set all EG's to pad-type settings)

- "Percussify" (set all EG's to drum-type envelope settings)

- Mod wheel->Flter (quickly set up mod wheel mod routings to all filter modules)

- DX-ify (Add FMO's in a random config, and set random ratios/FM amounts/scaling settings and so on)

- Analogify (Add random small amounts of filter drives, saturation, detuning and so on)

These are a few I can think of off the top of my head that would be cool, I'm sure other people can think of plenty more ideas...
Image

Post

beej wrote:I guess as Urs is planning to be doing some scripting docs at this point in time, I'll put in a request for a little pre-documentation scripting help for when he gets back...So if Urs can get us started on how to access some of the Osc1 parameters from a script, and maybe the names of how they are referenced, that'd be appreciated.
Yes, that would be great. I'm looking forward to getting my teeth into "ZScript" (does it already have a name?)
"Lock" all parameters except certain modules...
See Virus Control - works very well, BTW.
- Randomise Grid Order
Which grid do you mean? Wave order?
- "Evolve" patches
- Crossbreed two different patches
- "Pad-ify" (set all EG's to pad-type settings)
- "Percussify" (set all EG's to drum-type envelope settings)
- Mod wheel->Flter (quickly set up mod wheel mod routings to all filter modules)
- DX-ify (Add FMO's in a random config, and set random ratios/FM amounts/scaling settings and so on)
I think such functions might take more time and effort to get right than they are worth.
But if 3rd parties want to go there... :D
- Analogify (Add random small amounts of filter drives, saturation, detuning and so on)
Yes, please. Do you already know whether ZScript is suitable for the following extra functionality? :

* Copy/paste module parameters. Entire oscillators/noise generators, individual osc waves, filters/combs, envelopes, arpeggios, complete effects, individual effects, pad assignments...
* Convert waves from one mode to another
* Change the root path of the patch library.
* "Compactify" the patching grids

Post

Howard wrote:
"Lock" all parameters except certain modules...
See Virus Control - works very well, BTW.
Yeah, I've just seen that, it's the kind of thing I had in mind. These kinds of functions are a nice easy way to get new sound ideas quickly without much effort, so I support them wholeheartedly! :)
Howard wrote:
- Randomise Grid Order
Which grid do you mean? Wave order?
The main module grid where you insert modules and wire them up. Randomising the positions and orders of the modules and envelope assignments (with certain limitations) might be interesting,
Howard wrote: * Copy/paste module parameters. Entire oscillators/noise generators, individual osc waves, filters/combs, envelopes, arpeggios, complete effects, individual effects, pad assignments...
Yeah, that's an important one, but is probably more in need of a standard way of handling it in the gui - maybe for a new Zebra version...
Howard wrote: * Convert waves from one mode to another
Nice idea!
Image

Post

All of these ideas might work, except for crossbreeding patches... the scripting will not have access to actual files, it only has access to data that's already loaded into Zebra...

Adding support for filesystem functions (open, read, write...) would indeed open pandora's box, as this could be abused to create Zebra patches that install malware...

However, one thing to think about is this:

The u-he engine that drives all recent plugins is based on the concept of absolute modularity. This has the advantage that stuff is easy to maintain and it's easy to create a clear design. The disadvantage though is, the modules don't know about each other and there's no entity that could offer functions that work on multiple modules at once.

Now comes the scripting part. A script (like a normal preset) can have access to every parameter in every module at once. So the idea here is, one can add editing functions that can not be done (with reasonable effort) within normal coding.

You could

- grab the last note that was played on the keyboard, i.e. an A, and set up a microtuning table that "quantizes" the whole keyboard to match A minor - like the arpeggiator in Live

- Rotate the Arpeggiator Sequence left or right, so that the first step jumps into the last used slot and vice versa

- For those who want to be able to audition patches without effects, I have planned to add a customizable "standard script" that will always be executed when a preset is loaded. It could just move effects mix/levels to XY4 and set XY4 fully down...

Stuff like that...

... before it goes to next generation where i.e. oscillator waveforms could be calculated in realtime or scripts could be executed upon midi events...

;) Urs

Post

Great stuff!
Image

Post

sounds beautiful.

Post

Would it be possible to randomize patches with a script then?

Post

In case you didn't know, Tarekith, Zebra already comes with a preset that maps random things onto the X/Y controls and you can play with them. It's "UH Random XY" in the "Zebra Scripts" folder.

Post

Thanks I didn't know that, nor see it mentioned in the online manual!

Post

There's also a script Urs posted a while ago that generates random saw waves across the 16 waveslots of an oscillator every time you run it...
Image

Post

Is that on the u-he site?

Post

Tarekith wrote:Is that on the u-he site?
Urs wrote:Hehehe...

here's another one... and it changes slightly each time you load it!

I call it "SawRand.h2p"

Code: Select all

#defaults=no
#cm=OSC
Wave=2
<?

float Wave[ 128 ];

float filter = 0.2f;

for ( int table = 1; table <= 16; table++ )
{
	float saw = 1.0f;
	float saw_inc = -2.0f/127.0f;
	float out = 1.0f;

	for ( int i = 0; i < 64; i++ )
	{
		out *= (1.f - filter);
		out += saw * filter * rand(filter * -0.25f, filter * 2.f);
		Wave[ i ] = out;
		Wave[ 127 - i ] = -out;
		saw += saw_inc;
	}
	
	filter *= 1.12f;

	Selected.WaveTable.set( table, Wave );
	
}

?>
I dont think he has posted it on the web site yet. But it would be nice with a link to different scripts that users can try out.

Regards

Replicator

Post

Yo, I think I'll start on the scripting docs soonishly... this will include a lot of sample scripts, naturally.

But I think there's also need for improvement on the implementation side, such as an output facility that reports errors and debug messages... we'll see...

Later,

;) Urs

Post

Ooh, I've just remembered that you can save patches in h2p extended format, which might give me some scripting clues to access those parameters... ;)
Image

Post

beej wrote:Ooh, I've just remembered that you can save patches in h2p extended format, which might give me some scripting clues to access those parameters... ;)
Depends...

Actually a parameter should always have the name that's shown on the big display when you turn a knob.

And then there are complex parameters... hmmm... some of these can only be set at the moment, such as MSEGs...

However, here are some findings in my test script folder:

Code: Select all

#defaults=no
<?

Grid.clear();

Grid.setCell( 0, 5, Filter[ 2 ].id, 0, 0 );

?>
Two hints here:

- getting the ID of a module
- using that ID to put something in a grid

Parameters for setCell: column, row, ModuleID, input channel, side chain

Take care though... dunno if this could be used in malicious ways...

Code: Select all

#defaults=no
<?


float stepDuration = 1.0;
float fade = 0.5;


float levels[ 16 ] =  { 1.0, 0.1, 0.5, 0.0,
						1.0, 0.0, 0.5, 0.0,
						1.0, 0.0, 0.5, 0.0,
						1.0, 0.0, 0.5, 0.0 
					};

float value = 0.f;

float fadeIn = stepDuration * fade;
float levelTime = stepDuration - fadeIn;


MSEG1.setSegment( 1, value, fadeIn, -1.0, 0 );

for ( int i = 1; i <= 16; i++ )
{	

	value = levels[ i - 1 ];
	
	MSEG1.setSegment( i * 2, value, levelTime, 0.0, 0 );
	MSEG1.setSegment( i * 2 + 1, value, fadeIn, -1.0, 0 );

}


?>
This one takes an array and builds a step sequence in MSEG1. If you use "Selected" (or just "MSEG" without number?) instead of MSEG1, you can put it in the MSEG presets folder and load it into whatever MSEG you want.

Code: Select all

#defaults=no
<?

float a = 0;
float b = 1;

int count = 0;

float testFunc( int inOne, float inTwo, int inPotenz )
{
	if( inOne >= inPotenz ) return (inTwo);
	
	count++;
	
	inTwo *= 2.f;
	
	float out = testFunc( inOne + 1, inTwo, inPotenz );
	
	return (out);
}

a = testFunc( 0, b, 16 );

?>
(not sure if the last one is still up to the correct syntax...)

There are still some dead spots though:

- Microtuning table is not yet accessible
- Key/Velocity Zones are dark yet
- Parameters that still have a space in their names...
- spline based oscillator waveforms

Most importantly, there is still no support for literals. Thus parameters that take text as input (i.e. xy-labels) can not be scripted. I'll be working out a simple way for this though...

Later,

;) Urs

Post Reply

Return to “u-he”