Skip to content
This repository has been archived by the owner on Mar 14, 2023. It is now read-only.

Commit

Permalink
Generate midi files using markov chains and evaluate quality
Browse files Browse the repository at this point in the history
  • Loading branch information
VikParuchuri committed Jul 27, 2013
1 parent acc1c5c commit 5f5fc09
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 4 deletions.
1 change: 1 addition & 0 deletions config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
SOUNDFONT_PATH = "/usr/share/sounds/sf2/FluidR3_GM.sf2"

MUSIC_STORE_PATH = os.path.abspath(os.path.join(DATA_PATH, "generated"))
MIDI_STORE_PATH = os.path.abspath(os.path.join(DATA_PATH, "generated_midi"))

#Commands are discovered here, and tasks/inputs/formats are imported using only these modules
INSTALLED_APPS = [
Expand Down
2 changes: 1 addition & 1 deletion inputs/inputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def convert_to_ogg(mfile):
wavfile = file_end + ".wav"
oggpath = os.path.abspath(os.path.join(settings.MIDI_PATH,oggfile))
wavpath = os.path.abspath(os.path.join(settings.MIDI_PATH,wavfile))
if not os.path.isfile(oggfile):
if not os.path.isfile(oggpath):
subprocess.call(['fluidsynth', '-i','-n', '-F', wavpath, settings.SOUNDFONT_PATH, mfile])
subprocess.call(['oggenc', wavpath])
os.remove(wavpath)
Expand Down
86 changes: 83 additions & 3 deletions tasks/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -468,9 +468,10 @@ def convert_to_ogg(mfile):
wavfile = file_end + ".wav"
oggpath = os.path.abspath(os.path.join(settings.MIDI_PATH,oggfile))
wavpath = os.path.abspath(os.path.join(settings.MIDI_PATH,wavfile))

subprocess.call(['fluidsynth', '-i','-n', '-F', wavpath, settings.SOUNDFONT_PATH, mfile])
subprocess.call(['oggenc', wavpath])
if not os.path.isfile(oggpath):
subprocess.call(['fluidsynth', '-i','-n', '-F', wavpath, settings.SOUNDFONT_PATH, mfile])
subprocess.call(['oggenc', wavpath])
os.remove(wavpath)
return oggpath

def additive_transform(pitch,msign=1):
Expand Down Expand Up @@ -682,6 +683,19 @@ def generate_tempo_track(tempos,length):
track.append(midi.EndOfTrackEvent())
return track

def evaluate_midi_quality(pattern,clf):
midi_path = os.path.abspath(os.path.join(settings.MIDI_STORE_PATH,"tmp.mid"))
midi.write_midifile(midi_path,pattern)
oggpath = convert_to_ogg(midi_path)
data, fs, enc = oggread(oggpath)
features = process_song(data,fs)
quality = clf.predict_proba(features)[0,1]
return quality

def generate_pattern(tracks):
pat = midi.Pattern(tracks=tracks)
return pat

class GenerateTransitionMatrix(Task):
data = Complex()

Expand Down Expand Up @@ -719,4 +733,70 @@ def predict(self, data, **kwargs):

data = {'files' : data, 'notes' : notes, 'tempos' : tempos, 'nm' : nm, 'tm': tm}

return data

class GenerateMarkovTracks(Task):
data = Complex()

data_format = MusicFormats.dataframe

category = RegistryCategories.preprocessors
namespace = get_namespace(__module__)

help_text = "Process midi files."

args = {
'non_predictors' : ["labels","label_code","fs","enc","fname","Unnamed: 0"],
'target_var' : 'label_code',
}

def train(self, data, target, **kwargs):
"""
Used in the training phase. Override.
"""
self.data = self.predict(data, **kwargs)

def predict(self, data, **kwargs):
"""
Used in the predict phase, after training. Override
"""
frame1 = pd.read_csv(settings.MIDI_FEATURE_PATH)
frame2 = pd.read_csv(settings.FEATURE_PATH)

frame = pd.concat([frame1,frame2],axis=0)
non_predictors = kwargs.get('non_predictors')
target = kwargs.get('target_var')

frame.index = range(frame.shape[0])

alg = RandomForestTrain()
good_names = [i for i in frame.columns if i not in non_predictors]
for c in good_names:
frame[c] = frame[c].astype(float)

for c in good_names:
frame[c] = frame[c].real

clf = alg.train(np.asarray(frame[good_names]),frame[target],**alg.args)
track_pool = []
for i in xrange(0,100):
track_pool.append(generate_audio_track(data['nm'],1000))

tempo_pool = []
for i in xrange(0,100):
tempo_pool.append(generate_tempo_track(data['tm'],1000))

pattern_pool = []
for i in xrange(0,100):
track_count = random.randint(1,8)
tempo_track = random.choice(tempo_pool)
tracks = [tempo_track]
for i in xrange(0,track_count):
tracks.append(random.choice(track_pool))
pattern_pool.append(generate_pattern(tracks))

quality = []
for p in pattern_pool:
quality.append(evaluate_midi_quality(p,clf))

return data

0 comments on commit 5f5fc09

Please sign in to comment.