Exemple #1
0
    def testStartCapture_Multiple(self):
        captor_1 = self.midi_hub.start_capture(
            120, 0.0, stop_signal=midi_hub.MidiSignal(note=3))
        captor_2 = self.midi_hub.start_capture(120,
                                               1.0,
                                               stop_signal=midi_hub.MidiSignal(
                                                   type='control_change',
                                                   control=1))

        self.send_capture_messages()

        captor_1.join()
        captor_2.join()

        captured_seq_1 = captor_1.captured_sequence()
        expected_seq = music_pb2.NoteSequence()
        expected_seq.tempos.add(qpm=120)
        expected_seq.total_time = 4.0
        testing_lib.add_track_to_sequence(
            expected_seq, 0,
            [Note(0, 64, 0.01, 3),
             Note(1, 64, 2, 4),
             Note(2, 64, 3, 4)])
        self.assertProtoEquals(captured_seq_1, expected_seq)

        captured_seq_2 = captor_2.captured_sequence()
        expected_seq = music_pb2.NoteSequence()
        expected_seq.tempos.add(qpm=120)
        expected_seq.total_time = 6.0
        testing_lib.add_track_to_sequence(
            expected_seq, 0,
            [Note(1, 64, 2, 5),
             Note(2, 64, 3, 4),
             Note(3, 64, 4, 6)])
        self.assertProtoEquals(captured_seq_2, expected_seq)
Exemple #2
0
def main(unused_argv):
    tf.logging.set_verbosity(FLAGS.log)

    # Initialize MidiHub.
    hub = midi_hub.MidiHub(None, FLAGS.output_ports.split(','),
                           midi_hub.TextureType.MONOPHONIC)

    cc = FLAGS.clock_control_number

    # Assumes 4 beats per bar.
    metronome_signals = ([midi_hub.MidiSignal(control=cc, value=127)] +
                         [midi_hub.MidiSignal(control=cc, value=0)] * 3)

    hub.start_metronome(FLAGS.qpm,
                        start_time=0,
                        signals=metronome_signals,
                        channel=FLAGS.channel)

    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        hub.stop_metronome()

    print('Clock stopped.')
Exemple #3
0
    def testMidiSignal_Args_InferredType(self):
        sig = midi_hub.MidiSignal(note=1)
        self.assertEqual(r'^.* channel=\d+ note=1 velocity=\d+ time=\d+.\d+$',
                         str(sig))

        sig = midi_hub.MidiSignal(value=2)
        self.assertEqual(
            r'^control_change channel=\d+ control=\d+ value=2 time=\d+.\d+$',
            str(sig))
Exemple #4
0
    def testStartCapture_Iterate_Signal(self):
        start_time = 1.0
        captor = self.midi_hub.start_capture(120,
                                             start_time,
                                             stop_signal=midi_hub.MidiSignal(
                                                 type='control_change',
                                                 control=1))

        for msg in self.capture_messages[:-1]:
            threading.Timer(0.2 * msg.time, self.port.callback,
                            args=[msg]).start()

        captured_seqs = []
        for captured_seq in captor.iterate(signal=midi_hub.MidiSignal(
                type='note_off')):
            captured_seqs.append(captured_seq)

        self.assertEqual(4, len(captured_seqs))

        expected_seq = music_pb2.NoteSequence()
        expected_seq.tempos.add(qpm=120)
        expected_seq.total_time = 3
        testing_lib.add_track_to_sequence(expected_seq, 0, [Note(1, 64, 2, 3)])
        self.assertProtoEquals(captured_seqs[0], expected_seq)

        expected_seq = music_pb2.NoteSequence()
        expected_seq.tempos.add(qpm=120)
        expected_seq.total_time = 4
        testing_lib.add_track_to_sequence(
            expected_seq, 0,
            [Note(1, 64, 2, 4), Note(2, 64, 3, 4)])
        self.assertProtoEquals(captured_seqs[1], expected_seq)

        expected_seq = music_pb2.NoteSequence()
        expected_seq.tempos.add(qpm=120)
        expected_seq.total_time = 5
        testing_lib.add_track_to_sequence(
            expected_seq, 0,
            [Note(1, 64, 2, 5),
             Note(2, 64, 3, 4),
             Note(3, 64, 4, 5)])
        self.assertProtoEquals(captured_seqs[2], expected_seq)

        expected_seq = music_pb2.NoteSequence()
        expected_seq.tempos.add(qpm=120)
        expected_seq.total_time = 6
        testing_lib.add_track_to_sequence(
            expected_seq, 0,
            [Note(1, 64, 2, 5),
             Note(2, 64, 3, 4),
             Note(3, 64, 4, 6)])
        self.assertProtoEquals(captured_seqs[3], expected_seq)
