+// 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);
+}
+
+// by marshmellow - demodulate NRZ wave - requires a read with strong signal
+// peaks invert bit (high=1 low=0) each clock cycle = 1 bit determined by last peak
+int nrzRawDemod_ext(uint8_t *dest, size_t *size, int *clk, int *invert, int *startIdx) {
+ if (justNoise(dest, *size)) return -1;
+ *clk = DetectNRZClock(dest, *size, *clk);
+ if (*clk==0) return -2;
+ size_t i, gLen = 4096;
+ if (gLen>*size) gLen = *size-20;
+ int high, low;
+ if (getHiLo(dest, gLen, &high, &low, 75, 75) < 1) return -3; //25% fuzz on high 25% fuzz on low
+
+ uint8_t bit=0;
+ //convert wave samples to 1's and 0's
+ for(i=20; i < *size-20; i++){
+ if (dest[i] >= high) bit = 1;
+ if (dest[i] <= low) bit = 0;
+ dest[i] = bit;
+ }
+ //now demod based on clock (rf/32 = 32 1's for one 1 bit, 32 0's for one 0 bit)
+ size_t lastBit = 0;
+ size_t numBits = 0;
+ for(i=21; i < *size-20; i++) {
+ //if transition detected or large number of same bits - store the passed bits
+ if (dest[i] != dest[i-1] || (i-lastBit) == (10 * *clk)) {
+ memset(dest+numBits, dest[i-1] ^ *invert, (i - lastBit + (*clk/4)) / *clk);
+ numBits += (i - lastBit + (*clk/4)) / *clk;
+ if (lastBit == 0) {
+ *startIdx = i - (numBits * *clk);
+ if (g_debugMode==2) prnt("DEBUG NRZ: startIdx %i", *startIdx);
+ }
+ lastBit = i-1;
+ }
+ }
+ *size = numBits;
+ return 0;
+}
+int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert) {
+ int startIdx = 0;
+ return nrzRawDemod_ext(dest, size, clk, invert, &startIdx);
+}
+
+//translate wave to 11111100000 (1 for each short wave [higher freq] 0 for each long wave [lower freq])
+size_t fsk_wave_demod(uint8_t * dest, size_t size, uint8_t fchigh, uint8_t fclow, int *startIdx) {
+ size_t last_transition = 0;
+ size_t idx = 1;
+ if (fchigh==0) fchigh=10;
+ if (fclow==0) fclow=8;
+ //set the threshold close to 0 (graph) or 128 std to avoid static
+ uint8_t threshold_value = 123;
+ size_t preLastSample = 0;
+ size_t LastSample = 0;