changeset 375:768acdeea362 prerelease

Merge
author Giulio Moro <giuliomoro@yahoo.it>
date Fri, 10 Jun 2016 00:35:18 +0100
parents ecad1ea0382a (current diff) 3bed6b09223c (diff)
children 9d2ed561aac5
files
diffstat 21 files changed, 555 insertions(+), 45 deletions(-) [+]
line wrap: on
line diff
--- a/core/RTAudio.cpp	Fri Jun 10 00:02:48 2016 +0100
+++ b/core/RTAudio.cpp	Fri Jun 10 00:35:18 2016 +0100
@@ -152,12 +152,12 @@
 	}
 
 	// Limit the analog channels to sane values
-	if(settings->numAnalogChannels >= 8)
-		settings->numAnalogChannels = 8;
-	else if(settings->numAnalogChannels >= 4)
-		settings->numAnalogChannels = 4;
-	else
-		settings->numAnalogChannels = 2;
+	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";
+			return -1;
+	}
 
 	// Initialise the rendering environment: sample rates, frame counts, numbers of channels
 	gContext.audioSampleRate = 44100.0;
--- a/examples/analogDigitalDemo/render.cpp	Fri Jun 10 00:02:48 2016 +0100
+++ b/examples/analogDigitalDemo/render.cpp	Fri Jun 10 00:35:18 2016 +0100
@@ -1,9 +1,34 @@
-    /*
+/*
+ ____  _____ _        _    
+| __ )| ____| |      / \   
+|  _ \|  _| | |     / _ \  
+| |_) | |___| |___ / ___ \ 
+|____/|_____|_____/_/   \_\.io
+
+ */
+
+/*
  *
  * Andrew McPherson and Victor Zappi
  * Queen Mary, University of London
  */
 
+/**
+\example 3_analogDigitalDemo
+
+Analog digital workout
+----------------------
+
+This sketch showcases many different ways to write and read digital pins, 
+including generating clocks and creating binary counters.
+
+The code as it is will not work properly, as the direction of the pins is not 
+set. As an exercise, you will need to set the pin mode before writing or reading 
+the digital pins. 
+
+This is for advanced users only.
+*/
+
 #include <Bela.h>
 #include <Utilities.h>
 #include <cmath>
--- a/examples/audio_in_FFT/render.cpp	Fri Jun 10 00:02:48 2016 +0100
+++ b/examples/audio_in_FFT/render.cpp	Fri Jun 10 00:35:18 2016 +0100
@@ -1,10 +1,38 @@
+/*
+ ____  _____ _        _    
+| __ )| ____| |      / \   
+|  _ \|  _| | |     / _ \  
+| |_) | |___| |___ / ___ \ 
+|____/|_____|_____/_/   \_\.io
+
+ */
+
 /*
  * render.cpp
  *
  *  Created on: Oct 24, 2014
- *      Author: parallels
+ *      Author: Andrew McPherson, C4DM, QMUL
  */
 
+/**
+\example 4_audio_FFT
+
+Fast Fourier Transform
+----------------------
+
+This sketch performs an FFT (Fast Fourier Transform) on incoming audio. It uses 
+the NE10 library, included at the top of the file (line 11).
+
+Read the documentation on the NE10 library [here](http://projectne10.github.io/Ne10/doc/annotated.html).
+
+The variables `timeDomainIn`, `timeDomainOut` and `frequencyDomain` are 
+variables of the struct `ne10_fft_cpx_float32_t` [http://projectne10.github.io/Ne10/doc/structne10__fft__cpx__float32__t.html](http://projectne10.github.io/Ne10/doc/structne10__fft__cpx__float32__t.html). 
+These are declared at the top of the file (line 21), and memory is allocated 
+for them in `setup()` (line 41).
+
+In `render()` a `for` loop performs the FFT which is performed on each sample, 
+and the resulting output is placed on each channel.
+*/
 
 #include <Bela.h>
 #include <rtdk.h>
@@ -12,16 +40,15 @@
 #include <cmath>
 
 int gFFTSize;
-float gFFTScaleFactor = 0;
 
 int gReadPointer = 0;
 int gWritePointer = 0;
 
 // FFT vars
