> teletype: grid # code exchange

that looks great! some notes:

in script 1 if you’re using Z to pass a value to script 2 from the loop you should set it before calling the script:
L 1 6: Z I; SCRIPT 2

if you’re using the latest grid beta you can also take advantage of G.BTN.X and G.BTN.Y ops, so the first 2 lines of script 2 could be slightly more readable:

Y - 7 G.BTN.Y PN 0 Z
X N + * Y 5 G.BTN.X PN 0 Z

for voice stealing you want it to grab the first available, starting from 1? or something else?

Yes, something like this, for example, so that if you’re holding down a long note, it won’t be stolen as you’re playing others but instead they will take an available voice. And if there is no available voice then the algorithm should steal the note that voice that was least recently activated. (This is what I find intuitive and how it works on my poly synths at least)

The other issue is that if more than one voice are allocated to the same button you get strange behavoiur, I’m not sure how to tackle this.

Even with these imperfections, using the grid ops to operate just type like this feels really great!

This makes complete sense, but does it matter? It seems to function fine the other way too

Amazing! I’d missed these :slight_smile: (though I was also quite proud of my mathematical work around!)

So here is a much better version of the script for nice earthsea style polyphonic control of Just Type. To understand the scene, read it backwards (Start with Initial script, then 8->3)
Set Just Friends to SOUND/SUSTAIN.


#3
IF EQ PN 0 Z G.BTNI: C Z

#4
L 1 6: Z I; SCRIPT 3
JF.VOX C PN 0 C 0
PN 0 C 999
L 1 6: PN 3 I + 1 PN 3 I
PN 3 C 1000

#5
Y - 7 G.BTNY
X N + * Y 5 G.BTNX

#6
IF > PN 3 Z B: B PN 3 Z; A Z

#7
B 0
L 1 6: Z I; SCRIPT 6
SCRIPT 5
JF.VOX A X V 5
PN 3 A 0
PN 0 A G.BTNI

#8
IF G.BTNV: SCRIPT 7
ELSE: SCRIPT 4

#M

#I
G.BTX 0 1 0 1 1 0 3 8 15 8
JF.MODE 1
JF.SHIFT V -2

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

0	0	0	0
999	0	0	1003
999	0	0	1002
999	0	0	1000
999	0	0	1001
999	0	0	1004
999	0	0	1005
14 Likes

ooh looking forward to trying this out!

Oh my! This looks and sounds incredible, is that audio straight out of JF, or are there any patch notes here?
It looks like there’s enough empty scripts to do some more things too – maybe sustain pedal input via Walk?! :smile:

I can’t wait to play with this

1 Like

excellent!! funny enough, i just finished my version. i prefer your solution, it’s more elegant, but i’ll post mine just as an example of another way to implement it.

#1
IF G.BTNV: SCRIPT 2; BREAK
L 0 - PN.L 0 1: Z I; SCRIPT 5

#2
IF EQ PN.L 0 D: PN.RM 1 0
IF EQ PN.L 0 D: PN.RM 0 0
A 1
L 1 D: Z I; SCRIPT 3
PN.PUSH 0 G.BTNI; PN.PUSH 1 A
B G.BTNI; SCRIPT 4

#3
IF EZ PN.L 0: BREAK
C 0
T - PN.L 0 1
L 0 T: C || C EQ Z PN 1 I
IF EZ C: A Z

#4
Y - 7 G.BTN.Y B
X N + * Y 5 G.BTN.X B
JF.VOX A X V 8

#5
IF NE PN 0 Z G.BTNI: BREAK
PN.RM 0 Z
A PN.RM 1 Z
JF.VOX A 0 0

#I
G.BTX 0 1 0 1 1 0 3 1 15 8
JF.MODE 1
JF.SHIFT V -2
PN.L 0 0
PN.L 1 0
D 6

pattern bank 0 stores pressed button ids (so its length reflects how many buttons are currently pressed). pattern 1 stores the corresponding JF voice.

when a button is pressed script 2 gets executed (via script 1). if the length of pattern bank 0 is 6 this means all 6 notes are used, so we remove the top one (which would be the oldest one - we append new notes at the end). script 3 checks if a JF voice passed in Z variable is available, and if it is we store it in A. we then append the new note using PN.PUSH. finally, script 4 triggers the JF voice (A is the voice number and B is the button id). one thing i like about extracting this into its own script is that you can easily change the keyboard layout here, or do some additional stuff, like sending a pulse to trigger an envelope for a filter.

script 5 will be called upon a button release - it checks if this button was used for any of the active notes and removes the corresponding note.

edit: modified the scene so it can be used for any number of voices - set D to the desired number in I script.


re: using math on button id vs using G.BTN.X and G.BTN.Y - both are good options, but using X and Y has a couple of advantages: if you change your button ids it will still work, and if you decide to change the number of rows / columns you don’t have to change your formula.

6 Likes

These are both awesome. Thanks @scanner_darkly and @ghost!

It also looks like this scene could be re-purposed to do polyphonic output of CV or to the TXo oscillators… so flexible!

3 Likes

