Recreating a horse/fourses oscillator.....

Rodrigo's icon

Rodrigo

4月 01 2013 | 10:08 午後

Bit of an oddball question here.

I'm trying to recreate a 'horse' oscillator by ciat-lonbarde/shbobo. It was originally in an analog circuit by Peter Blasser (http://www.ciat-lonbarde.net/fyrall/paperz/fourses/index.html).

It's a bit funky to understand, but the simple explanation is as follows (from his newer digital instrument (shbobo.net).
(more info on all the different opcodes here : https://docs.google.com/document/d/1SexTfdaEcz6AtdOrBkiTWPSAK-jKj-NwFLZM0K0v6UQ/pub
)

horse [horse] nume nume deno deno mul add
Description: an oscillator with independently settable rise and fall and upper/lower boundaries
nume: sets the rate at which the oscillator rises
deno: sets the rate at which the oscillator falls
nume: sets the oscillator’s upper boundary (height)
deno: sets the oscillator’s lower boundary (depth)

So reducing that down, it's basically a sawtooth waveform that you can vary it's orientation (phase?). I can visualise what that means, but I've not done that in Max. In his version the up/down ramps are controllable/modulated independently.

Next is the upper/lower boundary thing. It's not really DC offset, just having the upper and lower halves of the waveform have different limits. I know how to limit/clip the waveform, but not asymmetrically, though this isn't clipping, it's scaling.

Anyone have any thoughts or suggestions as to what objects to look at for recreating something like this?

Roman Thilenius's icon

Roman Thilenius

4月 02 2013 | 12:11 午前

these "fourses paperz" are definetly the most scientific schemata i ever saw.
i would probably use [jit.lcd] to build this type of oscillator.

Rodrigo's icon

Rodrigo

4月 02 2013 | 12:27 午前

lol.

i was hesitant to post the paper bit of it, but rest assured, it's analog (and digital) counterpart sound pretty effing good.

do you mean manually draw the waveform in jit.lcd?

ideally id just produce four numbers, one for each of the parameters (up ramp, down ramp, top boundary, bottom boundary), which can then get modulated independently.

Lance Ford Jones's icon

Lance Ford Jones

4月 02 2013 | 11:39 午前

I read the second link first and was thinking "I wish I had an image or diagram of this" and then I looked at the first link - what moon of what planet was this found on? :-)

This looks really interesting. Do you have a sound sample you could post?

NOTE: There was a little problem with the first link:
http://www.ciat-lonbarde.net/fyrall/paperz/fourses/index.html

Rodrigo's icon

Rodrigo

4月 02 2013 | 2:45 午後

Yeah, funky guy. Smart as a whip though, just a very...esoteric design approach.

Not exactly a clear demo but at 2:20 in this vide you can see me controlling the fourses:
https://vimeo.com/21839786

The fourses instrument also has a bunch of 'horse' oscillators all intermodulated, so it's a quite layered/complex sound overall. The cell of recreating something like that would be the single horse oscillator.

