> teletype: grid code exchange


#21

same. indeed amazing. thanks for sharing! twenty likes


#22

Thanks @xeric and @sakul , I’m glad you like it. Don’t forget to play with different chords in the tracker screen. The last 8 slots are empty! :slight_smile:

@scanner_darkly I have a question. Is there any more efficient way to do this. It seems a shame to only be able to set up 3 groups of buttons in the initial script. The code is just a bit too long to combine the G.GRP and G.BTN/G.BTX commands in a single line


#23

just as a learning opportunity for myself: what happens if you combine G.GRP lines with a semicolon?


#24

It just doesn’t quite fit :frowning:


#25

ah, what about L 0 2: G.GRP I? is there some sequential relationship between G.GRP the G.BTN line that follows, where you couldn’t do a mass set of the G.GRP with a loop?


#26

The G.GRP sets the group number for the subsequent set of buttons so it’s important to be sequential


#27

Amazing indeed. We’re gonna make a lot of awesome little sequencers !
Here was my little idea today :


#28
thank you very much

#29

yeah, I can be used as a regular variable. with version 2.1 a cool thing about it is - it’s local to whatever script it’s used in, so there is no danger of this variable getting overwritten in some other script.

@kingcons already replied - thanks! i will just add that to do it inline you just use single ticks like this.

re: buttons - exactly! being able to do different actions on press and release opens a lot of possibilities that are worth sacrificing a line for something like IF NZ G.BTNV. consider controlling a gate with a momentary button, you would want to know when the button is released so you can set the gate to low. for latching buttons it does ignore button releases since it doesn’t change the state. i’m glad you brought this up - i should add this explanation to the button study.

@ghost - amazing scene, thanks for posting it! i’m going to create a page where we can track all the scenes posted so we can find them easily, and i need to add a grid category to the teletype codex repository.

@ghost @chapelierfou - it’s so great to see these. this is exactly what i hoped would happen with the grid extension. thank you!

i’m going to start a separate code exchange thread for grid scenes specifically, i think it warrants having its own at this point. if you’re okay with it i will also ask the mods to move your posts into that thread once it’s set up. also for feature requests and discussion on the language extension itself let’s use the main grid thread so we can see them all in one place.

edit: moved feature request discussion to the main grid/teletype thread Grid ops / integration [beta nov 23]


#30

You’ve really opened up the teletype in such a great way, and hugely increased the possibilities of using the grid with eurorack, so thank you! Is it too early to be talking about ‘Arc ops…’!!!

Happy for you to move the post wherever. A dedicated thread might be best. I’ve just updated the scene with forward/reverse and chord edit.


#31

Simple and gorgeous, a funny earthsea/rene crossbreed. :slight_smile:


#32

on the back of my mind :slight_smile: focusing on grid for now, but it totally makes sense to support arc at some point too. arc integration should be much simpler actually…


#33

Yesterday I made a multihead sequencer, inspired by the Fugue Machine, with my buddy Ollie who is a professional games programmer. I learnt a lot about writing code from him and we used some pretty cool techniques. The base code for the tapeheads is only a few lines and can run up to 63 tape heads if you want! We brought that down to 4 for a nicer user interface. I’ve tried to explain every line of code here. For those of you who are new to coding (like me), there are some really neat tricks in here. In particular we made good use of chaining Loop ( L ) commands and passing variables through them to other scripts. I’ve tried to make it clear how each script is linked.

On the main page you have the sequencer. Botton left button enters edit page, 2nd bottom button is a reset button. The 4 buttons at the bottom right are wrap/bounce buttons which decide on tape head behaviour when they reach the end of the sequence.

Edit mode hides the step sequencer and brings up 4 buttons on the left which act as mute buttons for each playhead. The 4 faders act as clock dividers for each track.

It sends 4 pairs of Gate/CV

Here’s a quick demo of it in action:

Things I’d like to add: (hopefully possible with the soon to be added group Ops, which should free up some space!)

Exclusive notes/step (currently it just reads the lowest, which isn’t very elegant)
Pitch shift/octave shift per tapehead
Global Scale Editor
Global Pause button or maybe per tapehead?
Trigger length dependent on clock division

Fugetta

