--- abgate-1.1.6/gate.cpp.orig	2011-02-15 12:16:02.000000000 +0100
+++ abgate-1.1.6/gate.cpp	2014-01-01 14:46:16.000000000 +0100
@@ -35,18 +35,16 @@
 			state = CLOSED;
 			gate = 0;
 			holding = 0;
-			input_db = 0;
 		}
-		virtual ~Gate();
+		~Gate() {}
 
-		bool bypass;
-		float *switch_button, *threshold, *attack, *hold, *decay, *range, input_db, sample_rate, gate, range_coef, attack_coef, decay_coef, *output;
+		float *switch_button, *threshold, *attack, *hold, *decay, *range, sample_rate, gate, *output;
 		const float *input;
 		int state, holding;
 };
 
 static LV2_Handle instantiateGate(const _LV2_Descriptor *descriptor, double s_rate, const char *path, const LV2_Feature * const* features) {
-	Gate *plugin_data = (Gate *)malloc(sizeof(Gate));
+	Gate *plugin_data = new Gate;
 	plugin_data->sample_rate = s_rate;
 	return (LV2_Handle)plugin_data;
 }
@@ -94,8 +92,8 @@
 	switch_button = switch_button < 0 ? 0 : switch_button;
 	switch_button = switch_button > 1 ? 1 : switch_button;
 
-	bool bypass = switch_button > 0 ? true : false;
-	if (bypass != false) {
+	bool active = switch_button > 0;
+	if (active) {
 
 		// Getting port values
 		const float threshold = *(plugin_data->threshold);
@@ -104,65 +102,84 @@
 		const float decay = *(plugin_data->decay);
 		const float range = *(plugin_data->range);
 
-		float sample_rate = plugin_data->sample_rate;
+		const float sample_rate = plugin_data->sample_rate;
+
+		const float threshold_value = pow(10, threshold * 0.05);
+		const float attack_coef = 1000 / (attack * sample_rate);
+		const int hold_samples = round(hold * sample_rate * 0.001);
+		const float decay_coef = 1000 / (decay * sample_rate);
+		const float range_coef = range > -90 ? pow(10, range * 0.05) : 0;
+		
 		int state = plugin_data->state;
 		float gate = plugin_data->gate;
 		int holding = plugin_data->holding;
-		float input_db = plugin_data->input_db;
 
-		float range_coef = range > -90 ? pow(10, range * 0.05) : 0;
-		float attack_coef = 1000 / (attack * sample_rate);
-		float decay_coef = 1000 / (decay * sample_rate);
-		
 		for (uint32_t i = 0; i < sample_count; ++i) {
 
 			// Counting input dB
-          		input_db = 20 * log10(fabs(input[i]));
+			float sample = input[i];
+			float abs_sample = fabs(sample);
+
 			switch (state){
 				case CLOSED:
-					if (input_db >= threshold) { state = ATTACK; }
+				case DECAY:
+					if (abs_sample >= threshold_value) { state = ATTACK; }
 					break;
 				case ATTACK:
-					// attacking :)
+					break;
+			  	case OPENED:
+			  		if (abs_sample >= threshold_value) { holding = hold_samples; }
+			  		else if (holding <= 0) { state = DECAY; }
+					else { holding--; }
+					break;
+				default:
+					// shouldn't happen
+					state = CLOSED;
+			}
+
+			// handle attack/decay in a second pass to avoid unnecessary one-sample delay
+			switch (state){
+				case CLOSED:
+					output[i] = sample * range_coef;
+					break;
+				case DECAY:
+					gate -= decay_coef;
+					if (gate <= 0) {
+						gate = 0;
+						state = CLOSED;
+					}
+					output[i] = sample * (range_coef * (1 - gate) + gate);
+			    		break;
+				case ATTACK:
 			 		gate += attack_coef;
 					if (gate >= 1) {
 						gate = 1;
 						state = OPENED;
-						holding = round(hold * sample_rate * 0.001);
+						holding = hold_samples;
 					}
+					output[i] = sample * (range_coef * (1 - gate) + gate);
 			    		break;
-			  	case OPENED:
-			    		if (holding <= 0) {
-						if (input_db < threshold) { state = DECAY; }
-					}
-					else { holding--; }
-			    		break;
-			  	case DECAY:
-			    		gate -= decay_coef;
-					if (input_db >= threshold) { state = ATTACK; }
-					else if (gate <= 0) {
-						gate = 0;
-						state = CLOSED;
-					}
+			    	case OPENED:
+			    		output[i] = sample;
 			    		break;
-			  	default:
-			    		state = CLOSED;
 			}
-			output[i] = input[i] * (range_coef * (1 - gate) + gate);
-		}	
-		plugin_data->input_db = input_db;
+		}
+
       		plugin_data->gate = gate;
       		plugin_data->state = state;
       		plugin_data->holding = holding;	
 	}
 	else {
 		// Bypassing
-		for (uint32_t i = 0; i < sample_count; ++i) { output[i] = input[i]; }
+		if (output != input) {
+			for (uint32_t i = 0; i < sample_count; ++i) { output[i] = input[i]; }
+		}
 	}
 }
 
 static void cleanupGate(LV2_Handle instance) {
-	free(instance);
+	Gate *plugin_data = (Gate *)instance;
+	delete plugin_data;
 }
 
 static void init() {
