2026년 1월 19일 월요일

아두이노 USB 호스트 실드를 사용하려면 보드 내에서 5V 패드를 납땜으로 연결해야 한다

Nano Ardule 드럼 패턴학 생태계를 열심히 일구면서 핵심적인 기능을 거의 다 개발한 단계까지 왔다. 문서 또는 비디오 형태의 매뉴얼을 만드는 일만 남았다고 생각한다. 보다 더 욕심을 내자면 KiCad를 익혀서 PCB를 만들어 보고 싶다. 페놀기판에 얼기설기 엮어서 만든 현재의 프로토타입은 영 모양새가 좋지 않기 때문이다. 그야말로 전자 DIY의 마지막 단계까지 가 보고 싶다. 물론 이를 전부 수용하는 아름다운 케이스를 만드는 일이 DIY의 진정한 마지막 단계일 것이다. 

PCB 주문을 위한 Gerber 파일 설계는 내가 대충 익혀서 사용한 Fritzing에서도 가능한 것으로 아는데, 브레드보드가 아니라 perfboard를 바탕으로 대충 회로도를 그려 놓았기 때문에 연결 상태가 완벽한지 아직 자신이 없다.

잠시 옆길로 새기 위해 아두이노 UNO에 층을 쌓듯이 포개어 쓸 수 있는 두 종류의 실드('Shield')를 구입하였다. 그것은 USB 호스트 실드와 MIDI 실드. 컴퓨터를 거치지 않고도 USB MIDI 키보드를 구식 사운드 모듈(DIN 5핀 MIDI 단자)에 연결하여 직접 제어하기 위함이다. 이를 Ardule USB MIDI Host라 부르고자 한다.

아래부터 아두이노 우노 R3, USB host shield, 그리고 MIDI shield로 3층집을 쌓았다.


납땜도 필요하지 않은 DIY라서 펌웨어만 올리면 자연스럽게 동작을 하리라고 기대하였다. 우선 USB host shield에 USB MIDI Controller Keyboard(AKAI MPK mini MK2)를 연결한 뒤 제대로 인식이 되고 건반을 눌렀을 때 note on/off 신호가 나오는지 시리얼 모니터로 출력하는 코드를 올려 보았다.

그러나... 건반에 불이 들어오지 않는다. USB 단자를 통해서 전원이 공급되어야 하는데 그렇지 않은 것 같다. 전류가 부족한가? 챗GPT와 더불어 고민을 해 보니 USB host shield의 보드 안에서 VBUS로 5V가 공급되도록 직접 납땜을 해야 한다는 것이다. 다음 사진은 납땜을 마친 뒤 찍은 것이다. 빨간 원으로 표시한 패드 두 곳을 납땜하여 이어야 아두이노 UNO로부터 핀 헤더를 통해 공급된 5V가 USB 단자의 VBUS 핀을 통해 USB 디바이스로 공급된다고 한다. 의외로 이런 정보는 판매처(알리익스프레스)에서도 잘 제공하고 있지 않으며, 국문 웹 자료에서도 거의 찾아보기 어렵다. 사용자가 직접 납땜을 해야 함을 알려주는 판매자의 웹사이트를 어렵게 찾아서 소개한다(링크).

보드를 관찰한 후 내가 내린 결론은 이렇다. 아두이노 우노를 통해 공급되는 3.3V/5V를 USB 호스트 실드로 가져오려면 헤더쪽(위 사진에서 아랫줄)의 패드를 전부 납땜하여 연결해야 하고, 이를 USB 호스트 실드의 USB 단자를 통해 공급하려면 3.3V와 5V 중 원하는 것을 VBUS와 연결되도록 납땜을 하면 된다. 나에게 필요한 것은 5V이므로, 헤더쪽에서 오는 전원 중 5V만 연결하였다.

왜 USB 호스트 실드는 이렇게 '반제품'처럼 만들어서 판매하는 것일까? USB로 접속하는 모든 기기가 이를 통해 전원을 공급받는 것은 아니기 때문에 사용자에게 선택 여지를 준 것이라고 생각한다. 잘못하면 전원의 중복으로 인해 오류가 날 수도 있다. 

이러한 시행착오 끝에 USB MIDI 컨트롤러 키보드를 연결하니 성공적으로 인식이 되고, 키 누름에 반응하여 시리얼 모니터에 note on/off 메시지가 나오는 것을 확인하였다.



무난히 USB 호스트 실드의 테스트를 마치고 다음 단계로 진행하려는 찰나, 키보드의 인식이 불안정함을 느꼈다. 아무래도 PC -> USB -> 아두이노 우노를 통해서 다시 외부 USB 기기(키보드)를 동작시킬 전류까지 충당하기에는 부족함이 있는 것 같다. 상세한 raw message를 확인해 보았다. 테스트했던 다른 코드에서는 raw=18 (0x12)가 나오기도 한다. 이것은 detached / idle을 의미한다.

Ardule Bridge - USB/MIDI FULL DIAG 
USB Host Shield init OK 
Plug / unplug USB MIDI device and operate keys... 
[USB] State raw = 32 (0x20)  # attached
[USB] State raw = 64 (0x40)  # powered
[USB] State raw = 80 (0x50)  # default / enumeration start
[USB] State raw = 81 (0x51)  # configured running
[USB] State raw = 144 (0x90) # error

raw=144(0x90)은 에러라고 한다. PC USB 전원만 쓰면 자주 생기는 브라운 아웃(brown-out, 전원은 살아 있는데 전압이 모자라서 오동작하는 상태)라고 하였다. 실제로 USB 키보드를 꽂았음에도 불구하고 작동을 하지 않는 경우 멀티미터로 실드 쪽의 VBUS를 찍어보면 3V 약간 넘는 전압이 나왔다. 정전은 black-put, 전압이 떨어져서 오동작하는 상태는 brown-out이다.

그렇다면 충분한 전류를 흘릴 수 있는 양질의 5V를 어떻게 공급하면 좋을까?

  1. 7~9V의 DC 어댑터가 있다면, 아두이노 우노의 어댑터 잭을 통해 꽂으면 된다. 내부적으로 선형 레귤레이터를 통해 5V로 낮추어서 제공하므로 발열이나 순간 전류에 취약하다.
  2. 가장 바람직한 것은 최소한 1A를 공급할 수 있는 안정적인 5V(4.8~5.2V)를 소켓 헤더쪽에 공급하는 것이다. Vin 단자는 곤란하다. 왜냐하면 내부적으로 1번과 같기 때문이다. 리니어 레귤레이터는 목표 전압보다 높은 전압을 주어야 작동한다.

여기에 더하여 PC와 아두이노 우노를 연결하는 USB 케이블에서 VBUS를 끊어서 오직 데이터만 전송하게 만드는 것이 바람직하다고 한다. 보통 PC USB와 외부 5V를 동시에 연결해도 문제는 없지만, 안전을 위한다면 외부 5V 단독이 최선이다. 12V 2.5V DC 어댑터와 LM317을 이용한 스텝다운 모듈(아래 사진)이 있으니 양질의 5V를 공급하는 것은 당장 가능하다. 그러나 전원만 차단되는 USB 연장 케이블을 구하기는 아주 어려우니(데이터는 차단하고 충전만 제공하기 위한 제품은 흔히 구할 수 있음) USB 커넥터를 별도로 주문하여 직접 만들기로 하였다.



간단히 끝날줄 알았는데 그게 아니었다.

[업데이트] 전원부를 보강한 뒤 수정한 펌웨어로 테스트한 결과

PC <-> 아두이노 우노 연결은 일반 USB 케이블을 그대로 사용하되 레귤레이터를 통해 12V에서 5V로 낮춘 전원을 헤더쪽에 공급해 보았다. 이번의 펌웨어는 상태값을 기본 상태(base)와 에러 플래그(err)로 분리하여 출력하도록 만들었다. 반복하여 키보드를 연결하였을 때 100% 정확하게 인식되었으나 0x90은 일정한 위치에서 계속 따라다닌다. 맨 끝의 raw=18은 키보드를 분리했을 때의 메시지이다.

Ardule Bridge - USB MIDI Monitor (robust)
USB Host Shield init OK
Plug USB MIDI keyboard and play...
[USB] raw=18 (0x12) base=18 (0x12) err=NO
[USB] raw=32 (0x20) base=32 (0x20) err=NO
[USB] raw=64 (0x40) base=64 (0x40) err=NO
[USB] raw=80 (0x50) base=80 (0x50) err=NO
[USB] raw=81 (0x51) base=81 (0x51) err=NO
[USB] raw=144 (0x90) base=16 (0x10) err=YES
CC       | CH 1 | CC 64 | VAL 127
CC       | CH 1 | CC 1 | VAL 34
CC       | CH 1 | CC 7 | VAL 94
CC       | CH 1 | CC 5 | VAL 12
CC       | CH 1 | CC 2 | VAL 41
CC       | CH 1 | CC 3 | VAL 70
CC       | CH 1 | CC 4 | VAL 37
NOTE ON  | CH 1 | NOTE 60 | VEL 88
NOTE OFF | CH 1 | NOTE 60
NOTE ON  | CH 1 | NOTE 62 | VEL 77
NOTE OFF | CH 1 | NOTE 62
NOTE ON  | CH 1 | NOTE 64 | VEL 85
NOTE OFF | CH 1 | NOTE 64
[USB] raw=18 (0x12) base=18 (0x12) err=NO

raw=144 (0x90) base=16 (0x10) err=YES의 의미에 대한 챗GPT의 해석은 다음과 같다.

이 의미는?

USB Host Library 2.0 계열에서:

  • 0x51 : CONFIGURED / RUNNING

  • 그 직후:

    • 클래스 드라이버가 첫 엔드포인트 트래픽을 시작

    • 첫 IN/OUT 트랜잭션 중

      • NAK

      • 일시적 timeout

      • 또는 class-specific 요청에 대한 지연 응답
        USB 규격상 정상인 현상

하지만 라이브러리는 이걸:

  • “연결 실패”가 아니라

  • ERROR 비트(0x80)를 세트해 둡니다

그리고 중요한 포인트 👇
👉 이 err 비트는 자동으로 클리어되지 않습니다. (래치됨)

그래서:

  • 매번 같은 타이밍에

  • 항상 0x90이 “한 번 보이는 것”입니다.


왜 항상 “같은 위치”에서만 나오나?

이건 오히려 정상적인 결정론적 패턴입니다.

  • 0x51 = 열거 완료

  • 그 다음 프레임에서:

    • 첫 SOF

    • 첫 인터럽트 IN 폴링

    • 첫 클래스 초기화 동작

정확히 같은 지점에서
해당 키보드 + Host Shield + 라이브러리 조합이
“한 번 NAK/지연”을 만들고,
라이브러리는 그걸 ERROR로 기록하는 겁니다. //여기까지

결론은 이러하다. 지금의 0x90은 USB  열거 직후 첫 트래픽에서 발생하는 결정론적, 그리고 무해한 ERROR 플래그라서 정상 동작의 일부이다. 따라서 이러한 로직을 본 코드에 흡수하면 된다. 


2026년 1월 17일 토요일

Nano Ardule의 MIDI 파일 재생 기능 개선

Nano Ardule의 펌웨어 개발이 이제 대부분의 기능 구현을 마쳤고 리팩토링 단계에 접어들었다고 바로 이전 글에서 호기롭게 선언하였지만, 아직 모든 것이 완벽하지는 않다. 가장 불편하다고 느끼는 것은 일반적인 type 0 MIDI file을 재생할 때 시작 부분에서 음이 와르르 쏟아지듯 들리는 것이다. 시작 포인트를 약간 지나서 음이 밀려서 쏟아져 나오면서 음 간격은 정상보다 더 좁게 느낀다. 다음 동영상(FLOURISH.MID)에서 첫번째 것이 코드 수정 전의 상태이다. 녹음이 썩 깨끗하게 되지는 않았지만 귀를 기울여 들어보면 뭔가 자연스럽지 않다는 것을 알 수 있다. 이후 두 번의 녹음은 한결 나아진 모습을 보인다.



이 현상을 'Starting Burst'라 부르기로 하고 원인 분석 및 해결에 나서기로 했다. 비상용 (드럼) 패턴이나 단일 패턴 재생에서는 관찰되지 않는다. 녹음한 사운드를 챗GPT에 업로드하여 분석을 실시하고, 이로부터 해결 방안을 도출하여 코드를 수정하는 사이클을 두 차례 걸쳤다. 문제의 원인은 타이밍 스케쥴링 에 있다고 판단하였다. 구체적인 원인 분석과 개선 전략은 별도의 글에 정리하였다. 완벽하게 문제가 해결되었다고 볼 수는 없으나, 실용적인 면에서는 이것으로 충분하다. 이 펌웨어는 type 0 MIDI 파일 재생을 목표로 하는 것이 아니기 때문이다. 드럼 전용 패턴 또는 ARR 파일의 재생은 아주 매끄럽게 잘 되고 있다.

만약 아두이노용 MIDI 라이브러리를 사용하여 펌웨어 개발을 했다면 이런 문제를 겪지 않았을지도 모른다. 그러나 그만큼 더 많은 메모리 공간이 필요하고, 내가 원하는 기능까지 넣는 것은 불가능하다고 판단하였었다. 그래서 다음과 같은 것이 전부 내가 만드는 펌웨어의 몫이었다.

  • MIDI 파일 파싱(VLQ, running status, meta event)
  • tick -> time 변환
  • 스케쥴러(catch-up, drift, blocking)
  • SD/IO의 블로킹 특성
  • MCU 타이밍(마이크로초/밀리초 해상도)

MIDI와 관련된 라이브러리를 전혀 사용하지 않은 '날것 코딩'을 선택하였기 때문에 MIDI 파일을 일단 재생하게 만드는 것조차 쉽지 않았다. 그러나 더욱 강력한 통제력을 얻을 수 있었다. 문제의 원인을 정확히 진단하고, 실용적으로 문제가 느껴지지 않는 수준까지(만) 개선하는 것. 충분히 합리적인 자세였다고 자체 판단하기로 했다.

