본문 바로가기

유니티/리듬게임

[개발일지7] 메트로놈 재설계

노트를 생성을 하고, 음악을 넣고 메트로놈 소리도 함께 들었는데, 처음에는 별다른 이상이 없었다.

하지만 음악이 진행되면 될수록 음악의 박자와 메트로놈의 박자가 어긋나는 것이다.

 

음악이 라이브 연주였다면 "세션이 박자 실수를 했나" 라고 생각할 수도 있지만

컴퓨터로 작업된 mp3 음악파일이였기 때문에, 나의 메트로놈 시스템에 문제가 있다고 볼 수 밖에 없었다.

 

문제는 유니티 내부 시간의 문제였다.

유니티는 시간을 Time 클래스로 관리를 하게 되는데, Update 메소드안에서 돌아가기 때문에

fps 에 영향을 받는 것이였다. fps가 높으면 그만큼 자주 호출되어 시간이 빨라질 것이며, 느리다면 그 반대일 것이다.

이러한 이유 때문에 유니티에서 deltaTime 이라던가 fixed, smooth와 같은 fps에 영향을 최소화 하기 위한

보정된 시간값을 가져오는 메소드들이 있다.

 

하지만, 칼박으로 이루어진 음악파일 앞에서는 소용이 없다.

아무리 보정을 했다고 하지만 오차가 있다.

 

120 BPM 기준 한 박자의 시간값

위 사진은 Time.deltaTime을 사용했을 때, 로그 값이다.

120 BPM 기준 한 박자는 0.5초라서 제대로 나온 값이라고 생각할 수 있지만, 정말로 정확히 0.5초가 나와야 한다.

1초가 지나간 동안의 0.5를 제외한 숫자를 더해보면 0.0174874란 값이 나오는데, 평균값은 아니지만 음악이 60초에 도달 했을 때 메트로놈은 약 1초 늦은 시간을 가지고 있게 된다.

 

밴드 공연을 보러갔다고 상상을 해보자.

다른 악기들은 정확한 박자에 맞춰서 연주를 하고 있는데, 드럼이 첫박을 1초 늦게 친다고 생각하면 정말 끔찍할 것이다.

사실, 라이브 연주에서 퍼커션의 박자를 따라가겠지만..

 

이런 상황을 악보로 표현하면 대략 이렇게 볼 수 있다.

위 : 음악 아래: 메트로놈

음악과 메트로놈이 동시에 같은 위치에 있어야 하는데, 그렇지 못하게 되는 것이다.

 

아무튼.

원초적인 방법등 여러가지 시도를 해보았지만, 근본은 해결할 수가 없었다.

결국 구글링을 통해, 해결의 힌트를 얻게 되었다.

 

바로 timeSamples 값이다.

일반적으로 우리가 접할 수 있는 음악파일의 주파수는 44100hz이다.

1초에 44100번 진동한다는 것인데 현재 플레이중인 음악파일의 주파수값은 frequency로 알아낼수 있다.

이 주파수값은 timeSamples에 시간이 지나면서 갱신이 된다.

예를 들어, 44100hz인 음악파일을 2초 재생하고 나서 timeSamples의 값을 확인해보면 88200이 나온다.

나는 이 값을 통해 음악과 동기화하기 위한 정확한 시간값을 얻어낼 수 있게 되었다.

 

예전에 작성했던, Sync 스크립트를 다시 만들었다.

 

재코딩한 Sync.cs

 

다시 적용을 했더니 음악과 메트로놈이 완벽하게 동기화되었다.

'유니티 > 리듬게임' 카테고리의 다른 글

[개발일지10] 키 입력받기  (0) 2019.06.03
[개발일지8] 중간 진행 상황  (0) 2019.05.31
[개발일지6] 노트생성  (3) 2019.05.21
[개발일지5] 노트파서  (2) 2019.05.19
[개발일지4] 메트로놈  (0) 2019.04.13