# HG changeset patch # User Giulio Moro # Date 1466776512 -3600 # Node ID 5d954690a7c19f700cc1b5f40eeed0a6c7346f20 # Parent a2096488a21ac7188d1f0f5477ba4cb855722378# Parent ff0e9e827dcd412e7af2c366a64c4d611b561b51 merge diff -r ff0e9e827dcd -r 5d954690a7c1 examples/01-Basics/minimal/render.cpp --- a/examples/01-Basics/minimal/render.cpp Fri Jun 24 12:42:48 2016 +0100 +++ b/examples/01-Basics/minimal/render.cpp Fri Jun 24 14:55:12 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). diff -r ff0e9e827dcd -r 5d954690a7c1 examples/01-Basics/passthrough/main.cpp --- a/examples/01-Basics/passthrough/main.cpp Fri Jun 24 12:42:48 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 -#include -#include -#include -#include -#include - -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; -} diff -r ff0e9e827dcd -r 5d954690a7c1 examples/01-Basics/passthrough/render.cpp --- a/examples/01-Basics/passthrough/render.cpp Fri Jun 24 12:42:48 2016 +0100 +++ b/examples/01-Basics/passthrough/render.cpp Fri Jun 24 14:55:12 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]`. */ diff -r ff0e9e827dcd -r 5d954690a7c1 examples/01-Basics/sinetone/main.cpp --- a/examples/01-Basics/sinetone/main.cpp Fri Jun 24 12:42:48 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 -#include -#include -#include -#include -#include -#include - -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; -} diff -r ff0e9e827dcd -r 5d954690a7c1 examples/01-Basics/sinetone/render.cpp --- a/examples/01-Basics/sinetone/render.cpp Fri Jun 24 12:42:48 2016 +0100 +++ b/examples/01-Basics/sinetone/render.cpp Fri Jun 24 14:55:12 2016 +0100 @@ -30,10 +30,6 @@ 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; @@ -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); diff -r ff0e9e827dcd -r 5d954690a7c1 examples/02-Digital/digital-input/render.cpp --- a/examples/02-Digital/digital-input/render.cpp Fri Jun 24 12:42:48 2016 +0100 +++ b/examples/02-Digital/digital-input/render.cpp Fri Jun 24 14:55:12 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. */ diff -r ff0e9e827dcd -r 5d954690a7c1 examples/02-Digital/digital-output/render.cpp --- a/examples/02-Digital/digital-output/render.cpp Fri Jun 24 12:42:48 2016 +0100 +++ b/examples/02-Digital/digital-output/render.cpp Fri Jun 24 14:55:12 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 diff -r ff0e9e827dcd -r 5d954690a7c1 examples/02-Digital/level-meter/render.cpp --- a/examples/02-Digital/level-meter/render.cpp Fri Jun 24 12:42:48 2016 +0100 +++ b/examples/02-Digital/level-meter/render.cpp Fri Jun 24 14:55:12 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) diff -r ff0e9e827dcd -r 5d954690a7c1 examples/03-Analog/analog-input/main.cpp --- a/examples/03-Analog/analog-input/main.cpp Fri Jun 24 12:42:48 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,133 +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 -#include -#include -#include -#include -#include - -using namespace std; - -int gSensorInputFrequency = 0; -int gSensorInputAmplitude = 1; - -// 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] input: Choose the analog input controlling frequency (0-7; default 0)\n"; - cerr << " --amplitude [-a] input: Choose the analog input controlling amplitude (0-7; default 1)\n"; - 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'}, - {"frequency", 1, NULL, 'f'}, - {"amplitude", 1, NULL, 'a'}, - {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:a:", customOptions, &settings)) < 0) - break; - switch (c) { - case 'h': - usage(basename(argv[0])); - exit(0); - case 'f': - gSensorInputFrequency = atoi(optarg); - if(gSensorInputFrequency < 0 || gSensorInputFrequency > 7) { - usage(basename(argv[0])); - exit(0); - } - break; - case 'a': - gSensorInputAmplitude = atoi(optarg); - if(gSensorInputAmplitude < 0 || gSensorInputAmplitude > 7) { - usage(basename(argv[0])); - exit(0); - } - break; - 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; - } - - if(settings.verbose) { - cout << "--> Frequency on input " << gSensorInputFrequency << endl; - cout << "--> Amplitude on input " << gSensorInputAmplitude << endl; - } - - // 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; -} diff -r ff0e9e827dcd -r 5d954690a7c1 examples/03-Analog/analog-input/render.cpp --- a/examples/03-Analog/analog-input/render.cpp Fri Jun 24 12:42:48 2016 +0100 +++ b/examples/03-Analog/analog-input/render.cpp Fri Jun 24 14:55:12 2016 +0100 @@ -23,27 +23,33 @@ #include -#include #include float gPhase; float gInverseSampleRate; int gAudioFramesPerAnalogFrame; -// These settings are carried over from main.cpp -// Setting global variables is an alternative approach -// to passing a structure to userData in setup() - -extern int gSensorInputFrequency; -extern int gSensorInputAmplitude; +// Set the analog channels to read from +int gSensorInputFrequency = 0; +int gSensorInputAmplitude = 1; bool setup(BelaContext *context, void *userData) { + + // Check if analog channels are enabled if(context->analogFrames == 0 || context->analogFrames > context->audioFrames) { rt_printf("Error: this example needs analog enabled, with 4 or 8 channels\n"); return false; } + // Check that we have the same number of inputs and outputs. + 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; + } + + // Useful calculations gAudioFramesPerAnalogFrame = context->audioFrames / context->analogFrames; gInverseSampleRate = 1.0 / context->audioSampleRate; gPhase = 0.0; @@ -61,16 +67,18 @@ for(unsigned int n = 0; n < context->audioFrames; n++) { if(!(n % gAudioFramesPerAnalogFrame)) { - // Even audio samples: update frequency and amplitude from the matrix + // On even audio samples: read analog inputs and update frequency and amplitude frequency = map(analogRead(context, n/gAudioFramesPerAnalogFrame, gSensorInputFrequency), 0, 1, 100, 1000); amplitude = analogRead(context, n/gAudioFramesPerAnalogFrame, gSensorInputAmplitude); } float out = amplitude * sinf(gPhase); - for(unsigned int channel = 0; channel < context->audioOutChannels; channel++) - context->audioOut[n * context->audioChannels + channel] = out; + for(unsigned int channel = 0; channel < context->audioOutChannels; channel++) { + audioWrite(context, n, channel, out); + } + // Update and wrap phase of sine tone gPhase += 2.0 * M_PI * frequency * gInverseSampleRate; if(gPhase > 2.0 * M_PI) gPhase -= 2.0 * M_PI; @@ -90,10 +98,10 @@ ------------------------- 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()`. +modulated by data received on the analog input pins. Before looping through each audio +frame, we declare a value for the `frequency` and `amplitude` of our sine tone; +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. @@ -113,8 +121,4 @@ } ```` -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! */ diff -r ff0e9e827dcd -r 5d954690a7c1 examples/03-Analog/analog-output/main.cpp --- a/examples/03-Analog/analog-output/main.cpp Fri Jun 24 12:42:48 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,121 +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 -#include -#include -#include -#include -#include - -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 LED fade (default: 1.0)\n"; - cerr << " --help [-h]: Print this menu\n"; -} - -int main(int argc, char *argv[]) -{ - BelaInitSettings settings; // Standard audio settings - float frequency = 1.0; // Frequency of LED fades - - struct option customOptions[] = - { - {"help", 0, NULL, 'h'}, - {"frequency", 1, NULL, 'f'}, - {NULL, 0, NULL, 0} - }; - - // Set default settings - Bela_defaultSettings(&settings); - - // In this example, audio isn't used so might as well leave speaker muted - settings.beginMuted = 1; - - // 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); - if(frequency < 0) - frequency = 0; - if(frequency > 11025.0) - frequency = 11025.0; - 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; -} diff -r ff0e9e827dcd -r 5d954690a7c1 examples/03-Analog/analog-output/render.cpp --- a/examples/03-Analog/analog-output/render.cpp Fri Jun 24 12:42:48 2016 +0100 +++ b/examples/03-Analog/analog-output/render.cpp Fri Jun 24 14:55:12 2016 +0100 @@ -23,24 +23,29 @@ #include -#include #include // Set range for analog outputs designed for driving LEDs const float kMinimumAmplitude = (1.5 / 5.0); const float kAmplitudeRange = 1.0 - kMinimumAmplitude; -float gFrequency; +float gFrequency = 3.0; float gPhase; float gInverseSampleRate; bool setup(BelaContext *context, void *userData) { - // Retrieve a parameter passed in from the initAudio() call - gFrequency = *(float *)userData; - if(context->analogFrames == 0) { - rt_printf("Error: this example needs the matrix enabled\n"); + // Check if analog channels are enabled + if(context->analogFrames == 0 || context->analogFrames > context->audioFrames) { + rt_printf("Error: this example needs analog enabled, with 4 or 8 channels\n"); + return false; + } + + // Check that we have the same number of inputs and outputs. + 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; } @@ -55,7 +60,7 @@ for(unsigned int n = 0; n < context->analogFrames; n++) { // Set LED to different phase for each matrix channel float relativePhase = 0.0; - for(unsigned int channel = 0; channel < context->analogChannels; channel++) { + for(unsigned int channel = 0; channel < context->analogOutChannels; channel++) { float out = kMinimumAmplitude + kAmplitudeRange * 0.5f * (1.0f + sinf(gPhase + relativePhase)); analogWrite(context, n, channel, out); @@ -64,6 +69,7 @@ relativePhase += M_PI * 0.25; } + // Update and wrap phase of sine tone gPhase += 2.0 * M_PI * gFrequency * gInverseSampleRate; if(gPhase > 2.0 * M_PI) gPhase -= 2.0 * M_PI; @@ -99,7 +105,7 @@ 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). +desired output (in this case set by the sine wave) and `n` is the frame number. 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 diff -r ff0e9e827dcd -r 5d954690a7c1 examples/03-Analog/scope-analog/render.cpp --- a/examples/03-Analog/scope-analog/render.cpp Fri Jun 24 12:42:48 2016 +0100 +++ b/examples/03-Analog/scope-analog/render.cpp Fri Jun 24 14:55:12 2016 +0100 @@ -37,6 +37,19 @@ // setup the scope with 3 channels at the audio sample rate scope.setup(3, context->audioSampleRate); + // Check if analog channels are enabled + if(context->analogFrames == 0 || context->analogFrames > context->audioFrames) { + rt_printf("Error: this example needs analog enabled, with 4 or 8 channels\n"); + return false; + } + + // Check that we have the same number of inputs and outputs. + 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; + } + gInverseSampleRate = 1.0 / context->audioSampleRate; gPhase = 0.0; @@ -66,8 +79,10 @@ scope.log(out, in1, in2); // pass the sine wave to the audio outputs - for(unsigned int channel = 0; channel < context->audioChannels; channel++) - context->audioOut[n * context->audioChannels + channel] = out; + for(unsigned int channel = 0; channel < context->audioOutChannels; channel++) { + audioWrite(context, n, channel, out); + } + } } @@ -81,10 +96,10 @@ /** \example scope-analog/render.cpp -Connecting potentiometers +Scoping sensor input ------------------------- -This example reads from analogue inputs 0 and 1 via `analogReadFrame()` and +This example reads from analogue inputs 0 and 1 via `analogRead()` 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 @@ -92,7 +107,21 @@ 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. +frequency of the sine wave change. You can also see the two sensor readings plotted +on the oscilloscope. + +The scope is initialised in `setup()` where the number of channels and sampling rate +are set. + +````` +scope.setup(3, context->audioSampleRate); +````` + +We can then pass signals to the scope in `render()` using: + +`````` +scope.log(out, in1, in2); +`````` 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 diff -r ff0e9e827dcd -r 5d954690a7c1 examples/04-Audio/FFT-audio-in/render.cpp --- a/examples/04-Audio/FFT-audio-in/render.cpp Fri Jun 24 12:42:48 2016 +0100 +++ b/examples/04-Audio/FFT-audio-in/render.cpp Fri Jun 24 14:55:12 2016 +0100 @@ -40,6 +40,14 @@ bool setup(BelaContext *context, void *userData) { + + // Check that we have the same number of inputs and outputs. + 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; + } + // Retrieve a parameter passed in from the initAudio() call gFFTSize = *(int *)userData; @@ -56,8 +64,8 @@ void render(BelaContext *context, void *userData) { for(unsigned int n = 0; n < context->audioFrames; n++) { - timeDomainIn[gReadPointer].r = (ne10_float32_t) ((context->audioIn[n*context->audioChannels] + - context->audioIn[n*context->audioChannels+1]) * 0.5); + timeDomainIn[gReadPointer].r = (ne10_float32_t) ((context->audioIn[n*context->audioInChannels] + + context->audioIn[n*context->audioOutChannels+1]) * 0.5); timeDomainIn[gReadPointer].i = 0; if(++gReadPointer >= gFFTSize) @@ -74,8 +82,8 @@ gWritePointer = 0; } - for(unsigned int channel = 0; channel < context->audioChannels; channel++) - context->audioOut[n * context->audioChannels + channel] = (float) timeDomainOut[gWritePointer].r; + for(unsigned int channel = 0; channel < context->audioOutChannels; channel++) + context->audioOut[n * context->audioOutChannels + channel] = (float) timeDomainOut[gWritePointer].r; gWritePointer++; } } diff -r ff0e9e827dcd -r 5d954690a7c1 examples/04-Audio/FFT-phase-vocoder/render.cpp --- a/examples/04-Audio/FFT-phase-vocoder/render.cpp Fri Jun 24 12:42:48 2016 +0100 +++ b/examples/04-Audio/FFT-phase-vocoder/render.cpp Fri Jun 24 14:55:12 2016 +0100 @@ -121,6 +121,13 @@ // Return true on success; returning false halts the program. bool setup(BelaContext* context, void* userData) { + // Check that we have the same number of inputs and outputs. + 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; + } + midi.readFrom(0); midi.setParserCallback(midiCallback); // Retrieve a parameter passed in from the initAudio() call @@ -138,7 +145,7 @@ memset(gOutputBuffer, 0, BUFFER_SIZE * sizeof(float)); // Allocate buffer to mirror and modify the input - gInputAudio = (float *)malloc(context->audioFrames * context->audioChannels * sizeof(float)); + gInputAudio = (float *)malloc(context->audioFrames * context->audioOutChannels * sizeof(float)); if(gInputAudio == 0) return false; @@ -232,7 +239,7 @@ { float* audioOut = context->audioOut; int numAudioFrames = context->audioFrames; - int numAudioChannels = context->audioChannels; + int numAudioChannels = context->audioOutChannels; // ------ this code internal to the demo; leave as is ---------------- // Prep the "input" to be the sound file played in a loop diff -r ff0e9e827dcd -r 5d954690a7c1 examples/04-Audio/bucket-brigade-chorus/render.cpp --- a/examples/04-Audio/bucket-brigade-chorus/render.cpp Fri Jun 24 12:42:48 2016 +0100 +++ b/examples/04-Audio/bucket-brigade-chorus/render.cpp Fri Jun 24 14:55:12 2016 +0100 @@ -64,6 +64,13 @@ bool setup(BelaContext *context, void *userData) { + // Check that we have the same number of inputs and outputs. + 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; + } + gInverseSampleRate = 1.0/context->audioSampleRate; gPhase1 = 0.0; diff -r ff0e9e827dcd -r 5d954690a7c1 examples/04-Audio/filter-FIR/main.cpp --- a/examples/04-Audio/filter-FIR/main.cpp Fri Jun 24 12:42:48 2016 +0100 +++ b/examples/04-Audio/filter-FIR/main.cpp Fri Jun 24 14:55:12 2016 +0100 @@ -145,7 +145,7 @@ } if(fileName.empty()){ - fileName = "filter/longsample.wav"; + fileName = "longsample.wav"; } if(settings.verbose) { diff -r ff0e9e827dcd -r 5d954690a7c1 examples/04-Audio/filter-FIR/render.cpp --- a/examples/04-Audio/filter-FIR/render.cpp Fri Jun 24 12:42:48 2016 +0100 +++ b/examples/04-Audio/filter-FIR/render.cpp Fri Jun 24 14:55:12 2016 +0100 @@ -51,6 +51,13 @@ bool setup(BelaContext *context, void *userData) { + // Check that we have the same number of inputs and outputs. + 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; + } + // Retrieve a parameter passed in from the initAudio() call gSampleData = *(SampleData *)userData; @@ -83,8 +90,8 @@ ne10_fir_float_neon(&gFIRfilter, gFIRfilterIn, gFIRfilterOut, blockSize); for(unsigned int n = 0; n < context->audioFrames; n++) { - for(unsigned int channel = 0; channel < context->audioChannels; channel++) - context->audioOut[n * context->audioChannels + channel] = gFIRfilterOut[n]; // ...and put it in both left and right channel + for(unsigned int channel = 0; channel < context->audioOutChannels; channel++) + context->audioOut[n * context->audioOutChannels + channel] = gFIRfilterOut[n]; // ...and put it in both left and right channel } diff -r ff0e9e827dcd -r 5d954690a7c1 examples/04-Audio/filter-IIR/main.cpp --- a/examples/04-Audio/filter-IIR/main.cpp Fri Jun 24 12:42:48 2016 +0100 +++ b/examples/04-Audio/filter-IIR/main.cpp Fri Jun 24 14:55:12 2016 +0100 @@ -151,7 +151,7 @@ } if(fileName.empty()){ - fileName = "filter/longsample.wav"; + fileName = "longsample.wav"; } if(settings.verbose) { diff -r ff0e9e827dcd -r 5d954690a7c1 examples/04-Audio/filter-IIR/render.cpp --- a/examples/04-Audio/filter-IIR/render.cpp Fri Jun 24 12:42:48 2016 +0100 +++ b/examples/04-Audio/filter-IIR/render.cpp Fri Jun 24 14:55:12 2016 +0100 @@ -63,6 +63,13 @@ bool setup(BelaContext *context, void *userData) { + // Check that we have the same number of inputs and outputs. + 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; + } + // Retrieve a parameter passed in from the initAudio() call gSampleData = *(SampleData *)userData; @@ -97,8 +104,8 @@ gLastY[1] = gLastY[0]; gLastY[0] = out; - for(unsigned int channel = 0; channel < context->audioChannels; channel++) - context->audioOut[n * context->audioChannels + channel] = out; // ...and put it in both left and right channel + for(unsigned int channel = 0; channel < context->audioOutChannels; channel++) + context->audioOut[n * context->audioOutChannels + channel] = out; // ...and put it in both left and right channel } diff -r ff0e9e827dcd -r 5d954690a7c1 examples/04-Audio/measure-noisefloor/render.cpp --- a/examples/04-Audio/measure-noisefloor/render.cpp Fri Jun 24 12:42:48 2016 +0100 +++ b/examples/04-Audio/measure-noisefloor/render.cpp Fri Jun 24 14:55:12 2016 +0100 @@ -49,6 +49,14 @@ bool setup(BelaContext *context, void *userData) { + + // Check that we have the same number of inputs and outputs. + 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; + } + // Clear the filter data structures for(int i = 0; i < 10; i++) { gReadBufferPointers[i] = gWriteBufferPointers[i] = 0; @@ -78,10 +86,10 @@ for(unsigned int n = 0; n < context->audioFrames; n++) { // Store audio inputs in buffer - for(unsigned int ch = 0; ch < context->audioChannels; ch++) { + for(unsigned int ch = 0; ch < context->audioOutChannels; ch++) { if(gWriteBufferPointers[ch] < gBufferSize) { gWriteBuffers[ch][gWriteBufferPointers[ch]] = - context->audioIn[n * context->audioChannels + ch]; + context->audioIn[n * context->audioOutChannels + ch]; gWriteBufferPointers[ch]++; if(gWriteBufferPointers[ch] >= gBufferSize) bufferIsFull = true; @@ -89,13 +97,13 @@ } } - if(context->analogChannels != 0) { + if(context->analogOutChannels != 0) { for(unsigned int n = 0; n < context->analogFrames; n++) { // Store analog inputs in buffer, starting at channel 2 - for(unsigned int ch = 0; ch < context->analogChannels; ch++) { + for(unsigned int ch = 0; ch < context->analogOutChannels; ch++) { if(gWriteBufferPointers[ch + 2] < gBufferSize) { gWriteBuffers[ch + 2][gWriteBufferPointers[ch + 2]] = - context->analogIn[n * context->analogChannels + ch]; + context->analogIn[n * context->analogOutChannels + ch]; gWriteBufferPointers[ch + 2]++; if(gWriteBufferPointers[ch + 2] >= gBufferSize) bufferIsFull = true; @@ -103,7 +111,7 @@ // Set all analog outputs to halfway point so they can be more // easily measured for noise - context->analogOut[n * context->analogChannels + ch] = 0.5; + context->analogOut[n * context->analogOutChannels + ch] = 0.5; } } } diff -r ff0e9e827dcd -r 5d954690a7c1 examples/04-Audio/oscillator-bank/render.cpp --- a/examples/04-Audio/oscillator-bank/render.cpp Fri Jun 24 12:42:48 2016 +0100 +++ b/examples/04-Audio/oscillator-bank/render.cpp Fri Jun 24 14:55:12 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; } diff -r ff0e9e827dcd -r 5d954690a7c1 examples/04-Audio/samples/main.cpp --- a/examples/04-Audio/samples/main.cpp Fri Jun 24 12:42:48 2016 +0100 +++ b/examples/04-Audio/samples/main.cpp Fri Jun 24 14:55:12 2016 +0100 @@ -145,7 +145,7 @@ } if(fileName.empty()){ - fileName = "samples/sample.wav"; + fileName = "sample.wav"; } if(settings.verbose) { diff -r ff0e9e827dcd -r 5d954690a7c1 examples/04-Audio/samples/render.cpp --- a/examples/04-Audio/samples/render.cpp Fri Jun 24 12:42:48 2016 +0100 +++ b/examples/04-Audio/samples/render.cpp Fri Jun 24 14:55:12 2016 +0100 @@ -38,6 +38,13 @@ bool setup(BelaContext *context, void *userData) { + // Check that we have the same number of inputs and outputs. + 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; + } + // Retrieve a parameter passed in from the initAudio() call gSampleData = *(SampleData *)userData; @@ -62,8 +69,8 @@ if(gReadPtr >= gSampleData.sampleLen) gReadPtr = -1; - for(unsigned int channel = 0; channel < context->audioChannels; channel++) - context->audioOut[n * context->audioChannels + channel] = out; // ...and put it in both left and right channel + for(unsigned int channel = 0; channel < context->audioOutChannels; channel++) + context->audioOut[n * context->audioOutChannels + channel] = out; // ...and put it in both left and right channel } // Request that the lower-priority task run at next opportunity diff -r ff0e9e827dcd -r 5d954690a7c1 examples/04-Audio/tremolo/render.cpp --- a/examples/04-Audio/tremolo/render.cpp Fri Jun 24 12:42:48 2016 +0100 +++ b/examples/04-Audio/tremolo/render.cpp Fri Jun 24 14:55:12 2016 +0100 @@ -30,6 +30,12 @@ bool setup(BelaContext *context, void *userData) { + // Check that we have the same number of inputs and outputs. + 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; + } gInverseSampleRate = 1.0 / context->audioSampleRate; gPhase = 0.0; @@ -50,7 +56,7 @@ 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++) { // Read the audio input and half the amplitude float input = audioRead(context, n, channel) * 0.5; // Write to audio output the audio input multiplied by the sinewave @@ -60,7 +66,7 @@ // Nested for loops for analog channels for(unsigned int n = 0; n < context->analogFrames; n++) { - for(unsigned int ch = 0; ch < context->analogChannels; ch++) { + for(unsigned int ch = 0; ch < context->analogOutChannels; ch++) { // Read analog channel 0 and map the range from 0-1 to 0.25-20 // use this to set the value of gFrequency gFrequency = map(analogRead(context, n, 0), 0.0, 1.0, 0.25, 20.0); diff -r ff0e9e827dcd -r 5d954690a7c1 examples/05-Communication/basic-midi/render.cpp --- a/examples/05-Communication/basic-midi/render.cpp Fri Jun 24 12:42:48 2016 +0100 +++ b/examples/05-Communication/basic-midi/render.cpp Fri Jun 24 14:55:12 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; } diff -r ff0e9e827dcd -r 5d954690a7c1 examples/08-PureData/gettingStarted/_main.pd --- a/examples/08-PureData/gettingStarted/_main.pd Fri Jun 24 12:42:48 2016 +0100 +++ b/examples/08-PureData/gettingStarted/_main.pd Fri Jun 24 14:55:12 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; diff -r ff0e9e827dcd -r 5d954690a7c1 examples/08-PureData/hello-midi/_main.pd --- a/examples/08-PureData/hello-midi/_main.pd Fri Jun 24 12:42:48 2016 +0100 +++ b/examples/08-PureData/hello-midi/_main.pd Fri Jun 24 14:55:12 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.; diff -r ff0e9e827dcd -r 5d954690a7c1 examples/08-PureData/scope/_main.pd --- a/examples/08-PureData/scope/_main.pd Fri Jun 24 12:42:48 2016 +0100 +++ b/examples/08-PureData/scope/_main.pd Fri Jun 24 14:55:12 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 diff -r ff0e9e827dcd -r 5d954690a7c1 examples/10-Instruments/airharp/String.cpp --- a/examples/10-Instruments/airharp/String.cpp Fri Jun 24 12:42:48 2016 +0100 +++ b/examples/10-Instruments/airharp/String.cpp Fri Jun 24 14:55:12 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; } diff -r ff0e9e827dcd -r 5d954690a7c1 examples/10-Instruments/airharp/render.cpp --- a/examples/10-Instruments/airharp/render.cpp Fri Jun 24 12:42:48 2016 +0100 +++ b/examples/10-Instruments/airharp/render.cpp Fri Jun 24 14:55:12 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; } diff -r ff0e9e827dcd -r 5d954690a7c1 examples/10-Instruments/d-box/render.cpp --- a/examples/10-Instruments/d-box/render.cpp Fri Jun 24 12:42:48 2016 +0100 +++ b/examples/10-Instruments/d-box/render.cpp Fri Jun 24 14:55:12 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)); diff -r ff0e9e827dcd -r 5d954690a7c1 examples/10-Instruments/oscillator-bank/render.cpp --- a/examples/10-Instruments/oscillator-bank/render.cpp Fri Jun 24 12:42:48 2016 +0100 +++ b/examples/10-Instruments/oscillator-bank/render.cpp Fri Jun 24 14:55:12 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; } diff -r ff0e9e827dcd -r 5d954690a7c1 examples/10-Instruments/tank-wars/render.cpp --- a/examples/10-Instruments/tank-wars/render.cpp Fri Jun 24 12:42:48 2016 +0100 +++ b/examples/10-Instruments/tank-wars/render.cpp Fri Jun 24 14:55:12 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; } diff -r ff0e9e827dcd -r 5d954690a7c1 examples/10-Instruments/vangelisiser/_main.pd --- a/examples/10-Instruments/vangelisiser/_main.pd Fri Jun 24 12:42:48 2016 +0100 +++ b/examples/10-Instruments/vangelisiser/_main.pd Fri Jun 24 14:55:12 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; diff -r ff0e9e827dcd -r 5d954690a7c1 examples/11-Extras/gpioAnalogLoopbackTest/render.cpp --- a/examples/11-Extras/gpioAnalogLoopbackTest/render.cpp Fri Jun 24 12:42:48 2016 +0100 +++ b/examples/11-Extras/gpioAnalogLoopbackTest/render.cpp Fri Jun 24 14:55:12 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); } } diff -r ff0e9e827dcd -r 5d954690a7c1 examples/11-Extras/userdata/main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/11-Extras/userdata/main.cpp Fri Jun 24 14:55:12 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 +#include +#include +#include +#include +#include +#include + +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; +} diff -r ff0e9e827dcd -r 5d954690a7c1 examples/11-Extras/userdata/render.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/11-Extras/userdata/render.cpp Fri Jun 24 14:55:12 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 +#include + +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. + +*/