def expressionOLD(alignment): melody = tools.parseScore(melodyscore) lastnote = None lastscorenote = None mean_vel = 0.0 skipped = 0 for note in melody: scoreindex = note.annotation scorenote = melodyscore[scoreindex[0]][scoreindex[1]][scoreindex[2]][scoreindex[3]] deviation = alignment.alignment[scorenote.id, str(scorenote.pitch)] if not deviation: skipped += 1 continue mean_vel += deviation[2] * 100.0 mean_vel = mean_vel / float(len(melody) - skipped) expression = [] lasttempo = float(alignment.deviations.bpm) lastdynamics = mean_vel lastdeviation = (0, 0, 1, 1) for note in melody: scoreindex = note.annotation scorenote = melodyscore[scoreindex[0]][scoreindex[1]][scoreindex[2]][scoreindex[3]] measure = melodyscore[scoreindex[0]][scoreindex[1]].number deviation = alignment.alignment[scorenote.id, str(scorenote.pitch)] if not deviation: deviation = lastdeviation attack = deviation[0] release = deviation[1] dynamics = deviation[2] relative_dynamics = dynamics * 100.0 / lastdynamics if (measure, int(scorenote.offset)) in alignment.deviations.tempo_deviations: tempo = alignment.deviations.tempo_deviations[measure, int(scorenote.offset)] * alignment.deviations.bpm else: print("{0} {1} not found in tempo deviations".format(measure, int(scorenote.offset))) tempo = lasttempo relative_tempo = tempo / lasttempo lasttempo = tempo lastdynamics = dynamics * 100.0 expression.append((attack, release, dynamics, math.log(relative_tempo), math.log(relative_dynamics))) lastnote = note lastscorenote = scorenote lastdeviation = deviation return expression
def vanDerWeijFeatures(melodyscore, segments): # This is radically different, we only look at features at constituent level melody = tools.parseScore(melodyscore) features = [] index = 0 for i in range(len(segments)): #if i > 0: # segments[i] = [segments[i-1][len(segments[i-1])-1]] + segments[i] length = len(segments[i]) # Calculate features: pitch_int = structure.bare_deltalist(structure.pitch, segments[i]) abs_pitch_int = structure.absolute_deltalist(structure.pitch, segments[i]) pitches = [structure.pitch(segments[i], j) for j in range(len(segments[i]))] durations = [structure.duration(segments[i], j) for j in range(len(segments[i]))] avg_pitch = 1/float(length) * sum(pitches) dPitch = 1/float(length) * sum(pitch_int) abs_dPitch = 1/float(length) * sum(abs_pitch_int) ddPitch = 1/float(length) * sum(structure.second_order_deltalist(pitch_int)) abs_ddPitch = 1/float(length) * sum(structure.second_order_deltalist(abs_pitch_int)) avg_duration_ratio = 0 avg_duration = 1/float(length) * sum(durations) dDuration = 1/float(length) * sum(structure.bare_deltalist(structure.duration, segments[i])) abs_dDuration = 1/float(length) * sum(structure.absolute_deltalist(structure.duration, segments[i])) ddDuration = 1/float(length) * sum(structure.second_order_deltalist(structure.bare_deltalist(structure.duration, segments[i]))) abs_ddDuration = 1/float(length) * sum(structure.second_order_deltalist(structure.absolute_deltalist(structure.duration, segments[i]))) silence = 1/float(length) * sum([structure.silence(segments[i], j+1) for j in range(len(segments[i])-1)]) onsets = structure.normalize([n.on for n in segments[i]]) pitches = structure.normalize([n.pitch for n in segments[i]]) if len(onsets) == 1: pitch_direction = 0 else: pitch_direction = pf.linear_fit(onsets, pitches)[1] # Polyfony? # Score markings? features.append((avg_pitch, dPitch, abs_dPitch, ddPitch, abs_ddPitch,\ avg_duration, dDuration, abs_dDuration, ddDuration, abs_ddDuration,\ silence, pitch_direction, length)) #featureset = ['avg_pitch', 'dPitch', 'abs_dPitch', 'ddPitch', 'abs_ddPitch',\ # 'avg_duration', 'dDuration', 'abs_dDuration', 'ddDuration',\ # 'abs_ddDuration', 'silence', 'pitch_direction'] return features
def expressionWidmer(alignment): performance = alignment.expressiveMelody() melodyscore = alignment.melody() score = tools.parseScore(melodyscore) # The two above should be guaranteed to be of equal length. # However, better be safe than sorry if len(performance) != len(score): print('This shouldn\'t happen: melodyscore and performance lengths don\'t match: {0} and {1}'.format(len(score), len(performance))) else: print("This is good, performance length and score length match") # Mean loudness mean_l = 0.0 for note in performance: mean_l += note.onvelocity mean_l = mean_l / float(len(performance)) expression = [] lasttempo = float(alignment.deviations.bpm) lastdynamics = mean_l # Assume same note order in score and performance (am I being naive?) for i in range(len(performance)): ioi_ratio = math.log(structure.ioi(performance, i) / float(structure.ioi(score, i))) loudness_ratio = math.log(performance[i].onvelocity / mean_l) # This obviously results in zero divisions #articulation = math.log(structure.silence(performance, i) / float(structure.silence(score, i))) articulation = 0 if(structure.duration(performance, i) < 1): print("Invalid performance note :( skipping") continue duration_ratio = math.log(structure.duration(performance, i) / float(structure.duration(score, i))) # To be implemented: second order ioi loudness and articulation ioi_change = 0 loudness_change = 0 articulation_change = 0 # E = (ioi_r, loudness_r, articulation, duration_r, ioi_ch, loundess_ch) e = (ioi_ratio, loudness_ratio, articulation, duration_ratio, ioi_change, loudness_change) expression.append(e) return expression
def features1(melodyscore): melody = tools.parseScore(melodyscore) onset_segments = structure.bestgrouping(melody, structure.second_order_tree(structure.onset, melody, 0.1)) pitch_segments = structure.bestgrouping(melody, structure.second_order_tree(structure.pitch, melody, 0.1)) features = [[] for i in range(len(melody))] index = 0 for i in range(len(onset_segments)): start = onset_segments[i][0].on end = onset_segments[i][len(onset_segments[i])-1].off length = float(end - start) if not i+1 >= len(onset_segments): end = onset_segments[i+1][0].on for note in onset_segments[i]: pos = note.on - start rel_pos = discretize(0, 1, pos / length, 10) features[index] = [rel_pos] index += 1 index = 0 for i in range(len(pitch_segments)): start = pitch_segments[i][0].on end = pitch_segments[i][len(pitch_segments[i])-1].off length = float(end - start) if not i+1 >= len(pitch_segments): end = pitch_segments[i+1][0].on for note in pitch_segments[i]: pos = note.on - start rel_pos = discretize(0, 1, pos / length, 10) features[index].append(rel_pos) index += 1 for i in range(len(melody)): features[i].append(pitch_interval(melody, i)) features[i].append(duration_ratio(melody, i)) return features
def widmerFeatures(melodyscore): melody = tools.parseScore(melodyscore) onset_segments = structure.bestgrouping(melody, structure.second_order_tree(structure.onset, melody, 0.1)) pitch_segments = structure.bestgrouping(melody, structure.second_order_tree(structure.pitch, melody, 0.1)) features = [[] for i in range(len(melody))] index = 0 for i in range(len(onset_segments)): start = onset_segments[i][0].on end = onset_segments[i][len(onset_segments[i])-1].off length = float(end - start) if not i+1 >= len(onset_segments): end = onset_segments[i+1][0].on for note in onset_segments[i]: nearest_border = min(end - note.on, note.on - start) features[index] = [nearest_border] index += 1 index = 0 for i in range(len(pitch_segments)): start = pitch_segments[i][0].on end = pitch_segments[i][len(pitch_segments[i])-1].off length = float(end - start) if not i+1 >= len(pitch_segments): end = pitch_segments[i+1][0].on for note in pitch_segments[i]: nearest_border = min(end - note.on, note.on - start) features[index].append(nearest_border) index += 1 for i in range(len(melody)): features[i].append(pitch_interval(melody, i)) features[i].append(duration_ratio(melody, i)) print(features[10]) return features
def train(trainset): expression = {} features = {} const = 0 Max = 0 Min = None count = 0 print(">>> Loading scores and deviations, this will take hours and may eat all you memory") for query in trainset: print(">>> Loading: {0}".format(query)) score = db.getScore1(query) deviations = db.getDeviation1(query) alignment = Alignment(score, deviations) melody = alignment.melody() #segments = structure.newSegmentation(tools.parseScore(melody)) segments = structure.noteLevel(tools.parseScore(melody)) const += len(segments) lengths = sum([len(s) for s in segments]) m = max([len(s) for s in segments]) mi = min([len(s) for s in segments]) if m > Max: Max = m if not Min: Min = mi if mi < Min: Min = mi print('>>> Extracting features') expression[query] = performancefeatures.vanDerWeijExpression(alignment, segments) features[query] = scorefeatures.vanDerWeijFeatures(melody, segments) count += 1 print('{0}/{1} done'.format(count, len(trainset))) print("Done, {0} segments found with an average length of: {1} (min: {2} max: {3})".format(const, lengths / float(const), Min, Max)) tools.saveFeatures(features, expression)
if __name__ == '__main__': import sys if len(sys.argv) > 1: l = [int(x) for x in sys.argv[1:]] print(relative_deltalist(test, l)) print(second_order_tree(test, l, 0.0, deltalist_function=relative_deltalist)) print(second_order_tree(test, l, 0.0)) sys.exit(0) import database as db import tools w = db.select() score = Score(db.getScore1(w)) melodyscore = score.melody() #melodyscore.show() melody = tools.parseScore(melodyscore, list(range(1, 9))) trees = [second_order_tree(onset, melody, 0.5), second_order_tree(pitch, melody, 0.0, ), first_order_tree(onset, melody, 0.0), first_order_tree(pitch, melody)] for tree in trees: print("Tree") print(tools.recursive_print(tree)) for i in range(5): for j in range(len(trees)): groups = groupings(list_to_tree(trees[j]), i) avg_group = 0 for group in groups: avg_group += len(group) avg_group /= float(len(groups)) print("Tree: {0} Level {1} group size {2}".format(j, i, avg_group))
import database as db from alignment import * from representation import * from sequencer import * from score import * import tools selection = db.select() score = db.getScore1(selection) notes = tools.parseScore(score) seq = Sequencer() seq.play(notes) #s = Score(alignment.score, alignment)
import database as db from sequencer import * from alignment import * import structure, tools import scorefeatures as sf import performancefeatures as pf import perform s = db.select() a = Alignment(db.getScore1(s), db.getDeviation1(s)) melodyscore = a.melody() melody = tools.parseScore(melodyscore) onset = structure.groupings(structure.list_to_tree(structure.first_order_tree(structure.onset, melody, 0.1)), 1) score = sf.vanDerWeijFeatures(melodyscore, onset) performance = pf.vanDerWeijExpression(a, onset) print(score) print(performance) seq = Sequencer() seq.play(perform.vanDerWeijPerformSimple(a.score, melodyscore, onset, performance, bpm=a.deviations.bpm, converter=melody))
def getNoteList(): return tools.parseScore(self.score)
for i in l: result.append(i*i) return result if len(sys.argv) > 1: notes = sys.argv[1] deltas = [int(x) for x in sys.argv[2]] s3 = structure.second_order_deltarule(notes, deltas, 0) print(tools.recursive_print(s3)) sys.exit(0) selection = db.select() score = Score(db.getScore1(selection).stripTies()) melody = score.melody() notes = tools.parseScore(melody) deltas = [] print("COMBINED DELTA TREES") #for feature in [structure.pitch, structure.onset]: # deltas.append(normalize(structure.repetition(feature, notes))) for feature in [structure.onset, structure.duration, structure.pitch]: print(">>>> {0} absolute:".format(feature)) print(structure.absolute_deltalist(feature, notes)) print(">>>> {0} relative:".format(feature)) print(structure.relative_deltalist(feature, notes)) #deltas.append(normalize(square(structure.absolute_deltalist(structure.onset, notes))))
# Load all the scores and notelists #while True: # print db.select() print(">>>> Loading materials.....") schumann = ('Schumann', 'kdz007', 'ashke', 'GPO-Concert-Steinway-ver2.sf2') mozart1 = ('Mozart', 'snt331-3', 'nakam', 'GPO-Concert-Steinway-ver2.sf2') chopin1 = ('Chopin', 'wlz010', 'ashke', 'Bosendorfer PIANO / GIGA') mozart2 = ('Mozart', 'snt331-1', 'mo', None) lastig = ('Bach', 'wtc219-f', 'richt', 'GPO-Concert-Steinway-ver2.sf2') score = Score(db.getScore1(chopin1).stripTies()) melody = score.melody() chopinnotes = tools.parseScore(melody) delta = structure.absolute_deltalist(structure.onset, chopinnotes) sodelta1 = structure.normalize(structure.second_order_deltalist(delta)) score = Score(db.getScore1(mozart2).stripTies()) melody = score.melody() mozartnotes = tools.parseScore(melody) delta2 = structure.square(structure.absolute_deltalist(structure.pitch, mozartnotes)) sodelta2 = structure.normalize(structure.second_order_deltalist(delta2)) s1 = structure.second_order_deltarule(chopinnotes, sodelta1, 0.1) s2 = structure.second_order_deltarule(mozartnotes, sodelta2, 0.1) while True: choice = util.menu("Select", ['Schumann exp', 'Schumann score', 'Schumann noexp', 'chopin struct', 'lastig struct bach', 'struct moz']) if choice == 0: