Making MIDI Controller #2

구종회 (JongHoe Koo)
Making MIDI Controller
6 min readMar 19, 2015

MIDI 신호와 시리얼 통신 프로그래밍에 관련된 내용을 정리했습니다. 특히 MIDI OUT을 위주로 살펴보겠습니다. 당장 만들어야 할 것이 MIDI OUT으로만 구성된 컨트롤러니까요.

MIDI 신호

이제와서 미디란 무엇인가~ 하는 주제는 재미 없지만, 안 하고 넘어가기에는 또 이상한 면이 있지요. 구체적인 정보는 인터넷에 차고 넘치니까 공작에 필요한 부분만 간추려서 살펴보겠습니다. (MIDI의 공식문서 보기)

잘 아시다시피, MIDI 신호는 음악 장비의 ‘동작’을 전달하는 신호입니다. MIDI 신호는 어떤 것을 눌렀다, 어떤 것을 움직였다, 어느 정도로 세게 눌렀다, 얼마나 오래 눌렀다 하는 것 처럼 어떤 동작을 구체적으로 전달하기 좋은 신호체계입니다.

MIDI의 MI에 해당하는 Musical Instrument, 이 장비를 다루는 동작들을 체계적으로 정리해 약속된 기호로 만든 것이 MIDI 입니다. 다음 표는 MIDI 신호의 종류와 구성 내용을 정리한 것의 일부 입니다. (MIDI 1.0 신호 전체 보기)

MIDI Message Table

표를 보니 내용이 어마어마 합니다. 우리가 목표로 하는 것은 컨트롤러 만들기니까, 내가 원하는 신호를 골라 MIDI 형식에 맞게 출력하면 됩니다. 그리고 참 다행스럽게도 대부분의 MIDI 신호는 2개 혹은 3개 정도의 글자(Byte, 바이트)로 신호를 구성하고 있다는 점입니다.

위 표에서 2번째 항목인 키보드 누름(Note On Event)을 보겠습니다. 첫번째 글자는 ‘키보드를 눌렀다’ 입니다. Note On을 ‘1001nnnn’ 으로 정의한 것입니다. MIDI 단자로 들어오는 신호가 ‘1001nnnn’ 이면 ‘키보드가 눌린 것으로 인식한다’는 약속입니다. 여기서 1001은 2진수 값이고, 뒤에 있는 nnnn은 채널번호를 뜻합니다. nnnn 자리에 0000 ~ 1111 사이의 값을 쓸 수 있습니다. 예를들어 ‘10010001' 이라는 값이라면 ‘1번 채널의 어떤 건반이 눌러졌다’라는 뜻이지요.

그 다음으로 들어오는 신호는 반드시 0kkkkkkk 라는 신호가 들어옵니다. 여기서 k는 0000000 ~ 1111111 사이의 값인데 ‘어떤 키’에 해당하는 정보가 기록됩니다. 피아노 건반에 하나 하나 번호를 붙여 놓은 것입니다.

그 다음으로 들어오는 신호는 0vvvvvvv 라는 신호가 있는데, 여기서 v는 ‘건반을 얼마나 세게 눌렀는가’ 하는 정보입니다. 벨로시티 라고 하지요.

Note On에 해당하는 정보는 이렇게 3개의 정보(3개의 바이트)로 구성된다는 것을 표에서 알 수 있습니다. 표를 자세히 보면 온갖 정보들이 있습니다. 어떤 신호를 골라 사용할지는 우리가 스스로 결정하거나, 정보를 받아들이는 장비가 필요로 하는 신호를 골라 사용할 수 있습니다.

MIDI 신호가 이렇게 생겼다~ 하는 정도로 이해하고 다음 단계로 진행하겠습니다. 참, 0000 ~ 1111 로 표시되는 숫자는 모두 2진수 표시입니다. 2진수, 10진수, 16진수 숫자 표현에 대해 익숙해지는 것이 도움이 됩니다.

Serial 통신

이번에는 시리얼 통신에 대해 살펴보겠습니다. MIDI도 복잡한데 Serial 통신이라니...

MIDI 신호는 시리얼 통신 체계에서 전달됩니다. MIDI가 신호 그 자체로 존재한다기 보다, 다른 어떤 장비와 연결이 되어 통제된다는 것을 전제로 하고 있습니다. A장비가 B 장비를 컨트롤 하는데 MIDI 신호를 사용한다라는 것이죠. MIDI는 컨트롤 신호일 뿐이고, 그 신호가 전달되기 위해서는 물리적인 케이블과 그 케이블로 신호를 전달하는 방법이 필요한데, 그것을 이미 사용하고 있는 시리얼 통신이라는 방식을 사용한 것입니다.

