i appreciate @scanner_darkly putting #3 first, but honestly #2 is by far the most important element at this point as i am fully buried in norns development.

regarding feature requests, i’d suggest including as much detail as possible so that a design can be considered as a whole proposition, not just a spark of an idea that then needs to be designed around. ie, scrolling scripts.

  1. memory usage, are people happy with vastly fewer scenes?
  2. how does scrolling actually work in terms of UI? hotkeys?
  3. is there visualization of scroll position? does that effectively shorten line length?
  4. is scroll position stored when moving around scripts?
  5. does this feature break or interfere with any other UI?
  6. does this feature open up possibilities to expose CPU limits, memory limits, stack limits, etc? ie, does it mean the user will have to internalize more user limitations, rather than have the design of the system have its limitations set intrinsically?

that last point is the most important in my opinion. it’s too easy to imagine anything is possible. even my proposition for the “timeline” feature may run into the same issues… creating situations where “normal use” actually breaks the whole thing. this is what i’d like to avoid.

that said, i don’t think these features should not be explored— but someone must have the time to do the actual work.

10 Likes

Answers not required from anyone in particular, just kicking this around:

  • memory usage, are people happy with vastly fewer scenes?

What’s the tradeoff? In other words, how much storage is available, how much does a scene currently consume, and how much does a line in a script consume?

  • how does scrolling actually work in terms of UI? hotkeys?

Follow the Rule of Least Surprise: do whatever Tracker Mode does. :slight_smile:

  • is there visualization of scroll position? does that effectively shorten line length?

There are two unused columns of pixels to the left in script view. Use one for scroll position (dimmed pixels).

  • is scroll position stored when moving around scripts?

As above: do whatever Tracker View does. :slight_smile:

  • does this feature break or interfere with any other UI?

If it is confined to a single script (i.e. init), I don’t think so.

  • does this feature open up possibilities to expose CPU limits, memory limits, stack limits, etc? ie, does it mean the user will have to internalize more user limitations, rather than have the design of the system have its limitations set intrinsically?

That depends on how scenes are stored in RAM and how they are processed. I would be overjoyed to have, say, 30 lines’ worth of init.

(The main use case for extra scripts IMO is function-like behaviors called from e.g. loops.)

2 Likes

Some ideas I’ve had floating around for rhythmic sequences, in order of increasing nerdiness:

LROT x y / RROT x y for bit shift with rotation

IF BGET C 0: TR.P 1
C RROT C 1

