docs: def fit_lines(self, window=1500, break_thresh=1500):
          """
          Fits lines to pitch contours.
  
          :param window: size of each chunk to which linear equation is to be fit (in milliseconds).
          To keep it simple, hop is chosen to be one third of the window.
          :param break_thresh: If there is silence beyond this limit (in milliseconds),
          the contour will be broken there into two so that we don't fit a line over and
          including the silent region.
          """
          window /= 1000
          hop = window/3
          break_thresh /= 1000
  
          #cut the whole song into pieces if there are gaps more than break_thresh seconds
          i = 0
          break_indices = []
          count = 0
          while i < len(self.pitch):
              if self.pitch[i] == -10000:
                  count = 1
                  start_index = i
                  while i < len(self.pitch) and self.pitch[i] == -10000:
                      count += 1
                      i += 1
                  end_index = i-1
                  if self.timestamps[end_index]-self.timestamps[start_index] >= break_thresh:
                      break_indices.append([start_index, end_index])
              i += 1
          break_indices = np.array(break_indices)
  
          #In creating the data blocks which are not silences, note that we
          # take complimentary break indices. i.e., if [[s1, e1], [s2, e2] ...]
          # is break_indices, we take e1-s2, e2-s3 chunks and build data blocks
  
          data_blocks = []
          if len(break_indices) == 0:
              t_pitch = self.pitch.reshape(len(self.pitch), 1)
              t_timestamps = self.timestamps.reshape(len(self.timestamps), 1)
              data_blocks = [np.append(t_timestamps, t_pitch, axis=1)]
          else:
              if break_indices[0, 0] != 0:
                  t_pitch = self.pitch[:break_indices[0, 0]]
                  t_pitch = t_pitch.reshape(len(t_pitch), 1)
                  t_timestamps = self.timestamps[:break_indices[0, 0]]
                  t_timestamps = t_timestamps.reshape(len(t_timestamps), 1)
                  data_blocks.append(np.append(t_timestamps, t_pitch, axis=1))
              block_start = break_indices[0, 1]
              for i in xrange(1, len(break_indices)):
                  block_end = break_indices[i, 0]
                  t_pitch = self.pitch[block_start:block_end]
                  t_pitch = t_pitch.reshape(len(t_pitch), 1)
                  t_timestamps = self.timestamps[block_start:block_end]
                  t_timestamps = t_timestamps.reshape(len(t_timestamps), 1)
                  data_blocks.append(np.append(t_timestamps, t_pitch, axis=1))
                  block_start = break_indices[i, 1]
              if block_start != len(self.pitch)-1:
                  t_pitch = self.pitch[block_start:]
                  t_pitch = t_pitch.reshape(len(t_pitch), 1)
                  t_timestamps = self.timestamps[block_start:]
                  t_timestamps = t_timestamps.reshape(len(t_timestamps), 1)
                  data_blocks.append(np.append(t_timestamps, t_pitch, axis=1))
  
          label_start_offset = (window-hop)/2
          label_end_offset = label_start_offset+hop
  
          #dataNew = np.zeros_like(data)
          #dataNew[:, 0] = data[:, 0]
          data_new = np.array([[0, 0]])
          for data in data_blocks:
              start_index = 0
              while start_index < len(data)-1:
                  end_index = utils.find_nearest_index(data[:, 0], data[start_index][0]+window)
                  segment = data[start_index:end_index]
                  if len(segment) == 0:
                      start_index = utils.find_nearest_index(data[:, 0], data[start_index, 0]+hop)
                      continue
                  segment_clean = np.delete(segment, np.where(segment[:, 1] == -10000), axis=0)
                  if len(segment_clean) == 0:
                      #After splitting into blocks, this loop better not come into play
                      #raise ValueError("This part of the block is absolute silence! Make sure block_thresh >= window!")
                      start_index = utils.find_nearest_index(data[:, 0], data[start_index, 0]+hop)
                      continue
                  n_clean = len(segment_clean)
                  x_clean = np.matrix(segment_clean[:, 0]).reshape(n_clean, 1)
                  y_clean = np.matrix(segment_clean[:, 1]).reshape(n_clean, 1)
                  #return [x_clean, y_clean]
                  theta = utils.normal_equation(x_clean, y_clean)
  
                  #determine the start and end of the segment to be labelled
                  label_start_index = utils.find_nearest_index(x_clean, data[start_index, 0]+label_start_offset)
                  label_end_index = utils.find_nearest_index(x_clean, data[start_index, 0]+label_end_offset)
                  x_clean = x_clean[label_start_index:label_end_index]
                  #return x_clean
                  x_clean = np.insert(x_clean, 0, np.ones(len(x_clean)), axis=1)
                  newy = x_clean*theta
                  result = np.append(x_clean[:, 1], newy, axis=1)
                  data_new = np.append(data_new, result, axis=0)
  
                  start_index = utils.find_nearest_index(data[:, 0], data[start_index, 0]+hop)
  
          return [data_new[:, 0], data_new[:, 1]]