Exemple #5
0
  def testMidiSignal_Args(self):
    sig = midi_hub.MidiSignal(type='note_on', note=1)
    self.assertEquals(r'^note_on channel=\d+ note=1 velocity=\d+ time=\d+.\d+$',
                      str(sig))

    sig = midi_hub.MidiSignal(type='note_off', velocity=127)
    self.assertEquals(
        r'^note_off channel=\d+ note=\d+ velocity=127 time=\d+.\d+$', str(sig))

    sig = midi_hub.MidiSignal(type='control_change', value=2)
    self.assertEquals(
        r'^control_change channel=\d+ control=\d+ value=2 time=\d+.\d+$',
        str(sig))
Exemple #6
0
  def testMidiSignal_Message(self):
    sig = midi_hub.MidiSignal(msg=mido.Message(type='note_on', note=1))
    self.assertEquals(r'^note_on channel=0 note=1 velocity=64 time=\d+.\d+$',
                      str(sig))

    sig = midi_hub.MidiSignal(msg=mido.Message(type='note_off', velocity=127))
    self.assertEquals(r'^note_off channel=0 note=0 velocity=127 time=\d+.\d+$',
                      str(sig))

    sig = midi_hub.MidiSignal(
        msg=mido.Message(type='control_change', control=1, value=2))
    self.assertEquals(
        r'^control_change channel=0 control=1 value=2 time=\d+.\d+$', str(sig))
Exemple #7
0
  def testStartCapture_Iterate_Period_Overrun(self):
    start_time = 1.0
    captor = self.midi_hub.start_capture(
        120, start_time,
        stop_signal=midi_hub.MidiSignal(type='control_change', control=1))

    for msg in self.capture_messages[:-1]:
      threading.Timer(0.1 * msg.time, self.port.callback, args=[msg]).start()

    period = 0.26
    captured_seqs = []
    wall_start_time = time.time()
    for captured_seq in captor.iterate(period=period):
      time.sleep(0.5)
      captured_seqs.append(captured_seq)

    self.assertEquals(2, len(captured_seqs))

    expected_seq = music_pb2.NoteSequence()
    expected_seq.tempos.add(qpm=120)
    end_time = captured_seqs[0].total_time
    self.assertAlmostEqual(wall_start_time + period, end_time, delta=0.005)
    expected_seq.total_time = end_time
    testing_lib.add_track_to_sequence(
        expected_seq, 0, [Note(1, 64, 2, end_time)])
    self.assertProtoEquals(captured_seqs[0], expected_seq)

    expected_seq = music_pb2.NoteSequence()
    expected_seq.tempos.add(qpm=120)
    expected_seq.total_time = 6
    testing_lib.add_track_to_sequence(
        expected_seq, 0,
        [Note(1, 64, 2, 5), Note(2, 64, 3, 4), Note(3, 64, 4, 6)])
    self.assertProtoEquals(captured_seqs[1], expected_seq)
Exemple #8
0
def main(unused_argv):
  tf.logging.set_verbosity(FLAGS.log)

  if not _validate_flags():
    return

  # Load generators.
  generators = []
  for bundle_file in FLAGS.bundle_files.split(','):
    generators.append(_load_generator_from_bundle_file(bundle_file))
    if generators[-1] is None:
      return

  # Initialize MidiHub.
  if FLAGS.input_port not in midi_hub.get_available_input_ports():
    print "Opening '%s' as a virtual MIDI port for input." % FLAGS.input_port
  if FLAGS.output_port not in midi_hub.get_available_output_ports():
    print "Opening '%s' as a virtual MIDI port for output." % FLAGS.output_port
  hub = midi_hub.MidiHub(FLAGS.input_port, FLAGS.output_port,
                         midi_hub.TextureType.MONOPHONIC)

  start_call_signal = (
      None if FLAGS.start_call_control_number is None else
      midi_hub.MidiSignal(control=FLAGS.start_call_control_number, value=0))
  end_call_signal = (
      None if FLAGS.end_call_control_number is None else
      midi_hub.MidiSignal(control=FLAGS.end_call_control_number, value=0))
  interaction = midi_interaction.CallAndResponseMidiInteraction(
      hub,
      generators,
      FLAGS.qpm,
      generator_select_control_number=FLAGS.generator_select_control_number,
      phrase_bars=FLAGS.phrase_bars,
      start_call_signal=start_call_signal,
      end_call_signal=end_call_signal,
      temperature_control_number=FLAGS.temperature_control_number)

  _print_instructions()

  interaction.start()
  try:
    while True:
      time.sleep(1)
  except KeyboardInterrupt:
    interaction.stop()

  print 'Interaction stopped.'
Exemple #9
0
  def testWaitForEvent_Signal(self):
    for msg in self.capture_messages[3:-1]:
      threading.Timer(0.2 * msg.time, self.port.callback, args=[msg]).start()

    wait_start = time.time()

    self.midi_hub.wait_for_event(
        signal=midi_hub.MidiSignal(type='control_change', value=1))
    self.assertAlmostEqual(time.time() - wait_start, 1.2, delta=0.01)
Exemple #10
0
  def testCaptureSequence_StopSignal(self):
    start_time = 1.0

    threading.Timer(0.1, self.send_capture_messages).start()

    captured_seq = self.midi_hub.capture_sequence(
        120, start_time,
        stop_signal=midi_hub.MidiSignal(type='control_change', control=1))

    expected_seq = music_pb2.NoteSequence()
    expected_seq.tempos.add(qpm=120)
    expected_seq.total_time = 6.0
    testing_lib.add_track_to_sequence(
        expected_seq, 0,
        [Note(1, 64, 2, 5), Note(2, 64, 3, 4), Note(3, 64, 4, 6)])
    self.assertProtoEquals(captured_seq, expected_seq)
Exemple #11
0
 def update_map(self):
   """Enters a loop that receives user input to set signal controls."""
   while True:
     print
     self._print_instructions()
     response = raw_input('Selection: ')
     if response == 'q':
       return
     try:
       signal = self._signals[int(response) - 1]
     except (ValueError, IndexError):
       print 'Invalid response:', response
       continue
     self._update_event.clear()
     self._midi_hub.register_callback(
         partial(self._update_signal, signal),
         midi_hub.MidiSignal(type='control_change'))
     print('Send a control signal using the control number you wish to '
           'associate with `%s`.' % signal)
     self._update_event.wait()
Exemple #12
0
  def testMidiSignal_ValidityChecks(self):
    # Unsupported type.
    with self.assertRaises(midi_hub.MidiHubException):
      midi_hub.MidiSignal(type='sysex')
    with self.assertRaises(midi_hub.MidiHubException):
      midi_hub.MidiSignal(msg=mido.Message(type='sysex'))

    # Invalid arguments.
    with self.assertRaises(midi_hub.MidiHubException):
      midi_hub.MidiSignal()
    with self.assertRaises(midi_hub.MidiHubException):
      midi_hub.MidiSignal(type='note_on', value=1)
    with self.assertRaises(midi_hub.MidiHubException):
      midi_hub.MidiSignal(type='control', note=1)
    with self.assertRaises(midi_hub.MidiHubException):
      midi_hub.MidiSignal(msg=mido.Message(type='control_change'), value=1)

    # Non-inferrale type.
    with self.assertRaises(midi_hub.MidiHubException):
      midi_hub.MidiSignal(note=1, value=1)
