Teletype 3.2+ feature requests and discussions

I just bought an MS-20 which tracks hz/v instead of v/oct. I’m working on a conversion OP for the teletype and have two questions:

  1. I’m thinking of the name HZ, so for tracking v/oct we write CV 1 N 12, for tracking hz/v we would write CV 1 HZ N 12. How do people feel about the name and usage?
  2. I prototyped the function in C (outside the TT environment), and I used function pow() from math.h. It seems the linker can’t find it even when adding #include <math.h> at the top of maths.c. How do I approach this? I need to be able to use floating point power, so it’s not that simple to write my own drop-in replacement pow().

EDIT: regarding 2): I found a seemingly public domain implementation of some math, including pow(). It works, but I can’t judge the quality/efficiency, and I don’t want to inject this found code into the firmware just like that…

1 Like

I regret to inform that Teletype lacks an FPU. It might be best to create a lookup table in this case. Perhaps a sparse LUT (semitone resolution) with interpolation would suffice?

Ok, thanks!

Wouldn’t a reimplementation of pow() in found-code be cleaner? Isn’t a lookup table taxing the memory too much?

If I should do lookup-table, I think I’d go with 256 values, covering the range -10 to 10 V for notes on the N grid and interpolate in between, would that be a good strategy?

Edit: I have no problem implementing it in a way that fits the rest of the code base. There’s just something beautiful in one line of code (leaving out the reimplementation of pow) that does everything and exposes what is actually going on. But if it’s better in a LUT, no problem. :smirk::smirk::smirk:

libabvr32 includes libfixmath. for good reasons, libfixmath doesn’t have a general pow(), it would be underspecified for required accuracy etc. but it does have a fix16 implementation of exp that you can use.

if i understand correctly, you want something like y = g(x), where:

f_0 * 2^{ax} = f0 + by,

x is your pitch control, y is your freq control,

and a and b are arbitrary scaling factors.

hint: you don’t need a general pow to compute 2^{ax} when you have a fast approxmation for exp(a*x) and can precompute log(2).

if you want to share the code for the function you want maybe we can puzzle out a quick+clean fix16 implementation without needing a special LUT. (since i may be misunderstanding what you actually want. spoiler, pitch accuracy will of course not be awesome at high freqs. TBH i’m not quite sure i see the value unless you’re trying to convert incoming pitch CV to outgoing freq CV.)

1 Like

Made a PR.

The conversion is just one line:
v_out = fs_pow(2, v_in / 1638.4) * 1638.4;

NB: fs_pow is a re-implementation of pow, located in helpers.c/helpers.h (along side with supporting functions:

double fs_pow(double x, double y);
double fs_fmod(double x, double y);
double fs_log(double x);
double fs_exp(double x);

EDIT: I redid the OP to use LUT with interpolation, get’s rid of the found code… Waiting for response to the new PR

I don’t know if there’s that much interest in arc ops (I saw a little bit of discussion above but it seems like it didn’t go much further unless I’m missing something!). Anyways here’s some thoughts/ideas:

I see two possible uses of arc:

  • As a basic encoder which I think can already be done with something like Hans and generic i2c ops(?) though I’m not sure exactly how that works.

  • As a controller for internal LFOs. Something like Returns where you can set the shape of the lfo, the scale, the friction of the encoder, and then you can control the speed with the knob? Maybe there’s some interesting double duty where the op can also be used without an arc to create LFOs inside teletype?

Just some initial ideas, I have a very limited understanding of what’s possible or what coding it would entail, just a notion of something that might be interesting.


The proposed ops are great but what about data transfer from the teletype to the crow? I would really like to use teletype to push pattern values from TT to Crow. I have Crow running sequencers with array variables, and it would be great to fill those in dynamically with TT.

I would be fine with a predefined input buffer on the Crow side that I could reference while running Crow scripts.

Couldn’t this be implemented as a loop over CROW.CALL? If there is some specific example that this wouldn’t satisfy, perhaps you can write an example script of the desired behaviour?


I misread the CROW.CALL description. It does seem like this would be an excellent example of that. I am confused about the differences between CROW.CALL 1-4.

so typing the following into teletype

CROW.CALL2 variable_name value

is akin to typing the following into druid

variable_name = value


So I do CALL3 and CALL4 work on 1 and 2 dimensional arrays? What does CALL1 do?

I think you’d need to make a little function in crow to accept values one-at-a-time and build your array that way. You could have separate “array begin/end” messages, too.

Oh it’s call function() with args. Duh.

@desolationjones @scanner_darkly @a773 etc:

Is there a timeline for a new release? The last official was over a year ago, and there are so many new features in the main branch since then. Would it make sense to draw a line under the features currently included & put a little effort into docs & make a new official release?

I’m happy to volunteer a couple hours over the next couple weeks (and I’m about to post a new PR for crow-ii support).

(also, I could be totally out of the loop and there is somewhere else y’all are talking about dev issues?)


my understanding is that we were waiting for w/ PR to be complete?

i don’t have anything outstanding at the moment. there is actually a change i’d love to get in, but i’m hitting the same issue @a773 and others also ran into. so, maybe it’s another reason to release now, but i think would be good to try and resolve it or at least understand why it happens before an official release.


I’m sitting on a couple of features, but nothing critical to a release. What’s holding me back ATM is The Issue as @scanner_darkly referred to.

IIRC @desolationjones is working on making N.Q use binary scales, that might be cleaner to get included…

1 Like

I have that change pretty close to done but I got caught up in a refactor. I’ll put some hours into it tomorrow morning. I’ll let you know if The Issue crops up for me.

This was my assumption, too, and I know @karol has been chipping away at it. The latest communication on github has me thinking that it is complete with the exception of renaming the filter OP per @Galapagoose’s preference.

I’d like to give w/2 the same “dual address” treatment as JF, but that’s not something that needs to hold up our release.

1 Like

Cool! While you’re at it, I suggest you make it nearest note not next note down :slight_smile:

I have QT.B and VN working with nearest notes, but the older QT.S and QT.CS code needed a lot of work. I ended up writing some generic methods for quantizing, octave handling, CV-to-note, note-to-CV, etc. to reduce duplicate code, and I was refactoring a lot of OPs. I honestly don’t remember where I left it, but I will definitely ping here for testing help!

@a773 and @Galapagoose, you’d both be very welcome over at the Teletype Discord (link expires 5/28). I’ve been trying to keep development noise out of the study hall areas and use the “dev zone” and lounge channels instead.

1 Like

I can pick up the W/ PR and get dual-address working (requires somewhat of a refactor). Also, after working on crow support yesterday and looking at the W/ PR again, it seems ‘getters’ aren’t supported, so I can add those too.


I am now equipped with dual W/, so I stand ready to test!

Speaking of getters, was the timestamp getter nixed? I see it’s commented out in wtape.lua

huge thanks to @Galapagoose for investigating and solving the issue, i’m hopeful we are unblocked now.

so, optimization and refactoring are needed, i propose the following plan:

  1. find low hanging fruit for optimization that won’t require major refactoring and testing so that we don’t delay the release
  2. once the above is done, devs with outstanding features that are ready or close to ready - submit your PRs
  3. post a new beta that includes everything we want included in the release and test it for a week
  4. release
  5. coordinate work on further refactoring and optimization.

does this sound like a reasonable plan?