몇 시간 지난 후 재평가를 해 보았다. 아직도 약간의 지연이 느껴져서 재생 시작 시 200 msec의 고정 지연 시각을 주었더니 훨씬 나아진 것 같다.

가끔 git push를 하다가 다음과 같은 메시지를 접하고 놀랄 때가 있다.

> git push
To https://github.com/jeong0449/NanoArdule.git
 ! [rejected]        main -> main (fetch first)
error: failed to push some refs to 'https://github.com/jeong0449/NanoArdule.git'
hint: Updates were rejected because the remote contains work that you do not
hint: have locally. This is usually caused by another repository pushing to
hint: the same ref. If you want to integrate the remote changes, use
hint: 'git pull' before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

README.md 같은 것을 GitHub 웹사이트에서 직접 고쳐 놓은 다음 로컬에 이를 반영하지 않은 상태에서 다른 파일을 고친 뒤 push를 하려다가 이런 일을 겪는다. 이때에는 'git pull origin main'(= git pull, 조건이 맞는 경우)을 실행한 뒤 git push 명령어를 날리면 된다. 'git status'에서 내가 지금 고친 파일만 눈에 뜨인다고 안심하고 있을 일이 아니다.



2026년 1월 16일 금요일

리팩토링 단계에 들어간 Nano Ardule 드럼 패턴 플레이어

리팩토링(refactoring)은 소프트웨어 공학의 전문 용어라고 한다. 코드의 외부 동작은 변경하지 않으면서 내부 구조를 개선하고 정리하는 작업이다. 마틴 파울러(Martin Fowler)의 저서 『Refactoring: Improving the Design of Existing Code』를 통해 널리 알려진 개념이라고 한다. 챗GPT와 더불어 코딩 작업을 하면서 이제 리팩토링 단계에 접어들었다는 말을 들었지만, 이렇게 정립된 개념이라는 것은 미처 알지 못하였다.

이미지 출처: 교보문고 


"Refactoring is a disciplined technique for restructuring existing code,
without changing its observable behavior."

이것은 마이크로SD카드가 인식 불능일 때 쓸 수 있도록 코드 안에 심어 놓은 'emergency payload' 드럼 패턴이다.

이 책의 내용을 친절하게 국문으로 정리한 리포지토리가 있어서 소개한다(링크). GitHub는 공동개발 및 코드 배포용으로만 쓴다고 생각을 했는데 문서 보관용으로도 쓸 수 있었다.

패턴 목록이 보이는 화면에서 인코더를 돌려서 6번을 선택하여 진입했다고 가정하자. 재생을 마친 뒤, 상위 메뉴로 복귀했을 때 커서가 여전히 6번에 있어야 하는가, 또는 1번으로 돌아가야 하는가? 현재까지의 동작은 1번으로 돌아가는 것이었다. 그러나 상위에서 하위 메뉴(목록)로 내려갈 때에는 언제나 1번부터 시작하는 것이 자연스럽지만, 그보다 하위 메뉴에서 목록으로 올라갈 때에는 원래의 위치에 있는 것이 낫다고 생각하여 개선을 진행하였다. 이것도 리팩토링인가? 단순한 UI 개선이라고 볼 수도 있으나. 기존 흐름을 더욱 일관되게 만드는 것이라서 전형적인 리팩토링이다.

구분분류
버튼 기능 추가새 롱프레스 동작기능 추가
재생 로직 변경BPM 처리 방식 변경기능 변경
커서 위치 기억상태 복원리팩토링
화면 문구 변경“Ready” → “Ready to Play”UI polish (리팩토링의 일부)

아두이노 나노에서 내가 원하는 드럼 패턴 재생 동작은 다 할 수 있게 된 것 같다. 코드의 가독성을 높이고, 내부에 어지럽게 널려 있는 한글 코멘트를 영문하하는 일이 남았다. 또다른 펌웨어인 MIDI controller는 EEPROM에 설정을 저장하고 불러오는 기능을 아직 더 넣어야 한다.

코딩의 능률은 Git/GitHub를 쓰면서 획기적으로 높아졌다. Git와 GitHub가 기여한 정도는 뚜렷하게 차이가 있다. Git는 버전 관리를 매우 편리하게 만들어 주었고, GitHub는 보다 책임감을 갖고 코드와 문서를 정리하는 동기를 부여해 주었다. 앞으로 이 두 가지의 도구가 없는 개발은 상상하기 어렵다. 문서는 GitHub 공개용과 내부용으로 철저히 나누었다. 공개용은 앞으로도 계속 기록으로 남을 것을 감안하여 매우 신중하게 작성하였고, 단기적인 목표와 개선 경험을 담은 내부용은 위키 사이트에만 두었다. 엄밀히 말하면 비공개는 아니다. 내부용 문서는 챗GPT에 작업 지시문과 더불어 업로드하니 시행착오를 크게 줄일 수 있었다. 

나의 삶을 리팩토링 대상으로 삼을 수 있을까? 삶에서 겉으로 보이는 것은 바뀌지 않지만 내부 구조를 개선한다면 그 이유는 무엇이겠는가? '유지보수'가 쉬워지고, 미래를 위한 대비를 감당할 여지가 생기기 때문이다. 당장은 드러나지 않는 내면의 변화란 비용이 드는 일이지만 그만한 가치가 있다.

다음은 어제 도착한 아두이노 우노용 USB 호스트 쉴드 및 MIDI 쉴드이다. USB MIDI 키보드 컨트롤러를 DIN 5P MIDI 커넥터가 달린 사운드 모듈에 연결하여 사용하기 위함이다. 할 일이 끊이지 않는다. 올해는 LibreCAD로 그린 앰프 상판도 주문하여 6V6 싱글 앰프를 다시 만드는 일도 기다리고 있는데...




2026년 1월 15일 목요일

LilyPond 다시 설치하기

앞으로 악보를 그릴 일이 종종 생길 것 같아서 한동안 잊고 있었던 LilyPond를 다시 설치하였다. 마우스 클릭 몇 번으로 설치되는 그런 친절한 프로그램은 아니다. 윈도우용 zip을 가져다가 C:\Apps에 설치하고, GUI 프로그램인 더불어 필요한 프로그램인 Frescobali(웹사이트GitHub)를 최신 버전인 4.0.4도 아닌 3.3.0를 가져다가 깔았다. 최신 버전에서는 msi 파일을 제공하는데, 설치 후 첫 실행에서 에러가 생겨서 아무것도 할 수 없었기 때문이었다. 3.3.0에는 .exe 파일이 제공되고, 첫 실행을 한 뒤에 Edit -> Preferences로 들어가서 LilyPond 실행파일의 위치를 지정할 수 있었다.