Exemple #13
0
def main(unused_argv):
    tf.logging.set_verbosity(FLAGS.log)

    if not _validate_flags():
        return

    # Load generators.
    generators = []
    for bundle_file in FLAGS.bundle_files.split(','):
        generators.append(_load_generator_from_bundle_file(bundle_file))
        if generators[-1] is None:
            return

    # Initialize MidiHub.
    if FLAGS.input_port not in midi_hub.get_available_input_ports():
        print "Opening '%s' as a virtual MIDI port for input." % FLAGS.input_port
    if FLAGS.output_port not in midi_hub.get_available_output_ports():
        print "Opening '%s' as a virtual MIDI port for output." % FLAGS.output_port
    hub = midi_hub.MidiHub(FLAGS.input_port,
                           FLAGS.output_port,
                           midi_hub.TextureType.MONOPHONIC,
                           passthrough=FLAGS.passthrough,
                           playback_channel=FLAGS.playback_channel,
                           playback_offset=FLAGS.playback_offset)

    if FLAGS.clock_control_number is None:
        # Set the tick duration to be a single bar, assuming a 4/4 time signature.
        clock_signal = None
        tick_duration = 4 * (60. / FLAGS.qpm)
    else:
        clock_signal = midi_hub.MidiSignal(control=FLAGS.clock_control_number,
                                           value=127)
        tick_duration = None

    end_call_signal = (None if FLAGS.end_call_control_number is None else
                       midi_hub.MidiSignal(
                           control=FLAGS.end_call_control_number, value=127))
    panic_signal = (None if FLAGS.panic_control_number is None else
                    midi_hub.MidiSignal(control=FLAGS.panic_control_number,
                                        value=127))
    mutate_signal = (None if FLAGS.mutate_control_number is None else
                     midi_hub.MidiSignal(control=FLAGS.mutate_control_number,
                                         value=127))
    interaction = midi_interaction.CallAndResponseMidiInteraction(
        hub,
        generators,
        FLAGS.qpm,
        FLAGS.generator_select_control_number,
        clock_signal=clock_signal,
        tick_duration=tick_duration,
        end_call_signal=end_call_signal,
        panic_signal=panic_signal,
        mutate_signal=mutate_signal,
        allow_overlap=FLAGS.allow_overlap,
        enable_metronome=FLAGS.enable_metronome,
        min_listen_ticks_control_number=FLAGS.min_listen_ticks_control_number,
        max_listen_ticks_control_number=FLAGS.max_listen_ticks_control_number,
        response_ticks_control_number=FLAGS.response_ticks_control_number,
        tempo_control_number=FLAGS.tempo_control_number,
        temperature_control_number=FLAGS.temperature_control_number,
        loop_control_number=FLAGS.loop_control_number,
        state_control_number=FLAGS.state_control_number)

    _print_instructions()

    interaction.start()
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        interaction.stop()

    print 'Interaction stopped.'
Exemple #14
0
def main(unused_argv):
    tf.logging.set_verbosity(FLAGS.log)

    if not _validate_flags():
        return

    # Load generators.
    generators = []
    for bundle_file in FLAGS.bundle_files.split(','):
        generators.append(_load_generator_from_bundle_file(bundle_file))
        if generators[-1] is None:
            return

    # Initialize MidiHub.
    hub = midi_hub.MidiHub(FLAGS.input_ports.split(','),
                           FLAGS.output_ports.split(','),
                           midi_hub.TextureType.POLYPHONIC,
                           passthrough=FLAGS.passthrough,
                           playback_channel=FLAGS.playback_channel,
                           playback_offset=FLAGS.playback_offset)

    control_map = {
        re.sub('_control_number$', '', f): FLAGS.__getattr__(f)
        for f in _CONTROL_FLAGS
    }
    if FLAGS.learn_controls:
        CCMapper(control_map, hub).update_map()

    if control_map['clock'] is None:
        # Set the tick duration to be a single bar, assuming a 4/4 time signature.
        clock_signal = None
        tick_duration = 4 * (60. / FLAGS.qpm)
    else:
        clock_signal = midi_hub.MidiSignal(control=control_map['clock'],
                                           value=127)
        tick_duration = None

    end_call_signal = (None if control_map['end_call'] is None else
                       midi_hub.MidiSignal(control=control_map['end_call'],
                                           value=127))
    panic_signal = (None if control_map['panic'] is None else
                    midi_hub.MidiSignal(control=control_map['panic'],
                                        value=127))
    mutate_signal = (None if control_map['mutate'] is None else
                     midi_hub.MidiSignal(control=control_map['mutate'],
                                         value=127))
    metronome_channel = (FLAGS.metronome_channel
                         if FLAGS.enable_metronome else None)
    interaction = midi_interaction.CallAndResponseMidiInteraction(
        hub,
        generators,
        FLAGS.qpm,
        FLAGS.generator_select_control_number,
        clock_signal=clock_signal,
        tick_duration=tick_duration,
        end_call_signal=end_call_signal,
        panic_signal=panic_signal,
        mutate_signal=mutate_signal,
        allow_overlap=FLAGS.allow_overlap,
        metronome_channel=metronome_channel,
        min_listen_ticks_control_number=control_map['min_listen_ticks'],
        max_listen_ticks_control_number=control_map['max_listen_ticks'],
        response_ticks_control_number=control_map['response_ticks'],
        tempo_control_number=control_map['tempo'],
        temperature_control_number=control_map['temperature'],
        loop_control_number=control_map['loop'],
        state_control_number=control_map['state'])

    _print_instructions()

    interaction.start()
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        interaction.stop()

    print 'Interaction stopped.'
