Hello everybody,
could anyone please suggest me how to send analog inputs through osc ?
Are there a code example or some informations about ?
Thanks a lot in advance and best regards.
Cristiano
Hello everybody,
could anyone please suggest me how to send analog inputs through osc ?
Are there a code example or some informations about ?
Thanks a lot in advance and best regards.
Cristiano
you can use something like this:
#include <Bela.h>
#include <libraries/OscSender/OscSender.h>
#include <libraries/Biquad/Biquad.h>
#include <vector>
std::vector<float> gFilteredAnalogIns;
std::vector<Biquad> filters;
OscSender oscSender;
int remotePort = 7563;
const char* remoteIp = "192.168.7.1";
const float kSendPeriod = 0.05; // 50 ms
void sendThread(void*)
{
while(!Bela_stopRequested())
{
for(int c = 0; c < int(gFilteredAnalogIns.size()); ++c)
{
// access the filtered values from the global variable and send them
oscSender.newMessage("/analog-in").add(c).add(gFilteredAnalogIns[c]).send();
}
usleep(kSendPeriod * 1000000);
}
}
bool setup(BelaContext *context, void *userData)
{
gFilteredAnalogIns.resize(context->analogInChannels);
// The analog inputs are sent over OSC every kSendPeriod seconds.
// This amounts to a downsampling of the input signals and so
// we filter them with a lowpass filter before downsampling
// in order to reduce noise and aliasing
float cutoff = 0.7f * 1.f / kSendPeriod;
BiquadCoeff::Settings settings = {
.fs = context->analogSampleRate,
.type = BiquadCoeff::lowpass,
.cutoff = cutoff,
.q = 0.707,
.peakGainDb = 0,
};
filters.resize(gFilteredAnalogIns.size(), settings);
oscSender.setup(remotePort, remoteIp);
Bela_runAuxiliaryTask(sendThread);
return true;
}
void render(BelaContext *context, void *userData)
{
for(unsigned int n = 0; n < context->analogFrames; ++n)
{
for(unsigned int c = 0; c < context->analogInChannels; ++c)
// filter the input signals here and store them in the
// global variable
gFilteredAnalogIns[c] = filters[c].process(analogRead(context, n, c));
}
}
void cleanup(BelaContext *context, void *userData)
{
}
on the host, open UDP port 7563 and listen for incoming messages. E.g.:
Good evening and many many thanks for your fast answer.
Unfortunately it does not work.
May be i' m doing something wrong.
Anyway i don' t want to use it with pure data but inside a software i'm writing which use Osc implementation via Liblo library.
Any check or suggestion ?
Cristiano May be i' m doing something wrong.
if you are on Windows you may need to change the remoteIp
on the board to 192.168.6.1
.
Cristiano Anyway i don' t want to use it with pure data but inside a software i'm writing which use Osc implementation via Liblo library.
Once you have that working, you should be able to receive it from your custom program. This code sends OSC via UDP. Non-trivial changes will be needed to send via TCP.
I have changed the remote ip but it does not work.
I have tried to receive in pure data through the "print OSC-packet" object and it prints out but
caotically:
OSC-packet: 47 97 110 97 108 111 103 45 105 110 0 0 44 105 102 0 0 0 0 0 57 138 28 254
OSC-packet: 47 97 110 97 108 111 103 45 105 110 0 0 44 105 102 0 0 0 0 1 60 216 0 33
OSC-packet: 47 97 110 97 108 111 103 45 105 110 0 0 44 105 102 0 0 0 0 2 62 131 26 99
OSC-packet: 47 97 110 97 108 111 103 45 105 110 0 0 44 105 102 0 0 0 0 3 62 185 203 151
OSC-packet: 47 97 110 97 108 111 103 45 105 110 0 0 44 105 102 0 0 0 0 0 57 134 29 175
OSC-packet: 47 97 110 97 108 111 103 45 105 110 0 0 44 105 102 0 0 0 0 1 60 219 220 126
OSC-packet: 47 97 110 97 108 111 103 45 105 110 0 0 44 105 102 0 0 0 0 2 62 131 106 190
OSC-packet: 47 97 110 97 108 111 103 45 105 110 0 0 44 105 102 0 0 0 0 3 62 186 25 66
OSC-packet: 47 97 110 97 108 111 103 45 105 110 0 0 44 105 102 0 0 0 0 0 57 140 26 31
OSC-packet: 47 97 110 97 108 111 103 45 105 110 0 0 44 105 102 0 0 0 0 1 60 222 248 204
OSC-packet: 47 97 110 97 108 111 103 45 105 110 0 0 44 105 102 0 0 0 0 2 62 131 171 131
OSC-packet: 47 97 110 97 108 111 103 45 105 110 0 0 44 105 102 0 0 0 0 3 62 186 98 65
and when i press the sensor connected to the channel:
OSC-packet: 47 97 110 97 108 111 103 45 105 110 0 0 44 105 102 0 0 0 0 0 63 127 255 0
On my software i can received from channel 0 but it seems to send only the succession of the numbers of the channels.
Cristiano I have tried to receive in pure data through the "print OSC-packet" object and it prints out but
caotically:
what's your patch like (hint: post it, next time)?
[netreceive -b -u 7563]
|
[print OSC-packet]
? That is not using any OSC-packet object, but rather it's printing the output of [netreceive]
prepending it with the string OSC-packet
. Data is received by [netereceive]
as "binary" so it outputs numbers between 0 and 255, each representing one byte that was received. If you simply print the output of [netreceive]
, it will print the decimal representation of each byte that was received. You should use something like [oscparse]
as above. The output would be like this:
So that shows that each message looks like this:
/analog-in CHANNEL VALUE
, where CHANNEL is an int
and VALUE is a float
. Hopefully these details are enough for you to properly parse the messages in your program.
Thank you very much, infact It does properly work.
One more question about the filtering, isn't it enough to output the acquired analog signal directly?
Cristiano ne more question about the filtering, isn't it enough to output the acquired analog signal directly?
Kindof. It does work but you are downsampling something from 22050Hz to about 200Hz (sending every 50ms), so any noise and high-frequency changes would be aliased. We therefore filter it before downsampling in order to reduce the noise and aliasing of your data.
Downsampling ? Why?
because you are sending the data over OSC about every 50ms, which means downsampling to about 200Hz.
I understand. Is 44100 Hz trasmission rate only possible internally or is there anorher way ?
It's supported only internally. That is a lot of data to send over network. It can be achieved, but then the overheads of OSC are too big to send individual messages like this. You'd have to look at using OSC blobs or just plain raw samples as I do here.
but why do you want to send full-rate signals to the host?
I need to have the same rate between sensor data and audio samples for perfect matching...
Then your best bet is to do it on Bela. Trying to send a lot of data over network is doable, as I mentioned, and probably you can send 8 to 10 channels, but you'll need large buffers on each side, which means latency will be pretty high (e.g.: 1 second).