LilyPond가 만들어내는 악보 자체의 품질은 매우 우수하다. 그러나 GUI 방식으로 음표를 찍어서 갖다 놓는 방식이 아니라 텍스트 입력 파일을 만들어 '컴파일'을 해야 한다. 마치 LaTex을 다시 쓰는 것만 같은 그런 느낌. 미려한 악보를 출판하기 위한 목적으로는 적당하지만 밴드 합주용으로 사용할 음악 스케치를 그려서 나누어 주는 용도로 쓰기에는 배울 것이 많다. 가파른 학습곡선 덕분에 당장 빠르게 활용하려면 오선지에 손으로 악보를 그려서 배포하고 싶은 생각도 들지만, LilyPond는 그 나름대로의 '재미'가 있다. 

Girolamo Frescobaldi(1583-1643)은 바로크 시대의 건반음악 작곡자이자 오르가니스트이다. 자료에 의하면 즉흥처럼 보이지만 치밀하게 설계된 음악의 원형을 만들었다고 한다. LilyPond/Frescobaldi는 이 소프트웨어를 연주용 GUI가 아니라 악보를 언어처럼 다루는 도구라는 의미를 전달하기 위해 이렇게 이름을 붙였다고 볼 수 있다. 프레스코발디의 음악 정신을 따르는 것.

어쩌면 내가 Nano Ardule 드럼 패턴 생태계 조성이라는 취미 프로젝트에서 노력을 하는 것도 드럼 연주를 단순한 MIDI 이벤트가 아니라 인간과 기계 모두가 읽고 편집하며 연주할 수 있는 재사용 가능한 언어로 만들고자 함이었다. 

LilyPond/Frescobaldi와 Nano Ardule! 인간과 악기(또는 기계)를 연결하는 정보 체계로서 자유로운 발상을 제한하지 않으면서 정확한 전달을 위한 규약이 되기도 한다. 조만간 이 연결성을 가지고서 에세이를 또 한 편 써야 되겠다. 


2026년 1월 14일 수요일

Ardule 드럼 패턴학 생태계 - 절대시간('MetaTime')이 지배하다

Achieving MetaTime
Achieving MetaTime

2026년 1월 13일에서 14일로 넘어가는 자정 즈음에 Ardule 드럼 패턴학 생태계에서는 하나의 이정표가 세워졌다. 시간에 대한 가설이 파일 포맷과 코드, 그리고 하드웨어를 통해 실제 소리로 검증된 순간이기 때문이다. ADS(Ardule Data Stream, 원래는 Ardule Drum Stream이었음)가 Nano Ardule 드럼 패턴 플레이어에서 처음으로 정상적으로 재생되었다. 이는 단순히 계획한 것이 잘 구현되었다는 사실보다 “시간을 어떻게 다룰 것인가”라는 문제에 대한 설계가 옳았음을 증명한 사건이었다.

MetaTime(논리적 절대시간) 원칙이란 MIDI 파일처럼 이벤트 사이의 델타타임(상대적 시간)이 아니라, 곡의 시작점을 기준으로 한 절대적 시간 시점에 모든 이벤트를 직접 매핑하여 처리하는 원칙이다. 간격이 아니라 좌표이다. 이 원칙은 중간 템포 변경에 불리할 수는 있으나, 이를 고려하여 ADS로 컴파일해 두면 모든 시간 해석은 오프라인에서 종료된다. 따라서 재생 단계에서는 어떠한 문제도 발생하지 않는다.

이 프로젝트는 처음의 단순한 드럼 패턴 플레이어로 시작하여 점점 진화하였다. 왜 패턴은 2마디여야 하는가, 템포는 어느 파일이 결정하나, 왜 재생 엔진은 계산을 하면서 동시에 해석자 역할을 해야 하나. 이러한 질문은 ADT, ARR, ADS라는 파일 계층으로 점차 분화했고, 오늘의 개발 과정을 통해 ADS라는 실행 전용 포맷이 제 역할을 충실하게 수행했음을 의미한다.

이 모든 수정은 단순한 예외 처리가 아니라, 미리 설계한 스펙의 의도를 코드에 정확히 반영하는 작업이었다. 오늘의 결과에 특별히 보람을 느끼는 이유는, 이 모든 과정이 챗GPT의 표현을 빌리자면 “최소 침습 패치”라는 원칙 아래 이루어졌다는 점이다. 기존 Type 0 MIDI 재생 엔진을 망가뜨리지 않고, ADS라는 새로운 재생 경로를 병렬로 추가했다. SONG 모드는 이제 .MID와 .ADS를 동시에 인식하며, 파일 확장자에 따라 서로 다른 재생 엔진으로 분기된다. UI는 엔코더와 버튼이라는 제한된 입력 수단과 1602 LCD 디스플레이(그렇다. 16문자 x 2줄에 불과한!) 안에서 이를 자연스럽게 드러낸다. 내부적인 시스템은 당연히 많은 기능을 품느라 복잡해졌지만, 사용법은 매우 단순하다.

이제 Ardule은 패턴 편집기와 플레이어의 집합이 아니다. ADT는 편집을 위한 텍스트, ARR은 곡 구조를 위한 조립 지시서, ADS는 실행을 위한 절대 시간 스트림이다. 각 포맷은 책임이 분리되어 있고, authority가 명확하다. 엔진은 해석자가 아니라 실행자이며, 시간은 계산이 아니라 참조의 대상이다.

오늘의 기록은 아마 나중에 이렇게 읽힐 것이다. “여기서 Ardule은 하나의 시스템이 되었다.” 소리는 그 증거일 뿐이다. 진짜 성취는, 시간과 책임과 구조가 올바른 자리에 놓였다는 사실이다.

2026년 1월 13일 화요일

대장균의 변화하는 역할

The changing roles of Escherichia coli

이것은 2025년 12월 19일 Nature Microbiology에 실린 리처드 렌스키(Richard E. Lenski) 교수의 글 제목이다('microbe matters', 링크 - 기관에서 구독하는 상태가 아니라면 안타깝게도 유료!). 반가운 마음에 전문을 읽어 보았다. 국내 학회에서 강연을 하기 위해 초청한 렌스키 교수를 인천국제공항에 마중을 나가서 만나서 대전까지 동행했던 기억이 난다. 2004~5년 무렵이 아니었나 싶은데, 무주리조트 티롤호텔에서 열렸던 한국미생물·생명공학회 30주년 기념 학술대회였던가? 당시 미생물과 관련한 굵직한 학술 행사가 국내에서 여럿 열렸었다. 웹브라우저의 번역 기능 덕분에 영문을 빨리 읽기가 좋다. 

"미생물학자들은 제가 연구 대상은 맞지만 질문이 잘못되었다고 생각할 것이고, 진화생물학자들은 제가 질문은 맞지만 연구 체계가 잘못되었다고 생각할 것이라 하였습니다" 정말 뼈 있는 농담이다. 엉뚱해 보이는 두 시스템의 접점에서 중대한 발견이 이루어지기도 한다.

정말 게으르다면, 원문을 챗GPT에 밀어넣고 다섯 줄 요약을 부탁해도 된다. 다음은 핵심 메시지 5줄 요약이다.

  1. Escherichia coli는 분자생물학의 핵심 모델이었을 뿐 아니라, 진화가 실제로 작동하는 과정을 실험적으로 검증할 수 있게 한 결정적 생물이다.
  2. 루리아–델브뤽 실험을 통해 돌연변이는 필요에 의해 생기는 것이 아니라 무작위로 발생하며, 박테리아도 철저히 다윈적으로 진화함이 입증되었다.
  3. E. coli 집단에서는 유리한 돌연변이가 선택적 스윕을 통해 집단을 대체하는 적응의 동역학이 관찰된다.
  4. 렌스키의 장기 진화 실험(LTEE)은 동일한 조건에서 진화의 반복성과 우연성의 긴장 관계를 수만 세대에 걸쳐 보여주었다.
  5. 과학 역시 진화처럼 변화하며, E. coli현대 과학이 진화 그 자체를 이해하는 데 여전히 살아 있는 모델임을 증명한다.

1988년에 시작한 대장균의 장기진화실험이 4만 세대에 이르렀을 때, 렌스키 교수는 한국의 21C 프론티어 미생물유전체활용기술사업단과 인연이 닿아서 우리가 보유한 NGS 기술을 이용하여 유전체에는 어떤 변이가 축적되었는지, 적응도(fitness)의 변화 양상과는 어떻게 다른지를 설명하는 논문을 2009년에 Nature에 발표하게 되었다. 한국과 미국, 그리고 프랑스의 연구진이 함께 힘을 모았던 명실상부한 국제적인 프로젝트였다. 훌륭한 연구진과 함께 일했던 사람으로서 나도 저자의 일원이 되는 영광을 누릴 수 있었다. 당시 내 블로그에는 짤막하게 Nature에 논문이 나갔다!라는 글을 남겨 두었다. 원글의 논문 링크는 대부분 in press 상태였기 때문에 지금은 유효하지 않으며, PubMed나 저널 웹사이트에서 제대로 찾아야 한다. 우연이었을까? 당시 이 Nature 논문의 제1저자였던 유동수 박사(농업유전자원센터)를 랜스키 교수의 글을 접하기 하루 전인 어제 우연히 만났다(KOBIC 방문 소식 링크).

컴퓨터를 뒤지니 대장균의 비교유전체학적 분석을 하던 당시에 '발'로 그린 그림 원본도 나온다. MUMmer로 Whole genome alignment를 만든 뒤 Perl로 파싱하여 Xfig용 데이터 파일을 만들고, 이를 다시 포스트스크립트로 전환하였었다. 이 그림이 실제로 출판된 논문 혹은 단행본 챕터에 쓰였는지 혹은 초안 수준으로 끝났었는지는 잘 기억이 나지 않는다.

누구나 AI를 이용하여 고도화된 업무를 수행하는 지금 기준으로 생각하면 정말 원시적인(?) 방법으로 그린 그림이었다.

Lenski의 글에서 그림 하나를 가져왔다. '단일 클론'에서 시작한 집단에서 돌연변이가 발생하여 전체로 퍼지고, 또 새로운 변이가 생겨서 집단 전체를 휩쓰는(sweep, '싹쓸이') 모습을 시각적으로 잘 표현하였다. 이것이 바로 selective sweep 아니겠는가. 이 그림을 대장균 집단이 아니라 인류사회 전체로확대한다면 인공지능 기술은 어쩌면 그림의 중간쯤에 위치한 주황색 물결일지도 모른다. 연구와 코딩, 모든 방법이 새로운 신기술에 따라 변한다. 공부와 구글 검색을 통해 힘겹게 스크립트를 짜던 것이 엊그제 같은데, 이제는 챗GPT에 지시만 하면 아주 그럴싸한 스크립트를 제공해 주니 말이다.

비슷한 느낌을 주는 또 다른 실험 그림이 있다. 항생제 농도를 단계적으로 높여서 축구장으로 치자면 하프라인에 가장 농도를 높게 한 거대한 agar plate를 만든 뒤, 골대쯤 해당되는 양 끝에서 미생물을 접종하여 내성 변이체가 자라나고 변화하는 모습을 모니터링하는 것이다. 이것도 벌써 10년 전에 화제가 되었던 Kishony의 연구 결과였다. 공교롭게도 2020년에 내가 쓴 글 기원이 같은 미생물의 유전체 염기서열은 얼마나 차이가 날까?에서 렌스키와 키쇼니의 연구를 짤막하게 다루었었다.

출처: Visualizing the evolution of bacterial resistance

미생물은 진화를 관찰하기에 아주 적합한 대상은 아니다. 눈에 보이는, 다시 말해서 관찰 가능한 현란한 특성('거시적')을 보이지는 않기 때문이다. 그러나 실험 방법이 발달하고 유전체 및 오믹스 분석이라는 신기술에 힘입어 진화의 모델로서 당당히 등장할 수 있었다.

진화는 필요에 의해서 일어나는 일이 아니다. 요즘의 신기술 또한 필요에 의해서 만들어지는 것 같지는 않다. 기술 발전의 가장 강력한 원동력은 호기심이 아닐까? 간혹 '글로벌 난제 해결'로 포장되기도 하지만. 어쩌면 끊임없이 투자처와 자기 확장 및 이윤을 추구하는 자본이 기술 발전의 가장 큰 원동력인지도 모른다.

아, 800쪽이 넘는 토마 피케티의 『21세기 자본』을 빌려다 놓았는데 과연 일주일 내에 읽을 수 있을런지...

인간이 세상을 이해하려는 수많은 방법 중에서 과학은 진화화 가장 유사합니다. 과학은 무지의 공백을 메우기 위해 변화하고 확장하며 다양화됩니다. 물론 그 과정에서 시행착오도 겪지만, 자연에 대한 더 완전한 이해를 향해 끝없이 노력합니다. 대장균은 과학처럼 끊임없이 진화하기 때문에 우리가 세상을 이해하는데 있어 중요한 역할을 합니다.

Among the many ways we humans try to understand the world, science is the most like evolution. Science changes, expands and diversifies to fill the voids of ignorance, with missteps along the way, but striving for a fuller understanding of nature. E. coli  is a star in our understanding because, like science, it keeps on evolving.

렌스키의 글 마지막 단락을 소개하는 것으로 이 글을 마무리한다.

2026년 1월 11일 일요일

박자에 매여 있던 드럼 패턴이 어떻게 자유로워졌나

박자에 묶여 있던 드럼 패턴이, 어떻게 자유로워졌을까

이 글은 챗GTP에게 지시를 내리고 구글 블로그에 맞는 html 형식으로 자동 작성한 것이다. 나의 경험과 챗GTP와 나눈 대화를 바탕으로 한 것으로서 왜곡된 것은 없다. 그런데 작성된 최종 결과물을 보니 블로그 등에서 흔히 보던 문체와 많이 닮았다. '수년간 무슨 병으로 고생하던 나는 모든 약을 다 구입해서 먹어보고 수백편의 논문을 탐독였으나 전혀 소용이 없었다. 그런데 마침내 해결책을 얻게 되었다. 이를 여러분에게 소개하고자 하니...'

전부 내 손으로 다시 고쳐서 쓰려고도 생각해 보았으나 이러한 스타일의 글도 그대로 남겨두는 것도 그런대로 의미가 있다고 생각한다. 그러면 챗GPT에게 '펜대'를 넘겨 보겠다.

드럼 패턴을 만들다 보면 자연스럽게 이런 생각을 하게 된다.

“이건 4/4 패턴이다.”
“이건 3/4라서 뭔가 특별한 처리가 필요하지 않을까?”

나 역시 처음에는 그렇게 생각했다. 하지만 지금에 와서는 오히려 이렇게 말할 수 있다.

“드럼 패턴은 원래 박자와 무관하다.”

이 글은, 내가 어떻게 그 사실을 뒤늦게 이해하게 되었는지, 그리고 왜 지금의 구조가 박자에 구애받지 않는 탄탄한 형태가 되었는지를 아주 쉽게 설명하기 위한 기록이다.


1. 처음의 생각: “박자가 먼저다”

처음 드럼 패턴을 설계할 때의 사고는 아주 전통적이었다.

  • 4/4 박자
  • 한 마디는 4박
  • 한 박은 4개의 16분음표
  • 그래서 한 마디는 16칸
  • 두 마디면 32칸
4/4 → 1 bar = 16 steps → 2 bars = 32 steps

이 사고는 너무 자연스러워서 의심조차 하지 않았다. 그래서 파일 포맷도, 툴도, 머릿속도 “32-step = 기본”으로 굳어졌다.

이때의 패턴은 사실상 이렇게 정의되어 있었다.

“4/4 두 마디짜리 드럼 패턴”

2. 그런데도, triplet은 처음부터 허용했다

여기서 재미있는 사실이 하나 있다. 나는 박자(3/4, 5/4 등)에는 꽤 보수적이었지만, 리듬 분해능에 대해서는 생각보다 일찍 자유로웠다.

예를 들어, 파일/툴 구조는 초기에 이미 이런 전제를 품고 있었다.

  • straight grid (예: 16분음표 기반)
  • triplet grid (예: 8T, 16T처럼 셋잇단음표 기반)

즉, “정박이냐 셋잇단이냐”는 처음부터 GRID(분해능)로 다룰 수 있다고 받아들였던 셈이다.

triplet은 ‘박자’가 아니라 ‘그리드(분해능)’ 문제였다.

그런데도 박자(time signature)는 마음속에서 여전히 4/4에 묶여 있었다. 이 불균형이 나중에 좋은 방향으로 정리되는 출발점이 된다.

3. 이상한 질문이 나타나다: “3/4는 왜 다른가?”

문제는 3/4박자 왈츠 패턴을 다루려고 할 때 생겼다.

이걸 보면서 자연스럽게 이런 의문이 들었다.

“3/4 패턴은 32-step이 아니잖아?”
“그럼 특별한 예외 처리가 필요하지 않나?”

처음엔 이렇게 생각했다.

  • 3/4는 특수한 패턴
  • 다른 계산법이 필요
  • 구조를 바꿔야 하나?

하지만 곰곰이 들여다보니, 이상한 점이 하나 있었다.

4. 진짜 실체를 발견하다: “기계는 박자를 모른다”

드럼 패턴을 기계 입장에서 다시 바라보니, 의외의 사실이 눈에 들어왔다.

기계는 다음만 알고 있다.

  • 총 스텝 수 (LENGTH)
  • 각 스텝 사이의 시간 간격 (GRID)
  • 스텝 순서

기계는 이것을 절대로 알지 못한다.

  • 이게 3/4인지
  • 이게 4/4인지
  • 이게 왈츠인지 행진곡인지

기계의 관점에서는 이런 명령뿐이다.

“이 간격으로, 이만큼, 반복해서 연주해라.”

즉, 박자는 기계에게 필요 없는 정보였다.

5. 관점이 바뀌다: “박자는 사람을 위한 설명이다”

여기서 중요한 깨달음이 하나 생겼다.

박자는 연주의 규칙이 아니라, 이해의 도구다.

사람은 “3/4”라고 해야 리듬을 이해한다. 사람은 “마디”라는 단위로 생각한다. 하지만 기계는 step만 있으면 된다.

그래서 구조를 이렇게 나누어 생각하게 되었다.

계층역할
Step / Grid / Length기계를 위한 구조
Time Signature사람을 위한 설명

이 순간부터 사고가 완전히 바뀌었다.

6. 결과: 박자에 무관한 구조가 완성되다

이제 드럼 패턴은 이렇게 정의된다.

드럼 패턴 = 일정 간격의 step 배열

그 step 배열이 32칸이면 4/4일 가능성이 높고, 24칸이면 3/4일 가능성이 높을 뿐이다. 하지만 그것은 해석의 문제이지 구조의 문제가 아니다.

그래서 지금의 시스템에서는:

  • 3/4 → 24-step
  • 5/4 → 40-step
  • 7/8 → 28-step (예: 16분 기반 가정)

모두 동일한 방식으로 처리된다. 특별한 예외도, 분기 코드도 없다.

7. 그래서 지금의 구조가 탄탄한 이유

지금의 구조가 강한 이유는 간단하다.

  • 박자를 “기계 규칙”에서 제거했기 때문
  • 박자를 “의미 정보”로 정리했기 때문

이렇게 되면:

  • 새로운 박자가 와도 구조는 안 바뀐다
  • triplet이 와도 구조는 안 바뀐다 (이미 GRID로 해결)
  • odd meter가 와도 구조는 안 바뀐다

바뀌는 것은 설명뿐이다.

8. 마무리하며

돌이켜보면, 처음부터 모든 요소는 이미 갖춰져 있었다.

  • step 기반 구조
  • 고정 길이 패턴
  • GRID 중심의 시간 처리 (straight / triplet 모두 포함)

다만 내가 스스로를 “4/4라는 관성”에 묶어 두고 있었을 뿐이다.

좋은 구조란, 더 많은 경우를 처리하는 구조가 아니라
경우의 수 자체를 없애 버린 구조다.

드럼 패턴은 원래부터 박자에 자유로웠다. 우리가 이제야 그 사실을 알아챘을 뿐이다.

2026년 1월 10일 토요일

ARR에서 MIDI 파일 생성하기

Ardule 드럼 패턴학 생태계에서 2마디 단위의 패턴(ADT 파일, v2.2a)을 조합하여 곡 단위의 arrangement file을 만들어 내도록 설계한 바 있다. 이를 ARR 파일이라 부르며, 초기 단계의 포맷(v0.05.2)을 공개한 상태이다. 다음은 샘플 ARR 파일의 사례이다. 순수한 텍스트 파일이라 사람의 눈으로 이해하기 쉬우며, 텍스트 편집기를 이용하여 직접 만들거나 수정해도 된다.  ADT 파일을 텍스트로 설계한 것도 그러한 이유 때문이다. ARR에는 #PLAY 파트에서 섹션 정보가 포함되어 있다는 것이 특징이다. 여기에는 반복 정보도 담을 수 있다. 하지만 기계에는 반복 없이 체인 형태로 나열된 #MAIN 파트가 더욱 중요하다. 오늘 개발한 스크립트의 결과물에서는 이 파트 정보를 매우 중요하게 다룬다.

