annotate examples/06-Sensors/capacitive-touch/render.cpp @ 507:1cec96845a23 prerelease

Explanted explantation
author Giulio Moro <giuliomoro@yahoo.it>
date Wed, 22 Jun 2016 01:51:17 +0100
parents ff6e9199c444
children
rev   line source
robert@501 1 /*
robert@501 2 ____ _____ _ _
robert@501 3 | __ )| ____| | / \
robert@501 4 | _ \| _| | | / _ \
robert@501 5 | |_) | |___| |___ / ___ \
robert@501 6 |____/|_____|_____/_/ \_\
robert@501 7
robert@501 8 The platform for ultra-low latency audio and sensor processing
robert@501 9
robert@501 10 http://bela.io
robert@501 11
robert@501 12 A project of the Augmented Instruments Laboratory within the
robert@501 13 Centre for Digital Music at Queen Mary University of London.
robert@501 14 http://www.eecs.qmul.ac.uk/~andrewm
robert@501 15
robert@501 16 (c) 2016 Augmented Instruments Laboratory: Andrew McPherson,
robert@501 17 Astrid Bin, Liam Donovan, Christian Heinrichs, Robert Jack,
robert@501 18 Giulio Moro, Laurel Pardue, Victor Zappi. All rights reserved.
robert@501 19
robert@501 20 The Bela software is distributed under the GNU Lesser General Public License
robert@501 21 (LGPL 3.0), available here: https://www.gnu.org/licenses/lgpl-3.0.txt
robert@501 22 */
robert@501 23
robert@501 24
robert@501 25 #include <Bela.h>
robert@501 26 #include <cmath>
robert@501 27 #include <rtdk.h>
robert@501 28 #include "I2C_MPR121.h"
robert@501 29
robert@501 30 // How many pins there are
robert@501 31 #define NUM_TOUCH_PINS 12
robert@501 32
robert@501 33 // Define this to print data to terminal
robert@501 34 #undef DEBUG_MPR121
robert@501 35
robert@501 36 // Change this to change how often the MPR121 is read (in Hz)
robert@501 37 int readInterval = 50;
robert@501 38
robert@501 39 // Change this threshold to set the minimum amount of touch
robert@501 40 int threshold = 40;
robert@501 41
robert@501 42 // This array holds the continuous sensor values
robert@501 43 int sensorValue[NUM_TOUCH_PINS];
robert@501 44
robert@501 45 // ---- test code stuff -- can be deleted for your example ----
robert@501 46
robert@501 47 // 12 notes of a C major scale...
robert@501 48 float gFrequencies[NUM_TOUCH_PINS] = {261.63, 293.66, 329.63, 349.23, 392.00, 440.00, 493.88, 523.25, 587.33, 659.25, 698.25, 783.99};
robert@501 49
robert@501 50 // This is internal stuff for the demo
robert@501 51 float gNormFrequencies[NUM_TOUCH_PINS];
robert@501 52 float gPhases[NUM_TOUCH_PINS] = {0};
robert@501 53
robert@501 54 // ---- internal stuff -- do not change -----
robert@501 55
robert@501 56 I2C_MPR121 mpr121; // Object to handle MPR121 sensing
robert@501 57 AuxiliaryTask i2cTask; // Auxiliary task to read I2C
robert@501 58
robert@501 59 int readCount = 0; // How long until we read again...
robert@501 60 int readIntervalSamples = 0; // How many samples between reads
robert@501 61
robert@501 62 void readMPR121();
robert@501 63
robert@501 64 // setup() is called once before the audio rendering starts.
robert@501 65 // Use it to perform any initialisation and allocation which is dependent
robert@501 66 // on the period size or sample rate.
robert@501 67 //
robert@501 68 // userData holds an opaque pointer to a data structure that was passed
robert@501 69 // in from the call to initAudio().
robert@501 70 //
robert@501 71 // Return true on success; returning false halts the program.
robert@501 72
robert@501 73 bool setup(BelaContext *context, void *userData)
robert@501 74 {
robert@501 75 if(!mpr121.begin(1, 0x5A)) {
robert@501 76 rt_printf("Error initialising MPR121\n");
robert@501 77 return false;
robert@501 78 }
robert@501 79
robert@501 80 i2cTask = Bela_createAuxiliaryTask(readMPR121, 50, "bela-mpr121");
robert@501 81 readIntervalSamples = context->audioSampleRate / readInterval;
robert@501 82
robert@501 83 for(int i = 0; i < NUM_TOUCH_PINS; i++) {
robert@501 84 gNormFrequencies[i] = 2.0 * M_PI * gFrequencies[i] / context->audioSampleRate;
robert@501 85 }
robert@501 86
robert@501 87 return true;
robert@501 88 }
robert@501 89
robert@501 90 // render() is called regularly at the highest priority by the audio engine.
robert@501 91 // Input and output are given from the audio hardware and the other
robert@501 92 // ADCs and DACs (if available). If only audio is available, numAnalogFrames
robert@501 93 // will be 0.
robert@501 94
robert@501 95 void render(BelaContext *context, void *userData)
robert@501 96 {
robert@501 97 for(int n = 0; n < context->audioFrames; n++) {
robert@501 98 // Keep this code: it schedules the touch sensor readings
robert@501 99 if(++readCount >= readIntervalSamples) {
robert@501 100 readCount = 0;
robert@501 101 Bela_scheduleAuxiliaryTask(i2cTask);
robert@501 102 }
robert@501 103
robert@501 104 float sample = 0.0;
robert@501 105
robert@501 106 // This code can be replaced with your favourite audio code
robert@501 107 for(int i = 0; i < NUM_TOUCH_PINS; i++) {
robert@501 108 float amplitude = sensorValue[i] / 400.0;
robert@501 109
robert@501 110 // Prevent clipping
robert@501 111 if(amplitude > 0.5)
robert@501 112 amplitude = 0.5;
robert@501 113
robert@501 114 sample += amplitude * sinf(gPhases[i]);
robert@501 115 gPhases[i] += gNormFrequencies[i];
robert@501 116 if(gPhases[i] > 2.0 * M_PI)
robert@501 117 gPhases[i] -= 2.0 * M_PI;
robert@501 118 }
robert@501 119
robert@501 120 for(int ch = 0; ch < context->audioChannels; ch++)
robert@501 121 context->audioOut[context->audioChannels * n + ch] = sample;
robert@501 122 }
robert@501 123 }
robert@501 124
robert@501 125 // cleanup() is called once at the end, after the audio has stopped.
robert@501 126 // Release any resources that were allocated in setup().
robert@501 127
robert@501 128 void cleanup(BelaContext *context, void *userData)
robert@501 129 {
robert@501 130 // Nothing to do here
robert@501 131 }
robert@501 132
robert@501 133
robert@501 134 // Auxiliary task to read the I2C board
robert@501 135 void readMPR121()
robert@501 136 {
robert@501 137 for(int i = 0; i < NUM_TOUCH_PINS; i++) {
robert@501 138 sensorValue[i] = -(mpr121.filteredData(i) - mpr121.baselineData(i));
robert@501 139 sensorValue[i] -= threshold;
robert@501 140 if(sensorValue[i] < 0)
robert@501 141 sensorValue[i] = 0;
robert@501 142 #ifdef DEBUG_MPR121
robert@501 143 rt_printf("%d ", sensorValue[i]);
robert@501 144 #endif
robert@501 145 }
robert@501 146 #ifdef DEBUG_MPR121
robert@501 147 rt_printf("\n");
robert@501 148 #endif
robert@501 149
robert@501 150 // You can use this to read binary on/off touch state more easily
robert@501 151 //rt_printf("Touched: %x\n", mpr121.touched());
robert@501 152 }
robert@501 153
robert@501 154
robert@501 155 /**
robert@502 156 \example capacitive-touch/render.cpp
robert@501 157
robert@501 158 Capacitive touch sensing with MPR121
robert@501 159 ---------------------------
robert@501 160
robert@501 161 This sketch allows you to hook up an MPR121 capactive touch sensing device
robert@501 162 to Bela, for example the SparkFun Capacitive Touch Sensor Breakout - MPR121.
robert@501 163 The breakout board gives you 12 electrode connections.
robert@501 164
robert@501 165 To get this working with Bela you need to connect the breakout board to the I2C
robert@501 166 terminal on the Bela board. See the Pin guide for details of which pin is which.
robert@501 167
robert@501 168 The sensor data will then be available for you to use in the array
robert@501 169 `sensorValue[NUM_TOUCH_PINS]`.
robert@501 170 */