/lib development

continuing the discussion from House Style for Lua OOP and Inheritance?:

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.

:revolving_hearts:!

6 Likes

been workin on an object oriented grid lib for * years *
wld love some assistance & feedback once I’m further along

not sure if it fits in with the core libs but I’ll link this one here anyway

4 Likes

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

2 Likes

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

2 Likes

I was just wishing for something like this.

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.

1 Like

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 :sweat_smile:

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)

2 Likes

thiswhat are some of those things?

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.

exciting to see the energy around this!

2 Likes

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.

4 Likes

@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.

3 Likes

Thanks - i might try out the power user way! This would work for making edits to say existing parts of the the core lib?

1 Like

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 :sweat_smile:

1 Like

so as I am porting m18s from crow to norns, these are the things that I have had to do this with:

  • how do I advance the sequencer clock (your post covered it)
  • what are the sound engines I could potentially use for generating notes (searched “list of engines” on lines, got pointed to https://monome.org/docs/norns/app/#synths-and-audio-processing by a post of yours)
  • 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.

2 Likes

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

1 Like

oh yes and this is why i love it! basically i always have two ssh sessions open to norns. all the tools i need are old, established, just work

5 Likes

Could definitely see that. If you have l33t vim skills it most definitely is less primitive than the way I use the code editor hah

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 :turtle::turtle::turtle:

Maybe we need a thread of ‘a-ha moments while scripting for norns’? Specifically open to all skill levels.

8 Likes

I’ll happily volunteer to pair program, help with architecture, design patterns, etc.

2 Likes