this thread is intended to collect some out-loud thoughts about revising existing norns lib modules and perhaps introducing a few new ones. as we sort out concrete plans, we can migrate relevant conversations to github.
it’d be fantastic if folks could pair-program these – for example, i’ve pretty much approached programming exclusively through norns and brute-forcing my way toward specific “art goals.” i learn so so much from working with others who have prior experience in other contexts. i suspect many folks will enter through this door, especially as the community grows. as such, it’d be awesome to broaden (and document!!) the range of modules and meta-structures so that folks don’t have to reinvent these building blocks or spend hours trying to grok utilization of them.
to the point of the previously-linked thread, this process would also likely help establish a “house style” that could be looked to as folks move into Lua and functional programming.
As noted in Kria-midi thread- I’ve got the first inklings of a midi/crow output module - it’s note only for now but allows for local configuration of how you have crow setup that survives between script upgrades and could be used cross scripts.
I’ll be coming back to it because I’m itching to start a new script I’ve thought of (more when I’ve actually got something to show for it) and that will use a lot more of crow
I’d be interested in seeing what you’re doing with this. I’ve considered building a sort of grid gesture library which extends the existing norns grid class, but keeps track of things like which pads are currently “held,” or if the current press is a “double click,” so your script doesn’t have to manage all of that state. I’m not sure if this would make too many assumptions about how the user may want to use the grid though. Maybe this kind of stuff is best left up to script authors to implement individually.
this would cover what you mentioned and a lot more things (like multi-key control paradigms, pattern recording, quantization, state management, all wrapped up in an expressive / hopefully easy to use and extensible syntax)
don’t want to say too much since it’s early - but probably a good thing to mention so nobody does the same work twice
my app msh has a super preliminary version of it which I ported over from javascript
I’m working on a lib that can display and edit any paramset. It’s functional now, but I’d like some feedback on ease of use before I’d deem it complete. Was thinking it might fit inside the UI lib, but I have yet to take a look around in there.
Less of a code suggestion and more of a documentation suggestion.
The way I personally find it easiest to program is the “find the pattern” method. Basically, I’ll come up with an idea of what I want to do and then try to find examples of something doing that thing. I think it would help out if the docs could include some examples in the form of links out to scripts or maybe even commits that implement certain features or do certain things. For example, I think this kind of thing is super useful:
I’ve been thinking of doing something similar for showing how to work with note states in the new clock system (clock.run with params, clock.sleep for note length, using a counter (and why you need it) to hold note states maintaining a buffer of on notes, etc.). i.e. this snippet which I’m still making sure is solid first
local noteCounter = 1
local heldNotes = {}
function pulseNote(freq, gateLength)
local currentNote = noteCounter
noteCounter = noteCounter + 1
engine.start(currentNote, freq)
clock.sleep(gateLength)
engine.stop(currentNote)
end
function playNote (noteNum, gateType, cur)
local freq = MusicUtil.note_num_to_freq(noteNum)
-- print(cur.nextStep .. ':' .. cur.nextStage ..' - play note ' .. freq .. 'hz of gate type ' .. gateType)
if gateType == 'pulse' then
clock.run(pulseNote, freq, cur.gateLength)
elseif gateType == 'hold' then
local currentNote = noteCounter
noteCounter = noteCounter + 1
table.insert(heldNotes, currentNote)
engine.start(currentNote, freq)
end
end
function stopHeldNote ()
local noteToStop = table.remove(heldNotes)
if noteToStop ~= nil then
engine.stop(noteToStop)
end
end
Maybe we need a place to house this kind of stuff that’s not just threads on lines.
And I will say I, love the procedural style of working with lua in norns/crow that a lot of scripts use. I wish engines were the same…every time I try to open a supercollider file to make some change I end up closing it more confused than when I started
EDIT: one more reason I think this could be good is that it could make it easy to find the most up to date way of doing things (provided the docs are kept up to date)
what i’m thinking from a docs standpoint is that we identify the common “I want to do this thing that is totally already implemented elsewhere” stuff and create/enhance the lib entries to make it easy to include in your script. so then documentation of these entries becomes an API guide. I think the original norns scripting docs still fulfill their original purpose – to get you thinking about musical code and show you how to get from small idea to instrument relatively quickly.
where we’re growing to (i think) is identifying the building blocks for complex ideas and helping folks recycle common elements.
i would love to contribute although i’ve hit a blocker of not finding the right workflow/setup - do you ssh in direct to Norns and make edits there? Or run a Norns setup in Docker?
I’ve always admired how SuperCollider had a bunch of examples in their docs, which are also available in a window right inside the editor. Looks like LDocs (the lua doc-writing tool that norns uses) has that ability based on this (also a plug for the lua functional lib). We could embed the code examples straight in the API page.
@nattog probably the easiest is to use maiden (accessible at http://norns.local when norns/your coding computer are on the same wifi), cmd+s/cmd+p to save and send your script to norns.
a more “power-user” workflow would be to use smb and then open dust/code of that norns network drive in your editor of choice. run maiden-repl in a terminal to send the script to norns. vs code is nice because both the terminal and code editor could be in the same window.
you could do it with ssh but that seems a little more primitive to me
One thing I’ve done that works for me is I copied most of norns to my local harddrive. I then setup my IDE to SSH into norns and automatically upload code whenever it’s modified.
The main reason I do this is all of the code is indexed locally so I can more easily do a “global search” if I’m trying to look something up. I also like having it locally so I can still work on things when away from the norns and then test it later.
do you mind doing a brief write-up of how you’ve done this? i’ve done rsync-based approaches like this before, but typically in a corp environment where the tools team could do most of the heavy lifting for me there
how do I properly set note lengths (couldn’t find a place where that was solved, so I used the clock api docs, combined with a guess that subsequent parameters to clock.run woudl get passed and params to the function it calls)
how do I see a list of monospace fonts (this one, the docs are only a subset of the first few fonts…I had to search font in monome/norns github and then look for commits to find where @zebra added a bunch of fonts to look at the source…foudn out this was a thing by searching “norns fonts” on lines)
how do I pan some notes hard left, some hard right…found that the rings engine included some panning, but it’s not pan-per-note. I started looking into the “Pan2” supercollider docs and got overwhelmed on that one, so moved on for the time being
what’s best practice for calling redraw (polling on a metro/calling imperatively inside of another function) (I couldn’t quickly find an answer to this one…my guess is the metro, but I’m going with the latter for now just coz it was easier to set up).
I’m finding it pretty difficult to guess what questions someone who has less familiarity with coding (in general) would ask, because they might not know what they want yet.
well, I’m using webstorm to do all of the hard work for me, so I’m not sure how useful my instructions would be for people using something else. I haven’t really used rsync much.
I basically just copied the stuff I wanted locally using scp, and then webstorm has a “deployment” feature where you can configure norns as a remote host, connect to it over SFTP, and map your local path to a “deployment path” on the device.
I only have webstorm because my job pays for it, but I imagine other IDEs have similar features… I’m sure you could do all this with rsync and some good bash-fu though
I dont think we need to try to answer that question. Rather, documenting for yourself-from-2-days-ago is perhaps far more useful. Not to mention we’re typically best at explaining things to folks with one step less knowledge. It’s turtles all the way down
Maybe we need a thread of ‘a-ha moments while scripting for norns’? Specifically open to all skill levels.