2020년 9월 3일 목요일

[우분투의 사운드와 MIDI] 스페이스 바를 서스테인 페달 대용으로 쓰게 만드는 파이썬 프로그램

마스터 키보드는 있는데 서스테인 페달은 미처 구입하지 못하였다. 별로 비싼 물건도 아니라서 구입을 망설일 필요도 없고, 심지어 55 TS 플러그와 스위치 및 케이블만 있으면 만들 수도 있는 물건이다. 하지만 키보드(건반이 아니라 컴퓨터의 자판)을 이용하여 특정 키를 누르면 CC 64 127 신호를 보내고, 키를 놓으면 CC 64 0 신호를 보내게 할 수는 없을까? SendMIDI라는 프로그램을 알아냈으니 MIDI 사운드 모듈로 서스테인 페달 신호를 보내는 것은 아주 쉽다. 퇴근 후 방구석에서 이 문제를 해결해 보기로 하였다.

어떤 작업을 지속하다가 키 입력이 들어오면 중단하는 bash 예제는 무궁무진하게 많다. 이를 잘 응용하면 쉽게 될 것이라 생각을 했다. 그런데 키를 누르고 떼는 순간에만 신호를 한 번씩 보내게 하는 방법은 영 찾기가 어려웠다. 심지어 이런 웹사이트까지 있었다.

Why is it so hard to detect keyup event on Linux?

전문 프로그래머가 아니니 여기에 실린 내용을 전부 이해하기는 어려웠지만, 그럴 만한 역사적 배경이 있었다. 심지어 명령행에서 이런 기능을 가능하게 하는 파이썬 스크립트를 실행하려면 관리자 권한을 써야 한다는 것은 충격이었다. 게다가 다른 창을 활성화시켜도 키 입력/릴리즈 감지가 일어난다. 키 입력 감지는 일반 유저 누구나 가능한데, 키 릴리즈 감지에는 관리자 권한이 필요하다니! X window 환경에서는 관리자 권한이 없이도 이를 구현할 수 있다고 하였다.

파이썬을 잘 모르니(남이 만든 프로그램을 맨날 쓰기만 했었지...) 이 웹사이트에 소개된 예제를 어렵사리 수정하여 sendmidi 커맨드를 넣어 테스트를 해 보았다. 스페이스 바를 누르고 있으면 CC 64 127, 즉 서스테인 페달 on 메시지가 계속 전송되는 것이 보였다. 그러다가 키에서 손을 떼면 CC 64 0 메시지가 한 번 전송된다. 결과만 놓고 본다면 귀에 들리는 소리는 차이가 없지만 만약 이를 시퀀서 프로그램으로 기록한다면 얼마나 지저분한 MIDI 파일이 되겠는가? Note on, note on, note on, note off 메시지를 통해서 음표 하나를 치는 것과 다를 바가 없다. 도무지 나의 저급한 파이썬 지식으로는 해결할 방법이 없었다.

에이, 하지 말까...

이 웹사이트의 중간쯤에 PyGame 패키지를 이용하는 짤막한 스크립트가 나와 있었다. 게임이라는 단어 때문에 나하고는 하나도 상관이 없는 방법이라고 생각하다가 그냥 테스트나 해 볼 생각으로 코드를 복사한 뒤 키 릴리즈 이벤트가 일어났다는 메시지를 화면에 뿌리는 줄을 수정하여 sendmidi 커맨드를 넣었다. 다음은 스크립트의 전문이다. 특별히 스페이스 바에 대해서만 작동하게 만들지는 않았다. 어떻게 고쳐야 하는 지를 모르니까. 파이썬을 이용한 MIDI programming에 대해 좀 더 지식이 있다면 sendmidi라는 외부 프로그램을 경유하지 않고도 CC 메시지를 보낼 수 있었을 것이다.

import pygame
import time
import os

pygame.init()
d = pygame.display.set_mode((800,600))
d.fill((255,255,255))

done = False
while not done:
  for event in pygame.event.get():
    if event.type == pygame.QUIT:
      done = True
    if event.type == pygame.KEYDOWN:
      print("Got keydown event: " + str(event))
      os.system("/home/hyjeong/bin/sendmidi dev 'SC-D70 Part A' cc 64 127")
    if event.type == pygame.KEYUP:
      print("Got keyup event: " + str(event))
      os.system("/home/hyjeong/bin/sendmidi dev 'SC-D70 Part A' cc 64 0")

pygame.quit()
quit()

일반 유저 권한으로 이를 실행시키면 아무 것도 표시되지 않는 창이 하나 뜬다. 이 상태에서 키를 눌렀다. 컴퓨터에 연결된 SC-D70의 MIDI 신호 표시창에 정확히 한 번 불이 들어왔다 꺼진다. 키를 놓았더니 마찬가지로 또 한 번만 불이 들어왔나 꺼진다. 마스터 키보드를 연주하면서 발로(!) 컴퓨터의 키를 눌렀다 떼었다를 해 보았다. 실제로 서스테인 페달을 밟는 것과 똑같은 효과가 나타나는 것이었다. 야, 이게 되는구나! 너무나 신기하고 즐거워서 껄껄 웃고 말았다.

연구 업무(본업)를 위해서도 파이썬 프로그래밍을 익힐 생각을 하지 않고 있었는데(나는 Perl/shell 프로그래머라고 스스로 생각하고 있었으므로) , 아무래도 취미 때문에 일을 벌려야 되겠다. 이러다가 SC-D70의 음색을 변경하는 GUI 프로그램을 만들게 되는 것은 아닌지 모르겠다.



댓글 없음: