<html><head></head><body><div style="color:#000; background-color:#fff; font-family:Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif;font-size:13px"><div id="yiv9021853663"><div id="yui_3_16_0_ym19_1_1497639033253_2527"><div style="color:#000;background-color:#fff;font-family:Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif;font-size:13px;" id="yui_3_16_0_ym19_1_1497639033253_2526"><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_3812">Hi Giulio,</div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_3898">Thanks for the message. I'll reply inline below.<br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_3899"><br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_3900">> Trying to re-send this from a different email address, given it has not received any response <br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_3928">since it was sent out one week ago and I previously experienced my yahoo address to end up <br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_3929">in everyone's spam folder.</div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_3930"><br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_3931">I've apparently had problems with my messages getting through as well.<br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_6380"><br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_3962">> Hello everyone,<br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_3963">> I have just subscribed to this list, though I have been on other Pd lists for a while (and in fact I wrote something related to the <br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_3964">> below on Pd-dev recently).<br clear="none"></div><div id="yui_3_16_0_ym19_1_1497639033253_2602"><br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_3965">> I work on Bela, an embedded platform for audio and sensor processing (<a rel="nofollow" shape="rect" target="_blank" href="http://bela.io/">http://bela.io</a>) which achieves ultra-low latency (down to <br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_3966">1ms roundtrip) on a full Linux computer (BeagleBone).<br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_4235"><br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_4236">> Our users have so far been able to run Pd patches using either a Vanilla 0.46 libpd which we wrapped with our own custom (non-ALSA) audio driver code or the online Heavy compiler. We make our audio, analog and digital I/O available within Pd through [adc~][dac~].<br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_4278"><br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_4377">> We are now looking into how to make live-patching for Pd on Bela.<br clear="none"></div><div><br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_4378">> I wrote a Pd audio backend for Bela and removed the file polling from the audio thread.</div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_4379"><br clear="none"></div><div dir="ltr" id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_4380">I'm not exactly sure what you mean by "removed" here. Doesn't Pd allow you to use<br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_4430">either a polling or callback API to use with the audio backend?<br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_4431"><br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_4542">> The latter is both good real-time programming practice AND required for Bela, as it uses Xenomai. <br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_4543">Bela has no way to connect a display, so we run Pd on Bela and the GUI on the host (Bela shows up <br clear="none"></div><div id="yui_3_16_0_ym19_1_1497639033253_20313">as a network device over USB to the host computer).<br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_4599"><br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_4600">> Great, I got 64 samples per block, below 4ms roundtrip latency (note that Pd's internal "delay" is set to 0, <br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_4601">thanks to Bela, so these are real roundtrip figures). Did the above with both the latest Pd and with Purr-data.</div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_4727"><br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_4660">That's quite impressive.</div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_4912"><br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_4913">How did you measure the 4ms roundtrip latency?<br clear="none"></div><div id="yui_3_16_0_ym19_1_1497639033253_20449"><br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_4914">> With this configuration I can do live patching and everything would work just fine, except that once you have <br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_4979">more than a handful of objects in your patch, then you start hearing dropouts as soon as you move your mouse <br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_4980">around. This is because each mouse move triggers a `motion` message to the Pd backend, handled by <br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_5047">`canvas_motion()` in `g_editor.h`, invokes `canvas_doclick(... doit = false)`, which in turn iterates through all the <br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_5048">objects on the patch and asks each of them "does the cursor happen to be on top of you?" (`canvas_findhitbox()`/`canvas_hitbox()`). This takes longer than you may expect, as it calls a callback function <br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_5049">(`w_getrectfn()`) for each of those objects.<br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_5050"><br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_5051">> Bottom line: this thing is iterating through the `w_getrectfn()` of each object of the patch every <br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_5052">time you move your mouse, and this happens within the audio thread, hence when you have many objects, <br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_5053">(and small blocksizes and an ARM CPU, as we have on Bela) you get glitches for simply moving your mouse.</div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_5054"><br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_5055">That's correct. Note that it is actually even a bit worse when mousing over a "Put" menu array, which triggers <br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_5056">a loop or two in order to find the array element underneath the mouse.<br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_5057"><br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_5058">> I thought I'd give it a shot to leverage the javascript in the Purr-data GUI to only send `motion` messages when <br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_5059">my mouse is on top of an object and to send along with it the Pd "tag" of the object (using `onmouseover` and <br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_5060">`onmouseout`). This drastically improves the performance on the Pd side, because much less needs to be done <br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_5061">in the audio thread. It still has some things not working (e.g.: copy/paste works badly now, your cursor shape may get stuck when you move out of an object), but here it is: <a rel="nofollow" shape="rect" id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_5062" target="_blank" href="https://github.com/giuliomoro/purrdata/tree/simpler-motion">https://github.com/giuliomoro/purrdata/tree/simpler-motion</a></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_6135"><br clear="none"></div><div>I just quickly glanced at the code, but it looks like a workable approach.</div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_6136"><br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_6137">There is one rather important edge case I can think of, which is [mousestate] from cyclone. It tracks the <br clear="none"></div><div dir="ltr" id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_6381">mouse position regardless of whether the mouse button is clicked. Currently Purr Data has a problem because <br clear="none"></div><div dir="ltr" id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_6964">there's no way I've found to track mouse motion outside of the document window (unless there's a Chrome <br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_6382">App API that I haven't discovered.)<br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_7131"><br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_7132">> Once these bugs are ironed out, this could be a viable solution for us (Bela). You would still get glitches <br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_7133">when moving many objects or creating many objects at a time, but you would be able to interact with a patch <br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_7134">(moving mouse in edit/run modes) without many problems.</div><div><br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_7135">Yes, I like this kind of incremental approach.</div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_7136"><br clear="none"></div><div id="yui_3_16_0_ym19_1_1497639033253_20450">Also, Pd-l2ork already has a nice improvement for moving selections. It still must be called back on each <br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_8131">x/y delta reported by the mouse, but it's only a single message instead of one per object in the selection.<br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_8132"><br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_8133">> At the point we are at, we are struggling to decide what is the path forward when running Pd on Bela. <br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_9734">Ideally we would want all the GUI stuff to be delegated to the GUI, to free up more CPU for our audio processing <br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_10222">and also because well... that's just the way it should be, right?</div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_10431"><br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_10432">One thing to keep in mind is that the lack of specification for Pd the language makes it difficult <br clear="none"></div><div dir="ltr" id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_10433">to predict how much work is required to do something like that. Essentially, anything that a user could <br clear="none"></div><div dir="ltr" id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_10434">possibly access from the language gets accessed and used for some creative purpose. For example, <br clear="none"></div><div dir="ltr" id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_10733">look on the Pd forum at what weird things somebody is doing with the data structures API, or even <br clear="none"></div><div dir="ltr" id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_10734">using iemguis to create a display surface.</div><div dir="ltr" id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_10735"><br clear="none"></div><div dir="ltr" id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_10736">I'm all for a clean separation between GUI and audio process, but I do need to keep in mind <br clear="none"></div><div dir="ltr" id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_10737">that such a separation _will_ initially end up degrading the UX for some set of cases. And because we <br clear="none"></div><div dir="ltr" id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_10738">don't have a spec to go by, such users will interpret that degradation as damage to the integrity of <br clear="none"></div><div dir="ltr" id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_10740">the language, even if the benefit of the change clearly outweighs everything else. So we have to <br clear="none"></div><div dir="ltr" id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_12815"><div>label such degradations as "bugs" when they occur and find a way to fix them.</div><div><br></div><div>Most of the work right now on Purr Data is labeling such bugs, and finding workarounds <br></div><div id="yui_3_16_0_ym19_1_1497639033253_20720">for them.<br></div></div><div dir="ltr" id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_12816"><br clear="none"></div><div dir="ltr" id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_12817">Here's an example-- a clean separation between GUI and audio process may decide to only <br clear="none"></div><div dir="ltr" id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_12819">send object position updates on mouseup. Such an approach would forget that [cnv] <br clear="none"></div><div dir="ltr" id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_12818">has a "get_pos" method to find the current coordinates of the object. So if the GUI doesn't <br clear="none"></div><div dir="ltr" id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_12820">send updates for each mouse motion tick, control surfaces based on that method will fail.</div><div dir="ltr" id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_12821">That's a bug that would need to be fixed.</div><div dir="ltr" id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_13031"><br clear="none"></div><div dir="ltr" id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_13911">Just thinking about that example-- another degradation would be that moving an [inlet] <br clear="none"></div><div dir="ltr" id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_13912">relative to another [inlet] inside a GOP wouldn't update corresponding connections on <br clear="none"></div><div dir="ltr" id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_13913">the parent in realtime. That's definitely not as important as above. But it's an example <br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_13914">of what to keep in mind when refactoring the current API.<br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_17079"><br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_14032">> As mentioned, I dirtied my hands with both Pd and PurrData code, and it seems that the latter <br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_14157">is more promising, but it may nevertheless require a huge effort to make it entirely suitable for our application. <br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_14272">Also, while we can provide some development time, we cannot really afford to maintain a separate fork of Pd or <br clear="none"></div><div id="yui_3_16_0_ym19_1_1497639033253_19880">Pd-l2ork on our own.</div><div><br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_17078">Well, once you work the kinks out of your currrent improvements, please make a merge request. <br clear="none"></div><div dir="ltr" id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_17077">I think it would be a huge usability improvement-- I know several Pd users have complained about mouse <br clear="none"></div><div id="yui_3_16_0_ym19_1_1497639033253_4875">motion eating their CPU in the past.<br clear="none"></div><div id="yui_3_16_0_ym19_1_1497639033253_4876"><br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_16267">> Now, after this long introduction to say what I have been up to, I'd like to ask the Purr-data developers what is <br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_16266">in the plans for Purr-data/Pd-l2ork.</div><div class="qtdSeparateBR"><br><br></div><div class="yiv9021853663yqt4227145927" id="yiv9021853663yqtfd22567"><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_19341">> I am interested in anything in the roadmap that aims at de-entangling the GUI stuff from the core <br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_19342">of Pd and delegating it to the GUI, along the lines of my hack above, but in a more structured and <br clear="none"></div><div id="yiv9021853663yui_3_16_0_ym19_1_1497627985357_19488">complete way (e.g.: why do we need to ask Pd if we should flash an outlet onmouseover in the GUI? <br clear="none"></div><div id="yui_3_16_0_ym19_1_1497639033253_12241">Why do we need to tell Pd that we are dragging a new patch cord until we actually release it? Why do <br clear="none"></div><div id="yui_3_16_0_ym19_1_1497639033253_12242">we have to ask Pd about the cursor shape?).</div><div id="yui_3_16_0_ym19_1_1497639033253_15521"><div id="yui_3_16_0_ym19_1_1497639033253_15520"><br clear="none"></div><div dir="ltr" id="yui_3_16_0_ym19_1_1497639033253_15522">Those are both low-hanging fruit that could pretty easily be moved to the GUI.</div><div dir="ltr" id="yui_3_16_0_ym19_1_1497639033253_15523"><br></div><div dir="ltr" id="yui_3_16_0_ym19_1_1497639033253_17020">I don't yet have a roadmap for doing more separation work.</div><div dir="ltr" id="yui_3_16_0_ym19_1_1497639033253_18220"><br></div><div dir="ltr" id="yui_3_16_0_ym19_1_1497639033253_18221">One starting point would be to go through and figure out which parts of the GUI <br></div><div dir="ltr" id="yui_3_16_0_ym19_1_1497639033253_18222">are eating the most CPU in the audio process.</div><div dir="ltr" id="yui_3_16_0_ym19_1_1497639033253_18223"><br></div><div dir="ltr" id="yui_3_16_0_ym19_1_1497639033253_18224">Another would be to go through and figure out which parts are just <br></div><div dir="ltr" id="yui_3_16_0_ym19_1_1497639033253_18225">trivial low hanging fruit-- like xlet highlighting, and which are most <br></div><div dir="ltr" id="yui_3_16_0_ym19_1_1497639033253_18226">complex-- like rtext_senditup.<br></div><div dir="ltr" id="yui_3_16_0_ym19_1_1497639033253_18227"><br></div><div dir="ltr" id="yui_3_16_0_ym19_1_1497639033253_18228">For example: rtext_senditup actually hold parts of the missing <br></div><div dir="ltr" id="yui_3_16_0_ym19_1_1497639033253_18229">specification within it. For one thing, that function has the recipe for how to <br></div><div dir="ltr" id="yui_3_16_0_ym19_1_1497639033253_18230">split lines of text in objects, messages, and comments. But even if <br></div><div dir="ltr" id="yui_3_16_0_ym19_1_1497639033253_18531">line splitting upon object creation eats a lot of CPU, it's unwise to <br></div><div dir="ltr" id="yui_3_16_0_ym19_1_1497639033253_18532">go about refactoring that function right now because you risk losing key <br></div><div dir="ltr" id="yui_3_16_0_ym19_1_1497639033253_18533">parts of the line-splittng algorithm in the process.<br></div></div><div class="yiv9021853663qtdSeparateBR" id="yui_3_16_0_ym19_1_1497639033253_18535"><div><br clear="none"></div><div id="yui_3_16_0_ym19_1_1497639033253_20030">But I'm certainly open to ideas here.</div><div id="yui_3_16_0_ym19_1_1497639033253_20032"><br></div><div id="yui_3_16_0_ym19_1_1497639033253_20031">> Also, if there is an interest in potentially accepting a merge request for <br></div><div id="yui_3_16_0_ym19_1_1497639033253_20312">an improved version of my code above, that would already be a great deal to us, <br></div><div id="yui_3_16_0_ym19_1_1497639033253_20311">so I am happy to hear your opinions on that as well as what's your general <br></div><div id="yui_3_16_0_ym19_1_1497639033253_20855">opinion on changing the GUI/Pd interface and the roles of each? Are you trying <br></div><div id="yui_3_16_0_ym19_1_1497639033253_21400">to keep the Pd code for l2ork and Purr-data exactly the same? Is Purr-data the <br></div><div id="yui_3_16_0_ym19_1_1497639033253_21401">new Pd-l2ork? When?</div><div id="yui_3_16_0_ym19_1_1497639033253_21402"><br></div><div dir="ltr" id="yui_3_16_0_ym19_1_1497639033253_21403">Purr Data is the 2.0 release of Pd-l2ork.</div><div dir="ltr" id="yui_3_16_0_ym19_1_1497639033253_21404"><br></div><div dir="ltr" id="yui_3_16_0_ym19_1_1497639033253_21405">I basically removed the tcl/tk code from the core in order to do improvements <br></div><div dir="ltr" id="yui_3_16_0_ym19_1_1497639033253_21406">like the ones you are suggesting.</div><div dir="ltr" id="yui_3_16_0_ym19_1_1497639033253_21548"><br></div><div dir="ltr" id="yui_3_16_0_ym19_1_1497639033253_21547">-Jonathan<br></div><div id="yui_3_16_0_ym19_1_1497639033253_21407"><br></div><div id="yui_3_16_0_ym19_1_1497639033253_20172">> Thanks,<br></div><div id="yui_3_16_0_ym19_1_1497639033253_21408">> Giulio<br clear="none"></div></div></div></div></div></div></div></body></html>