docs: def process_frames(self, data, sampling_rate, offset=0, last=False, utterance=None, corpus=None):
          """
          Execute the processing of this step and all dependent parent steps.
          """
  
          if offset == 0:
              self.steps_sorted = list(nx.algorithms.dag.topological_sort(self.graph))
              self._create_buffers()
              self._define_output_buffers()
  
          # Update buffers with input data
          self._update_buffers(None, data, offset, last)
  
          # Go through the ordered (by dependencies) steps
          for step in self.steps_sorted:
  
              chunk = self.buffers[step].get()
  
              if chunk is not None:
                  res = step.compute(chunk, sampling_rate, utterance=utterance, corpus=corpus)
  
                  # If step is self, we know its the last step so return the data
                  if step == self:
                      return res
  
                  # Otherwise update buffers of child steps
                  else:
                      self._update_buffers(step, res, chunk.offset + chunk.left_context, chunk.is_last)