diff core/default_libpd_render.cpp @ 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 5a936f8e9447
children 838a4a4a8580
line wrap: on
line diff
--- 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);