- Edited
Nice one, it probably works just fine, the issue is that time()
will call into the Linux kernel and as it is called from within the audio thread it breaks the real-time guarantees of Bela, hence the "mode switch" warning.
You have several options:
- start up a thread and call
time()
in there, have the audio thread print the result that was obtained from the other thread. If you don't want the other thread to be polling all the time, you'll need to trigger atime()
call in the other thread when you receive a bang, then set a pd timer (I believe that's what it's called?) a few ms later that reads the up-to-date result of time when it's ready and sends it out of the output. This is the most generally-applicable version, which will also improve real-time friendliness of your external when running outside Bela. It may get complicated because on a multi-core processor you'll need some way of guaranteeing memory coherence so that the audio thread never sees a corrupted version of the time and has a way of knowing for sure whether it's been updated. - instead of calling
time()
, call__wrap_time()
. This is a function provided by Xenomai's libcobalt that is safe to call from the audio thread. Before you call it you may have to declare it (depending on your compiler's options):
I don't think you have to change your linker flags. You should be able to build it like this and at runtime it will be resolved because libcobalt is already loaded by the Bela binary.extern time_t __wrap_time(time_t *tloc);
- leave the external exactly as it is. Bang it only once at the beginning of the script to get the time, ignore the mode switch message. Then use bangs to the
[timer]
object to measure elapsed time while the program is running. I appreciate this may have accuracy implications for long running patches (which you can obviate to by resetting the timer every so often) and if you need the year/month/day/hour/min/sec the previous option may be easier.