changeset 543:8f8809c77dda prerelease

updated basics, digital, instruments, extras examples
author chnrx <chris.heinrichs@gmail.com>
date Fri, 24 Jun 2016 13:19:52 +0100
parents 3016638b4da2
children cdabbaf3a252 db3e1a08cdee
files examples/01-Basics/minimal/render.cpp examples/01-Basics/passthrough/main.cpp examples/01-Basics/passthrough/render.cpp examples/01-Basics/sinetone/main.cpp examples/01-Basics/sinetone/render.cpp examples/02-Digital/digital-input/render.cpp examples/02-Digital/digital-output/render.cpp examples/02-Digital/level-meter/render.cpp examples/05-Communication/basic-midi/render.cpp examples/08-PureData/gettingStarted/_main.pd examples/08-PureData/hello-midi/_main.pd examples/08-PureData/scope/_main.pd examples/10-Instruments/airharp/String.cpp examples/10-Instruments/airharp/render.cpp examples/10-Instruments/d-box/render.cpp examples/10-Instruments/oscillator-bank/render.cpp examples/10-Instruments/tank-wars/render.cpp examples/10-Instruments/vangelisiser/_main.pd examples/11-Extras/gpioAnalogLoopbackTest/render.cpp examples/11-Extras/userdata/main.cpp examples/11-Extras/userdata/render.cpp
diffstat 21 files changed, 415 insertions(+), 367 deletions(-) [+]
line wrap: on
line diff
--- a/examples/01-Basics/minimal/render.cpp	Fri Jun 24 13:00:31 2016 +0100
+++ b/examples/01-Basics/minimal/render.cpp	Fri Jun 24 13:19:52 2016 +0100
@@ -103,13 +103,12 @@
 you need.
 
 Take a look at what's in the data structure [here]