BIN x (alias ‘#’ since I assume the standard ‘0b’ prefix is going to be confusing in all caps) for binary constants. Line length is a possible gotcha, but 8 bits may still be useful.

A BIN 1000110010001010
B | LSH B 4 # 1010

Also possible HEX or OCTL. A bit less intuitive for rhythm than binary, admittedly, but more concise, and possible to set variable display/pattern editor (DEVICE.BASE x).

ER.V x y for the values of Euclidean patterns (max length 16) as integers from binary, with ER.V x y where x= fill and y = length. So for example:

ER.V 1 4 = 8 = # 1000
ER.V 3 4 = 14 = # 1110
ER.V 4 8 = 170 = # 10101010
ER.V 3 8 = 146 = # 10010010

6 Likes

I would like to second left/right bit rotation

1 Like

Actually, expanding on the “loop on several lines” thing, it would make sense to have only one “continue” pre operator that would work for L, IF, ELIF, etc.

3 Likes

Expanding on the idea of adding bases: I’ve wished Teletype had support for base 12 in the tracker view for quite a while as it would be really useful for manipulating notes. In base 12 it’s very easy to add and remove octaves and interpret note numbers. Here are some examples of why this is the case.

Here are the basics

	base 10	base 12
C	0		0
C#	1		1
D	2		2
D#	3		3
E	4		4
F	5		5
F#	6		6
G	7		7
G#	8		8
A	9		9
A#	10		A
B	11		B

Now, let’s try some notes with different octave numbers. You’ll see that notation is base 12 is much simpler to interpret, because we can tell the octave by the first digit, and the note by the last one.

In contrast, in base 10, the number is equal to the note number at octave 0 plus the number of octaves times 12, which just isn’t intuitive.

We also don’t have weird cases where we get a three digit base 12 note number, because you’d need to use a range of 12 octaves or more, which is more than Teletype can output, and more than the earing range.

	base 10	base 12
C0	0		0
C1	12		10
C2	24		20
C3	36		30
G0	7		7
G1	19		17
G2	31		27
G3	43		37
B0	11		B
B1	23		1B
B2	35		2B
B3	47		3B

I think the place where this would be most useful is in the tracker view. It would be ideal to be able to set the display base for each pattern rather than the whole tracker view, as it would allow different types of data to coexist.

We could even generalize the idea to arbitrary bases, so we’d have a BASE B X to convert number X from base B to base 10, and P.BASE B / PN.BASE N B to change the tracker view display format of the selected pattern to base B.

9 Likes

I’ve been coding a TT quantizer this week and base-12 would have saved me a lot of modulo / division operations.

I’m still for shadow scripts… it’s just a perfect match for the grid ops! (while staying in familiar territory concerning GUI)

great idea! not too enamored about the A and B clashes with variable names. but I would love this as an optional setting/converter for the tracker for sure!

True, that would make it impossible to input base > 10 data with digits > 9 using BASE.

The first thing I thought about was adding some special characters. But that would need annoying key combinations, and might complicate exporting scenes. A more elegant solution I think is to have Teletype recognize characters as digits whenever they are preceded by a digit. This would work because (as far as I know) no OP starts with a digit. B would refer to the variable B, while 0B would refer to the number B (11). This also gives us the whole alphabet, if for whatever crazy reason we want to play around with base 35.

4 Likes

Yeah I’m not familiar with the innards. Since the tracker isn’t evaluating expressions (?) I thought it might be technically possible, but at the least it would be confusing otherwise.

@scanner_darkly @sliderule this [arbitrary bases] might be something I could implement, given some time. Would you give me some pointers on how to go about it?

Thinking in base 12, it Would be useful if the grid control mode coarse update would be +/- BASE. As this would allow you to easily pitch pattern values up and down octaves if they are passed to N.

Instead of a and b, you could do _0 and _1.

Also would be cool if you could get set base with a BASE op that could be updated in real time as a performance “gesture”

the main change would be in the tracker UI: https://github.com/monome/teletype/blob/master/module/pattern_mode.c

it’s an easy change for any base > 7. but for anything below it’s a major UI change as it would require scrolling. i think the UI for this should be given careful consideration - how do you display tracker in this case? would some banks be displayed partially, or do you just display the ones that fit? it would be also good to show the bases somehow, especially if you can set it per bank, but i’m not sure there is enough space. then for base 2 you probably want it to display the actual binary representation, not the positive portion with a minus sign - i don’t really see the benefits of the latter.

(as a side note i think only 10, 16, 12 and 2 are really useful, so not sure supporting any arbitrary base is necessary).

then you would need to implement the op, check the readme on the tt repository, it has some documentation there and i can help with specific questions.

finally, the choice should be persisted in flash, for that you would need to:

  • modify module/flash.c to store it
  • modify module/main.c to read the setting from flash upon bootup
  • add a function to update the setting to src/teletype_io.h - this is what the op will call
  • implement that function in module/main.c and make sure it updates flash. edit: also need to implement it in tests and simulator

and as @jlmitch5 mentions, the grid control mode will need to be updated - i can handle that part.

for base conversion patter.c uses itoa function, don’t remember for sure but i think it might have a hack that only makes it work with base 10, you want to double check that as well

1 Like

Can we merge @alphacactus’s XDEL OP? And perhaps consider my RAT variation? I understand the delay timing in general is a bit rough (±10 ms) but we’ve already got DEL so we might as well have other delay OPs :slight_smile:
I think that DELAY_SIZE would have to be increased to accommodate the larger queues.

yeah, definitely, just need a pull request.
we should discuss limiting the overall number of delays first though, it’d be nice to improve timer accuracy at some point and high number of delays might make it unfeasible.

Imagine if we went suuuuper retro with it and forced everyone to familiarize themselves with which hexadecimal digits correspond to which chunks of 4 binary numbers :joy:

that said, I do think base 2 has a good reason to be included if base 16 does, namely, if you want to use @starthief’s bitpacking correspondence between numbers and trigger patterns, but you want, say five or 11 beats per bar rather than four or 16.

1 Like

reminds me of the fact that the old classic trackers (and renoise now) had the option of switching between decimal and hexadecimal…

thinking more about it, for hexadecimal it probably also makes sense to treat values as unsigned.

2 Likes

ok give me like an hour and I’ll get it ready. if I recall the only bug I had was with very long delay times wrapping into negative and triggering immediately. never got around to fixing that.

1 Like

ok here’s the branch. it built okay, but I won’t be able to flash/test it for another hour or so here. I can hold off on the pull request until I can test it myself if desired.

1 Like

yes, please test it before a pull request. i would also recommend running tests, they are super helpful to catch any ops that are not set up properly.

re: op name - not sure about RAT as the op name. it’s short for “ratchet” but that kind of implies how it would be used, while something like REP would be more generally descriptive.