Replies: 13 comments 27 replies
-
|
it’s been a bit so my recollection is fuzzy. the nng change was part of an intended step which changed maiden and the repl/ws traffic to using TLS and adding authentication. at the time the work was done the nng runtime did not offer a way of controlling the number of i/o threads it spun up which IMO needlessly created noise when debugging, consumed extra memory, and provided little if any benefit (norns perf needs did not require it). since that time i believe nng eventually added some control over thread count. IIRC the nng change also addressed a case where getting output back from running a sub-process would would get truncated (due to the original implementation). that said there were weird issues with the converged process where spawning sub processes would trigger xruns in the audio thread. I think there was some hacky thing we did to work around that but i would have to go back to the code to remember. not sure the root cause was ever identified. none of the tls and auth work was started. in terms of the ambitions around crone + matron ipc or simplification i would have to defer to @catfact i had done some work on lua bindings to lv2 with the intention of possibly making the compressor and reverb pluggable but again time/interest wasn’t there along with compatibility concerns (more variation in cpu load causing additional support for example). In this area the only work done was a set of lua bindings to lilv |
Beta Was this translation helpful? Give feedback.
-
well as i recall we were trying to get to functional parity with a stable single-process architecture. i think there were still bugs with things like capturing output of child processes spawned by lua. but at a quick glance it seems like a first pass implementation was basically done? one of the goals is/was performance. so that goal seems acheived already by the rewrite - i remember it being: more responsive under floods of audio engine commands; avoiding some overruns while somehow causing some others. so next step was bug hunting. if there were systems that remained to be replaced, i can't remember what they are. steps after that, well, i think its about being able to add certain features more easily. off top of my head?:
... i'm probably forgetting some ideas. |
Beta Was this translation helpful? Give feedback.
-
|
oh yes the sidecar process was a bit of a hackaround, so that the combined norns process (now actually being a real grownup jack client) wouldn't be the direct parent of lua-spawned processes. |
Beta Was this translation helpful? Give feedback.
-
|
I tend to wrap my head around things faster when they are visualized. How does this look (simplified)? flowchart TD
subgraph COA["norns re-architecture"]
subgraph HW["norns Hardware"]
subgraph NP["norns JACK client"]
MT["matron (Control + Lua VM)"]
CQ["ConcurrentQueue"]
CT["crone (Audio + JACK)"]
MT -- "Commands::post()" --> CQ
CQ -- "handleCommand()" --> CT
CT -- "direct C++ callbacks / event_post()" --> MT
end
WW["ws-wrapper (NNG WebSocket ↔ stdio)"]
SD["sidecar (forked child)"]
SC["SuperCollider (sclang)"]
WW -- "stdio pipes" --> NP
MT <-- "NNG IPC (req/rep)" --> SD
SD -- "popen()" --> S["Subprocesses"]
MT <-- "OSC (UDP)" --> SC
end
subgraph CLIENT["Client"]
MAIDEN["maiden (Web IDE)"]
MR["maiden-repl (CLI)"]
end
MAIDEN -- "NNG WebSocket" --> WW
MR -- "NNG WebSocket" --> WW
end
|
Beta Was this translation helpful? Give feedback.
-
|
I rebased the norns-converged branch against current main, and it builds and starts up both in the dev container and on norns hardware. main...Dewb:norns:norns-converged-2026 Still a little short of having a working system off this branch, though. After building and installing nng (see Dockerfile for steps used) the normal build process succeeds. I am able to run the new setup with: $ ./stop.sh
$ systemctl start norns-jack.service
$ systemctl start norns-sclang.service
$ systemctl start norns-maiden.service
$ build/norns/nornsStartup proceeds encouragingly normally but we eventually crash with a GDB outputStarting program: /home/we/norns/build/norns/norns
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1".
[Detaching after fork from child process 9895]
[New Thread 0x75e25280 (LWP 9896)]
[New Thread 0x75624280 (LWP 9898)]
[New Thread 0x74e23280 (LWP 9900)]
[New Thread 0x74622280 (LWP 9905)]
[New Thread 0x73e21280 (LWP 9918)]
[New Thread 0x73620280 (LWP 9919)]
[New Thread 0x72e1f280 (LWP 9920)]
[New Thread 0x7261e280 (LWP 9921)]
[New Thread 0x71e1d280 (LWP 9922)]
[New Thread 0x7161c280 (LWP 9923)]
[New Thread 0x70e1b280 (LWP 9924)]
[New Thread 0x7061a280 (LWP 9925)]
[New Thread 0x6fe19280 (LWP 9926)]
[New Thread 0x6f618280 (LWP 9927)]
[New Thread 0x6ee17280 (LWP 9928)]
[New Thread 0x6e616280 (LWP 9929)]
[New Thread 0x6de15280 (LWP 9930)]
[New Thread 0x6d614280 (LWP 9931)]
[New Thread 0x6ccff280 (LWP 9932)]
constructed Client: crone
constructed Client: softcut
initializing buffer management worker..
[New Thread 0x6314f280 (LWP 9933)]
setting up jack clients..
[New Thread 0x6294e280 (LWP 9934)]
[New Thread 0x628cd280 (LWP 9935)]
engine sample rate: 48000
[New Thread 0x5c09e280 (LWP 9936)]
engine sample rate: 48000
starting jack clients..
[New Thread 0x5beff280 (LWP 9937)]
[New Thread 0x5be7e280 (LWP 9938)]
connecting ports...
starting OSC interface...
[New Thread 0x5bdfd280 (LWP 9939)]
osc methods:
/hello []
/goodbye []
/quit []
/poll/start/vu []
/poll/stop/vu []
/poll/start/tape []
/poll/stop/tape []
/set/level/adc [f]
/set/level/dac [f]
/set/level/ext [f]
/set/level/cut_master [f]
/set/level/ext_rev [f]
/set/level/rev_dac [f]
/set/level/monitor [f]
/set/level/monitor_mix [if]
/set/level/monitor_rev [f]
/set/level/compressor_mix [f]
/set/enabled/compressor [f]
/set/enabled/reverb [f]
/set/param/compressor/ratio [f]
/set/param/compressor/threshold [f]
/set/param/compressor/attack [f]
/set/param/compressor/release [f]
/set/param/compressor/gain_pre [f]
/set/param/compressor/gain_post [f]
/set/param/reverb/pre_del [f]
/set/param/reverb/lf_fc [f]
/set/param/reverb/low_rt60 [f]
/set/param/reverb/mid_rt60 [f]
/set/param/reverb/hf_damp [f]
/set/enabled/cut [if]
/set/level/cut [if]
/set/pan/cut [if]
/set/level/adc_cut [f]
/set/level/ext_cut [f]
/set/level/tape_cut [f]
/set/level/cut_rev [f]
/set/level/in_cut [iif]
/set/level/cut_cut [iif]
/set/param/cut/rate [if]
/set/param/cut/loop_start [if]
/set/param/cut/loop_end [if]
/set/param/cut/loop_flag [if]
/set/param/cut/fade_time [if]
/set/param/cut/rec_level [if]
/set/param/cut/pre_level [if]
/set/param/cut/rec_flag [if]
/set/param/cut/play_flag [if]
/set/param/cut/rec_offset [if]
/set/param/cut/position [if]
/set/param/cut/pre_filter_fc [if]
/set/param/cut/pre_filter_fc_mod [if]
/set/param/cut/pre_filter_rq [if]
/set/param/cut/pre_filter_lp [if]
/set/param/cut/pre_filter_hp [if]
/set/param/cut/pre_filter_bp [if]
/set/param/cut/pre_filter_br [if]
/set/param/cut/pre_filter_dry [if]
/set/param/cut/post_filter_fc [if]
/set/param/cut/post_filter_rq [if]
/set/param/cut/post_filter_lp [if]
/set/param/cut/post_filter_hp [if]
/set/param/cut/post_filter_bp [if]
/set/param/cut/post_filter_br [if]
/set/param/cut/post_filter_dry [if]
/set/param/cut/voice_sync [iif]
/set/param/cut/level_slew_time [if]
/set/param/cut/pan_slew_time [if]
/set/param/cut/recpre_slew_time [if]
/set/param/cut/rate_slew_time [if]
/set/param/cut/buffer [ii]
/softcut/buffer/read_mono [sfffiiff]
/softcut/buffer/read_stereo [sfffff]
/softcut/buffer/write_mono [sffi]
/softcut/buffer/write_stereo [sff]
/softcut/buffer/clear []
/softcut/buffer/clear_channel [i]
/softcut/buffer/clear_region [ff]
/softcut/buffer/clear_region_channel [iff]
/softcut/buffer/clear_fade_region [ffff]
/softcut/buffer/clear_fade_region_channel [iffff]
/softcut/buffer/copy_mono [iifffffi]
/softcut/buffer/copy_stereo [fffffi]
/softcut/buffer/render [iffi]
/softcut/query/position [i]
/softcut/reset []
/set/param/cut/phase_quant [if]
/set/param/cut/phase_offset [if]
/poll/start/cut/phase []
/poll/stop/cut/phase []
/tape/record/open [s]
/tape/record/start []
/tape/record/pause [i]
/tape/record/stop []
/tape/play/open [s]
/tape/play/start []
/tape/play/pause [i]
/tape/play/stop []
/tape/play/loop [i]
/set/level/tape [f]
/set/level/tape_rev [f]
MATRON
norns version: 0.0.0
git hash: 59f88b8
platform: cm3 (2)
no user matronrc file (/home/we/matronrc.lua) found, using default
loading matronrc file: /home/we/norns/matronrc.lua
setup IO keys:gpio
[New Thread 0x5b5fc280 (LWP 9940)]
setup IO enc:gpio
[New Thread 0x5adfb280 (LWP 9941)]
setup IO enc:gpio
[New Thread 0x5a5fa280 (LWP 9942)]
setup IO enc:gpio
[New Thread 0x59df9280 (LWP 9943)]
IO setup OK.
font setup OK.
battery init...
[New Thread 0x58718280 (LWP 9944)]
[Detaching after vfork from child process 9945]
[New Thread 0x57dff280 (LWP 9947)]
[New Thread 0x573ff280 (LWP 9948)]
*** WARNING *** The program 'norns' uses the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see
[New Thread 0x56bfe280 (LWP 9953)]
[New Thread 0x55fff280 (LWP 9959)]
[New Thread 0x575fe280 (LWP 9960)]
[New Thread 0x557fe280 (LWP 9961)]
[New Thread 0x54ffd280 (LWP 9962)]
[New Thread 0x547fc280 (LWP 9963)]
[New Thread 0x53ffb280 (LWP 9964)]
[New Thread 0x537fa280 (LWP 9965)]
init oracle...
OSC rx port: 8888
OSC crone port: 9999
OSC ext port: 57120
OSC remote port: 10111
[New Thread 0x52ff9280 (LWP 9966)]
init weaver...
starting main lua vm
running lua config file: dofile('/home/we/norns/lua/core/config.lua')
[New Thread 0x527f8280 (LWP 9967)]
init dev_monitor...
[New Thread 0x51ff7280 (LWP 9968)]
[New Thread 0x517f6280 (LWP 9969)]
setting cleanup...
init input...
[New Thread 0x50ff5280 (LWP 9970)]
i2c init...
ERROR (i2c/adc) failed to write [chan]
running startup...
error loading keyboard layout, using old value: us
start_audio():
[New Thread 0x507f4280 (LWP 9971)]
scanning devices...
dev_monitor: vendor=monome model=grid
dev_monitor: TTY appears to be a monome
monome device appears to be a grid; rows=8; cols=16; quads=2
[New Thread 0x4fff3280 (LWP 9972)]
handling pending events...
_norns.midi.add: 1, virtual, userdata: 0x597100
grid added: 2 monome 128 m4193185 m4193185
running post-startup...
_norns._post_startup
norns.startup_status.ok
[Thread 0x507f4280 (LWP 9971) exited]
# script clear
setting DAC level (main thread): 0.977679
crone_set_level_dac(0.977679)
&mixerCommands: 0x2268c0
### SCRIPT ERROR: NO SCRIPT
[New Thread 0x5757d280 (LWP 9973)]
Thread 50 "metro_loop" received signal SIG32, Real-time event 32.
[New Thread 0x57557280 (LWP 9974)]
[Thread 0x5757d280 (LWP 9973) exited]
[New Thread 0x4f7f2280 (LWP 9975)]
[New Thread 0x4eff1280 (LWP 9976)]
terminate called after throwing an instance of 'std::bad_function_call'
what(): bad_function_call
Thread 53 "norns" received signal SIGABRT, Aborted.
[Switching to Thread 0x4eff1280 (LWP 9976)]
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1 0x767ad804 in __GI_abort () at abort.c:79
#2 0x76e73f88 in __gnu_cxx::__verbose_terminate_handler() () from /lib/arm-linux-gnueabihf/libstdc++.so.6
#3 0x76e71acc in ?? () from /lib/arm-linux-gnueabihf/libstdc++.so.6
#4 0x76e71b58 in std::terminate() () from /lib/arm-linux-gnueabihf/libstdc++.so.6
#5 0x76e71f28 in __cxa_throw () from /lib/arm-linux-gnueabihf/libstdc++.so.6
#6 0x76e6d720 in std::__throw_bad_function_call() () from /lib/arm-linux-gnueabihf/libstdc++.so.6
#7 0x000808e0 in std::thread::_State_impl > >::_M_run() ()
#8 0x76e9d150 in ?? () from /lib/arm-linux-gnueabihf/libstdc++.so.6
#9 0x76f83300 in start_thread (arg=0x4eff1280) at pthread_create.c:477
#10 0x76872208 in ?? () at ../sysdeps/unix/sysv/linux/arm/clone.S:73 from /lib/arm-linux-gnueabihf/libc.so.6
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
This is about all the investigating I will have time to do until later next week at the earliest, so it would be great if someone feels like picking up and running with the baton a bit. Notes:
|
Beta Was this translation helpful? Give feedback.
-
|
This is fantastic. I'm returning tomorrow from a stretch of travel and will review and be available to do further testing when required.
Thanks for rebooting this effort!
b
…-------- Original Message --------
On Saturday, 02/21/26 at 04:44 Colin McArdell ***@***.***> wrote:
Nice work! I have some bandwidth to run with it in the evenings.
—
Reply to this email directly, [view it on GitHub](#1879 (reply in thread)), or [unsubscribe](https://github.com/notifications/unsubscribe-auth/AAB4I4H7UWHYFBWHRABAEQL4NBHJVAVCNFSM6AAAAACVUG7C4SVHI2DSMVQWIX3LMV43URDJONRXK43TNFXW4Q3PNVWWK3TUHMYTKOBYGA2DGMI).
You are receiving this because you are subscribed to this thread.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
|
Should nng stay in the dev container (and future norns-image update), or are things easier in the long term if it becomes a submodule and is built by waf? |
Beta Was this translation helpful? Give feedback.
-
|
holy cow, amazing work @colinmcardell. appreciate the attention to detail, great to see multithreading mechanisms get some TLC. there are various changes we could consider rolling into a 3.0, mostly or entirely non-breaking. concur that its best to keep a narrow focus on parity for this change, it would be well served by integrated testing with a wider user base, before introducing confounding changes to scripts &c. |
Beta Was this translation helpful? Give feedback.
-
|
opened discussion for milestone planning, with a couple suggestions to get the ball rolling: |
Beta Was this translation helpful? Give feedback.
-
|
Cross-posting this over here for completeness from #1883, and furthering the discussion on next steps. I've got a stable environment at this point using the service definitions below. I made a change in the last commit to make it so that norns will not spawn a jack server as it was causing a race condition with the
Any thoughts on the norns update process at this time ( These are the changes that need to happen:
It seems like this is all manageable as an
|
Beta Was this translation helpful? Give feedback.
-
|
Yes, the update script I change as needed, then pack the update tgz manually. I will take care of all of this part of it. I can separately make a rollback script. It's a little fiddly but not too bad. I haven't yet re-tested, what's the state of the maiden communication? |
Beta Was this translation helpful? Give feedback.
-
|
Update on the maiden-repl CLI. I've got the websocket dialing in place and tested working with the update to nng. Once I fixed the IPv4 dialing and tested, I uncovered another issue, which sent me on a long and winding road. I ended up refactoring a number of the bits within maiden-repl trying to solve it, which will show up as threading improvements and UI improvements. But the issue turned out to be rather funny... sclang wants ESC instead of newline. And it looks like that same issue was surfaced on the web maiden repl because there is a nice comment about it. Alright. I'm going to get this work buttoned up and committed this weekend. |
Beta Was this translation helpful? Give feedback.
-
|
Here is a guide for testing the work over on #1883 https://gist.github.com/colinmcardell/3b8982327c009c2c74f7e2a0dff22cab |
Beta Was this translation helpful? Give feedback.


Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
As I understand it, the goal of the converged branch was/is to combine the matron and crone processes into a single process, and use shared memory rather than OSC for the communication between the control and audio threads.
The first step IMO is getting to a new converged branch that's rebased on main so it contains all of the other improvements made in the last 3-4 years. I've done one pass of
git rebase -iand I'm going to do it again on top of the nng-ci branch so I can make sure every commit builds cleanly before proceeding. I'm omitting commits 186fa72 (the merge from main into the converged branch), f7c00c3, and 421ca6e (changes already committed to main as 4fe2521 and 41e0817.) There are a bit of entangled changes but most of it seems fairly straightforward to resolve. Couple areas of concern are main-branch changes to the VU polls and the tape messages; those will presumably require some rewriting for the converged architecture.Beyond that, I'm not sure what the next step is; what do we know about what work was still planned when development stopped?
Beta Was this translation helpful? Give feedback.
All reactions