There's also this video which has the designer (Peter) and myself performing together, and he's using the digital instrument (likely with some horse/fourses in there, but I can't point out exactly where).
https://vimeo.com/63028340

woyteg's icon

woyteg

4月 02 2013 | 11:02 午後

interesting and funny stuff!! I tried doing something like what you descibed as horse in gen.
Both of these versions are by far not perfect, maybe i even misunderstood a lot there, but maybe you can do something with it. Found it interesting and will work a bit more on it maybe, but since i have to go to sleep now, I thought i send what i have in a tired nonsense post.
The Fourse stuff actually looks much more interesting than the horse one though!

Max Patch
Copy patch and select New From Clipboard in Max.

cheers!

Rodrigo's icon

Rodrigo

4月 02 2013 | 11:32 午後

That sounds pretty slick, though I'm not sure I understand the parameters.

From the drawings and his explanation the upspeed/downspeed effect the orientation of a sawtooth. Either ramp down, or ramp up, and gradations in between. Modulating them independently would be effect pitch and timbre, as there's no direct control over period. The period/pitch is a byproduct of the combination of the up/downramp.

The lower/upper limit, I think, is where the the up/downspeed terminate. I imagine that to mean that having a lower limit of -1 and upper limit of 1 will make a regular waveform.

In fact, a couple recipes:

upspeed 100 / downspeed 100 / lowlimit -1 / uplimit 1 = triangle wave at 200hz
upspeed 10000 / downspeed 440 / lowlimit 0 / uplimit 2 = ramp down sawtooth at 440hz with DC offset of 1 (between 0 and 2)

It's possible my math is wrong there, but I think that's how the parameters are supposed to function.

woyteg's icon

woyteg

4月 02 2013 | 11:42 午後

Ahhh i seee.(still awake, more confusion to add)
I thought about this pitch independent of ramp speed and amplitude stuff.. I thought it would be possible to independently control them at least within given limits if one accepts that the oscillator would halt at max/min levels..
I think what you descibe should actually be a lot easier. mmh.. I'll give that another try tomorrow

Roman Thilenius's icon

Roman Thilenius

4月 03 2013 | 4:46 午前

modulating that part of an analog synthesizer in maxmsp which requires you to create some kind of dynamic wavetable is always the hardest part. it is not possible to think straight in lego, you must find out step by step which kind of process will work best for a certain situation. this is why i have neveer really made an attempt to create something" analog modelling", leave alone something from an existent device.

Rodrigo's icon

Rodrigo

4月 03 2013 | 9:25 午前

Would it require wavetable? In my noobish max thinking I was thinking I could event brute force it by using line~ for each part of the ramp, then scale~ to control each half of the orientation (though there's no split~ object).

I think the analog thing sounds great, and don't mean to fully recreate it, but just to step towards that sound world and then do something more max-y with it.

Wetterberg's icon

Wetterberg

4月 03 2013 | 10:38 午前

line~ might be fun, since we have the curve aspect to it now, too - I guess from the description that the basic circuit is related to the Serge DUSG http://clsound.com/Serge_Dual_Universal_Slope_Generator_files/DUSG-filtered.jpg

- which is essentially a heavily modded envelope, in some respects, but more precisely it's a voltage controlled slew.

...so that's why I'd attempt to start with a pulse train of sorts, scale it, and then slide~ or similar to get the underlying waveform.

Wetterberg's icon

Wetterberg

4月 03 2013 | 11:04 午前

hmmm. Been thinking about this a little bit. Obviously if you drive it with a pulse it will be synced, and you'll lose this free-running "sum time of slopes = frequency" aspect.

Some sort of feedback network of logic gates might be in order. Oh man, this sounds like good fun, actually.

woyteg's icon

woyteg

4月 03 2013 | 3:52 午後

Max Patch
Copy patch and select New From Clipboard in Max.

quit and dirty solution

ak's icon

ak

4月 03 2013 | 10:08 午後

Max Patch
Copy patch and select New From Clipboard in Max.

nice! below an easier way to obtain hysteresis in Gen.

Rodrigo's icon

Rodrigo

4月 03 2013 | 10:20 午後

That seems to work really nicely, though the uplim/lolim seem to both do the same thing (scale the overall signal, rather than each 'side' of it).

Nevermind, getting rid of dcblock did the trick. Awesome!

Rodrigo's icon

Rodrigo

4月 03 2013 | 10:54 午後

Ok, using Andrzej's version, and the text code description of a fourses (below) I recreated a fourses (four horses).

I had to use tapin/tapout as connecting directly killed audio processing. Probably possible to do all four horses inside of a gen to have single sample feedback, but this at least shows something. It's pretty slick sounding in some settings, and I have to say, sounds quite similar to the 'real' one, though the real one has even more things going on.

Text code:
([horse a] ([corp b]) 56 100 ([horse b]))
([horse b] 55 ([corp]) ([horse a]) ([horse c]))
([horse c] ([corp]) 54 ([horse b]) ([horse d]))
([horse d] 10 ([corp b]) ([horse c]) -100)

(corp is the radio antenna, so those are modulators).
Each horse takes 4 variables : upspeed, downspeed, uplim, lolim

Max Patch
Copy patch and select New From Clipboard in Max.

Here's the (sloppy) patch.

Wetterberg's icon

Wetterberg

4月 03 2013 | 11:47 午後

Max Patch
Copy patch and select New From Clipboard in Max.

Rodrigo, how's this? I tried to copy over the interconnects from yours into an all-gen thing.
(this is the first I've ever done in gen, so I'm hoping it's approved - at least it looks pretty on the inside! :) )

Wetterberg's icon

Wetterberg

4月 03 2013 | 11:50 午後

Max Patch
Copy patch and select New From Clipboard in Max.

hmm. On second thought, this one with [dcblock] on just the outputs, not the inter-feedback is a lot better to work with:

Rodrigo's icon

Rodrigo

4月 03 2013 | 11:56 午後

That's super awesome...as shit!

I kind of like the un-dcblocked, and uncompressed version. It does get a bit wild, but I think that's part of the charm of it.

So responsive and chaotic. Very sweet sounding.

Wetterberg's icon

Wetterberg

4月 04 2013 | 12:00 午前

I like it chaotic, don't get me wrong (you tend to get that with four oscs in a feedback loop) but the dcblocked one just has a ton more sweetspots.

Max Patch
Copy patch and select New From Clipboard in Max.

here's a quick edit with the last presets on it, too:

There's definitely a tweak that needs to get made: Control of each feedback point. Just a * and an input for each, to make this whole thing immensely more playable.

Rodrigo's icon

Rodrigo

4月 04 2013 | 12:08 午前

Hmm, I see what you mean. The dc can push it waaay out of audible range.

Control over feedback would have a nice impact on it. Looking through the fourses doc some more, it looks like there are two sets of these, and the text seems to imply that they sah each other:

"The intersexon freezes the angle of the ZI at the rhythm of the HAI"
(with the ZI and HAI being a 'fourses')

Also looks like any given osc can be be normal, inverted, squared normal, and squared inversion. Not sure how/when that happens.

Lokua's icon

Lokua

4月 04 2013 | 8:26 午前

Dude, it's hard to see at first but if you look a little more closely at the diagram you'll see that you need actual HORSES. Them, and some cyclops-penis crystal geometries. You're welcome.

Rodrigo's icon

Rodrigo

4月 04 2013 | 8:35 午前

Well, obviously!

Actually probing inside the gen it looks that intermodulating after the history object is only intermodulating values of 1 and 2, rather than the actual outputs.

However, when I change all the intermodulations to the += object, it locks the system up.

I basically started off by removing all the outer connections to the modulation points, to be able to control it with very few items 'from the outside', and it wasn't working well. So I probed.

Wetterberg's icon

Wetterberg

4月 04 2013 | 9:38 午前

okay, I think I'm going off on a tangent here, but would people mind if the inputs were normal non-signal connections? That would make it easier to manage - I'm up to 24 inputs (added feedback attenuation at all points), and as far as I remember gen~ only allows 16.

Wetterberg's icon

Wetterberg

4月 04 2013 | 11:52 午前

>Also looks like any given osc can be be normal, inverted, squared normal, and squared inversion. Not sure how/when that happens.

yeah, if you look at the waveform drawings they're all squared off. (I'm skipping that part completely)

Rodrigo's icon

Rodrigo

4月 04 2013 | 2:33 午後

I broke it up to audiorate stuff for intermodulation, but if it's all happening inside gen, it's a moot point.

Wetterberg's icon

Wetterberg

4月 04 2013 | 2:38 午後

Max Patch
Copy patch and select New From Clipboard in Max.

okay, this is about as far as I can bear to take it:

It's got a presentation mode and such, and some nice feedback controls, deliberately made difficult to mute completely, hehe. Hope someone finds it useful.

Rodrigo's icon

Rodrigo

4月 04 2013 | 2:42 午後

Is there a missing genfile or something? It's through up a bunch of gen~ : patchcord outlet out of range messages, and the gen~ bit is the default gen patcher when one instantiates gen.

Wetterberg's icon

Wetterberg

4月 04 2013 | 2:45 午後

ah shit, newb mistake, yeah. Hang on, lemme rip it out and put it in without the file.

Wetterberg's icon

Wetterberg

4月 04 2013 | 2:47 午後

Max Patch
Copy patch and select New From Clipboard in Max.

there - should work?

roger.carruthers's icon

roger.carruthers

4月 04 2013 | 2:49 午後

"Could not find gen patcher rod_horse"
Also with earlier versions "operator/abstraction latch not found in gen domain dsp.gen" - where are the gen objects kept?
Cheers
Roger

Rodrigo's icon

Rodrigo

4月 04 2013 | 2:59 午後

@wetterberg,

that's awesome!
Do you mind if I wrap an interface/UI for the shnth on this and share it on the shnth/shbobo docs? (crediting you of course)

Wetterberg's icon

Wetterberg

4月 04 2013 | 3:17 午後

not at all - do remember to credit Andrzej as well for the gen :)

It's a shame, I was a tester on the shbobo (?), but the hardware didn't function with my computer :( What a great little box.

Rodrigo's icon

Rodrigo

4月 04 2013 | 3:57 午後

Looks like I might have to unpack a bunch of the parameters to do signal rate smooth as using wild modulation inputs it gets reaaaally step/blippy.

I can't seem to find how many ins you can have in the help or reference. You sure it's 16?

Wetterberg's icon

Wetterberg

4月 04 2013 | 4:09 午後

yep, just tested it. 16.

I quite dig it as is, but I'm wondering if the smoothing can't be applied internally? Isn't ithere a quick mix + history trick to get cheap lpf'ing?

Rodrigo's icon

Rodrigo

4月 04 2013 | 4:11 午後

Hmm, that would be ideal. Coming in with the shbobo data, which is only 255unit resolution, and at 10ms, sounds pretty shit controlling anything.

roger.carruthers's icon

roger.carruthers

4月 04 2013 | 6:43 午後

Any idea about that latch abstraction? My curiosity is peaked..
Cheers
Roger

ak's icon

ak

4月 04 2013 | 6:59 午後

@roger: update to 6.1.x (or in this very case [latch] can be simulated with [sah 0] )

Rodrigo's icon

Rodrigo

4月 04 2013 | 9:51 午後

So is there a line~ equivalent in genland?

Like +=/history and some logic to go to the new value over x amount of samples or something?

bertrandfraysse's icon

bertrandfraysse

4月 04 2013 | 10:51 午後

Max Patch
Copy patch and select New From Clipboard in Max.

here is the mix + history trick to smooth transitions.

Rodrigo's icon

Rodrigo

4月 04 2013 | 11:07 午後

That works really well! Though with a patch that's 24 inlets deep, it's made a brutal mess of the gen code. Now time to tidy....

Wetterberg's icon

Wetterberg

4月 05 2013 | 1:28 午後

Max Patch
Copy patch and select New From Clipboard in Max.

I hope you don't mind I had a quick go at it - not what I'd call... "tidy", but it's readable, at least.

Wetterberg's icon

Wetterberg

4月 05 2013 | 1:30 午後

wow, this patch is inexpensive! It's a steady 3-4% cpu here, even after all that audio-rate smoothing. I'm loving it!

If you crank up the smoothing to max it creeps along in a lovely way, it takes what seems like over a minute to get to its destination...

stkr's icon

stkr

4月 05 2013 | 1:36 午後

hi rodrigo and all,
thanks very much for this thread - has been a lot of fun to follow. wish i had more time right now to join in.

Max Patch
Copy patch and select New From Clipboard in Max.

just a couple contributions here from me. first of all, i think you need to start using subpatches and/or abstractions in gen~, especially as there is so much repeated here. secondly, here are a couple more effective parameter smoothers; i use my 'pSmoothC' all the time in gen~, as it does not impose ramp times but cleverly smooths, but if you want 'line' functionality i include that here too (it is an example posted to the forum by graham wakefield some time ago).

.

Wetterberg's icon

Wetterberg

4月 05 2013 | 2:52 午後

haha, I was hoping you'd chime in.

In this particular case I actively sought to present all objects straight away. This is the first patch I've done in gen~ (and I only did a tiny bit of it, the copious copying of objects).

Smoothers, eh? Will investigate! Thanks for sharing, man.

Rodrigo's icon

Rodrigo

4月 05 2013 | 5:06 午後

@stkr
I didn't even know you could do subpatch/abstractions in gen... That's super handy.

Before I set off replacing everything in the patch with the abstractions, have you started to do the same wetterberg? I started tidying the patch last night only to see you posted one this morning, so I don't want to duplicate work!

Wetterberg's icon

Wetterberg

4月 05 2013 | 5:13 午後

okay, I'm diving into modularizing the gen~  section. Hey devs, I'll buy you a beer if you let us encapsulate soon... I never realized how important that is for reducing complexity.

Also, it seems I'll need additional [history] objects or other delays to do the feedback, as soon as I've got things packed away?

Wetterberg's icon

Wetterberg

4月 05 2013 | 5:15 午後

yeah I'm terribly sorry, I didn't know your status there. Also, time zones suck.

Right now the subpatch thing is really kicking my ass on this one.

Rodrigo's icon

Rodrigo

4月 05 2013 | 5:17 午後

No no it's fine. I didn't think to post it 'in progress' last night, so it's on me. Curious to see how the compartmentalised version would look.

Also being able to do comment comments in gen like you can in codebox would be super useful. For a gen file as chunky as this one, being able to label things would be great.

Wetterberg's icon

Wetterberg

4月 05 2013 | 6:57 午後

Max Patch
Copy patch and select New From Clipboard in Max.

okay, how about this for a prettied up subpatch rig? I've tried to stick everything in subpatchers, so as to avoid big zip files and such for abstractions:

Rodrigo's icon

Rodrigo

4月 05 2013 | 7:35 午後

Nice! Super tidy

Here's the patch I've been working on so far. Not much in terms of GUI. It's all pushed onto the shnth.

Max Patch
Copy patch and select New From Clipboard in Max.

The antennas control the feedback, buttons randomize the osc range values, and I'm still working out how to implement the bars.

Wetterberg's icon

Wetterberg

4月 05 2013 | 7:52 午後

aw shit yeah. Looks great. I'd love to see some up close performance things done with it.

Wetterberg's icon

Wetterberg

4月 06 2013 | 10:17 午後

oh btw, Rodrigo, could you update the thread title to be a [sharing] one? :)

Rodrigo's icon

Rodrigo

4月 06 2013 | 10:25 午後

There doesn't appear to be an edit button on my of my posts. I've noticed this across the forum that there appears to be an edit window of time, then the edit button goes away.
Unless there's something I'm missing...

artmusicsouth's icon

artmusicsouth

4月 07 2013 | 12:43 午後

I want to hear this!

This looks so awesome but I keep getting this message :

"operator/abstraction latch not found in gen domain dsp.gen"

I do not have gen installed. Is that the issue?

Rodrigo's icon

Rodrigo

4月 07 2013 | 12:44 午後

Apparently you need to install 6.1.1
You don't need the full license of gen to use it, only to edit it. But latch, apparently, is new.

Rodrigo's icon

Rodrigo

4月 15 2013 | 1:09 午前

Here's the done patch. You can use it without a Shnth by clicking in the bottom left. That randomizes a bunch of values. Not as expressive as using the Shnth as a controller, but still gives you an idea of what's what.

I want to try to expand it, and get some random repatching stuff going on, but not sure how to incorporate matrix~ into the mix, as you can only have 16 I/O in a gen, and looks like you can't have send~/receive~ inside of gen, so I don't know how it would be possible to randomly repatch a bunch of the stuff inside, but one thing at a time.

5426.c7fourses.maxpat
Max Patch
Wetterberg's icon

Wetterberg

4月 15 2013 | 11:25 午前

does anybody have a [codebox] version of matrix~? That'd be handy...!

jvkr's icon

jvkr

4月 08 2016 | 12:42 午後

Came across that intriguing image and realized I'd seen it before.
Here is an implementation in codebox, the simplest version possible.

History sawS(0.9);
History sawA(0.6);
History sawT(0.4);
History sawB(0.1);

History addS(0.011);
History addA(0.01);
History addT(0.009);
History addB(0.0103);

if (sawS >= 1) {
    addS = -abs(addS);
}

if (sawA >= sawS) {
    addS = abs(addS);
    addA = -abs(addA);
}

if (sawT >= sawA) {
    addA = abs(addA);
    addT = -abs(addT);
}

if (sawB >= sawT) {
    addT = abs(addT);
    addB = -abs(addB);
}

if (sawB
    addB = abs(addB);
}

out1 = sawS;
out2 = sawA;
out3 = sawT;
out4 = sawB;

sawS = clip(sawS + addS, sawA, 1);
sawA = clip(sawA + addA, sawT, sawS);
sawT = clip(sawT + addT, sawB, sawA);
sawB = clip(sawB + addB, 0, sawT);

oli larkin's icon

oli larkin

7月 11 2019 | 10:40 午前

ported this to run on the web with iPlug2: https://olilarkin.github.io/fourses/

Wetterberg's icon

Wetterberg

4月 18 2020 | 4:43 午後

Bumping this lovely thread because I found a CeReNeM video of James Bradbury using it for further research:

https://www.youtube.com/watch?v=Ro30O9u7l8M

James Bradbury's icon

James Bradbury

5月 06 2020 | 6:43 午後

Funny enough, I've come back to the thread to learn more...!

Rodrigo's icon

Rodrigo

5月 06 2020 | 7:55 午後

I too am down for revisiting this as I now have the euro version, and it's stripped back in terms of what it does, but it could make for a great thing to implement in a broader system.