2026년 7월 29일 수요일

검증은 보는 것에서 시작한다—ADC PatternLab 개발

PatternLab 결과물(실제 분석 보고서: 6BLUES, 6RANDB)

Type 0 MIDI 파일(.MID) 형태의 드럼 연주 패턴 데이터를 나의 '드럼 패턴학(Drum Patternlology)' 생태계에 집어넣기에 앞서서 파일 전체를 사람의 눈으로 확인하고 싶다는 생각이 들었다. 이 욕심을 실물로 구현한 것이 바로 adc-patternlab.py이라는 파이썬 스크립트이다. 스크립트의 이름은 (Drum) Pattern Lab, 즉 드럼 연주 패턴을 분석하는 실험실이다. 이 도구를 이용하여 커맨드라인에서 분석을 실시하면 HTML 결과 파일이 만들어지는데, 이를 웹 브라우저에서 열면 MIDI 이벤트 데이터를 있는 시각화한 화면과 매트릭스 형태로 변환한 화면을 전환하며 볼 수 있다. 철저히 비침습적으로 구동되며, 원본 MIDI 파일의 2-bar 단위 분할과 ADT/ADP 전환은 다른 도구가 맡는다.

Subdivision 분석을 통해 straingt/triplet-8/triplet-16을 구별하는 알고리즘도 실 데이터로 계속 테스트를 거치면서 더욱 고도화되었다. 처음에는 노트의 시작 시간(Note On Time)만 참고하였으나, 노트의 길이(duration) 또한 꽤 좋은 힌트가 됨을 알게 되었다. 패턴을 처음 생성했던 사람이 만약 DAW에서 작업을 했다고 가정해 보자. 셋잇단음표 체계의 리듬이라면(예: 블루스 또는 셔플), 삼등분 체계의 그리드를 만든 뒤 거기에 음표를 채우지 않았겠는가. '스윙'이라는 이름의 파일 안에 각 비트마다 킥과 스네어를 한 번씩만 타격한 패턴이 있다고 가정하자. Note on time으로는 스트레이트인지 트리플렛인지 알 수가 없다. 그러나 note duration이 1/3박자라면 triplet-8임이 명백해진다. Tick으로 계산해도 되지만, duration이 한 박자의 몇 %인지를 보는 것이 더 간단하다.

메타데이터, 즉 파일 자체에 붙어 있는 장르명 힌트도 매우 강력한 근거가 된다.

다음 그림은 작년말에 어설프게 만들었던 패턴 이미지이다. 지금 생각하면 대단히 부끄러운 수준이고 오류도 많았다. 그러나 이런 어설픔이 쌓이고 쌓여서 최근 며칠 동안 급격한 발전을 이루었다. Fluid Ardule에서 드럼 패턴 재생을 해 보겠다고 옆길로 새지 않았다면, 과거의 부족함과 오류를 발견하지 못한 상태로 그냥 방치하였을 것이다.


Pattern Lab은 단순한 시각화 도구를 넘어 grace/ghost note 및 flam 후보까지 찾아낸다. 최종 결정은 사람의 몫이다. 구현이 가장 시급한 flam이 경우 별도의 sidecar file을 써서 ADP 파일의 재생 시에 원래의 연주 의도를 그대로 표현하게 만드는 초기 테스트에도 성공하였다. 한 마디를 16 또는 24 스텝으로 추상화한 나의 드럼 패턴학 생태계에서 flam의 구현은 애초에 불가능하다고 생각했었으나 전혀 그렇지 않았다. 그러나 실제로는 그렇지 않았다. ADP는 최대한 단순하게 하되, 연주에 맛깔스럽게 양념을 치는 부가 정보는 sidecar file로 보완하면 단순한 스텝 기반 패턴에서도 실제 연주에 가까운 표현이 가능했다.

