annotate projects/d-box/sensors.cpp @ 0:8a575ba3ab52

Initial commit.
author andrewm
date Fri, 31 Oct 2014 19:10:17 +0100
parents
children 901d205d1a3c
rev   line source
andrewm@0 1 /*
andrewm@0 2 * sensors.cpp
andrewm@0 3 *
andrewm@0 4 * Created on: May 28, 2014
andrewm@0 5 * Author: Victor Zappi
andrewm@0 6 */
andrewm@0 7
andrewm@0 8 #include <stdio.h>
andrewm@0 9 #include <pthread.h>
andrewm@0 10 #include <unistd.h>
andrewm@0 11 #include <math.h>
andrewm@0 12 #include <vector>
andrewm@0 13 #include "prio.h"
andrewm@0 14 #include "sensors.h"
andrewm@0 15 #include "OscillatorBank.h"
andrewm@0 16 #include "DboxSensors.h"
andrewm@0 17
andrewm@0 18
andrewm@0 19 //----------------------------------------
andrewm@0 20 // main extern variables
andrewm@0 21 //----------------------------------------
andrewm@0 22 extern vector<OscillatorBank*> gOscBanks;
andrewm@0 23 extern int gCurrentOscBank;
andrewm@0 24 extern int gNextOscBank;
andrewm@0 25 extern bool gShouldStop;
andrewm@0 26 extern int gVerbose;
andrewm@0 27
andrewm@0 28 float gSensor0LatestTouchPos = 0; // most recent pitch touch location [0-1] on sensor 0, used by render.cpp
andrewm@0 29 int gSensor0LatestTouchNum = 0; // most recent num of touches on sensor 0, used by render.cpp
andrewm@0 30 float gSensor1LatestTouchPos[5]; // most recent touche locations on sensor 1, used by render.cpp
andrewm@0 31 //float gSensor1LatestTouchSizes[5];
andrewm@0 32 int gSensor1LatestTouchCount; // most recent number touches on sensor 1, used by render.cpp
andrewm@0 33 int gSensor1LatestTouchIndex = 0; // index of last touch in gSensor1LatestTouchPos[5], used by render.cpp
andrewm@0 34 int gLastFSRValue = 1799; // most recent fsr value, used by render.cpp
andrewm@0 35
andrewm@0 36
andrewm@0 37 DboxSensors Sensors;
andrewm@0 38
andrewm@0 39
andrewm@0 40 //----------------------------------------
andrewm@0 41 // var shared with logger
andrewm@0 42 //----------------------------------------
andrewm@0 43 int s0TouchNum = 0;
andrewm@0 44 float s0Touches_[MAX_TOUCHES];
andrewm@0 45 float s0Size_[MAX_TOUCHES];
andrewm@0 46 int s0LastIndex;
andrewm@0 47
andrewm@0 48 int s1TouchNum = 0;
andrewm@0 49 float s1Touches_[MAX_TOUCHES];
andrewm@0 50 float s1Size_[MAX_TOUCHES];
andrewm@0 51 int s1LastIndex;
andrewm@0 52
andrewm@0 53 int fsr = 1799;
andrewm@0 54
andrewm@0 55
andrewm@0 56
andrewm@0 57 using namespace std;
andrewm@0 58
andrewm@0 59 int initSensorLoop(int sensorAddress0, int sensorAddress1, bool useNewSensors)
andrewm@0 60 {
andrewm@0 61 int tk0_bus = 1;
andrewm@0 62 int tk0_address = sensorAddress0;
andrewm@0 63 int tk1_bus = 1;
andrewm@0 64 int tk1_address = sensorAddress1;
andrewm@0 65 int tk_file = 0;
andrewm@0 66 int fsr_max = 1799;
andrewm@0 67 int fsr_pinNum = 4;
andrewm@0 68
andrewm@0 69 if(gVerbose==1)
andrewm@0 70 cout << "---------------->Init Control Thread" << endl;
andrewm@0 71
andrewm@0 72 if(Sensors.initSensors(tk0_bus, tk0_address, tk1_bus, tk1_address, tk_file, fsr_pinNum, fsr_max, useNewSensors)>0)
andrewm@0 73 {
andrewm@0 74 gShouldStop = 1;
andrewm@0 75 cout << "control cannot start" << endl;
andrewm@0 76 return -1;
andrewm@0 77 }
andrewm@0 78
andrewm@0 79 for(int i=0; i<MAX_TOUCHES; i++)
andrewm@0 80 {
andrewm@0 81 s0Touches_[i] = 0.0;
andrewm@0 82 s0Size_[i] = 0.0;
andrewm@0 83
andrewm@0 84 s1Touches_[i] = 0.0;
andrewm@0 85 s1Size_[i] = 0.0;
andrewm@0 86 }
andrewm@0 87
andrewm@0 88 return 0;
andrewm@0 89 }
andrewm@0 90
andrewm@0 91 void sensorLoop(void *)
andrewm@0 92 {
andrewm@0 93 timeval start, end;
andrewm@0 94 unsigned long elapsedTime;
andrewm@0 95 //float touchSize = 0; // once used for timbre
andrewm@0 96
andrewm@0 97
andrewm@0 98
andrewm@0 99 float *s0Touches;
andrewm@0 100 float *s0Size;
andrewm@0 101 int s0PrevTouchNum = 0;
andrewm@0 102 int s0SortedTouchIndices[MAX_TOUCHES];
andrewm@0 103 float s0SortedTouches[MAX_TOUCHES];
andrewm@0 104 float s0PrevSortedTouches[MAX_TOUCHES];
andrewm@0 105
andrewm@0 106 float *s1Touches;
andrewm@0 107 float *s1Size;
andrewm@0 108 int s1PrevTouchNum = 0;
andrewm@0 109 int s1SortedTouchIndices[MAX_TOUCHES];
andrewm@0 110 float s1SortedTouches[MAX_TOUCHES];
andrewm@0 111 float s1PrevSortedTouches[MAX_TOUCHES];
andrewm@0 112
andrewm@0 113 float freqScaler = 0;
andrewm@0 114 int fsrMin = 0;//50; // was 200
andrewm@0 115 int fsrMax = 1799;//1300; // was 800
andrewm@0 116 float vel = 0;
andrewm@0 117 float prevVel = 0;
andrewm@0 118 float filterMaxF = 0;
andrewm@0 119 if(gVerbose==1)
andrewm@0 120 dbox_printf("__________set Control Thread priority\n");
andrewm@0 121
andrewm@0 122 if(gVerbose==1)
andrewm@0 123 dbox_printf("_________________Control Thread!\n");
andrewm@0 124
andrewm@0 125 // get freq scaler, cos freqs must be scaled according to the wavetable used in the oscillator bank
andrewm@0 126 freqScaler = gOscBanks[gCurrentOscBank]->getFrequencyScaler();
andrewm@0 127 filterMaxF = gOscBanks[gCurrentOscBank]->filterMaxF;
andrewm@0 128
andrewm@0 129 // init time vals
andrewm@0 130 gettimeofday(&start, NULL);
andrewm@0 131
andrewm@0 132 // here we go, sensor loop until the end of the application
andrewm@0 133 while(!gShouldStop)
andrewm@0 134 {
andrewm@0 135 gettimeofday(&end, NULL);
andrewm@0 136 elapsedTime = ( (end.tv_sec*1000000+end.tv_usec) - (start.tv_sec*1000000+start.tv_usec) );
andrewm@0 137 if( elapsedTime<4000 )
andrewm@0 138 usleep(4000-elapsedTime);
andrewm@0 139 else
andrewm@0 140 dbox_printf("%d\n", (int)elapsedTime); // this print happens when something's gone bad...
andrewm@0 141
andrewm@0 142 if(Sensors.readSensors()==0)
andrewm@0 143 {
andrewm@0 144 s0TouchNum = Sensors.getTKTouchCount(0);
andrewm@0 145 s0Touches = Sensors.getTKXPositions(0);
andrewm@0 146 s0Size = Sensors.getTKTouchSize(0);
andrewm@0 147
andrewm@0 148 s1TouchNum = Sensors.getTKTouchCount(1);
andrewm@0 149 s1Touches = Sensors.getTKXPositions(1);
andrewm@0 150 s1Size = Sensors.getTKTouchSize(1);
andrewm@0 151
andrewm@0 152 for(int i=0; i<MAX_TOUCHES; i++)
andrewm@0 153 {
andrewm@0 154 s0Touches_[i] = s0Touches[i];
andrewm@0 155 s0Size_[i] = s0Size[i];
andrewm@0 156
andrewm@0 157 s1Touches_[i] = s1Touches[i];
andrewm@0 158 s1Size_[i] = s1Size[i];
andrewm@0 159 }
andrewm@0 160
andrewm@0 161 gSensor0LatestTouchNum = s0TouchNum;
andrewm@0 162 if(s0TouchNum > 0)
andrewm@0 163 {
andrewm@0 164 //-----------------------------------------------------------------------------------
andrewm@0 165 // timbre, speed and pitch
andrewm@0 166 //touchSize = 0; \\ once used for timbre
andrewm@0 167
andrewm@0 168 // if we have a number of touches different from previous round, track their order of arrival [calculated using distance comparison]
andrewm@0 169 if(s0PrevTouchNum!=s0TouchNum)
andrewm@0 170 {
andrewm@0 171 float distances[MAX_TOUCHES*(MAX_TOUCHES-1)]; // maximum number of current+previous touches between rounds with different num of touches
andrewm@0 172 int ids[MAX_TOUCHES*(MAX_TOUCHES-1)];
andrewm@0 173 // calculate all distance permutations between previous and current touches
andrewm@0 174 for(int i=0; i<s0TouchNum; i++)
andrewm@0 175 {
andrewm@0 176 for(int p=0; p<s0PrevTouchNum; p++)
andrewm@0 177 {
andrewm@0 178 int index = i*s0PrevTouchNum+p; // permutation id [says between which touches we are calculating distance]
andrewm@0 179 distances[index] = fabs(s0Touches[i]-s0PrevSortedTouches[p]);
andrewm@0 180 ids[index] = index;
andrewm@0 181 if(index>0)
andrewm@0 182 {
andrewm@0 183 // sort, from min to max distance
andrewm@0 184 float tmp;
andrewm@0 185 while(distances[index]<distances[index-1])
andrewm@0 186 {
andrewm@0 187 tmp = ids[index-1];
andrewm@0 188 ids[index-1] = ids[index];
andrewm@0 189 ids[index] = tmp;
andrewm@0 190
andrewm@0 191 tmp = distances[index-1];
andrewm@0 192 distances[index-1] = distances[index];
andrewm@0 193 distances[index] = tmp;
andrewm@0 194
andrewm@0 195 index--;
andrewm@0 196
andrewm@0 197 if(index == 0)
andrewm@0 198 break;
andrewm@0 199 }
andrewm@0 200 }
andrewm@0 201 }
andrewm@0 202 }
andrewm@0 203
andrewm@0 204 int sorted = 0;
andrewm@0 205 bool currAssigned[MAX_TOUCHES] = {false};
andrewm@0 206 bool prevAssigned[MAX_TOUCHES] = {false};
andrewm@0 207
andrewm@0 208 // track touches assigning index according to shortest distance
andrewm@0 209 for(int i=0; i<s0TouchNum*s0PrevTouchNum; i++)
andrewm@0 210 {
andrewm@0 211 int currentIndex = ids[i]/s0PrevTouchNum;
andrewm@0 212 int prevIndex = ids[i]%s0PrevTouchNum;
andrewm@0 213 // avoid double assignment
andrewm@0 214 if(!currAssigned[currentIndex] && !prevAssigned[prevIndex])
andrewm@0 215 {
andrewm@0 216 currAssigned[currentIndex] = true;
andrewm@0 217 prevAssigned[prevIndex] = true;
andrewm@0 218 s0SortedTouchIndices[currentIndex] = prevIndex;
andrewm@0 219 sorted++;
andrewm@0 220 }
andrewm@0 221 }
andrewm@0 222 // we still have to assign a free index to new touches
andrewm@0 223 if(s0PrevTouchNum<s0TouchNum)
andrewm@0 224 {
andrewm@0 225 for(int i=0; i<s0TouchNum; i++)
andrewm@0 226 {
andrewm@0 227 if(!currAssigned[i])
andrewm@0 228 s0SortedTouchIndices[i] = sorted++; // assign next free index
andrewm@0 229
andrewm@0 230 // update tracked value
andrewm@0 231 s0SortedTouches[s0SortedTouchIndices[i]] = s0Touches[i];
andrewm@0 232 s0PrevSortedTouches[i] = s0SortedTouches[i];
andrewm@0 233 if(s0SortedTouchIndices[i]==s0TouchNum-1)
andrewm@0 234 s0LastIndex = i;
andrewm@0 235
andrewm@0 236 // accumulate sizes for timbre
andrewm@0 237 //touchSize += s0Size[i];
andrewm@0 238 }
andrewm@0 239 }
andrewm@0 240 else // some touches have disappeared...
andrewm@0 241 {
andrewm@0 242 // ...we have to shift all indices...
andrewm@0 243 for(int i=s0PrevTouchNum-1; i>=0; i--)
andrewm@0 244 {
andrewm@0 245 if(!prevAssigned[i])
andrewm@0 246 {
andrewm@0 247 for(int j=0; j<s0TouchNum; j++)
andrewm@0 248 {
andrewm@0 249 // ...only if touches that disappeared were before the current one
andrewm@0 250 if(s0SortedTouchIndices[j]>i)
andrewm@0 251 s0SortedTouchIndices[j]--;
andrewm@0 252 }
andrewm@0 253 }
andrewm@0 254 }
andrewm@0 255 // done! now update
andrewm@0 256 for(int i=0; i<s0TouchNum; i++)
andrewm@0 257 {
andrewm@0 258 // update tracked value
andrewm@0 259 s0SortedTouches[s0SortedTouchIndices[i]] = s0Touches[i];
andrewm@0 260 s0PrevSortedTouches[i] = s0SortedTouches[i];
andrewm@0 261 if(s0SortedTouchIndices[i]==s0TouchNum-1)
andrewm@0 262 s0LastIndex = i;
andrewm@0 263
andrewm@0 264 // accumulate sizes for timbre
andrewm@0 265 //touchSize += s0Size[i];
andrewm@0 266 }
andrewm@0 267 }
andrewm@0 268 }
andrewm@0 269 else // nothing's changed since last round
andrewm@0 270 {
andrewm@0 271 for(int i=0; i<s0TouchNum; i++)
andrewm@0 272 {
andrewm@0 273 // update tracked value
andrewm@0 274 s0SortedTouches[s0SortedTouchIndices[i]] = s0Touches[i];
andrewm@0 275 s0PrevSortedTouches[i] = s0SortedTouches[i];
andrewm@0 276
andrewm@0 277 // accumulate sizes for timbre
andrewm@0 278 //touchSize += s0Size[i];
andrewm@0 279 }
andrewm@0 280 }
andrewm@0 281
andrewm@0 282 if(s0TouchNum == 0)
andrewm@0 283 s0LastIndex = -1;
andrewm@0 284
andrewm@0 285 // timbre
andrewm@0 286 //touchSize = (touchSize > 0.7) ? 1 : touchSize/0.7;
andrewm@0 287 //gOscBanks[gCurrentOscBank]->hopNumTh = log((1-touchSize)+1)/log(2)*20000;
andrewm@0 288 //gOscBanks[gCurrentOscBank]->hopNumTh = 0;
andrewm@0 289
andrewm@0 290
andrewm@0 291 // pitch, controlled by last touch
andrewm@0 292 //prevTouchPos = touch[touchIndex];
andrewm@0 293 //touchPos = (s0SortedTouches[s0TouchNum-1]-0.5)/0.5; // from [0,1] to [-1,1]
andrewm@0 294 gSensor0LatestTouchPos = s0SortedTouches[s0TouchNum-1];
andrewm@0 295 //touchPos = s0Touches[0];
andrewm@0 296 //gOscBanks[gCurrentOscBank]->pitchMultiplier = pow(2, touchPos);
andrewm@0 297 //-----------------------------------------------------------------------------------
andrewm@0 298
andrewm@0 299
andrewm@0 300
andrewm@0 301 //-----------------------------------------------------------------------------------
andrewm@0 302 // note on
andrewm@0 303 //if(s0PrevTouchNum == 0)
andrewm@0 304 // gOscBanks[gCurrentOscBank]->play();
andrewm@0 305 // fsr = Sensors.getFSRVAlue();
andrewm@0 306 fsr = gLastFSRValue;
andrewm@0 307 //dbox_printf("fsr: %d\n", fsr);
andrewm@0 308 if(!gOscBanks[gCurrentOscBank]->note)
andrewm@0 309 {
andrewm@0 310 vel = fsr;
andrewm@0 311 vel /= (float)(fsrMax-fsrMin);
andrewm@0 312
andrewm@0 313 vel = 1-vel;
andrewm@0 314 dbox_printf("Attack vel: %f\n", vel);
andrewm@0 315 gOscBanks[gCurrentOscBank]->play(vel);
andrewm@0 316 prevVel = vel;
andrewm@0 317 }
andrewm@0 318 else if(gOscBanks[gCurrentOscBank]->getEnvelopeState() != env_release)
andrewm@0 319 {
andrewm@0 320 fsr = (fsr > fsrMax) ? fsrMax : fsr;
andrewm@0 321 vel = (fsr < fsrMin) ? fsrMin : fsr;
andrewm@0 322 vel -= fsrMin;
andrewm@0 323 vel /= (float)(fsrMax-fsrMin);
andrewm@0 324 vel = 1-vel;
andrewm@0 325 if(vel > prevVel)
andrewm@0 326 {
andrewm@0 327 gOscBanks[gCurrentOscBank]->afterTouch(vel);
andrewm@0 328 prevVel = vel;
andrewm@0 329 }
andrewm@0 330 }
andrewm@0 331 //-----------------------------------------------------------------------------------
andrewm@0 332 }
andrewm@0 333 else
andrewm@0 334 {
andrewm@0 335 //prevFsr = 1799;
andrewm@0 336 //prevTouchPos = -1;
andrewm@0 337 //-----------------------------------------------------------------------------------
andrewm@0 338 // note off
andrewm@0 339 if(s0PrevTouchNum > 0)
andrewm@0 340 {
andrewm@0 341 if(gOscBanks[gCurrentOscBank]->state==bank_playing)
andrewm@0 342 gOscBanks[gCurrentOscBank]->stop();
andrewm@0 343 }
andrewm@0 344 //-----------------------------------------------------------------------------------
andrewm@0 345 }
andrewm@0 346
andrewm@0 347
andrewm@0 348
andrewm@0 349 // sensor 2
andrewm@0 350 //-----------------------------------------------------------------------------------
andrewm@0 351 //filter - calculated even when no touches on first sensor, to filter also release tail
andrewm@0 352 gOscBanks[gCurrentOscBank]->filterNum = s1TouchNum;
andrewm@0 353
andrewm@0 354 gSensor1LatestTouchCount = gOscBanks[gCurrentOscBank]->filterNum;
andrewm@0 355 for(int i = 0; i < gSensor1LatestTouchCount; i++) {
andrewm@0 356 gSensor1LatestTouchPos[i] = s1Touches[i];
andrewm@0 357 //gSensor1LatestTouchSizes[i] = s1Size[i];
andrewm@0 358 }
andrewm@0 359
andrewm@0 360 /* for(int i=0; i<gOscBanks[gCurrentOscBank]->filterNum; i++)
andrewm@0 361 {
andrewm@0 362 // touch pos is linear but freqs are log
andrewm@0 363 gOscBanks[gCurrentOscBank]->filterFreqs[i] = ((exp(s0Touches[i]*4)-1)/(exp(4)-1))*filterMaxF*freqScaler;
andrewm@0 364 //gOscBanks[gCurrentOscBank]->filterQ[i] = size[i]*5*(1+touch[i]*1000)*freqScaler;
andrewm@0 365 gOscBanks[gCurrentOscBank]->filterQ[i] = s0Size[i];
andrewm@0 366 if(gOscBanks[gCurrentOscBank]->filterFreqs[i]>500*freqScaler)
andrewm@0 367 gOscBanks[gCurrentOscBank]->filterPadding[i] = 1+100000*( (gOscBanks[gCurrentOscBank]->filterFreqs[i]-500*freqScaler)/(filterMaxF-500)*freqScaler );
andrewm@0 368 else
andrewm@0 369 gOscBanks[gCurrentOscBank]->filterPadding[i] = 1;
andrewm@0 370 }*/
andrewm@0 371
andrewm@0 372 // each touch on sensor 2 is a notch filter, whose Q is determined by touch size
andrewm@0 373 for(int i=0; i<gOscBanks[gCurrentOscBank]->filterNum; i++)
andrewm@0 374 {
andrewm@0 375 // map touch pos [which is linear] on freqs exponentially
andrewm@0 376 float freq = ((exp(s1Touches[i]*4)-1)/EXP_DENOM)*filterMaxF;
andrewm@0 377 gOscBanks[gCurrentOscBank]->filterFreqs[i] = freq*freqScaler;
andrewm@0 378 // also size is mapped exponentially on Q
andrewm@0 379 float siz = (exp(s1Size[i])-1)/1.71828;
andrewm@0 380 gOscBanks[gCurrentOscBank]->filterQ[i] = siz*( (filterMaxF-freq)/filterMaxF * 0.9 + 0.1 ); // size weight on Q decreases with frequency
andrewm@0 381 }
andrewm@0 382 //-----------------------------------------------------------------------------------
andrewm@0 383
andrewm@0 384
andrewm@0 385
andrewm@0 386 //-----------------------------------------------------------------------------------
andrewm@0 387 // sort touches on sensor 2
andrewm@0 388 if(s1TouchNum > 0)
andrewm@0 389 {
andrewm@0 390 // if we have a number of touches different from previous round, track their order of arrival [calculated using distance comparison]
andrewm@0 391 if(s1PrevTouchNum!=s1TouchNum)
andrewm@0 392 {
andrewm@0 393 float distances[MAX_TOUCHES*(MAX_TOUCHES-1)]; // maximum number of current+previous touches between rounds with different num of touches
andrewm@0 394 int ids[MAX_TOUCHES*(MAX_TOUCHES-1)];
andrewm@0 395 // calculate all distance permutations between previous and current touches
andrewm@0 396 for(int i=0; i<s1TouchNum; i++)
andrewm@0 397 {
andrewm@0 398 for(int p=0; p<s1PrevTouchNum; p++)
andrewm@0 399 {
andrewm@0 400 int index = i*s1PrevTouchNum+p; // permutation id [says between which touches we are calculating distance]
andrewm@0 401 distances[index] = fabs(s1Touches[i]-s1PrevSortedTouches[p]);
andrewm@0 402 ids[index] = index;
andrewm@0 403 if(index>0)
andrewm@0 404 {
andrewm@0 405 // sort, from min to max distance
andrewm@0 406 float tmp;
andrewm@0 407 while(distances[index]<distances[index-1])
andrewm@0 408 {
andrewm@0 409 tmp = ids[index-1];
andrewm@0 410 ids[index-1] = ids[index];
andrewm@0 411 ids[index] = tmp;
andrewm@0 412
andrewm@0 413 tmp = distances[index-1];
andrewm@0 414 distances[index-1] = distances[index];
andrewm@0 415 distances[index] = tmp;
andrewm@0 416
andrewm@0 417 index--;
andrewm@0 418
andrewm@0 419 if(index == 0)
andrewm@0 420 break;
andrewm@0 421 }
andrewm@0 422 }
andrewm@0 423 }
andrewm@0 424 }
andrewm@0 425
andrewm@0 426 int sorted = 0;
andrewm@0 427 bool currAssigned[MAX_TOUCHES] = {false};
andrewm@0 428 bool prevAssigned[MAX_TOUCHES] = {false};
andrewm@0 429
andrewm@0 430 // track touches assigning index according to shortest distance
andrewm@0 431 for(int i=0; i<s1TouchNum*s1PrevTouchNum; i++)
andrewm@0 432 {
andrewm@0 433 int currentIndex = ids[i]/s1PrevTouchNum;
andrewm@0 434 int prevIndex = ids[i]%s1PrevTouchNum;
andrewm@0 435 // avoid double assignment
andrewm@0 436 if(!currAssigned[currentIndex] && !prevAssigned[prevIndex])
andrewm@0 437 {
andrewm@0 438 currAssigned[currentIndex] = true;
andrewm@0 439 prevAssigned[prevIndex] = true;
andrewm@0 440 s1SortedTouchIndices[currentIndex] = prevIndex;
andrewm@0 441 sorted++;
andrewm@0 442 }
andrewm@0 443 }
andrewm@0 444 // we still have to assign a free index to new touches
andrewm@0 445 if(s1PrevTouchNum<s1TouchNum)
andrewm@0 446 {
andrewm@0 447 for(int i=0; i<s1TouchNum; i++)
andrewm@0 448 {
andrewm@0 449 if(!currAssigned[i])
andrewm@0 450 s1SortedTouchIndices[i] = sorted++; // assign next free index
andrewm@0 451
andrewm@0 452 // update tracked value
andrewm@0 453 s1SortedTouches[s1SortedTouchIndices[i]] = s1Touches[i];
andrewm@0 454 s1PrevSortedTouches[i] = s1SortedTouches[i];
andrewm@0 455 if(s1SortedTouchIndices[i]==s1TouchNum-1)
andrewm@0 456 s1LastIndex = i;
andrewm@0 457 }
andrewm@0 458 }
andrewm@0 459 else // some touches have disappeared...
andrewm@0 460 {
andrewm@0 461 // ...we have to shift all indices...
andrewm@0 462 for(int i=s1PrevTouchNum-1; i>=0; i--)
andrewm@0 463 {
andrewm@0 464 if(!prevAssigned[i])
andrewm@0 465 {
andrewm@0 466 for(int j=0; j<s1TouchNum; j++)
andrewm@0 467 {
andrewm@0 468 // ...only if touches that disappeared were before the current one
andrewm@0 469 if(s1SortedTouchIndices[j]>i)
andrewm@0 470 s1SortedTouchIndices[j]--;
andrewm@0 471 }
andrewm@0 472 }
andrewm@0 473 }
andrewm@0 474 // done! now update
andrewm@0 475 for(int i=0; i<s1TouchNum; i++)
andrewm@0 476 {
andrewm@0 477 // update tracked value
andrewm@0 478 s1SortedTouches[s1SortedTouchIndices[i]] = s1Touches[i];
andrewm@0 479 s1PrevSortedTouches[i] = s1SortedTouches[i];
andrewm@0 480 if(s1SortedTouchIndices[i]==s1TouchNum-1)
andrewm@0 481 s1LastIndex = i;
andrewm@0 482 }
andrewm@0 483 }
andrewm@0 484 }
andrewm@0 485 else // nothing's changed since last round
andrewm@0 486 {
andrewm@0 487 for(int i=0; i<s1TouchNum; i++)
andrewm@0 488 {
andrewm@0 489 // update tracked value
andrewm@0 490 s1SortedTouches[s1SortedTouchIndices[i]] = s1Touches[i];
andrewm@0 491 s1PrevSortedTouches[i] = s1SortedTouches[i];
andrewm@0 492 }
andrewm@0 493 }
andrewm@0 494 }
andrewm@0 495
andrewm@0 496 if(s1TouchNum > 0)
andrewm@0 497 {
andrewm@0 498 gSensor1LatestTouchIndex = s1LastIndex;
andrewm@0 499 }
andrewm@0 500 else
andrewm@0 501 s1LastIndex = -1;
andrewm@0 502
andrewm@0 503 /* dbox_printf("-----------------------------\nnum: %d, latest: %d\n", s1TouchNum, gSensor1LatestTouchIndex);
andrewm@0 504 for(int i=0; i<s1TouchNum; i++)
andrewm@0 505 dbox_printf("\t%f\n", gSensor1LatestTouchPos[i]);
andrewm@0 506 dbox_printf("------\n");
andrewm@0 507 for(int i=0; i<s1TouchNum; i++)
andrewm@0 508 dbox_printf("\t%f\n", s1SortedTouches[i]);*/
andrewm@0 509
andrewm@0 510
andrewm@0 511
andrewm@0 512 // update variables for both sensors
andrewm@0 513 s0PrevTouchNum = s0TouchNum;
andrewm@0 514 s1PrevTouchNum = s1TouchNum;
andrewm@0 515 }
andrewm@0 516 else
andrewm@0 517 dbox_printf("Come on instrument!\n"); //break
andrewm@0 518
andrewm@0 519 gettimeofday(&start, NULL);
andrewm@0 520 }
andrewm@0 521
andrewm@0 522 dbox_printf("sensor thread ended\n");
andrewm@0 523 }
andrewm@0 524
andrewm@0 525 void *keyboardLoop(void *)
andrewm@0 526 {
andrewm@0 527 if(gVerbose==1)
andrewm@0 528 cout << "_________________Keyboard Control Thread!" << endl;
andrewm@0 529
andrewm@0 530 char keyStroke = '.';
andrewm@0 531 cout << "Press q to quit." << endl;
andrewm@0 532
andrewm@0 533 float speed;
andrewm@0 534
andrewm@0 535 do
andrewm@0 536 {
andrewm@0 537 keyStroke = getchar();
andrewm@0 538 while(getchar()!='\n'); // to read the first stroke
andrewm@0 539
andrewm@0 540 switch (keyStroke)
andrewm@0 541 {
andrewm@0 542 //----------------------------------------------------------------------------
andrewm@0 543 case 'a':
andrewm@0 544 gOscBanks[gCurrentOscBank]->hopNumTh = 0;
andrewm@0 545 gOscBanks[gCurrentOscBank]->play(1);
andrewm@0 546 //cout << "Note on" << endl;
andrewm@0 547 break;
andrewm@0 548 case 's':
andrewm@0 549 if(gOscBanks[gCurrentOscBank]->state==bank_playing)
andrewm@0 550 {
andrewm@0 551 gOscBanks[gCurrentOscBank]->stop();
andrewm@0 552 //cout << "Note off" << endl;
andrewm@0 553 }
andrewm@0 554 break;
andrewm@0 555 //----------------------------------------------------------------------------
andrewm@0 556 case '[':
andrewm@0 557 gOscBanks[gCurrentOscBank]->freqMovement-=0.05;
andrewm@0 558 if(gOscBanks[gCurrentOscBank]->freqMovement<0)
andrewm@0 559 gOscBanks[gCurrentOscBank]->freqMovement = 0;
andrewm@0 560 //cout << "gOscBanks[gCurrentOscBank]->FreqMov: " << gOscBanks[gCurrentOscBank]->freqMovement << endl;
andrewm@0 561 break;
andrewm@0 562 case ']':
andrewm@0 563 gOscBanks[gCurrentOscBank]->freqMovement+=0.05;
andrewm@0 564 if(gOscBanks[gCurrentOscBank]->freqMovement>1)
andrewm@0 565 gOscBanks[gCurrentOscBank]->freqMovement = 1;
andrewm@0 566 //cout << "gOscBanks[gCurrentOscBank]->FreqMov: " << gOscBanks[gCurrentOscBank]->freqMovement << endl;
andrewm@0 567 break;
andrewm@0 568 //----------------------------------------------------------------------------
andrewm@0 569 case '<':
andrewm@0 570 speed = gOscBanks[gCurrentOscBank]->getSpeed() - 0.1 ;
andrewm@0 571 gOscBanks[gCurrentOscBank]->setSpeed(speed);
andrewm@0 572 dbox_printf("Speed: %f\n", speed);
andrewm@0 573
andrewm@0 574 break;
andrewm@0 575 case '>':
andrewm@0 576 speed = gOscBanks[gCurrentOscBank]->getSpeed() + 0.1 ;
andrewm@0 577 gOscBanks[gCurrentOscBank]->setSpeed(speed);
andrewm@0 578 dbox_printf("Speed: %f\n", speed);
andrewm@0 579 break;
andrewm@0 580 case '0':
andrewm@0 581 speed = 0.1;
andrewm@0 582 gOscBanks[gCurrentOscBank]->setSpeed(speed);
andrewm@0 583 dbox_printf("Speed: %f\n", speed);
andrewm@0 584 break;
andrewm@0 585 case '1':
andrewm@0 586 speed = 0.5;
andrewm@0 587 gOscBanks[gCurrentOscBank]->setSpeed(speed);
andrewm@0 588 dbox_printf("Speed: %f\n", speed);
andrewm@0 589 break;
andrewm@0 590 case '2':
andrewm@0 591 speed = 1;
andrewm@0 592 gOscBanks[gCurrentOscBank]->setSpeed(speed);
andrewm@0 593 dbox_printf("Speed: %f\n", speed);
andrewm@0 594 break;
andrewm@0 595 case '3':
andrewm@0 596 speed = 2;
andrewm@0 597 gOscBanks[gCurrentOscBank]->setSpeed(speed);
andrewm@0 598 dbox_printf("Speed: %f\n", speed);
andrewm@0 599 break;
andrewm@0 600 case '4':
andrewm@0 601 speed = 3;
andrewm@0 602 gOscBanks[gCurrentOscBank]->setSpeed(speed);
andrewm@0 603 dbox_printf("Speed: %f\n", speed);
andrewm@0 604 break;
andrewm@0 605 //----------------------------------------------------------------------------
andrewm@0 606 case 'z':
andrewm@0 607 gOscBanks[gCurrentOscBank]->setJumpHop(0);
andrewm@0 608 break;
andrewm@0 609 case 'x':
andrewm@0 610 gOscBanks[gCurrentOscBank]->setJumpHop(100);
andrewm@0 611 break;
andrewm@0 612 case 'c':
andrewm@0 613 gOscBanks[gCurrentOscBank]->setJumpHop(600);
andrewm@0 614 break;
andrewm@0 615 case 'v':
andrewm@0 616 gOscBanks[gCurrentOscBank]->setJumpHop(1100);
andrewm@0 617 break;
andrewm@0 618 case 'b':
andrewm@0 619 gOscBanks[gCurrentOscBank]->setJumpHop(2000);
andrewm@0 620 break;
andrewm@0 621 case 'n':
andrewm@0 622 gOscBanks[gCurrentOscBank]->setJumpHop(gOscBanks[gCurrentOscBank]->getLastHop());
andrewm@0 623 break;
andrewm@0 624 //----------------------------------------------------------------------------
andrewm@0 625 case 'q':
andrewm@0 626 gShouldStop = true;
andrewm@0 627 break;
andrewm@0 628 case 'o':
andrewm@0 629 gNextOscBank = (gCurrentOscBank + 1) % gOscBanks.size();
andrewm@0 630 break;
andrewm@0 631 default:
andrewm@0 632 break;
andrewm@0 633 //----------------------------------------------------------------------------
andrewm@0 634 }
andrewm@0 635 usleep(1000); /* Wait 1ms to avoid checking too quickly */
andrewm@0 636 }
andrewm@0 637 while (keyStroke!='q');
andrewm@0 638
andrewm@0 639 cout << "keyboard thread ended" << endl;
andrewm@0 640
andrewm@0 641 return (void *)0;
andrewm@0 642 }