-(https://code.soundsoftware.ac.uk/projects/beaglert/embedded/structBeagleRTContext.html).
 
 You can access any of these bits of information about current audio and sensor 
 settings and pointers to data buffers that are contained in the data structure 
 like this: `context->name_of_item`.
 
-For example, `context->audioChannels` returns the number of audio channels. 
+For example, `context->audioInChannels` returns the number of audio input channels. 
 `context->audioSampleRate` returns the audio sample rate. 
 `context->audioIn[n]` would give you the current input sample (assuming that 
 your input is mono - if it's not you will have to account for multiple channels).
--- a/examples/01-Basics/passthrough/main.cpp	Fri Jun 24 13:00:31 2016 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-/*
- ____  _____ _        _    
-| __ )| ____| |      / \   
-|  _ \|  _| | |     / _ \  
-| |_) | |___| |___ / ___ \ 
-|____/|_____|_____/_/   \_\
-
-The platform for ultra-low latency audio and sensor processing
-
-http://bela.io
-
-A project of the Augmented Instruments Laboratory within the
-Centre for Digital Music at Queen Mary University of London.
-http://www.eecs.qmul.ac.uk/~andrewm
-
-(c) 2016 Augmented Instruments Laboratory: Andrew McPherson,
-	Astrid Bin, Liam Donovan, Christian Heinrichs, Robert Jack,
-	Giulio Moro, Laurel Pardue, Victor Zappi. All rights reserved.
-
-The Bela software is distributed under the GNU Lesser General Public License
-(LGPL 3.0), available here: https://www.gnu.org/licenses/lgpl-3.0.txt
-*/
-
-#include <iostream>
-#include <cstdlib>
-#include <libgen.h>
-#include <signal.h>
-#include <getopt.h>
-#include <Bela.h>
-
-using namespace std;
-
-// Handle Ctrl-C by requesting that the audio rendering stop
-void interrupt_handler(int var)
-{
-	gShouldStop = true;
-}
-
-// Print usage information
-void usage(const char * processName)
-{
-	cerr << "Usage: " << processName << " [options]" << endl;
-
-	Bela_usage();
-
-	cerr << "   --help [-h]:             Print this menu\n";
-}
-
-int main(int argc, char *argv[])
-{
-	BelaInitSettings settings;	// Standard audio settings
-
-	struct option customOptions[] =
-	{
-		{"help", 0, NULL, 'h'},
-		{NULL, 0, NULL, 0}
-	};
-
-	// Set default settings
-	Bela_defaultSettings(&settings);
-
-	// Parse command-line arguments
-	while (1) {
-		int c;
-		if ((c = Bela_getopt_long(argc, argv, "h", customOptions, &settings)) < 0)
-				break;
-		switch (c) {
-		case 'h':
-				usage(basename(argv[0]));
-				exit(0);
-		case '?':
-		default:
-				usage(basename(argv[0]));
-				exit(1);
-		}
-	}
-
-	// Initialise the PRU audio device
-	if(Bela_initAudio(&settings, 0) != 0) {
-		cout << "Error: unable to initialise audio" << endl;
-		return -1;
-	}
-
-	// Start the audio device running
-	if(Bela_startAudio()) {
-		cout << "Error: unable to start real-time audio" << endl;
-		return -1;
-	}
-
-	// Set up interrupt handler to catch Control-C and SIGTERM
-	signal(SIGINT, interrupt_handler);
-	signal(SIGTERM, interrupt_handler);
-
-	// Run until told to stop
-	while(!gShouldStop) {
-		usleep(100000);
-	}
-
-	// Stop the audio device
-	Bela_stopAudio();
-
-	// Clean up any resources allocated for audio
-	Bela_cleanupAudio();
-
-	// All done!
-	return 0;
-}
--- a/examples/01-Basics/passthrough/render.cpp	Fri Jun 24 13:00:31 2016 +0100
+++ b/examples/01-Basics/passthrough/render.cpp	Fri Jun 24 13:19:52 2016 +0100
@@ -25,7 +25,7 @@
 
 bool setup(BelaContext *context, void *userData)
 {
-	// Nothing to do here...
+	// For this example we need the same amount of audio and analog input and output channels
 	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");
@@ -82,10 +82,10 @@
 
 In `render()` you'll see a nested for loop structure. You'll see this in all Bela projects. 
 The first for loop cycles through `audioFrames`, the second through 
-`audioChannels` (in this case left 0 and right 1).
+`audioInChannels` (in this case left 0 and right 1).
 
 You can access any information about current audio and sensor settings you can do the following: 
-`context->name_of_item`. For example `context->audioChannels` returns current number of channels,
+`context->name_of_item`. For example `context->audioInChannels` returns current number of input channels,
 `context->audioFrames` returns the current number of audio frames, 
 `context->audioSampleRate` returns the audio sample rate.
 
@@ -112,7 +112,7 @@
 Note that for the analog channels we write to and read from the buffers in a separate set 
 of nested for loops. This is because the they are sampled at half audio rate by default. 
 The first of these for loops cycles through `analogFrames`, the second through
-`analogChannels`.
+`analogInChannels`.
 
 By setting `audioWriteFrame(context, n, ch, audioReadFrame(context, n, ch))` and
 `analogWrite(context, n, ch, analogReadFrame(context, n, ch))` we have a simple 
@@ -120,5 +120,5 @@
 
 
 It is also possible to address the buffers directly, for example: 
-`context->audioOut[n * context->audioChannels + ch]`.
+`context->audioOut[n * context->audioOutChannels + ch]`.
 */
--- a/examples/01-Basics/sinetone/main.cpp	Fri Jun 24 13:00:31 2016 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-/*
- ____  _____ _        _    
-| __ )| ____| |      / \   
-|  _ \|  _| | |     / _ \  
-| |_) | |___| |___ / ___ \ 
-|____/|_____|_____/_/   \_\
-
-The platform for ultra-low latency audio and sensor processing
-
-http://bela.io
-
-A project of the Augmented Instruments Laboratory within the
-Centre for Digital Music at Queen Mary University of London.
-http://www.eecs.qmul.ac.uk/~andrewm
-
-(c) 2016 Augmented Instruments Laboratory: Andrew McPherson,
-	Astrid Bin, Liam Donovan, Christian Heinrichs, Robert Jack,
-	Giulio Moro, Laurel Pardue, Victor Zappi. All rights reserved.
-
-The Bela software is distributed under the GNU Lesser General Public License
-(LGPL 3.0), available here: https://www.gnu.org/licenses/lgpl-3.0.txt
-*/
-
-#include <unistd.h>
-#include <iostream>
-#include <cstdlib>
-#include <libgen.h>
-#include <signal.h>
-#include <getopt.h>
-#include <Bela.h>
-
-using namespace std;
-
-// Handle Ctrl-C by requesting that the audio rendering stop
-void interrupt_handler(int var)
-{
-	gShouldStop = true;
-}
-
-// Print usage information
-void usage(const char * processName)
-{
-	cerr << "Usage: " << processName << " [options]" << endl;
-
-	Bela_usage();
-
-	cerr << "   --frequency [-f] frequency: Set the frequency of the oscillator\n";
-	cerr << "   --help [-h]:                Print this menu\n";
-}
-
-int main(int argc, char *argv[])
-{
-	BelaInitSettings settings;	// Standard audio settings
-	float frequency = 440.0;	// Frequency of oscillator
-
-	struct option customOptions[] =
-	{
-		{"help", 0, NULL, 'h'},
-		{"frequency", 1, NULL, 'f'},
-		{NULL, 0, NULL, 0}
-	};
-
-	// Set default settings
-	Bela_defaultSettings(&settings);
-
-	// Parse command-line arguments
-	while (1) {
-		int c;
-		if ((c = Bela_getopt_long(argc, argv, "hf:", customOptions, &settings)) < 0)
-				break;
-		switch (c) {
-		case 'h':
-				usage(basename(argv[0]));
-				exit(0);
-		case 'f':
-				frequency = atof(optarg);
-				break;
-		case '?':
-		default:
-				usage(basename(argv[0]));
-				exit(1);
-		}
-	}
-
-	// Initialise the PRU audio device
-	if(Bela_initAudio(&settings, &frequency) != 0) {
-		cout << "Error: unable to initialise audio" << endl;
-		return -1;
-	}
-
-	// Start the audio device running
-	if(Bela_startAudio()) {
-		cout << "Error: unable to start real-time audio" << endl;
-		return -1;
-	}
-
-	// Set up interrupt handler to catch Control-C and SIGTERM
-	signal(SIGINT, interrupt_handler);
-	signal(SIGTERM, interrupt_handler);
-
-	// Run until told to stop
-	while(!gShouldStop) {
-		usleep(100000);
-	}
-
-	// Stop the audio device
-	Bela_stopAudio();
-
-	// Clean up any resources allocated for audio
-	Bela_cleanupAudio();
-
-	// All done!
-	return 0;
-}
--- a/examples/01-Basics/sinetone/render.cpp	Fri Jun 24 13:00:31 2016 +0100
+++ b/examples/01-Basics/sinetone/render.cpp	Fri Jun 24 13:19:52 2016 +0100
@@ -30,12 +30,8 @@
 
 bool setup(BelaContext *context, void *userData)
 {
-	// Retrieve a parameter passed in from the initAudio() call
-	if(userData != 0)
-		gFrequency = *(float *)userData;
-
 	gInverseSampleRate = 1.0 / context->audioSampleRate;
-	gPhase = 0.0;
+	gPhase = 0.0;s
 
 	return true;
 }
@@ -48,11 +44,11 @@
 		if(gPhase > 2.0 * M_PI)
 			gPhase -= 2.0 * M_PI;
 
-		for(unsigned int channel = 0; channel < context->audioChannels; channel++) {
+		for(unsigned int channel = 0; channel < context->audioOutChannels; channel++) {
 			// Two equivalent ways to write this code
 
 			// The long way, using the buffers directly:
-			// context->audioOut[n * context->audioChannels + channel] = out;
+			// context->audioOut[n * context->audioOutChannels + channel] = out;
 
 			// Or using the macros:
 			audioWrite(context, n, channel, out);
--- a/examples/02-Digital/digital-input/render.cpp	Fri Jun 24 13:00:31 2016 +0100
+++ b/examples/02-Digital/digital-input/render.cpp	Fri Jun 24 13:19:52 2016 +0100
@@ -42,7 +42,7 @@
 		int status=digitalRead(context, 0, P8_08); //read the value of the button
 		digitalWriteOnce(context, n, P8_07, status); //write the status to the LED
 		float out = 0.1 * status * rand() / (float)RAND_MAX * 2 - 1; //generate some noise, gated by the button
-		for(unsigned int j = 0; j < context->audioChannels; j++){
+		for(unsigned int j = 0; j < context->audioOutChannels; j++){
 			audioWrite(context, n, j, out); //write the audio output
 		}
 	}
@@ -75,6 +75,8 @@
 P8_07 is set to `HIGH` as well, so that the LED conducts and emits light. When 
 the button is pressed, P8_08 goes `LOW` and P8_07 is set to `LOW`, turning off the LED.
 
+Note that there are two ways of specifying the digital pin: using the GPIO label (e.g. `P8_07`), or using the digital IO index (e.g. 0)
+
 As an exercise try and change the code so that the LED only turns on when 
 the button is pressed.
 */
--- a/examples/02-Digital/digital-output/render.cpp	Fri Jun 24 13:00:31 2016 +0100
+++ b/examples/02-Digital/digital-output/render.cpp	Fri Jun 24 13:19:52 2016 +0100
@@ -80,6 +80,8 @@
 either `HIGH` or `LOW`. When set `HIGH` the pin will give 3.3V, when set to 
 `LOW` 0V.
 
+Note that there are two ways of specifying the digital pin: using the GPIO label (e.g. `P8_07`), or using the digital IO index (e.g. 0)
+
 To keep track of elapsed time we have a sample counter count. When the count reaches 
 a certain limit it switches state to either `HIGH` or `LOW` depending on its current 
 value. In this case the limit is `context->digitalSampleRate*interval` which 
--- a/examples/02-Digital/level-meter/render.cpp	Fri Jun 24 13:00:31 2016 +0100
+++ b/examples/02-Digital/level-meter/render.cpp	Fri Jun 24 13:19:52 2016 +0100
@@ -57,6 +57,12 @@
 		rt_printf("Error: this project needs the audio and digital sample rates to be the same.\n");
 		return false;
 	}
+
+	// For this example we need the same amount of audio input and output channels
+	if(context->audioInChannels != context->audioOutChannels){
+		printf("Error: for this project, you need the same number of audio input and output channels.\n");
+		return false;
+	}
 	
 	// Initialise threshold levels in -3dB steps. One extra for efficiency in render()
 	// Level = 10^(dB/20)
@@ -77,10 +83,10 @@
 	for(unsigned int n = 0; n < context->audioFrames; n++) {
 		// Get average of audio input channels
 		float sample = 0;
-		for(unsigned int ch = 0; ch < context->audioChannels; ch++) {
-			context->audioOut[n * context->audioChannels + ch] = 
-				context->audioIn[n * context->audioChannels + ch];
-			sample += context->audioIn[n * context->audioChannels + ch];
+		for(unsigned int ch = 0; ch < context->audioInChannels; ch++) {
+			context->audioOut[n * context->audioOutChannels + ch] = 
+				context->audioIn[n * context->audioInChannels + ch];
+			sample += context->audioIn[n * context->audioInChannels + ch];
 		}
 		
 		// Do DC-blocking on the sum
@@ -92,7 +98,7 @@
 		gLastY[1] = gLastY[0];
 		gLastY[0] = out;
 		
-		out = fabsf(out / (float)context->audioChannels);
+		out = fabsf(out / (float)context->audioOutChannels);
 		
 		// Do peak detection: fast-responding local level
 		if(out > gAudioLocalLevel)
--- a/examples/05-Communication/basic-midi/render.cpp	Fri Jun 24 13:00:31 2016 +0100
+++ b/examples/05-Communication/basic-midi/render.cpp	Fri Jun 24 13:19:52 2016 +0100
@@ -67,6 +67,13 @@
 		rt_printf("Error: this example needs the analog I/O to be enabled\n");
 		return false;
 	}
+
+	if(context->audioOutChannels <= 2 ||
+		context->analogOutChannels <= 2){
+		printf("Error: for this project, you need at least 2 analog and audio output channels.\n");
+		return false;
+	}
+
 	gSamplingPeriod = 1/context->audioSampleRate;
 	return true;
 }
--- a/examples/08-PureData/gettingStarted/_main.pd	Fri Jun 24 13:00:31 2016 +0100
+++ b/examples/08-PureData/gettingStarted/_main.pd	Fri Jun 24 13:19:52 2016 +0100
@@ -1,124 +1,124 @@
 #N canvas 736 167 442 1518 10;
 #X text 32 20 Using Puredata (libpd) on Bela;
 #X text 32 30 ==============================;
-#X obj 100 538 osc~ 440;
-#X obj 100 560 *~ 0.1;
-#X obj 100 582 dac~;
-#X text 33 501 Here's how you produce a sine wave out of Bela's stereo
+#X obj 100 598 osc~ 440;
+#X obj 100 620 *~ 0.1;
+#X obj 100 642 dac~;
+#X text 33 561 Here's how you produce a sine wave out of Bela's stereo
 output:;
-#X text 33 611 Similarly \, Bela's stereo input can be addressed as
+#X text 33 671 Similarly \, Bela's stereo input can be addressed as
 follows:;
-#X obj 100 642 adc~;
-#X obj 100 664 dac~;
-#X text 177 653 Audio pass-through;
-#X text 33 1581 Supported objects;
-#X text 33 1591 -----------------;
-#X text 33 1625 All native pd (vanilla) objects can be used.;
-#X text 33 1611 By default Bela uses libpd to run puredata patches.
+#X obj 100 702 adc~;
+#X obj 100 724 dac~;
+#X text 177 713 Audio pass-through;
+#X text 33 1791 Supported objects;
+#X text 33 1801 -----------------;
+#X text 33 1835 All native pd (vanilla) objects can be used.;
+#X text 33 1821 By default Bela uses libpd to run puredata patches.
 ;
-#X text 33 1645 It is also possible to compile pd objects to optimised
+#X text 33 1855 It is also possible to compile pd objects to optimised
 ;
-#X text 33 1658 C code using the Heavy Cloud Compiler \, in which case
+#X text 33 1868 C code using the Heavy Cloud Compiler \, in which case
 ;
-#X text 33 1671 a different set of objects is supported (see below).
+#X text 33 1881 a different set of objects is supported (see below).
 ;
-#X text 33 701 Analog I/O;
-#X text 33 711 ----------;
-#X text 33 731 Analog inputs and outputs are treated as audio signals
+#X text 33 761 Analog I/O;
+#X text 33 771 ----------;
+#X text 33 791 Analog inputs and outputs are treated as audio signals
 and;
-#X text 33 745 are addressed using the next 8 channels of the [adc~]
+#X text 33 805 are addressed using the next 8 channels of the [adc~]
 and;
-#X text 33 759 [dac~] objects:;
-#X obj 36 785 adc~ 3 4 5 6 7 8 9 10;
-#X text 191 785 Analog Inputs 0 \, 1 \, 2 \, 3 \, 4 \, 5 \, 6 \, 7
+#X text 33 819 [dac~] objects:;
+#X obj 36 845 adc~ 3 4 5 6 7 8 9 10;
+#X text 191 845 Analog Inputs 0 \, 1 \, 2 \, 3 \, 4 \, 5 \, 6 \, 7
 ;
-#X text 191 815 Analog Outputs 0 \, 1 \, 2 \, 3 \, 4 \, 5 \, 6 \, 7
+#X text 191 875 Analog Outputs 0 \, 1 \, 2 \, 3 \, 4 \, 5 \, 6 \, 7
 ;
-#X obj 36 815 dac~ 3 4 5 6 7 8 9 10;
-#X text 33 853 examples.;
-#X text 33 891 MIDI;
-#X text 33 901 ----;
-#X text 99 921 and;
-#X obj 36 920 notein;
-#X obj 125 920 ctlin;
-#X text 183 921 objects can be used to interface MIDI devices;
-#X text 33 939 with the patch.;
-#X text 33 954 Most MIDI devices can be plugged into the Beaglebone's
+#X obj 36 875 dac~ 3 4 5 6 7 8 9 10;
+#X text 33 913 examples.;
+#X text 33 1101 MIDI;
+#X text 33 1111 ----;
+#X text 99 1131 and;
+#X obj 36 1130 notein;
+#X obj 125 1130 ctlin;
+#X text 183 1131 objects can be used to interface MIDI devices;
+#X text 33 1149 with the patch.;
+#X text 33 1164 Most MIDI devices can be plugged into the Beaglebone's
 USB;
-#X text 33 968 port and can be used with these objects.;
-#X text 33 839 See the 'BasicAnalogIn' and 'BasicAnalogOut' projects
+#X text 33 1178 port and can be used with these objects.;
+#X text 33 899 See the 'BasicAnalogIn' and 'BasicAnalogOut' projects
 for;
-#X text 33 983 See the 'hello-midi' and 'midi-poly-synth' projects
+#X text 33 1193 See the 'hello-midi' and 'midi-poly-synth' projects
 for more;
-#X text 33 997 for examples.;
-#X obj 57 1058 print;
-#X text 33 1058 The;
-#X text 115 1058 object can be used to log messages directly to Bela's
+#X text 33 1207 for examples.;
+#X obj 57 1268 print;
+#X text 33 1268 The;
+#X text 115 1268 object can be used to log messages directly to Bela's
 ;
-#X text 33 1076 terminal output (e.g. as viewable in the browser IDE).
+#X text 33 1286 terminal output (e.g. as viewable in the browser IDE).
 ;
-#X obj 100 1102 loadbang;
-#X obj 100 1146 print;
-#X msg 100 1124 Puredata says: 'Hello Bela!';
-#X text 33 1041 ----------------;
-#X text 33 1031 Debugging: print;
-#X text 33 1191 ----------------;
-#X text 33 1181 Debugging: scope;
-#X text 33 1208 Any signal can be visualised using Bela's browser-based
+#X obj 100 1312 loadbang;
+#X obj 100 1356 print;
+#X msg 100 1334 Puredata says: 'Hello Bela!';
+#X text 33 1251 ----------------;
+#X text 33 1241 Debugging: print;
+#X text 33 1401 ----------------;
+#X text 33 1391 Debugging: scope;
+#X text 33 1418 Any signal can be visualised using Bela's browser-based
 ;
-#X text 33 1222 scope. DAC channels 27 \, 28 \, 29 \, 30 address four
+#X text 33 1432 scope. DAC channels 27 \, 28 \, 29 \, 30 address four
 separate;
-#X text 33 1236 scope channels.;
-#X obj 147 1309 dac~ 27 28 29 30;
-#X obj 79 1261 osc~ 440;
-#X obj 149 1261 noise~;
-#X obj 209 1261 osc~ 880;
-#X obj 209 1283 *~;
-#X text 33 1364 visualised.;
-#X text 33 1710 Compiling Puredata patches with Heavy;
-#X text 33 1720 -------------------------------------;
-#X text 33 1740 As an alternative to libpd \, Puredata patches can
+#X text 33 1446 scope channels.;
+#X obj 147 1519 dac~ 27 28 29 30;
+#X obj 79 1471 osc~ 440;
+#X obj 149 1471 noise~;
+#X obj 209 1471 osc~ 880;
+#X obj 209 1493 *~;
+#X text 33 1574 visualised.;
+#X text 33 1920 Compiling Puredata patches with Heavy;
+#X text 33 1930 -------------------------------------;
+#X text 33 1950 As an alternative to libpd \, Puredata patches can
 be;
-#X text 33 1754 converted into optimised C code using the Heavy Cloud
+#X text 33 1964 converted into optimised C code using the Heavy Cloud
 ;
-#X text 33 1768 Compiler by Enzien Audio. The resulting code can result
+#X text 33 1978 Compiler by Enzien Audio. The resulting code can result
 ;
-#X text 33 1782 in large increases in performance and is therefore
+#X text 33 1992 in large increases in performance and is therefore
 well;
-#X text 33 1796 suited for complex patches and final stages of development.
+#X text 33 2006 suited for complex patches and final stages of development.
 ;
-#X text 33 1810 We recommend to use libpd for prototyping and less
+#X text 33 2020 We recommend to use libpd for prototyping and less
 CPU;
-#X text 33 1824 intensive patches.;
-#X text 33 1838 See our documentation to learn more about compiling
+#X text 33 2034 intensive patches.;
+#X text 33 2048 See our documentation to learn more about compiling
 patches;
-#X text 33 1852 using Heavy \, and visit enzienaudio.com for more info
+#X text 33 2061 using Heavy \, and visit enzienaudio.com for more info
 and;
-#X text 33 1866 a list of currently supported objects.;
-#X text 33 1401 Combining Pd and C++;
-#X text 33 1411 --------------------;
-#X text 33 1428 There are many cases where it is useful to combine
+#X text 33 2075 a list of currently supported objects.;
+#X text 33 1611 Combining Pd and C++;
+#X text 33 1621 --------------------;
+#X text 33 1638 There are many cases where it is useful to combine
 Pd;
-#X text 33 1442 patches with C++ code \, for example when needing to
+#X text 33 1652 patches with C++ code \, for example when needing to
 ;
-#X text 33 1456 incorporate system calls (e.g. networking) or for;
-#X text 33 1470 sample-accurate dsp processes that are inconvenient
+#X text 33 1666 incorporate system calls (e.g. networking) or for;
+#X text 33 1680 sample-accurate dsp processes that are inconvenient
 ;
-#X text 33 1484 to program in Puredata.;
-#X text 33 1517 is used \, which functions as a libpd wrapper. It is
+#X text 33 1694 to program in Puredata.;
+#X text 33 1727 is used \, which functions as a libpd wrapper. It is
 ;
-#X text 33 1504 When running Puredata patches a template render.cpp
+#X text 33 1714 When running Puredata patches a template render.cpp
 file;
-#X text 33 1531 possible to modify this file when starting a new pd
+#X text 33 1741 possible to modify this file when starting a new pd
 project.;
-#X text 33 1545 See the 'CustomRenderFile' example project for more
+#X text 33 1755 See the 'CustomRenderFile' example project for more
 info.;
-#X text 177 560 Sine Wave;
-#X obj 149 1283 *~ 0.1;
-#X obj 279 1261 osc~ 0.5;
-#X text 33 1350 click the scope button to see the above signals being
+#X text 177 620 Sine Wave;
+#X obj 149 1493 *~ 0.1;
+#X obj 279 1471 osc~ 0.5;
+#X text 33 1560 click the scope button to see the above signals being
 ;
-#X text 33 1336 If you're viewing this patch using the Bela IDE you
+#X text 33 1546 If you're viewing this patch using the Bela IDE you
 can;
 #X text 33 221 Patches can be drag-and-dropped into the browser IDE
 ;
@@ -151,8 +151,8 @@
 #X text 33 151 solutions.;
 #X text 33 191 Loading and running patches in the Bela IDE;
 #X text 33 201 -------------------------------------------;
-#X text 33 471 Audio I/O;
-#X text 33 481 ---------;
+#X text 33 531 Audio I/O;
+#X text 33 541 ---------;
 #X text 33 392 If you're viewing this inside the Bela IDE \, then you've
 ;
 #X text 33 406 noticed by now that all pd patches can be previewed
@@ -160,6 +160,25 @@
 #X text 33 420 the browser. Note \, however \, that patches cannot
 currently;
 #X text 33 434 be edited or interacted with inside this preview.;
+#X text 33 464 To view the contents of abstractions supplied with a
+;
+#X text 33 477 project in the IDE \, simply go to the project navigator
+;
+#X text 33 490 and open the corresponding patches from there.;
+#X text 33 951 Digital I/O;
+#X text 33 961 -----------;
+#X text 33 981 Digital pins can also be addressed from within a patch.
+;
+#X text 33 994 Unlike analog pins \, digital pins can be set to work
+as;
+#X text 33 1007 inputs or outputs and can be read/written as signals
+or;
+#X text 33 1020 as messages.;
+#X text 33 1033 See the 'digital' example for instructions on how to
+;
+#X text 33 1047 initialise \, read and write to digital pins as well
+as some;
+#X text 33 1060 usage examples;
 #X connect 2 0 3 0;
 #X connect 3 0 4 0;
 #X connect 3 0 4 1;
--- a/examples/08-PureData/hello-midi/_main.pd	Fri Jun 24 13:00:31 2016 +0100
+++ b/examples/08-PureData/hello-midi/_main.pd	Fri Jun 24 13:19:52 2016 +0100
@@ -1,4 +1,4 @@
-#N canvas 906 587 651 756 10;
+#N canvas 461 525 651 756 10;
 #X obj 45 706 dac~ 1 2;
 #X obj 45 663 *~ 0.1;
 #X obj 45 262 mtof;
@@ -36,10 +36,10 @@
 #X text 43 66 with a midi controller. Note and control messages can
 be;
 #X text 43 80 obtained using the;
-#X obj 159 80 notein;
-#X text 213 80 and;
-#X obj 240 80 ctlin;
-#X text 292 80 objects.;
+#X obj 169 80 notein;
+#X text 233 80 and;
+#X obj 260 80 ctlin;
+#X text 315 80 objects.;
 #X text 43 104 Most midi devices should be compatible when plugged
 into;
 #X text 43 117 the BeagleBone's USB port.;
--- a/examples/08-PureData/scope/_main.pd	Fri Jun 24 13:00:31 2016 +0100
+++ b/examples/08-PureData/scope/_main.pd	Fri Jun 24 13:19:52 2016 +0100
@@ -1,9 +1,9 @@
 #N canvas 1035 935 404 295 10;
-#X obj 126 235 dac~ 27 28 29 30;
-#X obj 76 201 osc~ 2321;
+#X obj 136 235 dac~ 27 28 29 30;
+#X obj 66 201 osc~ 2321;
 #X obj 143 201 osc~ 12;
-#X obj 268 201 noise~;
-#X obj 197 201 phasor~ 10;
+#X obj 288 201 noise~;
+#X obj 207 201 phasor~ 10;
 #X text 16 15 Bela Scope;
 #X text 16 25 ==========;
 #X text 16 81 If you're running this example in the Bela IDE \, simply
--- a/examples/10-Instruments/airharp/String.cpp	Fri Jun 24 13:00:31 2016 +0100
+++ b/examples/10-Instruments/airharp/String.cpp	Fri Jun 24 13:19:52 2016 +0100
@@ -42,9 +42,6 @@
 
 	// 3. use right waveguide as output
 
-	//rt_printf("BANANA %f ",_readPtr);
-	//rt_printf("%f\n",_previous_r);
-
 	return _previous_r;
 }
 
--- a/examples/10-Instruments/airharp/render.cpp	Fri Jun 24 13:00:31 2016 +0100
+++ b/examples/10-Instruments/airharp/render.cpp	Fri Jun 24 13:19:52 2016 +0100
@@ -1,6 +1,31 @@
+/*
+ ____  _____ _        _    
+| __ )| ____| |      / \   
+|  _ \|  _| | |     / _ \  
+| |_) | |___| |___ / ___ \ 
+|____/|_____|_____/_/   \_\
+
+The platform for ultra-low latency audio and sensor processing
+
+http://bela.io
+
+A project of the Augmented Instruments Laboratory within the
+Centre for Digital Music at Queen Mary University of London.
+http://www.eecs.qmul.ac.uk/~andrewm
+
+(c) 2016 Augmented Instruments Laboratory: Andrew McPherson,
+	Astrid Bin, Liam Donovan, Christian Heinrichs, Robert Jack,
+	Giulio Moro, Laurel Pardue, Victor Zappi. All rights reserved.
+
+The Bela software is distributed under the GNU Lesser General Public License
+(LGPL 3.0), available here: https://www.gnu.org/licenses/lgpl-3.0.txt
+*/
+
+
 /*
  * AIR-HARP
  * Physically modelled strings using waveguide junctions and mass-spring-dampers
+ * controllable using an accelerometer
  *
  * render.cpp
  *
@@ -44,7 +69,7 @@
 
 // DC BLOCK BUTTERWORTH
 
-// Coefficients for 100hz cut-off
+// Coefficients for 100hz high-pass centre frequency
 float a0_l = 0.9899759179893742;
 float a1_l = -1.9799518359787485;
 float a2_l = 0.9899759179893742;
@@ -194,8 +219,8 @@
     	y2_r = y1_r;
    	 	y1_r = out_r;
 
-		context->audioOut[n * context->audioChannels + 1] = out_l * out_gain;
-		context->audioOut[n * context->audioChannels + 0] = out_r * out_gain;
+		context->audioOut[n * context->audioOutChannels + 1] = out_l * out_gain;
+		context->audioOut[n * context->audioOutChannels + 0] = out_r * out_gain;
 
 	}
 
--- a/examples/10-Instruments/d-box/render.cpp	Fri Jun 24 13:00:31 2016 +0100
+++ b/examples/10-Instruments/d-box/render.cpp	Fri Jun 24 13:19:52 2016 +0100
@@ -159,27 +159,33 @@
 bool setup(BelaContext *context, void *userData) {
 	int oscBankHopSize = *(int *)userData;
 
-	if(context->analogChannels != 8) {
-		printf("Error: D-Box needs matrix enabled with 8 channels.\n");
+	if(context->analogOutChannels <= 8 || context->analogInChannels <= 8) {
+		printf("Error: D-Box needs at least 8 analog IO channels.\n");
+		return false;
+	}
+
+	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;
 	}
 
 	// Allocate two buffers for rendering oscillator bank samples
 	// One will be used for writing in the background while the other is used for reading
 	// on the audio thread. 8-byte alignment needed for the NEON code.
-	if(posix_memalign((void **)&gOscillatorBuffer1, 8, oscBankHopSize * context->audioChannels * sizeof(float))) {
+	if(posix_memalign((void **)&gOscillatorBuffer1, 8, oscBankHopSize * context->audioOutChannels * sizeof(float))) {
 		printf("Error allocating render buffers\n");
 		return false;
 	}
-	if(posix_memalign((void **)&gOscillatorBuffer2, 8, oscBankHopSize * context->audioChannels * sizeof(float))) {
+	if(posix_memalign((void **)&gOscillatorBuffer2, 8, oscBankHopSize * context->audioOutChannels * sizeof(float))) {
 		printf("Error allocating render buffers\n");
 		return false;
 	}
 	gOscillatorBufferWrite	= gOscillatorBuffer1;
 	gOscillatorBufferRead	= gOscillatorBuffer2;
 
-	memset(gOscillatorBuffer1, 0, oscBankHopSize * context->audioChannels * sizeof(float));
-	memset(gOscillatorBuffer2, 0, oscBankHopSize * context->audioChannels * sizeof(float));
+	memset(gOscillatorBuffer1, 0, oscBankHopSize * context->audioOutChannels * sizeof(float));
+	memset(gOscillatorBuffer2, 0, oscBankHopSize * context->audioOutChannels * sizeof(float));
 
 	// Initialise the dynamic wavetable used by the oscillator bank
 	// It should match the size of the static one already allocated in the OscillatorBank object
@@ -250,7 +256,7 @@
 
 	if(gOscBanks[gCurrentOscBank]->state==bank_playing)
 	{
-		assert(context->audioChannels == 2);
+		assert(context->audioOutChannels == 2);
 
 #ifdef OLD_OSCBANK
 		memset(audioOut, 0, numAudioFrames *  * sizeof(float));
--- a/examples/10-Instruments/oscillator-bank/render.cpp	Fri Jun 24 13:00:31 2016 +0100
+++ b/examples/10-Instruments/oscillator-bank/render.cpp	Fri Jun 24 13:19:52 2016 +0100
@@ -77,7 +77,7 @@
 {
 	srandom(time(NULL));
 
-	if(context->audioChannels != 2) {
+	if(context->audioOutChannels != 2) {
 		rt_printf("Error: this example needs stereo audio enabled\n");
 		return false;
 	}
--- a/examples/10-Instruments/tank-wars/render.cpp	Fri Jun 24 13:00:31 2016 +0100
+++ b/examples/10-Instruments/tank-wars/render.cpp	Fri Jun 24 13:19:52 2016 +0100
@@ -93,9 +93,9 @@
 {
 	srandom(time(NULL));
 
-	// Verify we are running with matrix enabled
-	if(context->analogFrames == 0 || context->analogChannels < 4) {
-		rt_printf("Error: this example needs the matrix enabled with at least 4 channels\n");
+	// Verify we are running with analog channels enabled
+	if(context->analogFrames == 0 || context->analogOutChannels < 4) {
+		rt_printf("Error: this example needs least 4 analog output channels\n");
 		return false;
 	}
 
--- a/examples/10-Instruments/vangelisiser/_main.pd	Fri Jun 24 13:00:31 2016 +0100
+++ b/examples/10-Instruments/vangelisiser/_main.pd	Fri Jun 24 13:19:52 2016 +0100
@@ -157,10 +157,10 @@
 #X text 612 648 use velocity to control reverb input level;
 #X obj 233 174 adc~ 3;
 #X obj 233 196 send~ \$0-x;
-#X obj 303 174 adc~ 4;
-#X obj 373 174 adc~ 5;
-#X obj 303 196 send~ \$0-y;
-#X obj 373 196 send~ \$0-z;
+#X obj 323 174 adc~ 4;
+#X obj 413 174 adc~ 5;
+#X obj 323 196 send~ \$0-y;
+#X obj 413 196 send~ \$0-z;
 #X obj 458 352 receive~ \$0-x;
 #X obj 477 501 receive~ \$0-z;
 #X obj 257 918 receive~ \$0-x;
--- a/examples/11-Extras/gpioAnalogLoopbackTest/render.cpp	Fri Jun 24 13:00:31 2016 +0100
+++ b/examples/11-Extras/gpioAnalogLoopbackTest/render.cpp	Fri Jun 24 13:19:52 2016 +0100
@@ -25,19 +25,26 @@
 int gDigitalOutLoopDelay;
 bool setup(BelaContext *context, void *userData)
 {
+	// For this test we need the same amount of audio and analog input and output channels
+	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;
+	}
+
 	rt_printf("For this test you need the following connections:\n"
 			"analog%d out->digital%d in, analog%d out->analog%d in, "
 			"digital%d out -> digital%d in, digital%d out-> analog%d in\n",
 			gAnalogOutCh, gDigitalInACh, gAnalogOutCh, 0, gDigitalOutCh, gDigitalInDCh, gDigitalOutCh, 0);
 	rt_printf("Running test with %d analog channels and a buffer size of %d\n",
-			context->analogChannels, context->audioFrames);
+			context->analogInChannels, context->audioFrames);
 
 	for(unsigned int n = 0; n < context->digitalFrames; n++){
 		pinMode(context, n, gDigitalInACh, INPUT);
 		pinMode(context, n, gDigitalInDCh, INPUT);
 		pinMode(context, n, gDigitalOutCh, OUTPUT);
 	}
-	switch (context->analogChannels){
+	switch (context->analogOutChannels){
 		case 2:
 			gAnalogOutLoopDelay = context->audioFrames*2 + 3;
 			gDigitalOutLoopDelay = context->audioFrames*2 + 2;
@@ -96,10 +103,10 @@
 		static bool analog0In = false;
 		static bool digitalAIn = false;
 		static int count = 0;
-		bool doReadWrite = context->analogChannels<=4 ? true : ((context->analogChannels == 8) && (n&1)==0);
+		bool doReadWrite = context->analogInChannels<=4 ? true : ((context->analogInChannels == 8) && (n&1)==0);
 		if(doReadWrite){
 			digitalAIn = digitalRead(context, n, gDigitalInACh);
-			switch(context->analogChannels){
+			switch(context->analogInChannels){
 			case 8:
 				analog0In = analogRead(context, n/2, 0) > 0.5;
 				analogWrite(context, n/2, analogOut, writePattern[outPointer]);
@@ -150,20 +157,20 @@
 		bool doReadWrite = false;
 		static bool pastAnalog1In = false;
 		digitalWriteOnce(context, n, gDigitalOutCh,  writePattern[digitalOutPointer]);
-		if(context->analogChannels == 8){
+		if(context->analogInChannels == 8){
 			if((n&1) == 0){ //do it every other sample
 				pastAnalog1In = analogRead(context, n/2, 1) > 0.5;
 				digitalDIn = digitalRead(context, n, gDigitalInDCh);
 				doReadWrite = true;
 			}
 		}
-		if(context->analogChannels == 4){
+		if(context->analogInChannels == 4){
 			pastAnalog1In = analogRead(context, n, 1) > 0.5;
 			digitalDIn = digitalRead(context, n, gDigitalInDCh);
 			digitalWriteOnce(context, n, gDigitalOutCh,  writePattern[digitalOutPointer]);
 			doReadWrite = true;
 		}
-		if(context->analogChannels == 2){
+		if(context->analogInChannels == 2){
 			pastAnalog1In = analogRead(context, n * 2, 1) > 0.5;
 			digitalDIn = digitalRead(context, n, gDigitalInDCh);
 			digitalWriteOnce(context, n, gDigitalOutCh,  writePattern[digitalOutPointer]);
@@ -198,12 +205,12 @@
 void cleanup(BelaContext *context, void *userData)
 {
 	if(anaErrorCount == 0 && digErrorCount == 0){
-		rt_printf("Test was succesful with %d analog channels and a buffer size of %d\n", context->analogChannels, context->audioFrames);
+		rt_printf("Test was succesful with %d analog channels and a buffer size of %d\n", context->analogInChannels, context->audioFrames);
 	} else {
 		rt_printf("------------------------\n%danalog %ddigital errors over %dsamples while running test with ",
 				anaErrorCount, digErrorCount, context->audioFramesElapsed);
 		rt_printf("%d analog channels and a buffer size of %d \n\n\n",
-				context->analogChannels, context->audioFrames);
+				context->analogInChannels, context->audioFrames);
 		exit(1);
 	}
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/11-Extras/userdata/main.cpp	Fri Jun 24 13:19:52 2016 +0100
@@ -0,0 +1,120 @@
+/*
+ ____  _____ _        _    
+| __ )| ____| |      / \   
+|  _ \|  _| | |     / _ \  
+| |_) | |___| |___ / ___ \ 
+|____/|_____|_____/_/   \_\
+
+The platform for ultra-low latency audio and sensor processing
+
+http://bela.io
+
+A project of the Augmented Instruments Laboratory within the
+Centre for Digital Music at Queen Mary University of London.
+http://www.eecs.qmul.ac.uk/~andrewm
+
+(c) 2016 Augmented Instruments Laboratory: Andrew McPherson,
+	Astrid Bin, Liam Donovan, Christian Heinrichs, Robert Jack,
+	Giulio Moro, Laurel Pardue, Victor Zappi. All rights reserved.
+
+The Bela software is distributed under the GNU Lesser General Public License
+(LGPL 3.0), available here: https://www.gnu.org/licenses/lgpl-3.0.txt
+*/
+
+#include <unistd.h>
+#include <iostream>
+#include <cstdlib>
+#include <libgen.h>
+#include <signal.h>
+#include <getopt.h>
+#include <Bela.h>
+
+using namespace std;
+
+// Handle Ctrl-C by requesting that the audio rendering stop
+void interrupt_handler(int var)
+{
+	gShouldStop = true;
+}
+
+// Print usage information
+void usage(const char * processName)
+{
+	cerr << "Usage: " << processName << " [options]" << endl;
+
+	Bela_usage();
+
+	cerr << "   --frequency [-f] frequency: Set the frequency of the oscillator\n";
+	cerr << "   --help [-h]:                Print this menu\n";
+}
+
+int main(int argc, char *argv[])
+{
+	BelaInitSettings settings;	// Standard audio settings
+	float frequency = 440.0;	// Frequency of oscillator
+
+	struct option customOptions[] =
+	{
+		{"help", 0, NULL, 'h'},
+		{"frequency", 1, NULL, 'f'},
+		{NULL, 0, NULL, 0}
+	};
+
+	// Set default settings
+	Bela_defaultSettings(&settings);
+
+	// Parse command-line arguments
+	while (1) {
+		int c;
+		if ((c = Bela_getopt_long(argc, argv, "hf:", customOptions, &settings)) < 0)
+				break;
+		switch (c) {
+		case 'h':
+				usage(basename(argv[0]));
+				exit(0);
+		case 'f':
+				frequency = atof(optarg);
+				break;
+		case '?':
+		default:
+				usage(basename(argv[0]));
+				exit(1);
+		}
+	}
+
+	// Initialise the PRU audio device
+
+	/* 
+	 *  Note how we are passing the frequency parameter so that it
+	 *  can be read from the setup() function inside render.cpp
+	 */
+
+	if(Bela_initAudio(&settings, &frequency) != 0) {
+		cout << "Error: unable to initialise audio" << endl;
+		return -1;
+	}
+
+	// Start the audio device running
+	if(Bela_startAudio()) {
+		cout << "Error: unable to start real-time audio" << endl;
+		return -1;
+	}
+
+	// Set up interrupt handler to catch Control-C and SIGTERM
+	signal(SIGINT, interrupt_handler);
+	signal(SIGTERM, interrupt_handler);
+
+	// Run until told to stop
+	while(!gShouldStop) {
+		usleep(100000);
+	}
+
+	// Stop the audio device
+	Bela_stopAudio();
+
+	// Clean up any resources allocated for audio
+	Bela_cleanupAudio();
+
+	// All done!
+	return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/11-Extras/userdata/render.cpp	Fri Jun 24 13:19:52 2016 +0100
@@ -0,0 +1,83 @@
+/*
+ ____  _____ _        _    
+| __ )| ____| |      / \   
+|  _ \|  _| | |     / _ \  
+| |_) | |___| |___ / ___ \ 
+|____/|_____|_____/_/   \_\
+
+The platform for ultra-low latency audio and sensor processing
+
+http://bela.io
+
+A project of the Augmented Instruments Laboratory within the
+Centre for Digital Music at Queen Mary University of London.
+http://www.eecs.qmul.ac.uk/~andrewm
+
+(c) 2016 Augmented Instruments Laboratory: Andrew McPherson,
+	Astrid Bin, Liam Donovan, Christian Heinrichs, Robert Jack,
+	Giulio Moro, Laurel Pardue, Victor Zappi. All rights reserved.
+
+The Bela software is distributed under the GNU Lesser General Public License
+(LGPL 3.0), available here: https://www.gnu.org/licenses/lgpl-3.0.txt
+*/
+
+#include <Bela.h>
+#include <cmath>
+
+float gFrequency = 440.0;
+float gPhase;
+float gInverseSampleRate;
+
+bool setup(BelaContext *context, void *userData)
+{
+	/*
+	 *  Retrieve the parameter passed in from the Bela_initAudio() call in main.cpp
+	 */
+	if(userData != 0)
+		gFrequency = *(float *)userData;
+
+	gInverseSampleRate = 1.0 / context->audioSampleRate;
+	gPhase = 0.0;
+
+	return true;
+}
+
+void render(BelaContext *context, void *userData)
+{
+	for(unsigned int n = 0; n < context->audioFrames; n++) {
+		float out = 0.8f * sinf(gPhase);
+		gPhase += 2.0 * M_PI * gFrequency * gInverseSampleRate;
+		if(gPhase > 2.0 * M_PI)
+			gPhase -= 2.0 * M_PI;
+
+		for(unsigned int channel = 0; channel < context->audioOutChannels; channel++) {
+			// Two equivalent ways to write this code
+
+			// The long way, using the buffers directly:
+			// context->audioOut[n * context->audioOutChannels + channel] = out;
+
+			// Or using the macros:
+			audioWrite(context, n, channel, out);
+		}
+	}
+}
+
+void cleanup(BelaContext *context, void *userData)
+{
+
+}
+
+
+/**
+\example userdata/render.cpp
+
+Passing parameters using the `*userData` argument
+-------------------------------------------------
+
+This sketch demonstrates how to pass command line arguments using the `*userData` argument inside the `setup()` function.
+
+In main.cpp we first parse a command line argument `-f` and allocate its value to the variable `frequency`.
+We then pass the address of this variable when we call `Bela_initAudio()`. The variable can now be accessed from the
+`setup()` and `render()` functions inside render.cpp.
+
+*/