annotate projects/d-box/sensors.cpp @ 151:e9c9404e3d1f ClockSync

Pff partially working. No PID. When setting the audio clock on the bbb to 44098 the master and slave clock keep diverging instead of converging ...
author Giulio Moro <giuliomoro@yahoo.it>
date Tue, 22 Sep 2015 04:10:07 +0100
parents 901d205d1a3c
children 18d03901f866
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@15 59 int initSensorLoop(int sensorAddress0, int sensorAddress1, int sensorType)
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@15 72 if(Sensors.initSensors(tk0_bus, tk0_address, tk1_bus, tk1_address, tk_file, fsr_pinNum, fsr_max, sensorType)>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 }