class_docstr: Implementation of a MidiInteraction for interactive "call and response".
  
  Alternates between receiving input from the MidiHub ("call") and playing
  generated sequences ("response"). During the call stage, the input is captured
  and used to generate the response, which is then played back during the
  response stage.
  
  The call phrase is started when notes are received and ended by an external
  signal (`end_call_signal`) or after receiving no note events for a full tick.
  The response phrase is immediately generated and played. Its length is
  optionally determined by a control value set for
  `response_ticks_control_number` or by the length of the call.
  
  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.
    clock_signal: An optional midi_hub.MidiSignal to use as a clock. Each tick
        period should have the same duration. No other assumptions are made
        about the duration, but is typically equivalent to a bar length. Either
        this or `tick_duration` must be specified.be
    tick_duration: An optional float specifying the duration of a tick period in
        seconds. No assumptions are made about the duration, but is typically
        equivalent to a bar length. Either this or `clock_signal` must be
        specified.
    end_call_signal: The optional midi_hub.MidiSignal to use as a signal to stop
        the call phrase at the end of the current tick.
    panic_signal: The optional midi_hub.MidiSignal to use as a signal to end
        all open notes and clear the playback sequence.
    mutate_signal: The optional midi_hub.MidiSignal to use as a signal to
        generate a new response sequence using the current response as the
        input.
    allow_overlap: A boolean specifying whether to allow the call to overlap
        with the response.
    metronome_channel: The optional 0-based MIDI channel to output metronome on.
        Ignored if `clock_signal` is provided.
    min_listen_ticks_control_number: The optional control change number to use
        for controlling the minimum call phrase length in clock ticks.
    max_listen_ticks_control_number: The optional control change number to use
        for controlling the maximum call phrase length in clock ticks. Call
        phrases will automatically be ended and responses generated when this
        length is reached.
    response_ticks_control_number: The optional control change number to use for
        controlling the length of the response in clock ticks.
    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.
    loop_control_number: The optional control change number to use for
        determining whether the response should be looped. Looping is enabled
        when the value is 127 and disabled otherwise.
    state_control_number: The optinal control change number to use for sending
        state update control changes. The values are 0 for `IDLE`, 1 for
        `LISTENING`, and 2 for `RESPONDING`.
  
    Raises:
      ValueError: If exactly one of `clock_signal` or `tick_duration` is not
         specified.
docstr: Generates a response sequence with the currently-selected generator.
  
  Args:
    input_sequence: The NoteSequence to use as a generation seed.
    zero_time: The float time in seconds to treat as the start of the input.
    response_start_time: The float time in seconds for the start of
        generation.
    response_end_time: The float time in seconds for the end of generation.
  
  Returns:
    The generated NoteSequence.
docstr_tok: ["Generates","a","response","sequence","with","the","currently-selected","generator",".","Args",":","input_sequence",":","The","NoteSequence","to","use","as","a","generation","seed",".","zero_time",":","The","float","time","in","seconds","to","treat","as","the","start","of","the","input",".","response_start_time",":","The","float","time","in","seconds","for","the","start","of","generation",".","response_end_time",":","The","float","time","in","seconds","for","the","end","of","generation",".","Returns",":","The","generated","NoteSequence","."]
code: def _generate(
      self,
      input_sequence,
      zero_time,
      response_start_time,
      response_end_time,
  ):
      """Generates a response sequence with the currently-selected generator.
  
      Args:
        input_sequence: The NoteSequence to use as a generation seed.
        zero_time: The float time in seconds to treat as the start of the input.
        response_start_time: The float time in seconds for the start of
            generation.
        response_end_time: The float time in seconds for the end of generation.
  
      Returns:
        The generated NoteSequence.
      """
      # Generation is simplified if we always start at 0 time.
      response_start_time -= zero_time
      response_end_time -= zero_time
  
      generator_options = generator_pb2.GeneratorOptions()
      generator_options.input_sections.add(
          start_time=0, end_time=response_start_time
      )
      generator_options.generate_sections.add(
          start_time=response_start_time, end_time=response_end_time
      )
  
      # Get current temperature setting.
      generator_options.args[
          "temperature"
      ].float_value = self._temperature()
  
      # Generate response.
      tf.logging.info(
          "Generating sequence using '%s' generator.",
          self._sequence_generator.details.id,
      )
      tf.logging.debug(
          "Generator Details: %s", self._sequence_generator.details
      )
      tf.logging.debug(
          "Bundle Details: %s", self._sequence_generator.bundle_details
      )
      tf.logging.debug("Generator Options: %s", generator_options)
      response_sequence = self._sequence_generator.generate(
          adjust_sequence_times(input_sequence, -zero_time),
          generator_options,
      )
      response_sequence = note_seq.trim_note_sequence(
          response_sequence, response_start_time, response_end_time
      )
      return adjust_sequence_times(response_sequence, zero_time)
  
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 9 for calling the CallAndResponseMidiInteraction obj's underlying member method code with example usage: obj._generate(input_sequence, zero_time, response_start_time, response_end_time) and returns: adjust_sequence_times