(Teletype) Pre-2.1 Operators and Features


i’d love to be able to return the cv out values from ansible when running kria (meadowphysics, too) so that i may sequence just friends in synth mode.


Yep, and of course it is okay for a product to have features that I do not use…:grinning:

Yes, and I am happy that this conversation now seems to have led to good compromise. I think I get a bit concerned when this process gets too fast with new propositions.

Of course everyone uses devices in a different way and has different needs and ideas what they could do/be. But I have a Reflex Live Loop which I rarely use because it got to complicated through a process of implementing all possible ideas and features.

There seems to be a trend to expect modules to be able to do everything which I don’t think is a good idea. I experience this watching the 3 HP minimal panning mixer thread and have a feeling that the Omnimod disappeared from reality for a similar reason. Even Mac OS seems to have gotten more complicated by implementing stuff that might sound great but isn’t. I just don’t want to experience this again in my rack…

What spontaneously comes to my mind:


Setting acceleration/friction per cycle
bumping/breaking individual cycles
setting the speed for individual cycles
Setting individual Pulse division

Transposing CV outputs pre/post scale
Reading CV outputs (might make transposing post scale obsolete)
Sart/Stop KRIA

Quantizing to scales


This would be super, particularly if there was a way to support user-defined scales.


Alright, I have a conceptual problem with BOUNCE mode: where is the fence, and where is “0,0” for each cell. Consider:

@MOVE 0 -1

Is the turtle Y = 0 or 1? If he was standing at (0.5, 0.5) and the fence were at (0, 0), Y would be 0. If he were standing at (0,0), Y would be 1.


  • Fence at “edge” of cell, such that len(FY) = FY2 - FY1 + 1
    This means that if you’re at “bottom edge” of (0,0), you need to move 2 whole units to exit the cell if you head up and bounce off the “top” edge.
  • Fence in middle of cell, such that len(FY) = FY2 - FY1


I am not sure if I got you right but I would think if the turtle is standing right in front of the fence and moves on step forward it bounces and will get to the same cell as it was before if the direction was perpendicular to the fence. If the direction was diagonal by 45 degrees it would get to one cell besides the former cell (except it stands in the corner). Both should be handled as entering a new cell by the firmware regarding triggering events.

I think in this conception the fence is between the cells. This might be what you think of by “at the edge” of a cell. So the fence is fencing in a field of cells.


Am I the only one using all of their restraint to avoid posting a turtle fence video or a super-catchy song made out of the turtle fence video? Alright - how about a picture:

I do love that the discussion has made it to turtle fences - for a variety of reasons!! :wink:


+1 with 20 characters


I think we might need @CLIMB as a fourth mode!



I’ll try to resist making up more op ideas, but…

@RAND could be a boundary condition that resets the turtle to a random place in the fence whenever it hits a wall.
@HOMEBOUND could be a boundary condition that resets the turtle to @HOME whenever it hits a wall.


I don’t know - @BUMP gives you a true/false condition so you can easily set the turtle anywhere using a script when it bumps against the fence.


@BUMP only tells you if you’re in bump mode, not if you’ve hit a wall.


Ah, okay - I misunderstood it then. So you would use the row and/or column numbers to achieve the effect.


@HOME didn’t make the cut.


I’ve been thinking about this a bit. It’s trickier than you think.

I’ve been trying to find time to play with my ‘inline array’ operators: to re-cap:

ARP2 a b i              // pick the i'th index from the repeating sequence "a b a b a b ..." (like an arpeggiator)
ARP7 a b c d e f g i    // as above but with 7 values for the arp, instead of 2

SCL2 a b                // define a scale with 'a' and 'b', based on 12 note western music, get the i'th degree
SCL7 a b c d e f g i    // as above but with 7 values, so you could write out a major or minor scale with it

I really haven’t had much time to get it finalised. But some of my shower thoughts have been directed towards applying the same scheme towards quantiation (e.g. QNT7). However the difficulty comes about from deciding what type of value we’re trying to quantise.

