Hello,
I am looking for some advice on a possible rewrite of the PureData GUI. I am a member of a team of student developers at Virginia Tech. We are looking to improve the usability and reliability of Pd for integration with Virginia Tech's Linux Laptop Orchestra ("l2ork," if you like witty acronyms). The creator and director of the orchestra, Dr. Ico Bukvic, has expressed to us his dissatisfaction with the current TCL/TK GUI. One possible solution we are discussing is to rewrite the GUI using either the Juce toolkit or the QT toolkit.
It would be very helpful to us if anyone could offer any suggestions, criticism, or comments on this project. Does anyone know of any similar projects? What could be some possible issues/consequences?
Some basic info about the Laptop Orchestra can be found at http://l2ork.music.vt.edu/. A goal of the project is to be as cost-efficient as possible, so commercial software like Max/MSP is not an option. PureData is being used as an interface for the performers and also as a compositional tool.
Again, any input or comments would be much appreciated.
Cheers,
Paul Kohlhoff Senior, B.S. Computer Science Virginia Tech
Did you try the current GUI rewrite?
http://puredata.info/dev/PdGuiRewrite
.hc
On Feb 23, 2010, at 2:43 PM, Paul Kohlhoff wrote:
Hello,
I am looking for some advice on a possible rewrite of the PureData GUI. I am a member of a team of student developers at Virginia Tech. We are looking to improve the usability and reliability of Pd for integration with Virginia Tech's Linux Laptop Orchestra ("l2ork," if you like witty acronyms). The creator and director of the orchestra, Dr. Ico Bukvic, has expressed to us his dissatisfaction with the current TCL/TK GUI. One possible solution we are discussing is to rewrite the GUI using either the Juce toolkit or the QT toolkit.
It would be very helpful to us if anyone could offer any suggestions, criticism, or comments on this project. Does anyone know of any similar projects? What could be some possible issues/ consequences?
Some basic info about the Laptop Orchestra can be found at http://l2ork.music.vt.edu/ . A goal of the project is to be as cost-efficient as possible, so commercial software like Max/MSP is not an option. PureData is being used as an interface for the performers and also as a compositional tool.
Again, any input or comments would be much appreciated.
Cheers,
Paul Kohlhoff Senior, B.S. Computer Science Virginia Tech _______________________________________________ Pd-dev mailing list Pd-dev@iem.at http://lists.puredata.info/listinfo/pd-dev
----------------------------------------------------------------------------
I have always wished for my computer to be as easy to use as my telephone; my wish has come true because I can no longer figure out how to use my telephone." --Bjarne Stroustrup (creator of C++)
Did you try the current GUI rewrite?
http://puredata.info/dev/PdGuiRewrite
.hc
Hi Hans,
Please allow me to chime in here for the sake of clarifying a few things about this project.
First of all, allow me to state that I honestly appreciate all the efforts being made in respect to the GUI rewrite. Yet, after messing with Tcl/Tk implementation over the past 9+ months, including SVN checkouts of the GUI-rewrite branch, I personally find Tcl/Tk solution inadequate for L2Ork's needs as we do depend in large part on GUI feedback and Tcl/Tk has so far proven quite inefficient, or more precisely CPU-hungry. For instance, having 5 tables displayed concurrently and updating their information every n samples (not that you would want to have this as part of the gui, but hopefully this will drive the point home, since similar setup using Max/JUCE yields literally no CPU overhead), or having a large-font-sized number box updating rapidly--even at lower update rates, this effectively requires a huge chunk of CPU on a typical Atom-based netbook.
Hence, I personally feel going after JUCE or Qt still allows Pd to be as platform-agnostic as Pd currently is (with the exception that these are AFAIK using GPL as opposed to BSD license), while also providing significant performance improvement. Max has certainly made a great use of JUCE and I still have fond memories of working with Qt while learning to program my first GUI applications.
I do understand that a good part of the community may not appreciate yet another attempt at GUI rewrite as much than contributing our time and energy to the existing GUI-rewrite projects. From this perspective I think you, Hans, and those helping you on the GUI-rewrite project are doing a great service to the community.
Yet, IMHO I feel that Tcl/Tk is a dead-end for L2Ork's needs in the long run and I would really like to see Pd wrapped in a new and more contemporary toolkit even if that means losing real-time scripting advantages of Tcl/Tk (which is something we can always work around later, if necessary).
I also suspect that this new implementation may in part or entirely break backwards compatibility in order to allow for GUI to be as customizable as possible, meaning that patches may contain considerably more information about each object in order to allow for additional information to be stored. Yet, even this hurdle could be overcome by providing ability to open older patches and saving them in newer format.
Despite a rather fundamentally different approach to GUI, I am sincerely hoping that we could somehow maintain this implementation in sync with the main branch, but am also aware that this may be impossible at first until our branch stabilizes. In addition, I am very much aware that such a sync may also require agreement from the community's perspective to allow alterations to the way Pd's code is structured which is something I by no means am expecting, but rather am kindly asking for everyone to consider in order for the community at large to be able to eventually benefit from our contribution.
Right now we have two students who are being assigned to work on this for a good chunk of a semester with a possibility of throwing more students at the task down the road. I think having community support would be a tremendous benefit to our project and efforts and we would certainly welcome anyone who wishes to join/contribute to our efforts.
At any rate, just my 0.000001-cents worth...
Best wishes,
Ico
The problem is that Tcl/Tk is not the bottleneck when it comes to array redrawing. Its how pd sends draw commands. Redrawing a big array once could result in literally 500KB of Tcl code generated by Pd and sent to the GUI.
So whether you use Tcl/Tk, Qt, JUCE, or whatever, you'll have to address that issue to get any real gain. I'd say the best place to start is try updating the array drawing code so that it just sends a simple command to Tcl and let's Tcl do the drawing work. You could easily make that an external and use it with any version of Pd.
.hc
On Tue, 23 Feb 2010 19:46 -0500, "Ivica Ico Bukvic" ico@vt.edu wrote:
Did you try the current GUI rewrite?
http://puredata.info/dev/PdGuiRewrite
.hc
Hi Hans,
Please allow me to chime in here for the sake of clarifying a few things about this project.
First of all, allow me to state that I honestly appreciate all the efforts being made in respect to the GUI rewrite. Yet, after messing with Tcl/Tk implementation over the past 9+ months, including SVN checkouts of the GUI-rewrite branch, I personally find Tcl/Tk solution inadequate for L2Ork's needs as we do depend in large part on GUI feedback and Tcl/Tk has so far proven quite inefficient, or more precisely CPU-hungry. For instance, having 5 tables displayed concurrently and updating their information every n samples (not that you would want to have this as part of the gui, but hopefully this will drive the point home, since similar setup using Max/JUCE yields literally no CPU overhead), or having a large-font-sized number box updating rapidly--even at lower update rates, this effectively requires a huge chunk of CPU on a typical Atom-based netbook.
Hence, I personally feel going after JUCE or Qt still allows Pd to be as platform-agnostic as Pd currently is (with the exception that these are AFAIK using GPL as opposed to BSD license), while also providing significant performance improvement. Max has certainly made a great use of JUCE and I still have fond memories of working with Qt while learning to program my first GUI applications.
I do understand that a good part of the community may not appreciate yet another attempt at GUI rewrite as much than contributing our time and energy to the existing GUI-rewrite projects. From this perspective I think you, Hans, and those helping you on the GUI-rewrite project are doing a great service to the community.
Yet, IMHO I feel that Tcl/Tk is a dead-end for L2Ork's needs in the long run and I would really like to see Pd wrapped in a new and more contemporary toolkit even if that means losing real-time scripting advantages of Tcl/Tk (which is something we can always work around later, if necessary).
I also suspect that this new implementation may in part or entirely break backwards compatibility in order to allow for GUI to be as customizable as possible, meaning that patches may contain considerably more information about each object in order to allow for additional information to be stored. Yet, even this hurdle could be overcome by providing ability to open older patches and saving them in newer format.
Despite a rather fundamentally different approach to GUI, I am sincerely hoping that we could somehow maintain this implementation in sync with the main branch, but am also aware that this may be impossible at first until our branch stabilizes. In addition, I am very much aware that such a sync may also require agreement from the community's perspective to allow alterations to the way Pd's code is structured which is something I by no means am expecting, but rather am kindly asking for everyone to consider in order for the community at large to be able to eventually benefit from our contribution.
Right now we have two students who are being assigned to work on this for a good chunk of a semester with a possibility of throwing more students at the task down the road. I think having community support would be a tremendous benefit to our project and efforts and we would certainly welcome anyone who wishes to join/contribute to our efforts.
At any rate, just my 0.000001-cents worth...
Best wishes,
Ico
The problem is that Tcl/Tk is not the bottleneck when it comes to array redrawing. Its how pd sends draw commands. Redrawing a big array once could result in literally 500KB of Tcl code generated by Pd and sent to the GUI.
So whether you use Tcl/Tk, Qt, JUCE, or whatever, you'll have to address that issue to get any real gain. I'd say the best place to start is try updating the array drawing code so that it just sends a simple command to Tcl and let's Tcl do the drawing work. You could easily make that an external and use it with any version of Pd.
.hc
Interesting. Still, this does not resolve the issue of a large number box on the screen being updated rapidly taking up a lot of CPU (it scales exponentially with growing font size and in this case I suspect Pd's output is minimal, amounting to change in the displayed set of characters).
Ico
I'm not a coder, but I could also give a sugestion, which I haven't tried myself for lack of time: how about circumventing tcl/tk, by writing your gui in gem? There was once a report that it's much faster - I can only say it does if you're using data structures inside a gop.
The problem is that Tcl/Tk is not the bottleneck when it comes to array redrawing. Its how pd sends draw commands. Redrawing a big array once could result in literally 500KB of Tcl code generated by Pd and sent to the GUI.
So whether you use Tcl/Tk, Qt, JUCE, or whatever, you'll have to address that issue to get any real gain. I'd say the best place to start is try updating the array drawing code so that it just sends a simple command to Tcl and let's Tcl do the drawing work. You could easily make that an external and use it with any version of Pd.
.hc
Interesting. Still, this does not resolve the issue of a large number box on the screen being updated rapidly taking up a lot of CPU (it scales exponentially with growing font size and in this case I suspect Pd's output is minimal, amounting to change in the displayed set of characters).
Ico
Pd-dev mailing list Pd-dev@iem.at http://lists.puredata.info/listinfo/pd-dev
On Feb 23, 2010, at 11:52 PM, Ivica Ico Bukvic wrote:
The problem is that Tcl/Tk is not the bottleneck when it comes to array redrawing. Its how pd sends draw commands. Redrawing a big array once could result in literally 500KB of Tcl code generated by Pd and sent to the GUI.
So whether you use Tcl/Tk, Qt, JUCE, or whatever, you'll have to address that issue to get any real gain. I'd say the best place to start is try updating the array drawing code so that it just sends a simple command to Tcl and let's Tcl do the drawing work. You could easily make that an external and use it with any version of Pd.
.hc
Interesting. Still, this does not resolve the issue of a large number box on the screen being updated rapidly taking up a lot of CPU (it scales exponentially with growing font size and in this case I suspect Pd's output is minimal, amounting to change in the displayed set of characters).
run pd with gui messages dumped to stderr and you can see what I mean, should be helpful in seeing the amount of code that gets sent for a given operation:
./pd -stderr -d 3
.hc
----------------------------------------------------------------------------
Access to computers should be unlimited and total. - the hacker ethic
It appears this is definitely linked to the amount of data exchanged between Pd and Tcl/Tk and apparently sliders are relatively hungry GUI-wise as their presence definitely increases frequency of this occurence. What is particularly curious is the stderr feedback. The moment gui loses ability to sync following objects stop responding:
hradio vradio vu hslider vslider number2 and old number objects
curiously bang and toggle remain operational
You can try to type in the old number and the first digit followed by ... appears but it never updates.
The system remains responsive even with gui stuck (data is still being passed through objects that appear stuck).
stderr shows last command that causes problem as: missing close-brace
which suggests to me that perhaps messages flow so fast to tcl/tk that it perhaps some of them get mangled and lose the closing brace. The patch in question uses only following gui objects: number2/number/toggle/vslider/bang/canvas.
Any ideas?
Best wishes,
Ico
I've noticed this behavior a bit also, but haven't had a chance to debug it. I'd try capturing the Tcl code send by the Pd GUI, then checking it in Tcl with [info complete].
The real key is isolating the step that makes it happen, then fixing it should be pretty easy.
I'm immersed in the Arduino 1.0 Conference this week, then I plan on diving back into the Pd-extedned 0.42 release, so I'll be able to help more after Sunday.
.hc
On Mar 17, 2010, at 11:44 AM, Ivica Ico Bukvic wrote:
It appears this is definitely linked to the amount of data exchanged between Pd and Tcl/Tk and apparently sliders are relatively hungry GUI-wise as their presence definitely increases frequency of this occurence. What is particularly curious is the stderr feedback. The moment gui loses ability to sync following objects stop responding:
hradio vradio vu hslider vslider number2 and old number objects
curiously bang and toggle remain operational
You can try to type in the old number and the first digit followed by ... appears but it never updates.
The system remains responsive even with gui stuck (data is still being passed through objects that appear stuck).
stderr shows last command that causes problem as: missing close-brace
which suggests to me that perhaps messages flow so fast to tcl/tk that it perhaps some of them get mangled and lose the closing brace. The patch in question uses only following gui objects: number2/number/toggle/vslider/bang/canvas.
Any ideas?
Best wishes,
Ico
----------------------------------------------------------------------------
There is no way to peace, peace is the way. -A.J. Muste
OK, more investigation brings up the following (I am including surrounding commands jut in case I missed something):
pdtk_ping .x9c14968.c coords 9c19e40KNOB 126 105 133 105 .x9c14968.c itemconfigure 9c1edc0NUMBER -fill #00fc04 -text {0} .x9c14968.c coords 9cfc848KNOB 666 106 673 106 .x9c14968.c itemconfigure 9cfffe0NUMBER -fill #b8b8b8 -text {0} .x9c14968.c coords 9cfe7f8KNOB 813 29 827 29 .x9c14968.c coords 9cfe7f8KNOB 813 25 827 25 .x9c14968.c itemconfigure 9cf5b58BUT -fill #000000 .x9c14968.c coords 9cfe7f8KNOB 813 19 827 19 .x9c14968.c itemconfigure 9cf60d8NUMBER -fill #fc8000 -text {0} .x9c14968.c coords 9cfed60KNOB 828 106 835 106 .x9c14968.c coords 9cfe2b0KNOB 801 106 808 106 .x9c14968.c coords 9cfdd68KNOB 774 106 781 106 .x9c14968.c coords 9cfd820KNOB 747 106 754 106 .x9c14968.c coords 9cfd2d8KNOB 720 106 727 106 .x9c14968.c coords 9cfcd90KNOB 693 106 700 106 .x9c14968.c coords 9cfc300KNOB 639 106 646 106 .xtext file '/home/l2orkist/L2Ork/Exercises/4/Ico/Conductor_Presets_Full/ambiance.0.conductor.coll.preset.txt'} .x9c14968.c coords 9cfbdb8KNOB 612 106 619 106 .x9c14968.c itemconfigure 9cf5b58BUT -fill #fc0.x9c.x9c14968.c coords 9cfb870KNOB 585 106 592 106 pdtk_ping .x9c14968.c itemconfigure 9cf6868LABEL -text {All sounds off} missing close-brace invalid color name "#fc0.x9c14968.c" bad option "crepdtk_ping": must be addtag, bbox, bind, canvasx, canvasy, cget, configure, coords, create, dchars, delete, dtag, find, focus, gettags, icursor, index, insert, itemcget, itemconfigure, lower, move, postscript, raise, scale, scan, select, type, xview, or yview .x9c14968.c itemconfigure 9cf5b58BUT -fill #000000 pdtk_post { coll: finished reading 28 lines from text file '/home/l2orkist/L2Ork/Exercises/4/Ico/Conductor_Presets_Full/ambiance.0.conductor.coll.preset.txt'} .x9c14968.c itemconfigure 9cf5b58BUT -fill #fc0400 .x9c14968.c itemconfigure 9cf6868LABEL -text {All sounds off} pdtk_post { coll: finished reading 28 lines from text file '/home/l2orkist/L2Ork/Exercises/4/Ico/Conductor_Presets_Full/ambiance.0.conductor.coll.preset.txt'} .x9c14968.c itemconfigure 9cf5b58BUT -fill #000000 .x9c14968.c itemconfigure 9cf6868LABEL -text {All sounds off} .x9c14968.c itemconfigure 9cf5b58BUT -fill #fc0400 .x9c14968.c itemconfigure 9cf5b58BUT -fill #000000
Notice crepdtk_ping. It is almost as if create <something> got caught in the middle of a pdtk_ping command that appears to flush the queue, so the create <something> e.g. a rectangle command got truncated and outputting garbage resulted in an invalid command after which the gui stops corresponding. Disabling pdtk_ping in s_inter.c indeed disables all GUI operations so this appears to be the culprit (as it runs in while(1) loop and hence the asynchronous operation. I wonder if there is a better way to invoke pdtk_ping than an apparently brute force
if (sys_bytessincelastping >= GUI_BYTESPERPING)
from the s_inter.c sys_flushqueue()?
Also, is the sys_flushtogui responsible for ensuring that whatever is being flushed is sane? Perhaps here one needs to check that the cutoff is indeed where \n exists?
Any thoughts?
Ico
2 more examples, but this time having nothing to do with pdtk_post but with other commands overlapping (in this case both appear to be truncated versions of 2 .x8d7b968.c). Something appears to be awful wrong with the way these things are getting enqueued.
BTW, overclocking the laptop lowers the likelihood of this occurring, or in other words, the system remains stable longer.
wrote 737 of 737 missing close-brace .x8d7b968.c itemconfigure 8e5d868LABEL -text {All sounds off} invalid command name ".x8d.x8d7b968.c" wrote 63 of 63
wrote 596 of 596 missing close-brace .x8d7b968.c itemconfigure 8e5d868LABEL -text {All sounds off} wrote 63 of 63 invalid command name ".x8d7b968..x8d7b968.c" .x8d7b968.c itemconfigure 8e5cb58BUT -fill #fc0400 wrote 51 of 51
Ico
A couple more instances (this time apparently canvas+create and canvas +-fill flag):
wrote 737 of 737 missing close-brace wrong # coordinates: expected 0 or 4, got 5 bad option "cre.x87260d8.c": must be addtag, bbox, bind, canvasx, canvasy, cget, configure, coords, create, dchars, delete, dtag, find, focus, gettags, icursor, index, insert, itemcget, itemconfigure, lower, move, postscript, raise, scale, scan, select, type, xview, or yview .x87260d8.c itemconfigure 8807fd8LABEL -text {All sounds off} wrote 63 of 63
missing close-brace .x87260d8.c itemconfigure 8807fd8LABEL -text {F6} wrote 51 of 51 unknown option "-f.x87260d8.c"
It is almost if there are three asynchronous streams trying to enqueue events inside Pd.
Ico
This kinds of sounds like the stuff we were dealing with in the pd-gui- rewrite branch. Do you have a patch you are using to test this? Is the word 'cre' always involved in these freak outs?
.hc
On Mar 17, 2010, at 3:30 PM, Ivica Ico Bukvic wrote:
A couple more instances (this time apparently canvas+create and canvas +-fill flag):
wrote 737 of 737 missing close-brace wrong # coordinates: expected 0 or 4, got 5 bad option "cre.x87260d8.c": must be addtag, bbox, bind, canvasx, canvasy, cget, configure, coords, create, dchars, delete, dtag, find, focus, gettags, icursor, index, insert, itemcget, itemconfigure, lower, move, postscript, raise, scale, scan, select, type, xview, or yview .x87260d8.c itemconfigure 8807fd8LABEL -text {All sounds off} wrote 63 of 63
missing close-brace .x87260d8.c itemconfigure 8807fd8LABEL -text {F6} wrote 51 of 51 unknown option "-f.x87260d8.c"
It is almost if there are three asynchronous streams trying to enqueue events inside Pd.
Ico
----------------------------------------------------------------------------
All mankind is of one author, and is one volume; when one man dies, one chapter is not torn out of the book, but translated into a better language; and every chapter must be so translated.... -John Donne
On Wed, 2010-03-17 at 16:38 -0400, Hans-Christoph Steiner wrote:
This kinds of sounds like the stuff we were dealing with in the pd-gui- rewrite branch. Do you have a patch you are using to test this? Is the word 'cre' always involved in these freak outs?
.hc
No, see my other replies. So far there were canvas names overwriting each other, canvas name and -fill flag of another statement, canvas and create, and create and pdtk_ping. It appears that the queuing engine has some serious issues that surface when there is heavy traffic between pd and tk.
Ico
I finally discovered the problem. It is not pd or pd-extended at all. It appears that the original implementation of the wiimote object I based l2ork's threaded version on was causing these issues as some of its output was callback driven from the external cwiid library, rather than being "pushed" by the incoming bang signal. I think this makes sense as when those messages are thrown out-of-sync in respect to the patch tree traversal (or whatever method is being used to do this), all kinds of weird things can happen, like seemingly random truncation of messages which becomes more prominent when the message activity increases.
Now, that I redesigned the object so that it only outputs stuff through non-signal outlets when it receives bang (as it should), I've yet to reproduce a problem which would've been otherwise occurring within seconds, but only if I used wiimote button messages to trigger gui events (keyboard events did not cause any problems whatsoever, which seems to speak in favor of the aforesaid explanation).
So, Hans, this perhaps may be the cause of your problems as well--FWIW you may want to check any less common pd objects you may be using in specific patches and see if they allow for out-of-sync outputs that are threaded separately from Pd's signal tree.
BTW, I would also love to hear thoughts from the hardened Pd devs regarding this. I haven't had a chance to read carefully through the external (design documentation which likely covers this), as my objects were mainly alterations of the existing designs.
Speaking of which, I've also implemented a simple alternative version of the phasor~ that outputs bang every time it completes a period (or as close as it gets to this moment based on pd's audio engine buffer which I believe is 64 bytes). Now I am wondering if having a "bang" outputted from a non-signal outlet whose triggering is dictated by the dsp thread may cause similar problems in the long run and whether I should simply stick to vanilla >~ kinds of solutions for this purpose.
Here's the relevant code (which is essentially identical to the built-in phasor with one notable exception towards the bottom):
t_int *disis_phasor_perform(t_int *w) { t_disis_phasor *x = (t_disis_phasor *)(w[1]); t_float *in = (t_float *)(w[2]); t_float *out = (t_float *)(w[3]); int n = (int)(w[4]); double dphase = x->x_phase + UNITBIT32; union disis_phasor_tabfudge tf; int normhipart; float conv = x->x_conv; tf.tf_d = UNITBIT32; normhipart = tf.tf_i[HIOFFSET]; tf.tf_d = dphase;
while (n--) { tf.tf_i[HIOFFSET] = normhipart; dphase += *in++ * conv; *out++ = tf.tf_d - UNITBIT32; tf.tf_d = dphase; } tf.tf_i[HIOFFSET] = normhipart; x->x_phase = tf.tf_d - UNITBIT32; //here comes the bang inside the dsp thread //is this a bad idea? if (x->x_phase_delta > 0.5 && x->x_phase < 0.5) outlet_bang(x->b_out); x->x_phase_delta = x->x_phase; return (w+5); }
Any advice on this one, particularly from the Pd-dev gurus would be most appreciated!
Best wishes,
Ico
Hi Ivo -
It's unsafe to issue messages from inside a DSP routine, because the message could eventually cause tables to relocate or even a rebuild of the DSP chain. The safe thing is to schedule the message using clock_delay().
examples are snapshot~ and (more complicatedly) fiddle~ and bonk~.
cheers Miller
On Wed, Mar 17, 2010 at 09:39:44PM -0400, Ivica Ico Bukvic wrote:
I finally discovered the problem. It is not pd or pd-extended at all. It appears that the original implementation of the wiimote object I based l2ork's threaded version on was causing these issues as some of its output was callback driven from the external cwiid library, rather than being "pushed" by the incoming bang signal. I think this makes sense as when those messages are thrown out-of-sync in respect to the patch tree traversal (or whatever method is being used to do this), all kinds of weird things can happen, like seemingly random truncation of messages which becomes more prominent when the message activity increases.
Now, that I redesigned the object so that it only outputs stuff through non-signal outlets when it receives bang (as it should), I've yet to reproduce a problem which would've been otherwise occurring within seconds, but only if I used wiimote button messages to trigger gui events (keyboard events did not cause any problems whatsoever, which seems to speak in favor of the aforesaid explanation).
So, Hans, this perhaps may be the cause of your problems as well--FWIW you may want to check any less common pd objects you may be using in specific patches and see if they allow for out-of-sync outputs that are threaded separately from Pd's signal tree.
BTW, I would also love to hear thoughts from the hardened Pd devs regarding this. I haven't had a chance to read carefully through the external (design documentation which likely covers this), as my objects were mainly alterations of the existing designs.
Speaking of which, I've also implemented a simple alternative version of the phasor~ that outputs bang every time it completes a period (or as close as it gets to this moment based on pd's audio engine buffer which I believe is 64 bytes). Now I am wondering if having a "bang" outputted from a non-signal outlet whose triggering is dictated by the dsp thread may cause similar problems in the long run and whether I should simply stick to vanilla >~ kinds of solutions for this purpose.
Here's the relevant code (which is essentially identical to the built-in phasor with one notable exception towards the bottom):
t_int *disis_phasor_perform(t_int *w) { t_disis_phasor *x = (t_disis_phasor *)(w[1]); t_float *in = (t_float *)(w[2]); t_float *out = (t_float *)(w[3]); int n = (int)(w[4]); double dphase = x->x_phase + UNITBIT32; union disis_phasor_tabfudge tf; int normhipart; float conv = x->x_conv; tf.tf_d = UNITBIT32; normhipart = tf.tf_i[HIOFFSET]; tf.tf_d = dphase;
while (n--) { tf.tf_i[HIOFFSET] = normhipart; dphase += *in++ * conv; *out++ = tf.tf_d - UNITBIT32; tf.tf_d = dphase; } tf.tf_i[HIOFFSET] = normhipart; x->x_phase = tf.tf_d - UNITBIT32;
//here comes the bang inside the dsp thread //is this a bad idea? if (x->x_phase_delta > 0.5 && x->x_phase < 0.5) outlet_bang(x->b_out); x->x_phase_delta = x->x_phase; return (w+5); }
Any advice on this one, particularly from the Pd-dev gurus would be most appreciated!
Best wishes,
Ico
Pd-dev mailing list Pd-dev@iem.at http://lists.puredata.info/listinfo/pd-dev
-----Original Message----- From: Miller Puckette [mailto:mpuckett@imusic1.ucsd.edu] Sent: Wednesday, March 17, 2010 10:26 PM To: Ivica Ico Bukvic Cc: Hans-Christoph Steiner; pd-dev@iem.at Subject: Re: [PD-dev] more information on the gui getting stuck on 0.42.5
Hi Ivo -
It's unsafe to issue messages from inside a DSP routine, because the message could eventually cause tables to relocate or even a rebuild of the DSP chain. The safe thing is to schedule the message using clock_delay().
examples are snapshot~ and (more complicatedly) fiddle~ and bonk~.
cheers Miller
Many thanks for the clarification Miller. This helps a lot!
BTW, how often does the clock_delay() fire? Are we talking major delays that would effectively render this kind of a bang-based sync useless or is this something that occurs practically as often as dsp calls?
Best wishes,
Ico
If you ask for clock_delay() of 0, it will fire before the next DSP tick, that is to say, as soon as possible.
cheers Miller
On Thu, Mar 18, 2010 at 12:04:13AM -0400, Ivica Ico Bukvic wrote:
-----Original Message----- From: Miller Puckette [mailto:mpuckett@imusic1.ucsd.edu] Sent: Wednesday, March 17, 2010 10:26 PM To: Ivica Ico Bukvic Cc: Hans-Christoph Steiner; pd-dev@iem.at Subject: Re: [PD-dev] more information on the gui getting stuck on 0.42.5
Hi Ivo -
It's unsafe to issue messages from inside a DSP routine, because the message could eventually cause tables to relocate or even a rebuild of the DSP chain. The safe thing is to schedule the message using clock_delay().
examples are snapshot~ and (more complicatedly) fiddle~ and bonk~.
cheers Miller
Many thanks for the clarification Miller. This helps a lot!
BTW, how often does the clock_delay() fire? Are we talking major delays that would effectively render this kind of a bang-based sync useless or is this something that occurs practically as often as dsp calls?
Best wishes,
Ico
Speaking of clock_delay(), does every kind of output that is triggered by something other than pd's tree traversal (e.g. incoming network messages that are gathered by a separate thread, or messages triggered by other libs) need to be sent through clock_delay() so that it occurs within the right timeframe or is that not a problem like triggering from the dsp thread?
Likewise, I noticed that netclient (maxlib) uses something called sys_pollfn() call, is this safe?
Best wishes,
Ico
Likewise, I noticed that netclient (maxlib) uses something called sys_pollfn() call, is this safe?
Oops, I meant sys_addpollfn()...
Another question related to this. In the netclient.c (maxlib) there is the following code excerpt:
/* get's called when connection has been made */ static void netclient_tick(t_netclient *x) { outlet_float(x->x_outconnect, 1); /* add pollfunction for checking for input */ sys_addpollfn(x->x_fd, (t_fdpollfn)netclient_rcv, x); }
Isn't the outlet_float call here unsafe as it is being triggered by an external potentially out-of-sync force (namely connection)? Shouldn't this be done through clock_delay() just to be safe? If I understand this correctly, Pd does audio in 64-byte chunks and then the data processing in between. Is this correct?
If so, how does Pd deal with such events if they happen during the times the pd's message tree is not being traversed (e.g. during the dsp cycle)?
Best wishes,
Ico
Ivica Ico Bukvic wrote:
Likewise, I noticed that netclient (maxlib) uses something called sys_pollfn() call, is this safe?
Oops, I meant sys_addpollfn()...
Another question related to this. In the netclient.c (maxlib) there is the following code excerpt:
/* get's called when connection has been made */ static void netclient_tick(t_netclient *x) { outlet_float(x->x_outconnect, 1); /* add pollfunction for checking for input */ sys_addpollfn(x->x_fd, (t_fdpollfn)netclient_rcv, x); }
Isn't the outlet_float call here unsafe as it is being triggered by an external potentially out-of-sync force (namely connection)? Shouldn't this be done through clock_delay() just to be safe? If I understand this correctly, Pd does audio in 64-byte chunks and then the data processing in between. Is this correct?
If so, how does Pd deal with such events if they happen during the times the pd's message tree is not being traversed (e.g. during the dsp cycle)?
That is why they are poll functions. The poll functions are polled right after the dsp update, in sys_microsleep(). A select call is made to see if any of the file descriptors are ready for read/writing. So if the socket connects at any random time, the float will only be sent out the outlet after the dsp. Another poll function is then registered to check for received data on the socket. sys_microsleep() is called from m_pollingscheduler(), Pd's main loop, in m_sched.c, after the dacs are written, so (as I understand it), it is safe to make calls from a pollfunction. I think it's only outlet writes made directly from the dsp object's perform routine that are dangerous, they should be scheduled for right after the dac writes using clock_delay(0).
Martin
Another question related to this. In the netclient.c (maxlib) there is the following code excerpt:
/* get's called when connection has been made */ static void netclient_tick(t_netclient *x) { outlet_float(x->x_outconnect, 1); /* add pollfunction for checking for input */ sys_addpollfn(x->x_fd, (t_fdpollfn)netclient_rcv, x); }
Isn't the outlet_float call here unsafe as it is being triggered by an external potentially out-of-sync force (namely connection)? Shouldn't this be done through clock_delay() just to be safe? If I understand this correctly, Pd does audio in 64-byte chunks and then the data processing in between. Is this correct?
If so, how does Pd deal with such events if they happen during the times the pd's message tree is not being traversed (e.g. during the dsp cycle)?
That is why they are poll functions. The poll functions are polled right after the dsp update, in sys_microsleep(). A select call is made to see if any of the file descriptors are ready for read/writing. So if the socket connects at any random time, the float will only be sent out the outlet after the dsp. Another poll function is then registered to check for received data on the socket. sys_microsleep() is called from m_pollingscheduler(), Pd's main loop, in m_sched.c, after the dacs are written, so (as I understand it), it is safe to make calls from a pollfunction. I think it's only outlet writes made directly from the dsp object's perform routine that are dangerous, they should be scheduled for right after the dac writes using clock_delay(0).
Martin
Thanks for the explanation. I am not sure however how does this apply to the aforesaid example, so I would greatly appreciate your insight in that specific scenario. Namely:
In the netclient example is the outlet_float call ok even though the netclient_tick function containing it is triggered by an external out-of-sync force (namely network connection)? If so, what ensures that this particular call is not going to happen right in the middle of other GUI stuff already being sent out and/or dsp loop as the network client has no idea when that is actually happening? Shouldn't this be also clock_delay()?
In other words, are outlet_<something> calls safe to be made from non-dsp functions no matter when they happen *or* are they safe to be made only in objects that are being pushed by incoming data streams (which is typically most of Pd objects, but not all, e.g. such as metro for instance)? If latter is the case, I would say clock_delay(0) is necessary even on the aforesaid call.
Likewise, if the latter is the case, this may potentially turn out to be the source of gui freezes where calls come in the middle of other calls and therefore cause "missing close-brace" tcl/tk errors.
Best wishes,
Ico
Ivica Ico Bukvic wrote:
Another question related to this. In the netclient.c (maxlib) there is the following code excerpt:
/* get's called when connection has been made */ static void netclient_tick(t_netclient *x) { outlet_float(x->x_outconnect, 1); /* add pollfunction for checking for input */ sys_addpollfn(x->x_fd, (t_fdpollfn)netclient_rcv, x); }
Isn't the outlet_float call here unsafe as it is being triggered by an external potentially out-of-sync force (namely connection)? Shouldn't this be done through clock_delay() just to be safe? If I understand this correctly, Pd does audio in 64-byte chunks and then the data processing in between. Is this correct?
If so, how does Pd deal with such events if they happen during the times the pd's message tree is not being traversed (e.g. during the dsp cycle)?
That is why they are poll functions. The poll functions are polled right after the dsp update, in sys_microsleep(). A select call is made to see if any of the file descriptors are ready for read/writing. So if the socket connects at any random time, the float will only be sent out the outlet after the dsp. Another poll function is then registered to check for received data on the socket. sys_microsleep() is called from m_pollingscheduler(), Pd's main loop, in m_sched.c, after the dacs are written, so (as I understand it), it is safe to make calls from a pollfunction. I think it's only outlet writes made directly from the dsp object's perform routine that are dangerous, they should be scheduled for right after the dac writes using clock_delay(0).
Martin
Thanks for the explanation. I am not sure however how does this apply to the aforesaid example, so I would greatly appreciate your insight in that specific scenario. Namely:
In the netclient example is the outlet_float call ok even though the netclient_tick function containing it is triggered by an external out-of-sync force (namely network connection)?
Yes, because netclient_tick is called after a clock timeout that was triggered by the connect routine running in a different thread.
If so, what ensures that this particular call is not going to happen right in the middle of other GUI stuff already being sent out and/or dsp loop as the network client has no idea when that is actually happening? Shouldn't this be also clock_delay()?
It _is_ clock_delayed. netclient_tick() is associated with a clock in netclient_new() as: x->x_clock = clock_new(x, (t_method)netclient_tick); and the x_clock is set to timeout in 0 milliseconds in netclient_child_connect() after the socket connects, which can happen at any time since it's running in a separate thread. The clock will only be checked at one point in the main loop, after the dacs have been written, so the function it calls will run at a safe time.
In other words, are outlet_<something> calls safe to be made from non-dsp functions no matter when they happen *or* are they safe to be made only in objects that are being pushed by incoming data streams (which is typically most of Pd objects, but not all, e.g. such as metro for instance)? If latter is the case, I would say clock_delay(0) is necessary even on the aforesaid call.
I guess the rule is this: Outlet calls are safe as long as they are: 1> outside of dsp perform routines and 2> called from Pd's main thread.
Martin
Cool! Thanks for all your help!
Best wishes,
Ico
Attached fixes (version 0.42.5 pd-extended):
out-of-order output on tcpserver.c
provides output of IP and socket on disconnect so if one maintains a database of what client is associated with what socket (e.g. through a coll), this way it reports it in a way that such an external database can be updated accordingly.
Attached patch is created using diff -u.
Best wishes,
Ico
Ivica Ico Bukvic wrote:
Attached fixes (version 0.42.5 pd-extended):
out-of-order output on tcpserver.c
provides output of IP and socket on disconnect so if one maintains a database of what client is associated with what socket (e.g. through a coll), this way it reports it in a way that such an external database can be updated accordingly.
Thanks for that. I have updated tcpserver.c in svn.
Attached patch is created using diff -u.
It is a diff against an old version of tcpserver.c. You should get a recent version from the Pd svn repository: http://sourceforge.net/scm/?type=svn&group_id=55736 or the nightly builds at: http://autobuild.puredata.info/auto-build/
Martin
Attached fixes (version 0.42.5 pd-extended):
lack of reporting of disconnect through the right outlet and added safer way of reporting disconnect as it can be triggered by out-of-order events. (there is still the issue of netserver not reporting socket info or ip address properly)
Attached patch is created using diff -u.
Best wishes,
Ico
Please add it to the patch tracker:
http://puredata.info/dev/patchtracker
.hc
On Mar 26, 2010, at 10:18 PM, Ivica Ico Bukvic wrote:
Attached fixes (version 0.42.5 pd-extended):
lack of reporting of disconnect through the right outlet and added safer way of reporting disconnect as it can be triggered by out-of- order events. (there is still the issue of netserver not reporting socket info or ip address properly)
Attached patch is created using diff -u.
Best wishes,
Ico
<netclient.patch>_______________________________________________ Pd-dev mailing list Pd-dev@iem.at http://lists.puredata.info/listinfo/pd-dev
----------------------------------------------------------------------------
Access to computers should be unlimited and total. - the hacker ethic
On Tue, Feb 23, 2010 at 07:46:32PM -0500, Ivica Ico Bukvic wrote:
Hence, I personally feel going after JUCE or Qt still allows Pd to be as platform-agnostic as Pd currently is (with the exception that these are AFAIK using GPL as opposed to BSD license)
This could be an issue: unless the new GUI would be decoupled from Pd (which is a bit of a muddy discussion), using a GPL GUI library would only be allowed if Pd itself was also licensed under the GPL. As Pd is currently under a BSDish license, (afaik) it can probably fairly easily switch to GPL - but that'd leave anyone who relies on the freedom offered by the BSD(ish) license in the cold.
Qt, however, is also offered under the LGPL, so that should be no problem.
It looks like JUCE is offered under both the GPL and a commercial license, neither seem a good fit for Pd.
Arnout
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Arnout Engelen wrote:
On Tue, Feb 23, 2010 at 07:46:32PM -0500, Ivica Ico Bukvic wrote:
Hence, I personally feel going after JUCE or Qt still allows Pd to be as platform-agnostic as Pd currently is (with the exception that these are AFAIK using GPL as opposed to BSD license)
This could be an issue: unless the new GUI would be decoupled from Pd (which is a bit of a muddy discussion), using a GPL GUI library would only be allowed
well, if the new gui follows the path of the old gui, then pd-gui and pd-core are two entirely different applications, communicating over a network socket. i don't think the GPL can do anything here (e.g. make all internet explorers grabbing pages from an apache2 server violate the GPL)
personally i think the way to go is: #1 clean up the communication between pd-core and pd-gui; (i like to see the pdguirewrite as a preparation for this step) once the interface between pd and pd-gui is sufficiently clean (e.g. no more tcl/tk commands are sent over the wire), then you can implement the gui in whatever toolkit you like (and see whether it really makes a difference)
#2 provide a mechanism so an "external" can hook into the gui-communication (replacing sys_vgui() and friends) this would allow to replace the current networked communication by e,g. a multithread-based one, which would make using shared memory and the like a lot simpler (with the malus of not being able to run pd-core and pd-gui on different machines any more (think peerdata))
gmsdf IOhannes
On Wed, Feb 24, 2010 at 09:54:40PM +0100, IOhannes m zmölnig wrote:
Arnout Engelen wrote:
unless the new GUI would be decoupled from Pd (which is a bit of a muddy discussion), using a GPL GUI library would only be allowed
well, if the new gui follows the path of the old gui, then pd-gui and pd-core are two entirely different applications, communicating over a network socket. i don't think the GPL can do anything here (e.g. make all internet explorers grabbing pages from an apache2 server violate the GPL)
Well, if the protocol used for the communication is very application-specific this might not be entirely clear-cut. Afaik there's room for discussion, and license discussions are never much fun, so I actually wanted to avoid that.. perhaps I should've just kept my mouth shut :). Sorry :).
Arnout
On 2010-02-24 22:23, Arnout Engelen wrote:
Well, if the protocol used for the communication is very application-specific this might not be entirely clear-cut.
sorry to continue on the "license" issue, but i don't think that we are in flamewar hell at all (yet :-))
anyhow: it's true that the communication between pd-core and pd-gui is "application specific". however, this only means that we are on OSI-layer 7 (application (sic!) layer). other protocols on this layer include HTTP, SMTP or CIFS.
all these protocols allow interaction between proprietary and GPL'ed code. i especially mention CIFS as this was really made for a proprietary OS, and still there are GPL implementations using it.
fgmasdr IOhannes
Afaik there's room for discussion, and license discussions are never much fun, so I actually wanted to avoid that.. perhaps I should've just kept my mouth shut :). Sorry :).
Arnout
Pd-dev mailing list Pd-dev@iem.at http://lists.puredata.info/listinfo/pd-dev
On Thu, Feb 25, 2010 at 09:26:09AM +0100, IOhannes m zmoelnig wrote:
On 2010-02-24 22:23, Arnout Engelen wrote:
Well, if the protocol used for the communication is very application-specific this might not be entirely clear-cut.
sorry to continue on the "license" issue, but i don't think that we are in flamewar hell at all (yet :-))
anyhow: it's true that the communication between pd-core and pd-gui is "application specific". however, this only means that we are on OSI-layer 7 (application (sic!) layer). other protocols on this layer include HTTP, SMTP or CIFS.
all these protocols allow interaction between proprietary and GPL'ed code. i especially mention CIFS as this was really made for a proprietary OS, and still there are GPL implementations using it.
The only thing you need to think about with the GPL is whether the code is 'linked'. If the new GUI was linked (e.g. with gcc's linker program) with the core Pd then there is a problem. As far as I can tell the gui is launched as a separate process or a subprocess so there is no issue with using a GPL GUI with the BSD Pd.
Chris.
------------------- http://mccormick.cx
On Feb 24, 2010, at 3:54 PM, IOhannes m zmölnig wrote:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Arnout Engelen wrote:
On Tue, Feb 23, 2010 at 07:46:32PM -0500, Ivica Ico Bukvic wrote:
Hence, I personally feel going after JUCE or Qt still allows Pd to be as platform-agnostic as Pd currently is (with the exception that these are AFAIK using GPL as opposed to BSD license)
This could be an issue: unless the new GUI would be decoupled from Pd (which is a bit of a muddy discussion), using a GPL GUI library would only be allowed
well, if the new gui follows the path of the old gui, then pd-gui and pd-core are two entirely different applications, communicating over a network socket. i don't think the GPL can do anything here (e.g. make all internet explorers grabbing pages from an apache2 server violate the GPL)
personally i think the way to go is: #1 clean up the communication between pd-core and pd-gui; (i like to see the pdguirewrite as a preparation for this step) once the interface between pd and pd-gui is sufficiently clean (e.g. no more tcl/tk commands are sent over the wire), then you can implement the gui in whatever toolkit you like (and see whether it really makes a difference)
This is definitely the way to go. pd-gui --> pd is already in the form of Pd messages, the next step is making pd --> pd-gui pd messages as well. I think the best path to do that would be to make a 'pd-gui' receive symbol that mirrors the 'pd' receive symbol. All messages sent to 'pd-gui' would be sent to the 'pd-gui' process. This could happen now as an external, then people could start writing GUI plugins using Pd messages as the communication. From that we can then figure out how the rest of the communication should look.
There has been some clean up along these lines of this in the pd-gui- rewrite branch. We have tried to structure the code so that its more modular and ready for a pd->pd-gui API, but it could definitely be improved a lot. For example, a handful of things that were a set of sys_vgui() calls have been replaced by a single sys_vgui() call which calls a Tcl proc. That Tcl proc then does the various steps.
.hc
#2 provide a mechanism so an "external" can hook into the gui-communication (replacing sys_vgui() and friends) this would allow to replace the current networked communication by e,g. a multithread-based one, which would make using shared memory and the like a lot simpler (with the malus of not being able to run pd-core and pd-gui on different machines any more (think peerdata))
gmsdf IOhannes -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iEYEARECAAYFAkuFkhAACgkQkX2Xpv6ydvSYQQCdHGWOWFM+tNb6YtkZ4gh10Owr teoAnAgFmC5sV+EOC9/JmJu+At6+MgZH =fAUS -----END PGP SIGNATURE-----
Pd-dev mailing list Pd-dev@iem.at http://lists.puredata.info/listinfo/pd-dev
----------------------------------------------------------------------------
The arc of history bends towards justice. - Dr. Martin Luther King, Jr.
Hi Paul,
On Tue, Feb 23, 2010 at 02:43:59PM -0500, Paul Kohlhoff wrote:
It would be very helpful to us if anyone could offer any suggestions, criticism, or comments on this project. Does anyone know of any similar projects? What could be some possible issues/consequences?
What we are doing at RjDj is running Pd with "-nogui" in a subprocess of a Python program, which is the GUI (wxWindows). If you interested in that, the library we are using to abstract out the control of Pd is here:
http://mccormick.cx/projects/PyPd/
Once the current work being done by Hans and friends on the modularisation of the GUI is complete, it should be possible to write custom tcl scripts or plugins to make the GUI behave a bit more as you need it to. If I was you I would wait for, or contribute to that work. I feel like re-writing the Pd UI from scratch in another language or toolkit is a huge undertaking and would become a bit of a maintenance headache. That is especially true as I have heard that some parts of Pd internals are actually hard coded to send TCL messages back to the GUI. I should look at the code to verify that, but I'm going to stick to my tradition on this list of empty promises[1] and vague, possibly incorrect claims[2]. ;)
Best,
Chris.
[1] http://lists.puredata.info/pipermail/pd-list/2002-07/007233.html [2] http://lists.puredata.info/pipermail/pd-list/2009-05/070416.html
------------------- http://mccormick.cx