Exemple #15
0
 def _signal_from_control_map(name):
     if control_map[name] is None:
         return None
     return midi_hub.MidiSignal(control=control_map[name], value=127)
Exemple #16
0
def main(unused_argv):
    if FLAGS.list_ports:
        print "Input ports: '%s'" % ("', '".join(
            midi_hub.get_available_input_ports()))
        print "Ouput ports: '%s'" % ("', '".join(
            midi_hub.get_available_output_ports()))
        return

    if FLAGS.bundle_file is None:
        print '--bundle_file must be specified.'
        return

    if (FLAGS.end_call_control_number, FLAGS.phrase_bars).count(None) != 1:
        print(
            'Exactly one of --end_call_control_number or --phrase_bars should be '
            'specified.')
        return

    try:
        bundle = magenta.music.sequence_generator_bundle.read_bundle_file(
            FLAGS.bundle_file)
    except magenta.music.sequence_generator_bundle.GeneratorBundleParseException:
        print 'Failed to parse bundle file: %s' % FLAGS.bundle_file
        return

    generator_id = bundle.generator_details.id
    if generator_id not in _GENERATOR_FACTORY_MAP:
        print "Unrecognized SequenceGenerator ID '%s' in bundle file: %s" % (
            generator_id, FLAGS.bundle_file)
        return
    generator = _GENERATOR_FACTORY_MAP[generator_id].create_generator(
        checkpoint=None, bundle=bundle)
    generator.initialize()
    print "Loaded '%s' generator bundle from file '%s'." % (
        bundle.generator_details.id, FLAGS.bundle_file)

    if FLAGS.input_port not in midi_hub.get_available_input_ports():
        print "Opening '%s' as a virtual MIDI port for input." % FLAGS.input_port
    if FLAGS.output_port not in midi_hub.get_available_output_ports():
        print "Opening '%s' as a virtual MIDI port for output." % FLAGS.output_port
    hub = midi_hub.MidiHub(FLAGS.input_port, FLAGS.output_port,
                           midi_hub.TextureType.MONOPHONIC)

    end_call_signal = (None if FLAGS.end_call_control_number is None else
                       midi_hub.MidiSignal(
                           control=FLAGS.end_call_control_number, value=0))
    interaction = midi_interaction.CallAndResponseMidiInteraction(
        hub,
        FLAGS.qpm,
        generator,
        phrase_bars=FLAGS.phrase_bars,
        end_call_signal=end_call_signal)

    print ''
    print 'Instructions:'
    print 'Play when you hear the metronome ticking.'
    if FLAGS.phrase_bars is not None:
        print('After %d bars (4 beats), Magenta will play its response.' %
              FLAGS.phrase_bars)
        print(
            'Once the response completes, the metronome will tick and you can '
            'play again.')
    else:
        print(
            'When you want to end the call phrase, signal control number %d '
            'with value 0' % FLAGS.end_call_control_number)
        print(
            'At the end of the current bar (4 beats), Magenta will play its '
            'response.')
        print(
            'Once the response completes, the metronome will tick and you can '
            'play again.')
    print ''
    print 'To end the interaction, press CTRL-C.'

    interaction.start()
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        interaction.stop()

    print 'Interaction stopped.'