changeset 537:bfcbeb437869 API-update

Updated RTAudioSettings with in/out, ported some examples and libpd
author Giulio Moro <giuliomoro@yahoo.it>
date Fri, 24 Jun 2016 01:36:07 +0100
parents 5c8f46fcd4d0
children b486344aa796
files core/RTAudio.cpp core/RTAudioCommandLine.cpp core/default_libpd_render.cpp examples/01-Basics/passthrough/render.cpp examples/03-Analog/analog-input/render.cpp include/Bela.h include/Utilities.h
diffstat 7 files changed, 83 insertions(+), 47 deletions(-) [+]
line wrap: on
line diff
--- a/core/RTAudio.cpp	Thu Jun 23 18:17:35 2016 +0100
+++ b/core/RTAudio.cpp	Fri Jun 24 01:36:07 2016 +0100
@@ -167,11 +167,16 @@
 		}
 	}
 
+	if(settings->numAnalogInChannels != settings->numAnalogOutChannels){
+		printf("Error: TODO: a different number of channels for inputs and outputs is not yet supported\n");
+		return 1;
+	}
+	unsigned int numAnalogChannels = settings->numAnalogInChannels;
 	// Limit the analog channels to sane values
-	if(settings->numAnalogChannels != 2 
-		&& settings->numAnalogChannels != 4
-		&& settings->numAnalogChannels != 8) {
-			cout << "Invalid number of analog channels: " << settings->numAnalogChannels << ". Valid values are 2, 4, 8.\n";
+	if(numAnalogChannels != 2
+		&& numAnalogChannels != 4
+		&& numAnalogChannels != 8) {
+			cout << "Invalid number of analog channels: " << numAnalogChannels << ". Valid values are 2, 4, 8.\n";
 			return -1;
 	}
 
@@ -185,11 +190,12 @@
 	if(settings->useAnalog) {
 		gContext.audioFrames = settings->periodSize;
 
-		gContext.analogFrames = gContext.audioFrames * 4 / settings->numAnalogChannels;
-		// TODO: settings a different number of channels for inputs and outputs is not yet supported
-		gContext.analogInChannels = settings->numAnalogChannels;
-		gContext.analogOutChannels = settings->numAnalogChannels;
-		gContext.analogSampleRate = gContext.audioSampleRate * 4.0 / (float)settings->numAnalogChannels;
+		// TODO: a different number of channels for inputs and outputs is not yet supported
+		gContext.analogFrames = gContext.audioFrames * 4 / settings->numAnalogInChannels;
+		gContext.analogInChannels = settings->numAnalogInChannels;
+		gContext.analogOutChannels = settings->numAnalogOutChannels;
+		unsigned int numAnalogChannelsForSampleRate = settings->numAnalogInChannels;
+		gContext.analogSampleRate = gContext.audioSampleRate * 4.0 / (float)numAnalogChannelsForSampleRate;
 	}
 	else {
 		gContext.audioFrames = settings->periodSize;
--- a/core/RTAudioCommandLine.cpp	Thu Jun 23 18:17:35 2016 +0100
+++ b/core/RTAudioCommandLine.cpp	Fri Jun 24 01:36:07 2016 +0100
@@ -53,7 +53,11 @@
 	settings->periodSize = 16;
 	settings->useAnalog = 1;
 	settings->useDigital = 1;
-	settings->numAnalogChannels = 8;
+	settings->numAudioInChannels = 2;
+	settings->numAudioOutChannels = 2;
+
+	settings->numAnalogInChannels = 8;
+	settings->numAnalogOutChannels = 8;
 	settings->numDigitalChannels = 16;
 
 	settings->beginMuted = 0;
@@ -168,23 +172,35 @@
 				settings->numDigitalChannels = 0;
 			}
 			break;
-		case 'C':
-			settings->numAnalogChannels = atoi(optarg);
-			if(settings->numAnalogChannels >= 8) {
+		case 'C': {
+			// TODO: a different number of channels for inputs and outputs is not yet supported
+			unsigned int numAnalogChannels = atoi(optarg);
+			settings->numAnalogInChannels = numAnalogChannels;
+			settings->numAnalogOutChannels = numAnalogChannels;
+			if(numAnalogChannels >= 8) {
+				// TODO: a different number of channels for inputs and outputs is not yet supported
+
 				// Use multiplexer capelet to run larger numbers of channels
-				if(settings->numAnalogChannels >= 64)
+				if(settings->numAnalogInChannels >= 64)
 					settings->numMuxChannels = 8;
-				else if(settings->numAnalogChannels >= 32)
+				else if(settings->numAnalogInChannels >= 32)
 					settings->numMuxChannels = 4;
-				else if(settings->numAnalogChannels >= 16)
+				else if(settings->numAnalogInChannels >= 16)
 					settings->numMuxChannels = 2;
-				settings->numAnalogChannels = 8;
+				settings->numAnalogInChannels = 8;
 			}
-			else if(settings->numAnalogChannels >= 4)
-				settings->numAnalogChannels = 4;
-			else
-				settings->numAnalogChannels = 2;
+			else if(numAnalogChannels >= 4){
+				// TODO: a different number of channels for inputs and outputs is not yet supported
+				settings->numAnalogInChannels = 4;
+				settings->numAnalogOutChannels = 4;
+			}
+			else{
+				// TODO: a different number of channels for inputs and outputs is not yet supported
+				settings->numAnalogInChannels = 2;
+				settings->numAnalogOutChannels = 2;
+			}
 			break;
+		}
 		case 'B':
 			settings->numDigitalChannels = atoi(optarg);
 			if(settings->numDigitalChannels >= 16)
--- a/core/default_libpd_render.cpp	Thu Jun 23 18:17:35 2016 +0100
+++ b/core/default_libpd_render.cpp	Fri Jun 24 01:36:07 2016 +0100
@@ -136,9 +136,13 @@
 		printf("Error file %s/%s not found. The %s file should be your main patch.\n", folder, file, file);
 		return false;
 	}
-
+	if(context->analogInChannels != context->analogOutChannels ||
+			context->audioInChannels != context->audioOutChannels){
+		printf("This project requires the number of inputs and the number of outputs to be the same\n");
+		return false;
+	}
 	// analog setup
-	gAnalogChannelsInUse = context->analogChannels;
+	gAnalogChannelsInUse = context->analogInChannels;
 
 	// digital setup
 	dcm.setCallback(sendDigitalMessage);
@@ -305,27 +309,27 @@
 		float* p0;
 		float* p1;
 		for (j = 0, p0 = gInBuf; j < gLibpdBlockSize; j++, p0++) {
-			for (k = 0, p1 = p0; k < context->audioChannels; k++, p1 += gLibpdBlockSize) {
+			for (k = 0, p1 = p0; k < context->audioInChannels; k++, p1 += gLibpdBlockSize) {
 				*p1 = audioRead(context, audioFrameBase + j, k);
 			}
 		}
 		// then analogs
 		// this loop resamples by ZOH, as needed, using m
-		if(context->analogChannels == 8 ){ //hold the value for two frames
+		if(context->analogInChannels == 8 ){ //hold the value for two frames
 			for (j = 0, p0 = gInBuf; j < gLibpdBlockSize; j++, p0++) {
 				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
+		} else if(context->analogInChannels == 4){ //write every frame
 			for (j = 0, p0 = gInBuf; j < gLibpdBlockSize; j++, p0++) {
 				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
+		} else if(context->analogInChannels == 2){ //drop every other frame
 			for (j = 0, p0 = gInBuf; j < gLibpdBlockSize; j++, p0++) {
 				for (k = 0, p1 = p0 + gLibpdBlockSize * gFirstAnalogChannel; k < gAnalogChannelsInUse; ++k, p1 += gLibpdBlockSize) {
 					unsigned int analogFrame = (audioFrameBase + j) * 2;
@@ -369,7 +373,7 @@
 
 		//audio
 		for (j = 0, p0 = gOutBuf; j < gLibpdBlockSize; j++, p0++) {
-			for (k = 0, p1 = p0; k < context->audioChannels; k++, p1 += gLibpdBlockSize) {
+			for (k = 0, p1 = p0; k < context->audioOutChannels; k++, p1 += gLibpdBlockSize) {
 				audioWrite(context, audioFrameBase + j, k, *p1);
 			}
 		}
@@ -383,23 +387,23 @@
 
 
 		//analog
-		if(context->analogChannels == 8){
+		if(context->analogOutChannels == 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 * gFirstAnalogChannel; k < gAnalogChannelsInUse; k++, p1 += gLibpdBlockSize) {
 					analogWriteOnce(context, analogFrame, k, *p1);
 				}
 			}
-		} else if(context->analogChannels == 4){ //write every frame
+		} else if(context->analogOutChannels == 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 < gAnalogChannelsInUse; k++, p1 += gLibpdBlockSize) {
+				for (k = 0, p1 = p0  + gLibpdBlockSize * gFirstAnalogChannel; k < gAnalogChannelsInUse; k++, p1 += gLibpdBlockSize) {
 					analogWriteOnce(context, analogFrame, k, *p1);
 				}
 			}
-		} else if(context->analogChannels == 2){ //write every frame twice
+		} else if(context->analogOutChannels == 2){ //write every frame twice
 			for (j = 0, p0 = gOutBuf; j < gLibpdBlockSize; j++, p0++) {
-				for (k = 0, p1 = p0 + gLibpdBlockSize * context->audioChannels; k < gAnalogChannelsInUse; k++, p1 += gLibpdBlockSize) {
+				for (k = 0, p1 = p0 + gLibpdBlockSize * gFirstAnalogChannel; k < gAnalogChannelsInUse; k++, p1 += gLibpdBlockSize) {
 					int analogFrame = audioFrameBase * 2 + j * 2;
 					analogWriteOnce(context, analogFrame, k, *p1);
 					analogWriteOnce(context, analogFrame + 1, k, *p1);
--- a/examples/01-Basics/passthrough/render.cpp	Thu Jun 23 18:17:35 2016 +0100
+++ b/examples/01-Basics/passthrough/render.cpp	Fri Jun 24 01:36:07 2016 +0100
@@ -22,26 +22,24 @@
 */
 
 #include <Bela.h>
-#include <Scope.h>
-
-Scope scope;
 
 bool setup(BelaContext *context, void *userData)
 {
 	// Nothing to do here...
-	printf("%d %d\n", context->audioInChannels, context->audioOutChannels);
-	scope.setup(8, 44100);
+	if(context->audioInChannels != context->audioOutChannels ||
+			context->analogInChannels != context-> analogOutChannels){
+		printf("Error: for this project, you need the same number of input and output channels.\n");
+		return false;
+	}
 	return true;
 }
 
 void render(BelaContext *context, void *userData)
 {
-	static const unsigned int audioChannels = min(context->audioInChannels, context->audioOutChannels);
-	static const unsigned int analogChannels = min(context->analogInChannels, context->analogOutChannels);
 
 	// Simplest possible case: pass inputs through to outputs
 	for(unsigned int n = 0; n < context->audioFrames; n++) {
-		for(unsigned int ch = 0; ch < audioChannels; ch++){
+		for(unsigned int ch = 0; ch < context->audioInChannels; ch++){
 			// Two equivalent ways to write this code
 
 			// The long way, using the buffers directly:
@@ -55,7 +53,7 @@
 
 	// Same with analog channels
 	for(unsigned int n = 0; n < context->analogFrames; n++) {
-		for(unsigned int ch = 0; ch < analogChannels; ch++) {
+		for(unsigned int ch = 0; ch < context->analogInChannels; ch++) {
 			// Two equivalent ways to write this code
 
 			// The long way, using the buffers directly:
--- a/examples/03-Analog/analog-input/render.cpp	Thu Jun 23 18:17:35 2016 +0100
+++ b/examples/03-Analog/analog-input/render.cpp	Fri Jun 24 01:36:07 2016 +0100
@@ -68,7 +68,7 @@
 
 		float out = amplitude * sinf(gPhase);
 
-		for(unsigned int channel = 0; channel < context->audioChannels; channel++)
+		for(unsigned int channel = 0; channel < context->audioOutChannels; channel++)
 			context->audioOut[n * context->audioChannels + channel] = out;
 
 		gPhase += 2.0 * M_PI * frequency * gInverseSampleRate;
--- a/include/Bela.h	Thu Jun 23 18:17:35 2016 +0100
+++ b/include/Bela.h	Fri Jun 24 01:36:07 2016 +0100
@@ -112,8 +112,14 @@
 	int useAnalog;
 	/// Whether to use the 16 programmable GPIOs
 	int useDigital;
-	/// How many channels for the ADC and DAC
-	int numAnalogChannels;
+	/// How many audio input channels
+	int numAudioInChannels;
+	/// How many audio out channels
+	int numAudioOutChannels;
+	/// How many analog input channels
+	int numAnalogInChannels;
+	/// How many analog output channels
+	int numAnalogOutChannels;
 	/// How many channels for the GPIOs
 	int numDigitalChannels;
 
--- a/include/Utilities.h	Thu Jun 23 18:17:35 2016 +0100
+++ b/include/Utilities.h	Fri Jun 24 01:36:07 2016 +0100
@@ -42,7 +42,7 @@
 /** @} */
 
 /**
- * \ingroup wiring
+ * \cond BIT_FUNCTIONS
  *
  * @{
  */
@@ -59,7 +59,9 @@
 /// Set/clear the given bit in \c word to \c value.
 #define changeBit(word,bit,value) 	((clearBit((word),(bit))) | ((value) << (bit)))
 
-/** @} */
+/** @}
+ * \endcond
+ * */
 
 /**
  * \ingroup iofunctions
@@ -295,11 +297,15 @@
 static inline float constrain(float x, float min_val, float max_val);
 
 /**
+ * \brief Returns the maximum of two numbers
+ *
  * Returns the maximum of two numbers
  */
 static inline float min(float x, float y);
 
 /**
+ * \brief Returns the minimum of two numbers
+ *
  * Returns the minimum of two numbers
  */
 static inline float max(float x, float y);