From 4160e32b0ae050383c56529c3d45a62881b52e86 Mon Sep 17 00:00:00 2001
From: Philippe Teuwen <phil@teuwen.org>
Date: Fri, 8 Mar 2019 19:06:55 +0100
Subject: [PATCH 1/2] Replace isNoise by computeSignalProperties and
 removeSignalOffset

---
 armsrc/lfsampling.c |   7 +--
 client/cmddata.c    |  66 +++++++++++++-------------
 client/cmdlfem4x.c  |  11 +++--
 client/cmdlft55xx.c |   6 ++-
 client/comms.c      |   2 +-
 common/lfdemod.c    | 111 ++++++++++++--------------------------------
 common/lfdemod.h    |  18 ++++---
 7 files changed, 92 insertions(+), 129 deletions(-)

diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c
index 96963d389..4b036d088 100644
--- a/armsrc/lfsampling.c
+++ b/armsrc/lfsampling.c
@@ -204,8 +204,9 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag
 					dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
 	}
 	
-	// Ensure that noise check is performed for any device-side processing
-	isNoise(dest, bufsize);
+	// Ensure that DC offset removal and noise check is performed for any device-side processing
+	removeSignalOffset(dest, bufsize);
+	computeSignalProperties(dest, bufsize);
 	
 	return data.numbits;
 }
@@ -451,4 +452,4 @@ uint32_t doCotagAcquisitionManchester() {
 		}
 	}
 	return sample_counter;
-}
\ No newline at end of file
+}
diff --git a/client/cmddata.c b/client/cmddata.c
index ba3d61156..285b4d189 100644
--- a/client/cmddata.c
+++ b/client/cmddata.c
@@ -1393,15 +1393,13 @@ int CmdHide(const char *Cmd) {
 
 //zero mean GraphBuffer
 int CmdHpf(const char *Cmd) {
-	int i, accum = 0;
-
-	for (i = 10; i < GraphTraceLen; ++i)
-		accum += GraphBuffer[i];
-	
-	accum /= (GraphTraceLen - 10);
-	
-	for (i = 0; i < GraphTraceLen; ++i)
-		GraphBuffer[i] -= accum;
+	uint8_t bits[GraphTraceLen];
+	size_t size = getFromGraphBuf(bits);
+	removeSignalOffset(bits, size);
+	// push it back to graph
+	setGraphBuf(bits, size);
+	// set signal properties low/high/mean/amplitude and is_noise detection
+	computeSignalProperties(bits, size);
 
 	RepaintGraphWindow();
 	return 0;
@@ -1471,12 +1469,15 @@ int getSamples(int n, bool silent) {
 		GraphTraceLen = n;
 	}
 
-	//ICEMAN todo
 	uint8_t bits[GraphTraceLen];
 	size_t size = getFromGraphBuf(bits);
-	// set signal properties low/high/mean/amplitude and is_noice detection
-	isNoise(bits, size);
-	
+	// TODO now DC removal is done already on device, right ?
+	// removeSignalOffset(bits, size);
+	// push it back to graph
+	// setGraphBuf(bits, size);
+	// set signal properties low/high/mean/amplitude and is_noise detection
+	computeSignalProperties(bits, size);
+
 	setClockGrid(0, 0);
 	DemodBufferLen = 0;
 	RepaintGraphWindow();
@@ -1610,15 +1611,19 @@ int CmdLoad(const char *Cmd) {
 		fclose(f);
 
 	PrintAndLogEx(SUCCESS, "loaded %d samples", GraphTraceLen);
+	
+	uint8_t bits[GraphTraceLen];
+	size_t size = getFromGraphBuf(bits);
+	// set signal properties low/high/mean/amplitude and is_noise detection
+	removeSignalOffset(bits, size);
+	// push it back to graph
+	setGraphBuf(bits, size);
+	// set signal properties low/high/mean/amplitude and is_noise detection
+	computeSignalProperties(bits, size);
+
 	setClockGrid(0,0);
 	DemodBufferLen = 0;
 	RepaintGraphWindow();
-	
-	//ICEMAN todo	
-	// set signal properties low/high/mean/amplitude and isnoice detection
-	uint8_t bits[GraphTraceLen];
-	size_t size = getFromGraphBuf(bits);
-	isNoise(bits, size);
 	return 0;
 }
 
@@ -1683,11 +1688,11 @@ int CmdNorm(const char *Cmd) {
 		}
 	}
 
-	//ICEMAN todo	
-	// set signal properties low/high/mean/amplitude and isnoice detection
 	uint8_t bits[GraphTraceLen];
 	size_t size = getFromGraphBuf(bits);
-	isNoise(bits, size);
+	// set signal properties low/high/mean/amplitude and is_noise detection
+	computeSignalProperties(bits, size);
+
 	RepaintGraphWindow();
 	return 0;
 }
