요약

  • 사라진 명령 하나는 악기에서 일회성 누락이 될 수도, 지속되는 오류가 될 수도 있다. RTP MIDI 복구는 후자를 대상으로 하며, 전자를 완벽하게 재구성한다고 주장하지 않는다.
  • 복구 저널은 수신자가 교정 명령을 생성할 수 있도록 범위가 제한된 과거 정보를 제공한다. 모든 누락된 패킷을 재전송하는 것이 아니며, 복구된 공격음이 재생되지 않고 남는 것은 적절할 수 있다.
  • 침묵, 체크포인트 범위, 늦은 도착, 새 수신자의 초기 상태가 모두 복구에 영향을 미친다. 공유된 의미 체계는 의무를 확립하면서도 각기 다른 로컬 렌더링 알고리즘의 여지를 남겨둔다.

더 이상 말할 것이 없는 5초

연주자가 한 음을 끝내고 멈춘다. NoteOff 명령을 담은 패킷이 사라진다. 이후 5초 동안은 전송할 새로운 동작이 없다. 다른 RTP 패킷이 도착하지 않는 한, 수신자는 연주자가 다시 연주를 시작할 때까지 시퀀스 공백을 알아차리지 못할 수 있다. 발신지에서의 침묵이 수신지에서는 원치 않는 지속음이 될 수 있다.

이것은 2006년 11월 구현 가이드인RFC 4696에 실린 설계 예시이지, 특정 콘서트에 대한 보고가 아니다. 이 예시는 대화형 시스템의 곤란한 속성을 드러낸다. 발신자는 새로운 이벤트 생성을 멈출 수 있지만, 잘못 유지되던 오래된 이벤트는 다른 곳에서 계속 문제를 일으킬 수 있다.

가이드는 빈 MIDI 목록을 담은 가드 패킷을 다룬다. 이 패킷들은 또 다른 음악적 동작을 만들어낼 필요가 없다. 패킷의 도착 자체가 빠진 시퀀스 번호를 드러내고, 수신자가 오류를 바로잡는 데 필요한 저널 정보를 가져오게 할 수 있다. 새로운 명령 목록이 비어 있다고 해서 패킷이 쓸모없어지는 것은 아니다.

그러나 원치 않는 소리를 끝내는 것은 이미 들려온 몇 초를 되돌리지 못한다. 기계를 고치는 것과 공연을 다시 만드는 것의 구분은 우연한 한계가 아니었다. 이 구분이 복구 시스템의 목적을 결정했다.

오류의 지속 시간 자체가 그 의미의 일부였다

MIDI는 오디오 파형의 녹음이 아니라 기호적 명령 언어다. 명령은 신시사이저나 소프트웨어 악기에서 음을 시작·종료하거나 설정을 바꾼다. 수신자는 그 명령과 이미 갖고 있던 상태를 이용해 소리를 낸다. 따라서 작은 명령 하나의 손실은 명령 자체보다 훨씬 긴 결과를 낳을 수 있다.

2006년 11월 페이로드 명세인RFC 4695는 렌더링 결함을 일시적(transient)과 무기한(indefinite)으로 분류했다. 잃어버린 NoteOn은 들리지 않는 음을 남길 수 있지만, 그 누락은 보통 해당 음의 의도된 길이를 넘어서 지속되지 않는다. 잃어버린 NoteOff는 음이 계속 울리게 남길 수 있다. 채널 볼륨 명령 하나를 잃으면 그 채널의 이후 모든 음이 너무 크거나 너무 작게 들릴 수 있다.

"~할 수 있다"는 표현이 중요하다. 악기의 엔벨로프, 페달 상태, 이후의 명령이 실제 결과에 영향을 미친다. 놓친 릴리스가 모든 악기에서 끝없는 음을 만드는 것은 아니다. 그럼에도 프로토콜은 자신이 잘못 남겨둔 상태를 우연히 뒤따르는 이벤트가 수리해 주기를 기대할 수는 없다.

따라서 패킷 하나씩의 손실 두 번은 서로 다른 음악적 결과를 낳을 수 있다. 하나는 유한한 구멍을 남기고, 다른 하나는 미래를 오염시킨다. 패킷 손실 개수만으로는 수신자가 어느 종류의 피해를 멈춰야 하는지 알 수 없다.

