Last active
September 29, 2020 10:58
-
-
Save NP-chaonay/c539aafc597457ecd9d8221b4916dcf8 to your computer and use it in GitHub Desktop.
Own created algorithm for classify key and mode of the music.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pandas as pd | |
import numpy as np | |
## Function "pitch_letter_encoder" from future module "np_chaonay.pymusicnote" | |
def pitch_letter_encoder(pitch_letter): | |
"""Encode pitch letter to 0-11 | |
Arguments: | |
- pitch_letter (str-alike): pitch letter | |
""" | |
### 2 lines below are commented: Requires future module "np_chaonay.main" | |
#_npc_m.alternative_isinstance('pitch_letter',(str,),pitch_letter) | |
#if not pitch_letter_checking(pitch_letter): raise _npc_m.arg_value_error('pitch_letter','be in supported') | |
pitch_letter=pitch_letter[0].upper()+pitch_letter[1:] | |
return {'C':3,'D':5,'E':7,'F':8,'G':10,'A':0,'B':2,'Cb':2,'Db':4,'Eb':6,'Fb':7,'Gb':9,'Ab':11,'Bb':1,'C#':4,'D#':6,'E#':8,'F#':9,'G#':11,'A#':1,'B#':3}[pitch_letter] | |
## Function "key_detector" | |
def key_detector(notes): | |
### Notes count for each pitch letter | |
a_note_count=notes.count(0) | |
bb_note_count=notes.count(1) | |
b_note_count=notes.count(2) | |
c_note_count=notes.count(3) | |
db_note_count=notes.count(4) | |
d_note_count=notes.count(5) | |
eb_note_count=notes.count(6) | |
e_note_count=notes.count(7) | |
f_note_count=notes.count(8) | |
gb_note_count=notes.count(9) | |
g_note_count=notes.count(10) | |
ab_note_count=notes.count(11) | |
### sum of 7-notes classification | |
C_Am=a_note_count+b_note_count+c_note_count+d_note_count+e_note_count+f_note_count+g_note_count | |
Db_Bbm=bb_note_count+c_note_count+db_note_count+eb_note_count+f_note_count+gb_note_count+ab_note_count | |
D_Bm=b_note_count+db_note_count+d_note_count+e_note_count+gb_note_count+g_note_count+a_note_count | |
Eb_Cm=c_note_count+d_note_count+eb_note_count+f_note_count+g_note_count+ab_note_count+bb_note_count | |
E_Dbm=db_note_count+eb_note_count+e_note_count+gb_note_count+ab_note_count+a_note_count+b_note_count | |
F_Dm=d_note_count+e_note_count+f_note_count+g_note_count+a_note_count+bb_note_count+c_note_count | |
Gb_Ebm=eb_note_count+f_note_count+gb_note_count+ab_note_count+bb_note_count+b_note_count+db_note_count | |
G_Em=e_note_count+gb_note_count+g_note_count+a_note_count+b_note_count+c_note_count+d_note_count | |
Ab_Fm=f_note_count+g_note_count+ab_note_count+bb_note_count+c_note_count+db_note_count+eb_note_count | |
A_Gbm=gb_note_count+ab_note_count+a_note_count+b_note_count+db_note_count+d_note_count+e_note_count | |
Bb_Gm=g_note_count+a_note_count+bb_note_count+c_note_count+d_note_count+eb_note_count+f_note_count | |
B_Abm=ab_note_count+bb_note_count+b_note_count+db_note_count+eb_note_count+e_note_count+gb_note_count | |
#### Split 12 musical key groups into 24 musical keys, due to sum of 7-notes cannot classify further two major-minor keys pair | |
C=C_Am | |
Am=C_Am | |
Db=Db_Bbm | |
Bbm=Db_Bbm | |
D=D_Bm | |
Bm=D_Bm | |
Eb=Eb_Cm | |
Cm=Eb_Cm | |
E=E_Dbm | |
Dbm=E_Dbm | |
F=F_Dm | |
Dm=F_Dm | |
Gb=Gb_Ebm | |
Ebm=Gb_Ebm | |
G=G_Em | |
Em=G_Em | |
Ab=Ab_Fm | |
Fm=Ab_Fm | |
A=A_Gbm | |
Gbm=A_Gbm | |
Bb=Bb_Gm | |
Gm=Bb_Gm | |
B=B_Abm | |
Abm=B_Abm | |
label=['C','Db','D','Eb','E','F','Gb','G','Ab','A','Bb','B','Cm','Dbm','Dm','Ebm','Em','Fm','Gbm','Gm','Abm','Am','Bbm','Bm'] | |
count=[C,Db,D,Eb,E,F,Gb,G,Ab,A,Bb,B,Cm,Dbm,Dm,Ebm,Em,Fm,Gbm,Gm,Abm,Am,Bbm,Bm] | |
n7_notes=set(pd.DataFrame({'pitch_letter':label,'count':count}).nlargest(1,'count',keep='all').pitch_letter) | |
### sum of 5-notes classification | |
C=c_note_count+d_note_count+e_note_count+f_note_count+g_note_count | |
Db=db_note_count+eb_note_count+f_note_count+gb_note_count+ab_note_count | |
D=d_note_count+e_note_count+gb_note_count+g_note_count+a_note_count | |
Eb=eb_note_count+f_note_count+g_note_count+ab_note_count+bb_note_count | |
E=e_note_count+gb_note_count+ab_note_count+a_note_count+b_note_count | |
F=f_note_count+g_note_count+a_note_count+bb_note_count+c_note_count | |
Gb=gb_note_count+ab_note_count+bb_note_count+b_note_count+db_note_count | |
G=g_note_count+a_note_count+b_note_count+c_note_count+d_note_count | |
Ab=ab_note_count+bb_note_count+c_note_count+db_note_count+eb_note_count | |
A=a_note_count+b_note_count+db_note_count+d_note_count+e_note_count | |
Bb=bb_note_count+c_note_count+d_note_count+eb_note_count+f_note_count | |
B=b_note_count+db_note_count+eb_note_count+e_note_count+gb_note_count | |
Am=a_note_count+b_note_count+c_note_count+d_note_count+e_note_count | |
Bbm=bb_note_count+c_note_count+db_note_count+eb_note_count+f_note_count | |
Bm=b_note_count+db_note_count+d_note_count+e_note_count+gb_note_count | |
Cm=c_note_count+d_note_count+eb_note_count+f_note_count+g_note_count | |
Dbm=db_note_count+eb_note_count+e_note_count+gb_note_count+ab_note_count | |
Dm=d_note_count+e_note_count+f_note_count+g_note_count+a_note_count | |
Ebm=eb_note_count+f_note_count+gb_note_count+ab_note_count+bb_note_count | |
Em=e_note_count+gb_note_count+g_note_count+a_note_count+b_note_count | |
Fm=f_note_count+g_note_count+ab_note_count+bb_note_count+c_note_count | |
Gbm=gb_note_count+ab_note_count+a_note_count+b_note_count+db_note_count | |
Gm=g_note_count+a_note_count+bb_note_count+c_note_count+d_note_count | |
Abm=ab_note_count+bb_note_count+b_note_count+db_note_count+eb_note_count | |
label=['C','Db','D','Eb','E','F','Gb','G','Ab','A','Bb','B','Cm','Dbm','Dm','Ebm','Em','Fm','Gbm','Gm','Abm','Am','Bbm','Bm'] | |
count=[C,Db,D,Eb,E,F,Gb,G,Ab,A,Bb,B,Cm,Dbm,Dm,Ebm,Em,Fm,Gbm,Gm,Abm,Am,Bbm,Bm] | |
n5_notes=set(pd.DataFrame({'pitch_letter':label,'count':count}).nlargest(1,'count',keep='all').pitch_letter) | |
### sum of 3-notes classification | |
C=c_note_count+e_note_count+g_note_count | |
Db=db_note_count+f_note_count+ab_note_count | |
D=d_note_count+gb_note_count+a_note_count | |
Eb=eb_note_count+g_note_count+bb_note_count | |
E=e_note_count+ab_note_count+b_note_count | |
F=f_note_count+a_note_count+c_note_count | |
Gb=gb_note_count+bb_note_count+db_note_count | |
G=g_note_count+b_note_count+d_note_count | |
Ab=ab_note_count+c_note_count+eb_note_count | |
A=a_note_count+db_note_count+e_note_count | |
Bb=bb_note_count+d_note_count+f_note_count | |
B=b_note_count+eb_note_count+gb_note_count | |
Am=a_note_count+c_note_count+e_note_count | |
Bbm=bb_note_count+db_note_count+f_note_count | |
Bm=b_note_count+d_note_count+gb_note_count | |
Cm=c_note_count+eb_note_count+g_note_count | |
Dbm=db_note_count+e_note_count+ab_note_count | |
Dm=d_note_count+f_note_count+a_note_count | |
Ebm=eb_note_count+gb_note_count+bb_note_count | |
Em=e_note_count+g_note_count+b_note_count | |
Fm=f_note_count+ab_note_count+c_note_count | |
Gbm=gb_note_count+a_note_count+db_note_count | |
Gm=g_note_count+bb_note_count+d_note_count | |
Abm=ab_note_count+b_note_count+eb_note_count | |
label=['C','Db','D','Eb','E','F','Gb','G','Ab','A','Bb','B','Cm','Dbm','Dm','Ebm','Em','Fm','Gbm','Gm','Abm','Am','Bbm','Bm'] | |
count=[C,Db,D,Eb,E,F,Gb,G,Ab,A,Bb,B,Cm,Dbm,Dm,Ebm,Em,Fm,Gbm,Gm,Abm,Am,Bbm,Bm] | |
n3_notes=set(pd.DataFrame({'pitch_letter':label,'count':count}).nlargest(1,'count',keep='all').pitch_letter) | |
### sum of 1-notes classification | |
C=c_note_count | |
Db=db_note_count | |
D=d_note_count | |
Eb=eb_note_count | |
E=e_note_count | |
F=f_note_count | |
Gb=gb_note_count | |
G=g_note_count | |
Ab=ab_note_count | |
A=a_note_count | |
Bb=bb_note_count | |
B=b_note_count | |
Am=a_note_count | |
Bbm=bb_note_count | |
Bm=b_note_count | |
Cm=c_note_count | |
Dbm=db_note_count | |
Dm=d_note_count | |
Ebm=eb_note_count | |
Em=e_note_count | |
Fm=f_note_count | |
Gbm=gb_note_count | |
Gm=g_note_count | |
Abm=ab_note_count | |
label=['C','Db','D','Eb','E','F','Gb','G','Ab','A','Bb','B','Cm','Dbm','Dm','Ebm','Em','Fm','Gbm','Gm','Abm','Am','Bbm','Bm'] | |
count=[C,Db,D,Eb,E,F,Gb,G,Ab,A,Bb,B,Cm,Dbm,Dm,Ebm,Em,Fm,Gbm,Gm,Abm,Am,Bbm,Bm] | |
n1_notes=set(pd.DataFrame({'pitch_letter':label,'count':count}).nlargest(1,'count',keep='all').pitch_letter) | |
# print sets | |
print('[Sets]') | |
print('7-notes sum: ',n7_notes) | |
print('5-notes sum: ',n5_notes) | |
print('3-notes sum: ',n3_notes) | |
print('1-notes sum: ',n1_notes) | |
# print sets combination | |
print('[Sets Combination]') | |
print('Combination of each 7-notes sum: ',n7_notes) | |
print('Combination of each 7-notes,5-notes sum: ',n7_notes&n5_notes) | |
print('Combination of each 7-notes,5-notes,3-notes sum: ',n7_notes&n5_notes&n3_notes) | |
print('Combination of each 7-notes,5-notes,3-notes,1-notes sum: ',n7_notes&n5_notes&n3_notes&n1_notes) | |
# print prediction | |
print('[Prediction]') | |
val=n7_notes&n5_notes | |
print('1st attempts : Combination of each 7-notes,5-notes sum') | |
if len(val)>1: | |
val=n7_notes&n5_notes&n3_notes | |
print('2nd attempts : Combination of each 7-notes,5-notes,3-notes sum') | |
if len(val)>1: | |
val=n7_notes&n5_notes&n3_notes&n1_notes | |
print('3rd attempts : Combination of each 7-notes,5-notes,3-notes,1-notes sum') | |
if len(val)>1: | |
raise ValueError('Multiple solution on maximum sets combination.') | |
elif len(val)==1: | |
print(tuple(val)[0]) | |
return tuple(val)[0] | |
else: | |
raise ValueError('No possible combination.') | |
elif len(val)==1: | |
print(tuple(val)[0]) | |
return tuple(val)[0] | |
else: | |
raise ValueError('No possible combination.') | |
elif len(val)==1: | |
print(tuple(val)[0]) | |
return tuple(val)[0] | |
else: | |
raise ValueError('No possible combination.') | |
## Song musical notation from popular traditional song (Happy Birthday) | |
maj_notes=['c', 'c', 'd', 'c', 'f', 'e', 'c', 'c', 'd', 'c', 'g', 'f', 'c', 'c', 'c', 'a', 'f', 'f', 'e', 'd', 'a#', 'a#', 'a', 'f', 'a', 'g', 'c', 'c', 'd', 'c', 'f', 'e', 'c', 'c', 'd', 'c', 'g', 'f', 'c', 'c', 'c', 'a', 'f', 'f', 'e', 'd', 'a#', 'a#', 'a', 'f', 'g', 'f'] | |
min_notes=['c', 'c', 'c#', 'c', 'f', 'e', 'c', 'c', 'c#', 'c', 'g', 'f', 'c', 'c', 'g#', 'f', 'd#', 'd#', 'd#', 'c#', 'g#', 'g#', 'g#', 'f', 'g#', 'g', 'c', 'c', 'c#', 'c', 'f', 'e', 'c', 'c', 'c#', 'c', 'g', 'f', 'c', 'c', 'g#', 'f', 'd#', 'd#', 'd#', 'c#', 'g#', 'g#', 'g#', 'f', 'g', 'f'] | |
## Song musical notation from popular Thai song (Lao Duang Duen) | |
# Major mode in C | |
maj_notes=['C','D','E','G','C','G','A','C','A','G','E','G','C','D','E','C','B','A','D','C','A','G','E','D','E','G','E','D','C','D','G','A','G','C','D','E','G','C','C','D','E','G','D','E','D','C','A','C','E','G','A','C','A','G','E','G','A','C','D','E','D','C',] | |
# Major mode in C with additional melody added | |
maj_extra_notes=['C','D','E','G','C','C','C','B','A','G','G','A','C','A','G','E','G','A','G','F','E','D','C','C','D','E','C','B','A','D','C','A','G','E','D','E','G','E','D','C','D','E','F','A','G','G','A','G','C','D','E','G','C','C','D','E','G','D','E','D','C','A','C','B','A','C','E','D','C','G','A','C','A','G','E','G','A','C','D','E','D','C',] | |
# Minor mode in C | |
min_notes=['C','D','Eb','G','C','G','Ab','C','Ab','G','F','G','C','D','Eb','C','Bb','Ab','C','Bb','Ab','G','F','Eb','F','G','F','Eb','D','Eb','F','G','Ab','G','C','D','Eb','G','C','C','D','Eb','G','D','Eb','D','C','Ab','C','G','G','Ab','C','Ab','G','F','G','Ab','C','D','Eb','D','C',] | |
# Minor mode in C with additional melody added | |
min_extra_notes=['C','D','Eb','G','C','C','C','Bb','Ab','G','G','Ab','C','Ab','G','F','G','Ab','G','F','Eb','D','C','C','D','Eb','C','Bb','Ab','C','Bb','Ab','G','F','Eb','F','G','F','Eb','D','Eb','F','G','Ab','C','B','G','Ab','G','C','D','Eb','G','C','C','D','Eb','G','D','Eb','D','C','Ab','C','Bb','Ab','C','G','F','Eb','G','Ab','C','Ab','G','F','G','Ab','C','D','Eb','D','C'] | |
## Test dataset | |
key_detector(list(map(pitch_letter_encoder,maj_notes))) # C==C | |
key_detector(list(map(pitch_letter_encoder,maj_extra_notes))) # C==C | |
key_detector(list(map(pitch_letter_encoder,min_notes))) # Cm==Cm | |
key_detector(list(map(pitch_letter_encoder,min_extra_notes))) #Cm==Cm | |
## Test dataset (also test with every key-transposing) | |
if True: | |
# maj_notes | |
for i in range(12): | |
tmp=list((np.array(list(map(pitch_letter_encoder,maj_notes)))+i)%12) | |
key_detector(tmp) | |
# maj_extra_notes | |
for i in range(12): | |
tmp=list((np.array(list(map(pitch_letter_encoder,maj_extra_notes)))+i)%12) | |
key_detector(tmp) | |
# min_notes | |
for i in range(12): | |
tmp=list((np.array(list(map(pitch_letter_encoder,min_notes)))+i)%12) | |
key_detector(tmp) | |
# min_extra_notes | |
for i in range(12): | |
tmp=list((np.array(list(map(pitch_letter_encoder,min_extra_notes)))+i)%12) | |
key_detector(tmp) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment