ScorePlayer TIL 5
소리를 붙인 날인데, 정작 코드를 짜는 Claude는 소리를 들을 수 없다. “됐다”고 말하려면 무엇을 근거로 삼을지부터 정해야 했고, 거기서 나온 판단들이다.
확인할 수 없는 결과물에는 확인할 수 있는 신호를 붙인다
화면은 한 장 뽑아서 보면 된다. 소리는 그럴 수가 없다. 그러면 “붙였다”는 말의 근거가 아무것도 없는 상태가 된다.
그래서 소리 자체 대신 소리가 나기 위해 참이어야 하는 것들을 신호로 만들었다.
- 장치가 열렸나 — 안 열리면 조용한 게 정상이다. 이걸 모르면 버그와 환경을 구분 못 한다.
- 시계가 실시간으로 도나 — 1.2초를 기다렸을 때 오디오 클럭(소리 장치가 소리를 가져간 만큼 흐르는 시간)이 1.21초를 가리키면 제 속도로 돌고 있다는 뜻이다.
- 나가는 소리의 크기가 0이 아닌가 — 피크(출력 신호에서 가장 큰 진폭)가 0이면 시계만 돌고 소리는 안 실린 상태다. 이런 상태가 실제로 가능하다.
셋이 다 참이면 “안 들린다”의 후보가 음색·음량 문제로 좁혀진다. 그건 사람이 판단할 몫이다.
일반화하면 이렇다. 결과물을 직접 확인할 수 없을 때는 확인을 포기하지 말고, 결과물이 나오려면 참이어야 하는 중간 조건들을 값으로 뽑는다. 그러면 “모르겠다”가 “여기까지는 맞고 나머지는 사람이 본다”로 바뀐다.
이건 소리만의 이야기가 아니다. 남의 기기에서만 나는 문제, 특정 시간대에만 도는 작업, 눈으로 구분 안 되는 색 차이가 전부 같은 모양이다.
시간의 주인은 어긋남이 쌓이는 쪽에 둔다
앞선 TIL 1에서 기획 때 “재생 중 시간은 소리가 정한다”고 적어 뒀는데, 실제로 붙여 보니 이유가 더 분명해졌다.
한 프레임의 오차는 눈에 안 보인다. 문제는 그게 매 프레임 쌓인다는 것이다. 3분짜리 곡이면 만 번 넘게 더해지고, 끝에 가면 볼이 소리보다 눈에 띄게 앞서거나 뒤진다. 시작 부분만 보고 “맞네” 하면 놓친다.
그래서 실제로 내보낸 소리의 양(소리 장치에 넘긴 샘플 수를 샘플레이트 — 1초에 담는 소리 조각 수 — 로 나눈 값)을 경과 시간으로 삼는다. 화면이 몇 프레임을 건너뛰든 둘이 벌어지지 않는다.
가져갈 원리는 이것이다. 두 흐름을 맞춰야 할 때, 오차가 쌓이는 쪽을 기준으로 삼고 나머지가 따라가게 한다. 반대로 두면 처음엔 맞고 나중에 틀린다.
목적에 맞는 최소 품질로 시작한다
소리를 붙일 때 선택지가 둘이었다. 실제 피아노 음원(샘플 — 진짜 피아노를 건반마다 녹음해 둔 소리 파일)을 넣거나, 간단한 합성음(사인파에 배음(기본음 위에 겹치는 정수배 진동)을 조금 섞어 계산으로 만든 소리)으로 시작하거나.
이 소리의 목적은 감상이 아니라 “볼이 제 박자에 튀는지 귀로 확인하는 것”이다. 그 목적에는 합성음으로 충분하다. 음원을 넣으면 파일 용량과 라이선스 확인이 따라오고, 그건 배포를 생각할 때 다시 판단할 일이다.
판단 기준으로 삼을 것 — 기능을 붙일 때 “이게 무엇을 위한 것인가”를 먼저 좁히면 품질 수준이 자동으로 정해진다. 목적을 안 좁히면 처음부터 완성도를 올리다가 정작 확인해야 할 것을 못 한다.
미룬 것은 백로그에 이유와 함께 적어 뒀다. “나중에 더 좋게”가 아니라 “음원과 라이선스가 따라오므로 배포 판단과 같이”로 적어야 다음에 볼 때 판단이 선다.
없으면 없는 대로 돌아가게 둔다
소리 장치를 못 여는 환경이 있을 수 있다. 그때 앱이 멈추거나 재생이 안 되면 곤란하다.
그래서 장치가 없으면 소리 없이 화면 시간으로 돌게 뒀다. 평소라면 이런 대비를 미리 넣지 않는 편이 낫지만, 여기서는 판단이 달랐다 — 소리가 없는 상황에서는 소리와 그림이 어긋날 일도 없어서, 대체 동작이 정확히 맞는 답이 된다.
즉 대비를 넣을지 말지는 “그 상황에서 무엇이 맞는 동작인가”로 정한다. 답이 분명하면 넣고, 억지로 지어내야 하면 안 넣는다.
요약
- 직접 확인할 수 없는 결과물은, 그것이 나오려면 참이어야 하는 조건들을 값으로 뽑는다
- 두 흐름을 맞출 때는 오차가 쌓이는 쪽을 기준으로 삼는다. 반대로 두면 처음엔 맞고 끝에서 틀린다
- 기능의 목적을 좁히면 필요한 품질 수준이 정해진다. 안 좁히면 확인해야 할 것을 못 한 채 완성도만 올린다
- 미루는 것은 이유와 함께 적는다. “나중에 더 좋게”는 다음에 봐도 판단이 안 선다
- 없는 상황의 대체 동작은 그게 정확히 맞는 답일 때만 넣는다