Dead Man's Catch modified firmware for Peaks


The clock divider is easy. The clock multiplier could re-use the Tap LFO pattern predictor code to work out the frequency, and then multiply it. So in fact, it would be a variant of the existing Tap LFO mode. Should be doable. I agree, it makes sense.

The other thing that might make sense for peaks is a version of the Perlin Pattern Generator. It could be internally clocked, with the trigger input for that channel acting as a reset, or it could be externally clocked, but then no reset - thus two variations. All other parameters just set by the 4 knobs.


Cool! I thought it made sense to have a clock-manipulator option for Peaks. I should have thought of that earlier.

Re. the PPG… well, I guess Frank isn’t going to produce it, given his near silence for some time now, so probably wouldn’t be stepping on his toes there.

Frank was thinking of implementing it using an 8bit Picaxe chip, which would severely limit the possibilities. The Peaks processor may make it possible to do realtime 2 or 3D Perlin Noise with interpolation, at a reasonable rate. The question is, would the Peaks very limited UI provide enough controls to make it useable.

If the hardware could cope with it, I’d suggest a 3D variant of the Perlin algorithm, with two parameters in Dual mode; X-Axis Scale, and Z position.
In Expert mode, you could map the 4 knobs to X, Y and Z position, and Scale.

Could we work on this together? I would really like to do a standalone Perlin-based module of my own, so I’d really love to see how well this would work on existing hardware.



@toneburst, yes, happy to collaborate, just e-mail or PM me. The Cortex M3 processor in Peaks doesn’t have hardware floating point arithmetic, but I don’t think audio-rate Perlin noise is required, so it should be fast enough, and software maths libraries can be used if integer arithmetic isn’t sufficient. I need to think more about how you and Frank were proposing to implement it. One possibility for a 3D Perlin texture is to use the 4 knobs to set the start and end points of a transection of the texture - viewed from above, you are setting a start and end point of a straight line journey across the terrain, and measuring the height at each point on the journey. Non-linear variations would be possible. No idea if any of these thing produce interesting or useful results. Probably best to try a range of ideas out using Python or similar first.

I’m also interested in implementing this on the excellent Ornament + Crime module by Max Stadler (aka mxmxmx on MW). It has four gate and four 12-bit ADC inputs, two encoders, two push buttons, an OLED display (so a 3D Perlin texture could even be visualised…) and four 16-bit DAC outputs - thus multiple, or correlated Perlin noise CVs could be produced. But starting with Peaks is a good idea.

Edit: a linear traverse of a Perlin-random 3D terrain map makes no sense. Better to use a circular “traverse”, or a regular polygonal approximation of a circle, in which case only the centre and the diameter need to specified, so that’s just 3 parameters, not 4. I’ll mock this up in R. Rendering a reasonably sized map in memory on Peaks may be an issue. With 8-bit Z values, a 100x100 terrain/texture requires 10k of RAM, out of only 20k on the chip.


I’m thinking 2D peril noise would probably work fine.

There would be three tweakable parameters:

X-Scale: Sets ‘roughness’/randomness of pattern
Y-Scale: Sets scale of pattern morph as Y Position values change
Y-Position: Morph pattern by changing scan position on Y axis

Scanning would take place along the X axis.

You wouldn’t need to hold a texture in memory, at all. You’d calculate the value at each coordinate in realtime (or on every clock-pulse, see below), while incrementing the lookup position on the X axis. Assuming Peak’s MCU would be up to the task, if course.

I think Frank’s idea of pre-rendering values was just because he thought the Pickaxe chip wouldn’t be able to calculate the value each time.

I think to be useful, though, you’d need to use both input sockets.

The first one would be a clock, driving scanning across the X axis.
The second would be a reset, resetting the X value to 0.

Ideally, I’d like to be able to sample the noise at selectable subdivisions of the clock pulse. Maybe the 4th knob could multiply/divide the clock pulse, acting like an adjustable-rate sample-and hold. Maximum division would produce a more-or-less smooth waveform out, at whatever the maximum rate the MCU could run the Perlin noise algorithm.

In Dual mode, Knob 1 could set X-Scale, and Knob 2 Y-Position, and the noise would be evaluated at the maximum rate with no jack inserted into the input, or when a pulse is received when one is. Or a pulse on the input could reset X to 0.

I think the real USP of using Perlin Noise is that it provides a wide range of patterns, but is repeatable. The same parameter values will always produce the same output. It might even be reducing the race of possibly control values, to make it easier to setup the same pattern again is needed.



There are integer version of the Perlin Noise algorithm around.

This 3D version for Arduino, for example:

I think 3D is overkill, though, especially considering the very limited UI of Peaks.

A lot of the material on Pelin noise assumes you’re using it for texture or terrain-generation (it was originally developed for this, so no surprise there), and are more complicated that we’d need.

I think we’d just need a single octave of 3D Perlin Noise.



This might be useful.



Hi. Perlin noise sounds nice, good idea. I’m not sure why you would want to pre-render it, or even scan it with a parameter though. The basic code is already in Peaks; the LFO with the smoothed random waveform does exactly what you need: draws random values at each cycle and interpolate between them (cosine interpolation). As far as I understand, all you need to do is take multiple instances of such an LFO at multiples of a fundamental frequency and sum them. The amplitude of higher “octaves” determines the “roughness” and the ratio between harmonics the nature of the terrain. One of the difficulty you might run into is normalization: adding all harmonics will likely have an amplitude > 1.0; I came up with a solution on Two-bumps in Tides (in my Github) if you want to have a look.
Incidentally I just implemented it last week for another project. I’m happy to help if you run into trouble.


@mqtthiqs I didn’t realise there was something similar in the stock firmware! Thanks for the tip.

Having said that, from your description, it doesn’t sound quite like Perlin Noise, and the implementation we’ve been discussing is significantly different.

The key point is it’s not actually random, values can be sampled at different rates (like a built in sample and hold), and it can be reset, for looping patterns.

I’d be interested to see your implementation in action. Is it a Euro module you’ve been working on, or something unrelated?

I did quite a lot of work with realtime graphics, in a former life, so I have a particular interest in seeing how algorithms for image-generation can find applications in modular synthesis.



> Is it a Euro module you’ve been working on, or something unrelated?

It’s in XAOC Batumi’s upcoming firmware. I can’t share the source code just now because it’s not out officialy yet, but it will be in a few weeks. The source will be on my Github then.

> The key point is it’s not actually random, values can be sampled at different rates (like a built in sample and hold)

I’m not sure I follow you (you have a purely analog background, don’t you?). There’s a “random” function in Olivier’s library that draws a (pseudo-)random value at each call. You can call it every 1/9600 seconds or every seconds, as you want; in this sense, it can be used as a sample and hold.

> and it can be reset, for looping patterns.

If you want looping, then you’ll have to memorize the n last random values you drew in a ring buffer, and “replay” these values when reset. This might require a significant amount of memory depending on the maximum octave’s frequency, I’d advise to be careful with this feature.


Hmm… I really need to simulate exactly what I had in mind.

You wouldn’t need to memorise anything.

The Perlin noise function is evaluated for a point’s X and Y position. So, if you reset the point to position 0,0, and Scale remains the same, you will always get the same value.

The point of Perlin Noise is that you ALWAYS get the same value out, with the same values for scale and position. So, it’s entirely deterministic, but creates a wide variety of patterns with a small number of parameters.

The nice thing is, you can change parameter values in realtime, and the processor load is exactly the same at every sample. It doesn’t have to store anything in memory except the seed array of random values (which can be stored in static RAM, as it never changes).

The downside is the MCU may not be able to cope with evaluating the noise quickly enough to get a completely smooth output. That’s why I was thinking of it more as a generator of stepped patterns, rather than of smooth LFO-style waveforms. Olivier’s implementation probably works much better for that.



@mqtthiqs I don’t think we’d need more than a single octave of noise. The Scale parameter essentially determines how ‘rough’ the output is.



Ok, I see what you mean. Indeed, it should be easy enough: just reset the seed to its value n samples ago to get an n samples-long loop. I’m pretty sure the MCU will be able to evaluate at least 6-7 octaves.


Now that I’ve read a bit more, I now see that pre-computation is unnecessary - it should be possible to evaluate it on-the-fly in Peaks. The architecture of the Peaks firmware permits each channel to read the trigger input of the other channel, so using both inputs simultaneously isn’t a problem. It would need to be an Easter egg function, because you would want both channels of Peaks to be Perlin generators, both reading both inputs - so they would be clocked and reset identically, but would generate different values due to different parameters.


@mqtthiqs You don’t reset the seed, at least in the classic Perlin implementation. You just reset the lookup coordinates. You scale and offset the coordinates of the lookup position to lookup different values.

My idea would be to scan across the x-axis of the noise field by incrementing the x coordinate of the lookup position by a pre-defined amount on clock pulses (or multiples/divisions of the input clock). The noise field itself is never stored, and the value is only ever calculated for a single coordinate.

The x coordinate value would be scaled by another control, which effectively zooms in/out of the noise field, producing smoother or more jagged sequences of output values. That way, you’d only ever need to evaluate a single octave of noise per-lookup, and you’d still get a range of patterns from apparently random at one end, to very slowly evolving at the other.

The y coordinate would be set by one of the other controls, so changing this value would have the effect of morphing the sequence. The y axis scale would be pre-set to a value that allows for nice smooth morphing of sequences, while still allowing a good variety of different patterns to be produced.



@BennelongBicyclist good to know you think the MCU would be able to cope with it.

There could still be a useful variation for Dual mode (see my earlier post), but it would definitely be more useful to have all four knobs and both inputs, as you say.



@mqtthiqs The advantage of this method over a standard seeded noise is that you can change parameters on the fly, without it having to pre-calculate a load of values every time.



Well, we’ll need to see, but the Monte Carlo bounding box (or cube) method of evaluating the Perlin function for given co-ordinates, as used by the Arduino code you referenced (its the standard approach), seems pretty efficient.


@BennelongBicyclist that’s cool. Most Perlin implementations rely on floating-point maths, as the fractional part of the coordinate determines the interpolation values on the two/three axes (the grid points on the seed array are at integer positions).

It’s obviously possible to massage the algorithm to do the same thing with integer-only coordinates. The maths is a bit beyond me, sadly.



Ok, I don’t understand what you’re trying to do, we seem to be talking about unrelated objects… I guess I’ll leave you to it then… :slight_smile:


@mqtthiqs I think we’re probably just talking about slightly different approaches to essentially the same thing :slight_smile:

If I get a chance, I’ll try and knock up a simulation in JavaScript, or something.