+//by marshmellow
+//encode binary data into binary manchester
+//NOTE: BitStream must have triple the size of "size" available in memory to do the swap
+int ManchesterEncode(uint8_t *BitStream, size_t size) {
+ //allow up to 4K out (means BitStream must be at least 2048+4096 to handle the swap)
+ size = (size>2048) ? 2048 : size;
+ size_t modIdx = size;
+ size_t i;
+ for (size_t idx=0; idx < size; idx++){
+ BitStream[idx+modIdx++] = BitStream[idx];
+ BitStream[idx+modIdx++] = BitStream[idx]^1;
+ }
+ for (i=0; i<(size*2); i++){
+ BitStream[i] = BitStream[i+size];
+ }
+ return i;
+}
+
+// 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;
+}
+
+//**********************************************************************************************
+//-------------------Clock / Bitrate Detection Section------------------------------------------
+//**********************************************************************************************
+
+// by marshmellow
+// to help detect clocks on heavily clipped samples
+// based on count of low to low
+int DetectStrongAskClock(uint8_t dest[], size_t size, int high, int low, int *clock) {
+ size_t startwave;
+ size_t i = 100;
+ size_t minClk = 255;
+ int shortestWaveIdx = 0;
+ // get to first full low to prime loop and skip incomplete first pulse
+ getNextHigh(dest, size, high, &i);
+ getNextLow(dest, size, low, &i);
+
+ // loop through all samples
+ while (i < size) {
+ // measure from low to low
+ startwave = i;
+
+ getNextHigh(dest, size, high, &i);
+ getNextLow(dest, size, low, &i);
+ //get minimum measured distance
+ if (i-startwave < minClk && i < size) {
+ minClk = i - startwave;
+ shortestWaveIdx = startwave;
+ }
+ }
+ // set clock
+ if (g_debugMode==2) prnt("DEBUG ASK: DetectStrongAskClock smallest wave: %d",minClk);
+ *clock = getClosestClock(minClk);
+ if (*clock == 0)
+ return 0;
+
+ return shortestWaveIdx;
+}
+
+// by marshmellow
+// not perfect especially with lower clocks or VERY good antennas (heavy wave clipping)
+// maybe somehow adjust peak trimming value based on samples to fix?
+// return start index of best starting position for that clock and return clock (by reference)
+int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr) {
+ size_t i=1;
+ uint8_t clk[] = {255,8,16,32,40,50,64,100,128,255};
+ uint8_t clkEnd = 9;
+ uint8_t loopCnt = 255; //don't need to loop through entire array...
+ if (size <= loopCnt+60) return -1; //not enough samples
+ size -= 60; //sometimes there is a strange end wave - filter out this....
+ //if we already have a valid clock
+ uint8_t clockFnd=0;
+ for (;i<clkEnd;++i)
+ if (clk[i] == *clock) clockFnd = i;
+ //clock found but continue to find best startpos
+
+ //get high and low peak
+ int peak, low;
+ if (getHiLo(dest, loopCnt, &peak, &low, 75, 75) < 1) return -1;
+
+ //test for large clean peaks
+ if (!clockFnd){
+ if (DetectCleanAskWave(dest, size, peak, low)==1){
+ int ans = DetectStrongAskClock(dest, size, peak, low, clock);
+ if (g_debugMode==2) prnt("DEBUG ASK: detectaskclk Clean Ask Wave Detected: clk %i, ShortestWave: %i",clock, ans);
+ if (ans > 0) {
+ return ans; //return shortest wave start position
+ }
+ }
+ }
+ uint8_t ii;
+ uint8_t clkCnt, tol = 0;
+ uint16_t bestErr[]={1000,1000,1000,1000,1000,1000,1000,1000,1000};
+ uint8_t bestStart[]={0,0,0,0,0,0,0,0,0};
+ size_t errCnt = 0;
+ size_t arrLoc, loopEnd;
+
+ if (clockFnd>0) {
+ clkCnt = clockFnd;
+ clkEnd = clockFnd+1;
+ }
+ else clkCnt=1;
+
+ //test each valid clock from smallest to greatest to see which lines up
+ for(; clkCnt < clkEnd; clkCnt++){
+ if (clk[clkCnt] <= 32){
+ tol=1;
+ }else{
+ tol=0;
+ }
+ //if no errors allowed - keep start within the first clock
+ if (!maxErr && size > clk[clkCnt]*2 + tol && clk[clkCnt]<128) loopCnt=clk[clkCnt]*2;
+ bestErr[clkCnt]=1000;
+ //try lining up the peaks by moving starting point (try first few clocks)
+ for (ii=0; ii < loopCnt; ii++){
+ if (dest[ii] < peak && dest[ii] > low) continue;
+
+ errCnt=0;
+ // now that we have the first one lined up test rest of wave array
+ loopEnd = ((size-ii-tol) / clk[clkCnt]) - 1;
+ for (i=0; i < loopEnd; ++i){
+ arrLoc = ii + (i * clk[clkCnt]);
+ if (dest[arrLoc] >= peak || dest[arrLoc] <= low){
+ }else if (dest[arrLoc-tol] >= peak || dest[arrLoc-tol] <= low){
+ }else if (dest[arrLoc+tol] >= peak || dest[arrLoc+tol] <= low){
+ }else{ //error no peak detected
+ errCnt++;