annotate examples/06-Sensors/mpr121/render.cpp @ 496:eb237b131ec7 prerelease

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