Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using grid/arc with libmonome directly? #288

Open
PaulBatchelor opened this issue Feb 10, 2021 · 8 comments
Open

Using grid/arc with libmonome directly? #288

PaulBatchelor opened this issue Feb 10, 2021 · 8 comments

Comments

@PaulBatchelor
Copy link

Would there be any value in writing up a document on writing apps using libmonome directly (without the OSC layer)? This is how I personally have been using my grid/arc on osx/linux for the past few years. I'd be happy to contribute this if there is interest.

@tehn
Copy link
Member

tehn commented Feb 10, 2021

i think this would be a fantastic edition to the docs.

there are already some python examples inside of libmonome, but they're somewhat terse and figure-it-out-yourself. i do think some people would appreciate a bit more detail presented in a guided form.

@PaulBatchelor
Copy link
Author

Cool. Most of what I know comes from the existing C examples that are in libmonome, but some more explanation would be helpful. IIRC I did slightly peel back an abstraction doing the event polling so that I could manage it more manually (I think I did this worked out better for debugging purposes in my system). There are also some nuances in getting it to read from serial directly and not OSC, which differ on OSX and Linux. Never tested anything on Windows, so no clue what happens there.

So, would making files like grid/libmonome.md arc/libmonome.md make sense? Or would you want to keep stuff in one place? And if so, where?

@tehn
Copy link
Member

tehn commented Feb 18, 2021

yes i think that's a good approach.

would also be interested to hear more about your libmonome fork (if that's what you were suggesting?)

@PaulBatchelor
Copy link
Author

cool. I try to take an initial stab at it. I'll probably start with the grid. My goal will be to use the least amount of (readable) code possible to get a decent starting point. Probably a patch that turns lights on and off or something. Words will surround this, naturally. To keep things brief yet informative, I think I'm going to write for an audience reasonably competent at compiling C code from the command line.

Monolith still uses upstream libmonome. However, I opted to manually create my own event loop rather than use the one supplied in monome_event_loop: https://github.com/monome/libmonome/blob/master/examples/simple.c#L57. This was done so I could poll other devices and things in addition to the monome stuff.

So, instead of doing this stuff: https://github.com/monome/libmonome/blob/fdebcb62efdad5e791eed544c1c8783629033b6c/src/platform/posix.c#L198

I have code which looks like this

void monolith_monome_poll(monolith_d *m)
{
    if(m->monome == NULL) return;
    while(monome_event_handle_next(m->monome));
}

And this gets called inside of a single event loop thread which polls other hardware events in a non-blocking manner, which could be as simple as:

while (program_is_running) {
...
monolith_monome_poll(m);
...
usleep(800);
}

Which in practice has worked out great for my needs. As I mentioned previously, the added benefit of doing all the event polling in a single thread is it makes debugging a lot easier. Before doing this, I actually was using the serialosc protocol using liblo. Well, liblo kept on breaking my heart. Threads were always abstracted away, which made debugging very difficult and restarting the program unpredictably buggy. Then, when I actually figured out how to control OSC messages on my own event thread that I controlled using the low-level liblo API, I still wasn't quite sure where memory was being allocated and freed, and if I was actually freeing things, even after consulting the liblo source code. I ditched liblo, serialosc, and OSC entirely, and went straight to libmonome calls. Things have been consistently snappy ever since.

@PaulBatchelor
Copy link
Author

PaulBatchelor commented Mar 18, 2021

Following up on this.

I'm currently in the process of outlining structure for what will be a guide for using libmonome with the grid.

Current sections I have in mind:

  • Introduction: what this document is, who it is for.
  • SerialOSC vs libmonome: brief words on what SerialOSC does and the connection to libmonome (TL;DR: libmonome = no SerialOSC or OSC).
  • Hello Grid: more or less the "simple.c" program, with some words on how to build and run it from the command line on OSX/Linux.
  • Lighting Columns and Rows: modifying the program to light rows and columns. Some words on performance (it's better to draw with rows/columns when lighting many LEDs at once).
  • Extending the event loop: replacing "monome_event_loop" to explicitly poll events instead, and why you'd want to do that.

No idea on timeline on this. Still chewing on the fact that over a month has passed by? Like what?! But I do intend to complete this eventually.

Thoughts?

@tehn
Copy link
Member

tehn commented Mar 18, 2021

i think this is a great outline.

to me the main difference between libmonome and serialosc (besides OSC) is the latter allows for focus swapping between applications (which is more complex than serial), multi-unit support, and hot-swapping/auto-detection. BUT libmonome is honestly perhaps perfect for most use cases when you're not just switching max patches a ton, or using ableton/etc.

one thing i'd like to suggest for section 4: rather than cols/rows, use "map" and have this section be about maintaining an array within the application itself and using a global dirty flag, along with a fixed timer for refresh. (i can make an example of this... it's how i structure norns scripts and the avr32 based firmwares).

also, not exactly related, but @catfact is doing some work on libmonome and serialosc and might have insight, or, if any changes/additions were to be made this would be a good time.

thanks for your time on this! (when it happens) ;)

@catfact
Copy link
Contributor

catfact commented Mar 19, 2021

woop sorry didn't see this for a while!

yes this would be a good time for those changes.

i agree that for integrating the serial interface with real world C programs, definitely want an explicit poll mechanism instead of / in addition to the polling thread managed by the lib with callbacks. (so that C programmer can make their own decision about threading structure.)

i'm also adding a serial example, boatload of README, and API documentation markup.

@PaulBatchelor
Copy link
Author

@catfact did you ever end up adding new examples?

Life got in the way a bit, but I'm slowly trying to get back into this. I actually have initial words and code for the first few sections of the grid. Believe it or not, I've never used map before, so I'll need to get friendly with that before I write the code for that section. I don't really see any hurdles learning that.

Once I get all the sections and programs fleshed out, I'll make a PR here, where I'll expect some additions and changes will be made.

to me the main difference between libmonome and serialosc (besides OSC) is the latter allows for focus swapping between applications (which is more complex than serial), multi-unit support, and hot-swapping/auto-detection. BUT libmonome is honestly perhaps perfect for most use cases when you're not just switching max patches a ton, or using ableton/etc.

@tehn Yeah I forgot about some of the magic things like auto-detection that SerialOSC does. I've never really used SerialOSC much in the years I've had this thing. Will include some of this.

As for the Arc, I'm thinking it could be treated as a continuation. Most of the core libmonome stuff is the same, it's just a few arc-specific calls. Maybe this section could focus on a handful of boiler plate design interaction ideas for the Arc in C?

(Wow, it's hard to believe how slowly I've been progressing. But progressing, I am.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants