changeset 269:ac8eb07afcf5

Oxygen text added to each render.cpp file for the default projects. Text includes project explanation from Wiki, edited in places. Empty project added as a default project. Doxyfile updated. Each of the project locations added to INPUT configuration option. Consider just watching the whole project file so all new projects are automatically pulled through.
author Robert Jack <robert.h.jack@gmail.com>
date Tue, 17 May 2016 15:40:16 +0100
parents 381f352c44eb
children 7bfb25a2e158 cb9a80040150
files Doxyfile projects/analogDigitalDemo/render.cpp projects/audio_in_FFT/render.cpp projects/basic/render.cpp projects/basic_FFT_phase_vocoder/render.cpp projects/basic_analog_input/render.cpp projects/basic_analog_output/render.cpp projects/basic_blink/render.cpp projects/basic_button/render.cpp projects/basic_network/render.cpp projects/basic_passthru/render.cpp projects/empty_project/main.cpp projects/empty_project/render.cpp projects/oscillator_bank/render.cpp projects/samples/render.cpp
diffstat 15 files changed, 595 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/Doxyfile	Wed May 11 10:29:23 2016 +0100
+++ b/Doxyfile	Tue May 17 15:40:16 2016 +0100
@@ -648,7 +648,7 @@
 # directories like "/usr/src/myproject". Separate the files or directories
 # with spaces.
 
-INPUT                  =	include/BeagleRT.h include/Utilities.h include/digital_gpio_mapping.h include/PulseIn.h include/Scope.h include/Midi.h include/UdpClient.h include/WriteFile.h
+INPUT                  =	include/BeagleRT.h include/Utilities.h include/digital_gpio_mapping.h include/PulseIn.h include/Scope.h include/Midi.h include/UdpClient.h include/WriteFile.h projects/basic/render.cpp projects/basic_analog_input/render.cpp projects/basic_passthru/render.cpp projects/basic_blink/render.cpp projects/basic_button/render.cpp projects/basic_analog_output/render.cpp projects/samples/render.cpp projects/audio_in_FFT/render.cpp projects/basic_FFT_phase_vocoder/render.cpp projects/oscillator_bank/render.cpp projects/empty_project/render.cpp projects/analogDigitalDemo/render.cpp projects/basic_network/render.cpp
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
@@ -715,7 +715,7 @@
 # and *.h) to filter out the source-files in the directories. If left
 # blank all files are included.
 
-EXAMPLE_PATTERNS       =
+EXAMPLE_PATTERNS       = 
 
 # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
 # searched for input files to be used with the \include or \dontinclude
--- a/projects/analogDigitalDemo/render.cpp	Wed May 11 10:29:23 2016 +0100
+++ b/projects/analogDigitalDemo/render.cpp	Tue May 17 15:40:16 2016 +0100
@@ -1,9 +1,35 @@
-    /*
+/*
+ ____  _____ _        _    
+| __ )| ____| |      / \   
+|  _ \|  _| | |     / _ \  
+| |_) | |___| |___ / ___ \ 
+|____/|_____|_____/_/   \_\.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 <BeagleRT.h>
 #include <Utilities.h>
 #include <cmath>
--- a/projects/audio_in_FFT/render.cpp	Wed May 11 10:29:23 2016 +0100
+++ b/projects/audio_in_FFT/render.cpp	Tue May 17 15:40:16 2016 +0100
@@ -1,3 +1,12 @@
+/*
+ ____  _____ _        _    
+| __ )| ____| |      / \   
+|  _ \|  _| | |     / _ \  
+| |_) | |___| |___ / ___ \ 
+|____/|_____|_____/_/   \_\.io
+
+ */
+
 /*
  * render.cpp
  *
@@ -5,6 +14,31 @@
  *      Author: parallels
  */
 
+/**
+\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 <BeagleRT.h>
 #include <rtdk.h>
--- a/projects/basic/render.cpp	Wed May 11 10:29:23 2016 +0100
+++ b/projects/basic/render.cpp	Tue May 17 15:40:16 2016 +0100
@@ -1,3 +1,12 @@
+/*
+ ____  _____ _        _    
+| __ )| ____| |      / \   
+|  _ \|  _| | |     / _ \  
+| |_) | |___| |___ / ___ \ 
+|____/|_____|_____/_/   \_\.io
+
+ */
+
 /*
  * render.cpp
  *
@@ -5,6 +14,26 @@
  *      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.
+
+The important thing to notice is the nested `for` loop structure. You will see 
+this in all Bela projects and in most digital audio applications. The first `for`
+loop cycles through the audio frames, the second through each of the audio
+channels (in this case left 0 and right 1). It is good to familiarise yourself
+with this structure as it is fundamental to producing sound with the system.
+*/
+
 
 #include <BeagleRT.h>
 #include <cmath>
@@ -22,7 +51,6 @@
 // in from the call to initAudio().
 //
 // Return true on success; returning false halts the program.
-
 bool setup(BeagleRTContext *context, void *userData)
 {
 	// Retrieve a parameter passed in from the initAudio() call
--- a/projects/basic_FFT_phase_vocoder/render.cpp	Wed May 11 10:29:23 2016 +0100
+++ b/projects/basic_FFT_phase_vocoder/render.cpp	Tue May 17 15:40:16 2016 +0100
@@ -1,3 +1,12 @@
+/*
+ ____  _____ _        _    
+| __ )| ____| |      / \   
+|  _ \|  _| | |     / _ \  
+| |_) | |___| |___ / ___ \ 
+|____/|_____|_____/_/   \_\.io
+
+ */
+
 /*
  * render.cpp
  *
@@ -5,6 +14,19 @@
  *      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 <BeagleRT.h>
 #include <rtdk.h>
--- a/projects/basic_analog_input/render.cpp	Wed May 11 10:29:23 2016 +0100
+++ b/projects/basic_analog_input/render.cpp	Tue May 17 15:40:16 2016 +0100
@@ -1,3 +1,12 @@
+/*
+ ____  _____ _        _    
+| __ )| ____| |      / \   
+|  _ \|  _| | |     / _ \  
+| |_) | |___| |___ / ___ \ 
+|____/|_____|_____/_/   \_\.io
+
+ */
+
 /*
  * render.cpp
  *
@@ -5,6 +14,30 @@
  *      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, a potentiometer).
+
+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 <BeagleRT.h>
 #include <Utilities.h>
@@ -31,6 +64,7 @@
 //
 // Return true on success; returning false halts the program.
 
+
 bool setup(BeagleRTContext *context, void *userData)
 {
 	if(context->analogFrames == 0 || context->analogFrames > context->audioFrames) {
--- a/projects/basic_analog_output/render.cpp	Wed May 11 10:29:23 2016 +0100
+++ b/projects/basic_analog_output/render.cpp	Tue May 17 15:40:16 2016 +0100
@@ -1,10 +1,48 @@
 /*
- * render.cpp
+ ____  _____ _        _    
+| __ )| ____| |      / \   
+|  _ \|  _| | |     / _ \  
+| |_) | |___| |___ / ___ \ 
+|____/|_____|_____/_/   \_\.io
+
+ */
+
+/*
  *
- *  Created on: Oct 24, 2014
- *      Author: parallels
+ * 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.
+
+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 `analogWriteFrame` within the `for` loop that 
+cycles through the analog output channels. This needs to be provided with 
+arguments as follows `analogWriteFrame(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 <BeagleRT.h>
 #include <Utilities.h>
--- a/projects/basic_blink/render.cpp	Wed May 11 10:29:23 2016 +0100
+++ b/projects/basic_blink/render.cpp	Tue May 17 15:40:16 2016 +0100
@@ -1,3 +1,46 @@
+/*
+ ____  _____ _        _    
+| __ )| ____| |      / \   
+|  _ \|  _| | |     / _ \  
+| |_) | |___| |___ / ___ \ 
+|____/|_____|_____/_/   \_\.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 (set it in the 
+`render()` function).
+
+Firstly the pin mode must be set to output mode: 
+`pinModeFrame(context, 0, P8_07, OUTPUT);` in the `setup()` function. The output 
+of the digital pins is set by the following code: 
+`digitalWriteFrame(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 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 <BeagleRT.h>
 #include <Utilities.h>
 #include <cmath>
--- a/projects/basic_button/render.cpp	Wed May 11 10:29:23 2016 +0100
+++ b/projects/basic_button/render.cpp	Tue May 17 15:40:16 2016 +0100
@@ -1,9 +1,43 @@
+/*
+ ____  _____ _        _    
+| __ )| ____| |      / \   
+|  _ \|  _| | |     / _ \  
+| |_) | |___| |___ / ___ \ 
+|____/|_____|_____/_/   \_\.io
+
+ */
+
 /*
  *
  * Andrew McPherson and Victor Zappi
  * Queen Mary, University of London
  */
 
+/**
+\example 2_digital_button
+
+Switching an LED on and off
+---------------------------
+
+This sketch brings together digital out with digital in. 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 <BeagleRT.h>
 #include <Utilities.h>
 #include <cmath>
--- a/projects/basic_network/render.cpp	Wed May 11 10:29:23 2016 +0100
+++ b/projects/basic_network/render.cpp	Tue May 17 15:40:16 2016 +0100
@@ -1,3 +1,12 @@
+/*
+ ____  _____ _        _    
+| __ )| ____| |      / \   
+|  _ \|  _| | |     / _ \  
+| |_) | |___| |___ / ___ \ 
+|____/|_____|_____/_/   \_\.io
+
+*/
+
 /*
  * render.cpp
  *
@@ -5,6 +14,20 @@
  *      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 <BeagleRT.h>
 //#include <rtdk.h>
 #include <cmath>
--- a/projects/basic_passthru/render.cpp	Wed May 11 10:29:23 2016 +0100
+++ b/projects/basic_passthru/render.cpp	Tue May 17 15:40:16 2016 +0100
@@ -1,10 +1,50 @@
 /*
+ ____  _____ _        _    
+| __ )| ____| |      / \   
+|  _ \|  _| | |     / _ \  
+| |_) | |___| |___ / ___ \ 
+|____/|_____|_____/_/   \_\.io
+
+ */
+
+ /*
  * render.cpp
  *
  *  Created on: Oct 24, 2014
  *      Author: parallels
  */
 
+/**
+\example 1_basic_audio_passthrough
+
+Audio passthrough: input to output
+-----------------------------------------
+
+This sketch demonstrates the simplest possible case of using audio: it passes 
+audio input straight to audio output.
+
+Note the nested `for` loop structure. You will see this in all Bela projects. The 
+first `for` loop cycles through the audio frames, the second through each of the 
+audio channels (in this case left 0 and right 1).
+
+
+We write samples to the audio output buffer like this: 
+`context->audioOut[n * context->audioChannels + ch]` where `n` is the current audio 
+frame and `ch` is the current channel, both provided by the nested for loop structure.
+
+We can access samples in the audio input buffer in a similar way, like this: 
+`context->audioIn[n * context->audioChannels + ch]`.
+
+So a simple audio pass through is achieved by setting output buffer equal to 
+input buffer: 
+`context->audioOut[n * context->audioChannels + ch] = context->audioIn[n * context->audioChannels + ch]`.
+
+
+*/
+
+
+
+
 
 #include <BeagleRT.h>
 #include <Utilities.h>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/empty_project/main.cpp	Tue May 17 15:40:16 2016 +0100
@@ -0,0 +1,96 @@
+/*
+ * default_main.cpp
+ *
+ *  Created on: Oct 24, 2014
+ *      Author: parallels
+ */
+//#include <unistd.h>
+#include <iostream>
+#include <cstdlib>
+#include <libgen.h>
+#include <signal.h>
+#include <getopt.h>
+#include "../include/BeagleRT.h"
+
+using namespace std;
+
+int returnCode = 0;
+
+// Handle Ctrl-C by requesting that the audio rendering stop
+void interrupt_handler(int var)
+{
+	gShouldStop = true;
+	// allows other process to monitor why beagleRT has exited
+	// var=15, returnCode = 143 if terminated with SIGTERM
+	returnCode = var + 128;
+}
+
+// Print usage information
+void usage(const char * processName)
+{
+	cerr << "Usage: " << processName << " [options]" << endl;
+
+	BeagleRT_usage();
+
+	cerr << "   --help [-h]:                Print this menu\n";
+}
+
+int main(int argc, char *argv[])
+{
+	BeagleRTInitSettings settings;	// Standard audio settings
+
+	struct option customOptions[] =
+	{
+		{"help", 0, NULL, 'h'},
+		{NULL, 0, NULL, 0}
+	};
+
+	// Set default settings
+	BeagleRT_defaultSettings(&settings);
+
+	// Parse command-line arguments
+	while (1) {
+		int c;
+		if ((c = BeagleRT_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(BeagleRT_initAudio(&settings, 0) != 0) {
+		cout << "Error: unable to initialise audio" << endl;
+		return -1;
+	}
+
+	// Start the audio device running
+	if(BeagleRT_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
+	BeagleRT_stopAudio();
+
+	// Clean up any resources allocated for audio
+	BeagleRT_cleanupAudio();
+
+	// All done!
+	return returnCode;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/empty_project/render.cpp	Tue May 17 15:40:16 2016 +0100
@@ -0,0 +1,112 @@
+/*
+ ____  _____ _        _    
+| __ )| ____| |      / \   
+|  _ \|  _| | |     / _ \  
+| |_) | |___| |___ / ___ \ 
+|____/|_____|_____/_/   \_\.io
+
+*/
+
+/**
+\example 1_empty_project
+
+The bare bones
+----------------------
+
+The structure of a render.cpp file
+----------------------------------
+A render.cpp file has three functions: `setup()`, `render()` and `cleanup()`.
+
+`setup()` is an initialisation function which runs before audio rendering begins. 
+It is called once when the project starts. Use it to prepare any memory or 
+resources that will be needed in `render()`.
+
+`render()` is a function that is regularly called, over and over continuously, at 
+the highest priority by the audio engine. It is used to process audio and 
+sensor data. This function is called regularly by the system every time there 
+is a new block of audio and/or sensor data to process.
+
+`cleanup()` is a function that is called when the program stops, to finish up any 
+processes that might still be running.
+
+Here we will briefly explain each function and the structure of the render.cpp 
+
+Before any of the functions
+---------------------------
+At the top of the file, include any libraries you might need.
+
+Additionally, declare any global variables. In these tutorial sketches, all 
+global variables are preceded by a `g` so we always know which variables are 
+global - `gSampleData`, for example. It's not mandatory but is a really good way 
+of keeping track of what's global and what's not.
+
+Sometimes it's necessary to access a variable from another file, such as 
+main.cpp. In this case, precede this variable with the keyword `extern`.
+
+Function arguments
+------------------
+`setup()`, `render()` and `cleanup()` each take the same arguments. These are:
+
+`0ext *context`
+`void *userData`
+
+These arguments are pointers to data structures. The main one that's used is 
+`context`, which is a pointer to a data structure containing lots of information 
+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. 
+`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).
+
+Note that `audioIn`, `audioOut`, `analogIn`, `analogOut` are all arrays (buffers).
+
+*/
+
+
+
+
+#include <BeagleRT.h>
+#include <Utilities.h>
+#include <rtdk.h>
+#include <cmath>
+
+// setup() is called once before the audio rendering starts.
+// Use it to perform any initialisation and allocation which is dependent
+// on the period size or sample rate.
+//
+// userData holds an opaque pointer to a data structure that was passed
+// in from the call to initAudio().
+//
+// Return true on success; returning false halts the program.
+
+bool setup(BeagleRTContext *context, void *userData)
+{
+
+	return true;
+}
+
+// render() is called regularly at the highest priority by the audio engine.
+// Input and output are given from the audio hardware and the other
+// ADCs and DACs (if available). If only audio is available, numMatrixFrames
+// will be 0.
+
+void render(BeagleRTContext *context, void *userData)
+{
+
+}
+
+// cleanup() is called once at the end, after the audio has stopped.
+// Release any resources that were allocated in setup().
+
+void cleanup(BeagleRTContext *context, void *userData)
+{
+
+}
--- a/projects/oscillator_bank/render.cpp	Wed May 11 10:29:23 2016 +0100
+++ b/projects/oscillator_bank/render.cpp	Tue May 17 15:40:16 2016 +0100
@@ -1,3 +1,12 @@
+/*
+ ____  _____ _        _    
+| __ )| ____| |      / \   
+|  _ \|  _| | |     / _ \  
+| |_) | |___| |___ / ___ \ 
+|____/|_____|_____/_/   \_\.io
+
+ */
+
 /*
  * render.cpp
  *
@@ -5,6 +14,18 @@
  *      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 <BeagleRT.h>
 #include <Utilities.h>
--- a/projects/samples/render.cpp	Wed May 11 10:29:23 2016 +0100
+++ b/projects/samples/render.cpp	Tue May 17 15:40:16 2016 +0100
@@ -1,10 +1,44 @@
 /*
- * render.cpp
+ ____  _____ _        _    
+| __ )| ____| |      / \   
+|  _ \|  _| | |     / _ \  
+| |_) | |___| |___ / ___ \ 
+|____/|_____|_____/_/   \_\.io
+
+ */
+
+/*
  *
- *  Created on: Oct 24, 2014
- *      Author: Andrew McPherson and Victor Zappi
+ * 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)`;
+
+Edit
+
+*/
+
+
 
 #include <BeagleRT.h>
 #include <cmath>