• sdaau_ml

    Meh, I should have thought of this earlier - the fix is just to use [set $1(, to update the value but not trigger a bang/message on the output:

    pd-sync-ok.png

    posted in technical issues read more
  • sdaau_ml

    Hi all,

    For a while I've wanted to have "synchronized" toggles, so that say I could have two of them, maybe one in top left of the patch window - and the other in the bottom right of the patch window, where I might be doing some work; and in case the window is large, then from the position of bottom right it would be a bit tedious and scroll to top left each time I wanted to click the button. In this kind of situation, I'd expect only one (say, the top left) to have its outlet connected to an actual object - the other would be there just to ease the working process.

    So basically, it would be "either/or" pair - if I toggle one button on, the other turns on too; if I then toggle the other off, the first one turns of too.

    Of course, if you just try to do the most trivial implementation of this:

    pd-recursegui.png

    ... that is, outlet of one into inlet of other, and vice versa - and then you click either one, - PD will either crash/segfault, or you'll get a "stack overflow" message; since in this case, a recursive update loop happens.

    So is there another method to allow for such "synchronized" buttons, without ending up in a recursive loop, and potentially crashing PD? Also, I could image synchronized number boxes to be useful, too...

    posted in technical issues read more
  • sdaau_ml

    Hi all,

    Let's assume you have an external, with this kind of code in it:

    ...
    typedef struct _MyExternal {
      ...
      int        var_a;
      int        var_b;
      int        var_c;
      int        var_d;
      ...
      t_symbol* obj_name;
     ...
    } t_MyExternal;
    ...
    
    void MyExternal_calcandprint(t_MyExternal *x) {
      x->var_d = x->var_a + x->var_b + x->var_c;
      post("The external has obj_name %s with values %d (%d+%d+%d)", x->obj_name->s_name, x->var_d, x->var_a, x->var_b, x->var_c );
    }
    
    void MyExternal_seta(t_MyExternal *x, t_float f) {
      x->var_a = f;
      MyExternal_calcandprint(x);
    }
    
    void MyExternal_setb(t_MyExternal *x, t_float f) {
      x->var_b = f;
      MyExternal_calcandprint(x);
    }
    
    void MyExternal_setc(t_MyExternal *x, t_float f) {
      x->var_c = f;
      MyExternal_calcandprint(x);
    }
    ...
      class_addmethod(MyExternal_class, (t_method)MyExternal_seta, gensym("seta"), A_FLOAT, 0);
      class_addmethod(MyExternal_class, (t_method)MyExternal_setb, gensym("setb"), A_FLOAT, 0);
      class_addmethod(MyExternal_class, (t_method)MyExternal_seta, gensym("setc"), A_FLOAT, 0);
    ...
    

    So, let's say I want to set these variables from PD, in a message like this:

    [ ;               <
    [ recvobj seta 3; |
    [ recvobj setb 4; |
    [ recvobj setc 5; <
    

    So, even if this content is in one message box, all of these message will be received individually, and so

    • first MyExternal_seta will run, calling MyExternal_calcandprint
    • then MyExternal_setb will run, calling MyExternal_calcandprint again
    • then MyExternal_setc will run, calling MyExternal_calcandprint yet again

    The thing is, these messages could come from different message boxes, but all sort of close in time, and this is the case I want to handle - I want each set* function to run individually as they do - but I'd want MyExternal_calcandprint to run only once, once all the variables have been set.

    However it is kind of impossible to predetermine whether only a, or also b and c will be changed in a call. So I imagine, if there existed a function, say, pd_defer_ctrl which I could use like:

    void MyExternal_setc(t_MyExternal *x, t_float f) {
      x->var_c = f;
      pd_defer_ctrl( 5, x->MyExternal_calcandprint );
    }
    

    it would help me with my problem, if it worked like this - if PD is not in "defer mode", then it enters it, and sets a threshold of 5 ms from now; then it adds MyExternal_calcandprint to a queue. Then when next set* message comes in, PD sees its already in "defer mode", sees it arrived before the threshold of 5 ms has expired - and so it first checks if MyExternal_calcandprint is already in the queue, and if it is, it does not add it again. Finally, once the threshold of 5 ms has expired, PD then runs all the functions in the defer queue.

    Is there something like that I could use in a PD external?


    EDIT: Turns out Max/MSP probably already has such an API function, because I can see in bonk~.c source:

    ...
    #ifdef MSP
    static void bonk_write(t_bonk *x, t_symbol *s)
    {
        defer(x, (method)bonk_dowrite, s, 0, NULL);
    }
    ...
    

    .... but I guess there is nothing like that for Pure Data...

    posted in extra~ read more
  • sdaau_ml

    Every once in a while, I come to having to program an external which ends up having some specific variables, which I'd prefer being set "internally" instead of exposing them through outlets, mostly to reduce clutter. And unfortunately, that is usually not easily visible in https://github.com/pure-data/externals-howto ...

    So, I'm not really sure if the below is the "correct" thing - I just managed to patch it together by reading from the PD source.

    You can find the code in:

    The help patch looks like this:

    sendtest-help.png

    Basically, this is a copy of [send], which when banged, triggers r AHA and r EHE - even if there aren't corresponding send objects. It turns out, there must be a pd_bind in order for this to work, and for a long time I thought the object argument there is the sender object - but actually it seems to be the receiving object reference. So this objects includes an additional "dummy" receiver class, a copy of [receive], which is there simply to initialize this binding, once this is done, other normal [receive] objects begin reacting on messages too.

    Now I noticed I don't actually have the code for setting [value] variables there, but it is easier - you simply declare a symbol, and then you call PD functions on it:

      t_symbol* s_mysimbol;
      ...
      x->s_mysimbol    = gensym("myvar");
      ...
      // initialize/instantiate the [value] variables (reading is with value_getfloat)
      // note - via value_get, these will also gain non-null ->s_thing property
      value_get(x->s_mysimbol);
      ...
      value_setfloat(x->s_mysimbol, 42);
      ...
      value_release(x->s_mysimbol);
    

    posted in extra~ read more
  • sdaau_ml

    Hi all,

    Is it possible for a PD external to detect its environment? By this I mean, distinguishing whether it runs on PD standalone on desktop, vs running in say libpd in an embedded environment?

    Thanks!

    posted in extra~ read more
  • sdaau_ml

    OK, I got the counting part solved - test.pd :

    pd-test2.png

    Simply another counter has to be added, it will count incoming messages on the cold inlet, and receive a slow "bang" on the hot one - and at the same time, this "bang" can reset this another counter...

    However, it will still be nice to know if there is a way to collect (and output) actual messages..

    posted in technical issues read more
  • sdaau_ml

    HI all,

    Consider the following patch, test.pd :

    pd-test.png

    Basically, when the [metro] is started, I'm having a message printed every 100 ms - this is as expected.

    However, this is what I'd like to do: put some sort of a "bucket" object at the output of the [hello $1 world $1( message box, and then have that "bucket" output connected to [print]. So, the incoming messages at 100 ms would be "collected"/"collated" by the "bucket" object, and nothing would be printed by [print] - and then when I "bang" the "bucket" object, either:

    • All messages received so fat would be output on the "bucket" object outlet, causing them to be printed
    • I would get a message such as "10 messages received" or similar, depending on how many messages arrived in the previous period

    As soon as the "bucket" object is "bang"ed in this way, it is "emptied", and a new period of collection can start again.

    Is there an object that does this in PD vanilla - or is there a combo of vanilla objects I could use to achieve this?

    posted in technical issues read more
  • sdaau_ml

    Awesome - many thanks for the help, @whale-av - I like both approaches, but I think I'd prefer the canvas properties.

    EDIT: if going through canvas properties, you must have "Graph on Parent" enabled, otherwise the size is not settable (and is ignored); but that is not really a problem, the default rendering is the same; also the default height for object boxes seems to be 18 pixels in PD vanilla...

    Btw, the limit that you noticed - I'm pretty sure there is a similar kind of limit of text character width in a comment box, so I guess it makes sense it is also applied to object boxes (at least 'pd' subpatch ones).

    Many thanks again!

    posted in technical issues read more
  • sdaau_ml

    Hi all, am on Ubuntu 18.04, using the PD vanilla that comes with it (puredata:all/bionic 0.48.1-3).

    This is the test I tried doing: I make a new patch (test.pd), inside I make a subpatch [pd blah], and inside blah, I put several [outlet]s:

    out1.png

    Clearly, the outlets on the subpatch are so tight close to each other, that it makes sense that I would "stretch" the width of the [pd blah] object:

    out2.png

    Great, it stretches, the outlets are now individually visible... So I save the test.pd, close it, reopen it again... and [pd blah] is again just as tight as on the first image?!

    Does anyone know, if there is some sort of a trick, so I can save the "widened" [pd blah] object in my test.pd patch?!

    posted in technical issues read more
  • sdaau_ml

    Thanks again for the discussion, all:

    Hi @sdaau_ml I was intrigued by how this might be done in Windows (you didn't say which OS).

    I'm on Ubuntu 18 / Linux, so [shell] would have been great, but not for patches that would run in vanilla...

    Thanks again!

    posted in technical issues read more
  • sdaau_ml

    Many thanks @60htz and @whale-av - for letting me know exactly what I needed to know :)

    posted in technical issues read more
  • sdaau_ml

    Hi all,

    I would want the following: Whenever I press Ctrl-S to save a patch in Puredata, I'd want the timestamp of that action to be written in a message box; then, I could do a:

    [loadbang]
    |
    [Fri Nov  9 11:39:07 CET 2018(
    |
    [print]
    

    ... and have the timestamp of the last save, be output whenever I start a patch.

    So, is there a way to detect a save within Puredata?

    posted in technical issues read more
  • sdaau_ml

    I would like to enter something like the following pseudocode in PD:

    if ($f1<$f3) {
      output (0);
    } else {
      if($f1-$f3<=$f2) {
        output (($f1-$f3)/$f2);
      } else {
        output(1.0);
      }
    }
    

    So, I've tried to enter this expr if construction:

    [ expr if ($f1<$f3, 0, if( ($f1-$f3<=$f2, ($f1-$f3)/$f2, 1.0) )) ]
    

    However, PD will not accept this, and it returns:

    expr: syntax error: illegal comma
    
    ,
    (
    $f1 
    -
    $f3 
    ) 
    /
    $f2 
    ,
    1.000000 
    
    
    expr: syntax error
     expr if ($f1<$f3 , 0 , if( ($f1-$f3<=$f2 , ($f1-$f3)/$f2 , 1.0) ))
    ... couldn't create
    

    Is there a syntax where I can use nested "if"s in an [expr] object?

    posted in technical issues read more
  • sdaau_ml

    Hi @whale-av ,

    Many thanks for the feedback!

    First, a note - I also checked [Scope~] found in pd-extended (pd-l2ork, Purr-data) - and it has also its troubles:

    • It only reacts on zero-crossings - so it basically shows phasor~ as a straight line, unless it is brought down [-~ 0.5] a bit;
    • If using bufsize 1000, it basically updates more than each second - so buffer size seems not to be expressed in samples ?!

    Maybe it's possible to control this somehow, since if I open a patch with [Scope~] in PD vanilla, I do get some numbers:

    Scope~.png

    ... but I cannot find documentation on this anywhere, and don't really have the time to reverse engineer it...

    @whale-av said:

    @sdaau_ml Reliable will be to put the data and then bang once only for the new data.
    scop.pd

    Well, I don't think this will help me much:

    scop-pd.png

    First, the timing of slider bangs is inconsistent, at least on Linux/Gnome (and possibly macOS) - sometimes it will hit at 30-40 ms apart, sometimes in much less than a millisecond ( see https://forum.pdpatchrepo.info/topic/8961/repost-measuring-the-elapsed-time-for-gui-hsl-slider-object-events-in-puredata ); and that means sometimes I'll get more data shown in the array98 graphs, and sometimes less (which is not how an oscilloscope display works)... Also, it will not be continually updated, as you noted:

    @whale-av said:

    Unless you want continuous update in which case you need [snapshot~] and a counter..... sort of like this....... phase meter.zip

    Ok, this is pretty cool, thanks for that:

    phase_meter.png

    ... but this gives me Lissajous curves, not time-domain waveform which I need. Although, I guess [snapshot~] will "lose" some data (due to artifacts of a sampling process), whereas I'd prefer to throw data directly in the array...

    @whale-av said:

    This might help......... scop2.zip
    You will need to play around with the metro timing and the length of the array (and therefore the count object....... send the length of the array to it's right inlet so that it counts through the whole index), doing some range sensing (trigger) math just like a real scope if you want to auto stabilise the waveform.
    {{note.... this is using [tabwrite]...... not [tabwrite~].......}}

    Ah, this is pretty cool - and actually seems to work close to what I want:

    scop2.png

    So, I guess [tabwrite ___ $1 $2] means write value $1 at index $2 (couldn't find anything explicit about this syntax in the help file)? In any case, even if it eats quite a bit of CPU, it seems to do the trick for what I need (and thankfully, I don't really need trigger conditions right now)..

    Many thanks again for the help,
    Cheers!

    posted in technical issues read more
  • sdaau_ml

    Hi all,

    I needed to have some more long-running visualisation of waveforms in PD, so as there is no vanilla [scope~] object, I thought I'd use [tabwrite~] with [array], as commonly recommended - however, I have stumbled upon a somewhat strange behavior, which I'm not sure whether it's a bug. This is on Ubuntu 18.04, vanilla Puredata from Ubuntu repos (0.48.1-3)

    So, basically I made a patch, which is mostly reused help of [tabwrite~] :

    test-array-scopevis-metro.png

    The patch itself is here: test-array-scopevis-metro.pd

    So, basically, I want to view signals as if on a scope with timebase of 1 second. My PD/Media/Audio Settings tells me: Sample rate: 44100, Block size: 64, Delay (msec): 25

    So, all I have in addition to what was there in the [tabwrite~] help, is a few objects to set the array98 array size to 44100 when the patch is loaded - so there is enough memory to record 1 second of signal. And then I've added a metro, so it bangs the tabwrite~ each second (each 1000 msec) - the idea being that I bang the tabwrite~, it records 44100 samples in a second and shows them, then after that second I bang again, it records 44100 samples in a second and shows them anew and so on - pretty much like an oscilloscope at a timebase of 1 sec would do.

    However, the actual response is shown in this video:

    test-array-scopevis-metro.ogv

    That is, when I start the metro at 1000 msec, it keeps banging for at least 10 times, without the array ever refreshing the waveform display?! Then, when I stop the metro, the waveform is displayed ?! At that point, I draw whatever in the array graph so as to "reset" this display, change the metro to 1001 msec - and start the metro again. This time the display does update as expected - but only after an initial delay of some 2 seconds (or three bangs) - I would have otherwise expected a delay of 1 second (two bangs).

    Does anyone knows why this happens, and how to get a more reliable behavior for this kind of case? My guess is, for a [metro 1000], PD actually does not have enough time to fill the entire array with all 44100 samples, and thus it never updates the graph - apparently 1 millisecond extra is enough for PD to realize that the array has been filled, and so it updates the graph, but then why does it take 2 sec (at 3rd bang) to update, and not only 1 second (at 2nd bang)?

    posted in technical issues read more
  • sdaau_ml

    Sorry to necro this thread, but I finally found out how to run PureData under Pulseaudio (which otherwise results with "ALSA output error (snd_pcm_open): Device or resource busy").

    First of all, run:

    pd -alsa -listdev
    

    PD will start, and in the message window you'll see:

    audio input devices:
    1. HDA Intel PCH (hardware)
    2. HDA Intel PCH (plug-in)
    audio output devices:
    1. HDA Intel PCH (hardware)
    2. HDA Intel PCH (plug-in)
    API number 1
    
    no midi input devices found
    no midi output devices found
    
    

    ... or something similar.

    Now, let's add the pulse ALSA device, and run -listdev again:

    pd -alsa -alsaadd pulse -listdev
    

    The output is now:

    audio input devices:
    1. HDA Intel PCH (hardware)
    2. HDA Intel PCH (plug-in)
    3. pulse
    audio output devices:
    1. HDA Intel PCH (hardware)
    2. HDA Intel PCH (plug-in)
    3. pulse
    API number 1
    
    no midi input devices found
    no midi output devices found
    

    Notice, how from the original two ALSA devices, now we got three - where the third one is pulse!

    Now, the only thing we want to do, is that at startup (so, via the command line), we set pd to run in ALSA mode, we add the pulse ALSA device, and then we choose the third (3) device (which is to say, pulse) as the audio output device - and the command line argument for that in pd is -audiooutdev:

    pd -alsa -alsaadd pulse -audiooutdev 3 ~/Desktop/mypatch.pd
    

    Yup, now when you enable DSP, the patch mypatch.pd should play through Pulseaudio, which means it will play (and mix) with other applications that may be playing sound at the time! You can confirm that the correct output device has been selected from the command line, if you open Media/Audio Settings... once pd starts:

    Screenshot-Audio Settings.png

    As the screenshot shows, now "Output device 1" is set to "pulse", which is what we needed.

    Hope this helps someone!

    EDIT: I had also done changes to /etc/pulse/default.pa as per https://wiki.archlinux.org/index.php/PulseAudio#ALSA.2Fdmix_without_grabbing_hardware_device beforehand, not sure whether that makes a difference or not (in any case, trying to add dmix as a PD device and playing through it, doesn't work on my Ubuntu 14.04)

    posted in technical issues read more
  • sdaau_ml

    Many thanks for the prompt answer, @LiamG:

    @LiamG said:

    It seems to me that you are confusing the difference between a subpatch and an abstraction.

    Indeed I was - many thanks for the great explanation, it was exactly what I needed!

    An abstraction is a unique object that can take creation arguments. You have done the right thing by saving it as a pd file "mysubpatch.pd" in the same directory, but to initiate it you just need to create the object [mysubpatch]. If you create [pd mysubpatch.pd], as you have reported above, then you will get a subpatch, which is not the same thing.

    I cannot believe I had forgotten this, even if just last year I was doing patches with abstractions :) Great to have this as reference, for the next time it happens :)

    Anyways - indeed, it works great - once the (sub)patch is loaded as an abstraction proper, then the patch "sleeps" (as in, no reported warnings), even with DSP on and two abstractions (and even the window title bar tells you that the abstraction now sees argument (A)):

    pd-namearrayabs2.png

    Great to have this solved - thanks again, cheers!

    posted in technical issues read more
  • sdaau_ml

    Consider the following trivial patch (testing on Pd 0.45.4 on Ubuntu 14.04):

    pd-namearraysub.png

    In it, I have a [pd mysubpatch A]. As far as I remember, the A is now an argument of/to the subpatch, in particular it is the first argument - and references to $1 inside the subpatch should expand to A.

    So, I've decided to place an array inside the subpatch, and call it $1-array, similar to how in abstractions, arrays are/can be called $0-array - except there the $0 doesn't expand to any arguments, but instead expands to a random number (Dollar signs in objects and messages | PURE DATA forum~). My expectation is that the $1 in my case would expand to the first argument, A, and thus the array name at instantiation time of the object [pd mysubpatch A] would expand to A-array.

    The idea is thus to be able to put multiple subpatches in a patch, and control their internal arrays' names by supplying unique arguments. So, I try to copy/duplicate the [pd mysubpatch A] into a [pd mysubpatch B], expecting its array would ultimately be called B-array. So far so good, because I can do this without any problems.

    Now consider a slightly more complicated case where I also have a tabwrite~ in the subpatch:

    pd-namearraysub2.png

    Now that I have [tabwrite~ $1-array] referencing the $1-array in the subpatch, as soon as I turn on DSP/audio, I get a ton of warning: $1-array: multiply defined messages. As I don't get this message when I have only the $1-array in the subpatch, I'm assuming it is not the logic in naming the arrays $1-array via subpatch arguments that is the problem, but instead it is the reference in the [tabwrite~ $1-array] which is causing the warning message.

    Note that exactly the same happens, if I save the subpatch as an abstraction mysubpatch.pd, and use it as two objects [pd mysubpatch.pd A] and [pd mysubpatch.pd B]:

    pd-namearrayabs.png

    But then, in this case, how would I reference such a subpatch/abstraction array, named through an argument, from inside the subpatch/abstraction itself? Note that I need fixed, explicit, known names of arrays, so a workaround like $0-$1-array wouldn't work for me, since the $0 would expand to a random number, which I in principle do not know from the outside (and I'm not sure $0 even applies to subpatches).

    posted in technical issues read more
  • sdaau_ml

    @gsagostinho Thanks for the report, - btw my video is taken on Ubuntu Linux 11.04, not Windows :) So this is definitely something to do with Linux - my guess is, I think in most Linuces, it is X Windows which is the main arbiter of GUI events to user-space programs, so this probably has to do with the interaction of X Windows and Pure Data. (I seem to recall that X Windows, if it cannot deliver a GUI event in time, it queues it for later; and thus at a certain point, I have two events - the current one; and the previous one that was late, so requeued for the current time - reporting in a quick succession - but I am not 100% sure about this). In any case, if this is the root cause of the issue, I guess there is not much Pure Data can do about it... (apart from tricks like thresholding). But hopefully someone will come up with a more accurate understanding of the problem - and even a possible solution :) Cheers!

    posted in technical issues read more
  • sdaau_ml

    @LandonPD Many thanks for reporting - it seems now confirmed that this behavior does not occur under Windows. Would be nice to hear a report from a Linux user, or a Mac user as well (although I suspect Mac should work fine too).

    (Actually, a possible workaround for this in PD would be simply to set a threshold, something like 0.5 ms (= 500 μs); if [timer]/[realtime] measures delta t any less than this, we simply refuse to bang the expr for velocity calculation; the timer keeps on measuring, and next time a slider event is received, we should have the most current value at the time, and definitely a delta t > 0 - which should provide a more accurate velocity measure, than if the short measurements are included. But I do not have the time ATM to develop a test for this; I hope to get back to this once I do).

    Cheers!

    posted in technical issues read more
Internal error.

Oops! Looks like something went wrong!