On the Teletype we have 2 ways to represent pitch, chromatic notes, or raw CV values. And we can convert from chromatic note numbers to CV with the N op.

Let’s consider that we want to quantise “something” to a scale that contains C and E (duotonic?). (Please bear with my descriptions of scales and such, I have zero musical training.)

Firstly let’s consider it with our input being chromatic notes. If I pass in a C#, I’d expect a C out of my quantisation function, and if I pass in a D#, I’d expect an E. But what if I pass in a D? There are 4 options:

  • quantise up
  • quantise down
  • choose randomly
  • prefer better quality intervals (so unison trumps perfect 5th, which trumps perfect 4th, which trumps…), the assumption being that the first value provided to the function would be the root

Secondly let’s consider it with CV inputs. In this scenario, some things are actually much easier, as the probability of hitting the CV value that’s exactly half way between C and E is much harder (remember CV values go from 0 to 16,383.) But it get’s much hard to specify the scale as we’d need to use N convert the value e.g. QNT2 N 0 N 4 IN. So rather we’d need a different version that did the conversion for us (QNN2 0 4 IN).

Anyway, that’s probably a bit of a ramble.

My general plan of attack is to get the current array ops finished (ARPx, SCLx, and BNDx - bounded arrays, and UNBx unbounded arrays), I’m trying to get something pushed to my git repo this week, sorry to those that I had indicated that it might be sooner.

If they end up making their way into the official firmware, then I figure we can start talking about quantisation. But I’m afraid it’s all happening at my speed (it took me 6 months to do 2.0), sorry about that!


I’m not picking on this comment in particular… but…

Remember it’s really easy to add ops, but it’s really hard remove them once they’ve been released into the wild.

Convenience functions can always be added in later on, especially once everyone has a feel for how the turtle will work.


It really seems like an array operator would be ideal. Instead of

FOO7 P 1 2 3 4 5 6 7

You could have

FOO P [ 1 2 ... N ]

I’ll think about what this means to the parser, but what do you think of the idea in general?

At first glance it seems pretty easy to implement. Really easy actually. There’d be some implementation requirements for operators to take arrays, but it’s as simple as adding the two operators, storing a single array of values, then pushing the number of arguments on to the stack or a magic number or set a flag or something.


Maybe… but that’s changing the language… whereas my syntax just requires some C macros to reduce duplication. It would have to be extremely compelling to justify the extra maintenance burden, and the extra burden on users.

Speaking of language changes, I’m probably going to post an (mild) argument against W if I ever get the chance. Or rather a, please understand the cost of it’s inclusion, and make sure that the price is worth paying (which it might well be).

The extreme tl;dr of the argument is that W makes a lambda function (or function pointer)1 of some OPs before the mod separator.

1 though not a closure, though that is feasible now that exec_state_t behaves like a stack frame… (thanks for that!)


Whoa. I’d be interested in that post.


It probably sounds more exciting than it really is.

Consider L:

L 0 1: P I I

L, in effect turns the part after the : into a lambda function, and then executes it multiple times. In fact all mods take a command as one of their inputs, i.e. all mods take a lambda as one of their inputs, that’s how they all work.

I can’t remember the exact way you implemented W, I think you’re just re-running the line? Anyway, the way that the code is structured it appears as if the first argument to `W is a lambda function, e.g.

X 1000
W GT X 0: X SUB X 1

That looks like W takes 2 functions, GT X 0 and X SUB X 1. Even if that’s not how it works.

I had a quick look in your code btw, if run_command is dead code then delete it.

Have you enabled travis-ci on your fork too? It’s probably worth doing, so you don’t end up getting any surprises. Shout if you need some help.


Just to say, I would love this though! The the functional programmer in me, says it should be the other way round:

FOO [1 2 ... N ] P

I’m just not sure I want to be the one supporting the code, or answering questions from confused users.


You’re right, the whole while command gets rerun. So essentially, yes, the condition is a lambda. Does this make it bad in some respect, other than its potential for resource intensity?

It gets used by the test framework, which I have a few updates to to incorporate the es_push() stuff.

Negative on Travis-CI. I’ll look into it.