Skip to content

Instantly share code, notes, and snippets.

@NP-chaonay
Last active September 29, 2020 10:58
Show Gist options
  • Save NP-chaonay/c539aafc597457ecd9d8221b4916dcf8 to your computer and use it in GitHub Desktop.
Save NP-chaonay/c539aafc597457ecd9d8221b4916dcf8 to your computer and use it in GitHub Desktop.
Own created algorithm for classify key and mode of the music.
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