ScorePlayer TIL 1
착수 전에 기획만 정리한 날인데, 정한 것 셋이 전부 같은 모양이었다. “지금 하나뿐인 것”을 나중에 둘로 늘릴 자리를 어디에 비워 두느냐는 문제였다.
지금 하나여도 나중에 둘이 될 자리는 미리 갈라 둔다
이 도구는 악보 파일(MusicXML — 악보 프로그램끼리 음표·박자·가사를 주고받는 표준 형식)을 읽어 그린다. 언젠가 연주 파일(MIDI — 어느 건반을 언제 얼마나 눌렀는지만 적힌 연주 기록)도 받게 된다. 두 형식은 담고 있는 게 달라서, 그리는 쪽이 “이게 어느 형식인지”를 알기 시작하면 그 구분이 그리는 코드 전체로 번진다.
그래서 읽는 부분과 그리는 부분 사이에 칸막이(어댑터 — 형식마다 하나씩 두는 번역층)를 하나 뒀다. 읽는 쪽이 형식 차이를 다 흡수해서 같은 모양으로 넘기고, 그리는 쪽은 파일이 무엇이었는지 모른다.
값을 언제 치르느냐가 판단의 핵심이다.
- 지금 두면 — 코드가 한 겹 늘고, 당장은 아무 이득이 없다. 입력이 하나뿐이니까.
- 나중에 두면 — 이미 그려진 것 전부를 뜯어야 한다. 그때는 “이번 기능만 급하니 그냥 분기 하나 더” 쪽으로 기운다.
즉 이 칸막이는 두 번째 것이 들어올 때 이득이 나오는데, 그때 만들려면 이미 비싸다. 그래서 지금 뒀다.
반대로 아무 데나 칸막이를 두면 코드만 늘어난다. 판단 기준은 “두 번째가 올 거라는 근거가 있나”다. 여기서는 있었다 — 가진 악보 중 일부는 MIDI뿐이다.
시간을 누가 알려주는지는 상황마다 다르다
같은 장면을 화면에서 재생할 때와 영상으로 뽑을 때, “지금 몇 초인가”의 답이 달라야 한다.
- 재생 중에는 소리가 기준이다. 소리와 그림이 어긋나면 소리 쪽이 맞다.
- 뽑을 때는 프레임 번호가 기준이다. 이때는 소리가 없고, 실시간도 아니다.
여기서 배운 건 “시간”이 하나가 아니라는 것이다. 벽시계로 세면 두 상황 모두 틀린다 — 재생 중에는 소리와 조금씩 벌어지고, 뽑을 때는 컴퓨터가 느린 날 결과물의 박자가 달라진다.
그래서 그리는 쪽은 시간을 스스로 세지 않고 받아쓰기만 한다. 누가 주는지는 상황이 정한다.
특수한 경우를 일반한 경우의 부분집합으로 만든다
악보는 한 줄짜리(선율)일 수도, 두 줄짜리(피아노 왼손·오른손)일 수도 있다. 내가 다루는 건 대부분 두 줄이다.
한 줄을 전제로 세로 자리를 잡아 두면 두 줄을 붙일 때 음표 위치·볼 궤적·가사 줄을 전부 다시 잡는다. 반대로 처음부터 “줄이 여러 개”로 잡으면 한 줄짜리는 개수가 1인 경우로 저절로 처리된다.
특수를 일반의 부분집합으로 만드는 쪽이 언제나 싸다. 반대로 하면 나중에 일반을 만들 때 특수까지 다시 만든다.
요약
- 두 번째가 올 근거가 있으면 칸막이는 지금 둔다. 나중에 두는 값이 훨씬 비싸다
- 근거가 없으면 두지 않는다. 미리 두는 칸막이도 공짜가 아니다
- “지금 몇 초인가”의 답은 상황마다 다르다. 만드는 쪽이 스스로 세지 않게 한다
- 특수한 경우를 일반의 부분집합으로 만든다. 반대로 하면 두 번 만든다