docs: def windowed(a, windowsize, stepsize=None, dopad=False):
      """
      Parameters
          a          - the input array to restructure into overlapping windows
          windowsize - the size of each window of samples
          stepsize   - the number of samples to shift the window each step. If not
                       specified, this defaults to windowsize
          dopad      - If false (default), leftover samples are returned seperately.
                       If true, the input array is padded with zeros so that all
                       samples are used.
      """
  
      if windowsize < 1:
          raise ValueError('windowsize must be greater than or equal to one')
  
      if stepsize is None:
          stepsize = windowsize
  
      if stepsize < 1:
          raise ValueError('stepsize must be greater than or equal to one')
  
      if not a.flags['C_CONTIGUOUS']:
          a = a.copy()
  
      if windowsize == 1 and stepsize == 1:
          # A windowsize and stepsize of one mean that no windowing is necessary.
          # Return the array unchanged.
          return np.zeros((0,) + a.shape[1:], dtype=a.dtype), a
  
      if windowsize == 1 and stepsize > 1:
          return np.zeros(0, dtype=a.dtype), a[::stepsize]
  
      # the original length of the input array
      l = a.shape[0]
  
      if dopad:
          p = _wpad(l, windowsize, stepsize)
          # pad the array with enough zeros so that there are no leftover samples
          a = pad(a, p)
          # no leftovers; an empty array
          leftover = np.zeros((0,) + a.shape[1:], dtype=a.dtype)
      else:
          # cut the array so that any leftover samples are returned seperately
          c, lc = _wcut(l, windowsize, stepsize)
          leftover = a[lc:]
          a = a[:c]
  
      if 0 == a.shape[0]:
          return leftover, np.zeros(a.shape, dtype=a.dtype)
  
      n = 1 + (a.shape[0] - windowsize) // (stepsize)
      s = a.strides[0]
      newshape = (n, windowsize) + a.shape[1:]
      newstrides = (stepsize * s, s) + a.strides[1:]
  
      out = np.ndarray.__new__( \
          np.ndarray,
          strides=newstrides,
          shape=newshape,
          buffer=a,
          dtype=a.dtype)
  
      return leftover, out