Mercurial > hg > beaglert
changeset 474:efc9a9f8e63d prerelease
Libpd added scope support and example
author | Giulio Moro <giuliomoro@yahoo.it> |
---|---|
date | Mon, 20 Jun 2016 20:38:46 +0100 |
parents | 2a0b468ce1dd |
children | faa5f58c71af |
files | core/OSCServer.cpp core/Scope.cpp core/default_libpd_render.cpp examples/08-PureData/scope/_main.pd |
diffstat | 4 files changed, 64 insertions(+), 36 deletions(-) [+] |
line wrap: on
line diff
--- a/core/OSCServer.cpp Mon Jun 20 18:35:47 2016 +0100 +++ b/core/OSCServer.cpp Mon Jun 20 20:38:46 2016 +0100 @@ -20,13 +20,13 @@ void OSCServer::createAuxTasks(){ char name [30]; - sprintf (name, "OSCRecieveTask %i", port); - OSCRecieveTask = Bela_createAuxiliaryTask(OSCServer::checkMessages, BELA_AUDIO_PRIORITY-5, name, this, true); + sprintf (name, "OSCReceiveTask %i", port); + OSCReceiveTask = Bela_createAuxiliaryTask(OSCServer::checkMessages, BELA_AUDIO_PRIORITY-5, name, this, true); } void OSCServer::messageCheck(){ - if (socket.waitUntilReady(true, UDP_RECIEVE_TIMEOUT_MS)){ - int msgLength = socket.read(&inBuffer, UDP_RECIEVE_MAX_LENGTH, false); + if (socket.waitUntilReady(true, UDP_RECEIVE_TIMEOUT_MS)){ + int msgLength = socket.read(&inBuffer, UDP_RECEIVE_MAX_LENGTH, false); pr.init(inBuffer, msgLength); oscpkt::Message *inmsg; while (pr.isOk() && (inmsg = pr.popMessage()) != 0) { @@ -49,9 +49,9 @@ return poppedMessage; } -void OSCServer::recieveMessageNow(int timeout){ +void OSCServer::receiveMessageNow(int timeout){ if (socket.waitUntilReady(true, timeout)){ - int msgLength = socket.read(&inBuffer, UDP_RECIEVE_MAX_LENGTH, false); + int msgLength = socket.read(&inBuffer, UDP_RECEIVE_MAX_LENGTH, false); pr.init(inBuffer, msgLength); oscpkt::Message *inmsg; while (pr.isOk() && (inmsg = pr.popMessage()) != 0) {
--- a/core/Scope.cpp Mon Jun 20 18:35:47 2016 +0100 +++ b/core/Scope.cpp Mon Jun 20 20:38:46 2016 +0100 @@ -20,9 +20,9 @@ sampleRate = _sampleRate; // setup the OSC server && client - // used for sending / recieving settings + // used for sending / receiving settings // oscClient has it's send task turned off, as we only need to send one handshake message - oscServer.setup(OSC_RECIEVE_PORT); + oscServer.setup(OSC_RECEIVE_PORT); oscClient.setup(OSC_SEND_PORT, "127.0.0.1", false); // setup the udp socket @@ -36,18 +36,18 @@ // send an OSC message to address /scope-setup // then wait 1 second for a reply on /scope-setup-reply - bool handshakeRecieved = false; + bool handshakeReceived = false; oscClient.sendMessageNow(oscClient.newMessage.to("/scope-setup").add((int)numChannels).add(sampleRate).end()); - oscServer.recieveMessageNow(1000); + oscServer.receiveMessageNow(1000); while (oscServer.messageWaiting()){ - if (handshakeRecieved){ + if (handshakeReceived){ parseMessage(oscServer.popMessage()); } else if (oscServer.popMessage().match("/scope-setup-reply")){ - handshakeRecieved = true; + handshakeReceived = true; } } - if (handshakeRecieved && connected) + if (handshakeReceived && connected) start(); } @@ -82,7 +82,7 @@ void Scope::log(float chn1, ...){ - // check for any recieved OSC messages + // check for any received OSC messages while (oscServer.messageWaiting()){ parseMessage(oscServer.popMessage()); }
--- a/core/default_libpd_render.cpp Mon Jun 20 18:35:47 2016 +0100 +++ b/core/default_libpd_render.cpp Mon Jun 20 20:38:46 2016 +0100 @@ -15,10 +15,10 @@ #include <libpd/s_stuff.h> #include <UdpServer.h> #include <Midi.h> -//extern t_sample* sys_soundin; -//extern t_sample* sys_soundout; +#include <Scope.h> + // if you are 100% sure of what value was used to compile libpd/puredata, then -// you could #define this instead of getting it at runtime. It has proved to give some 0.3% +// you could #define gBufLength instead of getting it at runtime. It has proved to give some 0.3% // performance boost when it is 8 (thanks to vectorize optimizations I guess). int gBufLength; @@ -33,6 +33,7 @@ rt_printf("%s", recv); } +//TODO: remove this function void libpdReadFilesLoop(){ while(!gShouldStop){ // check for modified sockets/file descriptors @@ -106,7 +107,7 @@ int receiver = ((source[prefixLength] - 48) * 10); receiver += (source[prefixLength+1] - 48); unsigned int channel = receiver - 11; // go back to the actual Bela digital channel number - if(channel >= 0 && channel < 16){ //16 is the hardcoded value for the number of digital channels + if(channel < 16){ //16 is the hardcoded value for the number of digital channels dcm.setValue(channel, value); } } @@ -121,12 +122,21 @@ {"bela_digitalIn26"} }; -static unsigned int analogChannelsInUse; +static unsigned int gAnalogChannelsInUse; static unsigned int gLibpdBlockSize; -static unsigned int gChannelsInUse = 26; +// 2 audio + (up to)8 analog + (up to) 16 digital + 4 scope outputs +static const unsigned int gChannelsInUse = 30; +static const unsigned int gFirstAudioChannel = 0; +static const unsigned int gFirstAnalogChannel = 2; +static const unsigned int gFirstDigitalChannel = 10; +static const unsigned int gFirstScopeChannel = 26; +Scope scope; +unsigned int gScopeChannels = 4; bool setup(BelaContext *context, void *userData) { + scope.setup(gScopeChannels, context->audioSampleRate); + // Check first of all if file exists. Will actually open it later. char file[] = "_main.pd"; char folder[] = "./"; @@ -138,7 +148,7 @@ return false; } dcm.setCallback(sendDigitalMessage); - analogChannelsInUse = min(context->analogChannels, gChannelsInUse - context->audioChannels - context->digitalChannels); + gAnalogChannelsInUse = context->analogChannels; if(context->digitalChannels > 0){ for(unsigned int ch = 0; ch < context->digitalChannels; ++ch){ dcm.setCallbackArgument(ch, receiverNames[ch]); @@ -151,12 +161,11 @@ #else midi.enableParser(false); #endif /* PARSE_MIDI */ -// gChannelsInUse = min((int)(context->analogChannels+context->audioChannels), (int)gChannelsInUse); // udpServer.bindToPort(1234); gLibpdBlockSize = libpd_blocksize(); // check that we are not running with a blocksize smaller than gLibPdBlockSize - // it would still work, but the load would be executed unevenly between calls to render + // We could still make it work, but the load would be executed unevenly between calls to render if(context->audioFrames < gLibpdBlockSize){ fprintf(stderr, "Error: minimum block size must be %d\n", gLibpdBlockSize); return false; @@ -299,11 +308,6 @@ static unsigned int numberOfPdBlocksToProcess = gBufLength / gLibpdBlockSize; - // these are reset at every audio callback. Persistence across audio callbacks - // is handled by the core code. -// setDataOut = 0; -// clearDataOut = 0; - for(unsigned int tick = 0; tick < numberOfPdBlocksToProcess; ++tick){ unsigned int audioFrameBase = gLibpdBlockSize * tick; unsigned int j; @@ -319,21 +323,21 @@ // this loop resamples by ZOH, as needed, using m if(context->analogChannels == 8 ){ //hold the value for two frames for (j = 0, p0 = gInBuf; j < gLibpdBlockSize; j++, p0++) { - for (k = 0, p1 = p0 + gLibpdBlockSize * context->audioChannels; k < analogChannelsInUse; k++, p1 += gLibpdBlockSize) { + for (k = 0, p1 = p0 + gLibpdBlockSize * gFirstAnalogChannel; k < gAnalogChannelsInUse; ++k, p1 += gLibpdBlockSize) { unsigned int analogFrame = (audioFrameBase + j) / 2; *p1 = analogRead(context, analogFrame, k); } } } else if(context->analogChannels == 4){ //write every frame for (j = 0, p0 = gInBuf; j < gLibpdBlockSize; j++, p0++) { - for (k = 0, p1 = p0 + gLibpdBlockSize * context->audioChannels; k < analogChannelsInUse; k++, p1 += gLibpdBlockSize) { + for (k = 0, p1 = p0 + gLibpdBlockSize * gFirstAnalogChannel; k < gAnalogChannelsInUse; ++k, p1 += gLibpdBlockSize) { unsigned int analogFrame = audioFrameBase + j; *p1 = analogRead(context, analogFrame, k); } } } else if(context->analogChannels == 2){ //drop every other frame for (j = 0, p0 = gInBuf; j < gLibpdBlockSize; j++, p0++) { - for (k = 0, p1 = p0 + gLibpdBlockSize * context->audioChannels; k < analogChannelsInUse; k++, p1 += gLibpdBlockSize) { + for (k = 0, p1 = p0 + gLibpdBlockSize * gFirstAnalogChannel; k < gAnalogChannelsInUse; ++k, p1 += gLibpdBlockSize) { unsigned int analogFrame = (audioFrameBase + j) * 2; *p1 = analogRead(context, analogFrame, k); } @@ -348,7 +352,7 @@ // digital in at signal-rate for (j = 0, p0 = gInBuf; j < gLibpdBlockSize; j++, p0++) { unsigned int digitalFrame = audioFrameBase + j; - for (k = 0, p1 = p0 + gLibpdBlockSize * (context->audioChannels + 8); + for (k = 0, p1 = p0 + gLibpdBlockSize * gFirstDigitalChannel; k < 16; ++k, p1 += gLibpdBlockSize) { if(dcm.isSignalRate(k) && dcm.isInput(k)){ // only process input channels that are handled at signal rate *p1 = digitalRead(context, digitalFrame, k); @@ -362,7 +366,7 @@ // digital out at signal-rate for (j = 0, p0 = gOutBuf; j < gLibpdBlockSize; ++j, ++p0) { unsigned int digitalFrame = (audioFrameBase + j); - for (k = 0, p1 = p0 + gLibpdBlockSize * (context->audioChannels + 8); + for (k = 0, p1 = p0 + gLibpdBlockSize * gFirstDigitalChannel; k < context->digitalChannels; k++, p1 += gLibpdBlockSize) { if(dcm.isSignalRate(k) && dcm.isOutput(k)){ // only process output channels that are handled at signal rate digitalWriteOnce(context, digitalFrame, k, *p1 > 0.5); @@ -379,25 +383,34 @@ audioWrite(context, audioFrameBase + j, k, *p1); } } + //scope + for (j = 0, p0 = gOutBuf; j < gLibpdBlockSize; ++j, ++p0) { + float scopeOut[gScopeChannels]={0}; + for (k = 0, p1 = p0 + gLibpdBlockSize * gFirstScopeChannel; k < gScopeChannels; k++, p1 += gLibpdBlockSize) { + scopeOut[k] = *p1; + } + scope.log(scopeOut[0], scopeOut[1], scopeOut[2], scopeOut[3]); + } + //analog if(context->analogChannels == 8){ for (j = 0, p0 = gOutBuf; j < gLibpdBlockSize; j += 2, p0 += 2) { //write every two frames unsigned int analogFrame = (audioFrameBase + j) / 2; - for (k = 0, p1 = p0 + gLibpdBlockSize * context->audioChannels; k < analogChannelsInUse; k++, p1 += gLibpdBlockSize) { + for (k = 0, p1 = p0 + gLibpdBlockSize * gFirstAnalogChannel; k < gAnalogChannelsInUse; k++, p1 += gLibpdBlockSize) { analogWriteOnce(context, analogFrame, k, *p1); } } } else if(context->analogChannels == 4){ //write every frame for (j = 0, p0 = gOutBuf; j < gLibpdBlockSize; ++j, ++p0) { unsigned int analogFrame = (audioFrameBase + j); - for (k = 0, p1 = p0 + gLibpdBlockSize * context->audioChannels; k < analogChannelsInUse; k++, p1 += gLibpdBlockSize) { + for (k = 0, p1 = p0 + gLibpdBlockSize * context->audioChannels; k < gAnalogChannelsInUse; k++, p1 += gLibpdBlockSize) { analogWriteOnce(context, analogFrame, k, *p1); } } } else if(context->analogChannels == 2){ //write every frame twice for (j = 0, p0 = gOutBuf; j < gLibpdBlockSize; j++, p0++) { - for (k = 0, p1 = p0 + gLibpdBlockSize * context->audioChannels; k < analogChannelsInUse; k++, p1 += gLibpdBlockSize) { + for (k = 0, p1 = p0 + gLibpdBlockSize * context->audioChannels; k < gAnalogChannelsInUse; k++, p1 += gLibpdBlockSize) { int analogFrame = audioFrameBase * 2 + j * 2; analogWriteOnce(context, analogFrame, k, *p1); analogWriteOnce(context, analogFrame + 1, k, *p1);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/08-PureData/scope/_main.pd Mon Jun 20 20:38:46 2016 +0100 @@ -0,0 +1,15 @@ +#N canvas 394 368 477 304 10; +#X text 16 25 ============; +#X obj 104 239 dac~ 27 28 29 30; +#X obj 27 186 osc~ 2321; +#X obj 123 175 osc~ 12; +#X obj 267 175 noise~; +#X obj 192 170 phasor~ 10; +#X text 16 15 Bela Scope; +#X text 116 15 Make sure the IDE is running and then bring up the scope +in your browser http://192.168.7.2/scope/ You can log to the scope +by sending to dac~ 27 to 30; +#X connect 2 0 1 0; +#X connect 3 0 1 1; +#X connect 4 0 1 3; +#X connect 5 0 1 2;