20 characters of thank you!:raised_hands:

1 Like

Hey, when I installed the latest version, upon restart it shows Otis (error: init). The buffer loops work and I can use the parameters page, but I can’t access the “front” page at all, or whatever it’s called (the one where there’s speed and skip buttons for example).

@bereenondo, can you connect to maiden still? If so, connect to maiden and launch the script from there. Post the error message here.

When you say “upon restart” did you mean a restart of the script, or a restart of norns? It requires a restart of Norns.

Sorry for being hasty with my comment, I thought I had the latest version of Norns installed but that was not the case. So after updating the system it works as supposed. Thanks though, can’t wait to give it a proper test.

1 Like

Glad you got it working!

you know what i am going to ask…
can you add ARC for sample rate and bit depth?
maybe Filter Cutoff for each channel on the other two knobs?

just spent a few mins with it tonight with a Plumbutter 2 controlled by a Deerhorn running through it.


thanks again for the code update!


One of these days… I finally found that I can set speed to octaves (I guess I never looked close enough before, hihi) … oh wow. so good! The new update is fun. Wondering if sample rate could be an lfo target but I guess not…

1 Like

Sample rate/bit depth is definitely on my modulation radar :slight_smile:


Just pushed a small update to get in line with Norns 2.2.

Panning has changed from 0 - 1 to -1 - 1.
There is now a pan slew parameter.

Using 1pan or 2pan as an LFO target is a little wonky right now, but a fix will be coming. Until then, you can use the offset params to shift the range around.


@Justmat hey, weirdly specific and/or amateur question for you. i’ve found a bit of time to try to clean up cccccccc.lua and hnds being self contained is obviously the ideal.

but i’m not quite able to wrap my head around: why is just lfo.process being defined in otis.lua? is it simply that it’s easier to build the LFOs with variables/params from otis?

sorry if this is a dumb question, i am extremely rusty. really appreciate all the work you’ve done on this amazing app!

1 Like

Presumably because this keeps the LFO code in hnds.lua generic, unrelated to otis, and more easily reusable in other scripts. ie. all I need to do in my script is add the import, and define how the LFOs are used in the lfo.process function.


@GoneCaving hit it on the head :slight_smile: hnds has no way of knowing what params a script will have, or what lfo targets you’ll want. so it initializes lfo.process as an empty function and lfo.targets as an empty table. these are then re-defined in the importing script, to supply hnds with the relevant data.


totally makes sense now. the ouroborosness of defining .process using .scale and .slope was what was wrinkling my brain. i was thinking ‘why not just query the lfo object for the value whenever you needed to update something instead of every time the metro is called’. after an afternoon of messing around i realized that you can but then you’re using two metros instead of one. thanks for indulging me!


Hi @Justmat , so first off, hnds.lua is awesome, and thank you for making it.

I was playing around with it in my own script and noticed a couple (mostly minor) issues, which I’ve addressed in a PR. Let me know what you think!

Details and stuff
  1. The “sine” LFO will sometimes “jump” to a different point in the phase.

I’ve tracked this down to line 113:

lfo[i].counter = (lfo[i].counter + lfo[i].freq) % 360

If you remove the modulo 360 it fixes the issue. This is maybe easiest to hear if you play a single note and turn feedback all the way up with a short delay time. Set an lfo_target to “speed1” and add a print(lfo[i].counter) after that line. You should hear the lfo “skip” when the counter gets to 360.

  1. The square wave seems to be slower than the sine. I noticed because I was attempting to make a tempo synced LFO in my script. I updated the square to make it derived from the sine, that way they should always be the same frequency.

  2. The initial waveform in the lfo[i] table should be set to “sine” instead of 1. In my script, this causes the LFO to not work until I manually go to params and set the shape (so it is updated from 1 to a valid value). This isn’t an issue in Otis, I think because you call params:bang which auto sets it.

  3. Not an issue but more of a feature :slight_smile: , I added an lfo depth param.


Nice! I will check this out later today.

maybe you could add a randomness in square lfo while you are there :slight_smile:
I’d like to achieve random recording. thanks anyway!

1 Like

This is mostly a hnds update, many thanks to @crim!

LFO behavior has changed.
Instead of min/max lfo params you now have offset and depth.
(At depth = 100 an lfo will output from -1 to 1.)

Also, offset and depth calculation has been moved out of otis and into hnds.lua, making it much easier to include hnds in other scripts.


update v1.2

this update adds sample rate and bit depth as LFO targets!


was wondering how you accomplished that on ig, exciting times :upside_down_face:

1 Like

Is Otis supposed to monitor/playthru audio all the time? This seems new with the norns update today.

I changed dry signal in the params, but no change.

bug, feature or user error?