yeah, could be used for any number of voices. i modified my scene so that it works for any number - just set D in the init script to the desired number. to use it with TXo update scripts 4 and 5.

forgot to mention - i do plan to add a dedicated grid op for “earthsea” style keyboard. but it’s great to see this kind of scenes as it shows you can do a lot with just the basic ops. if you look at @ghost’s scene there are only 5 grid ops used!

7 Likes

That’s marvelous!! Thank you for sharing!!!

@freqout @xeric @scan @emenel @kali_yuga Glad you like it!

Nice! I’m going to have a good look at this too. I must admit, my version occasionally doesn’t trigger notes and sometimes notes stick, though the code seems to be operating properly - I think the issue lies within Just Friends. Am interested if your version avoids this.

I am passively mixing all of the JF individual outputs and running them into a filter. The Mix out from JF is going into an envelope follwer (Cold Mac) - the output of this is controller filter cutoff. I also like to use a subtle LFO either to the filter or to Ramp on JF

Looking back at the script, I think we could probably combine script 5 and 7 and also variables A and C to allow for lots of other functionality. Polyphonic Earthsea style recording maybe!? ( I do actually have a working monophonic version of this on TT, though it’s not perfect)

6 Likes

I made a 4-track, 16-step trigger/CV sequencer with skippable steps and the ability to set start and stop points. This is my first Teletype scene.

Usage: The Grid is divided up into pairs of adjacent rows. Each pair of rows represents a track. A lit button on an even row indicates the active step for the corresponding track. Press two buttons in an even row to set a track’s start and stop points (the entire track plays by default). (Thanks @scanner_darkly for showing me how to do this!) Hold a single button in an even row and the next row will show the current trigger/CV combination assigned for that step, if any. Continue holding a single button in an even row and press a button in the next row to set or toggle the trigger/CV combination assigned for that step. (I was inspired by @freqout’s ER-301 slice sequencer for this interaction.) Finally, without holding any buttons, buttons in odd rows indicate whether or not a step will be skipped (skipped steps are unlit). Hope that’s clear! I should make a video… Send a clock to trigger input 1.

Other details: Each track corresponds to a pattern. Indices 0–15 indicate whether a step is skipped (0 is skipped, 1 is not skipped). Indices 16–31 indicate whether a trigger/CV combination is assigned (-1 is unassigned, 0–15 is CV note). Scripts 2–4 handle even row button presses. Scripts 5–6 handle odd row button presses. Scripts 1 and 7 handle advancing steps. Script 8 continues initialization from Script I. Could it be shorter?

#1
L 0 3: A I; SCRIPT 7

#2
P.N / G.GRPI 2; SCRIPT 3
IF G.BTNV: SCRIPT 4; BREAK
A + 16 * G.GRPI 16
L 0 15: G.BTN.V + A I P I

#3
I G.BTNX; T G.BTNV
IF && ! T EQ I Z: Z -1; BREAK
IF ! T: BREAK
IF EQ Z -1: Z I; BREAK
X MIN Z I; Y MAX Z I
P.START X; P.I - X 1; P.END Y

#4
A P + 16 G.BTNX; B + G.GRPI 1
IF < A 0: G.GBTN.V B 0; BREAK
G.BTN.SW + A + 16 * G.GRPI 16

#5
P.N / G.GRPI 2; A < Z 0
B G.BTNX; C G.BTNV; D P B
IF && A EQ C D: G.BTNV ! D
IF A: P B ! D; BREAK
B + Z 16; A G.BTNX; SCRIPT 6

#6
IF EQ P B A: G.BTNV 0
IF EQ P B A: P B -1; BREAK
P B A; G.BTN.SW G.BTNI

#7
P.N A; B P.I; D + A 1
W AND EZ P.NEXT NE P.I - B 1:
IF EZ P.HERE: BREAK
G.BTN.SW + P.I * A 32
C P + P.I 16; I > C -1
IF I: TR.PULSE D; CV D N C

#8
P.N A; P.L 16; P.WRAP 1
P.START 0; P.END 15; B * A 16
L 0 32: P I + * 2 < I 16 -1
C + 2 * 3 % A 2; D % A 2
G.GBX A B 0 A 1 1 D 0 C 16 1
L B + B 15: G.BTN.V I % A 2

#M

#I
G.RST
L 0 7: A I; SCRIPT 8
L 0 3: PN.I I 15
L 0 3: TR.TIME I 10
8 Likes

@ghost, @andrus - added your scenes to the grid code exchange page!

in your script 8 instead of L B + B 15: G.BTN.V I % A 2 you can do G.GBTN.V A % A 2 since you’re using different groups already (G.GBTN.V sets all buttons within a group). also noticed this: L 0 3: TR.TIME I 10 - the loop should be L 1 4 since trigger and CV numbers are 1-based, not 0-based.

5 Likes

somebody sent me a link to a video posted on cirklon fb (not posting the link as the video is unlisted but you can find it on the fb page) with cirklon imitating rhythmicon, an instrument invented by henry cowell and leon theremin. from wikipedia:

