no. lua has no built-in debugger. the lua c interface provides the primitives needed to build one. but it’s a non-trivial amount of work. (to put it mildly.) even then, it would not be possible to set breakpoints without launching the VM in debug mode.

ok, thanks for the quick response. fortunately most norns programs are small enough that print statements will do the trick. i’m diving into arcologies which is pretty big for norns (i think) and was missing a debugger but it’s certainly not a blocker.

yeah, if you’re looking for a “philosophical” justification: norns scripts should be small, or composed of testable components. (??? ehh…)

also note:

  • it’s fine to use global variables in scripts, including global functions. (all non-system globals will be wiped from the environment between script loads.)
  • global variables/functions can be inspected/invoked from the REPL
5 Likes
  • it’s fine to use global variables in scripts, including global functions. (all non-system globals will be wiped from the environment between script loads.)
  • global variables/functions can be inspected/invoked from the REPL

this is a pretty key rationale for having chosen lua for the norns system! live lo-fi debugging (ie, no breakpoints, but you can query/set globals whenever…)

so livecode style debugging, which seems to be a good tradeoff for “musical” coding

4 Likes

also tabutil.print() !

1 Like

i’m interested in having a norns engine send an osc message back to a norns lua script on every “beat” detected with sc’s BeatTrack. i got a start from this, but i’m a little stuck and would appreciate any help.

namely, how to i setup a OSCFunc to send back the message using SendTrig? the following is not functional, but contains what i think are the elements needed to do this…

// CroneEngine_BeatTrack
// beat tracker
Engine_BeatTrack : CroneEngine {
	var pg;

	*new { arg context, doneCallback;
		^super.new(context, doneCallback);
	}

	alloc {
	    var  buffer1 = Buffer.alloc(context.server,44100 * 1, 2,bufnum:bufnum); 
		pg = ParGroup.tail(context.xg);
	    
	    SynthDef("BeatTrack", {
			arg out, inL=0, inR=1;
			var o, trackb, trackh, trackq, tempo, fft;	        
			fft = FFT(LocalBuf(1024), In.ar([inL, inR]);
			#trackb, trackh, trackq, tempo = BeatTrack.kr(fft, 0);
	        o = OSCFunc({ arg msg, time; [time, msg].postln;},'/tr', NetAddr.new("127.0.0.1", 10111));
	        SendTrig.kr(trackb, 0, tempo);
		}).add;

		context.server.sync;

		this.addCommand("on", "f", { arg msg;
			Synth("BeatTrack", [\out, context.out_b,\inL, context.in_b[0].index,\inR, context.in_b[1].index], target:pg);
		});
	}
}

okay i got it working. just replying to myself in case anyone’s search engine leads them here. my implementation is here. i have a recorder and a beattracker that uses the SendTrig synced to the beat and the SendTrig receiver sends an osc message to lua with the pulse. probably a better way to do this, but this seems to work!

1 Like

since you are forwarding the messages from SendTrig already, i guess you may as well use the “poll” system if you want. polls can be constructed with the “periodic” argument set to false. a non-periodic poll should ignore start/stop/rate requests, and just fire callbacks whenever supercollider feels like it.

under the hood, polls are just OSC messages, but i guess it’s a little “better” to stick to uniform APIs when possible. (also: allows some introspection, saves some cycles/allocation in Lua since polls OSC is handled in C.)

hm… i’ll try and make a quick minimal example of using non-periodic polls for event generation from SC.

3 Likes

thanks for your input! my intuition was to use polls but it looked to me like i would have had to edit the crone engine itself.

that’s really cool that their is potential to create a custom poll, esp a non-periodic one for event generation. i would greatly benefit from an example :slight_smile: my supercollider skills at the moment basically typing one word at a time and restarting crone each time to see if it still compiles. :snail::computer:

Just dropping this here as a consideration. 8gb ram + 32gb storage seems nice for norns world. also no more wifi dongle!

looking at a user getting an error trying to record to TAPE…

tape.lua line 52-ish… (in function update_tape_index())

local f = io.open(_path.tape..'index.txt','r')
  if f ~= nil then
    local a = tonumber(f:read("*line"))
    m.fileindex = a or 0
    f:close()
  else
    m.fileindex = 0
  end

If the file does not exist and f returns nil, does the file still need to be closed (with a f:close() in the else statement there) or no?

This would error if f is nil because f:close() is shorthand for f.close(f). If f is nil then the file is not open, so there is nothing to close. Docs for io.open are here.

What is the matron error when recording to tape?

Makes sense. I wasnt sure if that would be causing the problem or not.

The issue is reported here: Fates - a DIY norns DAC board for Raspberry Pi

lua: /home/we/norns/lua/core/menu/tape.lua:66: attempt to index a nil value (local ‘f’)

Maybe it is a permissions problem (waiting on feedback from user on that)

so, errors on this line:

where it attempts to use the index file in write mode.

evidently it did not fail to open and use the same file in read mode a few lines up.

permissions problem seems likely. (why/how? got me.)

(i guess we should have a check for nil, but erroring if we can’t write to the filesystem there is probably the right behavior.)

1 Like

Figured out the error. The user’s tape directory had been deleted. Thus the filepath was invalid.

In the code snippet I posted, if f is nil on the first read, it does not throw an error, m.fileindex is just set to zero. Then when it tries to write afterwards, it gets an actual error.

Maybe @dan_derks would want to file this as a support issue/solution?

pff, thanks, i should have realized that.

yes, i’ll submit a fix right now since i happen to have the norns out for once. (and dan is, hopefully, asleep)

1 Like

here is a PR. (really though: probably best not to remove the audio or tape directories in the first place.)

Unrelated, but I was chatting with @tyleretters and @dan_derks about development environments (e.g., VS Code, auto-complete, etc.) a few weeks ago during the Norns study session, and decided to put this together. I hope it helps someone else! Thanks Tyler and Dan for the help!

8 Likes

A quicker/nicer run/“build” setup is described here https://github.com/monome/norns/issues/1067
It was written for Atom but should be adaptable to VS Code or any other editor that supports build commands.

1 Like

really nice work on this! i love this genre of writing: “precise, level-headed development environment setup”