How can I receive a named signal from a Pure Data patch using libpd?

500 Views Asked by At

I'm using libpd to embed the Pure Data engine in my project, and I am trying to receive signal messages from the patch.

If I place a non-signal message (i.e.) control in the patch:

|
|
|
[s toCPP]

I have no trouble receiving the message. However, if I try to do the same message with a ~, signifying a signal message, my handlers never receive it, an example patch is as follows:

[osc~ 440]
|
|
|
[s~ toCPP]

This patch never receives any "toCPP" messages, regardless of whether I use polling or callbacks. Here is my [stripped down] example code:

#include <PdBase.hpp>
#include <iostream>

using namespace pd;
class PdRec : public pd::PdReceiver
{
    public:
    void receiveFloat(const std::string & dest, float num)
    {
        std::cout << "received float: " << dest << ": " << num << std::endl;
    }
    void receiveSymbol(const std::string & dest, const std::string & symbol)
    {
         std::cout << "Received symbol: " << dest << ": " << symbol << std::endl;
    }
    void receiveMessage(const std::string & dest, const std::string & msg, const pd::List& list)
    {
         std::cout << "Received message: " << dest << ": " << msg << std::endl;
    }
    void receiveList(const std::string & dest, const pd::List & list)
    {
         std::cout << "Received list: " << dest << std::endl;
    }
}

int main(int argc, char** argv)
{
    float inbuf[64], outbuf[64];
    pd::PdBase pdEngine;
    if(!pdEngine.init(1, 1, 44100))
    {
         std::cout << "Failed to initialize pd!" << std::endl;
         exit(1);
    }
    std::cout << "Init success!" << std::endl;
    pd::Patch patch = pdEngine.openPatch("a440test.pd", "./");
    std::cout << patch << std::endl;

    PdRec rec;
    pdEngine.subscribe("toCPP");
    pdEngine.setReceiver(&rec);

    pdEngine.computeAudio(true);

    for(int i = 0; i < 30 * 44100 / 64; i++)
    {
          pdEngine.processFloat(1, inbuf, outbuf);
    }

    return 0;
}

One would expect this code to receive a float (or list of floats) from the patch every tick cycle for the symbol toCPP, however, this is not the case. This test code will receive the [s toCPP] version of a message, but not the [s~ toCPP]. As an aside, I can however, receive the output from [osc~ 440] if I connect it to a [dac~] object and read in the data through outbuf, but this is not optimal for my uses and I'd like to avoid it (the main reason being I may need to output upwards of 8 or more sets of acoustic data, and it gets somewhat unwieldy in the patch to create and use a dac~ object with that many channels).

My questions are thus:

Is it possible to receive signal-based messages from a Pd patch using libpd?

How does one receive a signal-based message from a Pd patch using libpd on the C++ side?

1

There are 1 best solutions below

0
On BEST ANSWER

the only way to communicate signals between the host and libpd is by using [adc~] and [dac~].

however, you need not create a [dac~] with an "unwieldy" number of inlet~s.

instead use [dac~ 27] to output a signal on the 27th channel.

btw, there are no "signal-based messages"; a message is an asynchronous event, whereas a signal is a a synchronous data stream.