class_docstr: Base class for handling interaction between MIDI and SequenceGenerator.
  
  Child classes will provided the "main loop" of an interactive session between
  a MidiHub used for MIDI I/O and sequences generated by a SequenceGenerator in
  their `run` methods.
  
  Should be started by calling `start` to launch in a separate thread.
  
  Args:
    midi_hub: The MidiHub to use for MIDI I/O.
    sequence_generators: A collection of SequenceGenerator objects.
    qpm: The quarters per minute to use for this interaction. May be overriden
       by control changes sent to `tempo_control_number`.
    generator_select_control_number: An optional MIDI control number whose
       value to use for selection a sequence generator from the collection.
       Must be provided if `sequence_generators` contains multiple
       SequenceGenerators.
    tempo_control_number: An optional MIDI control number whose value to use to
       determine the qpm for this interaction. On receipt of a control change,
       the qpm will be set to 60 more than the control change value.
    temperature_control_number: The optional control change number to use for
        controlling generation softmax temperature.
  
  Raises:
    ValueError: If `generator_select_control_number` is None and
        `sequence_generators` contains multiple SequenceGenerators.
code: def __init__(
      self,
      midi_hub,
      sequence_generators,
      qpm,
      generator_select_control_number=None,
      tempo_control_number=None,
      temperature_control_number=None,
  ):
      if (
          generator_select_control_number is None
          and len(sequence_generators) > 1
      ):
          raise ValueError(
              "`generator_select_control_number` cannot be None if there are "
              "multiple SequenceGenerators."
          )
      self._midi_hub = midi_hub
      self._sequence_generators = sequence_generators
      self._default_qpm = qpm
      self._generator_select_control_number = (
          generator_select_control_number
      )
      self._tempo_control_number = tempo_control_number
      self._temperature_control_number = temperature_control_number
  
      # A signal to tell the main loop when to stop.
      self._stop_signal = threading.Event()
      super(MidiInteraction, self).__init__()
  
imports: import abc
  import threading
  import time
  import note_seq
  from note_seq.protobuf import generator_pb2
  from note_seq.protobuf import music_pb2
  import tensorflow.compat.v1
label_desc: Use image node_id 1 to create a new MidiInteraction object from inherited base classes: threading with example: obj = MidiInteraction(midi_hub, sequence_generators, qpm, generator_select_control_number, tempo_control_number, temperature_control_number)