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 andrewm@0: #include andrewm@0: #include andrewm@0: #include andrewm@0: #include 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 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; igetFrequencyScaler(); 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 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; i0) andrewm@0: { andrewm@0: // sort, from min to max distance andrewm@0: float tmp; andrewm@0: while(distances[index]=0; i--) andrewm@0: { andrewm@0: if(!prevAssigned[i]) andrewm@0: { andrewm@0: for(int j=0; ji) andrewm@0: s0SortedTouchIndices[j]--; andrewm@0: } andrewm@0: } andrewm@0: } andrewm@0: // done! now update andrewm@0: for(int i=0; i 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; ifilterNum; 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; ifilterNum; 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; i0) andrewm@0: { andrewm@0: // sort, from min to max distance andrewm@0: float tmp; andrewm@0: while(distances[index]=0; i--) andrewm@0: { andrewm@0: if(!prevAssigned[i]) andrewm@0: { andrewm@0: for(int j=0; ji) andrewm@0: s1SortedTouchIndices[j]--; andrewm@0: } andrewm@0: } andrewm@0: } andrewm@0: // done! now update andrewm@0: for(int i=0; i 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; ihopNumTh = 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: }