[cheat codes 2] (rev 220714: LTS7.2.1 [LFOs + more!])

Thank you very much!

1 Like

I’m having something strange going on. I’m on the 220321 release, but I still see the midi_panic error message. Maybe relatedly, and more importantly, the script doesn’t always detect the Grid, and when it does none of the keys work.

In those no-keys-work situations, this is the error message in Maiden on each keypress:

lua: 
/home/we/dust/code/cranes/cranes.lua:836: attempt to call a nil value (global 'window')
stack traceback:
	/home/we/dust/code/cranes/cranes.lua:836: in field 'key'
	/home/we/norns/lua/core/grid.lua:210: in function </home/we/norns/lua/core/grid.lua:201>

I assume that the problem is on my end, though the Grid does work normally for other scripts.

hi y’all – hope everyone’s well :slight_smile:

you can uncomment this line to get it back!

there’s currently no support for resizing the live buffer to the current pad’s length – i’ll see about adding these ALT gestures back in!

weird! this is when running cheat codes? this looks like it’s somehow grabbing cranes?
if you’ve confirmed you’re on the 220321 release by hitting K2 on the SELECT / SYSTEM / SLEEP screen, does a fresh install of cheat codes 2 help?

1 Like

That didn’t fix it, but a SYSTEM > RESET did. Not sure what the issue was, but I noticed that there was also a clock error in the mix, so I gave it a shot and :person_shrugging:

2 Likes

The time has finally come! Cheat Codes 2 is used in a lot of places on the album (out in two days!), but the main place it was used was this track:

This track came directly out of my first deep dive into Cheat Codes 2 and the Music Hackspaces courses. Just one short loop from a Deckard’s Dream mk2 pad, used on all 3 banks:

One bank is configured with a lot of highpass to accentuate the noise, and a random pad pattern. One bank is configured with a lot of volume LFOs to get a rhythmic tremolo effect (and another random pad pattern). And then finally one bank gets performed more actively with delays, random patterns, and arpeggios.

Thanks again for all your wonderful work on this script, @dan_derks !! I’m sure it’ll be a key tool in my toolbelt for years to come :smile:

17 Likes

Thanks @dan_derks as always for the great support!

A couple observations/questions/requests after spending some time:

(1) Is it possible to make loose ‘the time from first press to the time the recording button is pressed again’ rather the the time ‘the recording button is disengaged’? For me, this would be a simpler gesture when trying to record a loop in time that will also set BPM: Press Record to Arm>Play Pattern that is x Bars (recording starts on first pad pressed)>Press Record on downbeat>Pattern is now looping in time and BPM is set (drift not withstanding). I find trying to release (disengage) the record button in time to be a bit tricky and also kinda ties up right hand rather than having both hands available to play my pattern.

(2) ALT+Page doesn’t seem to cycle to previous page? Is this an outdated feature?

(3) Params > CROW IN/OUT > Crow Out 4 > transport pulse doesn’t seem to work (no pulse when CC transport is running). Though transport gate works as expected.

Hi! I just got a fates and dove into cheat codes straight away. I’m having an issue tho…I don’t understand how saving a collection works! I’m not sure what I’m doing wrong but I’ve had two excellent sessions bite the dust in as many days (not that I’m too distraught, it takes about fifteen minutes to get something amazing to come out of cc.2 - it’s that good).

Here was my process: after getting things to where I liked them I went to params>collections>save new collection (collection named ‘LA MER.CC2’ both times [deleted the first one once it was clear nothing saved] in case that is important). The second time over I also saved the live buffers, and I do have audio saved in the cc path. On start up I go again to params>collection and load the collection. I get the collection name on the main screen but that’s it. None of my parameters are saved, buffers are empty - it’s essentially a new, empty project.

What am I doing wrong?

Edit: forget to add that ‘Collect live buffers’ was on for both save attempts.

hi hi! hope all’s well with y’all :slight_smile:

@juje – sorry to hear about the trouble! could you please share anything that posts to maiden as you try to load your collection? i’m wondering if the space in the filename is causing trouble with loading.

@FLORINS – i’ll take a look at these items in the coming week! last week was joyfully busy, apologies!

1 Like

Aha! Looks like we have a culprit.

loading...
/home/we/dust/data/cheat_codes_2/names/LA MER.cc2
pset >> read: /home/we/dust/data/cheat_codes_2/collection-LA MER/params/all.pset
pset :: /home/we/dust/data/cheat_codes_2/collection-LA MER/params/all.pset not read.

Weirdly the tempo was actually restored, unless cc remembers that between sessions regardless of what collection is loaded :thinking:

Did a little more futzing about. Made a new collection with no spaces and made some changes to the randomizations and everything loaded. No ...pset not read message. I didn’t record anything into the audio buffers but i think that was it! Silly me! Thanks for the speedy reply @dan_derks

1 Like

ah yep!

the trouble is definitely saving with spaces – the directory creation just totally fails unless it’s a single string (so dashes or underscores could work in lieu of spaces).

maiden errors from my test using `LA MER` as a name during collection save:
mkdir: 
cannot create directory ‘MER/’
: Permission denied
mkdir: 
cannot create directory ‘/home/we/dust/data/cheat_codes_2/collection-LA’
: File exists
mkdir: 
cannot create directory ‘MER/banks/’
: No such file or directory
mkdir: cannot create directory ‘/home/we/dust/data/cheat_codes_2/collection-LA’
: File exists
mkdir: cannot create directory ‘MER/params/’
: No such file or directory
mkdir: 
cannot create directory ‘/home/we/dust/data/cheat_codes_2/collection-LA’
: File exists
mkdir: 
cannot create directory ‘MER/arc-rec/’
: No such file or directory
mkdir: cannot create directory ‘/home/we/dust/data/cheat_codes_2/collection-LA’
: File exists
mkdir: cannot create directory ‘MER/patterns/’: No such file or directory
mkdir: cannot create directory ‘/home/we/dust/data/cheat_codes_2/collection-LA’
: File exists
mkdir: cannot create directory ‘MER/step-seq/’: No such file or directory
mkdir: cannot create directory ‘/home/we/dust/data/cheat_codes_2/collection-LA’
: File exists
mkdir: cannot create directory ‘MER/arps/’: No such file or directory
mkdir: cannot create directory ‘/home/we/dust/data/cheat_codes_2/collection-LA’
: File exists
mkdir: 
cannot create directory ‘MER/euclid/’: No such file or directory
mkdir: 
cannot create directory ‘/home/we/dust/data/cheat_codes_2/collection-LA’: File exists
mkdir: cannot create directory ‘MER/rnd/’
: No such file or directory
mkdir: cannot create directory ‘/home/we/dust/data/cheat_codes_2/collection-LA’
: File exists
mkdir: 
cannot create directory ‘MER/delays/’
: No such file or directory
mkdir: cannot create directory ‘/home/we/dust/data/cheat_codes_2/collection-LA’
: File exists
mkdir: cannot create directory ‘MER/rec/’: No such file or directory
mkdir: cannot create directory ‘/home/we/dust/data/cheat_codes_2/collection-LA’
: File exists
mkdir: cannot create directory ‘MER/misc/’
: No such file or directory
mkdir: 
cannot create directory ‘/home/we/dust/data/cheat_codes_2/collection-LA’
: File exists
mkdir: 
cannot create directory ‘MER/midi_output_maps/’
: No such file or directory
mkdir: cannot create directory ‘/home/we/dust/data/cheat_codes_2/collection-LA’
: File exists
mkdir: cannot create directory ‘MER/macros/’: No such file or directory
mkdir: 
cannot create directory ‘MER/’
: Permission denied
mkdir: cannot create directory ‘/home/we/dust/audio/cc2_live-audio/LA’
: File exists
mkdir: cannot create directory ‘MER/’: Permission denied
mkdir: cannot create directory ‘/home/we/dust/audio/cc2_live-audio/LA’
: File exists
mkdir: cannot create directory ‘MER/’: Permission denied
pset >> write: /home/we/dust/data/cheat_codes_2/collection-LA MER/params/all.pset
pset: BAD FILENAME
lua: 
/home/we/norns/lua/core/clock.lua:65: /home/we/dust/code/cheat_codes_2/cheat_codes_2.lua:6832: standard output file is closed
stack traceback:
	[C]: in function 'error'
	/home/we/norns/lua/core/clock.lua:65: in function 'core/clock.resume'
	/home/we/norns/lua/core/clock.lua:24: in function 'core/clock.run'
	/home/we/dust/code/cheat_codes_2/cheat_codes_2.lua:5683: in function 'textentry.callback'
	/home/we/norns/lua/lib/textentry.lua:78: in function 'textentry.exit'
	/home/we/norns/lua/lib/textentry.lua:107: in function 'textentry.key'
	/home/we/norns/lua/core/menu.lua:143: in function </home/we/norns/lua/core/menu.lua:120>

so looks like the save just never occurs – i’ll take a look at supporting filenames with spaces, apologies for the bummer but glad it’s all working out without spaces :sparkles:

2 Likes

@21echoes, i’m so so grateful for your spending time with cheat codes and working in into your explorations. the preview tracks were absolutely fantastic and i’m stoked to dig into the full listen this weekend!!


rev 220507: LTS 5.1

very tiny update, but protects against the filename issues during collection saves @juje describes above.

NEW

  • if a collection’s name contains spaces, it will be automatically reformatted with dashes – eg. LA MER will be saved as LA-MER
  • if a collection’s name contains any other characters or formatting which will result in Lua syntax errors, preventing full save/restore, there’s a heads up displayed on the norns screen
    error: bad filename
       will not save
    
    as well as maiden:
    attempting to save collection '?<9961/'
    CANNOT SAVE COLLECTION WITH THAT NAME
    
    in which case, just adjust the name and it’ll accept. you’ll get an on-screen notification of successful save with:
    saved!
    

hope all’s well with y’all <3

11 Likes

@dan_derks after spending the past 2 weeks with this script I have to say you have created something truly magnificent and my dream instrument of a sampler! Thank you so much for your contribution!
I have been using a launchpad (tried using 2 to simulate a 128 grid but actually prefer using one for a 64 grid) in 64 grid mode and while I’m starting to dig deep into the delay page I was wondering if there’s a way to sequence each bank in the delay page like there already is in the 128 grid version? Or is there a special way to do it on the 64 grid? I’ve been going through your courses which I’ve found very very helpful too.

6 Likes

Has anyone been able to successfully sync cheat codes as a follower to the op1 as leader? I assumed norns would pick up the midi clock from op1 but I haven’t figured out how to get it to work. I have been able to sync norns to midi with other devices and crow.

new to lines, and to monome, but spent the past few weeks getting to grips with cheat codes and it is spectacular. already learned so much but still feel like there are worlds to discover. thank you @dan_derks for your generosity!

a feature request I would love to see would be selecting which input to sample (or maybe this is possible?). I use two mono inputs into my norns shield and it would be amazing to be sampling one while only monitoring the other.

I know a fairly rudimentary mixing desk would resolve this but I love minimal set-ups and using norns’ comp + reverb to glue everything together.

6 Likes

thanks so much for the very positive vibes, everyone! it means a great deal to see new adventures continue to form with the script :toolbox: :sparkles:

rev 220513: LTS 6

NEW

  • support for user script side-loading, which allows an artist to bundle their own Lua sketches with a saved collection – more on this below the break!
  • added parameter for adjusting levels for audio coming into the live buffer (@dgsiii , thank you for asking!)

FIXED

  • delay bundles actually save + restore now!! (dang, this has been borked for so long, i had no idea lol)
  • delay bundle saving only takes 250ms instead of a full second (dang, a 1 second hold is long)
  • grid now redraws as soon as its plugged in (dang, how did i forget to do this before??)
  • if live buffer was recording when collection was saved, the rec flag was still enabled when it was reloaded, even though it wasn’t actually recording (no dang, just never noticed before!)

user script side-loading

okay, so, @TPeak , your question cracked a bit of daylight onto my brain in a really nice way:

the pattern sequencer on the 128 is a good target for repurposing for this, but i completely rewrote the sequencing mechanism for cheat codes yellow (for new folks, this is the working title for the next and final version of this script) and wanted to explore alternatives which could serve a dual purpose: getting this feature request met + getting folks scripting in a low impact way.

so, LTS 6 introduces a user script side-loading mechanism which allows you to roll your own executions of functions from the main script, or any other code you might want to run in parallel!

how it works

( edit: added expanders cuz it was a lot of text :slight_smile: )

location to save in

<~~ click to expand
  • save a collection (let’s use AEILL for this example)
  • under data > cheat_codes_2, you’ll find a collection-AEILL folder
  • inside of that folder, create a blank user_script.lua file (or import one!)
    • important! the file needs to be named user_script.lua in order for cheat codes to catch it when loading your collection
    • important! don’t put it inside of any of the other folders inside of the collection-AEILL folder (like, arps or banks, etc), just create it on the same level as those folders, eg:

how to build a user_script

<~~ click to expand

as of rev 220513: LTS 6, cheat codes has some callback actions to support user scripts:

  • user_script.init() is called when cheat codes finds a user_script.lua file inside of a loaded collection’s folder
  • user_script.transport_start() is called when the transport starts, useful to keep clock-based functions synced up with the main script
  • user_script.transport_stop() is called when the transport stops, useful to stop any clock-based functions running or resetting state when the main script stops

a boilerplate user script would then look like:

-- required container, do not change this:
local user_script = {}

-- this function is called whenever a loaded collection
--   has a 'user_script.lua' file in the collection:
function user_script.init()
  print("hello from the user script")
end

-- this function is called whenever the transport starts:
function user_script.transport_start()
  print("user script started")
end

-- this function is called whenever the transport stops:
function user_script.transport_stop()
  print("user script stopped")