전송 프레임워크는 빠진 음악을 추론할 수 없었다

2003년 7월 RTP 명세인RFC 3550은 시퀀스 번호, 타임스탬프, 페이로드 식별, 수신 모니터링을 제공한다. 그러나 이 명세는 전달 보장, 제시간 도착, 순서 보장을 명시적으로 하지 않는다. 이것들은 불완전한 네트워크를 다루기 위한 도구이지, 네트워크가 더 이상 불완전하지 않다는 증거가 아니다.

시퀀스 공백 자체는 악기의 볼륨 설정에 대해서도 아무것도 말해 주지 않는다. 그 지식은 애플리케이션에 속한다. 그래서 MIDI 페이로드 형식은 애플리케이션이 공백의 존재를 알아차리는 데 그치지 않고 그 결과를 이해할 수 있게 하는 정보를 함께 전달한다.

2011년 6월의 대체 명세인RFC 6295는 복구 저널의 중심 위임을 그대로 유지했다. 신뢰할 수 없는 전송으로 보내진 스트림에서 렌더링되는 공연은 무기한 결함을 포함해서는 안 된다는 것이다. 목적은 모든 순간적 오동작을 막는 것이 아니라, 오류가 자연스러운 끝 없이 계속 유효하게 남는 것을 막는 것이다.

수신자는 스트림에 대해 알고 있던 지식과 손실 이벤트를 종료하는 패킷의 저널을 비교한다. 차이가 있으면 로컬 복구 명령을 실행할 수 있다. 이렇게 무기한 오류는 일시적 오류로 전환된다. 로컬에서 생성된 릴리스가 원래의 원격 릴리스가 도착하지 못한 음을 멈출 수 있다.

저널은 모든 누락된 패킷을 재전송하는 방식으로 이를 달성하지 않는다. 악기를 정상 상태로 되돌리는 데 필요한 과거 정보를 전달하는데, 이는 전송 이력을 바이트 단위로 재현하는 것과는 다른 목표다.

저널은 세션 전체의 녹음이 아니었다

체크포인트는 관련 이력의 시작을 정의한다. 도착한 패킷이 I이고 체크포인트가 C라면, 체크포인트 이력은 C부터 I−1까지의 명령을 포괄하며 현재 패킷 자체의 명령은 제외한다. C가 I와 같으면 그 이력은 비어 있다.

임의 개수의 패킷 손실을 복구할 수 있다는 명세의 능력은 이 범위로 제한된다. 임의로 긴 장애를 복구 가능하게 만들지는 않는다. 수신자는 체크포인트를 검사하여 저널이 자신이 목격한 공백까지 충분히 거슬러 올라가는지 판단할 수 있다.

저널이 모든 과거의 공격음을 보존하는 것도 아니다. N 챕터는 한 음높이에 대한 일반적인 NoteOn·NoteOff 교차 패턴을 복구에 유용한 표현으로 지원한다. 더 복잡한 겹침 음 패턴은 E 챕터의 추가 지원이 필요하다. 건반이나 드럼 패드에 적합한 단순화된 설명이 모든 기타나 관악 컨트롤러의 알고리즘이 되는 것은 아니다.

N 챕터의 NoteOn 로그는 원래 명령의 정확한 실행 시각을 인코딩하지 않는다. Y 비트는 해당 음을 연주할지 건너뛸지에 대한 권고를 제공한다. 이는 지금 유용한 동작에 대한 힌트이지, 복구된 모든 이벤트를 재생하라는 지시가 아니다.

구현 가이드는 누락된 공격음을 건너뛰면서도 그 공격음이 반영된 것처럼 복구 기록을 갱신할 수 있는 수신자의 예를 보여준다. 그 기록 관리는 더 이상 현재 음악적 시점에 속하지 않는 소리를 추가하지 않고도 일관성을 갖출 수 있다. 청중이 늦게 듣도록 요구하지 않으면서 정보를 복구할 수 있다.

릴리스 명령은 모든 음향적 질문을 해결하지 않았다