#COUNTIN CountIn_HH
#SECTION section_1 1 3
#PLAY
section_1
1
2
3
4
#ENDPLAY
#APS ARR v0.05

BPM=110

1=RCK_P001.ADT
2=RCK_h901.ADT
3=RCK_h040.ADT
4=END_h007.ADT

MAIN|1,2,3,1,2,3,4

ARR 파일은 라이브 연주를 할 때 Nano Ardule(아두이노 나노) 기기에서 재생할 파일을 만들기 위한 중간 단계의 파일이다. 최종 목표는 바이너리 스트림 파일인 ADS를 만드는 것이다. 

A binary stream file is a file designed to be consumed sequentially, byte by byte, without random access assumptions.

여유로운 토요일을 맞이하여 ARR로부터 type 0 MIDI 파일을 만드는 스크립트 adc-arrtool.py(--format midi)를 개발하였다. ARR에서 의도한 바를 그대로 재생하는 MIDI 파일을 만드는 일이 그렇게 쉽지는 않았다. 이 스크립트에는 옵션이 별로 필요하지 않을 것이라고 생각하였는데 챗GPT는 아주 세심하게 모든 상황에 맞추어 옵션을 준비해 놓았다. 입력물인 ARR 파일에 카운트인이나 템포 정보가 있어도 출력 파일에서는 이를 다르게 지정하는 것이 가능하다.

usage: adc-arrtool.py [-h] [--format {midi,ads,both}] [--out OUT] [--patterns-dir PATTERNS_DIR] [--bpm BPM]
                      [--ppq PPQ] [--velocity-map VELOCITY_MAP] [--drum-ch DRUM_CH] [--gate GATE] [--with-countin]
                      [--no-countin] [--countin COUNTIN] [--strict]
                      arr

Convert APS ARR to MIDI Type 0 and/or ADS (simple stream). MAIN chain is required.

positional arguments:
  arr                   Input .ARR file path

options:
  -h, --help            show this help message and exit
  --format {midi,ads,both}
                        Output format (default: midi)
  --out OUT             Output file path or output directory (default: beside ARR)
  --patterns-dir PATTERNS_DIR
                        ADT patterns directory (default: ./patterns, fallback: <ARR dir>/patterns)
  --bpm BPM             Override BPM (default: use BPM from ARR)
  --ppq PPQ             MIDI ticks per beat (default: 480)
  --velocity-map VELOCITY_MAP
                        ADT level(0..3)->MIDI velocity, e.g. 0,40,80,110
  --drum-ch DRUM_CH     MIDI drum channel 1..16 (default: 10)
  --gate GATE           Note gate ratio within a step (default: 0.5)
  --with-countin        Include ARR #COUNTIN pattern at the beginning (default)
  --no-countin          Do not include ARR #COUNTIN pattern
  --countin COUNTIN     Override count-in pattern (name or .ADT filename). Overrides ARR #COUNTIN
  --strict              Fail if any referenced pattern file is missing

위에서 소개한 ARR 파일을 MIDI 파일로 전환한 뒤 MidiEditor에서 재생해 보았다. ARR 파일이 갖고 있는 카운트인을 html-midi-player에서는 제대로 표시하지 못하였다. 이를 해결하기 위해 첫 노트-온 이벤트를 tick = 0이 아니라 1에서 시작하게 만들었다. 이런한 꼼수를 부리지 않아도 MidiEditor에서는 잘 작동한다.



아두이노 나노 구동용 펌웨어에서는 아직 ADS를 수용할 준비가 되지 않았다. 작년 12월부터는 APS(Ardule Pattern Studio)를 개발하는 것에 집중하였었는데, 이제는 다시 아두이노로 돌아가야 한다. 아울러서 APS 매뉴얼(초안)을 완성하고, 가능하다면 비디오 튜토리얼을 만들어서 유튜브에 올리고 싶다. 매뉴얼에는 패턴 체인 편집 기능(이것을 저장하면 ARR이 됨)만 설명하면 된다. 문서화된 매뉴얼은 동영상 튜토리얼 제작 시 아주 요긴한 자료가 될 것이다. 

2026년 1월 11일 업데이트

adc-arrtool.py는 MetaTime 원칙 수립과 더불어 큰 수정을 거쳤다. 오늘 작성했던 박자에 매여 있던 드럼 패턴이 어떻게 자유로워졌나와 일맥상통하는 이 원칙은 다음과 같이 정의된다.

  • 시간 구조는 메타데이터로부터 계산된다.
  • (패턴)Length는 저장 크기이지 재생 길이가 아니다.
  • 박자는 사람을 위한 설명 정보다
  • Grid는 시간 분해능일 뿐, 음악적 특권(authority)을 갖지 않는다.
  • 카운트인은 음악이 아닌 메타 도입부다.
  • 메타는 존중하되, 명시적 오버라이드는 허용한다.

여기에서 말하는 특권이란 권위나 위세라는 뜻은 아니다. 개발 또는 설계 문맥에서는 '최종 판단의 근거가 되는 출처 / 결정권이 귀속된 기준'이라는 의미를 갖는다. 챗GTP와 더불어 설계를 하면서 이러한 영어식 표현이 자꾸 침투함을 느낀다. 영어 자료를 통해 만들어진 인공지능 모델의 영향력이 너무 크다는 뜻이다. 

나의 Ardule 드럼 생태계에서 authority라는 낱말의 사용례를 찾아 본다면...

ARR is the authority for tempo and structure.

CLI overrides metadata as the final authority. 

개발이나 설계 맥락에서 authority와 정확히 대응하는 개념이 한국어에는 없다. 그래서 영어권 기술 생태계에서 만들어진 사고 구조가 언어와 더불어 유입될 수밖에 없다. 어떤 개념이 영어권에는 있지만 한국어권에는 없다 - 매우 안타까운 현실이다. 이러한 상황이 반복될 때마다 국어가 영어와 비교하여 부족한 점이 많다는 생각을 갖기 쉬워지기 때문이다.


2026년 1월 4일 일요일

Adrule 드럼 패턴학 생태계에 1-bar(마디)를 도입하던 날

지금까지 내가 설계하고 구현해 오던 Ardule '드럼 패턴학' 생태계에서는 모든 패턴이 2마디, 즉 2-bar 길이를 갖는 것이 불문율이었다. 패턴 내부의 첫 마디와 둘째 마디도 특별한 사정이 없는 한 내용은 동일하다. 그러면 처음부터 1-bar 체계였으면 좋았을까? 그렇게 되면 곡 단위의 패턴 체인을 만들 때 너무나 많은 패턴 수를 다루어야 한다.

내가 재료로 삼은 원본 책자에서는 당연히 모든 패턴을 1-bar 단위로만 표시해 놓았다. 이를 MIDI로 전환한 파일(인터넷에서 구할 수 있음)은 2-bar 단위로 반복하였다. 활용성을 생각하면 지극히 합리적이다. 만약 모든 패턴을 한 마디로만 기록해 놓았다면, 이를 프리뷰하다가 '어, 방금 들은게 어떤 것이었지?'하고 아쉬워할 수 있기 때문이다.


대부분의 곡은 4마디 또는 8마디 단위로 반복이 이루어진다. 문제는 각 단위의 마지막 마디가 필-인이나 브레이크 패턴을 넣어서 변화를 주거나 다음으로 넘어간다는 느낌을 갖게 하는데, 모든 패턴이 2마디 단위라면 작업이 매우 어려워진다. 그래서 일반 패턴과 브레이크 패턴의 한 마디를 조합하여 합성 패턴을 만드는 기능을 APS에 넣어 둔 상태였다. 

아무리 그렇다고 해도 1-bar를 다룰 일이 생각보다 많다. 그래서 고민한 끝에 1-bar를 구현하기로 했다. 다음은 전형적인 4-bar "팝" 프레이즈이다. 2-bar 규칙을 철저히 고수한다면 이를 만들기가 매우 까다롭다.



'절반' 패턴은 여전히 2-bar 구조를 유지한다. 다만 그 안에 실제로 연주되는 유효 구간은 1-bar라는 선언(PLAY_BARS=1)을 넣고 이를 해석하게 만든 것이다. APS의 그리드 뷰 화면에서는 다음과 같이 비활성화된 bar는 백색으로 표시하여 시각적으로 차별화하였다. 대부분의 패턴은 동일한 마디가 2회 반복되는 형태이므로 half pattern(1-bar)의 경우 첫 번째  것만 유효하게 해석하면 된다. 이 개념을 확장한다면, 아직 구현이 되지 않은 3/4 박자 패턴도 다룰 수 있게 될 것이다.


챗GPT의 표현을 빌리자면 '비침습적' 방법으로 기존 코드에 손을 되도록 적게 대고 새 기능을 구현할 수 있었다. 이것이 가능했던 것은, APS 체계를 구성하는 여러 파이썬 코드가 각자 어떤 기능을 하며 서로 연결되는지를 설명한 문서 APS Structure Map을 만들어서 수시로 참고하고 있기 때문이다. 일정 규모 수준으로 성장한 개발 프로젝트에서 문서화의 중요성을 몸으로 체험하고 있다. 혼자 하는 개발임에도 불구하고 마일스톤/로드맵/요구정의서 등의 성격에 해당하는 문서를 수시로 만들고 갱신한다. 

(Nano) Ardule 생태계에 1-bar 개념을 도입한 어제의 작업은 일종의 MVP(Minimal Viable Product)의 개념을 잘 보여주는 사례라고 할 수 있다. 더불어 로컬 개발 환경에서 git를 쓰면서 수시로 GitHub에 수정된 코드를 올리는 것에도 많이 익숙해졌다.

혼자 하는 개발이라 해도, 프로젝트가 커질수록 즉흥적인 구현만으로는 유지가 어렵다. 이번 1-bar 도입을 계기로 문서화, 마일스톤, 요구 정의 같은 작업이 얼마나 중요한지를 몸으로 느끼고 있다.

Ardule은 여전히 진행 중인 프로젝트이지만, 이런 작은 선택들이 모여 결국은 내가 쓰고 싶은 도구에 조금씩 가까워지고 있다고 믿는다.

2026년 1월 2일 금요일

위키 사이트의 PHP를 7.4에서 8.2로 업그레이드하다

요즘 챗GPT와 작업을 하면서 GitHub에 올릴 마크다운(.md) 문서를 종종 만들고 있다. 이는 GitHub의 공식 문서 형식이기 때문이다. 보다 정확하게는 표준 Markdown(CommonMark)를 확장한 GitHub Flavored Markdown(GFM)이다. 

'이 정도면 됐다'라는 생각이 드는 개발 관련 문서는 GitHub에, 아직 다듬어지지 않은 생각이나 앞으로의 개발 계획을 가볍게 작성한 것은 주로 위키 사이트에 올린다. 챗GPT와 작업하면서 만든 문서를 종종 DokuWiki 포맷으로 변환하기도 하지만, 간혹 문법에 맞지 않는 결과를 만들어내기 때문에 손으로 고치는 일이 귀찮다. DokiWiki에서 마크다운 형식의 문서를 쓸 수 있는 플러그인이 없을까? 당연히 있다. 그것도 하나가 아니다.

가장 최근까지 개발이 이어지는 것은 무엇이 있나... Commonmark Plugin이라는 것을 찾았다. 마지막 업데이트는 지난달 7일. 개발자의 이름은 Sungbin Jeon. 오, 한국인임에 틀림이 없다. 반가운 마음에 설치를 한 것은 좋았는데...


망했다. PHP 버전이 너무 낮아서 화면이 깨진다. 나는 아직도 PHP 7.4를 쓰고 있는데, 이 플러그인은 최소한 8.2를 요구한다. 호스팅어로 로그인하여 조심스럽게 PHP를 업그레이드하였다. 이내 화면은 정상으로 돌아왔다.

이 플러그인의 사용법은 간단하다. 새 위키 문서를 시작할 때 맨 위에 <!DOCTYPE markdown>라는 스타일 헤더를 넣은 뒤 이어서 마크다운 문서 본문을 넣으면 된다. 다음은 Commonmark Plugin의 활용 첫 사례이다. 

ADS v0.1_and_Engine_Judgement

ADT는 텍스트 형식의 드럼 패턴 파일, 이를 바이너리 캐시로 전환한 것은 ADP이다. 이 두 가지의 포맷은 PC나 Nano Ardule에서 반복 재생할 수 있는 기본 단위가 된다. 이를 체인 형태로 엮어서 곡 단위로 만든 텍스트 파일은 ARR이며, 이를 다시 바이너리 스트림으로 전환한 것이 앞으로 개발할 ADS 파일이다. 'S'는 스트림을 뜻한다. 현재 개발 완료된 Nano Ardule 펌웨어(C++)의 재생 엔진이 혹시 1-bar 패턴 정보를 다루는 것이 가능한지를 점검하고자 코드를 분석한 뒤 만든 보고서가 바로 이 문서이다. 덧붙이자면 이러한 정보 체계는 모두 내가 고안하였다. 드럼 연주 패턴을 그리드 형식으로 표현하는 관행은 매우 오래되었지만, PC와 임베디드 시스템(아두이노 나노)을 위한 공개형 '표준' 포맷으로 만드려는 시도는 거의 없었던 것으로 안다.

마크다운 문서를 직접 웹브라우저에서 확인하는 것과 느낌은 사뭇 다르다. DokuWiki의 느낌이 물씬 난다. 

Ardule Drum Patternology Ecosystem을 만들기 위해 가야 할 길은 아직도 멀다. 재료에 해당하는 447개의 드럼 패턴은 일단 확보해 두었으나 두 시스템(아두이노 나노와 PC)에서 돌아가는 프로그램에 추가할 기능은 아직도 많다. 이 여정을 이어나가기 위해 필요한 문서는 앞으로 Ardule - Design Notes & Architectural Decision에 정리해 둘 것이다.