## Copyright (C) 2009, 2010 Thomas Weidenfeller
## 
## This file is part of gds2000tools/gds-octave.
## 
## gds2000tools/gds-octave is free software: you can redistribute it
## and/or modify it under the terms of the GNU General Public License
## version 3 as published by the Free Software Foundation.
## 
## gds2000tools/gds-octave is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
## 
## You should have received a copy of the GNU General Public License
## along with gds2000tools/gds-octave.  If not,
## see <http://www.gnu.org/licenses/>.
##

## usage: [X] = __gds_zcross(Y, EPSILON)
## usage: [X] = __gds_zcross(Y)
##
## Calculate the points in time X where the data in vector Y
## crosses zero. 
##
## EPSILON indicates the margins of Y data which are considered close
## enough to be counted as 0. If not provided, zero is assumed.
##
##
## NOTE: The coctave signal package 1.0.7 doesn't have a zero crossing
## detection. Later versions have. To make sure gds-octave
## works with older signal packages, gds-octave uses this own implemenmtation.
##
## See also: gds_zcross, zerocrossing()

## Author: Thomas Weidenfeller
## Created: 2009-07-19
## Version: $Id: __gds_zcross.m,v 1.1 2010/12/31 02:28:33 tw Exp $
## Keywords: Oscilloscope, GDS-2000, gds2000tools, sign

function [x] = __gds_zcross(y, epsilon)

	if(nargin < 2)
		epsilon = 0;
		if(nargin < 1)
			print_usage();
		endif
	endif

	##
	## Either use a passband below and above -epsilon ... epsilon
	## or reduce noise by quantizing. We go for a passband.
	##
	## -1: in lower passband, 0: out of passband, 1: in upper passband
	signum = (y > epsilon) - (y < -epsilon);

	##
	## Change of signum indicates action required
	## diff: Vector of first differences
	## find: Vector of indices of nonzero elements = the zcrossing positions
	x_edges = diff(signum);

	##
	## Get the values at the change interval starts and ends
	## TODO: Collapse consecutive zero intervals
	##	Until now the x interval is always 1.
	##
	x1 = find(x_edges);
	x2 = x1 .+ 1;
	y1 = y(x1);
	y2 = y(x2);

	##
	## Linear interpolation to find "better" position of zero crossings
	## 
	x = ((x1 .* y2 .- y1 .* x2) ./ (y2 .- y1) .- 1);

endfunction
