- if (g_debugMode==2) prnt("DEBUG STT: start of data: %d end of data: %d, datalen: %d, clk: %d, bits: %d, phaseoff: %d", skip, end, end-skip, clk, (end-skip)/clk, phaseoff);
- //now begin to trim out ST so we can use normal demod cmds
- start = skip;
- size_t datalen = end - start;
- // check validity of datalen (should be even clock increments) - use a tolerance of up to 1/8th a clock
- if ( clk - (datalen % clk) <= clk/8) {
- // padd the amount off - could be problematic... but shouldn't happen often
- datalen += clk - (datalen % clk);
- } else if ( (datalen % clk) <= clk/8 ) {
- // padd the amount off - could be problematic... but shouldn't happen often
- datalen -= datalen % clk;
- } else {
- if (g_debugMode==2) prnt("DEBUG STT: datalen not divisible by clk: %u %% %d = %d - quitting", datalen, clk, datalen % clk);
- return false;
- }
- // if datalen is less than one t55xx block - ERROR
- if (datalen/clk < 8*4) {
- if (g_debugMode==2) prnt("DEBUG STT: datalen is less than 1 full t55xx block - quitting");
- return false;
- }
- size_t dataloc = start;
- if (buffer[dataloc-(clk*4)-(clk/8)] <= low && buffer[dataloc] <= low && buffer[dataloc-(clk*4)] >= high) {
- //we have low drift (and a low just before the ST and a low just after the ST) - compensate by backing up the start
- for ( i=0; i <= (clk/8); ++i ) {
- if ( buffer[dataloc - (clk*4) - i] <= low ) {
- dataloc -= i;
- break;
- }
- }
- }
-
- size_t newloc = 0;
- i=0;
- if (g_debugMode==2) prnt("DEBUG STT: Starting STT trim - start: %d, datalen: %d ",dataloc, datalen);
- bool firstrun = true;
- // warning - overwriting buffer given with raw wave data with ST removed...
- while ( dataloc < bufsize-(clk/2) ) {
- //compensate for long high at end of ST not being high due to signal loss... (and we cut out the start of wave high part)
- if (buffer[dataloc]<high && buffer[dataloc]>low && buffer[dataloc+3]<high && buffer[dataloc+3]>low) {
- for(i=0; i < clk/2-tol; ++i) {
- buffer[dataloc+i] = high+5;
- }
- } //test for single sample outlier (high between two lows) in the case of very strong waves
- if (buffer[dataloc] >= high && buffer[dataloc+2] <= low) {
- buffer[dataloc] = buffer[dataloc+2];
- buffer[dataloc+1] = buffer[dataloc+2];
- }
- if (firstrun) {
- *stend = dataloc;
- *ststart = dataloc-(clk*4);
- firstrun=false;
- }
- for (i=0; i<datalen; ++i) {
- if (i+newloc < bufsize) {
- if (i+newloc < dataloc)
- buffer[i+newloc] = buffer[dataloc];
-
- dataloc++;
- }
- }
- newloc += i;
- //skip next ST - we just assume it will be there from now on...
- if (g_debugMode==2) prnt("DEBUG STT: skipping STT at %d to %d", dataloc, dataloc+(clk*4));
- dataloc += clk*4;
- }
- *size = newloc;
- return true;
-}
-bool DetectST(uint8_t buffer[], size_t *size, int *foundclock) {
- size_t ststart = 0, stend = 0;
- return DetectST_ext(buffer, size, foundclock, &ststart, &stend);
-}
-
-//by marshmellow
-//take 01 or 10 = 1 and 11 or 00 = 0
-//check for phase errors - should never have 111 or 000 should be 01001011 or 10110100 for 1010
-//decodes biphase or if inverted it is AKA conditional dephase encoding AKA differential manchester encoding
-int BiphaseRawDecode(uint8_t *BitStream, size_t *size, int offset, int invert) {
- uint16_t bitnum = 0;
- uint16_t errCnt = 0;
- size_t i = offset;
- uint16_t MaxBits=512;
- //if not enough samples - error
- if (*size < 51) return -1;
- //check for phase change faults - skip one sample if faulty
- uint8_t offsetA = 1, offsetB = 1;
- for (; i<48; i+=2){
- if (BitStream[i+1]==BitStream[i+2]) offsetA=0;
- if (BitStream[i+2]==BitStream[i+3]) offsetB=0;
- }
- if (!offsetA && offsetB) offset++;
- for (i=offset; i<*size-3; i+=2){
- //check for phase error
- if (BitStream[i+1]==BitStream[i+2]) {
- BitStream[bitnum++]=7;
- errCnt++;
- }
- if((BitStream[i]==1 && BitStream[i+1]==0) || (BitStream[i]==0 && BitStream[i+1]==1)){
- BitStream[bitnum++]=1^invert;
- } else if((BitStream[i]==0 && BitStream[i+1]==0) || (BitStream[i]==1 && BitStream[i+1]==1)){
- BitStream[bitnum++]=invert;
- } else {
- BitStream[bitnum++]=7;
- errCnt++;
- }
- if(bitnum>MaxBits) break;
- }
- *size=bitnum;
- return errCnt;
-}
-
-//by marshmellow
-//take 10 and 01 and manchester decode
-//run through 2 times and take least errCnt
-int manrawdecode(uint8_t * BitStream, size_t *size, uint8_t invert, uint8_t *alignPos) {
- uint16_t bitnum=0, MaxBits = 512, errCnt = 0;
- size_t i, ii;
- uint16_t bestErr = 1000, bestRun = 0;
- if (*size < 16) return -1;
- //find correct start position [alignment]
- for (ii=0;ii<2;++ii){
- for (i=ii; i<*size-3; i+=2)
- if (BitStream[i]==BitStream[i+1])
- errCnt++;
-
- if (bestErr>errCnt){
- bestErr=errCnt;
- bestRun=ii;
- }
- errCnt=0;
- }
- *alignPos=bestRun;
- //decode
- for (i=bestRun; i < *size-3; i+=2){
- if(BitStream[i] == 1 && (BitStream[i+1] == 0)){
- BitStream[bitnum++]=invert;
- } else if((BitStream[i] == 0) && BitStream[i+1] == 1){
- BitStream[bitnum++]=invert^1;
- } else {
- BitStream[bitnum++]=7;
- }
- if(bitnum>MaxBits) break;
- }
- *size=bitnum;
- return bestErr;
-}
-
-// by marshmellow
-// to detect a wave that has heavily clipped (clean) samples
-uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, uint8_t high, uint8_t low) {
- bool allArePeaks = true;
- uint16_t cntPeaks=0;
- size_t loopEnd = 512+160;
- if (loopEnd > size) loopEnd = size;
- for (size_t i=160; i<loopEnd; i++){
- if (dest[i]>low && dest[i]<high)
- allArePeaks = false;
- else
- cntPeaks++;
- }
- if (!allArePeaks){
- if (cntPeaks > 300) return true;
- }
- return allArePeaks;
-}
-
-//by marshmellow
-//demodulates strong heavily clipped samples
-int cleanAskRawDemod(uint8_t *BinStream, size_t *size, int clk, int invert, int high, int low, int *startIdx)
-{
- *startIdx=0;
- size_t bitCnt=0, smplCnt=1, errCnt=0;
- bool waveHigh = (BinStream[0] >= high);
- for (size_t i=1; 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++;
- if (g_debugMode==2) prnt("DEBUG ASK: Modulation Error at: %u", i);
- BinStream[bitCnt++] = 7;
- } else if (waveHigh) {
- BinStream[bitCnt++] = invert;
- BinStream[bitCnt++] = invert;
- } else if (!waveHigh) {
- BinStream[bitCnt++] = invert ^ 1;
- BinStream[bitCnt++] = invert ^ 1;
- }
- if (*startIdx==0) *startIdx = i-clk;
- waveHigh = !waveHigh;
- smplCnt = 0;
- } else if (smplCnt > (clk/2) - (clk/4)-1) { //half clock
- if (waveHigh) {
- BinStream[bitCnt++] = invert;
- } else if (!waveHigh) {
- BinStream[bitCnt++] = invert ^ 1;
- }
- if (*startIdx==0) *startIdx = i-(clk/2);
- waveHigh = !waveHigh;
- smplCnt = 0;
- } else {
- smplCnt++;
- //transition bit oops
- }
- } else { //haven't hit new high or new low yet
- smplCnt++;
- }
- }
- }
- *size = bitCnt;
- return errCnt;
-}
-
-//by marshmellow
-//attempts to demodulate ask modulations, askType == 0 for ask/raw, askType==1 for ask/manchester
-int askdemod_ext(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr, uint8_t amp, uint8_t askType, int *startIdx) {
- if (*size==0) return -1;
- int start = DetectASKClock(BinStream, *size, clk, maxErr); //clock default
- if (*clk==0 || start < 0) return -3;
- if (*invert != 1) *invert = 0;
- if (amp==1) askAmp(BinStream, *size);
- if (g_debugMode==2) prnt("DEBUG ASK: clk %d, beststart %d, amp %d", *clk, start, amp);
-
- //start pos from detect ask clock is 1/2 clock offset
- // NOTE: can be negative (demod assumes rest of wave was there)
- *startIdx = start - (*clk/2);
- uint8_t initLoopMax = 255;
- if (initLoopMax > *size) initLoopMax = *size;
- // Detect high and lows
- //25% clip in case highs and lows aren't clipped [marshmellow]
- int high, low;
- if (getHiLo(BinStream, initLoopMax, &high, &low, 75, 75) < 1)
- return -2; //just noise
-
- size_t errCnt = 0;
- // if clean clipped waves detected run alternate demod
- if (DetectCleanAskWave(BinStream, *size, high, low)) {
- if (g_debugMode==2) prnt("DEBUG ASK: Clean Wave Detected - using clean wave demod");
- errCnt = cleanAskRawDemod(BinStream, size, *clk, *invert, high, low, startIdx);
- if (askType) { //askman
- uint8_t alignPos = 0;
- errCnt = manrawdecode(BinStream, size, 0, &alignPos);
- *startIdx += *clk/2 * alignPos;
- if (g_debugMode) prnt("DEBUG ASK CLEAN: startIdx %i, alignPos %u", *startIdx, alignPos);
- return errCnt;
- } else { //askraw
- return errCnt;
- }
- }
- if (g_debugMode) prnt("DEBUG ASK WEAK: startIdx %i", *startIdx);
- if (g_debugMode==2) prnt("DEBUG ASK: Weak Wave Detected - using weak wave demod");
-
- int lastBit; //set first clock check - can go negative
- size_t i, bitnum = 0; //output counter
- uint8_t midBit = 0;
- 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 = 1; //clock tolerance may not be needed anymore currently set to + or - 1 but could be increased for poor waves or removed entirely
- size_t MaxBits = 3072; //max bits to collect
- lastBit = start - *clk;
-
- for (i = start; i < *size; ++i) {
- if (i-lastBit >= *clk-tol){
- if (BinStream[i] >= high) {
- BinStream[bitnum++] = *invert;
- } else if (BinStream[i] <= low) {
- BinStream[bitnum++] = *invert ^ 1;
- } else if (i-lastBit >= *clk+tol) {
- if (bitnum > 0) {
- if (g_debugMode==2) prnt("DEBUG ASK: Modulation Error at: %u", i);
- BinStream[bitnum++]=7;
- errCnt++;
- }
- } else { //in tolerance - looking for peak
- continue;
- }
- midBit = 0;
- lastBit += *clk;
- } else if (i-lastBit >= (*clk/2-tol) && !midBit && !askType){
- if (BinStream[i] >= high) {
- BinStream[bitnum++] = *invert;
- } else if (BinStream[i] <= low) {
- BinStream[bitnum++] = *invert ^ 1;
- } else if (i-lastBit >= *clk/2+tol) {
- BinStream[bitnum] = BinStream[bitnum-1];
- bitnum++;
- } else { //in tolerance - looking for peak
- continue;
- }
- midBit = 1;
- }
- if (bitnum >= MaxBits) break;
- }
- *size = bitnum;
- return errCnt;
-}
-
-int askdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr, uint8_t amp, uint8_t askType) {
- int start = 0;
- return askdemod_ext(BinStream, size, clk, invert, maxErr, amp, askType, &start);