Thanks! I’d been banging my head against the wall on this one :slight_smile:

1 Like

Is there a more semantic way of accessing external midi clock stop than this? Couldn’t find anything in the docs…

m.event = function(data)
  clk:process_midi(data)
  if data[1] == 252 and external then
    stop()
  end
end

See an example here

You now have a helper functions for clock, start, stop and continue

m.event = function(data)
  local d = midi.to_msg(data)
  -- print something for various data types
  -- ignore clock for the moment but look at other types
  if d.type ~= "clock" then
    if d.type == "cc" then
        print("ch:".. d.ch .. " " .. d.type .. ":".. d.cc.. " ".. d.val)
    elseif d.type=="note_on" or d.type=="note_off" then
        --print("ch:".. d.ch .. " " .. d.type .. " note:".. d.note .. " vel:" .. d.vel)
    elseif d.type=="channel_pressure" or d.type=="pitchbend" then
        print("ch:".. d.ch .. " " .. d.type .. " val:" .. d.val)
        
    elseif d.type=="start" then
        print("start")
    elseif d.type=="stop" then
        print("stop")
    elseif d.type=="continue" then
        print("continue")
    else
        tab.print(d)
    end
  end
end
3 Likes

nice, was hoping for something like that!

Do lib files imported using “require” get cached somehow? I’m working on a new script and I’ve created a library, but when I add a new function to my table in the library, the value is nil in my main script. If I turn Norns off and back on it is no longer nil. I reproduced a couple times to make sure I’m not crazy. I’m not using Maiden, for what it’s worth (but yes, I am reloading the script after making any changes).

1 Like

yes. require caches. search and ye shall receive


Thank you, and sorry for asking a question that was already answered. It’s hard to know where to find certain Norns info sometimes, since it’s spread across studies, documentation, this forum, and just reading the code and trial and error (I also understand this particular issue is a Lua thing and not a Norns thing).

1 Like

I asked the same thing when I started out. The include() function worked great for me.

1 Like

https://monome.org/docs/norns/script-reference/#using-libraries

2 Likes

What is the proper way of cleaning up midi event handlers?

I’ve noticed that if I reload a script repeatedly in maiden, over time I get midi noise. The noise gets worse the more I reload. The noise resembles earlier midi messages sent from the midi controller, as though my event handler is getting ghost events from a few seconds ago. audio:restart() does not solve the issue. What does maybe seem to work is physically unplugging the controller, running midi.cleanup() at the console, and replugging in the controller.

I noticed a comment earlier in this thread:

iirc all midi tidying has been neatly inlined so it’s no longer needed in user code.

Since my issue gets worse with more reloads, it sure looks like something is not getting cleaned up for me.

I added this to my script to see if it would do anything, but it doesn’t seem to help.

function cleanup()
  mid.event = nil -- I created the mid object with midi.connect()
  midi.cleanup() -- found this method in the docs and figured I'd try it
end

I can use the same midi controller with other environments (e.g. supercollider hosted on my macbook) without the issue, so it seems specific to the norns environment. Matron does not show anything unusual in the console when cleaning up my script.

Possibly it’s because I’m often debugging errors in my script, and the midi handlers don’t cleaned up within some global error handler when the script hits an issue at runtime?

What’s the best strategy for me to debug further?

Also, apologies if this is the wrong place to ask, I’m new here.

are tape_record_start and tape_record_stop from the core Audio class working? I’m trying to call audio.tape_record_start() within a script, but it doesn’t appear to do anything.

update: so I’m not sure if I did something to cause this, but my tape has also stopped incrementing file numbers. I recorded up to 0015.wav and the numbers have now started over - the tape page shows 0004 and it will record over that file if I start a new recording. Does anyone know how I could have gotten into this state, and any way to fix it? Maybe it’s unrelated to the first issue I brought up, in which case I can ask this question in the help thread.

see here for how the menu system does it.

did you first call

audio.tape_record_open()

with a filename?

did you write some code to modify norns.state.tape? it shouldn’t reset otherwise.

1 Like

i know you read this elsewhere, but by design you shouldn’t need to clean up.

midi.cleanup() is run by script.clear() which happens when you reload the script.

can you describe the symptom more precisely? what is the time lag of ghost messages?

Thanks - I should’ve looked for that menu code, this is helpful. I did not call audio.tape_record_open - it wasn’t intuitive to me that first I had to “open” a file before recording to it (I wasn’t sure how much tape_record_start was supposed to do for me under the hood).

The only global I’ve been messing around with is the norns.vu callback, but I didn’t think that would cause any issues. Not sure how my tape state got weird but I’ll just rename my files and let you know if I can reproduce the issue.

you can also edit /home/we/dust/data/system.state to change your tape counter (requires a RESTART after)

Can someone give me an example of using a formatter with a param controlspec?

I have added a control but it’s returning a float value and I’d like that to display as a whole number. Would a formatter help me here?

  cs_bpm = controlspec.new(1,480,'lin',0,120,'')
  params:add{type="control",id="bpm",controlspec=cs_bpm,
    action=function(x) self:bpm_change(x) end}

(changing from a number to a control param) The value I get jumps by 5-6 values when I turn an encoder with the control param. Would using delta be better here? If so, an example of how to use that?

The docs are lacking in these areas.

EDIT - I just looked at github jssues and this one pretty much describes why I’m having this problem. If any of the devs can point me to any work in this params area I’d be keen to help (if I can)

1 Like

yeah, JS objects ~== Lua tables, and prototypes ~== metatables.

there’s no ‘official’ way to implement classes in lua, but this same pattern is used in norns core modules a lot (metro, grid, &c):

foo.lua:

local Foo = {}
Foo.__index = Foo

Foo:new ( props ) 
  local f = props or {}
  setmetatable(f, Foo)
  return f
end

function Foo:method()
   print ('i am foo')
end

return foo

you can also do inheritance:

Bar = Foo:new()

that’s it! now Bar:new() will return a table identical to Foo, but named differently.
so you can “override methods” or add new ones or whatever

function Bar:method() 
  print ('i am bar')
end
6 Likes

honestly a huge fan of lua classes. I love that they’re syntactically the same thing as arrays mostly.

For the sole purpose of learning some basic skills I’m trying to swap the Polysub engine used in the Earthsea script with Passersby.
I’ve already done it with fugu without any problem, just by changing the engine references. Did the same with earthsea, but the script doesn’t start

#16 local passersby = include 'passersby/lib/passersby_engine'
#34 engine.name = 'Passersby'
#62 passersby:params()

seem to be the only three times the engine is recalled and i just swapped the engine name and included the right directory.
Is there something else that needs to be done?

Here’s the earthsea script for reference
https://raw.githubusercontent.com/tehn/ash/master/earthsea.lua

:slight_smile:

Check the error output in Maiden - it looks like passersby_engine doesn’t have a function called params, but if you try passersby:add_params() instead it might work.