Advertisement
Guest User

pythonchik_3

a guest
Jun 21st, 2018
55
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.55 KB | None | 0 0
  1. # from _overlapped import NULL
  2. import math, mido, numpy, scipy
  3. from mido import MidiFile
  4. import music21
  5. import time
  6. import operator
  7. import pylab as plt
  8. from matplotlib_venn import venn3
  9.  
  10. input_files = {
  11. "in/Star Trek TNG kurz.mid": "F minor", "in/sleepsat.mid": "E- major", "in/silentnight.mid": "C major",
  12. "in/shephard.mid": "F major", "in/sesame.mid": "C minor",
  13. "in/scooby.mid": "C major", "in/Sara.mid": "C major", "in/santacom.mid": "C major", "in/rudolph.mid": "C major",
  14. "in/Rikasmies.mid": "C minor",
  15. "in/reichwaehr.mid": "C minor", "in/prima.mid": "C major", "in/policeacademy.mid": "C major",
  16. "in/pipi-langstrumpf.mid": "C major", "in/Petteri.mid": "C major",
  17. "in/superman.mid": "G major", "in/StheB.mid": "G major", "in/Sternenhimmel.mid": "G major",
  18. "in/starwars-imperial.mid": "D minor", "in/starwars.mid": "C minor",
  19. "in/99 Luftballons.mid": "D minor", "in/90210.mid": "F major", "in/Zorbas.mid": "D major",
  20. "in/ZieGindsKomtDeStoomboot.mid": "F major",
  21. "in/you R not alone.mid": "D minor",
  22. "in/X Files.mid": "E minor", "in/winnerabba.mid": "B major", "in/WalkOfLife.mid": "A major",
  23. "in/Uralinpihlaja.mid": "D minor", "in/tlc.mid": "C major",
  24. "in/Titanic.mid": "C major", "in/tannebaum.mid": "F major",
  25.  
  26. "in/oxygen.mid": "C minor", "in/ohcome.mid": "D minor", "in/Oh_come.mid": "G major",
  27. "in/offspring_getajob.mid": "A minor", "in/o_little.mid": "F major",
  28. "in/o_la_paloma.mid": "G major", "in/nur getrumt.mid": "C major",
  29. "in/Niemals in New York 2.mid": "C major", "in/nie wieder.mid": "C major", "in/murka.mid": "D minor",
  30. "in/Mit 66 Jahren.mid": "F major", "in/Mission_impossible.mid": "E- major",
  31. "in/mief.mid": "C major", "in/marmor-stein.mid": "C major",
  32. "in/major tom.mid": "F major", "in/Macarena.mid": "F major",
  33. "in/LivingRoom.mid": "D minor", "in/liquido.mid": "A minor",
  34.  
  35. "in/Lindenstrae2.mid": "C major", "in/kiss.mid": "A minor", "in/Insel m. 2 Bergen.mid": "C major",
  36. "in/indiana.mid": "C major", "in/howmuchisthefish.mid": "A minor", "in/HoheBerge.mid": "D major",
  37. "in/GWein.mid": "A minor",
  38.  
  39. "in/GuteZeiten.mid": "A minor", "in/Griechischer Wein2.mid": "A minor",
  40. "in/goodbad.mid": "A minor", "in/good.mid": "F major", "in/godfather.mid": "C minor",
  41. "in/god_rest.mid": "D minor", "in/gl_ck.mid": "C major", "in/FofS.mid": "G major",
  42.  
  43. "in/flintstones.mid": "A minor", "in/flieger.mid": "C major",
  44. "in/Eldanka.mid": "D minor", "in/Elamaa_juoksuhaudoissa.mid": "G minor",
  45. "in/einfallfuer2.mid": "A minor", "in/Ein_Fall_Fuer_Zwei.mid": "A minor",
  46. "in/east_end.mid": "B- major", "in/DschingesKhan.mid": "A minor",
  47. "in/deutschlandlied.mid": "G major", "in/denneboom.mid": "F major",
  48. # "in/davy.mid": "C major",
  49. "in/Cucaracha.mid": "C major",
  50. "in/cccp.mid": "A major", "in/boom.mid": "F major", "in/Bittersweetharmonie.mid": "A- major",
  51. "in/big big girl.mid": "C major", "in/Biene Maja.mid": "C major",
  52. "in/away.mid": "F major", "in/advkal8.mid": "C major", "in/advkal10.mid": "C major",
  53. "in/advkal12.mid": "A minor", "in/advkal15.mid": "C major",
  54. "in/advkal17.mid": "C major"
  55.  
  56. }
  57.  
  58. major_profile = [6.35, 2.23, 3.48, 2.33, 4.38, 4.09, 2.52, 5.19, 2.39, 3.66, 2.29, 2.88]
  59. minor_profile = [5.38, 2.60, 3.53, 2.54, 4.75, 3.98, 2.69, 3.34, 3.17, 6.33, 2.68, 3.52]
  60.  
  61. ignored_messages = ["note_off", "polytouch", "control_change", "program_change", "aftertouch",
  62. "pitchwheel", "sysex", "quarter_frame", "songpos", "song_select", "tune_request",
  63. "clock", "start", "continue", "stop", "active_sensing", "reset"]
  64.  
  65. correlate_krumh = {"10": "A", "11": "B-", "12": "B", "1": "C", "2": "D-", "3": "D", "4": "E-",
  66. "5": "E", "6": "F", "7": "G-", "8": "G", "9": "A-"}
  67. correlate_algo = {9: "A", 10: "A ♯ or B ♭", 11: "B", 0: "C", 1: "C ♯ or D ♭", 2: "D", 3: "D ♯ or E ♭",
  68. 4: "E", 5: "F", 6: "F ♯ or G ♭", 7: "G", 8: "G ♯ or A ♭"}
  69.  
  70.  
  71. def get_key(midi_file):
  72. r_major = [0] * 12
  73. r_minor = [0] * 12
  74. frequency = [0] * 12
  75. y = [0] * 12
  76. for i in midi_file.tracks:
  77. for j in i[2:]:
  78. # print("This is j: ", j)
  79. if not j.is_meta and not ignored_messages.__contains__(j.type): # and j.velocity != 0 :
  80. # print("This is j: ", j)
  81. my_note = j.note
  82. frequency[my_note % 12] += 1
  83. x = major_profile
  84. for i in range(12):
  85. for j in range(12):
  86. y[j] = frequency[(j + i) % 12]
  87. help = helper(x, y)
  88. r_major[i] = help[0] / help[1]
  89. x = minor_profile
  90. for i in range(12):
  91. for j in range(12):
  92. y[j] = frequency[(j + i + 3) % 12]
  93. help = helper(x, y)
  94. r_minor[i] = help[0] / help[1]
  95. max_r = -100000
  96. fit_key = 0
  97. for i in range(12):
  98. if max_r < r_major[i]:
  99. max_r = r_major[i]
  100. fit_key = i + 1
  101. lad = "major"
  102. for i in range(12):
  103. if max_r < r_minor[i]:
  104. max_r = r_minor[i]
  105. fit_key = -i - 1
  106. lad = "minor"
  107. return (str)(correlate_krumh[(str)(abs(fit_key))] + " " + (str)(lad))
  108.  
  109.  
  110. def helper(x, y):
  111. meanX = mean(x)
  112. meanY = mean(y)
  113. numerator = 0
  114. denominator_one = 0
  115. denominator_two = 0
  116. for j in range(12):
  117. numerator += (x[j] - meanX) * (y[j] - meanY)
  118. denominator_one += (x[j] - meanX) * (x[j] - meanX)
  119. denominator_two += (y[j] - meanY) * (y[j] - meanY)
  120. denominator = math.sqrt(denominator_one * denominator_two)
  121. return numerator, denominator
  122.  
  123.  
  124. def mean(arr):
  125. size = len(arr)
  126. summ = 0
  127. for i in range(size):
  128. summ += arr[i]
  129. return summ / size
  130.  
  131.  
  132. notes_letters = [['C', 'A'],
  133. ['F', 'D', 'G', 'E'],
  134. ['B-', 'G', 'D', 'B'],
  135. ['E-', 'C', 'A', 'F+'],
  136. ['A-', 'F', 'E', 'C+'],
  137. ['D-', 'B-', 'B', 'G+'],
  138. ['G-', 'E-', 'F+', 'D+'],
  139. ['C-', 'A-', 'C+', 'A+']]
  140. signs_by_key = {
  141. 'C major': 0, 'A minor': 0,
  142. 'F major': 1, 'D minor': 1, 'G major': 1, 'E minor': 1,
  143. 'B- major': 2, 'G minor': 2, 'D major': 2, 'B minor': 2,
  144. 'E- major': 3, 'C minor': 3, 'A major': 3, 'F+ minor': 3,
  145. 'A- major': 4, 'F minor': 4, 'E major': 4, 'C+ minor': 4,
  146. 'D- major': 5, 'B- minor': 5, 'B major': 5, 'G+ minor': 5,
  147. 'G- major': 6, 'E- minor': 6, 'F+ major': 6, 'D+ minor': 6,
  148. }
  149. notes_num = [[0, 9],
  150. [7, 5, 4, 2],
  151. [2, 10, 11, 7],
  152. [9, 3, 6, 0],
  153. [4, 8, 1, 5],
  154. [11, 1, 8, 10],
  155. [6, 6, 3, 3],
  156. [1, 11, 10, 8]]
  157. signs = [6, 1, 8, 3, 10]
  158. sharps = [6, 1, 8, 3, 10, 5, 0]
  159. flats = [10, 3, 8, 1, 6, 11, 4]
  160.  
  161.  
  162. def is_a_sign(x):
  163. return signs.__contains__(x)
  164.  
  165.  
  166. def is_a_sharp(x):
  167. return sharps.__contains__(x)
  168.  
  169.  
  170. def is_a_flat(x):
  171. return flats.__contains__(x)
  172.  
  173.  
  174. major_intervals = [2, 2, 1, 2, 2, 2, 1]
  175. minor_intervals = [2, 1, 2, 2, 1, 2, 2]
  176.  
  177. relative_key = {"C major": "A minor", "D- major": "B- minor", "D major": "B minor", "E- major": "C minor",
  178. "E major": "C+ minor", "F major": "A minor", "F+ major": "D+ minor", "G- major": "E- minor",
  179. "G major": "E minor", "A- major": "F minor", "A major": "F+ minor", "B- major": "G minor",
  180. "B major": "G+ minor",
  181. }
  182.  
  183.  
  184. def algo(file):
  185. frequency = {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0, 10: 0, 11: 0}
  186. note_count = 0
  187. last_note = 0
  188. for i in file.tracks:
  189. # print("track ", i)
  190. for j in i[2:len(i)]:
  191. if not j.is_meta and not ignored_messages.__contains__(j.type) and j.velocity != 0:
  192. # print("msg ", j)
  193. last_note = j.note
  194. note_count += 1
  195. frequency[last_note % 12] += 1
  196. # print("last_note ", last_note)
  197. # print("frequency", frequency)
  198. last_note = last_note % 12
  199.  
  200. the_signs = []
  201. the_sharps = []
  202. the_flats = []
  203. sign_count = 0
  204. meanX = mean(frequency)
  205. # print("mean freq", meanX)
  206. flag = False
  207. we_have_flats = False
  208. sorted_frequency = sorted(frequency.items(), key=operator.itemgetter(1))
  209. sorted_frequency.reverse()
  210. # print("sorted frequency", sorted_frequency)
  211. sorted_frequency = sorted_frequency[:8]
  212. # print("most common ", sorted_frequency)
  213.  
  214. maybe_a_sign = []
  215. for i in range(12):
  216. if frequency[i] > 1:
  217. # if sign_count >= 5:
  218. # flag = True
  219. # if is_a_sharp(i):
  220. # print(frequency[i], "sign_count >= 5, a sharp")
  221. # the_sharps.append(i)
  222. # sign_count += 1
  223. # sharp_count += 1
  224. # elif is_a_flat(i):
  225. # print(frequency[i], "sign_count >= 5, a flat")
  226. # the_flats.append(i)
  227. # sign_count += 1
  228. # flat_count += 1
  229. if is_a_sign(i):
  230. the_signs.append(i)
  231. sign_count += 1
  232. if the_signs.__contains__(signs[0]):
  233. we_have_sharps = True
  234. for x in the_signs: the_sharps.append(x)
  235. elif the_signs.__contains__(signs[len(signs) - 1]):
  236. we_have_flats = True
  237. for x in the_signs: the_flats.append(x)
  238. elif len(the_signs) == 0:
  239. pass
  240. # print("no signs")
  241. # else:
  242. # if the_signs.__contains__(signs[1] or
  243. # the_signs.__contains__(signs[len(signs) - 2])):
  244. # print('how can it be')
  245. # print("hz")
  246.  
  247. # print("note_count ", note_count)
  248. # print("the signs ", the_signs, "signs count ", sign_count)
  249. # print("the sharps ", the_sharps, "\nthe_flats ", the_flats)
  250.  
  251. potential_note_num = []
  252. for i in range(7):
  253. for j in range(0, 1):
  254. if sorted_frequency[i][1] != 0:
  255. potential_note_num.append(sorted_frequency[i][j])
  256. potential_notes_letters = []
  257. for i in range(len(potential_note_num)):
  258. # print("potential note num ",correlate[potential_note_num[i]])
  259. potential_notes_letters.append(correlate_algo[(potential_note_num[i])])
  260. # print("potential notes ", potential_note_num)
  261.  
  262. k = 0
  263. for n in potential_notes_letters:
  264. if len(n) > 2:
  265. if we_have_flats:
  266. potential_notes_letters[k] = n[7:]
  267. else:
  268. potential_notes_letters[k] = n[:3]
  269. k += 1
  270. # print("potential notes ", potential_notes_letters)
  271. # print("num of signs is ", sign_count, "so it should be one of these", notes_letters[sign_count],
  272. # "we have flats? ",
  273. # we_have_flats, ", so it is ", notes_letters[sign_count][:2])
  274. # print("let's try to determine if it is major or minor")
  275.  
  276. if sign_count == 0 or we_have_flats:
  277. major_begin = notes_num[sign_count][0]
  278. minor_begin = notes_num[sign_count][1]
  279. else:
  280. major_begin = notes_num[sign_count][2]
  281. minor_begin = notes_num[sign_count][3]
  282. potential_note_num.sort()
  283. major = []
  284. minor = []
  285. for i in major_intervals:
  286. major_begin += i
  287. major.append(major_begin % 12)
  288. for i in minor_intervals:
  289. minor_begin += i
  290. minor.append(minor_begin % 12)
  291. # print(potential_note_num)
  292. major_count = 0
  293. minor_count = 0
  294. for i in range(7):
  295. if potential_note_num.__contains__(i) and major.__contains__(i):
  296. major_count += 1
  297. if potential_note_num.__contains__(i) and minor.__contains__(i):
  298. minor_count += 1
  299. if major_count >= minor_count and major_count >= 2:
  300. if sign_count == 0 or we_have_flats:
  301. # print('major no signs last note ', last_note, notes_letters[sign_count][0])
  302. if (correlate_algo[(last_note)]) == str(notes_letters[sign_count][0]):
  303. flag = True
  304. return str(notes_letters[sign_count][0]) + " major"
  305. else:
  306. # print('major sharps last note ', last_note, notes_letters[sign_count][2])
  307. if (correlate_algo[(last_note)]) == str(notes_letters[sign_count][2]):
  308. flag = True
  309. return str(notes_letters[sign_count][2]) + " major"
  310.  
  311. elif minor_count >= major_count and minor_count >= 2:
  312. if sign_count == 0 or we_have_flats:
  313. # print('minor no signs last note ', last_note, notes_letters[sign_count][1])
  314. if (correlate_algo[(last_note)]) == str(notes_letters[sign_count][1]):
  315. flag = True
  316. return str(notes_letters[sign_count][1]) + " minor"
  317. else:
  318. # print('minor sharps last note ', last_note, notes_letters[sign_count][3])
  319. if str(correlate_algo[(last_note)]) == str(notes_letters[sign_count][3]):
  320. flag = True
  321. return str(notes_letters[sign_count][3]) + " minor"
  322. # else:
  323. # print("maybe do smth else?")
  324.  
  325.  
  326. def is_paral(one, two):
  327. return relative_key.get(str(one)) == str(two) or relative_key.get(str(two)) == str(one)
  328.  
  329.  
  330. def is_true(key):
  331. return input_files[x] == key
  332.  
  333. # return list(mydict_num.keys())[list(mydict_num.values()).index([0, 9])] == notes_num[input_files[x]]
  334.  
  335.  
  336. # " m21 par or true", "krumhansl par or true", " "," ",
  337. print("true key ", "music21 ", "Krumhansl ", " algo2 ",
  338.  
  339. "music21 = krum ", "", "music21 == algo", " ", " krum = algo ", )
  340.  
  341. music21_true = False
  342. krumhansl_true = False
  343. algo_true = False
  344. music21_krumhansl = False
  345. music21_algo = False
  346. krumhansl_algo = False
  347. all_say_the_same = False
  348. all_say_the_same_and_true = False
  349. at_least_one_true = False
  350. music21_relative = False
  351. krumhansl_relative = False
  352. num_of_files = len(input_files)
  353. music21_num = 0
  354. krumhansl_num = 0
  355. music21_krumhansl_num = 0
  356. music21_parallel_number = 0
  357. krumhansl_parallel_number = 0
  358. krum_algo_num = 0
  359. algo_num = 0
  360. music21_algo_num = 0
  361. intersection = 0
  362. at_least_one_num = 0
  363. i = 0
  364. for x in input_files:
  365. key = music21.converter.parse(x).analyze('key')
  366. mid = MidiFile(x)
  367. krum_key = get_key(mid)
  368. algo_key = algo(mid)
  369.  
  370. if is_true(str(key.tonic.name + " " + key.mode)):
  371. music21_true = True
  372. music21_num += 1
  373. if input_files[x] == krum_key:
  374. krumhansl_true = True
  375. krumhansl_num += 1
  376. if input_files[x] == str(algo_key):
  377. algo_true = True
  378. algo_num += 1
  379.  
  380. if is_true(str(krum_key)) and is_true(str(key.tonic.name + " " + key.mode)) and is_true(str(algo_key)):
  381. # print("all the same! ")
  382. intersection += 1
  383. if is_true(str(krum_key)) or is_true(str(key.tonic.name + " " + key.mode)) or is_true(str(algo_key)):
  384. # print("all the same! ")
  385. at_least_one_num += 1
  386. if is_true(str(krum_key)) and is_true(str(key.tonic.name + " " + key.mode)):
  387. music21_krumhansl = True
  388. music21_krumhansl_num += 1
  389. if is_true(str(algo_key)) and is_true(str(key.tonic.name + " " + key.mode)):
  390. music21_algo = True
  391. music21_algo_num += 1
  392. if is_true(str(krum_key)) and is_true(str(algo_key)):
  393. krumhansl_algo = True
  394. krum_algo_num += 1
  395.  
  396. if str(key.tonic.name + " " + key.mode) == str(relative_key.get(input_files[x])) or music21_true \
  397. or (str)(input_files[x]) == (str)(relative_key.get(key.tonic.name + " " + key.mode)):
  398. music21_relative = True
  399. music21_parallel_number += 1
  400. if str(krum_key) == (str)(relative_key.get(input_files[x])) or krumhansl_true \
  401. or (str)(input_files[x]) == (str)(relative_key.get(krum_key)):
  402. krumhansl_relative = True
  403. krumhansl_parallel_number += 1
  404. # music21_relative, krumhansl_relative, " ",
  405. print(i, input_files[x], " ", key.tonic.name, key.mode, " ", krum_key, " ", algo_key,
  406. " ", music21_krumhansl, " ", music21_algo, " ", krumhansl_algo)
  407. i += 1
  408. music21_true = False
  409. krumhansl_true = False
  410. algo_true = False
  411. music21_krumhansl = False
  412. music21_algo = False
  413. krumhansl_algo = False
  414. all_say_the_same = False
  415. all_say_the_same_and_true = False
  416. at_least_one_true = False
  417. music21_relative = False
  418. krumhansl_relative = False
  419. # music21_parallel_number * 100 // num_of_files, krumhansl_parallel_number * 100 // num_of_files,
  420. print("Percent ", " ", (format(music21_num * 100 / num_of_files,".2f")), " ",
  421. (format(krumhansl_num * 100 / num_of_files, ".2f")), " ",
  422. (format(algo_num * 100 / num_of_files, ".2f")), " ",
  423. (format(music21_krumhansl_num * 100 / num_of_files, ".2f")), " ",
  424. # algo_num * 100 / num_of_files," ",
  425. (format(music21_algo_num * 100 / num_of_files, ".2f")), " ",
  426. (format(krum_algo_num * 100 / num_of_files, ".2f")))
  427.  
  428. print("num of files considered: ", len(input_files))
  429. print(intersection, at_least_one_num)
  430. print(music21_num, krumhansl_num, algo_num)
  431. print(music21_krumhansl_num, music21_algo_num, krum_algo_num)
  432. my_subsets = [0] * 7
  433. my_subsets[6] = intersection #* 100 // at_least_one_num
  434. # my_subsets[6] = all_number * 100 / at_least_one_num
  435. my_subsets[2] = music21_krumhansl_num - my_subsets[6]
  436. my_subsets[4] = music21_algo_num - my_subsets[6]
  437. # print(music21_num, my_subsets[6], my_subsets[2], my_subsets[4])
  438. my_subsets[0] = music21_num - my_subsets[2] - my_subsets[4] - my_subsets[6]
  439. my_subsets[5] = krum_algo_num - my_subsets[6]
  440. my_subsets[1] = krumhansl_num - my_subsets[2] - my_subsets[5] - my_subsets[6]
  441. my_subsets[3] = algo_num - my_subsets[4] - my_subsets[5] - my_subsets[6]
  442. print(my_subsets)
  443. for i in range(7):
  444. if my_subsets[i] < 0:
  445. my_subsets[i] = 0
  446. for i in range(7):
  447. my_subsets[i] = (my_subsets[i] * 100 / at_least_one_num)
  448. # my_subsets[i] = format(my_subsets[i],".2f")
  449. my_subsets[i] = round(my_subsets[i], 2)
  450. venn3(subsets=my_subsets, set_labels=('music21', 'Krumhansl', 'algorithm SA'))
  451. plt.title("Percent of intersection of right answers between algorithms")
  452. plt.show()
  453.  
  454. k = 0
  455. n = 0
  456. i = 0
  457. for x in input_files:
  458. algo_key = algo(MidiFile(x))
  459. # print(input_files[x], algo_key, (is_paral(input_files[x], algo_key) or is_true(algo_key)))
  460. # # print(signs_by_key[str(input_files[x])])
  461. # # print(signs_by_key[input_files[i][1]], signs_by_key[algo_key])
  462. if is_paral(input_files[x], algo_key) or is_true(algo_key):
  463. k += 1
  464. if is_true(algo_key):
  465. n += 1
  466. i += 1
  467. # print(k / len(input_files), n / len(input_files))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement