[cheat codes 2] (rev 230319: LTS11 - nb!)

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

confirmed. :heart_eyes:

i am happily stumbling my way around cheatcodes, loving every moment. here are today’s results.

11 Likes

New Norns user here. Is there a way to get the output of the playing tape into the buffers?

I’m super excited about cheat codes and would like to use it in a workflow to build off of prerecorded modular jams. Idea would be something like this: load up longish audio and play in the tape, then start grabbing portions in realtime in Cheat codes buffers to loop, slice, etc. on top of the playing tape.

I see in the Crone signal flow diagram that the tape in comes after the softcut in, but is there anything I’m missing that could make such a workflow possible with the current script?

3 Likes

@SpectralClockworks, welcome!

(edited for incorrectness :P)
i don’t think this is possible given how norns is wired by default. it might be possible to perform some jack rewiring so the tape output is sent to softcut, similar to the approach described here.

i mucked around a bit trying to do this but i don’t understand how tape is wired up well enough get it working (assuming it is even possible).

1 Like

i believe you’d check in params/levels

Thanks @edison & @jaseknighter!

I’d actually tried the level param for tape with no luck. I tried again after reading edison’s post, with oooooo loaded, and it actually worked fine. Went back to CC2, no dice.

I was ready to take the question off this topic, assuming it was a routing issue, but the fact that it seems to work with some scripts and not others makes me wonder…

ah! apologies… i’ve actually never tried it, but always assumed it worked that way. i’m sure dan will holler in a bit, but this would be a really handy way of jamming!

the other option is to just set the buffer to 32 seconds…. then load in your tape to a buffer. i believe it will load in the first 32 seconds of your recording that way. not perfect but had some really rad jams that way with old orgn recordings.

1 Like

No apologies needed at all, your comment was super helpful…I don’t know all the expected behavious so was really at a loss.

After browsing the oooooo code and meditating on the Crone a bit, I see that oooooo is using SoundIn within a custom engine. I believe CC2 uses the standard softcut ins (I’m not as able to skim the lua code as sc code). It looks like the softcut lit bus is just ext and engine, while the aux send (which I assume goes to the engine in) comes after tape and mirrors the level params.

I suspect what would be needed is a utility passthrough engine that just forwarded SC in to out. Maybe I’ll see if I can figure out how to hack that together.

hey y’all hope all’s well!

just to confirm, it’s totally possible to route TAPE playback into softcut (+ cheat codes) without any jack-hacking! :slight_smile:

if you navigate to PARAMETERS > SOFTCUT, there’s an input tape level which is likely -inf. if you bump that up to ~0dB, you’ll be able to route TAPE playback into the live buffers in cheat codes like you would with the incoming audio signal. it does require the tape level on PARAMETERS > LEVELS to be turned up as well – the default norns routing doesn’t allow bypassing monitoring the TAPE signal as you route it into softcut.

just tested + confirmed on my end, so please lmk if there’s anything else and i’ll be happy to help!


just for the code-curious, oooooo bypasses the softcut tape input parameter and sets the level directly depending on the recording mode selected: oooooo/oooooo.lua at main · schollz/oooooo · GitHub

13 Likes

Thanks @dan_derks !

Skimmed your post too fast at first, then tried the softcut params, and voila! (tbh a little bummed I couldn’t introduce myself with a bugfix or feature add PR or something like that, but all in good time!)

4 Likes