파이썬으로 Chord(화음) 만들기 Python

** 2017.07
여기서 사용한 건 Mingus 인데, Pychord 라는 것도 있다.




전 글에서, 그냥 대충 쉽게 파이썬으로 화음을 만들어 보았었다.

그렇게 만들어진 코드가 별 문제는 없는데.. 좀 더 보강을 해보고 싶어졌다.

왜 그랬는가 하면..

C#aug7 : C#,E#,G##,B
Dbm7b5 : Db,Fb,Abb,Cb

이런 문제 때문이다. C# 의 5도는 G# 이 맞고, 여기에 반음을 올려야 하므로 G## 이 맞다. G##은 A와 이명동음이지만, C# 과 A 는 엄밀히 말해서 증5도가 아니라 단6도 관계이다. (뭐.. 증5도나 단6도나 음정은 같지만..)

따라서, 내가 이용한 모듈인 Mingus 도 정확함을 위해 저런 결과를 내도록 한 것이다.

그런데.. 이론은 이론이고, 내가 외울 때는 G## 보다는 A, Abb 보다는 G 가 아무래도 편하고 더 실용적인 방법이겠다.

하여, 이렇게 고쳐보았다.

C#aug7 : C#,E#(F),G##(A),B
Dbm7b5 : Db,Fb(E),Abb(G),Cb(B)

이렇게 만드느라 OrderedDict 도 사용했고, csv 모듈의 사용법도 약간 배울 수 있었다.

또, 지난 번엔 적당히 만든 후에 리브레오피스에서 편집을 하여 최종 csv 파일을 만들었는데, 이번엔 아예 csv 를 제대로 만들어냈다. 후후훗!


  1. #!/usr/bin/python3
  2.  
  3. import mingus.core.chords as chords
  4. import mingus.core.notes as notes
  5. import mingus.core.intervals as intervals
  6.  
  7. from collections import OrderedDict
  8.  
  9. import csv
  10.  
  11. rootsAll = ['C', 'C#', 'Db', 'D', 'D#', 'Eb', 'E', 'F', 'F#', 'Gb', 'G', 'G#', 'Ab', 'A', 'A#', 'Bb', 'B']
  12. rootsSelected = ['C', 'Db', 'D', 'Eb', 'E', 'F', 'F#', 'G', 'Ab', 'A', 'Bb', 'B']
  13.  
  14.  
  15. ###
  16. ### 화음 이름(C, C7 등)과 그것을 구현해주는 함수를 Dict 로 할당.
  17.  
  18. # 아래에서 3화음(Triad)은 그냥 '' 을 줬다.
  19.  
  20. note_and_func = OrderedDict( [('',chords.from_shorthand),
  21.     ('M7',chords.major_seventh),
  22.     ('7',chords.dominant_seventh),
  23.     ('m7',chords.minor_seventh),
  24.     ('m7b5',chords.half_diminished_seventh),
  25.     ('dim7',chords.diminished_seventh),
  26.     ('aug7',chords.augmented_minor_seventh),
  27.     ('6',chords.major_sixth),
  28.     ('m6',chords.minor_sixth)]
  29.     )
  30.  
  31.  
  32.  
  33. all_chords = []
  34.  
  35. for rootNote in rootsAll:
  36.    
  37.     #Dict 에서 화음명과 화음 함수를 쌍으로 불러와서 처리.      
  38.     for c_Name, c_Func in note_and_func.items():
  39.         chords_4_oneNote = []
  40.         chords_4_oneNote.append(rootNote + c_Name)   # 근음과 화음명 입력.
  41.        
  42.         for ch_notes in c_Func(rootNote):
  43.             # 코드톤이 나오는 데, 여기서 두가지 조건에 따른다. 합집합(or 연산) 이다.
  44.             # 1. E#, Fb, Cb, B# 등은 E 와 C 를 병기한다.
  45.             # 2. 세글자(Abb 등) 은, notes.reduce_accidentals() 함수의 결과를 병기한다.
  46.            
  47.             if ch_notes in ['Fb', 'E#', 'B#', 'Cb'] or len(ch_notes)==3:
  48.                 chords_4_oneNote.append(ch_notes + '(' + notes.reduce_accidentals(ch_notes) + ')')
  49.             else:
  50.                 chords_4_oneNote.append(ch_notes)
  51.    
  52.      
  53.         all_chords.append(chords_4_oneNote)
  54.  
  55.  
  56.  
  57. myfile = open('all_chords5-1.csv','w',newline='')
  58.  
  59. # 구분자를 ; 로 한다.
  60. wr = csv.writer(myfile, delimiter=';')
  61.  
  62. # 제네레이터를 만드는데, 첫필드와 나머지를 분리한다.
  63. ## 이 결과는 이런식이 된다. ['C', 'CEG'] ---> 이걸 write 하면 C; C,E,G 가 된다.
  64. wr.writerows([c[0], ','.join(c[1:])] for c in all_chords)
  65.  
  66. myfile.close()
  67.  
  68. # csv 모듈을 사용하지 않고 아래와 같이 해도 된다.
  69.  
  70. #with open('C_chords_print.csv','w') as out_file:
  71.   #for row in all_chords:
  72.     #print('{};{}'.format(row[0], ','.join(row[1:])), file=out_file)


실행한 뒤, 만들어진 csv 파일을 앙키에서 불어오면 된다.

핑백


Google Analyze


LastFm

MathJax