//M
//Line 1: The metro starts by setting all sequencer buttons (group 0) to brightness level 2.
//Line 2: It then starts a loop which applies the local variable I to global variable X, and triggering script 1. This essentially triggers script 1 4 times with X at 1,2,3 and 4. (You can in theory change the Loop range to be higher to have more play heads, but it wouldn’t work with the user interface…)
//Line 3: This detects if button 117, the reset button, is on. It then sets the wrap/bounce setting for each track to ‘wrap’. (As metro is triggered by this button it will engage as soon as pressed.)
//Line 4: Metro will be disabled as long as the reset button is held.
//Line 5: This detects if the reset button is on and subsequently sets all sequencer button (group 0) brightness to 2 (normal)
//Line 6: Sets PARAM knob to control BPM

#M
G.GBTN.L 0 2 2
L 1 4: X I; SCRIPT 1
IF G.BTN.V 117: G.GBTN.V 1 0
M.ACT - 1 G.BTN.V 117
IF G.BTN.V 117: G.GBTN.L 0 2 2
M SCALE 0 16383 300 20 PARAM

// Initialisation script sets up 2 groups of buttons: Group 0 are the main sequencer buttons, group 1 are the wrap/bounce buttons at the bottom right. We then run out space and so defer to script 7 for more initialisation but not before setting the active group to 2. (see #7 for continuation
//Line 1: Sets button group to 0
//Line 2: Creates step sequencer buttons
//Line 3: Sets button group to 1
//Line 4: Creates wrap/bounce buttons
//Line 5: Sets group to 2. Then triggers script 7 (which acts as an extra initialisation script)

#I
G.GRP 0
G.BTX 0 0 0 1 1 1 2 0 16 7
G.GRP 1
G.BTX 112 12 7 1 1 1 4 0 4 1
G.GRP 2; SCRIPT 7

//#1 Is triggered at every metro beat. It runs 4 times, once for each X = 1,2,3 & 4 (see #M Line 2)
//Line 1: Sets variable T to the current playhead (X)’s clock divider counter (PN 3) and adds 1. We are using T as a local variable. Then sets variable B to the reset buttons value
//Line 2: Sets the clock divider (PN 3) counter to T, therefore incrementing by 1. This is wrapped between 1 and the clock division value (PN 2)
//Line 3: If the clock divider counter (PN 3) is at 1, Script 2 will be run (which will move the active playhead to the next step)
//Line 4: This is looped 7 times, applying local variable I to Y which and triggering Script 8, taking the value of Y with it (Script 8 will light up the playhead position)
//Line 5: If the reset button is being held (B - see line 1), sets the clock divider counter (PN 3) to 0 and the playhead position (PN 1) to -1
//Line 6: If the reset button is being held, sets playhead direction to forward and sets variables D and A to 0 (Reviewing this, I’m not certain why setting these variables here was necessary)

#1
T + PN 3 X 1; B G.BTN.V 117
PN 3 X WRAP T 1 PN 2 X
IF EQ 1 PN 3 X: SCRIPT 2
L 0 6: Y I; SCRIPT 8
IF B: PN 3 X 0; PN 1 X -1
IF B: PN 0 X 1; D 0; A 0

//#2 This is the script to move the playhead 1 step in it’s direction. It is triggered by Script 1, Line 3.
//Line 1: Sets local variable to the current playheads direction (PN 0 X). Then it sets variable C to the sum of the playhead direction (-1 or +1) and the playhead position.
//Line 2: If the corresponding wrap/bounce button is on (set to bounce) go to script 3 (the bounce rules)
//Line 3: Otherwise set C to wrap between 0 and 15
//Line 4: The playhead position (PN 1) is then updated to C
//Line 5: This is run 7 times, applying local variable I to A (I was previously set to PN 0 X (direction)) and taking it through to script 4.

#2
I PN 0 X; C + I PN 1 X
IF G.BTN.V + 111 X: SCRIPT 3
ELSE: C WRAP C 0 15
PN 1 X C
L 0 6: A I; SCRIPT 4

#3 This is for bouncing playheads. It takes variable C from script 2. It takes 2 steps to reverse a play head, resulting in steps 0/15 being triggered twice, for the most musical effect.
//Line 1: If the playhead is at position 15, it sets the direction variable (PN 0) to -1 it’s current value
//Line 2: If the playhead is at position 0, it sets the direction variable to +1 it’s current value

#3
IF EQ C 15: PN 0 X - PN 0 X 1
IF EZ C: PN 0 X + PN 0 X 1