더 미세한 한계도 있다. N 챕터는 NoteOff의 릴리스 벨로시티를 보존하지 않으며, E 챕터가 그 정보에 대한 지원을 추가할 수 있다. 저널은 릴리스와 댐퍼 페달 변경의 전체 상대적 순서를 보존하지 못할 수도 있다.

때로는 수신자가 자신의 이력에서 순서를 추론할 수 있다. 그럴 수 없을 때 명세는, 불쾌한 일시적 음을 남기는 비용을 치르더라도 페달로 유지되는 잘못 지속되는 음을 피하는 쪽을 선호한다. NoteOff를 보내는 것은 페달 상태와 무관하게 모든 악기가 즉시 조용해진다는 보편적 선언이 아니다.

이것들은 미관상의 예외가 아니다. 공연을 모든 동작과 그 시점의 완전한 기록이 아니라 상태를 수리하기에 충분한 이력으로 표현할 때 무엇이 사라지는지 보여 준다. 프로토콜은 불충분한 정보를 다루는 규칙을 제공하며, 불충분한 정보가 충분해졌다고 가장하지 않는다.

침묵에는 네트워크 비용이 있었다

가드 패킷은 침묵에 앞서 마지막으로 잃어버린 명령을 감지하고 수리할 기회를 제공한다. 복구 저널을 사용하는 스트림에서는 빈 MIDI 목록이 유용한 이력을 담은 저널과 함께 갈 수 있다. 빈 명령 목록, 빈 저널, 저널링을 하지 않도록 구성된 스트림은 서로 다른 세 가지다.

가이드의 예시 가드 스케줄은 구현 예시일 뿐이며, 모든 애플리케이션이 반드시 따라야 하는 보편적 타이머가 아니다. RFC 6295에서 설명하는 guardtime 매개변수는 연속 패킷 사이의 최대 간격을 RTP 타임스탬프 단위로 표현하며, 문서 자체가 제시하는 전형적인 범위도 명시적으로 규범적 한계가 아니다.

혼잡 제어가 요청된 전송 빈도보다 우선한다.RFC 3551의 오디오/비디오 프로파일은 다른 트래픽과 합리적으로 공존할 필요를 설명한다. 음악 애플리케이션이 자신의 오류가 들린다는 이유만으로 공유 대역폭에 무한한 권리를 갖는 것은 아니다. 손실을 만드는 조건을 악화시킨다면 더 잦은 복구 기회가 단순한 개선이 아니다.

모든 RTP MIDI 스트림이 어디서나 저널을 사용해야 한다는 요구도 없다. UDP 같은 신뢰할 수 없는 전송은 기본적으로 저널을 사용하고, TCP 같은 신뢰할 수 있는 전송은 그렇지 않다. 세션 기술은 복구 의무의 범위 안에서 기본값을 재정의할 수 있지만, 저널링 방식은 세션 시작 시 고정된다. 신뢰 가능하다고 알려진 로컬 데이터그램 환경은 명세가 논의한 한 예일 뿐, 모든 로컬 네트워크가 신뢰 가능하다고 가정할 근거가 아니다.

이력을 저장하는 일은 새로 들어온 수신자에 대한 의무를 만들었다

기본인 폐루프(closed-loop) 전송 정책은 수신자 피드백을 사용해 반복적으로 실어야 할 이력을 줄인다. 보통 RTCP 보고서가 수신된 확장 최고 시퀀스 번호를 제공하며, 합의된 다른 피드백 메커니즘이 그 역할을 할 수도 있다. 작은 체크포인트 이력은 일반적으로 더 작은 저널을 허용한다.

이 경제성은 수신자가 요구되는 복구를 수행한다는 전제에 의존한다. 시퀀스 진행에 대한 보고는 완벽한 음악적 경험에 대한 보고가 아니다. 과거 정보 중 무엇이 여전히 필요한지에 대한 범위가 제한된 판단을 지원할 뿐이다.

