Hi Bela Community !

It it possible to use C++ and SuperCollider together in any way ?

I would like to read values from an MPR121-cap touch sensor using I2C and use the values in SuperCollider...

What would be the best approach ?

-- by the way - Bela is great !!

Best,
Hjalte

Hi,
I answered a somehow similar question here.
Long story short: I think you should write your SC Ugen for this. I have no idea how to do it - I never did it - but it must not be that hard. This is the most powerful and flexible way of handling those data from within SC. Alternatively, you could read the sensors in a stand-alone program and send the data to SuperCollider over OSC or virmidi (see here). This is probably easier to do but less flexible and slower.

Either way, you would probably use the I2C_MPR121... files from the example and only have to write a wrapper for those.

Thank you for the reply 🙂

Seems that writing a SuperCollider UGEN is the way to go...

Can somebody who knows about this point me to a good starting point ? Maybe the source code of a SuperCollider UGEN for Bela - with comments ?
the more documentation the better !

Best,
Hjalte

    The interfaces of @nescivi 's Bela classes are here and the implementation should be here. Not sure how you compile the latter outside of SC, I hope that there is a way to do so!

    Looking at the implementation of the BelaUGens is the way to go.
    The Bela context is made available with this line:
    BelaContext *context = world->mBelaContext;
    Otherwise it follows the usual UGen writing guidelines. You will need to compile it against the Bela-enabled SuperCollider source code/headers, as this one contains the extensions made for Bela, making the Bela-context available to the plugin interface.

    For this one you may not even need the BelaContext*, or any of the Bela API, for what is worth: if you can stick the sensor reading in a pthread and use a queue to bring them in, then it is standard Linux programming. This would be beneficial to SuperCollider users on other platforms as well, so I'd encourage you to do that!

    9 days later

    I'm currently working on a SuperCollider plugin to get data from an IMU sensor, which brings in the sensor data from a pthread. First I tried to use std::thread but for some reason it didn't play well with Bela. The code for the plugin is over here. It's a bit messy but might be useful. I've used the code in UIUGens.cpp in the main SuperCollider repo as a starting point.

    That is great, thanks for sharing.
    What issues did you have with std::thread?

    If I remember correctly, I got a "Bus Error" when starting the thread, which after a bit of googling seemed to be a Xenomai issue, though I don't know what caused it. I'm quite new to C++, threads and everything, so I just decided to try with a pthread instead, which worked from the start.

    One thing I haven't quite grasped yet is how to deal with memory sharing between threads. I tried to follow the UIUGens.cpp model, but it seems it could be possible to read from a variable at the same time as the other thread is writing to it, which apparently is a bad thing. Is this an issue when using AuxiliaryTasks as well?

    I have no idea about the bus error.

    For simple memory sharing, if you are using 32-bit variables then it should be safe to read / write from them from the separate threads if the program is structured the appropriate way (i.e: either only one thread writes to it and the other one reads it, OR one thread sets a flag, the other one reads it and resets it and you don't care if the number of times the flag is reset is smaller than the number of time the flag is set).
    You can do most stuff this way, otherwise you can use some lock-free queues for more compicated stuff (I used the simple one that comes with libpd, but also something from std:: should work just fine on Bela unless it uses locks/mutexes).

    3 years later

    Hey HjalteBestedMoeller ~~~ you might also want to take a look at the UGens I recently wrote to support Trill sensors. I'm not using the I2C library directly, but you can take a look into the Trill library to see how the I2C library is used within there.

    I'm still not sure myself what the most effective way of dealing with I2C (and for that matter, UART serial) is on the Bela with SuperCollider. Building custom UGens per device seems like a good option.

    Another idea I've been toying with is to write a template for a C++ standalone utility that runs alongside SuperCollider and pipes data in via OSC. Doing it this way I imagine would avoid most of the fuss of starting and stopping auxiliary tasks from the audio thread, and make porting over I2C device libraries (from the Arduino world, for example) done more easily.