@@ -1773,11 +1778,11 @@ int CmdDirectionalThreshold(const char *Cmd) {
 
 	directionalThreshold(GraphBuffer, GraphBuffer, GraphTraceLen, up, down);
 	
-	//ICEMAN todo	
 	// set signal properties low/high/mean/amplitude and isnoice detection
 	uint8_t bits[GraphTraceLen];
 	size_t size = getFromGraphBuf(bits);
-	isNoise(bits, size);
+	// set signal properties low/high/mean/amplitude and is_noice detection
+	computeSignalProperties(bits, size);
 
 	RepaintGraphWindow();
 	return 0;
@@ -1805,11 +1810,10 @@ int CmdZerocrossings(const char *Cmd) {
 		}
 	}
 
-	//ICEMAN todo	
-	// set signal properties low/high/mean/amplitude and isnoice detection
 	uint8_t bits[GraphTraceLen];
 	size_t size = getFromGraphBuf(bits);
-	isNoise(bits, size);
+	// set signal properties low/high/mean/amplitude and is_noise detection
+	computeSignalProperties(bits, size);
 
 	RepaintGraphWindow();
 	return 0;
@@ -2063,13 +2067,11 @@ int CmdDataIIR(const char *Cmd){
 	//iceIIR_Butterworth(GraphBuffer, GraphTraceLen);
 	iceSimple_Filter(GraphBuffer, GraphTraceLen, k);
 
-	//ICEMAN todo	
-	// set signal properties low/high/mean/amplitude and isnoice detection
 	uint8_t bits[GraphTraceLen];
 	size_t size = getFromGraphBuf(bits);
-	isNoise(bits, size);
-
-	RepaintGraphWindow();	
+	// set signal properties low/high/mean/amplitude and is_noise detection
+	computeSignalProperties(bits, size);
+	RepaintGraphWindow();
 	return 0;
 }
 
diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c
index 6d90e550f..e4909ace9 100644
--- a/client/cmdlfem4x.c
+++ b/client/cmdlfem4x.c
@@ -800,7 +800,7 @@ int EM4x50Read(const char *Cmd, bool verbose) {
 	
 	uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0};
 	size_t size = getFromGraphBuf(bits);
-	isNoise(bits, size);
+	computeSignalProperties(bits, size);
 	
 	signal_t *sp = getSignalProperties();
 	high = sp->high;
@@ -999,9 +999,14 @@ bool downloadSamplesEM(){
 		PrintAndLogEx(WARNING, "command execution time out");
 		return false;
 	}
-	setGraphBuf(got, sizeof(got));
 
-	if (isNoise(got, sizeof(got))) {
+	// TODO now DC removal is done already on device, right ?
+	// removeSignalOffset(got, sizeof(got));
+	setGraphBuf(got, sizeof(got));
+	// set signal properties low/high/mean/amplitude and is_noise detection
+	computeSignalProperties(got, sizeof(got));
+	RepaintGraphWindow();
+	if (getSignalProperties()->isnoise) {
 		PrintAndLogEx(DEBUG, "No tag found");
 		return false;
 	}
diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c
index 3c7547e34..446e440ce 100644
--- a/client/cmdlft55xx.c
+++ b/client/cmdlft55xx.c
@@ -1330,8 +1330,12 @@ bool AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password )
 		PrintAndLogEx(WARNING, "command execution time out");
 		return false;
 	}
+	// set signal properties low/high/mean/amplitude and is_noise detection
+	removeSignalOffset(got, sizeof(got));
+	computeSignalProperties(got, sizeof(got));
 	setGraphBuf(got, sizeof(got));