end

-- required return, do not change this:
return user_script

other functions and variables can totally be added to this boilerplate! just prepend each function with user_script.. for variables, either use locals or try to pick unique variable names.
want to check to see if cheat codes already has something registered? just execute the keyword you want to use in the maiden repl (the >> at the bottom of maiden) and if it returns nil then you’re good!

example 1: delay snapshot step sequencer

<~~ click to expand

with a user script, totally! here’s a full script for a step sequencer which starts when the main script’s transport starts and stops + resets position when the transport stops, where you fill in my_delays[x].steps (x = 1 for L delay, x = 2 for R delay) to sequence snapshots:

cheat codes user script: delay sequencer example · GitHub

if you’re curious about the delay grid page’s snapshot numbering along the sides, it runs like this (with other functions present for orientation):

L L L length L rate R rate R length R R
1 9 x2 x2 x2 x2 1 9
2 10 /2 /2 /2 /2 2 10
3 11 rev rev 3 11
4 12 x x x x 4 12
5 13 x x x x 5 13
6 14 x x x x 6 14
7 15 x x x x 7 15
8 16 x x x x 8 16

so, incorporating that example would look like:

  • build a set with delay snapshots
  • save it as a collection
  • place the example script in that collection’s data/cheat_codes_2 folder
  • build your own delay snapshot step sequencer by editing the user_script.lua file in maiden to match your saved snapshots and how you want the sequencer to behave, eg:
    • line 13: [1] = 1
      • change [1] to [9] to execute on the 9th step
      • change = 1 to = 6 to call up the 6th snapshot instead of the first
    • line 17: end_point = 64
      • change 64 to 16 to execute a 16-step sequence (or change the start_point, too?!)
    • line 19: sync = 1/4
      • change 1/4 to 1 to change from 1/16th notes to whole notes (assuming in 4/4)
  • reload the collection and your user script will be loaded!

example 2: pad step sequencer

<~~ click to expand

this one’s the same concept of building your own step sequencer inside of cheat codes, all with code, but focused on sequencing pads instead of delay snapshots:

cheat codes user script: pad sequencer example · GitHub

same cadence applies:

  • build a set
  • save it as a collection
  • place the example script in that collection’s data/cheat_codes_2 folder
  • build your own pad step sequencer by editing the user_script.lua file in maiden to match your whims!

closing note

user script side-loading can open up a ton of new gestures, which i’m very excited to explore with y’all!!

there are a lot of functions in cheat codes which could be looped in, but the script is kinda sprawling (it represents basically my learning process for ~3 years), so i’m very happy to help point folks toward the functions they want to subvert and remix! just lmk :slight_smile: :gem:

36 Likes

This update is a wild piece of work, I appreciate the work you do. Really looking forward to diving in!

4 Likes

I’m interested to experiment with using 2 LPs as a 128 grid with CC2, but every time I try these instructions, when I get to the last bullet “reboot the script”, it always resets “grid size” to 64 and “midigrid?” to yes in parameters. I’ve tried rebooting the norns before restarting the script, and saving or deleting presets, but in all cases it resets params to 64/yes.

I’m using 2 Launchpad Xs with a norns shield, and they function as a 128 grid with the ‘neauoire/tutorial/9_grid.lua’ script.

I’ve reviewed this forum (what a great community here!), searched for other steps, but must be overlooking something or perhaps something has changed?

Anyway, Dan - I’m so impressed with your work and looking forward to learning more about this remarkable script/instrument/world!

EDIT: After some power cycles, installing the grid-test script, setting CC2 params to 128 and midigrid yes, and saving presets, it seems to be working! I’m super excited to go throught the musichackspace courses and really dig into this!

2 Likes

You are an amazing human.

6 Likes

@dan_derks, are these grid copy/paste instructions still correct? i’m finding that in order to copy/paste i have to release the ALT key between the copy and paste steps. so, i’m thinking the instructions are actually more like:

enable pad focus mode → hold global ALT + press pad you want to copy → release global ALT → hold global ALT+ press pad you want to paste into.

does that sound right?

2 Likes

ooo stoked you’re digging into the script, thank you @jaseknighter !!!

:gem:

it sounds like an accurate assessment of a bug, for sure! idk when this got in there, but it’s cleared up now and copy/paste follows those details!

rev 220517: LTS 6.1

FIXED

  • pad copy/paste now works as historically described:

this is all aligned! the vertical 128 experience on the two horizontal launchpads is reportedly wonky experience, so the script will encourage the 64 layout for the launchpad’d – but you can override it in the params and save that and you should be good!

this is super sweet :hugs: i’m just hanging out, v v grateful for y’all <3

6 Likes