#4 This is for triggering pulse and CV outputs. The script is run once per single sequencer button. It is run in response to Script 2, Line 5.
//Line 1: Sets local variable D to be the the sequencer button identity, informed by playhead position (PN 1) and direction (A)
//Line 2: If the reset button (117) is on, stops the script
//Line 3: If the sequencer button is on, a trigger is made at the corresponding gate
//Line 4: Sets local variable I to the new playhead position (PN 0 + A) added to 9. A will give the look up position for note from the scale which is saved in PN 0, Index 9 - 15. I will then be set to that note (N) number
//Line 5: If the sequencer button is on, set the corresponding CV out to the note value of I

#4
D + PN 1 X * 16 A
IF EZ G.BTN.V + 117 X: BREAK
IF G.BTN.V D: TR.P X
I PN 0 + A 9
IF G.BTN.V D: CV X N I

//#5 Triggered by the Clock divider faders in edit mode - sets clock division
//Line 1: Loops 4 times - sets each clock division memory (PN 2) to the fader value

#5
L 1 4: PN 2 I G.FDR.V I

//#6 This is triggered when the edit button (116) is pressed. It creates the clock divider control faders
//Line 1: Sets active group to 3
//Line 2: Creates 4 horizontal faders
//Line 3: Disables and hides the sequencer trigger buttons when in edit mode. It will re-enable this group on leaving as the script is triggered again.
//Line 4: Sets the range of the faders to 1-8
//Line 5: Sets the mute buttons (Group 5) to be enabled when in edit mode and disable when leaving.

#6
G.GRP 3
G.FDX 1 2 1 8 1 0 4 5 1 4
G.GRP.EN 3 G.BTNV
G.GRP.EN 0 - 1 G.BTNV
G.GFDR.RN 3 1 8
G.GRP.EN 5 G.BTNV

//#7 is triggered on initialisation, the current group is 2. We then create 2 new buttons.
//Line 1: Button 116 is a latch button to enter edit mode by triggering script.
//Line 2: Button 117 is a reset button which triggers the metro script.
//Line 3: Set group to 5
//Line 4: We create a new group of buttons in group 5 which will be the active/mute buttons.
//Line 5: These are then de-activated and set to off. Therefore all tracks are muted on start up.

#7
G.BTN 116 0 7 1 1 1 4 6
G.BTN 117 2 7 1 1 0 4 9
G.GRP 5
G.BTX 118 0 1 1 1 1 5 0 1 4
G.GRP.EN 5 0; G.GBTN.V 5 0

//#8 Lights up the active playhead positions on the grid. It is triggered by Script #1 7 times (each row) for each play head. Therefore 27 times.
//Line 1: Local variable D is set to the sequencer button ID number - This is calculated from the playhead position (PN 1 X) and the row number (Y - sent through from script 1)
//Line 2: Lights up the button - play heads 1-4 have slightly different levels to try and distinguish them

#8
D + PN 1 X * 16 Y
G.BTN.L D + 4 * 2 X

//#P
// P0 1-4: Direction of play ; P0 9-15: Scale
// P1 1-4: Position of playhead
// P2 1-4: Clock division
// P3 1-4: Clock divider counter (will increment on each metro)

#P
5	5	6	0
1	1	1	1
0	0	0	0
63	63	63	63

0	0	0	0
1	2	4	3
1	8	4	2
1	5	4	1
1	7	4	4
0	13	5	4
0	0	0	0
0	0	0	0
0	0	0	0
12	0	0	0
11	0	0	0
9	0	0	0
7	0	0	0
5	0	0	0
4	0	0	0
2	0	0	0
0	0	0	0

#34

amazing, i love seeing more complex scenes, it really shows how far we can push this! (although i should add i don’t want folks to think that grid scenes have to be necessarily complex - adding some basic grid control to any scene is very easy and fun). and thank you for posting a detailed explanation!

@chapelierfou and @ghost - added your scenes to the index page. i really appreciate you sharing your creations here.


#35

Glad you liked it. I actually found going back through all the code a really useful exercise for myself. The Github index is a really great way to keep track of all the projects, thanks for adding. Can I suggest that for Daemon, you call it ‘Daemon for Just Type’ as it quite specifically needs to work with Just Friends.