The invention, completed by Theremin in 1931, can produce up to sixteen different rhythms—a periodic base rhythm on a selected fundamental pitch and fifteen progressively more rapid rhythms, each associated with one of the ascending notes of the fundamental pitch’s overtone series. Like the overtone series itself, the rhythms follow an arithmetic progression, so that for every single beat of the fundamental, the first overtone (if played) beats twice, the second overtone beats three times, and so forth. Using the device’s keyboard, each of the sixteen rhythms can be produced individually or in any combination.

it’s a perfect example of what can be easily done with teletype, and using grid provides natural control for the scene. it also shows that adding grid control to any scene can be done with a very few lines:

#1
M SCALE 0 15 30 200 G.FDR.N 0

#8
IF P Z: BREAK
TO.OSC.N Z + 40 PN 1 Z
I + 35 * 30 G.FDR.N Z
TO.ENV.DEC Z I
IF G.FDR.N Z: TO.ENV.TRIG Z

#M
L 1 16: P I + 1 P I
L 1 16: P I % P I + 1 - 17 I
L 1 16: Z I; SCRIPT 8

#I
L 1 16: TO.CV I V 5
L 1 16: TO.ENV.ACT I 1
G.FDX 1 0 1 1 7 1 0 0 16 1
G.FDR 0 0 0 16 1 2 8 1
SCRIPT 1

there are 16 vertical faders. when a fader is set to any value higher than 0 it will enable that note. the fader value determines the note decay. an additional horizontal fader sets the metro script rate. instead of overtone series i’m using a pattern bank as a scale here. one downside with this scene is that you need 16 sound sources, i’m using 4 TXo modules here, alternatively you could use er-301 as well.

as you can see there are only 5 grid ops used in this scene, 2 of them to initialize the UI. here is a couple of demos:

as with many other grid scenes posted here you can easily use it without a grid (i added another fader here to control the waveform):

9 Likes

In the grand tradition of lovingly ripping off Make Noise control surfaces - and because I desperately needed it:

PRESSIN' PALS!

EACH COLUMN, PRESS BOTTOM 2
ROWS TO SEND COL VALUES TO CV
1-4. TO SET COL VALUES, PRESS
ROW 1-4 THEN USE 5 & 6 TO
MOVE BY HALF STEPS. (OR JUST
USE PATTERN MODE MANUALLY)

ALSO IT TRIGGERS TR 1 WHEN YOU
CHANGE COLUMNS. WHEEEEEEEEEEEE

#1
G.BTN.SW G.BTNI

#2
L 0 3: Z I; SCRIPT 6
IF LT Y 0: BREAK
IF G.BTN.V G.BTNI: $ 3
Y -1

#3
P.N Y
IF EQ G.BTNY 4: T 1
ELSE: T -1
P G.BTNX + P G.BTNX T
IF EQ X G.BTNX: $ 5

#4
X G.BTNX
$ 5
TR.PULSE 1
G.BTN.SW G.BTNI

#5
L 1 4: CV I N PN - I 1 X

#6
T ADD Z MUL G.BTNX 4
IF G.BTN.V T: Y Z

#7

#8
Y MUL Z 4
IF GT Z 15: BREAK
G.GBX Z Y Z 0 1 1 1 7 1 1 4

#M

#I
L 0 15: Z I; $ 8
G.GBX 16 64 0 4 1 1 0 0 2 16 2
G.GBX 18 96 0 6 1 2 1 7 4 16 1
G.REC 0 6 16 1 1 15
Y -1

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

0	7	3	6
8	1	1	10
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	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
1000100010001000
1000100010001000
1000100010001000
1000100010001000
0000000000000000
0000000000000000
1000000000000000
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

I should move everything around so script 1 is clear, and then make it so you can ping port 1 to advance. Also I don’t have a variable-brightness grid, so aesthetic suggestions (or really any suggestions) are most welcome.

A not-great-sounding but hopefully illustrative demo:

5 Likes

another option could be using the PARAM knob to enter values. so then when you press in rows 1-4 it updates the current value for that step based on PARAM. the downside is you lose the ability to fine tune a previously entered value. with this option you could also use a fast Metro script to update the selected value while the button is pressed, so then you can press-turn-release.

for non VB grids brightness levels of 0…7 are treated as “off” and 8 and higher as “on”.

added your script to the code exchange page!

Why not both? M could check PARAM to see if it’s changed (happily I have a couple of globals left over), and store the new value in the current track if so. There’s a chance I can do that all in the M script.

The simulator page tells me that varibrights probably look okay-ish; honestly at this point I’m more worried that no one will ever bother with this scene at all. I mean, if you really need more than eight rows of Pressure Points, you’re going to want to enter the pattern values with the keyboard anyway… ah well.

Next I’m trying for a Push-style grid keyboard!

2 Likes

PARAM has some noise on it, so it might appear as it’s changing constantly, so this might not work well if you don’t lose some precision on it.

Oh right, that was a whole thing. hm.

Is it possible to convert this to JF Just Type using the Daemon note settings?
Basically would love to run this but don’t have TXo modules and love the sound of Daemon

i’ve been playing on this today and its stunning, is there a way to save the new chords and inputs after power down?

1 Like