Serial communication
This example demonstrates how to receive and transmit serial data from Bela. When a 'k' or 's' are received on the specified serial port, a kick or snare sound, respectively, are generated.
Serial data is received in a lower-priority thread (an AuxiliaryTask). From there, relevant data is passed to the audio thread via a Pipe. The AuxiliaryTask is also writing to the serial port.
The sound generator is very simple and "retro". IT is using a decaying noise burst for the snare sound and a decaying sine sweep for the kick
#include <libraries/Pipe/Pipe.h>
#include <libraries/Serial/Serial.h>
#include <cmath>
unsigned int gSnareDuration;
int gSnareTime = 0;
unsigned int gKickDuration;
int gKickTime = 0;
float gKickPhase = 0;
void serialIo(void* arg) {
{
unsigned int maxLen = 128;
char serialBuffer[maxLen];
int ret = gSerial.
read(serialBuffer, maxLen, 100);
if (ret > 0) {
printf("Received: %.*s\n", ret, serialBuffer);
for(int n = 0; n < ret; ++n)
{
if('k' == serialBuffer[n])
{
gSerial.
write(
"kick!\n\r");
} else if('s' == serialBuffer[n])
{
gSerial.
write(
"snare!\n\r");
}
}
}
}
}
gSerial.
setup (
"/dev/ttyUSB0", 19200);
gPipe.
setup(
"serialpipe", 1024);
return true;
}
char c;
{
if('s' == c)
gSnareTime = gSnareDuration;
if('k' == c)
gKickTime = gKickDuration;
}
{
float snareOut = 0;
float kickOut = 0;
if(gSnareTime)
{
float noise = 2.f * (rand() / (float)RAND_MAX) - 1.f;
float env = gSnareTime / (float)gSnareDuration;
snareOut = 0.4f * noise * env;
--gSnareTime;
}
if(gKickTime)
{
float frequency =
map(gKickTime, gKickDuration, 0, 150, 20);
float env = gKickTime / (float)gKickDuration;
if(gKickPhase > M_PI)
gKickPhase -= 2.f * (float)M_PI;
kickOut = env * sinf(gKickPhase);
--gKickTime;
}
float out = snareOut + kickOut;
{
}
}
}