what i mean is: you use Z as your current position. in your scene, the only valid positions are 0…127. if you use addition or subtraction to determine a new position, you have to make sure not to go out of bounds.

there are 2 options: you either wrap to the other side when it reaches any of the edges, or you treat it as a collision. if you wrap (which iirc what my scene does), then you can use WRAP op. let’s say you want to move down one row, and Z is 120. to move down one row you add 16. 120+16=136. this is out of the valid range. if we wrap it, we will get 136%128=8 - which means moving down from the bottom row it will appear at the top row [essentially, your grid becomes a toroid - left column is connected to the right column, bottom row is connected to the top row].

if you don’t need to wrap, then you just have to check that your new position will not be out of bounds, which you already do.

this is also the case for checking pressed buttons - if you in the leftmost column, then there is no button to the left of it - unless you want it to wrap to the other edge. to get the button to the left from the current one you have to subtract 1. so if Z is 0 then the you’ll be checking G.BTN.V -1. since there is no button with that index, the op will simply return 0. in your case it doesn’t matter, since you have separate checks for your edge collision detection anyway.

1 Like

Got it. I appreciate your help.

Since getting the Grid to go with my Teletype I have been experimenting with writing little sequencers that captures some aspect of how I work with other sequencers. This one is a simple two track polymeter that makes it easy to switch key and mode. Check out the video for a quick demo.

I:
G.FDR 0 0 7 12 1 2 2 2
G.FDR 1 0 6 9 1 2 2 2
O.INC 1; O.MAX 11; O.WRAP 1
G.FDR 2 0 0 13 1 2 2 2
G.FDR 3 0 3 13 1 2 2 2
SCRIPT 7

M:
X WRAP + X 1 0 - G.FDR.n 2 1
Y WRAP Y 1 0 - G.FDR.N 3 1
SCRIPT 1
SCRIPT 3
SCRIPT 4

1:
G.CLR
P.N 0; J - G.FDR.N 2 1
L 0 J: G.LED I 0 * P I 4
P.N 2; J - G.FDR.N 3 1
L 0 J: G.LED I 3 * P I 4
G.LED X 0 6; G.LED y 3 6

2:
P.N 0; P.L G.FDR.N 2; J 16
L 0 P.L: P I G.BTN.V + J / I 6
P.N 1; P.L 0; P.END 7
L 0 6: P.PUSH G.BTN.V I
L 0 6: P I ? EQ P I 0 -1 P I
SCRIPT 5

3:
IF ! PN 0 X: BREAK
A G.FDR.N 0; B G.FDR.N 1
PN.NEXT 1
W EQ PN.HERE 1 -1: PN.NEXT 1
C N.S A B PN.HERE 1
CV 1 C; TR.PULSE 1

4:
IF ! PN 2 Y: BREAK
A G.FDR.N 0; B G.FDR.N 1
PN.NEXT 3
W EQ PN.HERE 3 -1: PN.NEXT 3
C N.S A B PN.HERE 3
CV 3 C; TR.PULSE 3

5:
PN.2; P.L G.FDR.N 3; J 24
L 0 P.L: P I G.BTN.V + J / I 6
P.N 3; P.L 0; P.END 7
L 0 6: P.PUSH G.BTN.V + I 7
L 0 6: P I ? EQ P I 0 -1 P I
SCRIPT 6

6:
P.N 1
L 0 6: P I ? EQ P I -1 -1 I
P.N 3
L 0 6: P I ? EQ P I -1 -1 I

7:
G.BTX 0 7 1 1 1 1 2 2 7 1
G.BTX 7 7 4 1 1 1 2 2 7 1
G.BTX 16 0 1 1 1 1 2 2 6 1
G.BTX 24 0 4 1 1 1 2 2 6 1

Still feeling new to the Teletype language, though it does bring fond memories of Lisp, Forth and OPL programming, so… don’t hesitate to suggest different ways of doing things!

Thanks to @scanner_darkly for all these wonderfully well thought out Grid ops!

/K

8 Likes

great work! and also a good example of how even with limitations of a single scene you can still build a fully featured sequencer. also nice to see newer ops like N.S being used, especially important in grid teletype scenes, since it allows you to dedicate more script space to the UI / sequencer logic.

added your scene to the codex page!

1 Like

I made a grid-enabled teletype scene today that I call chordboard. It uses the N.C operator in teletype to create a performance-friendly interface for playing with chord progressions. It supports four different voices.

