docs: def findzc(x, thresh, t_max=None):
      '''
      Find cues to each zero-crossing in vector x.
  
      To be accepted as a zero-crossing, the signal must pass from below
      -thresh to above thresh, or vice versa, in no more than t_max samples.
  
      Args
      ----
      thresh: (float)
          magnitude threshold for detecting a zero-crossing.
      t_max: (int)
          maximum duration in samples between threshold crossings.
  
      Returns
      -------
      zc: ndarray
          Array containing the start **zc_s**, finish **zc_f** and direction **S**
          of zero crossings
  
          where:
  
          * zc_s: the cue of the first threshold-crossing in samples
          * zc_f: the cue of the second threshold-crossing in samples
          * S: the sign of each zero-crossing (1 = positive-going, -1 = negative-going).
  
      Notes
      -----
      This routine is a reimplementation of Mark Johnson's Dtag toolbox method
      and tested against the Matlab version to be sure it has the same result.
      '''
      import numpy
  
      # positive threshold: p (over) n (under)
      pt_p = x > thresh
      pt_n = ~pt_p
  
      # negative threshold: p (over) n (under)
      nt_n = x < -thresh
      nt_p = ~nt_n
  
      # Over positive threshold +thresh
      # neg to pos
      pt_np = (pt_p[:-1] & pt_n[1:]).nonzero()[0]
      # pos to neg
      pt_pn = (pt_n[:-1] & pt_p[1:]).nonzero()[0] + 1
  
      # Over positive threshold +thresh
      # neg to pos
      nt_np = (nt_p[:-1] & nt_n[1:]).nonzero()[0] + 1
      # pos to neg
      nt_pn = (nt_n[:-1] & nt_p[1:]).nonzero()[0]
  
      # Concat indices, order sequentially
      ind_all = numpy.hstack((pt_np, nt_np, pt_pn, nt_pn))
      ind_all.sort()
  
      # Omit rows where just touching but not crossing
      crossing_mask = ~(numpy.diff(numpy.sign(x[ind_all])) == 0)
  
      # Append a False to make the same length as ind_all
      crossing_mask = numpy.hstack((crossing_mask, False))
  
      # Get 1st and 2nd crossings
      ind_1stx = ind_all[crossing_mask]
      ind_2ndx = ind_all[numpy.where(crossing_mask)[0]+1]
  
      # TODO odd option to replace with NaNs rather than delete?
      # Delete indices that do not have a second crossing
      del_ind = numpy.where(ind_2ndx > len(x)-1)[0]
      for i in del_ind:
          ind_1stx = numpy.delete(ind_1stx, i)
          ind_2ndx = numpy.delete(ind_1stx, i)
  
      # Get direction/sign of crossing
      signs = numpy.sign(x[ind_1stx])*-1
  
      # Add column of direction and transpose
      zc = numpy.vstack((ind_1stx, ind_2ndx, signs)).T
  
      # TODO not mentioned in docstring, remove?
      #x_norm? = ((x[:, 1] * zc[:, 0]) - (x[:, 0] * zc[:, 1])) / x[:, 1] - x[:, 0]
  
      if t_max:
          zc = zc[zc[:, 1] - zc[:, 0] <= t_max, :]
  
      return zc.astype(int)