-//by marshmellow
-void askAmp(uint8_t *BitStream, size_t size)
-{
- int shift = 127;
- int shiftedVal=0;
- for(int i = 1; i<size; i++){
- if (BitStream[i]-BitStream[i-1]>=30) //large jump up
- shift=127;
- else if(BitStream[i]-BitStream[i-1]<=-20) //large jump down
- shift=-127;
-
- shiftedVal=BitStream[i]+shift;
-
- if (shiftedVal>255)
- shiftedVal=255;
- else if (shiftedVal<0)
- shiftedVal=0;
- BitStream[i-1] = shiftedVal;
- }
- return;
-}
-
-int cleanAskRawDemod(uint8_t *BinStream, size_t *size, int clk, int invert, int high, int low)
-{
- size_t bitCnt=0, smplCnt=0, errCnt=0;
- uint8_t waveHigh = 0;
- //PrintAndLog("clk: %d", clk);
- for (size_t i=0; i < *size; i++){
- if (BinStream[i] >= high && waveHigh){
- smplCnt++;
- } else if (BinStream[i] <= low && !waveHigh){
- smplCnt++;
- } else { //transition
- if ((BinStream[i] >= high && !waveHigh) || (BinStream[i] <= low && waveHigh)){
- if (smplCnt > clk-(clk/4)-1) { //full clock
- if (smplCnt > clk + (clk/4)+1) { //too many samples
- errCnt++;
- BinStream[bitCnt++]=77;
- } else if (waveHigh) {
- BinStream[bitCnt++] = invert;
- BinStream[bitCnt++] = invert;
- } else if (!waveHigh) {
- BinStream[bitCnt++] = invert ^ 1;
- BinStream[bitCnt++] = invert ^ 1;
- }
- waveHigh ^= 1;
- smplCnt = 0;
- } else if (smplCnt > (clk/2) - (clk/4)-1) {
- if (waveHigh) {
- BinStream[bitCnt++] = invert;
- } else if (!waveHigh) {
- BinStream[bitCnt++] = invert ^ 1;
- }
- waveHigh ^= 1;
- smplCnt = 0;
- } else if (!bitCnt) {
- //first bit
- waveHigh = (BinStream[i] >= high);
- smplCnt = 1;
- } else {
- smplCnt++;
- //transition bit oops
- }
- } else { //haven't hit new high or new low yet
- smplCnt++;
- }
- }
- }
- *size = bitCnt;
- return errCnt;
-}
-
-//by marshmellow
-//takes 3 arguments - clock, invert and maxErr as integers
-//attempts to demodulate ask only
-int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr, uint8_t amp)
-{
- uint32_t i;
- if (*size==0) return -1;
- int start = DetectASKClock(BinStream, *size, clk, 20); //clock default
- if (*clk==0) return -1;
- if (start<0) return -1;
- if (*invert != 0 && *invert != 1) *invert =0;
- if (amp==1) askAmp(BinStream, *size);
-
- uint32_t initLoopMax = 200;
- if (initLoopMax > *size) initLoopMax=*size;
- // Detect high and lows
- //25% clip in case highs and lows aren't clipped [marshmellow]
- uint8_t clip = 75;
- int high, low, ans;
- ans = getHiLo(BinStream, initLoopMax, &high, &low, clip, clip);
- if (ans<1) return -1; //just noise
-
- if (DetectCleanAskWave(BinStream, *size, high, low)) {
- //PrintAndLog("Clean");
- return cleanAskRawDemod(BinStream, size, *clk, *invert, high, low);
- }
-
- //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low);
- int lastBit = 0; //set first clock check
- uint32_t bitnum = 0; //output counter
- uint8_t tol = 0; //clock tolerance adjust - waves will be accepted as within the clock
- // if they fall + or - this value + clock from last valid wave
- if (*clk == 32) tol=0; //clock tolerance may not be needed anymore currently set to
- // + or - 1 but could be increased for poor waves or removed entirely
- uint32_t iii = 0;
- uint32_t gLen = *size;
- if (gLen > 500) gLen=500;
- //if 0 errors allowed then only try first 2 clock cycles as we want a low tolerance
- if (!maxErr) gLen = *clk * 2;
- uint8_t errCnt =0;
- uint32_t bestStart = *size;
- uint32_t bestErrCnt = maxErr; //(*size/1000);
- uint8_t midBit=0;
- uint16_t MaxBits=1000;
-
- //PrintAndLog("DEBUG - lastbit - %d",lastBit);
- //loop to find first wave that works
- for (iii=start; iii < gLen; ++iii){
- if ((BinStream[iii]>=high) || (BinStream[iii]<=low)){
- lastBit=iii-*clk;
- errCnt=0;
- //loop through to see if this start location works
- for (i = iii; i < *size; ++i) {
- if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){
- lastBit+=*clk;
- midBit=0;
- } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){
- //low found and we are expecting a bar
- lastBit+=*clk;
- midBit=0;
- } else if ((BinStream[i]<=low) && (midBit==0) && ((i-lastBit)>((*clk/2)-tol))){
- //mid bar?
- midBit=1;
- } else if ((BinStream[i]>=high) && (midBit==0) && ((i-lastBit)>((*clk/2)-tol))){
- //mid bar?
- midBit=1;
- } else if ((i-lastBit)>((*clk/2)+tol) && (midBit==0)){
- //no mid bar found
- midBit=1;
- } else {
- //mid value found or no bar supposed to be here
-
- if ((i-lastBit)>(*clk+tol)){
- //should have hit a high or low based on clock!!
- //debug
- //PrintAndLog("DEBUG - no wave in expected area - location: %d, expected: %d-%d, lastBit: %d - resetting search",i,(lastBit+(clk-((int)(tol)))),(lastBit+(clk+((int)(tol)))),lastBit);
-
- errCnt++;
- lastBit+=*clk;//skip over until hit too many errors
- if (errCnt > maxErr){
- //errCnt=0;
- break;
- }
- }
- }
- if ((i-iii)>(MaxBits * *clk)) break; //got enough bits
- }
- //we got more than 64 good bits and not all errors
- if ((((i-iii)/ *clk) > (64)) && (errCnt<=maxErr)) {
- //possible good read
- if (errCnt==0){
- bestStart=iii;
- bestErrCnt=errCnt;
- break; //great read - finish
- }
- if (errCnt<bestErrCnt){ //set this as new best run
- bestErrCnt=errCnt;
- bestStart = iii;
- }
- }
- }
- }
- if (bestErrCnt<=maxErr){
- //best run is good enough - set to best run and overwrite BinStream
- iii = bestStart;
- lastBit = bestStart - *clk;
- bitnum=0;
- for (i = iii; i < *size; ++i) {
- if ((BinStream[i] >= high) && ((i-lastBit) > (*clk-tol))){
- lastBit += *clk;
- BinStream[bitnum] = *invert;
- bitnum++;
- midBit=0;
- } else if ((BinStream[i] <= low) && ((i-lastBit) > (*clk-tol))){
- //low found and we are expecting a bar
- lastBit+=*clk;
- BinStream[bitnum] = 1 - *invert;
- bitnum++;
- midBit=0;
- } else if ((BinStream[i]<=low) && (midBit==0) && ((i-lastBit)>((*clk/2)-tol))){
- //mid bar?
- midBit=1;
- BinStream[bitnum] = 1 - *invert;
- bitnum++;
- } else if ((BinStream[i]>=high) && (midBit==0) && ((i-lastBit)>((*clk/2)-tol))){
- //mid bar?
- midBit=1;
- BinStream[bitnum] = *invert;
- bitnum++;
- } else if ((i-lastBit)>((*clk/2)+tol) && (midBit==0)){
- //no mid bar found
- midBit=1;
- if (bitnum!=0) BinStream[bitnum] = BinStream[bitnum-1];
- bitnum++;
-
- } else {
- //mid value found or no bar supposed to be here
- if ((i-lastBit)>(*clk+tol)){
- //should have hit a high or low based on clock!!
-
- //debug
- //PrintAndLog("DEBUG - no wave in expected area - location: %d, expected: %d-%d, lastBit: %d - resetting search",i,(lastBit+(clk-((int)(tol)))),(lastBit+(clk+((int)(tol)))),lastBit);
- if (bitnum > 0){
- BinStream[bitnum]=77;
- bitnum++;
- }
- lastBit+=*clk;//skip over error
- }
- }
- if (bitnum >= MaxBits) break;
- }
- *size=bitnum;
- } else{
- *invert=bestStart;
- *clk=iii;
- return -1;
- }
- return bestErrCnt;
-}
-