이처럼 PatternLab은 단순히 MIDI 파일을 읽어 보여주는 프로그램이 아니라, 사람의 눈으로 데이터를 검증하고 알고리즘을 개선하는 실험실(Laboratory) 역할을 담당하고 있다. 결국 좋은 자동화는 충분한 관찰에서 시작된다. PatternLab 역시 "먼저 본다. 그리고 이해한다. 그 다음에 변환한다."는 원칙 위에서 조금씩 진화하고 있다.

데이터 분석을 통해 음악 장르에 따라서 널리 쓰이는 드럼/타악기 세트(12개 이내)를 다음과 같이 확정한 것도 큰 성과이다. 약간의 추상화를 거치면 GM 드럼 표준 배열에서 12개로 충분하다!

Slot map definition. 원본에 해당하는 JSON 파일은 여기에 있다.


[부록] Subdivision 판정과 confidence 계산

PatternLab은 드럼 패턴의 subdivision을 단순히 음표가 놓인 위치만으로 결정하지 않는다. 현재 구현에서는 각 후보에 대해 note-on 위상, note duration, 입력 MIDI 파일명에 포함된 힌트를 종합하여 점수를 계산한다. 비교 대상은 straight-16, triplet-8, triplet-16이다.

가장 중요한 근거는 note-on의 위상이다. 각 타격이 한 박 안에서 16분음표 격자에 가까운지, 8분 셋잇단음표 또는 16분 셋잇단음표 격자에 가까운지를 조사한다. 이 위상 분석이 전체 판단의 중심이며, 최대 약 70%의 가중치를 갖는다. 박의 시작점과 정확한 반박 위치처럼 straight와 triplet에 공통으로 나타나는 지점은 판별력이 없으므로 증거에서 제외한다. 또한 flam으로 추정된 선행 grace note도 subdivision 판정을 흐리지 않도록 분석 대상에서 제외한다.

Note duration은 보조 증거로 사용한다. 음표 길이가 16분음표, 8분음표 또는 4분음표 계열에 가까우면 straight 후보에 점수를 주고, 1/3박·2/3박 또는 1/6박 계열에 가까우면 해당 triplet 후보에 점수를 준다. MIDI 드럼 파일에서는 note duration이 연주 의도를 정확히 반영하지 않는 경우도 많으므로, 이 항목의 영향은 최대 약 22%로 제한하였다.

파일명도 제한적으로 참조한다. 예를 들어 파일명에 straight, 16th, 16beat가 있으면 straight 후보에, shuffle, swing, triplet, 8T, 16T가 있으면 해당 triplet 후보에 추가 점수를 준다. 다만 파일명은 잘못 붙을 수도 있으므로, 실제 note-on 위상보다 우선하지 않는 보조 정보로만 사용한다.

세 종류의 근거를 합산한 뒤 가장 높은 점수를 얻은 후보를 1위, 그다음 후보를 2위로 정한다. 최고 점수가 너무 낮으면 unknown, 1위와 2위의 점수 차이가 작으면 mixed로 판정한다. 명확한 승자가 있을 때 confidence는 다음과 같이 계산한다.

confidence = (1위 점수 - 2위 점수) / (1위 점수 + 2위 점수)

이 값은 단순히 1위 점수가 얼마나 큰지를 나타내는 것이 아니라, 1위가 가장 유력한 경쟁 후보를 얼마나 확실하게 앞서는가를 나타낸다. 예를 들어 1위가 0.80, 2위가 0.20이면 confidence는 0.60이다. 반면 1위가 0.80이라도 2위가 0.70이면 confidence는 약 0.067에 불과하다. 즉, 절대 점수가 높더라도 두 후보가 팽팽하면 낮은 confidence가 부여된다.

이러한 계산은 subdivision 판정을 절대적인 정답으로 선언하기 위한 것이 아니다. PatternLab의 역할은 사람이 전체 MIDI 파일을 검토하기 전에 가장 가능성 높은 격자를 제안하고, 애매한 패턴을 낮은 confidence로 표시하여 재검토가 필요한 부분을 드러내는 데 있다.

댓글 없음: