andrewm@0: /* andrewm@0: * sensors.cpp andrewm@0: * andrewm@0: * Created on: May 28, 2014 andrewm@0: * Author: Victor Zappi andrewm@0: */ andrewm@0: andrewm@0: #include <stdio.h> andrewm@0: #include <pthread.h> andrewm@0: #include <unistd.h> andrewm@0: #include <math.h> andrewm@0: #include <vector> andrewm@0: #include "prio.h" andrewm@0: #include "sensors.h" andrewm@0: #include "OscillatorBank.h" andrewm@0: #include "DboxSensors.h" andrewm@0: andrewm@0: andrewm@0: //---------------------------------------- andrewm@0: // main extern variables andrewm@0: //---------------------------------------- andrewm@0: extern vector<OscillatorBank*> gOscBanks; andrewm@0: extern int gCurrentOscBank; andrewm@0: extern int gNextOscBank; giuliomoro@233: extern int gShouldStop; andrewm@0: extern int gVerbose; andrewm@0: andrewm@0: float gSensor0LatestTouchPos = 0; // most recent pitch touch location [0-1] on sensor 0, used by render.cpp andrewm@0: int gSensor0LatestTouchNum = 0; // most recent num of touches on sensor 0, used by render.cpp andrewm@0: float gSensor1LatestTouchPos[5]; // most recent touche locations on sensor 1, used by render.cpp andrewm@0: //float gSensor1LatestTouchSizes[5]; andrewm@0: int gSensor1LatestTouchCount; // most recent number touches on sensor 1, used by render.cpp andrewm@0: int gSensor1LatestTouchIndex = 0; // index of last touch in gSensor1LatestTouchPos[5], used by render.cpp andrewm@0: int gLastFSRValue = 1799; // most recent fsr value, used by render.cpp andrewm@0: andrewm@0: andrewm@0: DboxSensors Sensors; andrewm@0: andrewm@0: andrewm@0: //---------------------------------------- andrewm@0: // var shared with logger andrewm@0: //---------------------------------------- andrewm@0: int s0TouchNum = 0; andrewm@0: float s0Touches_[MAX_TOUCHES]; andrewm@0: float s0Size_[MAX_TOUCHES]; andrewm@0: int s0LastIndex; andrewm@0: andrewm@0: int s1TouchNum = 0; andrewm@0: float s1Touches_[MAX_TOUCHES]; andrewm@0: float s1Size_[MAX_TOUCHES]; andrewm@0: int s1LastIndex; andrewm@0: andrewm@0: int fsr = 1799; andrewm@0: andrewm@0: andrewm@0: andrewm@0: using namespace std; andrewm@0: andrewm@15: int initSensorLoop(int sensorAddress0, int sensorAddress1, int sensorType) andrewm@0: { andrewm@0: int tk0_bus = 1; andrewm@0: int tk0_address = sensorAddress0; andrewm@0: int tk1_bus = 1; andrewm@0: int tk1_address = sensorAddress1; andrewm@0: int tk_file = 0; andrewm@0: int fsr_max = 1799; andrewm@0: int fsr_pinNum = 4; andrewm@0: andrewm@0: if(gVerbose==1) andrewm@0: cout << "---------------->Init Control Thread" << endl; andrewm@0: andrewm@15: if(Sensors.initSensors(tk0_bus, tk0_address, tk1_bus, tk1_address, tk_file, fsr_pinNum, fsr_max, sensorType)>0) andrewm@0: { andrewm@0: gShouldStop = 1; andrewm@0: cout << "control cannot start" << endl; andrewm@0: return -1; andrewm@0: } andrewm@0: andrewm@0: for(int i=0; i<MAX_TOUCHES; i++) andrewm@0: { andrewm@0: s0Touches_[i] = 0.0; andrewm@0: s0Size_[i] = 0.0; andrewm@0: andrewm@0: s1Touches_[i] = 0.0; andrewm@0: s1Size_[i] = 0.0; andrewm@0: } andrewm@0: andrewm@0: return 0; andrewm@0: } andrewm@0: andrewm@0: void sensorLoop(void *) andrewm@0: { andrewm@0: timeval start, end; andrewm@0: unsigned long elapsedTime; andrewm@0: //float touchSize = 0; // once used for timbre andrewm@0: andrewm@0: andrewm@0: andrewm@0: float *s0Touches; andrewm@0: float *s0Size; andrewm@0: int s0PrevTouchNum = 0; andrewm@0: int s0SortedTouchIndices[MAX_TOUCHES]; andrewm@0: float s0SortedTouches[MAX_TOUCHES]; andrewm@0: float s0PrevSortedTouches[MAX_TOUCHES]; andrewm@0: andrewm@0: float *s1Touches; andrewm@0: float *s1Size; andrewm@0: int s1PrevTouchNum = 0; andrewm@0: int s1SortedTouchIndices[MAX_TOUCHES]; andrewm@0: float s1SortedTouches[MAX_TOUCHES]; andrewm@0: float s1PrevSortedTouches[MAX_TOUCHES]; andrewm@0: andrewm@0: float freqScaler = 0; andrewm@0: int fsrMin = 0;//50; // was 200 andrewm@0: int fsrMax = 1799;//1300; // was 800 andrewm@0: float vel = 0; andrewm@0: float prevVel = 0; andrewm@0: float filterMaxF = 0; andrewm@0: if(gVerbose==1) andrewm@0: dbox_printf("__________set Control Thread priority\n"); andrewm@0: andrewm@0: if(gVerbose==1) andrewm@0: dbox_printf("_________________Control Thread!\n"); andrewm@0: andrewm@0: // get freq scaler, cos freqs must be scaled according to the wavetable used in the oscillator bank andrewm@0: freqScaler = gOscBanks[gCurrentOscBank]->getFrequencyScaler(); andrewm@0: filterMaxF = gOscBanks[gCurrentOscBank]->filterMaxF; andrewm@0: andrewm@0: // init time vals andrewm@0: gettimeofday(&start, NULL); andrewm@0: andrewm@0: // here we go, sensor loop until the end of the application andrewm@0: while(!gShouldStop) andrewm@0: { andrewm@0: gettimeofday(&end, NULL); andrewm@0: elapsedTime = ( (end.tv_sec*1000000+end.tv_usec) - (start.tv_sec*1000000+start.tv_usec) ); andrewm@0: if( elapsedTime<4000 ) andrewm@0: usleep(4000-elapsedTime); andrewm@0: else andrewm@0: dbox_printf("%d\n", (int)elapsedTime); // this print happens when something's gone bad... andrewm@0: andrewm@0: if(Sensors.readSensors()==0) andrewm@0: { andrewm@0: s0TouchNum = Sensors.getTKTouchCount(0); andrewm@0: s0Touches = Sensors.getTKXPositions(0); andrewm@0: s0Size = Sensors.getTKTouchSize(0); andrewm@0: andrewm@0: s1TouchNum = Sensors.getTKTouchCount(1); andrewm@0: s1Touches = Sensors.getTKXPositions(1); andrewm@0: s1Size = Sensors.getTKTouchSize(1); andrewm@0: andrewm@0: for(int i=0; i<MAX_TOUCHES; i++) andrewm@0: { andrewm@0: s0Touches_[i] = s0Touches[i]; andrewm@0: s0Size_[i] = s0Size[i]; andrewm@0: andrewm@0: s1Touches_[i] = s1Touches[i]; andrewm@0: s1Size_[i] = s1Size[i]; andrewm@0: } andrewm@0: andrewm@0: gSensor0LatestTouchNum = s0TouchNum; andrewm@0: if(s0TouchNum > 0) andrewm@0: { andrewm@0: //----------------------------------------------------------------------------------- andrewm@0: // timbre, speed and pitch andrewm@0: //touchSize = 0; \\ once used for timbre andrewm@0: andrewm@0: // if we have a number of touches different from previous round, track their order of arrival [calculated using distance comparison] andrewm@0: if(s0PrevTouchNum!=s0TouchNum) andrewm@0: { andrewm@0: float distances[MAX_TOUCHES*(MAX_TOUCHES-1)]; // maximum number of current+previous touches between rounds with different num of touches andrewm@0: int ids[MAX_TOUCHES*(MAX_TOUCHES-1)]; andrewm@0: // calculate all distance permutations between previous and current touches andrewm@0: for(int i=0; i<s0TouchNum; i++) andrewm@0: { andrewm@0: for(int p=0; p<s0PrevTouchNum; p++) andrewm@0: { andrewm@0: int index = i*s0PrevTouchNum+p; // permutation id [says between which touches we are calculating distance] andrewm@0: distances[index] = fabs(s0Touches[i]-s0PrevSortedTouches[p]); andrewm@0: ids[index] = index; andrewm@0: if(index>0) andrewm@0: { andrewm@0: // sort, from min to max distance andrewm@0: float tmp; andrewm@0: while(distances[index]<distances[index-1]) andrewm@0: { andrewm@0: tmp = ids[index-1]; andrewm@0: ids[index-1] = ids[index]; andrewm@0: ids[index] = tmp; andrewm@0: andrewm@0: tmp = distances[index-1]; andrewm@0: distances[index-1] = distances[index]; andrewm@0: distances[index] = tmp; andrewm@0: andrewm@0: index--; andrewm@0: andrewm@0: if(index == 0) andrewm@0: break; andrewm@0: } andrewm@0: } andrewm@0: } andrewm@0: } andrewm@0: andrewm@0: int sorted = 0; andrewm@0: bool currAssigned[MAX_TOUCHES] = {false}; andrewm@0: bool prevAssigned[MAX_TOUCHES] = {false}; andrewm@0: andrewm@0: // track touches assigning index according to shortest distance andrewm@0: for(int i=0; i<s0TouchNum*s0PrevTouchNum; i++) andrewm@0: { andrewm@0: int currentIndex = ids[i]/s0PrevTouchNum; andrewm@0: int prevIndex = ids[i]%s0PrevTouchNum; andrewm@0: // avoid double assignment andrewm@0: if(!currAssigned[currentIndex] && !prevAssigned[prevIndex]) andrewm@0: { andrewm@0: currAssigned[currentIndex] = true; andrewm@0: prevAssigned[prevIndex] = true; andrewm@0: s0SortedTouchIndices[currentIndex] = prevIndex; andrewm@0: sorted++; andrewm@0: } andrewm@0: } andrewm@0: // we still have to assign a free index to new touches andrewm@0: if(s0PrevTouchNum<s0TouchNum) andrewm@0: { andrewm@0: for(int i=0; i<s0TouchNum; i++) andrewm@0: { andrewm@0: if(!currAssigned[i]) andrewm@0: s0SortedTouchIndices[i] = sorted++; // assign next free index andrewm@0: andrewm@0: // update tracked value andrewm@0: s0SortedTouches[s0SortedTouchIndices[i]] = s0Touches[i]; andrewm@0: s0PrevSortedTouches[i] = s0SortedTouches[i]; andrewm@0: if(s0SortedTouchIndices[i]==s0TouchNum-1) andrewm@0: s0LastIndex = i; andrewm@0: andrewm@0: // accumulate sizes for timbre andrewm@0: //touchSize += s0Size[i]; andrewm@0: } andrewm@0: } andrewm@0: else // some touches have disappeared... andrewm@0: { andrewm@0: // ...we have to shift all indices... andrewm@0: for(int i=s0PrevTouchNum-1; i>=0; i--) andrewm@0: { andrewm@0: if(!prevAssigned[i]) andrewm@0: { andrewm@0: for(int j=0; j<s0TouchNum; j++) andrewm@0: { andrewm@0: // ...only if touches that disappeared were before the current one andrewm@0: if(s0SortedTouchIndices[j]>i) andrewm@0: s0SortedTouchIndices[j]--; andrewm@0: } andrewm@0: } andrewm@0: } andrewm@0: // done! now update andrewm@0: for(int i=0; i<s0TouchNum; i++) andrewm@0: { andrewm@0: // update tracked value andrewm@0: s0SortedTouches[s0SortedTouchIndices[i]] = s0Touches[i]; andrewm@0: s0PrevSortedTouches[i] = s0SortedTouches[i]; andrewm@0: if(s0SortedTouchIndices[i]==s0TouchNum-1) andrewm@0: s0LastIndex = i; andrewm@0: andrewm@0: // accumulate sizes for timbre andrewm@0: //touchSize += s0Size[i]; andrewm@0: } andrewm@0: } andrewm@0: } andrewm@0: else // nothing's changed since last round andrewm@0: { andrewm@0: for(int i=0; i<s0TouchNum; i++) andrewm@0: { andrewm@0: // update tracked value andrewm@0: s0SortedTouches[s0SortedTouchIndices[i]] = s0Touches[i]; andrewm@0: s0PrevSortedTouches[i] = s0SortedTouches[i]; andrewm@0: andrewm@0: // accumulate sizes for timbre andrewm@0: //touchSize += s0Size[i]; andrewm@0: } andrewm@0: } andrewm@0: andrewm@0: if(s0TouchNum == 0) andrewm@0: s0LastIndex = -1; andrewm@0: andrewm@0: // timbre andrewm@0: //touchSize = (touchSize > 0.7) ? 1 : touchSize/0.7; andrewm@0: //gOscBanks[gCurrentOscBank]->hopNumTh = log((1-touchSize)+1)/log(2)*20000; andrewm@0: //gOscBanks[gCurrentOscBank]->hopNumTh = 0; andrewm@0: andrewm@0: andrewm@0: // pitch, controlled by last touch andrewm@0: //prevTouchPos = touch[touchIndex]; andrewm@0: //touchPos = (s0SortedTouches[s0TouchNum-1]-0.5)/0.5; // from [0,1] to [-1,1] andrewm@0: gSensor0LatestTouchPos = s0SortedTouches[s0TouchNum-1]; andrewm@0: //touchPos = s0Touches[0]; andrewm@0: //gOscBanks[gCurrentOscBank]->pitchMultiplier = pow(2, touchPos); andrewm@0: //----------------------------------------------------------------------------------- andrewm@0: andrewm@0: andrewm@0: andrewm@0: //----------------------------------------------------------------------------------- andrewm@0: // note on andrewm@0: //if(s0PrevTouchNum == 0) andrewm@0: // gOscBanks[gCurrentOscBank]->play(); andrewm@0: // fsr = Sensors.getFSRVAlue(); andrewm@0: fsr = gLastFSRValue; andrewm@0: //dbox_printf("fsr: %d\n", fsr); andrewm@0: if(!gOscBanks[gCurrentOscBank]->note) andrewm@0: { andrewm@0: vel = fsr; andrewm@0: vel /= (float)(fsrMax-fsrMin); andrewm@0: andrewm@0: vel = 1-vel; andrewm@0: dbox_printf("Attack vel: %f\n", vel); andrewm@0: gOscBanks[gCurrentOscBank]->play(vel); andrewm@0: prevVel = vel; andrewm@0: } andrewm@0: else if(gOscBanks[gCurrentOscBank]->getEnvelopeState() != env_release) andrewm@0: { andrewm@0: fsr = (fsr > fsrMax) ? fsrMax : fsr; andrewm@0: vel = (fsr < fsrMin) ? fsrMin : fsr; andrewm@0: vel -= fsrMin; andrewm@0: vel /= (float)(fsrMax-fsrMin); andrewm@0: vel = 1-vel; andrewm@0: if(vel > prevVel) andrewm@0: { andrewm@0: gOscBanks[gCurrentOscBank]->afterTouch(vel); andrewm@0: prevVel = vel; andrewm@0: } andrewm@0: } andrewm@0: //----------------------------------------------------------------------------------- andrewm@0: } andrewm@0: else andrewm@0: { andrewm@0: //prevFsr = 1799; andrewm@0: //prevTouchPos = -1; andrewm@0: //----------------------------------------------------------------------------------- andrewm@0: // note off andrewm@0: if(s0PrevTouchNum > 0) andrewm@0: { andrewm@0: if(gOscBanks[gCurrentOscBank]->state==bank_playing) andrewm@0: gOscBanks[gCurrentOscBank]->stop(); andrewm@0: } andrewm@0: //----------------------------------------------------------------------------------- andrewm@0: } andrewm@0: andrewm@0: andrewm@0: andrewm@0: // sensor 2 andrewm@0: //----------------------------------------------------------------------------------- andrewm@0: //filter - calculated even when no touches on first sensor, to filter also release tail andrewm@0: gOscBanks[gCurrentOscBank]->filterNum = s1TouchNum; andrewm@0: andrewm@0: gSensor1LatestTouchCount = gOscBanks[gCurrentOscBank]->filterNum; andrewm@0: for(int i = 0; i < gSensor1LatestTouchCount; i++) { andrewm@0: gSensor1LatestTouchPos[i] = s1Touches[i]; andrewm@0: //gSensor1LatestTouchSizes[i] = s1Size[i]; andrewm@0: } andrewm@0: andrewm@0: /* for(int i=0; i<gOscBanks[gCurrentOscBank]->filterNum; i++) andrewm@0: { andrewm@0: // touch pos is linear but freqs are log andrewm@0: gOscBanks[gCurrentOscBank]->filterFreqs[i] = ((exp(s0Touches[i]*4)-1)/(exp(4)-1))*filterMaxF*freqScaler; andrewm@0: //gOscBanks[gCurrentOscBank]->filterQ[i] = size[i]*5*(1+touch[i]*1000)*freqScaler; andrewm@0: gOscBanks[gCurrentOscBank]->filterQ[i] = s0Size[i]; andrewm@0: if(gOscBanks[gCurrentOscBank]->filterFreqs[i]>500*freqScaler) andrewm@0: gOscBanks[gCurrentOscBank]->filterPadding[i] = 1+100000*( (gOscBanks[gCurrentOscBank]->filterFreqs[i]-500*freqScaler)/(filterMaxF-500)*freqScaler ); andrewm@0: else andrewm@0: gOscBanks[gCurrentOscBank]->filterPadding[i] = 1; andrewm@0: }*/ andrewm@0: andrewm@0: // each touch on sensor 2 is a notch filter, whose Q is determined by touch size andrewm@0: for(int i=0; i<gOscBanks[gCurrentOscBank]->filterNum; i++) andrewm@0: { andrewm@0: // map touch pos [which is linear] on freqs exponentially andrewm@0: float freq = ((exp(s1Touches[i]*4)-1)/EXP_DENOM)*filterMaxF; andrewm@0: gOscBanks[gCurrentOscBank]->filterFreqs[i] = freq*freqScaler; andrewm@0: // also size is mapped exponentially on Q andrewm@0: float siz = (exp(s1Size[i])-1)/1.71828; andrewm@0: gOscBanks[gCurrentOscBank]->filterQ[i] = siz*( (filterMaxF-freq)/filterMaxF * 0.9 + 0.1 ); // size weight on Q decreases with frequency andrewm@0: } andrewm@0: //----------------------------------------------------------------------------------- andrewm@0: andrewm@0: andrewm@0: andrewm@0: //----------------------------------------------------------------------------------- andrewm@0: // sort touches on sensor 2 andrewm@0: if(s1TouchNum > 0) andrewm@0: { andrewm@0: // if we have a number of touches different from previous round, track their order of arrival [calculated using distance comparison] andrewm@0: if(s1PrevTouchNum!=s1TouchNum) andrewm@0: { andrewm@0: float distances[MAX_TOUCHES*(MAX_TOUCHES-1)]; // maximum number of current+previous touches between rounds with different num of touches andrewm@0: int ids[MAX_TOUCHES*(MAX_TOUCHES-1)]; andrewm@0: // calculate all distance permutations between previous and current touches andrewm@0: for(int i=0; i<s1TouchNum; i++) andrewm@0: { andrewm@0: for(int p=0; p<s1PrevTouchNum; p++) andrewm@0: { andrewm@0: int index = i*s1PrevTouchNum+p; // permutation id [says between which touches we are calculating distance] andrewm@0: distances[index] = fabs(s1Touches[i]-s1PrevSortedTouches[p]); andrewm@0: ids[index] = index; andrewm@0: if(index>0) andrewm@0: { andrewm@0: // sort, from min to max distance andrewm@0: float tmp; andrewm@0: while(distances[index]<distances[index-1]) andrewm@0: { andrewm@0: tmp = ids[index-1]; andrewm@0: ids[index-1] = ids[index]; andrewm@0: ids[index] = tmp; andrewm@0: andrewm@0: tmp = distances[index-1]; andrewm@0: distances[index-1] = distances[index]; andrewm@0: distances[index] = tmp; andrewm@0: andrewm@0: index--; andrewm@0: andrewm@0: if(index == 0) andrewm@0: break; andrewm@0: } andrewm@0: } andrewm@0: } andrewm@0: } andrewm@0: andrewm@0: int sorted = 0; andrewm@0: bool currAssigned[MAX_TOUCHES] = {false}; andrewm@0: bool prevAssigned[MAX_TOUCHES] = {false}; andrewm@0: andrewm@0: // track touches assigning index according to shortest distance andrewm@0: for(int i=0; i<s1TouchNum*s1PrevTouchNum; i++) andrewm@0: { andrewm@0: int currentIndex = ids[i]/s1PrevTouchNum; andrewm@0: int prevIndex = ids[i]%s1PrevTouchNum; andrewm@0: // avoid double assignment andrewm@0: if(!currAssigned[currentIndex] && !prevAssigned[prevIndex]) andrewm@0: { andrewm@0: currAssigned[currentIndex] = true; andrewm@0: prevAssigned[prevIndex] = true; andrewm@0: s1SortedTouchIndices[currentIndex] = prevIndex; andrewm@0: sorted++; andrewm@0: } andrewm@0: } andrewm@0: // we still have to assign a free index to new touches andrewm@0: if(s1PrevTouchNum<s1TouchNum) andrewm@0: { andrewm@0: for(int i=0; i<s1TouchNum; i++) andrewm@0: { andrewm@0: if(!currAssigned[i]) andrewm@0: s1SortedTouchIndices[i] = sorted++; // assign next free index andrewm@0: andrewm@0: // update tracked value andrewm@0: s1SortedTouches[s1SortedTouchIndices[i]] = s1Touches[i]; andrewm@0: s1PrevSortedTouches[i] = s1SortedTouches[i]; andrewm@0: if(s1SortedTouchIndices[i]==s1TouchNum-1) andrewm@0: s1LastIndex = i; andrewm@0: } andrewm@0: } andrewm@0: else // some touches have disappeared... andrewm@0: { andrewm@0: // ...we have to shift all indices... andrewm@0: for(int i=s1PrevTouchNum-1; i>=0; i--) andrewm@0: { andrewm@0: if(!prevAssigned[i]) andrewm@0: { andrewm@0: for(int j=0; j<s1TouchNum; j++) andrewm@0: { andrewm@0: // ...only if touches that disappeared were before the current one andrewm@0: if(s1SortedTouchIndices[j]>i) andrewm@0: s1SortedTouchIndices[j]--; andrewm@0: } andrewm@0: } andrewm@0: } andrewm@0: // done! now update andrewm@0: for(int i=0; i<s1TouchNum; i++) andrewm@0: { andrewm@0: // update tracked value andrewm@0: s1SortedTouches[s1SortedTouchIndices[i]] = s1Touches[i]; andrewm@0: s1PrevSortedTouches[i] = s1SortedTouches[i]; andrewm@0: if(s1SortedTouchIndices[i]==s1TouchNum-1) andrewm@0: s1LastIndex = i; andrewm@0: } andrewm@0: } andrewm@0: } andrewm@0: else // nothing's changed since last round andrewm@0: { andrewm@0: for(int i=0; i<s1TouchNum; i++) andrewm@0: { andrewm@0: // update tracked value andrewm@0: s1SortedTouches[s1SortedTouchIndices[i]] = s1Touches[i]; andrewm@0: s1PrevSortedTouches[i] = s1SortedTouches[i]; andrewm@0: } andrewm@0: } andrewm@0: } andrewm@0: andrewm@0: if(s1TouchNum > 0) andrewm@0: { andrewm@0: gSensor1LatestTouchIndex = s1LastIndex; andrewm@0: } andrewm@0: else andrewm@0: s1LastIndex = -1; andrewm@0: andrewm@0: /* dbox_printf("-----------------------------\nnum: %d, latest: %d\n", s1TouchNum, gSensor1LatestTouchIndex); andrewm@0: for(int i=0; i<s1TouchNum; i++) andrewm@0: dbox_printf("\t%f\n", gSensor1LatestTouchPos[i]); andrewm@0: dbox_printf("------\n"); andrewm@0: for(int i=0; i<s1TouchNum; i++) andrewm@0: dbox_printf("\t%f\n", s1SortedTouches[i]);*/ andrewm@0: andrewm@0: andrewm@0: andrewm@0: // update variables for both sensors andrewm@0: s0PrevTouchNum = s0TouchNum; andrewm@0: s1PrevTouchNum = s1TouchNum; andrewm@0: } andrewm@0: else andrewm@0: dbox_printf("Come on instrument!\n"); //break andrewm@0: andrewm@0: gettimeofday(&start, NULL); andrewm@0: } andrewm@0: andrewm@0: dbox_printf("sensor thread ended\n"); andrewm@0: } andrewm@0: andrewm@0: void *keyboardLoop(void *) andrewm@0: { andrewm@0: if(gVerbose==1) andrewm@0: cout << "_________________Keyboard Control Thread!" << endl; andrewm@0: andrewm@0: char keyStroke = '.'; andrewm@0: cout << "Press q to quit." << endl; andrewm@0: andrewm@0: float speed; andrewm@0: andrewm@0: do andrewm@0: { andrewm@0: keyStroke = getchar(); andrewm@0: while(getchar()!='\n'); // to read the first stroke andrewm@0: andrewm@0: switch (keyStroke) andrewm@0: { andrewm@0: //---------------------------------------------------------------------------- andrewm@0: case 'a': andrewm@0: gOscBanks[gCurrentOscBank]->hopNumTh = 0; andrewm@0: gOscBanks[gCurrentOscBank]->play(1); andrewm@0: //cout << "Note on" << endl; andrewm@0: break; andrewm@0: case 's': andrewm@0: if(gOscBanks[gCurrentOscBank]->state==bank_playing) andrewm@0: { andrewm@0: gOscBanks[gCurrentOscBank]->stop(); andrewm@0: //cout << "Note off" << endl; andrewm@0: } andrewm@0: break; andrewm@0: //---------------------------------------------------------------------------- andrewm@0: case '[': andrewm@0: gOscBanks[gCurrentOscBank]->freqMovement-=0.05; andrewm@0: if(gOscBanks[gCurrentOscBank]->freqMovement<0) andrewm@0: gOscBanks[gCurrentOscBank]->freqMovement = 0; andrewm@0: //cout << "gOscBanks[gCurrentOscBank]->FreqMov: " << gOscBanks[gCurrentOscBank]->freqMovement << endl; andrewm@0: break; andrewm@0: case ']': andrewm@0: gOscBanks[gCurrentOscBank]->freqMovement+=0.05; andrewm@0: if(gOscBanks[gCurrentOscBank]->freqMovement>1) andrewm@0: gOscBanks[gCurrentOscBank]->freqMovement = 1; andrewm@0: //cout << "gOscBanks[gCurrentOscBank]->FreqMov: " << gOscBanks[gCurrentOscBank]->freqMovement << endl; andrewm@0: break; andrewm@0: //---------------------------------------------------------------------------- andrewm@0: case '<': andrewm@0: speed = gOscBanks[gCurrentOscBank]->getSpeed() - 0.1 ; andrewm@0: gOscBanks[gCurrentOscBank]->setSpeed(speed); andrewm@0: dbox_printf("Speed: %f\n", speed); andrewm@0: andrewm@0: break; andrewm@0: case '>': andrewm@0: speed = gOscBanks[gCurrentOscBank]->getSpeed() + 0.1 ; andrewm@0: gOscBanks[gCurrentOscBank]->setSpeed(speed); andrewm@0: dbox_printf("Speed: %f\n", speed); andrewm@0: break; andrewm@0: case '0': andrewm@0: speed = 0.1; andrewm@0: gOscBanks[gCurrentOscBank]->setSpeed(speed); andrewm@0: dbox_printf("Speed: %f\n", speed); andrewm@0: break; andrewm@0: case '1': andrewm@0: speed = 0.5; andrewm@0: gOscBanks[gCurrentOscBank]->setSpeed(speed); andrewm@0: dbox_printf("Speed: %f\n", speed); andrewm@0: break; andrewm@0: case '2': andrewm@0: speed = 1; andrewm@0: gOscBanks[gCurrentOscBank]->setSpeed(speed); andrewm@0: dbox_printf("Speed: %f\n", speed); andrewm@0: break; andrewm@0: case '3': andrewm@0: speed = 2; andrewm@0: gOscBanks[gCurrentOscBank]->setSpeed(speed); andrewm@0: dbox_printf("Speed: %f\n", speed); andrewm@0: break; andrewm@0: case '4': andrewm@0: speed = 3; andrewm@0: gOscBanks[gCurrentOscBank]->setSpeed(speed); andrewm@0: dbox_printf("Speed: %f\n", speed); andrewm@0: break; andrewm@0: //---------------------------------------------------------------------------- andrewm@0: case 'z': andrewm@0: gOscBanks[gCurrentOscBank]->setJumpHop(0); andrewm@0: break; andrewm@0: case 'x': andrewm@0: gOscBanks[gCurrentOscBank]->setJumpHop(100); andrewm@0: break; andrewm@0: case 'c': andrewm@0: gOscBanks[gCurrentOscBank]->setJumpHop(600); andrewm@0: break; andrewm@0: case 'v': andrewm@0: gOscBanks[gCurrentOscBank]->setJumpHop(1100); andrewm@0: break; andrewm@0: case 'b': andrewm@0: gOscBanks[gCurrentOscBank]->setJumpHop(2000); andrewm@0: break; andrewm@0: case 'n': andrewm@0: gOscBanks[gCurrentOscBank]->setJumpHop(gOscBanks[gCurrentOscBank]->getLastHop()); andrewm@0: break; andrewm@0: //---------------------------------------------------------------------------- andrewm@0: case 'q': andrewm@0: gShouldStop = true; andrewm@0: break; andrewm@0: case 'o': andrewm@0: gNextOscBank = (gCurrentOscBank + 1) % gOscBanks.size(); andrewm@0: break; andrewm@0: default: andrewm@0: break; andrewm@0: //---------------------------------------------------------------------------- andrewm@0: } andrewm@0: usleep(1000); /* Wait 1ms to avoid checking too quickly */ andrewm@0: } andrewm@0: while (keyStroke!='q'); andrewm@0: andrewm@0: cout << "keyboard thread ended" << endl; andrewm@0: andrewm@0: return (void *)0; andrewm@0: }