The top row buttons correspond to 16 memory locations. Each memory location stores a chord-type (one of the 12 that N.C offers), a root note and a root note octave.

Each TR and CV pair correspond to a voice.

The first voice always outputs the root note of the chord at the octave set by the left column of buttons along the bottom of the grid.

The second voice outputs a random note from the current chord when a trigger is received on input 5. This voice has its own octave buttons next to the root note octave buttons. The param knob also changes the range of the random notes from 1 octave at full ccw to 4 octaves at full cw.

The third voice will output a note from the current chord based on the external CV input when a trigger is received at input 6. In this track, I’m using a looping smooth random channel from Pamela’s New Workout that is 6 beats long so it phases a bit with the bars of the chord changes. Each octave of the chord spans 1v of CV, but it’s not quantizing the voltage itself, just using its value for lookups.

The fourth voice is played manually on a 4x4 grid of buttons on the bottom left corner of the grid. Each row corresponds to the notes of the chord at successive octaves.

I slapped on a really basic script for the 8th input to let me go through the first four memory slots, but I’m hoping to come up with something more flexible for looping sequences of the memory slots.

p.s. can someone remind me how you do the cool monospace indented formatting for teletype code?

Chordboard code (how do I format this the cool way?)

CHORDBOARD

#1
G.BTN.SW G.BTNI; A G.BTNX
G.BTN.SW + PN 0 A 16
G.BTN.SW + PN 1 A 32
G.BTN.SW + - 3 PN 2 A 64
C PN 1 A; B PN 0 A; D PN 2 A
CV 1 + V D N.C C B 0; TR.P 1

#2
G.BTN.SW G.BTNI; X G.GBTN.X1 1
PN 0 X G.BTNX; B G.BTNX

#3
G.BTN.SW G.BTNI; X G.GBTN.X1 1
PN 1 X G.BTNX; C G.BTNX
CV 1 + V D N PN 1 X; TR.P 1

#4
Z && EZ G.BTNV EZ G.GBTN.C 4
IF NZ Z: TR 4 0
IF EZ G.BTNV: BREAK
TR 4 1; X V - 7 G.BTNY
CV 4 + N.C C B G.BTNX X

#5
PARAM.SCALE 0 3; Z PARAM
X - 7 G.GBTN.Y2 7; Y RRAND 1 4
X + RRAND 0 Z X
CV 2 + V X N.C C B Y; TR.P 2

#6
IN.SCALE 0 40; X IN
Y V / X 4; Z % X 4
CV 3 + N.C C B Z Y; TR.P 3

#7
X ? == G.BTNX 5 2 3
Y - 7 G.BTNY; G.BTN.SW G.BTNI
PN X A Y
IF == X 2: D Y; TR.P 1
CV 1 + V D N.C C B 0

#8
X % + G.GBTN.I 1 0 1 4
G.BTN.PR X 1

#M
M.ACT 0

#I
G.GBX 1 0 0 0 1 1 1 3 1 16 1
G.GBX 2 16 0 1 1 1 1 3 2 12 1
G.GBX 3 32 0 2 1 1 1 3 3 12 1
G.GBX 4 48 0 4 1 1 0 3 4 4 4
G.GBX 5 64 5 4 1 1 1 3 7 1 4
G.GBX 7 80 7 4 1 1 1 3 7 1 4

#P
0 0 0 0
1 1 1 1
0 0 0 0
63 63 63 63

2 1 0 2
1 5 0 1
0 4 0 3
2 8 0 1
2 1 1 0
1 5 1 0
0 4 1 0
2 8 1 1
8 6 0 0
9 2 0 0
10 11 0 0
11 4 0 0
7 8 0 0
8 9 0 0
10 11 0 0
10 11 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0

#G
0100000000000000
0100000000000000
0000010000000000
0000000000000000
0001100000000000
0010000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

tt03s.txt (1.9 KB)

2 Likes

love the track!

this is a perfect example of why i think grid integration can be so usable - teletype has some really powerful ops that really open up when you interact with them directly via a grid interface.

for code formatting use backticks: `
for inline use, surround the content with single backticks, for multiple lines place content between lines with 3 backticks each. alternatively, select a block and press ctrl-shift-c.

1 Like

Hi! Here’s a video using rhythmicon code. I’ve changed faders behaviour: instead of controlling decay time, they are controlling note’s pitch (based on scales stored on pattern one). Great, great, code, @scanner_darkly!

1 Like