Also, as we update our projects, is it better just to post the new script in a new post or go back and edit the previous posts? I can see benefits/drawbacks in both approaches.


#36

(edit, sorry i still can’t figure out how to post code properly…such a newbie !)
Here is a nice little 8 step pitch sequencer.
Clock is 1.
The left half is the 8 step pitch sequence.
The right half is :

  • octaves per step
  • scale selection (currently 4 available, Major, Minor, ?? and ??)
  • Transposition (in scale)
  • clock reset



#1
G.CLR; Z WRAP + Z 1 0 7
G.REC + Z 8 3 1 8 10 10
G.REC Z 0 1 8 7 7
D - * 12 G.FDR.N Z 36
SCRIPT 3

#2
IF NZ G.BTNV: Z 7

#3
T - * 8 G.FDR.N 8 8
T - * 8 G.FDR.N 8 8
CV 1 N + D PN 1 + T PN 0 Z
TR.P 1

#4
L 0 7: G.BTN.V + I 64 0
G.BTN.V G.BTNI 1
P.N 3
L 0 7: P I - PN 1 + T I 36
A PN 3 - G.BTNI 64
CV.OFF 1 N A

#5

#6

#7
G.BTN.SW G.BTNI
P.N 0; P.L 8
X - 7 % G.BTNI 8
P.I / G.BTNI 8; P.HERE X
G.FDR 8 8 0 4 1 0 5 0
G.BTX 64 8 1 1 1 1 7 4 8 1

#8
G.GRP Y; A MUL Y 8;
G.BTX A Y 0 1 1 1 0 7 1 8
B - 7 Y
G.BTN.SW + A B
G.FDX 0 8 3 1 5 1 3 0 8 5
G.FDR.N Y 3

#M

#I
L 0 7: Y I; SCRIPT 8
L 7 0: Y I; SCRIPT 7
Z 0
G.BTN 127 15 0 1 1 0 15 2

#P
8	32	0	0
1	1	1	1
0	0	0	0
63	63	63	63

1	36	0	0
1	38	0	2
2	40	0	4
4	41	0	5
2	43	0	7
7	45	0	9
2	47	0	11
5	48	0	12
0	36	0	0
0	38	0	0
0	39	0	0
0	41	0	0
0	43	0	0
0	45	0	0
0	46	0	0
0	48	0	0
0	36	0	0
0	38	0	0
0	40	0	0
0	42	0	0
0	43	0	0
0	45	0	0
0	46	0	0
0	48	0	0
0	36	0	0
0	38	0	0
0	39	0	0
0	42	0	0
0	43	0	0
0	44	0	0
0	47	0	0
0	48	0	0
0	0	0	0
0	0	0	0
0	0	0	0
0	0	0	0
0	0	0	0
0	0	0	0
0	0	0	0
0	0	0	0
0	0	0	0
0	0	0	0
0	0	0	0
0	0	0	0
0	0	0	0
0	0	0	0
0	0	0	0
0	0	0	0
0	0	0	0
0	0	0	0
0	0	0	0
0	0	0	0
0	0	0	0
0	0	0	0
0	0	0	0
0	0	0	0
0	0	0	0
0	0	0	0
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
0000000000000010
0000001000000100
0001000000000100
1000000000000100
0000000010000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000

2	2	2	2	2	2	2	2	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0

#37

if it’s just a correction or some additional info maybe edit the original post, if it’s some changes based on the discussion here a new post probably makes more sense? for the index doesn’t really matter, i can just add all the relevant posts under the same header.

i’ve updated the name of your scene!

@chapelierfou - really nice, very playable and immediate. looks like 1 row still available :slight_smile: - could use that for reset too (just using a fader to set the total sequence length). or use it as another track to specify steps with enabled probability which could be used to switch octaves or something else (or a probability based reset?). another interesting thing to try would be driving the right side with its own clock (like a division of the main clock), then you start getting into kria territory. i’ll add the scene to the index, what would you like me to call it? “slice + seq”?

for code you need to surround it with single ` if it’s inline:

`like this`

for bigger blocks use triple ``` before and after (and place them on their own lines):

```
like this
```

#38

Thanks !
I’ll make some use of this damn row… Could be mutes as well. ‘Slice + seq’ is not representative of the scene, i propose “ST8P” because i’m lazy.


#39

that’s perfect! added.


#40

is there a link for this particular sequencer? I would love to try it myself!