-ne10_fft_cpx_float32_t* timeDomainIn;
-ne10_fft_cpx_float32_t* timeDomainOut;
-ne10_fft_cpx_float32_t* frequencyDomain;
-ne10_fft_cfg_float32_t cfg;
+static ne10_fft_cpx_float32_t* timeDomainIn;
+static ne10_fft_cpx_float32_t* timeDomainOut;
+static ne10_fft_cpx_float32_t* frequencyDomain;
+static ne10_fft_cfg_float32_t cfg;
 
 // setup() is called once before the audio rendering starts.
 // Use it to perform any initialisation and allocation which is dependent
@@ -36,12 +63,11 @@
 {
 	// Retrieve a parameter passed in from the initAudio() call
 	gFFTSize = *(int *)userData;
-	gFFTScaleFactor = 1.0f / (float)gFFTSize;
 
 	timeDomainIn = (ne10_fft_cpx_float32_t*) NE10_MALLOC (gFFTSize * sizeof (ne10_fft_cpx_float32_t));
 	timeDomainOut = (ne10_fft_cpx_float32_t*) NE10_MALLOC (gFFTSize * sizeof (ne10_fft_cpx_float32_t));
 	frequencyDomain = (ne10_fft_cpx_float32_t*) NE10_MALLOC (gFFTSize * sizeof (ne10_fft_cpx_float32_t));
-	cfg = ne10_fft_alloc_c2c_float32 (gFFTSize);
+	cfg = ne10_fft_alloc_c2c_float32_neon (gFFTSize);
 
 	memset(timeDomainOut, 0, gFFTSize * sizeof (ne10_fft_cpx_float32_t));
 
@@ -63,19 +89,19 @@
 		if(++gReadPointer >= gFFTSize)
 		{
 			//FFT
-			ne10_fft_c2c_1d_float32_neon (frequencyDomain, timeDomainIn, cfg->twiddles, cfg->factors, gFFTSize, 0);
+			ne10_fft_c2c_1d_float32_neon (frequencyDomain, timeDomainIn, cfg, 0);
 
 			//Do frequency domain stuff
 
 			//IFFT
-			ne10_fft_c2c_1d_float32_neon (timeDomainOut, frequencyDomain, cfg->twiddles, cfg->factors, gFFTSize, 1);
+			ne10_fft_c2c_1d_float32_neon (timeDomainOut, frequencyDomain, cfg, 1);
 
 			gReadPointer = 0;
 			gWritePointer = 0;
 		}
 
 		for(unsigned int channel = 0; channel < context->audioChannels; channel++)
-			context->audioOut[n * context->audioChannels + channel] = (float) timeDomainOut[gWritePointer].r * gFFTScaleFactor;
+			context->audioOut[n * context->audioChannels + channel] = (float) timeDomainOut[gWritePointer].r;
 		gWritePointer++;
 	}
 }
--- a/examples/basic/render.cpp	Fri Jun 10 00:02:48 2016 +0100
+++ b/examples/basic/render.cpp	Fri Jun 10 00:35:18 2016 +0100
@@ -1,3 +1,12 @@
+/*
+ ____  _____ _        _    
+| __ )| ____| |      / \   
+|  _ \|  _| | |     / _ \  
+| |_) | |___| |___ / ___ \ 
+|____/|_____|_____/_/   \_\.io
+
+ */
+
 /*
  * render.cpp
  *
@@ -5,6 +14,23 @@
  *      Author: parallels
  */
 
+/**
+\example 1_basic_helloworld
+
+Producing your first bleep!
+---------------------------
+
+This sketch is the hello world of embedded interactive audio. Better known as bleep, it 
+produces a sine tone.
+
+The frequency of the sine tone is determined by a global variable, `gFrequency` 
+(line 12). The sine tone is produced by incrementing the phase of a sin function 
+on every audio frame.
+
+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). 
+It is good to familiarise yourself with this structure as it's fundamental to producing sound with the system.
+*/
 
 #include <Bela.h>
 #include <cmath>
--- a/examples/basic_FFT_phase_vocoder/render.cpp	Fri Jun 10 00:02:48 2016 +0100
+++ b/examples/basic_FFT_phase_vocoder/render.cpp	Fri Jun 10 00:35:18 2016 +0100
@@ -1,3 +1,12 @@
+/*
+ ____  _____ _        _    
+| __ )| ____| |      / \   
+|  _ \|  _| | |     / _ \  
+| |_) | |___| |___ / ___ \ 
+|____/|_____|_____/_/   \_\.io
+
+ */
+
 /*
  * render.cpp
  *
@@ -5,6 +14,17 @@
  *      Author: parallels
  */
 