새로 합류한 수신자는 그 판단의 한계를 드러낸다. 스트림 초반에 설정된 채널 볼륨은 짧은 최근 이력에는 더 이상 나타나지 않을 수 있다. 기존 수신자들은 그 값을 안다. 새 수신자는 이후 패킷을 받으면서 잘못된 볼륨으로 렌더링할 수 있다. 발신자가 새 수신자의 존재를 알게 되면, 그 수신자가 무기한 결함 없이 시작하도록 보장해야 하며, 수신이 보고될 때까지 현재 컨트롤러 상태를 보호해야 할 수 있다.

일부 멀티캐스트나 다자간 구성에서는 발신자가 처음부터 누가 듣고 있는지 모를 수 있다. 알려지지 않은 수신자는 끼어 있는 음(stuck note)에 대한 예방 조치를 취할 수 있지만, 한 번도 받지 못한 볼륨 값을 추론할 수는 없다. 현재의 연결이 충분한 초기화를 보증하지는 않는다.

2017년 5월의 설계 가이드RFC 8088은 요약된 상태의 복구와 RTCP 기반 가지치기를 RTP MIDI의 흥미로운 특징으로 꼽았다. 그 유용성을 고도로 상태적인 기호 매체와 연결 지은 것이다. 이것은 설계 관찰이지 상업적 채택을 측정한 것이 아니다.

예시 수신자 하나가 허용되는 유일한 수신자는 아니었다

RFC 4696에서 논의된 NMP 구현은 순서가 어긋난 패킷을 무시한다. 이전 복구 동작이 이미 그 부재를 보상했을 수 있기 때문이다. 오래된 명령을 실행하면 교정이 중복될 수 있다. 제시간의 지식과 늦은 과거의 완전성은 서로 교환 가능하지 않다.

그러나 RFC 4696은 명시적으로 비규범적 문서다. 그 예시는 MIDI 명령의 일부만을 보호하고 특정 과거 네트워크 특성을 겨냥한다. 플레이아웃 버퍼를 사용하지 않으며, 가이드 자체가 버퍼 능력을 요구하는 인용된 상호운용성 조항을 완전히 충족하지는 못한다고 밝힌다.

규범적 규칙은 그 구현을 지시하는 것보다 좁다. 수신자는 순서가 어긋난 패킷을 처리할 때 무기한 결함을 만들어서는 안 된다. 플레이아웃 버퍼를 가진 수신자는 저널 처리를 렌더링 시점까지 미룰 수 있다. 잃어버린 것으로 보였던 패킷이 늦게 도착하더라도 여전히 사용 가능한 시점일 수 있기 때문이다.

세션 진입과 퇴장에도 의무가 따른다. 첫 패킷은 손실 이벤트를 종료하는 것처럼 처리되고, 세션을 떠나는 수신자는 무기한 잘못된 렌더링 상태를 남겨서는 안 된다. 복구는 바이트 수신을 넘어, 애플리케이션이 계속되는 — 또는 멈추는 — 상태까지 미친다.

등록된 형식이 완벽한 공연의 증거는 아니었다

audio/rtp-midi에 대한 IANA 등록은 실시간 MIDI 스트림을 위한 공통 이름, 매개변수, 명세 참조를 제공한다. 구현이 형식을 식별하는 데 도움을 준다. 특정 공연의 소리를 보증하거나 채택한 시스템 수를 세지 않는다.

2011년 개정판은 복구 원칙을 유지하면서 그림, 문법, 구성 예시를 수정했다. 수정된 오류에 대해 알려진 상호운용성 문제가 없다고 저자들이 말한 것은, 모든 곳의 모든 구현에 대한 진술이 아니다. 2011년 특정 애플리케이션 영역에 대한 그들의 평가 역시 시대를 반영한 평가로 남아야 하며, 오늘 시장에 대한 주장이 아니다.

지속된 기여는 복구에 대한 신중한 정의였다. 어떤 누락된 동작은 그 시점이 지나면 수행되어서는 안 된다. 다른 누락된 동작은 그 부재가 계속 작용하기 때문에 여전히 보상되어야 한다. RTP MIDI는 그 구분을 기계가 사용할 수 있게 만들었다. 동일한 과거를 복원한다고 주장하지 않으면서도 사용 가능한 현재를 되찾을 수 있었다.