-	return !isNoise(got, sizeof(got));
+	RepaintGraphWindow();
+	return !getSignalProperties()->isnoise;
 }
 
 char * GetBitRateStr(uint32_t id, bool xmode) {
diff --git a/client/comms.c b/client/comms.c
index 5beaa0adb..f08c5f413 100644
--- a/client/comms.c
+++ b/client/comms.c
@@ -463,7 +463,7 @@ bool GetFromDevice(DeviceMemType_t memtype, uint8_t *dest, uint32_t bytes, uint3
 			return dl_it(dest, bytes, start_index, response, ms_timeout, show_warning, CMD_FLASHMEM_DOWNLOADED);
 		}
 		case SIM_MEM: {
-			//UsbCommand c = {CMD_DOWNLOAND_SIM_MEM, {start_index, bytes, 0}};
+			//UsbCommand c = {CMD_DOWNLOAD_SIM_MEM, {start_index, bytes, 0}};
 			//SendCommand(&c);
 			//return dl_it(dest, bytes, start_index, response, ms_timeout, show_warning, CMD_DOWNLOADED_SIMMEM);
 			return false;
diff --git a/common/lfdemod.c b/common/lfdemod.c
index 1fd69d1b9..b9807ff8f 100644
--- a/common/lfdemod.c
+++ b/common/lfdemod.c
@@ -47,8 +47,7 @@
 //**********************************************************************************************
 #define LOWEST_DEFAULT_CLOCK 32
 #define FSK_PSK_THRESHOLD   123
-//might not be high enough for noisy environments
-#define NOICE_AMPLITUDE_THRESHOLD 10
+
 //to allow debug print calls when used not on dev
 
 //void dummy(char *fmt, ...){}
@@ -76,6 +75,7 @@ static void resetSignal(void) {
 	signalprop.amplitude = 0;
 	signalprop.isnoise = true;
 }
+
 static void printSignal(void) {
 	prnt("LF signal properties:");
 	prnt("  high..........%d", signalprop.high);
@@ -83,94 +83,47 @@ static void printSignal(void) {
 	prnt("  mean..........%d", signalprop.mean);
 	prnt("  amplitude.....%d", signalprop.amplitude);
 	prnt("  is Noise......%s", (signalprop.isnoise) ? "Yes" : "No");
-	prnt("  THRESHOLD noice amplitude......%d" , NOICE_AMPLITUDE_THRESHOLD);
+	prnt("  THRESHOLD noise amplitude......%d" , NOISE_AMPLITUDE_THRESHOLD);
 }
 
-// Function to compute mean for a series
-// rounded to integer..
-uint32_t compute_mean_uint(uint8_t *in, size_t N) {
-	uint32_t mean = 0;
-	for (size_t i = 0; i < N; i++)
-		mean += in[i];		
-
-	return mean / N;
-}
-// Function to compute mean for a series
-// rounded to integer..
-int32_t compute_mean_int(int *in, size_t N) {
-	int32_t mean = 0;
-	for (size_t i = 0; i < N; i++)
-		mean += in[i];
-	
-	return mean / (int)N;
-}
-
-void zeromean(uint8_t* data, size_t size) {
-
-	// zero mean data
-	int i, accum = 0;
-	for (i = 10; i < size; ++i)
-		accum += data[i] - 128;
-	accum /= (int)(size - 10);
-
-	for (i = 0; i < size; ++i) {
-		if (accum > 0) {
-			data[i] = (data[i] >= accum)? data[i] - accum : 0;
-		}
-		if (accum < 0) {
-			data[i] = (255 - data[i] >=  -accum)? data[i] - accum : 255;
-		}
-	}
-	// recompute signal characteristics:
-	isNoise(data, size);
-}
-
-//test samples are not just noise
-// By measuring mean and look at amplitude of signal from HIGH / LOW,   we can detect noise
-bool isNoise_int(int *bits, uint32_t size) {
+void computeSignalProperties(uint8_t *samples, uint32_t size) {
 	resetSignal();
-	if ( bits == NULL || size < 100 ) return true;
-	
-	int32_t sum = 0;
-	for ( size_t i = 0; i < size; i++) {
-		if ( bits[i] < signalprop.low ) signalprop.low = bits[i];
-		if ( bits[i] > signalprop.high ) signalprop.high = bits[i];
-		sum += bits[i];		
-	}
 
-	// measure amplitude of signal
-	signalprop.mean = sum / (int)size;
-	signalprop.amplitude = ABS(signalprop.high - signalprop.mean);
-	signalprop.isnoise = signalprop.amplitude < NOICE_AMPLITUDE_THRESHOLD;
-	
-	if (g_debugMode) 
-		printSignal();
-	
-	return signalprop.isnoise;
-}
-//test samples are not just noise
-// By measuring mean and look at amplitude of signal from HIGH / LOW, 
-// we can detect noise
-bool isNoise(uint8_t *bits, uint32_t size) {
-	resetSignal();
-	if ( bits == NULL || size < 100 ) return true;
-	
 	uint32_t sum = 0;
 	for ( uint32_t i = 0; i < size; i++) {
-		if ( bits[i] < signalprop.low ) signalprop.low = bits[i];
-		if ( bits[i] > signalprop.high ) signalprop.high = bits[i];
-		sum += bits[i];		
+		if ( samples[i] < signalprop.low ) signalprop.low = samples[i];
+		if ( samples[i] > signalprop.high ) signalprop.high = samples[i];
+		sum += samples[i];
 	}
 
 	// measure amplitude of signal
 	signalprop.mean = sum / size;
 	signalprop.amplitude = signalprop.high - signalprop.mean;
-	signalprop.isnoise =  signalprop.amplitude < NOICE_AMPLITUDE_THRESHOLD;
-	
+	// By measuring mean and look at amplitude of signal from HIGH / LOW, 
+	// we can detect noise
+	signalprop.isnoise =  signalprop.amplitude < NOISE_AMPLITUDE_THRESHOLD;
+
 	if (g_debugMode) 
 		printSignal();
+}
 
-	return signalprop.isnoise;
+void removeSignalOffset(uint8_t *samples, uint32_t size) {
+	if ( samples == NULL || size < SIGNAL_MIN_SAMPLES ) return;
+
+	int acc_off = 0;
+	for (uint32_t i = SIGNAL_IGNORE_FIRST_SAMPLES; i < size; i++)
+		acc_off += samples[i] - 128;
+	acc_off /= (int)(size - SIGNAL_IGNORE_FIRST_SAMPLES);
+
+	// shift and saturate samples to center the mean
+	for ( uint32_t i = 0; i < size; i++) {
+		if (acc_off > 0) {
+			samples[i] = (samples[i] >= acc_off)? samples[i] - acc_off : 0;
+		}
+		if (acc_off < 0) {
+			samples[i] = (255 - samples[i] >=  -acc_off)? samples[i] - acc_off : 255;
+		}
+	}
 }
 
 //by marshmellow
@@ -1962,8 +1915,6 @@ int detectAWID(uint8_t *dest, size_t *size, int *waveStartIdx) {
 
 	if (signalprop.isnoise) return -2;
 
-	zeromean(dest, *size);
-	
 	// FSK2a demodulator  clock 50, invert 1, fcHigh 10, fcLow 8
 	*size = fskdemod(dest, *size, 50, 1, 10, 8, waveStartIdx); //awid fsk2a
 
@@ -2029,8 +1980,6 @@ int HIDdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32
 	
 	if (signalprop.isnoise) return -2;
 
-	zeromean(dest, *size);
-	
 	// FSK demodulator  fsk2a so invert and fc/10/8
 	*size = fskdemod(dest, *size, 50, 1, 10, 8, waveStartIdx); //hid fsk2a
 
@@ -2090,8 +2039,6 @@ int detectIOProx(uint8_t *dest, size_t *size, int *waveStartIdx) {
 	
 	if (signalprop.isnoise) return -2;
 	
-	zeromean(dest, *size);
-		
 	// FSK demodulator  RF/64, fsk2a so invert, and fc/10/8
 	*size = fskdemod(dest, *size, 64, 1, 10, 8, waveStartIdx);  //io fsk2a
 	
diff --git a/common/lfdemod.h b/common/lfdemod.h
index 43537b18b..a6542059e 100644
--- a/common/lfdemod.h
+++ b/common/lfdemod.h
@@ -20,6 +20,14 @@
 #include <stdbool.h> // for bool
 #include "parity.h"  // for parity test
 #include "util.h"	 // for ARRAYLEN
+
+//might not be high enough for noisy environments
+#define NOISE_AMPLITUDE_THRESHOLD 10
+//ignore buffer with less than x samples
+#define SIGNAL_MIN_SAMPLES 100
+//ignore first x samples of the buffer
+#define SIGNAL_IGNORE_FIRST_SAMPLES 10
+
 //generic
 typedef struct {
 	int low;
@@ -28,14 +36,10 @@ typedef struct {
 	int amplitude;
 	bool isnoise;
 } signal_t;
-extern signal_t* getSignalProperties(void);
+signal_t* getSignalProperties(void);
 
-extern uint32_t	compute_mean_uint(uint8_t *in, size_t N);
-extern int32_t	compute_mean_int(int *in, size_t N);
-bool isNoise_int(int *bits, uint32_t size);
-bool isNoise(uint8_t *bits, uint32_t size);
-extern void zeromean(uint8_t* data, size_t size);
-	
+void computeSignalProperties(uint8_t *bits, uint32_t size);
+void removeSignalOffset(uint8_t *samples, uint32_t size);
 void getNextLow(uint8_t *samples, size_t size, int low, size_t *i);
 void getNextHigh(uint8_t *samples, size_t size, int high, size_t *i);
 bool loadWaveCounters(uint8_t *samples, size_t size, int lowToLowWaveLen[], int highToLowWaveLen[], int *waveCnt, int *skip, int *minClk, int *high, int *low);

From 1cba26decfc6997b3501f45acec2f85746a2c80a Mon Sep 17 00:00:00 2001
From: Philippe Teuwen <phil@teuwen.org>
Date: Fri, 8 Mar 2019 20:30:54 +0100
Subject: [PATCH 2/2] remove redundant removeSignalOffset

---
 client/cmddata.c    | 4 ----
 client/cmdlfem4x.c  | 2 --
 client/cmdlft55xx.c | 5 ++---
 3 files changed, 2 insertions(+), 9 deletions(-)

diff --git a/client/cmddata.c b/client/cmddata.c
index 285b4d189..fc34f3e80 100644
--- a/client/cmddata.c
+++ b/client/cmddata.c
@@ -1471,10 +1471,6 @@ int getSamples(int n, bool silent) {
 
 	uint8_t bits[GraphTraceLen];
 	size_t size = getFromGraphBuf(bits);
-	// TODO now DC removal is done already on device, right ?
-	// removeSignalOffset(bits, size);
-	// push it back to graph
-	// setGraphBuf(bits, size);
 	// set signal properties low/high/mean/amplitude and is_noise detection
 	computeSignalProperties(bits, size);
 
diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c
index e4909ace9..8b9530957 100644
--- a/client/cmdlfem4x.c
+++ b/client/cmdlfem4x.c
@@ -1000,8 +1000,6 @@ bool downloadSamplesEM(){
 		return false;
 	}
 
-	// TODO now DC removal is done already on device, right ?
-	// removeSignalOffset(got, sizeof(got));
 	setGraphBuf(got, sizeof(got));
 	// set signal properties low/high/mean/amplitude and is_noise detection
 	computeSignalProperties(got, sizeof(got));
diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c
index 446e440ce..b9256fc29 100644
--- a/client/cmdlft55xx.c
+++ b/client/cmdlft55xx.c
@@ -1330,10 +1330,9 @@ bool AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password )
 		PrintAndLogEx(WARNING, "command execution time out");
 		return false;
 	}
-	// set signal properties low/high/mean/amplitude and is_noise detection
-	removeSignalOffset(got, sizeof(got));
-	computeSignalProperties(got, sizeof(got));
 	setGraphBuf(got, sizeof(got));
+	// set signal properties low/high/mean/amplitude and is_noise detection
+	computeSignalProperties(got, sizeof(got));
 	RepaintGraphWindow();
 	return !getSignalProperties()->isnoise;
 }