시리얼 통신은 1가닥 케이블로 전송하는 통신 방식입니다. 케이블은 규격에 따라 여러가닥으로 구성될 수도 있지만 있지만, 실제 통신에 사용하는 것은 1가닥 뿐입니다. 그래서 시리얼 통신, 직렬 통신이라 부릅니다.

생활에서의 예를 통해 시리얼통신을 생각해 보겠습니다. 옆집에 있는 친구와 후래쉬를 사용해 신호를 주고 받기로 했습니다. 후래쉬가 켜지면 1, 꺼지면 0 이라고 하지요. 일상 생활에서야 깜빡 깜빡 하면 호출하는 것이다~ 라고 정하는 것이지요.

미디 메세지 테이블과 같은 코드를 임시로 만들어 보겠습니다. 11은 나와라, 10은 숨어라, 01은 문을 열어라, 00은 이제 안녕~ 이라고 정했다고 합시다. 꽤 괜찮은 코드지만 현실에선 10과 01이 구분되지 않습니다. 왜냐하면 평소에 꺼져있던(0의 상태) 후래쉬가 켜졌을 때 이게 시작하는 1인지 구분하기가 어렵기 때문입니다. 시작하는 1이라면 다음에 또 켜지면 11이 될 것이고, 꺼진다면 10이 됩니다. 시작하는 1이 아니라면 01 이라는 코드였겠지요. 이런 상태로는 원하는 신호를 전달할 수 없습니다.

시리얼 통신은 메세지표 이외에 시간이라는 것을 함께 약속합니다. 여기서는 1초 동안 한가지 신호라는 것으로 하지요. 후래쉬가 2초 동안 켜져 있으면 11이 되고, 1초 동안 켜져있다가 꺼지면 10이 되는 방식입니다. 좀 더 정확한 전달이 되겠지요.

여기에 좀 더 규칙을 더 만들어 넣으면 정확한 전달이 됩니다.

  1. 평소에는 늘 켜져있게 한다. 그래서 신호를 보낼 수 있는 상태라는 것을 표시한다. 평소에 늘 꺼져 있으면 신호를 보낼 수 있는 상태인지 아닌지 알 수 없기 때문이다.
  2. 후래쉬가 꺼지면(0이 되면) 신호의 시작으로 본다. 처음 꺼지는 1초 동안의 0은 시작이라는 표시만 의미하고 데이터는 아니다.
  3. 1초에 하나의 신호(1비트)로 구성된다.
  4. 신호는 2개로 구성되어 있다.
  5. 신호의 끝은 후래쉬가 켜진 상태로 유지한다. (1초 이상)

시리얼 통신은 몇가지 복잡한 약속을 가지고 있다는 단점이 있지만 1개의 케이블만 이용하면 되니까 기계적으로는 간단하다는 장점이 있습니다.

시리얼 통신의 복잡한 약속은 컴퓨터가 해결하므로 이 방식은 장비간의 연결에 자주 사용됩니다.

MIDI 신호를 주고 받는 시리얼 통신의 약속은 다음과 같습니다.

  1. 신호의 속도는 31250bps로 한다. 1초에 31250번 깜빡일 수 있는 속도로 후래쉬의 깜빡임을 체크한다는 뜻입니다.
  2. 평소에는 켜져있는 상태(1의 상태)를 유지한다.
  3. 시작은 0 상태로 한번의 시간 단위(1비트)를 사용한다.
  4. 끝은 1 상태로 한번의 시간단위 이상을 사용한다. -> 데이터의 끝에는 반드시 1 상태로 1비트를 만든 다음 다음 데이터가 없으면 계속 1의 상태로 둔다는 얘기입니다.
  5. 모든 데이터는 8비트(8개의 시간단위)로 구성한다. -> MIDI 메세지 테이블에서 보았던 10010001 처럼 8개의 비트로 구성된다는 뜻입니다.
  6. 8개 비트의 가장 하위 비트 부터 전송합니다. — 가장 낮은 자리에 있는 비트 부터 전송을 시작합니다. 예를들어 1234 라는 숫자라면 4–3–2–1 순서로 전송이 됩니다.

이런 형태로 약속을 하고 데이터를 주고 받는 통신을 시리얼 통신이라고 합니다.

이제 문제를 풀어봅시다!

머리를 식히는 차원에서...

  1. 1개의 미디 신호를 보낼때 몇개의 비트가 사용될까요?
  2. MIDI 메세지 테이블에서 보았던 Note On 신호를 전달하기 위해 데이터를 구성하고 Serial 통신 형식으로 구성해 봅시다. (채널 1, 건반은 60, 얼마나 세게 눌렀나는 100 으로 하지요)

댓글로 답을 남겨주시기 바랍니다. (혹시 여기까지 읽은 분이 있다면..)

=> 문제풀이 보기

--

--