+/**
+\example 4_audio_FFT_phase_vocoder
+
+Phase Vocoder
+----------------------
+
+This sketch shows an implementation of a phase vocoder and builds on the previous FFT example.
+Again it uses the NE10 library, included at the top of the file (line 11).
+
+Read the documentation on the NE10 library [here](http://projectne10.github.io/Ne10/doc/annotated.html).
+*/
 
 #include <Bela.h>
 #include <rtdk.h>
@@ -60,7 +80,10 @@
 float gDryWet = 1; // mix between the unprocessed and processed sound
 float gPlaybackLive = 0.5f; // mix between the file playback and the live audio input
 float gGain = 1; // overall gain
+float *gInputAudio = NULL;
 Midi midi;
+
+
 void midiCallback(MidiChannelMessage message, void* arg){
 	if(message.getType() == kmmNoteOn){
 		if(message.getDataByte(1) > 0){
@@ -113,11 +136,16 @@
 	timeDomainIn = (ne10_fft_cpx_float32_t*) NE10_MALLOC (gFFTSize * sizeof (ne10_fft_cpx_float32_t));
 	timeDomainOut = (ne10_fft_cpx_float32_t*) NE10_MALLOC (gFFTSize * sizeof (ne10_fft_cpx_float32_t));
 	frequencyDomain = (ne10_fft_cpx_float32_t*) NE10_MALLOC (gFFTSize * sizeof (ne10_fft_cpx_float32_t));
-	cfg = ne10_fft_alloc_c2c_float32 (gFFTSize);
+	cfg = ne10_fft_alloc_c2c_float32_neon (gFFTSize);
 
 	memset(timeDomainOut, 0, gFFTSize * sizeof (ne10_fft_cpx_float32_t));
 	memset(gOutputBuffer, 0, BUFFER_SIZE * sizeof(float));
 
+	// Allocate buffer to mirror and modify the input
+	gInputAudio = (float *)malloc(context->audioFrames * context->audioChannels * sizeof(float));
+	if(gInputAudio == 0)
+		return false;
+
 	// Allocate the window buffer based on the FFT size
 	gWindowBuffer = (float *)malloc(gFFTSize * sizeof(float));
 	if(gWindowBuffer == 0)
@@ -157,7 +185,7 @@
 	}
 
 	// Run the FFT
-	ne10_fft_c2c_1d_float32_neon (frequencyDomain, timeDomainIn, cfg->twiddles, cfg->factors, gFFTSize, 0);
+	ne10_fft_c2c_1d_float32_neon (frequencyDomain, timeDomainIn, cfg, 0);
 
 	switch (gEffect){
 	  case kRobot :
@@ -182,7 +210,7 @@
 	  }
 
 	// Run the inverse FFT
-	ne10_fft_c2c_1d_float32_neon (timeDomainOut, frequencyDomain, cfg->twiddles, cfg->factors, gFFTSize, 1);
+	ne10_fft_c2c_1d_float32_neon (timeDomainOut, frequencyDomain, cfg, 1);
 	// Overlap-and-add timeDomainOut into the output buffer
 	pointer = outWritePointer;
 	for(int n = 0; n < gFFTSize; n++) {
@@ -206,7 +234,6 @@
 // will be 0.
 void render(BelaContext* context, void* userData)
 {
-	float* audioIn = context->audioIn;
 	float* audioOut = context->audioOut;
 	int numAudioFrames = context->audioFrames;
 	int numAudioChannels = context->audioChannels;
@@ -215,21 +242,21 @@
 	// Prep the "input" to be the sound file played in a loop
 	for(int n = 0; n < numAudioFrames; n++) {
 		if(gReadPtr < gSampleData.sampleLen)
-			audioIn[2*n] = audioIn[2*n+1] = gSampleData.samples[gReadPtr]*(1-gPlaybackLive) +
+			gInputAudio[2*n] = gInputAudio[2*n+1] = gSampleData.samples[gReadPtr]*(1-gPlaybackLive) +
 			gPlaybackLive*0.5f*(audioRead(context,n,0)+audioRead(context,n,1));
 		else
-			audioIn[2*n] = audioIn[2*n+1] = 0;
+			gInputAudio[2*n] = gInputAudio[2*n+1] = 0;
 		if(++gReadPtr >= gSampleData.sampleLen)
 			gReadPtr = 0;
 	}
 	// -------------------------------------------------------------------
 
 	for(int n = 0; n < numAudioFrames; n++) {
-		gInputBuffer[gInputBufferPointer] = ((audioIn[n*numAudioChannels] + audioIn[n*numAudioChannels+1]) * 0.5);
+		gInputBuffer[gInputBufferPointer] = ((gInputAudio[n*numAudioChannels] + gInputAudio[n*numAudioChannels+1]) * 0.5);
 
 		// Copy output buffer to output
 		for(int channel = 0; channel < numAudioChannels; channel++){
-			audioOut[n * numAudioChannels + channel] = gOutputBuffer[gOutputBufferReadPointer] * gGain * gDryWet + (1 - gDryWet) * audioIn[n * numAudioChannels + channel];
+			audioOut[n * numAudioChannels + channel] = gOutputBuffer[gOutputBufferReadPointer] * gGain * gDryWet + (1 - gDryWet) * gInputAudio[n * numAudioChannels + channel];
 		}
 
 		// Clear the output sample in the buffer so it is ready for the next overlap-add
@@ -267,5 +294,6 @@
 	NE10_FREE(timeDomainOut);
 	NE10_FREE(frequencyDomain);
 	NE10_FREE(cfg);
+	free(gInputAudio);
 	free(gWindowBuffer);
 }
--- a/examples/basic_analog_input/render.cpp	Fri Jun 10 00:02:48 2016 +0100
+++ b/examples/basic_analog_input/render.cpp	Fri Jun 10 00:35:18 2016 +0100
@@ -1,3 +1,12 @@
+/*
+ ____  _____ _        _    
+| __ )| ____| |      / \   
+|  _ \|  _| | |     / _ \  
+| |_) | |___| |___ / ___ \ 
+|____/|_____|_____/_/   \_\.io
+
+ */
+
 /*
  * render.cpp
  *
@@ -5,6 +14,34 @@
  *      Author: parallels
  */
 
+/**
+\example 3_analog_input
+
+Connecting potentiometers
+-------------------------
+
+This sketch produces a sine tone, the frequency and amplitude of which are 
+affected by data received on the analog pins. Before looping through each audio 
+frame, we declare a value for the frequency and amplitude of our sine tone 
+(line 55); we adjust these values by taking in data from analog sensors 
+(for example potentiometers) with `analogRead()`.
+
+- connect a 10K pot to 3.3V and GND on its 1st and 3rd pins.
+- connect the 2nd middle pin of the pot to analogIn 0.
+- connect another 10K pot in the same way but with the middle pin connected to analogIn 1.
+
+The important thing to notice is that audio is sampled twice as often as analog 
+data. The audio sampling rate is 44.1kHz (44100 frames per second) and the 
+analog sampling rate is 22.05kHz (22050 frames per second). On line 62 you might 
+notice that we are processing the analog data and updating frequency and 
+amplitude only on every second audio sample, since the analog sampling rate is 
+half that of the audio.
+
+Note that the pin numbers are stored in the variables `gAnalogInputFrequency` and 
+`gAnalogInputAmplitude`. These are declared in the main.cpp file; if you look in 
+that file you will see that they have the values of 0 and 1. Bear in mind that 
+these are analog input pins which is a specific header!
+*/
 
 #include <Bela.h>
 #include <Utilities.h>
--- a/examples/basic_analog_output/render.cpp	Fri Jun 10 00:02:48 2016 +0100
+++ b/examples/basic_analog_output/render.cpp	Fri Jun 10 00:35:18 2016 +0100
@@ -1,10 +1,48 @@
 /*
- * render.cpp
- *
- *  Created on: Oct 24, 2014
- *      Author: parallels
+ ____  _____ _        _    
+| __ )| ____| |      / \   
+|  _ \|  _| | |     / _ \  
+| |_) | |___| |___ / ___ \ 
+|____/|_____|_____/_/   \_\.io
+
  */
 
+/*
+ *
+ * Andrew McPherson and Victor Zappi
+ * Queen Mary, University of London
+ */
+
+/**
+\example 3_analog_output
+
+Fading LEDs
+-----------
+
+This sketch uses a sine wave to drive the brightness of a series of LEDs 
+connected to the eight analog out pins. Again you can see the nested `for` loop 
+structure but this time for the analog output channels rather than the audio.
+
+- connect an LED in series with a 470ohm resistor between each of the analogOut pins and ground.
+
+Within the first for loop in render we cycle through each frame in the analog 
+output matrix. At each frame we then cycle through the analog output channels 
+with another for loop and set the output voltage according to the phase of a 
+sine tone that acts as an LFO. The analog output pins can provide a voltage of 
+~4.092V.
+
+The output on each pin is set with `analogWrite()` within the for loop that 
+cycles through the analog output channels. This needs to be provided with 
+arguments as follows `analogWrite(context, n, channel, out)`. Channel is 
+where the you give the address of the analog output pin (in this case we cycle 
+through each pin address in the for loop), out is the variable that holds the 
+desired output (in this case set by the sine wave).
+
+Notice that the phase of the brightness cycle for each led is different. This 
+is achieved by updating a variable that stores a relative phase value. This 
+variable is advanced by pi/4 (1/8 of a full rotation) for each channel giving 
+each of the eight LEDs a different phase.
+*/
 
 #include <Bela.h>
 #include <Utilities.h>
--- a/examples/basic_blink/render.cpp	Fri Jun 10 00:02:48 2016 +0100
+++ b/examples/basic_blink/render.cpp	Fri Jun 10 00:35:18 2016 +0100
@@ -1,3 +1,44 @@
+/*
+ ____  _____ _        _    
+| __ )| ____| |      / \   
+|  _ \|  _| | |     / _ \  
+| |_) | |___| |___ / ___ \ 
+|____/|_____|_____/_/   \_\.io
+
+ */
+
+/*
+ *
+ * Andrew McPherson and Victor Zappi
+ * Queen Mary, University of London
+ */
+
+/**
+\example 2_digital_blink
+
+Blinking an LED
+---------------
+
+This sketch shows the simplest case of digital out. 
+
+- Connect an LED in series with a 470ohm resistor between P8_07 and ground. 
+
+The led is blinked on and off by setting the digital pin `HIGH` and `LOW` every interval seconds which is set in 
+`render()`.
+
+In `setup()` the pin mode must be set to output mode via `pinMode()`. For example: 
+`pinMode(context, 0, P8_07, OUTPUT)`. 
+In `render()` the output of the digital pins is set by `digitalWrite()`. For example: 
+`digitalWrite(context, n, P8_07, status)` where `status` can be equal to 
+either `HIGH` or `LOW`. When set `HIGH` the pin will give 3.3V, when set to 
+`LOW` 0V.
+
+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 
+allows us to write the desired interval in seconds, stored in `interval`.
+*/
+
 #include <Bela.h>
 #include <Utilities.h>
 #include <cmath>
--- a/examples/basic_button/render.cpp	Fri Jun 10 00:02:48 2016 +0100
+++ b/examples/basic_button/render.cpp	Fri Jun 10 00:35:18 2016 +0100
@@ -1,9 +1,42 @@
+/*
+ ____  _____ _        _    
+| __ )| ____| |      / \   
+|  _ \|  _| | |     / _ \  
+| |_) | |___| |___ / ___ \ 
+|____/|_____|_____/_/   \_\.io
+
+ */
+
 /*
  *
  * Andrew McPherson and Victor Zappi
  * Queen Mary, University of London
  */
 
+/**
+\example 2_digital_button
+
+Switching an LED on and off
+---------------------------
+
+This example brings together digital input and digital output. The program will read 
+a button and turn the LED on and off according to the state of the button.
+
+- connect an LED in series with a 470ohm resistor between P8_07 and ground.
+- connect a 1k resistor to P9_03 (+3.3V),
+- connect the other end of the resistor to both a button and P8_08
+- connect the other end of the button to ground.
+
+You will notice that the LED will normally stay on and will turn off as long as 
+the button is pressed. This is due to the fact that the LED is set to the same 
+value read at input P8_08. When the button is not pressed, P8_08 is `HIGH` and so 
+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.
+
+As an exercise try and change the code so that the LED only turns on when 
+the button is pressed.
+*/
+
 #include <Bela.h>
 #include <Utilities.h>
 #include <cmath>
--- a/examples/basic_network/render.cpp	Fri Jun 10 00:02:48 2016 +0100
+++ b/examples/basic_network/render.cpp	Fri Jun 10 00:35:18 2016 +0100
@@ -1,3 +1,12 @@
+/*
+ ____  _____ _        _    
+| __ )| ____| |      / \   
+|  _ \|  _| | |     / _ \  
+| |_) | |___| |___ / ___ \ 
+|____/|_____|_____/_/   \_\.io
+
+*/
+
 /*
  * render.cpp
  *
@@ -5,6 +14,19 @@
  *      Author: parallels
  */
 
+/**
+\example 5_basic_network
+
+Networking 
+----------
+
+This sketch allows you to send audio and sensor data over UDP to a 
+DAW on the host. The host needs to run Udpioplugin which you can f
+ind [here](https://code.soundsoftware.ac.uk/projects/udpioplugin). 
+
+Note that this sketch and the accompanying plugin are still in testing.
+*/
+
 #include <Bela.h>
 //#include <rtdk.h>
 #include <cmath>
--- a/examples/basic_passthru/render.cpp	Fri Jun 10 00:02:48 2016 +0100
+++ b/examples/basic_passthru/render.cpp	Fri Jun 10 00:35:18 2016 +0100
@@ -1,10 +1,69 @@
 /*
+ ____  _____ _        _    
+| __ )| ____| |      / \   
+|  _ \|  _| | |     / _ \  
+| |_) | |___| |___ / ___ \ 
+|____/|_____|_____/_/   \_\.io
+
+ */
+
+ /*
  * render.cpp
  *
  *  Created on: Oct 24, 2014
  *      Author: parallels
  */
 
+/**
+\example 1_basic_audio_analog_passthrough
+
+Audio and analog passthrough: input to output
+-----------------------------------------
+
+This sketch demonstrates how to read from and write to the audio and analog input and output buffers.
+
+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).
+
+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->audioFrames` returns the current number of audio frames, 
+`context->audioSampleRate` returns the audio sample rate.
+
+You can look at all the information you can access in ::BeagleRTContext.
+
+Reading and writing from the audio buffers
+------------------------------------------
+
+The simplest way to read samples from the audio input buffer is with
+`audioRead()` which we pass three arguments: context, current audio 
+frame and current channel. In this example we have 
+`audioRead(context, n, ch)` where both `n` and `ch` are provided by 
+the nested for loop structure.
+
+We can write samples to the audio output buffer in a similar way using 
+`audioWrite()`. This has a fourth argument which is the value of the output.
+For example `audioWrite(context, n, ch, value_to_output)`.
+
+Reading and writing from the analog buffers
+-------------------------------------------
+
+The same is true for `analogRead()` and `analogWrite()`.
+
+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`.
+
+By setting `audioWriteFrame(context, n, ch, audioReadFrame(context, n, ch))` and
+`analogWrite(context, n, ch, analogReadFrame(context, n, ch))` we have a simple 
+passthrough of audio input to output and analog input to output.
+
+
+It is also possible to address the buffers directly, for example: 
+`context->audioOut[n * context->audioChannels + ch]`.
+*/
 
 #include <Bela.h>
 #include <Utilities.h>
--- a/examples/d-box/FIRfilter.h	Fri Jun 10 00:02:48 2016 +0100
+++ b/examples/d-box/FIRfilter.h	Fri Jun 10 00:35:18 2016 +0100
@@ -8,7 +8,7 @@
 #ifndef FIRFILTER_H_
 #define FIRFILTER_H_
 
-
+#define ENABLE_NE10_FIR_FLOAT_NEON	// Define needed for Ne10 library
 #include <NE10.h>
 
 //#define FILTER_TAP_NUM 21
--- a/examples/d-box/render.cpp	Fri Jun 10 00:02:48 2016 +0100
+++ b/examples/d-box/render.cpp	Fri Jun 10 00:35:18 2016 +0100
@@ -22,13 +22,16 @@
 
 // Mappings from pin numbers on PCB to actual DAC channels
 // This gives the DAC and ADC connectors the same effective pinout
-#define DAC_PIN0	6
-#define DAC_PIN1	4
+// Update June 2016: this is no longer needed in the latest Bela
+// release, but is kept here for convenience: it used to be 
+// 6 4 2 0 1 3 5 7 for the DAC pins
+#define DAC_PIN0	0
+#define DAC_PIN1	1
 #define DAC_PIN2	2
-#define DAC_PIN3	0
-#define DAC_PIN4	1
-#define DAC_PIN5	3
-#define DAC_PIN6	5
+#define DAC_PIN3	3
+#define DAC_PIN4	4
+#define DAC_PIN5	5
+#define DAC_PIN6	6
 #define DAC_PIN7	7
 
 #define ADC_PIN0	0
--- a/examples/filter_FIR/render.cpp	Fri Jun 10 00:02:48 2016 +0100
+++ b/examples/filter_FIR/render.cpp	Fri Jun 10 00:35:18 2016 +0100
@@ -1,3 +1,12 @@
+/*
+ ____  _____ _        _    
+| __ )| ____| |      / \   
+|  _ \|  _| | |     / _ \  
+| |_) | |___| |___ / ___ \ 
+|____/|_____|_____/_/   \_\.io
+
+*/
+
 /*
  * render.cpp
  *
@@ -5,6 +14,16 @@
  *      Author: Andrew McPherson and Victor Zappi
  */
 
+/**
+\example 4_filter_FIR
+
+Finite Impulse Response Filter
+------------------------------
+
+This is an example of a finite impulse response filter implementation.
+*/
+
+#define ENABLE_NE10_FIR_FLOAT_NEON	// Define needed for Ne10 library
 
 #include <Bela.h>
 #include <cmath>
--- a/examples/filter_IIR/render.cpp	Fri Jun 10 00:02:48 2016 +0100
+++ b/examples/filter_IIR/render.cpp	Fri Jun 10 00:35:18 2016 +0100
@@ -1,3 +1,12 @@
+/*
+ ____  _____ _        _    
+| __ )| ____| |      / \   
+|  _ \|  _| | |     / _ \  
+| |_) | |___| |___ / ___ \ 
+|____/|_____|_____/_/   \_\.io
+
+*/
+
 /*
  * render.cpp
  *
@@ -5,6 +14,14 @@
  *      Author: Andrew McPherson and Victor Zappi
  */
 
+/**
+\example 4_filter_IIR
+
+Infinite Impulse Response Filter
+------------------------------
+
+This is an example of a infinite impulse response filter implementation.
+*/
 
 #include <Bela.h>	// to schedule lower prio parallel process
 #include <rtdk.h>
--- a/examples/osc/render.cpp	Fri Jun 10 00:02:48 2016 +0100
+++ b/examples/osc/render.cpp	Fri Jun 10 00:35:18 2016 +0100
@@ -1,3 +1,34 @@
+/*
+ ____  _____ _        _    
+| __ )| ____| |      / \   
+|  _ \|  _| | |     / _ \  
+| |_) | |___| |___ / ___ \ 
+|____/|_____|_____/_/   \_\.io
+
+ */
+
+/**
+\example 5_osc
+
+Open Sound Control
+------------------
+
+This example shows an implementation of OSC (Open Sound Control) which was 
+developed at UC Berkeley Center for New Music and Audio Technology (CNMAT).
+
+It is designed to be run alongside resources/osc/osc.js
+
+The OSC server port on which to receive is set in `setup()` 
+via `oscServer.setup()`. Likewise the OSC client port on which to 
+send is set in `oscClient.setup()`.
+
+In `setup()` an OSC message to address `/osc-setup`, it then waits 
+1 second for a reply on `/osc-setup-reply`.
+
+in `render()` the code receives OSC messages, parses them, and sends 
+back an acknowledgment.
+*/
+
 #include <Bela.h>
 #include <OSCServer.h>
 #include <OSCClient.h>
--- a/examples/oscillator_bank/render.cpp	Fri Jun 10 00:02:48 2016 +0100
+++ b/examples/oscillator_bank/render.cpp	Fri Jun 10 00:35:18 2016 +0100
@@ -1,3 +1,12 @@
+/*
+ ____  _____ _        _    
+| __ )| ____| |      / \   
+|  _ \|  _| | |     / _ \  
+| |_) | |___| |___ / ___ \ 
+|____/|_____|_____/_/   \_\.io
+
+ */
+
 /*
  * render.cpp
  *
@@ -5,6 +14,15 @@
  *      Author: parallels
  */
 
+/**
+\example 4_oscillator_bank
+
+Oscillator Bank
+----------------------
+
+These files demonstrate an oscillator bank implemented in assembly code 
+that is used as part of the d-box project.
+*/
 
 #include <Bela.h>
 #include <Utilities.h>
--- a/examples/samples/render.cpp	Fri Jun 10 00:02:48 2016 +0100
+++ b/examples/samples/render.cpp	Fri Jun 10 00:35:18 2016 +0100
@@ -1,10 +1,39 @@
 /*
- * render.cpp
- *
- *  Created on: Oct 24, 2014
- *      Author: Andrew McPherson and Victor Zappi
+ ____  _____ _        _    
+| __ )| ____| |      / \   
+|  _ \|  _| | |     / _ \  
+| |_) | |___| |___ / ___ \ 
+|____/|_____|_____/_/   \_\.io
+
  */
 
+/*
+ *
+ * Andrew McPherson and Victor Zappi
+ * Queen Mary, University of London
+ */
+
+/**
+\example 4_audio_samples
+
+Playback WAV files
+------------------
+
+This sketch shows how to playback audio samples from a buffer.
+
+An audio file is loaded into a buffer `SampleData` as `gSampleData`. This is 
+accessed with a read pointer that is incremented at audio rate within the render 
+function: `out += gSampleData.samples[gReadPtr++]`.
+
+Note that the read pointer is stopped from incrementing past the length of the 
+`gSampleData`. This is achieved by comparing the read pointer value against the 
+sample length which we can access as follows: `gSampleData.sampleLen`.
+
+The sample is triggered by keyboard input: (a) starts sample playback, (s) 
+stops sample playback. The triggering is treated as a lower priority task than 
+the audio. You can see this at the bottom of the render function: 
+`Bela_scheduleAuxiliaryTask(gTriggerSamplesTask)`;
+*/
 
 #include <Bela.h>
 #include <cmath>
--- a/examples/scope_analogue/render.cpp	Fri Jun 10 00:02:48 2016 +0100
+++ b/examples/scope_analogue/render.cpp	Fri Jun 10 00:35:18 2016 +0100
@@ -1,7 +1,33 @@
-// this example reads the analogue inputs 0 and 1
-// and generates a sine wave with an amplitude and
-// frequency determined by their values
-// it then plots these on the oscilloscope
+/*
+ ____  _____ _        _    
+| __ )| ____| |      / \   
+|  _ \|  _| | |     / _ \  
+| |_) | |___| |___ / ___ \ 
+|____/|_____|_____/_/   \_\.io
+
+ */
+
+/**
+\example 3_scope_analog
+
+Connecting potentiometers
+-------------------------
+
+This example reads from analogue inputs 0 and 1 via `analogReadFrame()` and 
+generates a sine wave with amplitude and frequency determined by their values. 
+It's best to connect a 10K potentiometer to each of these analog inputs. Far 
+left and far right pins of the pot go to 3.3V and GND, the middle should be 
+connected to the analog in pins.
+
+The sine wave is then plotted on the oscilloscope. Click the Open Scope button to 
+view the results. As you turn the potentiometers you will see the amplitude and 
+frequency of the sine wave change.
+
+This project also shows as example of `map()` which allows you to re-scale a number 
+from one range to another. Note that `map()` does not constrain your variable 
+within the upper and lower limits. If you want to do this use the `constrain()`
+function.
+*/
 
 #include <Bela.h>
 #include <cmath>
--- a/examples/scope_basic/render.cpp	Fri Jun 10 00:02:48 2016 +0100
+++ b/examples/scope_basic/render.cpp	Fri Jun 10 00:35:18 2016 +0100
@@ -1,3 +1,35 @@
+/*
+ ____  _____ _        _    
+| __ )| ____| |      / \   
+|  _ \|  _| | |     / _ \  
+| |_) | |___| |___ / ___ \ 
+|____/|_____|_____/_/   \_\.io
+
+ */
+
+/**
+\example 1_scope_basic
+
+Oscilloscope in-browser
+-----------------------
+
+This example demonstrates the scope feature of the IDE.
+
+The scope is instantiated at the top of the file via `Scope scope;`
+
+In `setup()` we define how many channels the scope should have and the sample 
+rate that it should run at via `scope.setup(3, context->audioSampleRate)`.
+
+In `render()` we choose what the scope log via `scope.log(out, out2, out3)`. 
+In this example the scope is logging three sine waves with different phases. To see
+the output click on the <b>Open Scope</b> button.
+
+An additional option is to set the trigger of the oscilloscope from within `render()`.
+In this example we are triggering the scope when oscillator 1 becomes less than 
+oscillator 2 via `scope.trigger()`. Note that this functionality only takes effect
+when the triggering mode is set to custom in the scope UI.
+*/
+
 #include <Bela.h>
 #include <Scope.h>
 #include <cmath>
Binary file libNE10.a has changed