본문 바로가기

Programming/C#

C#, WPF | 악보 제작 프로그램





[실행화면]



    MIDI를 이용하여 WPF에서 구현한 악보 제작 프로그램입니다.


   기존의 MIDI 라이브러리 대부분이 WPF에서 지원하지 않아 관련 라이브러리를 찾느라 많이 고생을 했습니다. 여러 라이브러리를 계속해서 검색하다가 'Toub.Sound.Midi'라는 라이브러리를 찾아서 적용을 했습니다.


http://grouplab.cpsc.ucalgary.ca/cookbook/index.php/VisualStudio/HowToPlayMIDIInstruments


[관련링크]


   

   MidiPlayer.Play에 대한 4개의 파라미터는 다음과 같습니다.

1. Delta Time

2. Channel : 0 ~ 15 사이의 범위를 가집니다.

3. Note : 음악 표기법에서 음표를 나타내는 문자열. 값의 범위는 "C0" ~ "G10"까지이며 여기서 "C3"은 중간 C로 간주됩니다. 

샤프(#) 역시 지원되고, 열거형은 'C0, ... Cn, C # n, Dn, D # n, En, Fn, F # n, Gn, G # n, An + 1, A # n +1, Bn + 1, B # n + 1, Cn + 1, ..., G10'로 이루어져 있습니다.

4. Velocity : 노트가 얼마나 강하게 연주되는지 나타냅니다. 0은 가장 약하게, 127은 가장 강하게 연주됩니다. 보통 100이 평균적인 값입니다.



   모든 표준 타악기를 나열하는 GeneralMidiPercussion이라는 열거형을 사용해서 타악기를 지원합니다. 


   음표들은 같은 규격으로 편집하여 .png로 저장해 각각 Window.Resources로 지정했고, List<object>를 이용해 사운드와 박자를 하나씩 저장해놓은 뒤, 제일 위의 'PlayButton'을 누르면 순서대로 재생됩니다.

   16분음표, 8분음표, 4분음표, 2분음표, 온음표를 'RadioButton'으로 만든 뒤, 5개의 버튼의 스타일을 'ToggleButton'으로 지정하여 5개의 버튼 중 하나만 클릭되도록 만들었습니다. 그리고 버튼마다 'Tag'를 지정해주어 클릭되었을 때 'Tag' 값을 받아오도록 만들었습니다.

   WPF의 Grid는 X, Y좌표를 받아오는데에 있어서 상당히 많은 어려움이 따라오게 됩니다. 방법에 대한 고민을 하던 중, 자연스레 좌표값을 지정할 수 있는 Canvas를 사용하여 해결 할 수 있었습니다.

   음표들은 실행화면에서 보이는 18개의 버튼을 작은 Canvas 안에 자식 컨트롤로 생성해 Canvas.GetLeft, Canvas.GetTop로 값을 받아오고 음표와 해당 위치에 생성하고 노트를 List<object>에 저장한 뒤, Canvas.SetLeft, Canvas.SetTop을 이용하여 해당 음표가 가지는 박자만큼 18개 버튼의 부모 컨트롤인 Canvas를 이동시켜주었습니다.



   음표를 생성하는 코드의 작성을 끝내고 많이 고민한 부분은, 

1. 낮은 C(도)를 포함해 더 낮은 음계일수록, 높은 A(라)을 포함해 더 높은 음계일수록 추가되어야 하는 Bar의 존재와 

2. 사진에서 두번째 B(시)부터 뒤집히는 음표들이었습니다.

   프로그램적으로 Rotate 같은 메서드를 이용할수도 있었으나 아직은 포토샵이 더 편한 나이(...)라 포토샵을 이용해 정자세인 음표와 역자세인 음표를 따로 만들어주고, 현재 시스템적으로 가장 많은 Bar가 있는 음표가 2개까지여서 한 개짜리 Bar와 두 개짜리 Bar를 만들어 역시 Window.Resources에 지정했습니다. 어짜피 음계마다 각각 List<object>에 넣는 노가다를 했기 때문에(...) 크게 상관이 없는 작업이었습니다.




   추가 수정사항

1. 쉼표 및 박자표(4/4, 6/8 등), 음자리표 추가

2. 각 박자가 충족되는 경우 마디로 분할

3. 임시표(플랫/내추럴/샤프) 추가

4. MIDI로 저장/불러오기 가능한 기능 추가

5. 단축키 기능 추가


ComposeProgram.zip

[실행파일]


https://drive.google.com/open?id=1tQlpONz8m8kG9FJGCuH66c8eVXoPn1nU

[논문이라고 하기엔 뭔가 부족한 것]


추가적인 궁금증이나 질문은 답글로 달아주시면 친절히 설명해드리도록 노력하겠습니다.

 

'Programming > C#' 카테고리의 다른 글

C#, Winform | 열차 예약 프로그램  (7) 2018.12.04
C#, WPF | 음악 플레이어  (0) 2018.05.10
C#, Winform | 계산기  (0) 2018.03.30