Lojik v1.1.1 - Sequencers and logical operators for v0.6

Hello all let me introduce Lojik! A collection of bespoke units for the latest v0.6 firmware, using the amazing, newly available, DSP layer. This collection includes a bunch of logical operators as well as some excellent new sequencer primitives.

These units all perform as well as the built-in core units, using < 1-2% CPU each.

Trig - Convert the input signal to a trigger.
Not - Is the input signal less than or equal to zero?
And - Is the input signal and gate input greater than zero?
Or - Is the input signal or gate input greater than zero?
Pick - Output input on gate low, alt on gate high.
Wait - Arm to wait a number of input pulses, invert to pass a number of pulses.
Latch - An SR latch, set it high and reset it low.
DLatch - A data latch, essentially just a sample and hold.
Pulse - A square wave oscillator.
Euclid - A euclidean rhythm generator.
euclid euclid-ext
Chance - A probabilistic gate. Randomly pass clock pulses based on a probability.

:star: Sequencers :star:
Register - A shift register that can hold up to 64 steps of arbitrary voltages. Contains a built in random source to sample from.
Turing - Basically just a register with a scale quantizer in front of it, ideal for quickly generating V/Oct sequences.
Seq - A step sequencer

:star2: Download from the hub


The game is on :star_struck: :boom:


Quick preview from my new mix tape :wink: Sorry about the bad quality ha

Explanation in case it’s hard to see:

  1. Make a triangle oscillator.
  2. Add a Turing to the V/Oct, seed with random values by toggling “write”
  3. Add another triangle oscillator to the sync input.
  4. Track that V/Oct with the same sequence from Turing.
  5. Adjust to taste.
  6. Add a filter + envelope
  7. Add a Register to the freq input of the first oscillator. Seed with random values to add variation to the base sequence.

Custom graphics?? Simply wonderful…

Love your display of muscle memory in this demo, haha. That turing unit is going to compete in usefulness with Accent’s scaled random for sure.

I believe I may have a bug report however: the recorded voltages disappear when you move the unit or a parent unit (like an oscillator) into a mixer Steps to reproduce:

  • Load up a Turing unit, either standalone or inside another unit
  • Record some voltages
  • Select the unit (or parent unit) and hit S3 (move into Mixer)

This platform is just getting started, I’m so excited :cowboy_hat_face:

more low level units! YAY!!! love it!!!

Fantastic @tomf, thanks for these! Over the years I’ve thought about ways to do a shift register but could never come up with a way that was worth the CPU it was going to take. Nice to see you solve it so quickly after getting access to the c++ layer - it’s real now. :slight_smile:

Haha, I was thinking the same thing - Tom is bewilderingly fast on that 301 panel!

Oh by the way @Joe, did you notice those categories in tomf’s package? :wink: :wink: :sweat_smile: Pretty organized guy!

1 Like

Without trying to derail this topic too much, do you think that’s a better approach - keeping the non-core units in their own separate categories rather than mixing them with the built-ins?

I see what you mean. I was assuming that the categories from different packages would always be separate from those in the same category of other packages, but probably the reason why they are separate is that “Gates” and “Data” did not exist as categories yet. Are we sure about that? Why do the core units not have something like “Accents:” or “Lojik:” prepended? From my perspective, it would be very handy to have something like “Accents: oscillators”, then I would know where to find Joe’s oscillators, separate from the Core oscillators.

Maybe it is time for a package distribution, management and organization thread. There are some discussions about this topic scattered around several V0.6 threads.


Ha that’s actually just the built in scale quantizer view, copied it straight out of the ScaleQuantizer unit

What you don’t see is the three other takes I did where I messed up and had to start over :slight_smile:

Yea these units don’t serialize properly at the moment so they’ll drop their sequences when deleted (or moved around), I’ll fix that shortly.

Same. I coded one up in the middle layer using latches and gates but it was super difficult, used a ton of CPU, and best case could run at frame rate. These on the other hand are much easier to code, use practically no CPU, and can run at audio rate easily!

1 Like

With Turing I think what I was hearing was that new values (write) were constrained to 1 octave (0.1)? A nice enhancement might be some kind of range slider. Might already be on your list.

Got you covered, press enter over the write toggle to show the input gain control :wink:

Screen Shot 2021-03-10 at 11.45.50 AM

This also reveals the “scatter” toggle. Disable to sample from the unit input instead of the random source. The input gain is applied either way.

1 Like

Great! I think you use this paradigm of tucking views in behind controls in a few of your other units. I always forget to look there - I guess because the factory units don’t do that. I like it though - it’s one less click than going through the header menu just to change views.

Yea it’s a shame they don’t show up in the scope view though. I try to keep the base unit controls to just a single page (< 5 controls) and keep the most interesting / touchable things on top. In this case I would have put input gain at the top level but needed two ply for the scale view instead. The scatter definitely belongs there though since most of the time you just want it on or off, not gonna change frequently.

1 Like

This looks extremely dope. You buried the lede on register/turing units and I almost missed them until I watched your video. Wow those fingers, didn’t realize the 301 could respond that quickly to user input!

1 Like

I guess that’s the pro of putting view switching in the header menu; you don’t lose the scope functionality for that control and can observe the unit output while adjusting it. Might also be a little less guesswork as to what views exist and which controls have additional views of controls behind them. The pro of view switching with controls is that it somehow feels a little “closer”.

Might be a better discussion in one of the dev threads, but it’s interesting to me and it came up here… :slight_smile:


Was just thinking btw, using a register + counter is everything you need to build an SH101-style sequencer. Might add that as a built in while I’m at it if I can get the interface right.


hey @tomf , finally got some time to check new stuff!
i was wondering, is there any difference between dlatch and a sample and hold factory unit? what does the reset do?
in the register, how do you access the random generator? just sending gates to the WRITE input?

1 Like

Hey yea that’s a great question, I kinda forgot how I did it but just checked.

clock - Sample a value on trigger
reset - Sample a value on gate high

So if you just hit the clock it’s a sample and hold. If you toggle the reset then it becomes a track and hold.

One key difference between the factory unit is that DLatches can be chained to create a simple form of the register unit. Put one after the other and give them all the same clock and they will delay the incoming signal by that clock, you could make a clock divider for example (optionally tie the last DLatch back to the input of the first :wink: ). This works well at frame rate but falls apart at audio rate, this is one of the reasons why I built the register separately; to handle audio-rate dlatches…

For the register, the random generator is enabled by scatter inside the write sub-view. When this is on, the register samples from a random source (white noise). When disabled it samples from the unit input. Either way the input is multiplied by the gain value before sampling so you can tame the input. scatter is enabled by default.

To be clear about the way the register works, it will always operate synced to the step input, but what happens depends on which gates are high. If write is high it will sample, if shift is high it will shift, and if reset is high it will “reset” (go back to the first slot).