def extract_trios(self, config, download=False, genre='undefined'): """Extract trios and convert to notesequence Args: input_trio_midi_data: midi files used for encoding config: pre-trained model configuration that was loaded download: should the trios be downloaded genre: genre string that will be used for the downloaded filename""" print 'Extracting trios...' seqs = [] for m in self.input_data: try: mns = mm.midi_to_sequence_proto(m) seqs.append(mns) except: pass extracted_trios = [] for ns in seqs: extracted_trios.extend( config.data_converter.to_notesequences( config.data_converter.to_tensors(ns)[1])) if download: for i, ns in enumerate(extracted_trios): self.download(ns, './content/midi/%s_extrio_%d.mid' % (genre, i)) print '[LG] Done downloading trios' return extracted_trios
def generate_midi(input_midi): primer_sequence = mm.midi_to_sequence_proto(input_midi) generated_sequence = _generate_sequence(primer_sequence) output = tempfile.NamedTemporaryFile() mm.sequence_proto_to_midi_file(generated_sequence, output.name) output.seek(0) return output
def _getPianoTrackFromTrio(self, input_sequence, midFilepath, midRootpath): print('midFilepath:' + midFilepath) print('midRootpath:' + midRootpath) tempPath = midRootpath + 'temp' print('tempPath:' + tempPath) subprocess.call([ 'python', '/Users/inhyukyee/git/AIM/tools/midi_splitter.py', '-f', midFilepath, '-d', tempPath ]) #save input_sequence to midi file mm.sequence_proto_to_midi_file( input_sequence, midRootpath + '/temp/input_sequence.mid') front_midi_data = pretty_midi.PrettyMIDI(midRootpath + 'temp/input_sequence.mid') orig_midi_data = pretty_midi.PrettyMIDI(midRootpath + 'temp/0_.mid') merged_midi_data = pretty_midi.PrettyMIDI(midRootpath + 'temp/0_.mid') del merged_midi_data.instruments[0].notes[:] #front_midi_data_start_time = None front_midi_data_end_time = None for note in front_midi_data.instruments[0].notes: #print(note) #if front_midi_data_start_time == None: #front_midi_data_start_time = note.start #note.start = note.start - front_midi_data_start_time #note.end = note.end -front_midi_data_start_time front_midi_data_end_time = note.end merged_midi_data.instruments[0].notes.append(note) ##print('\n\n') #merge front & orig for note in orig_midi_data.instruments[0].notes: #print(note) if note.start >= front_midi_data_end_time: merged_midi_data.instruments[0].notes.append(note) ##print('\n\n') ''' for note in merged_midi_data.instruments[0].notes: print(note) ''' merged_midi_data.write(midRootpath + 'temp/merged.mid') #merge to trio trio_merged_midi_data = pretty_midi.PrettyMIDI(midRootpath + 'temp/merged.mid') #trio_merged_midi_data.instruments.append(midRootpath + 'temp/merged.mid') trio_merged_midi_data.instruments.append( pretty_midi.PrettyMIDI(midRootpath + 'temp/1_.mid').instruments[0]) trio_merged_midi_data.instruments.append( pretty_midi.PrettyMIDI(midRootpath + 'temp/2_.mid').instruments[0]) trio_merged_midi_data.write(midRootpath + 'temp/trio_merged.mid') return mm.midi_to_sequence_proto( pretty_midi.PrettyMIDI(midRootpath + 'temp/merged.mid'))
def extract_trios(self, config, download=False, genre='undefined'): """Extract trios and convert to notesequence Args: input_trio_midi_data: midi files used for encoding config: pre-trained model configuration that was loaded download: should the trios be downloaded genre: genre string that will be used for the downloaded filename""" print 'Extracting trios...' seqs = [] for m in self.input_data: try: mns = mm.midi_to_sequence_proto(m) seqs.append(mns) except Exception, e: print e
def run(config_map): """Load model params, save config file and start trainer. Args: config_map: Dictionary mapping configuration name to Config object. Raises: ValueError: if required flags are missing or invalid. """ date_and_time = time.strftime('%Y-%m-%d_%H%M%S') if FLAGS.run_dir is None and FLAGS.checkpoint_file is None: raise ValueError( 'Exactly one of `--run_dir` or `--checkpoint_file` must be specified.') if FLAGS.output_dir is None: raise ValueError('`--output_dir` is required.') tf.gfile.MakeDirs(FLAGS.output_dir) if FLAGS.mode != 'sample' and FLAGS.mode != 'interpolate': raise ValueError('Invalid value for `--mode`: %s' % FLAGS.mode) if FLAGS.config not in config_map: raise ValueError('Invalid config name: %s' % FLAGS.config) config = config_map[FLAGS.config] config.data_converter.max_tensors_per_item = None if FLAGS.mode == 'interpolate': if FLAGS.input_midi_1 is None or FLAGS.input_midi_2 is None: raise ValueError( '`--input_midi_1` and `--input_midi_2` must be specified in ' '`interpolate` mode.') input_midi_1 = os.path.expanduser(FLAGS.input_midi_1) input_midi_2 = os.path.expanduser(FLAGS.input_midi_2) if not os.path.exists(input_midi_1): raise ValueError('Input MIDI 1 not found: %s' % FLAGS.input_midi_1) if not os.path.exists(input_midi_2): raise ValueError('Input MIDI 2 not found: %s' % FLAGS.input_midi_2) input_1 = mm.midi_to_sequence_proto(tf.gfile.GFile(input_midi_1, 'rb').read()) input_2 = mm.midi_to_sequence_proto(tf.gfile.GFile(input_midi_2, 'rb').read()) def _check_extract_examples(input_ns, path, input_number): """Make sure each input returns exactly one example from the converter.""" tensors = config.data_converter.to_tensors(input_ns).outputs if not tensors: print( 'MusicVAE configs have very specific input requirements. Could not ' 'extract any valid inputs from `%s`. Try another MIDI file.' % path) sys.exit() elif len(tensors) > 1: basename = os.path.join( FLAGS.output_dir, '%s_input%d-extractions_%s-*-of-%03d.mid' % (FLAGS.config, input_number, date_and_time, len(tensors))) for i, ns in enumerate(config.data_converter.to_notesequences(tensors)): mm.sequence_proto_to_midi_file(ns, basename.replace('*', '%03d' % i)) print( '%d valid inputs extracted from `%s`. Outputting these potential ' 'inputs as `%s`. Call script again with one of these instead.' % (len(tensors), path, basename)) sys.exit() logging.info( 'Attempting to extract examples from input MIDIs using config `%s`...', FLAGS.config) _check_extract_examples(input_1, FLAGS.input_midi_1, 1) _check_extract_examples(input_2, FLAGS.input_midi_2, 2) logging.info('Loading model...') checkpoint_dir_or_path = os.path.expanduser( os.path.join(FLAGS.run_dir, 'train') if FLAGS.run_dir else FLAGS.checkpoint_file) model = TrainedModel( config, batch_size=min(FLAGS.max_batch_size, FLAGS.num_outputs), checkpoint_dir_or_path=checkpoint_dir_or_path) if FLAGS.mode == 'interpolate': logging.info('Interpolating...') _, mu, _ = model.encode([input_1, input_2]) z = np.array([ _slerp(mu[0], mu[1], t) for t in np.linspace(0, 1, FLAGS.num_outputs)]) results = model.decode( length=config.hparams.max_seq_len, z=z, temperature=FLAGS.temperature) elif FLAGS.mode == 'sample': logging.info('Sampling...') results = model.sample( n=FLAGS.num_outputs, length=config.hparams.max_seq_len, temperature=FLAGS.temperature) basename = os.path.join( FLAGS.output_dir, '%s_%s_%s-*-of-%03d.mid' % (FLAGS.config, FLAGS.mode, date_and_time, FLAGS.num_outputs)) logging.info('Outputting %d files as `%s`...', FLAGS.num_outputs, basename) for i, ns in enumerate(results): mm.sequence_proto_to_midi_file(ns, basename.replace('*', '%03d' % i)) logging.info('Done.')
#@title Optionally download MIDI samples. print 'Downloading samples...' for i, ns in enumerate(trio_16_samples): download(ns, './content/midi/%s_sample_%d.mid' % (trio_sample_model, i)) print 'Finished downloading samples' #@title Option 1: Use example MIDI files for interpolation endpoints. print 'Using example MIDI files' input_trio_midi_data = [ tf.gfile.Open(fn).read() for fn in sorted(tf.gfile.Glob('./content/midi/trio_16bar*.mid')) ] #@title Extract trios from MIDI files. This will extract all unique 16-bar trios using a sliding window with a stride of 1 bar. print 'Extracting trios...' trio_input_seqs = [mm.midi_to_sequence_proto(m) for m in input_trio_midi_data] # toy = trio_input_seqs[0] # print type(toy) # print toy # print hierdec_trio_16bar_config.data_converter.to_tensors(toy)[1] extracted_trios = [] for ns in trio_input_seqs: extracted_trios.extend( hierdec_trio_16bar_config.data_converter.to_notesequences( hierdec_trio_16bar_config.data_converter.to_tensors(ns)[1])) for i, ns in enumerate(extracted_trios): print "Trio", i play(ns)
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. """ print('zero_time:' + str(zero_time)) print('response_start_time:' + str(response_start_time)) print('response_end_time:' + str(response_end_time)) time_adjusted_input_sequence = adjust_sequence_times( input_sequence, -zero_time) MidiInteraction.count = MidiInteraction.count + 1 # 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 print('####################self._sequence_generator:' + str(self._sequence_generator) + '####################') if self._sequence_generator == 'Trio': Rootpath = '/Users/inhyukyee/repo/pregenerated/' midRootpath = '' wavFilepath = '' num_mid_file = 0 if self._should_short: print('SHORT 8s') midRootpath = '/Users/inhyukyee/repo/pregenerated/8s/mid/' wavFilepath = '/Users/inhyukyee/repo/pregenerated/8s/wav/trio_merged.wav' num_mid_file = 4392 else: print('LONG 32s') midRootpath = '/Users/inhyukyee/repo/pregenerated/32s/mid/' wavFilepath = '/Users/inhyukyee/repo/pregenerated/32s/wav/trio_merged.wav' num_mid_file = 10000 targetNum = random.randint(1, num_mid_file) midFilepath = os.path.join(midRootpath, str(targetNum) + '.mid') print(midFilepath) #wavFilepath = os.path.join(wavRootpath, targetNum + '.wav') #command = 'sleep 1 && afplay ' + audio_file #proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) response_sequence = self._getPianoTrackFromTrio( time_adjusted_input_sequence, midFilepath, midRootpath) diff = 0 for i in range(0, len(response_sequence.notes)): if response_sequence.notes[ i].start_time < response_start_time and i == 0: diff = response_start_time - response_sequence.notes[ i].start_time if diff == 0: break response_sequence.notes[ i].start_time = response_sequence.notes[i].start_time + diff response_sequence.notes[ i].end_time = response_sequence.notes[i].end_time + diff f_response_sequence = adjust_sequence_times( response_sequence, zero_time) ''' for note in f_response_sequence.notes: print(note) ''' midi_data = pretty_midi.PrettyMIDI(midRootpath + 'temp/trio_merged.mid') note_sequence = mm.midi_to_sequence_proto(midi_data) mm.play_sequence(note_sequence, synth=mm.fluidsynth, wavpath=wavFilepath) #proc = subprocess.Popen(['afplay', wavFilepath]) command = 'sleep 1 && afplay ' + wavFilepath proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, preexec_fn=os.setsid) #proc = self._popenAndCall(self._onSubProcessExit, command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, preexec_fn=os.setsid) pe = ProcElement(proc, time.time()) self._procsQ.append(pe) return f_response_sequence elif self._sequence_generator == 'Multitracks': print('Multitracks!') #just get any melody track from Trio midRootpath = '/Users/inhyukyee/repo/pregenerated/32s/mid/' num_mid_file = 1458 targetNum = random.randint(1, num_mid_file) midFilepath = os.path.join(midRootpath, str(targetNum) + '.mid') print(midFilepath) response_sequence = self._getPianoTrackFromTrio( time_adjusted_input_sequence, midFilepath, midRootpath) f_response_sequence = adjust_sequence_times( response_sequence, zero_time) #END:just get any melody track from Trio wavRootpath = '/Users/inhyukyee/repo/pregenerated/32s/multitracks_wav/' wavFilepath = wavRootpath + str(random.randint( 0, num_mid_file)) + '.wav' print('wavFilepath:' + wavFilepath) #wavFilepath = os.path.join(wavRootpath, str(random.randint(0, num_mid_file)), '.wav') #wavFilepath = os.path.join(wavRootpath, '99.wav') ''' midi_data = pretty_midi.PrettyMIDI( '/Users/inhyukyee/repo/pregenerated/32s/4tracks_mid/' + str(targetNum) + '.mid') note_sequence = mm.midi_to_sequence_proto(midi_data) mm.play_sequence(note_sequence, synth=mm.fluidsynth, sf2_path='/Users/inhyukyee/Downloads/SGM-v2.01-Sal-Guit-Bass-V1.3.sf2', wavpath=wavFilepath) ''' command = 'sleep 1 && afplay ' + wavFilepath proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, preexec_fn=os.setsid) #proc = self._popenAndCall(self._onSubProcessExit, command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, preexec_fn=os.setsid) pe = ProcElement(proc, time.time()) self._procsQ.append(pe) return f_response_sequence else: # 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 = magenta.music.trim_note_sequence( response_sequence, response_start_time, response_end_time) final_response_sequence = adjust_sequence_times( response_sequence, zero_time) ''' print('##############################final_response_sequence##############################') print('response_start_time:' + str(response_start_time)) print('response_end_time:' + str(response_end_time)) print('zero_time:' + str(zero_time)) print(final_response_sequence) print('##############################final_response_sequence##############################') ''' return final_response_sequence
seqs = model.decode(length=TOTAL_STEPS, z=z, temperature=temperature) trim_sequences(seqs) fix_instruments_for_concatenation(seqs) interp_ns = concatenate_sequences(seqs) play(interp_ns) mm.plot_sequence(interp_ns) #@title (Optional) Save to MIDI download(interp_ns, 'interp.mid') #@title Upload MIDI Files to Reconstruct midi_files = files.upload().values() seqs = [mm.midi_to_sequence_proto(midi) for midi in midi_files] uploaded_seqs = [] for seq in seqs: _, tensors, _, _ = model._config.data_converter.to_tensors(seq) uploaded_seqs.extend(model._config.data_converter.from_tensors(tensors)) trim_sequences(uploaded_seqs) print('Parsed %d measures' % len(uploaded_seqs)) #@title Encode and Decode index = 0 #@param {type:"integer"} temperature = 0.2 #@param {type:"slider", min:0.01, max:1.5, step:0.01}
#@title Optionally download generated MIDI samples. for i, ns in enumerate(drums_samples): download(ns, '%s_sample_%d.mid' % (drums_sample_model, i)) """## Generate Interpolations""" #@title Option 1: Use example MIDI files for interpolation endpoints. input_drums_midi_data = [ tf.gfile.Open(fn).read() for fn in sorted(tf.gfile.Glob('/content/midi/drums_2bar*.mid'))] #@title Option 2: upload your own MIDI files to use for interpolation endpoints instead of those provided. input_drums_midi_data = files.upload().values() or input_drums_midi_data #@title Extract drums from MIDI files. This will extract all unique 2-bar drum beats using a sliding window with a stride of 1 bar. drums_input_seqs = [mm.midi_to_sequence_proto(m) for m in input_drums_midi_data] extracted_beats = [] for ns in drums_input_seqs: extracted_beats.extend(drums_nade_full_config.data_converter.to_notesequences( drums_nade_full_config.data_converter.to_tensors(ns)[1])) for i, ns in enumerate(extracted_beats): print "Beat", i play(ns) #@title Interpolate between 2 beats, selected from those in the previous cell. drums_interp_model = "drums_2bar_oh_hikl" #@param ["drums_2bar_oh_lokl", "drums_2bar_oh_hikl", "drums_2bar_nade_reduced", "drums_2bar_nade_full"] start_beat = 0 #@param {type:"integer"} end_beat = 1 #@param {type:"integer"} start_beat = extracted_beats[start_beat] end_beat = extracted_beats[end_beat]