-
Notifications
You must be signed in to change notification settings - Fork 0
/
MTC2PointSet.py
97 lines (76 loc) · 3 KB
/
MTC2PointSet.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# -*- coding: utf-8 -*-
"""
Created on Tue Apr 3 16:04:16 2018
@author: Tim
"""
import music21 as m21
#m21.environment.set('musescoreDirectPNGPath', 'C:\\Program Files (x86)\\MuseScore 2\\bin\\MuseScore.exe')
import os
#import numpy
import csv
from fractions import Fraction
#and here we attempt to gather up all the 360 songs in MTC-ANN and output them
#into a concatenated point-set representation, using music21
thisfileDir = os.path.dirname(os.path.realpath('__file__'))
fileDir = os.path.join(thisfileDir, './MTC-ANN-2.0.1/krn')
annFile = os.path.join(thisfileDir, './MTC-ANN-2.0.1/metadata/MTC-ANN-motifs.csv')
tuneFamFile = os.path.join(thisfileDir, './MTC-ANN-2.0.1/metadata/MTC-ANN-tune-family-labels.csv')
#for now points will just be (start time, midi pitch, duration)
#get all the files into songNames
songNames = []
for root, dirs, files in os.walk(fileDir):
for file in files:
if file.endswith('.krn'):
songNames.append(file[:-4])
#make dictionary linking filenames -> songs of each score
print("fetching scores...")
songs = {}
#get songnames in sorted order!!
songNames = sorted(songNames)
for i in range(0,len(songNames)):
f = songNames[i]
songs[f] = {'score': m21.converter.parse(os.path.join(fileDir, f) + ".krn")}
#curScore = songs[f]['score'].flat.notes.stream()
curScore = songs[f]['score'].flat.notes.stream()
pointSet = []
for n in curScore.iter.notes:
off = n.offset
midiVal = n.pitch.midi
dur = n.quarterLength
#this is incredibly stupid but i'm not sure how else to keep
#each song totally separate
pointSet.append((off,midiVal,dur,i))
songs[f]['pointSet'] = pointSet
#dictionary linking tune family names -> lists of song names that belong to
#each tune family
tuneFamToSongNames = {};
with open(tuneFamFile) as csvfile:
reader = csv.reader(csvfile)
for row in reader:
if row[1] in tuneFamToSongNames:
tuneFamToSongNames[row[1]].append(row[0])
else:
tuneFamToSongNames[row[1]] = [row[0]]
print("writing to file...")
for tuneFamName in tuneFamToSongNames.keys():
fname = "./mtcpointset/tuneFam_" + tuneFamName[0:12] + ".txt"
file = open(fname,"w")
tuneFamList = sorted(tuneFamToSongNames[tuneFamName])
#to be compatible with the examples in PattDisc we want no decimals;
#all fractions
for i in range(0,len(tuneFamList)):
sn = tuneFamList[i]
for pt in songs[sn]['pointSet']:
file.write("(")
for j in range(0,len(pt)):
if j != 0:
file.write(" ")
if type(pt[j]) == Fraction:
file.write(str(pt[j].numerator) + "/" + str(pt[j].denominator))
elif (pt[j] != int(pt[j])):
temp = Fraction(pt[j]).limit_denominator(10)
file.write(str(temp.numerator) + "/" + str(temp.denominator))
else:
file.write(str(int(pt[j])))
file.write(")\n")
file.close()