docs: def append_processor(self, proc, source_proc=None):
          "Append a new processor to the pipe"
          if source_proc is None and len(self.processors):
              source_proc = self.processors[0]
  
          if source_proc and not isinstance(source_proc, Processor):
              raise TypeError('source_proc must be a Processor or None')
  
          if not isinstance(proc, Processor):
              raise TypeError('proc must be a Processor or None')
  
          if proc.type == 'decoder' and len(self.processors):
              raise ValueError('Only the first processor in a pipe could be a Decoder')
  
          # TODO : check if the processor is already in the pipe
          if source_proc:
              for child in self._graph.neighbors_iter(source_proc.uuid()):
                  child_proc = self._graph.node[child]['processor']
                  if proc == child_proc:
                      proc._uuid = child_proc.uuid()
                      proc.process_pipe = self
                      break
          if not self._graph.has_node(proc.uuid()):
              self.processors.append(proc)  # Add processor to the pipe
              self._graph.add_node(proc.uuid(), processor=proc, id=proc.id())
              if source_proc:
                  self._graph.add_edge(self.processors[0].uuid(), proc.uuid(),
                                       type='audio_source')
              proc.process_pipe = self
              # Add an edge between each parent and proc
              for parent in proc.parents.values():
                  self._graph.add_edge(parent.uuid(), proc.uuid(),
                                       type='data_source')