[要約] RFC 4696は、RTP MIDIの実装ガイドであり、RTPを使用したMIDIデータの転送に関する手順とベストプラクティスを提供します。このRFCの目的は、RTP MIDIの実装者に対して、効果的なデータ転送を実現するためのガイダンスを提供することです。
Network Working Group J. Lazzaro Request for Comments: 4696 J. Wawrzynek Category: Informational UC Berkeley November 2006
An Implementation Guide for RTP MIDI
RTP MIDIの実装ガイド
Status of This Memo
本文書の位置付け
This memo provides information for the Internet community. It does not specify an Internet standard of any kind. Distribution of this memo is unlimited.
このメモは、インターネットコミュニティに情報を提供します。いかなる種類のインターネット標準を指定しません。このメモの配布は無制限です。
Copyright Notice
著作権表示
Copyright (C) The IETF Trust (2006).
Copyright(c)The IETF Trust(2006)。
Abstract
概要
This memo offers non-normative implementation guidance for the Real-time Protocol (RTP) MIDI (Musical Instrument Digital Interface) payload format. The memo presents its advice in the context of a network musical performance application. In this application two musicians, located in different physical locations, interact over a network to perform as they would if located in the same room. Underlying the performances are RTP MIDI sessions over unicast UDP. Algorithms for sending and receiving recovery journals (the resiliency structure for the payload format) are described in detail. Although the memo focuses on network musical performance, the presented implementation advice is relevant to other RTP MIDI applications.
このメモは、リアルタイムプロトコル(RTP)MIDI(楽器デジタルインターフェイス)ペイロード形式の非規範的な実装ガイダンスを提供します。このメモは、ネットワークミュージカルパフォーマンスアプリケーションのコンテキストでそのアドバイスを提示します。このアプリケーションでは、異なる物理的な場所にある2人のミュージシャンが、ネットワークを介して対話して、同じ部屋にある場合と同じように実行します。パフォーマンスの根底にあるのは、Unicast UDPを介したRTP MIDIセッションです。回復ジャーナルを送信および受信するためのアルゴリズム(ペイロード形式の回復力構造)について詳しく説明します。メモはネットワークの音楽パフォーマンスに焦点を当てていますが、提示された実装アドバイスは他のRTP MIDIアプリケーションに関連しています。
Table of Contents
目次
1. Introduction ....................................................2 2. Starting the Session ............................................3 3. Session Management: Session Housekeeping ........................6 4. Sending Streams: General Considerations .........................7 4.1. Queuing and Coding Incoming MIDI Data .....................11 4.2. Sending Packets with Empty MIDI Lists .....................12 4.3. Congestion Control and Bandwidth Management ...............13 5. Sending Streams: The Recovery Journal ..........................14 5.1. Initializing the RJSS .....................................16 5.2. Traversing the RJSS .......................................19 5.3. Updating the RJSS .........................................19 5.4. Trimming the RJSS .........................................20 5.5. Implementation Notes ......................................21 6. Receiving Streams: General Considerations ......................21 6.1 The NMP Receiver Design ....................................22 6.2 High-Jitter Networks, Local Area Networks ..................24 7. Receiving Streams: The Recovery Journal ........................25 7.1. Chapter W: MIDI Pitch Wheel (0xE) .........................30 7.2. Chapter N: MIDI NoteOn (0x8) and NoteOff (0x9) ............30 7.3. Chapter C: MIDI Control Change (0xB) ......................32 7.4. Chapter P: MIDI Program Change (0xC) ......................34 8. Security Considerations ........................................35 9. IANA Considerations ............................................35 10. Acknowledgements ..............................................35 11. References ....................................................35 11.1. Normative References .....................................35 11.2. Informative References ...................................36
[RFC4695] normatively defines a Real-time Transport Protocol (RTP, [RFC3550]) payload format for the MIDI (Musical Instrument Digital Interface) command language [MIDI], for use under any applicable RTP profile, such as the Audio/Visual Profile (AVP, [RFC3551]).
[RFC4695]は、オーディオ/ビジュアルプロファイルなどの任意のRTPプロファイルで使用するために、MIDI(楽器デジタルインターフェイス)コマンド言語[MIDI]のリアルタイムトランスポートプロトコル(RTP、[RFC3550])のペイロード形式を定義します。(AVP、[RFC3551])。
However, [RFC4695] does not define algorithms for sending and receiving MIDI streams. Implementors are free to use any sending or receiving algorithm that conforms to the normative text in [RFC4695], [RFC3550], [RFC3551], and [MIDI].
ただし、[RFC4695]は、MIDIストリームを送信および受信するためのアルゴリズムを定義していません。実装者は、[RFC4695]、[RFC3550]、[RFC3551]、および[MIDI]の規範テキストに準拠する送信または受信アルゴリズムを自由に使用できます。
In this memo, we offer implementation guidance on sending and receiving MIDI RTP streams. Unlike [RFC4695], this memo is not normative.
このメモでは、MIDI RTPストリームの送信と受信に関する実装ガイダンスを提供しています。[RFC4695]とは異なり、このメモは規範的ではありません。
RTP is a mature protocol, and excellent RTP reference materials are available [RTPBOOK]. This memo aims to complement the existing literature by focusing on issues that are specific to the MIDI payload format.
RTPは成熟したプロトコルであり、優れたRTP参照資料が利用可能です[RTPBook]。このメモは、MIDIペイロード形式に固有の問題に焦点を当てることにより、既存の文献を補完することを目的としています。
The memo focuses on one application: two-party network musical performance over wide-area networks, following the interoperability guidelines in Appendix C.7.2 of [RFC4695]. Underlying the performances are RTP MIDI sessions over unicast UDP transport. Resiliency is provided by the recovery journal system [RFC4695]. The application also uses the RTP Control Protocol (RTCP, [RFC3550]).
メモは、[RFC4695]の付録C.7.2の相互運用性ガイドラインに従って、1つのアプリケーションに焦点を当てています。パフォーマンスの根底にあるのは、Unicast UDPトランスポートを介したRTP MIDIセッションです。回復力は、Recovery Journal System [RFC4695]によって提供されます。アプリケーションは、RTP制御プロトコル(RTCP、[RFC3550])も使用します。
The application targets a network with a particular set of characteristics: low nominal jitter, low packet loss, and occasional outlier packets that arrive very late. However, in Section 6.2 of this memo, we discuss adapting the application to other network environments.
このアプリケーションは、特定の特性セットを備えたネットワークをターゲットにします。公称ジッターが低い、パケット損失が低い、非常に遅れて到着する場合によっては異常値のパケットです。ただし、このメモのセクション6.2では、アプリケーションを他のネットワーク環境に適応させることについて説明します。
As defined in [NMP], a network musical performance occurs when musicians located at different physical locations interact over a network to perform as they would if located in the same room.
[NMP]で定義されているように、ネットワークの音楽パフォーマンスは、異なる物理的な位置にあるミュージシャンがネットワーク上でやり取りして、同じ部屋にある場合にパフォーマンスを発揮するときに発生します。
Sections 2-3 of this memo describe session startup and maintenance. Sections 4-5 cover sending MIDI streams, and Sections 6-7 cover receiving MIDI streams.
このメモのセクション2〜3は、セッションの起動とメンテナンスについて説明します。セクション4〜5は、MIDIストリームを送信するカバーをカバーし、セクション6〜7はMIDIストリームを受け取るカバーをカバーします。
In this section, we describe how the application starts a two-player session. We assume that the two parties have agreed on a session configuration, embodied by a pair of Session Description Protocol (SDP, [RFC4566]) session descriptions.
このセクションでは、アプリケーションが2プレイヤーセッションを開始する方法について説明します。2つの当事者は、セッション説明プロトコルのペア(SDP、[RFC4566])セッションの説明によって具体化されたセッション構成に同意していると仮定します。
One session description (Figure 1) defines how the first party wishes to receive its stream. The other session description (Figure 2) defines how the second party wishes to receive its stream.
1つのセッションの説明(図1)は、最初の当事者がストリームを受信する方法を定義しています。他のセッションの説明(図2)は、第2のパーティがそのストリームをどのように受け取ることを望んでいるかを定義しています。
The session description in Figure 1 codes that the first party intends to receive a MIDI stream on IP4 number 192.0.2.94 (coded in the c= line) at UDP port 16112 (coded in the m= line). Implicit in the SDP m= line syntax [RFC4566] is that the first party also intends to receive an RTCP stream on 192.0.2.94 at UDP port 16113 (16112 + 1). The receiver expects that the PT field of each RTP header in the received stream will be set to 96 (coded in the m= line).
図1のセッションの説明では、最初のパーティがUDPポート16112(M =行でコーディング)のIP4番号192.0.2.94(C = lineでコード化)のMIDIストリームを受信する予定です。SDP M = line Syntax [RFC4566]で暗黙的には、最初のパーティは、UDPポート16113(16112 1)で192.0.2.94でRTCPストリームを受信する予定です。受信者は、受信ストリーム内の各RTPヘッダーのPTフィールドが96に設定されることを期待しています(M = Lineでコード化)。
Likewise, the session description in Figure 2 codes that the second party intends to receive a MIDI stream on IP4 number 192.0.2.105 at UDP port 5004 and intends to receive an RTCP stream on 192.0.2.105 at UDP port 5005 (5004 + 1). The second party expects that the PT RTP header field of received stream will be set to 101.
同様に、図2のセッションの説明は、第2党がUDPポート5004でIP4番号192.0.2.105でMIDIストリームを受信しようとしていることをコードし、UDPポート5005(5004 1)で192.0.2.105にRTCPストリームを受信する予定です。第2党は、受信されたストリームのPT RTPヘッダーフィールドが101に設定されることを期待しています。
v=0 o=first 2520644554 2838152170 IN IP4 first.example.net s=Example t=0 0 c=IN IP4 192.0.2.94 m=audio 16112 RTP/AVP 96 b=AS:20 b=RS:0 b=RR:400 a=rtpmap:96 mpeg4-generic/44100 a=fmtp:96 streamtype=5; mode=rtp-midi; config=""; profile-level-id=12; cm_unused=ABFGHJKMQTVXYZ; cm_unused=C120-127; ch_never=ADEFMQTVX; tsmode=buffer; linerate=320000; octpos=last; mperiod=44; rtp_ptime=0; rtp_maxptime=0; guardtime=44100; render=synthetic; rinit="audio/asc"; url="http://example.net/sa.asc"; cid="xjflsoeiurvpa09itnvlduihgnvet98pa3w9utnuighbuk"
(The a=fmtp line has been wrapped to fit the page to accommodate memo formatting restrictions; it constitutes a single line in SDP.)
(A = FMTP行は、メモのフォーマット制限に対応するためにページに適合するようにラップされています。SDPの単一行を構成します。)
Figure 1. Session description for first participant
図1.最初の参加者のセッションの説明
v=0 o=second 2520644554 2838152170 IN IP4 second.example.net s=Example t=0 0 c=IN IP4 192.0.2.105 m=audio 5004 RTP/AVP 101 b=AS:20 b=RS:0 b=RR:400 a=rtpmap:101 mpeg4-generic/44100 a=fmtp:101 streamtype=5; mode=rtp-midi; config=""; profile-level-id=12; cm_unused=ABFGHJKMQTVXYZ; cm_unused=C120-127; ch_never=ADEFMQTVX; tsmode=buffer; linerate=320000;octpos=last;mperiod=44; guardtime=44100; rtp_ptime=0; rtp_maxptime=0; render=synthetic; rinit="audio/asc"; url="http://example.net/sa.asc"; cid="xjflsoeiurvpa09itnvlduihgnvet98pa3w9utnuighbuk"
(The a=fmtp line has been wrapped to fit the page to accommodate memo formatting restrictions; it constitutes a single line in SDP.)
(A = FMTP行は、メモのフォーマット制限に対応するためにページに適合するようにラップされています。SDPの単一行を構成します。)
Figure 2. Session description for second participant
図2. 2番目の参加者のセッションの説明
The session descriptions use the mpeg4-generic media type (coded in the a=rtpmap line) to specify the use of the MPEG 4 Structured Audio renderer [MPEGSA]. The session descriptions also use parameters to customize the stream (Appendix C of [RFC4695]). The parameter values are identical for both parties, yielding identical rendering environments for the two client hosts.
セッションの説明では、MPEG4-GENERICメディアタイプ(A = RTPMAP行でコーディング)を使用して、MPEG 4構造化オーディオレンダラー[MPEGSA]の使用を指定します。セッションの説明では、パラメーターを使用してストリームをカスタマイズします([RFC4695]の付録C)。パラメーター値は両方の当事者で同一であり、2つのクライアントホストの同一のレンダリング環境をもたらします。
The bandwidth (b=) AS parameter [RFC4566] [RFC3550] indicates that the total RTP session bandwidth is 20 kbs. This value assumes that the two players send 10 kbs streams concurrently. To derive the 10 kbs value, we begin with the analysis of RTP MIDI payload bandwidth in Appendix A.4 of [NMP] and add in RTP and IP4 packet overhead and a small safety factor.
パラメーター[RFC4566] [RFC3550]としての帯域幅(b =)は、合計RTPセッション帯域幅が20 kbsであることを示しています。この値は、2人のプレーヤーが10 KBSストリームを同時に送信することを前提としています。10 KBS値を導出するために、[NMP]の付録A.4のRTP MIDIペイロード帯域幅の分析から始め、RTPおよびIP4パケットオーバーヘッドと小さな安全係数を追加します。
The bandwidth RR parameter [RFC3556] indicates that the shared RTCP session bandwidth for the two parties is 400 bps. We set the bandwidth SR parameter to 0 bps, to signal that sending parties and non-sending parties equally share the 400 bps of RTCP bandwidth. (Note that in this particular example, the guardtime parameter value of 44100 ensures that both parties are sending for the duration of the session.) The 400 bps RTCP bandwidth value supports one RTCP packet per 5 seconds from each party, containing a Sender Report and CNAME information [RFC3550].
帯域幅RRパラメーター[RFC3556]は、2つのパーティの共有RTCPセッション帯域幅が400 bpsであることを示しています。帯域幅SRパラメーターを0 bpsに設定し、パーティーと非送信者を送信することは、400 bpsのRTCP帯域幅を均等に共有することを示します。(この特定の例では、44100のGuardTimeパラメーター値は、両当事者がセッションの期間中に送信することを保証します。)400 bps RTCP帯域幅値は、各当事者から5秒あたり1つのRTCPパケットをサポートし、送信者レポートと送信者レポートが含まれています。CNAME情報[RFC3550]。
We now show an example of code that implements the actions the parties take during the session. The code is written in C and uses the standard network programming techniques described in [STEVENS]. We show code for the first party (the second party takes a symmetric set of actions).
ここで、セッション中に当事者が行うアクションを実装するコードの例を示します。コードはCで記述されており、[Stevens]で説明されている標準ネットワークプログラミング手法を使用しています。最初のパーティのコードを表示します(2番目のパーティは対称的なアクションセットを取得します)。
Figure 3 shows how the first party initializes a pair of socket descriptors (rtp_fd and rtcp_fd) to send and receive UDP packets. After the code in Figure 3 runs, the first party may check for new RTP or RTCP packets by calling recv() on rtp_fd or rtcp_fd.
図3は、最初のパーティがソケット記述子のペア(RTP_FDおよびRTCP_FD)を初期化してUDPパケットを送信および受信する方法を示しています。図3のコードが実行された後、最初のパーティは、RTP_FDまたはRTCP_FDでRecv()を呼び出すことにより、新しいRTPまたはRTCPパケットを確認できます。
Applications may use recv() to receive UDP packets on a socket using one of two general methods: "blocking" or "non-blocking".
アプリケーションは、recv()を使用して、2つの一般的な方法のいずれかを使用してソケットでUDPパケットを受信する場合があります。「ブロッキング」または「非ブロッキング」です。
A call to recv() on a blocking UDP socket puts the calling thread to sleep until a new packet arrives.
ブロッキングUDPソケットでRecv()への呼び出しにより、新しいパケットが到着するまで呼び出しスレッドがスリープされます。
A call to recv() on a non-blocking socket acts to poll the device: the recv() call returns immediately, with a return value that indicates the polling result. In this case, a positive return value signals the size of a new received packet, and a negative return value (coupled with an errno value of EAGAIN) indicates that no new packet was available.
非ブロッキングソケットでRecv()への呼び出しは、デバイスを投票するために機能します:Recv()コールはすぐに返され、ポーリング結果を示す返品値があります。この場合、正のリターン値は、新しい受信パケットのサイズを示し、ネガティブリターン値(イーガインのerrno値と相まって)は、新しいパケットが利用できなかったことを示します。
The choice of blocking or non-blocking sockets is a critical application choice. Blocking sockets offer the lowest potential latency (as the OS wakes the caller as soon as a packet has arrived). However, audio applications that use blocking sockets must adopt a multi-threaded program architecture, so that audio samples may be generated on a "rendering thread" while the "network thread" sleeps, awaiting the next packet. The architecture must also support a thread communication mechanism, so that the network thread has a mechanism to send MIDI commands the rendering thread.
ブロッキングまたは非ブロックソケットの選択は、重要なアプリケーションの選択です。ブロッキングソケットは、最低の潜在的な遅延を提供します(OSがパケットが到着するとすぐに発信者を覚醒させるため)。ただし、ブロッキングソケットを使用するオーディオアプリケーションは、マルチスレッドプログラムアーキテクチャを採用する必要があります。これにより、「ネットワークスレッド」が眠りながら「レンダリングスレッド」でオーディオサンプルを生成し、次のパケットを待っています。アーキテクチャは、ネットワークスレッドにMIDIコマンドにレンダリングスレッドを送信するメカニズムがあるように、スレッド通信メカニズムもサポートする必要があります。
In contrast, audio applications that use non-blocking sockets may be coded using a single thread, that alternates between audio sample generation and network polling. This architecture trades off increased network latency (as a packet may arrive between polls) for a simpler program architecture. For simplicity, our example uses non-blocking sockets and presumes a single run loop. Figure 4 shows how the example configures its sockets to be non-blocking.
対照的に、非ブロッキングソケットを使用するオーディオアプリケーションは、オーディオサンプルの生成とネットワークポーリングを交互にする単一のスレッドを使用してコード化される場合があります。このアーキテクチャは、より単純なプログラムアーキテクチャのために(投票の間にパケットが到着する可能性があるため)、ネットワークレイテンシの増加をトレードオフします。簡単にするために、私たちの例では、非ブロッキングソケットを使用して、単一の実行ループを推定します。図4は、この例がソケットを非ブロッキングとして構成する方法を示しています。
Figure 5 shows how to use recv() to check a non-blocking socket for new packets.
図5は、recv()を使用して新しいパケットの非ブロッキングソケットを確認する方法を示しています。
The first party also uses rtp_fd and rtcp_fd to send RTP and RTCP packets to the second party. In Figure 6, we show how to initialize socket structures that address the second party. In Figure 7, we show how to use one of these structures in a sendto() call to send an RTP packet to the second party.
また、最初のパーティはRTP_FDとRTCP_FDを使用して、RTPとRTCPパケットを第2パーティに送信します。図6では、第2パーティに対処するソケット構造を初期化する方法を示します。図7では、これらの構造のいずれかをSendto()コールで使用する方法を示して、RTPパケットを第2パーティに送信します。
Note that the code shown in Figures 3-7 assumes a clear network path between the participants. The code may not work if firewalls or Network Address Translation (NAT) devices are present in the network path.
図3〜7に示すコードは、参加者間の明確なネットワークパスを想定していることに注意してください。ファイアウォールまたはネットワークアドレス変換(NAT)デバイスがネットワークパスに存在する場合、コードは機能しない場合があります。
After the two-party interactive session is set up, the parties begin to send and receive RTP packets. In Sections 4-7, we discuss RTP MIDI sending and receiving algorithms. In this section, we describe session "housekeeping" tasks that the participants also perform.
2パーティのインタラクティブセッションが設定された後、パーティーはRTPパケットの送信と受け取りを開始します。セクション4〜7では、RTP MIDIの送信および受信アルゴリズムについて説明します。このセクションでは、参加者も実行するセッション「ハウスキーピング」タスクについて説明します。
One housekeeping task is the maintenance of the 32-bit Synchronization Source (SSRC) value that uniquely identifies each party. Section 8 of [RFC3550] describes SSRC issues in detail, as does Section 2.1 in [RFC4695]. Another housekeeping task is the sending and receiving of RTCP. Section 6 of [RFC3550] describes RTCP in detail.
ハウスキーピングタスクの1つは、各パーティーを一意に識別する32ビット同期ソース(SSRC)値のメンテナンスです。[RFC3550]のセクション8では、[RFC4695]のセクション2.1と同様に、SSRCの問題について詳しく説明しています。別のハウスキーピングタスクは、RTCPの送信と受信です。[RFC3550]のセクション6では、RTCPについて詳しく説明しています。
Another housekeeping task concerns security. As detailed in the Security Considerations section of [RFC4695], per-packet authentication is strongly recommended for use with MIDI streams, because the acceptance of rogue packets may lead to the execution of arbitrary MIDI commands.
別のハウスキーピングタスクはセキュリティに関するものです。[RFC4695]のセキュリティ上の考慮事項セクションで詳述されているように、Rogueパケットの受け入れが任意のMIDIコマンドの実行につながる可能性があるため、パケットごとの認証はMIDIストリームでの使用に強くお勧めします。
A final housekeeping task concerns the termination of the session. In our two-party example, the session terminates upon the exit of one of the participants. A clean termination may require active effort by a receiver, as a MIDI stream stopped at an arbitrary point may cause stuck notes and other indefinite artifacts in the MIDI renderer.
最終的なハウスキーピングタスクは、セッションの終了に関するものです。2パーティの例では、セッションは参加者の1人の出口で終了します。任意のポイントでMIDIストリームが停止する可能性があるため、クリーンな終了には受信機による積極的な努力が必要になる場合があります。
The exit of a party may be signalled in several ways. Session management tools may offer a reliable signal for termination (such as the SIP BYE method [RFC3261]). The (unreliable) RTCP BYE packet [RFC3550] may also signal the exit of a party. Receivers may also sense the lack of RTCP activity and timeout a party or may use transport methods to detect an exit.
In this section, we discuss sender implementation issues.
このセクションでは、送信者の実装の問題について説明します。
The sender is a real-time data-driven entity. On an ongoing basis, the sender checks to see if the local player has generated new MIDI data. At any time, the sender may transmit a new RTP packet to the remote player for the reasons described below:
送信者は、リアルタイムのデータ駆動型エンティティです。継続的に、送信者はローカルプレーヤーが新しいMIDIデータを生成したかどうかを確認するためにチェックします。いつでも、送信者は、以下に説明する理由により、新しいRTPパケットをリモートプレーヤーに送信できます。
1. New MIDI data has been generated by the local player, and the sender decides that it is time to issue a packet coding the data.
1. 新しいMIDIデータはローカルプレーヤーによって生成されており、送信者はデータをコーディングするパケットを発行する時が来たと判断します。
2. The local player has not generated new MIDI data, but the sender decides that too much time has elapsed since the last RTP packet transmission. The sender transmits a packet in order to relay updated header and recovery journal data.
2. ローカルプレーヤーは新しいMIDIデータを生成していませんが、送信者は、最後のRTPパケット送信以来、時間が多すぎると判断します。送信者は、更新されたヘッダーとリカバリジャーナルデータを中継するためにパケットを送信します。
In both cases, the sender generates a packet that consists of an RTP header, a MIDI command section, and a recovery journal. In the first case, the MIDI list of the MIDI command section codes the new MIDI data. In the second case, the MIDI list is empty.
どちらの場合も、送信者は、RTPヘッダー、MIDIコマンドセクション、回復ジャーナルで構成されるパケットを生成します。最初のケースでは、MIDIコマンドセクションのMIDIリストが新しいMIDIデータをコーディングします。2番目のケースでは、MIDIリストが空です。
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h>
int rtp_fd, rtcp_fd; /* socket descriptors */ struct sockaddr_in addr; /* for bind address */
/*********************************/ /* create the socket descriptors */ /*********************************/
if ((rtp_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) ERROR_RETURN("Couldn't create Internet RTP socket");
if ((rtcp_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) ERROR_RETURN("Couldn't create Internet RTCP socket");
/**********************************/ /* bind the RTP socket descriptor */ /**********************************/
memset(&(addr.sin_zero), 0, 8); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(16112); /* port 16112, from SDP */
if (bind(rtp_fd, (struct sockaddr *)&addr, sizeof(struct sockaddr)) < 0) ERROR_RETURN("Couldn't bind Internet RTP socket");
/***********************************/ /* bind the RTCP socket descriptor */ /***********************************/
memset(&(addr.sin_zero), 0, 8); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(16113); /* port 16113, from SDP */
if (bind(rtcp_fd, (struct sockaddr *)&addr, sizeof(struct sockaddr)) < 0) ERROR_RETURN("Couldn't bind Internet RTCP socket");
Figure 3. Setup code for listening for RTP/RTCP packets
図3. RTP/RTCPパケットをリスニングするためのセットアップコード
#include <unistd.h> #include <fcntl.h>
/***************************/ /* set non-blocking status */ /***************************/
if (fcntl(rtp_fd, F_SETFL, O_NONBLOCK)) ERROR_RETURN("Couldn't unblock Internet RTP socket");
if(fcntl(rtp_fd、f_setfl、o_nonblock))error_return( "インターネットRTPソケットを解除できなかった");
if (fcntl(rtcp_fd, F_SETFL, O_NONBLOCK)) ERROR_RETURN("Couldn't unblock Internet RTCP socket");
if(fcntl(rtcp_fd、f_setfl、o_nonblock))error_return( "インターネットRTCPソケットを解除できませんでした");
Figure 4. Code to set socket descriptors to be non-blocking
図4.ソケット記述子を非ブロッキングに設定するコード
#include <errno.h> #define UDPMAXSIZE 1472 /* based on Ethernet MTU of 1500 */
unsigned char packet[UDPMAXSIZE+1]; int len, normal;
unsigned charパケット[udpmaxsize 1];int len、正常;
while ((len = recv(rtp_fd, packet, UDPMAXSIZE + 1, 0)) > 0) { /* process packet[]. If (len == UDPMAXSIZE + 1), recv() * may be returning a truncated packet -- process with care */ }
/* line below sets "normal" to 1 if the recv() return */ /* status indicates no packets are left to process */
normal = (len < 0) && (errno == EAGAIN);
if (!normal) { /* * recv() return status indicates an empty UDP payload * (len == 0) or an error condition (coded by (len < 0) * and (errno != EAGAIN)). Examine len and errno, and * take appropriate recovery action. */ }
Figure 5. Code to check rtp_fd for new RTP packets
図5.新しいRTPパケットのRTP_FDを確認するコード
#include <arpa/inet.h> #include <netinet/in.h>
struct sockaddr_in * rtp_addr; /* RTP destination IP/port */ struct sockaddr_in * rtcp_addr; /* RTCP destination IP/port */
/* set RTP address, as coded in Figure 2's SDP */
rtp_addr = calloc(1, sizeof(struct sockaddr_in)); rtp_addr->sin_family = AF_INET; rtp_addr->sin_port = htons(5004); rtp_addr->sin_addr.s_addr = inet_addr("192.0.2.105");
/* set RTCP address, as coded in Figure 2's SDP */
rtcp_addr = calloc(1, sizeof(struct sockaddr_in)); rtcp_addr->sin_family = AF_INET; rtcp_addr->sin_port = htons(5005); /* 5004 + 1 */ rtcp_addr->sin_addr.s_addr = rtp_addr->sin_addr.s_addr;
Figure 6. Initializing destination addresses for RTP and RTCP
図6. RTPおよびRTCPの宛先アドレスの初期化
unsigned char packet[UDPMAXSIZE]; /* RTP packet to send */ int size; /* length of RTP packet */
/* first fill packet[] and set size ... then: */
if (sendto(rtp_fd, packet, size, 0, rtp_addr, sizeof(struct sockaddr)) == -1) { /* * try again later if errno == EAGAIN or EINTR * * other errno values --> an operational error */ }
Figure 7. Using sendto() to send an RTP packet
図7. sendto()を使用してRTPパケットを送信します
Figure 8 shows the 5 steps a sender takes to issue a packet. This algorithm corresponds to the code fragment for sending RTP packets shown in Figure 7 of Section 2. Steps 1, 2, and 3 occur before the sendto() call in the code fragment. Step 4 corresponds to the sendto() call itself. Step 5 may occur once Step 3 completes.
図8は、送信者がパケットを発行するために取る5つのステップを示しています。このアルゴリズムは、セクション2の図7に示すRTPパケットを送信するためのコードフラグメントに対応しています。手順1、2、および3は、コードフラグメントのsend()呼び出しの前に発生します。ステップ4は、sendto()コール自体に対応します。ステップ5が完了すると、ステップ5が発生する場合があります。
The algorithm for Sending a Packet is as follows:
パケットを送信するためのアルゴリズムは次のとおりです。
1. Generate the RTP header for the new packet. See Section 2.1 of [RFC4695] for details.
1. 新しいパケットのRTPヘッダーを生成します。詳細については、[RFC4695]のセクション2.1を参照してください。
2. Generate the MIDI command section for the new packet. See Section 3 of [RFC4695] for details.
2. 新しいパケットのMIDIコマンドセクションを生成します。詳細については、[RFC4695]のセクション3を参照してください。
3. Generate the recovery journal for the new packet. We discuss this process in Section 5.2. The generation algorithm examines the Recovery Journal Sending Structure (RJSS), a stateful coding of a history of the stream.
3. 新しいパケットのRecovery Journalを生成します。このプロセスについては、セクション5.2で説明します。生成アルゴリズムは、ストリームの履歴のステートフルコーディングであるRecovery Journal Sending Structure(RJSS)を調べます。
4. Send the new packet to the receiver.
4. 新しいパケットを受信機に送信します。
5. Update the RJSS to include the data coded in the MIDI command section of the packet sent in step 4. We discuss the update procedure in Section 5.3.
5. RJSSを更新して、ステップ4で送信されたパケットのMIDIコマンドセクションにコード化されたデータを含めるように、セクション5.3の更新手順について説明します。
Figure 8. A 5 step algorithm for sending a packet
図8.パケットを送信するための5ステップアルゴリズム
In the sections that follow, we discuss specific sender implementation issues in detail.
以下のセクションでは、特定の送信者の実装の問題について詳しく説明します。
Simple senders transmit a new packet as soon as the local player generates a complete MIDI command. The system described in [NMP] uses this algorithm. This algorithm minimizes the sender queuing latency, as the sender never delays the transmission of a new MIDI command.
シンプルな送信者は、ローカルプレーヤーが完全なMIDIコマンドを生成するとすぐに新しいパケットを送信します。[NMP]で説明されているシステムは、このアルゴリズムを使用します。このアルゴリズムは、送信者が新しいMIDIコマンドの送信を決して遅らせないため、送信者キューイングレイテンシを最小限に抑えます。
In a relative sense, this algorithm uses bandwidth inefficiently, as it does not amortize the overhead of a packet over several commands. This inefficiency may be acceptable for sparse MIDI streams (see Appendix A.4 of [NMP]). More sophisticated sending algorithms [GRAME] improve efficiency by coding small groups of commands into a single packet, at the expense of increasing the sender queuing latency.
相対的な意味では、このアルゴリズムは、いくつかのコマンドでパケットのオーバーヘッドを償却しないため、帯域幅を非効率的に使用します。この非効率性は、まばらなMIDIストリームで受け入れられる可能性があります([NMP]の付録A.4を参照)。より洗練された送信アルゴリズム[grame]は、送信者のキューイングレイテンシを増やすことを犠牲にして、コマンドの小さなグループを単一のパケットにコーディングすることにより、効率を改善します。
Senders assign a timestamp value to each command issued by the local player (Appendix C.3 of [RFC4695]). Senders may code the timestamp value of the first MIDI list command in two ways. The most efficient method is to set the RTP timestamp of the packet to the timestamp value of the first command. In this method, the Z bit of the MIDI command section header (Figure 2 of [RFC4695]) is set to 0, and the RTP timestamps increment at a non-uniform rate.
送信者は、ローカルプレーヤーが発行した各コマンドにタイムスタンプの値を割り当てます([RFC4695]の付録C.3)。送信者は、最初のMIDIリストコマンドのタイムスタンプ値を2つの方法でコーディングできます。最も効率的な方法は、パケットのRTPタイムスタンプを最初のコマンドのタイムスタンプ値に設定することです。この方法では、MIDIコマンドセクションヘッダー([RFC4695]の図2)のzビットが0に設定され、RTPタイムスタンプは不均一な速度で増分します。
However, in some applications, senders may wish to generate a stream whose RTP timestamps increment at a uniform rate. To do so, senders may use the Delta Time MIDI list field to code a timestamp for the first command in the list. In this case, the Z bit of the MIDI command section header is set to 1.
ただし、一部のアプリケーションでは、送信者は、RTPタイムスタンプが均一な速度で増加するストリームを生成したい場合があります。そのために、送信者は、リスト内の最初のコマンドのタイムスタンプをコーディングするために、Delta Time MIDIリストフィールドを使用できます。この場合、MIDIコマンドセクションヘッダーのzビットは1に設定されています。
Senders should strive to maintain a constant relationship between the RTP packet timestamp and the packet sending time: if two packets have RTP timestamps that differ by 1 second, the second packet should be sent 1 second after the first packet. To the receiver, variance in this relationship is indistinguishable from network jitter. Latency issues are discussed in detail in Section 6.
送信者は、RTPパケットタイムスタンプとパケットの送信時間との間に絶え間ない関係を維持するよう努力する必要があります。2つのパケットが1秒で異なるRTPタイムスタンプがある場合、2番目のパケットを最初のパケットの1秒後に送信する必要があります。受信者にとって、この関係の分散は、ネットワークジッターと区別できません。レイテンシの問題については、セクション6で詳しく説明します。
Senders may alter the running status coding of the first command in the MIDI list, in order to comply with the coding rules defined in Section 3.2 of [RFC4695]. The P header bit (Figure 2 of [RFC4695]) codes this alteration of the source command stream.
送信者は、[RFC4695]のセクション3.2で定義されているコーディングルールに準拠するために、MIDIリストの最初のコマンドの実行ステータスコーディングを変更する場合があります。Pヘッダービット([RFC4695]の図2)は、ソースコマンドストリームのこの変更をコードします。
During a session, musicians might refrain from generating MIDI data for extended periods of time (seconds or even minutes). If an RTP stream followed the dynamics of a silent MIDI source and stopped sending RTP packets, system behavior might be degraded in the following ways:
セッション中、ミュージシャンは長期間(秒または数分)長期間MIDIデータを生成することを控えることができます。RTPストリームがサイレントMIDIソースのダイナミクスに従い、RTPパケットの送信を停止した場合、システムの動作は次の方法で分解される可能性があります。
o The receiver's model of network performance may fall out of date.
o ネットワークパフォーマンスのレシーバーモデルは時代遅れになる可能性があります。
o Network middleboxes (such as Network Address Translators) may "time-out" the silent stream and drop the port and IP association state.
o ネットワークミドルボックス(ネットワークアドレス翻訳者など)は、サイレントストリームを「タイムアウト」し、ポートおよびIPアソシエーションの状態をドロップする場合があります。
o If the session does not use RTCP, receivers may misinterpret the silent stream as a dropped network connection.
o セッションがRTCPを使用していない場合、受信機はサイレントストリームをドロップされたネットワーク接続として誤って解釈する場合があります。
Senders avoid these problems by sending "keep-alive" RTP packets during periods of network inactivity. Keep-alive packets have empty MIDI lists.
送信者は、ネットワークの不活性の期間中に「キープアライブ」RTPパケットを送信することにより、これらの問題を回避します。キープアライブパケットには、空のMIDIリストがあります。
Session participants may specify the frequency of keep-alive packets during session configuration with the MIME parameter "guardtime" (Appendix C.4.2 of [RFC4695]). The session descriptions shown in Figures 1-2 use guardtime to specify a keep-alive sending interval of 1 second.
セッション参加者は、MIMEパラメーター「GuardTime」([RFC4695]の付録C.4.2)を使用して、セッション構成中にキープアリブパケットの頻度を指定できます。図1-2に示すセッションの説明では、GuardTimeを使用して、1秒のキープアライブ送信間隔を指定します。
Senders may also send empty packets to improve the performance of the recovery journal system. As we describe in Section 6, the recovery process begins when a receiver detects a break in the RTP sequence number pattern of the stream. The receiver uses the recovery journal of the break packet to guide corrective rendering actions, such as ending stuck notes and updating out-of-date controller values.
送信者は、Recovery Journalシステムのパフォーマンスを改善するために空のパケットを送信することもできます。セクション6で説明するように、回復プロセスは、レシーバーがストリームのRTPシーケンス番号パターンのブレークを検出すると始まります。受信者は、Break PacketのRecovery Journalを使用して、スタックノートの終了や時代遅れのコントローラー値の更新など、修正レンダリングアクションをガイドします。
Consider the situation where the local player produces a MIDI NoteOff command (which the sender promptly transmits in a packet) but then 5 seconds pass before the player produces another MIDI command (which the sender transmits in a second packet). If the packet coding the NoteOff is lost, the receiver is not aware of the packet loss incident for 5 seconds, and the rendered MIDI performance contains a note that sounds for 5 seconds too long.
ローカルプレーヤーがMIDIノートオフコマンド(送信者が速やかにパケットに送信する)を生成する状況を考えてみましょうが、その後、プレイヤーが別のMIDIコマンド(送信者が2番目のパケットで送信する)を生成する前に5秒が通過します。ノートオフのパケットコーディングが失われた場合、受信者は5秒間のパケット損失インシデントを認識しておらず、レンダリングされたMIDIパフォーマンスには5秒間長すぎる音が含まれています。
To handle this situation, senders may transmit empty packets to "guard" the stream during silent sections. The guard packet algorithm defined in Section 7.3 of [NMP], as applied to the situation described above, sends a guard packet after 100 ms of player inactivity, and sends a second guard packet 100 ms later. Subsequent guard packets are sent with an exponential backoff, with a limiting period of 1 second (set by the "guardtime" parameter in Figures 1-2). The algorithm terminates once MIDI activity resumes, or once RTCP receiver reports indicate that the receiver is up to date.
この状況を処理するために、送信者は空のパケットを送信して、サイレントセクション中にストリームを「ガード」することができます。上記の状況に適用されるように、[NMP]のセクション7.3で定義されているガードパケットアルゴリズムは、100ミリ秒のプレーヤーの不活動後にガードパケットを送信し、100ミリ秒後に2番目のガードパケットを送信します。後続のガードパケットは、1秒の制限期間(図1-2の「ガードタイム」パラメーターによって設定)で指数関数的なバックオフで送信されます。アルゴリズムは、MIDIアクティビティが再開すると終了します。または、RTCPレシーバーレポートが受信機が最新であることを示します。
The perceptual quality of guard packet-sending algorithms is a quality of implementation issue for RTP MIDI applications. Sophisticated implementations may tailor the guard packet sending rate to the nature of the MIDI commands recently sent in the stream, to minimize the perceptual impact of moderate packet loss.
As an example of this sort of specialization, the guard packet algorithm described in [NMP] protects against the transient artifacts that occur when NoteOn commands are lost. The algorithm sends a guard packet 1 ms after every packet whose MIDI list contains a NoteOn command. The Y bit in Chapter N note logs (Appendix A.6 of [RFC4695]) supports this use of guard packets.
この種の専門化の例として、[NMP]で説明されているガードパケットアルゴリズムは、ノートソンコマンドが失われたときに発生する過渡的なアーティファクトから保護します。アルゴリズムは、MIDIリストにNoteonコマンドが含まれているパケットごとに1ミリ秒後にガードパケットを送信します。NノートログのYビット([RFC4695]の付録A.6)は、このガードパケットの使用をサポートしています。
Congestion control and bandwidth management are key issues in guard packet algorithms. We discuss these issues in the next section.
混雑制御と帯域幅管理は、ガードパケットアルゴリズムの重要な問題です。次のセクションでこれらの問題について説明します。
The congestion control section of [RFC4695] discusses the importance of congestion control for RTP MIDI streams and references the normative text in [RFC3550] and [RFC3551] that concerns congestion control. To comply with the requirements described in those normative documents, RTP MIDI senders may use several methods to control the sending rate: o As described in Section 4.1, senders may pack several MIDI commands into a single packet, thereby reducing stream bandwidth (at the expense of increasing sender queuing latency).
[RFC4695]の輻輳制御セクションでは、RTP MIDIストリームの輻輳制御の重要性について説明し、輻輳制御に関係する[RFC3550]および[RFC3551]の規範テキストを参照しています。これらの規範的文書で説明されている要件に準拠するために、RTP MIDI送信者は、送信速度を制御するためにいくつかの方法を使用できます。Oセクション4.1で説明されているように、送信者はいくつかのMIDIコマンドを単一のパケットに詰め込んで、それによりストリーム帯域幅を削減できます(費用で犠牲を払って増加する送信者キューイングレイテンシの)。
o Guard packet algorithms (Section 4.2) may be designed in a parametric way, so that the tradeoff between artifact reduction and stream bandwidth may be tuned dynamically.
o ガードパケットアルゴリズム(セクション4.2)は、アーティファクトの削減とストリーム帯域幅のトレードオフが動的に調整されるように、パラメトリックな方法で設計される場合があります。
o The recovery journal size may be reduced by adapting the techniques described in Section 5 of this memo. Note that in all cases, the recovery journal sender must conform to the normative text in Section 4 of [RFC4695].
o このメモのセクション5に記載されている手法を適応させることにより、回復ジャーナルのサイズを縮小することができます。すべての場合において、Recovery Journal送信者は[RFC4695]のセクション4の規範的なテキストに準拠する必要があることに注意してください。
o The incoming MIDI stream may be modified to reduce the number of MIDI commands without significantly altering the performance. Lossy "MIDI filtering" algorithms are well developed in the MIDI community and may be directly applied to RTP MIDI rate management.
o 入ってくるMIDIストリームは、パフォーマンスを大幅に変更することなくMIDIコマンドの数を減らすために変更される場合があります。Losyの「MIDIフィルタリング」アルゴリズムは、MIDIコミュニティでよく開発されており、RTP MIDIレート管理に直接適用される場合があります。
RTP MIDI senders incorporate these rate control methods into feedback systems to implement congestion control and bandwidth management. Sections 10 and 6.4.4 of [RFC3550] and Section 2 in [RFC3551] describe feedback systems for congestion control in RTP, and Section 6 of [RFC4566] describes bandwidth management in media sessions.
RTP MIDI送信者は、これらのレート制御方法をフィードバックシステムに組み込み、混雑制御と帯域幅管理を実装します。[RFC3550]のセクション10および6.4.4および[RFC3551]のセクション2は、RTPの輻輳制御のフィードバックシステムを説明し、[RFC4566]のセクション6でメディアセッションの帯域幅管理について説明します。
In this section, we describe how senders implement the recovery journal system. The implementation we describe uses the default "closed-loop" recovery journal semantics (Appendix C.2.2.2 of [RFC4695]).
このセクションでは、送信者がRecovery Journal Systemをどのように実装するかについて説明します。私たちが説明する実装では、デフォルトの「閉ループ」回復ジャーナルのセマンティクスを使用します([RFC4695]の付録C.2.2.2)。
We begin by describing the Recovery Journal Sending Structure (RJSS). Senders use the RJSS to generate the recovery journal section for RTP MIDI packets.
まず、Recovery Journalの送信構造(RJSS)を説明することから始めます。送信者はRJSSを使用して、RTP MIDIパケットのRecovery Journalセクションを生成します。
The RJSS is a hierarchical representation of the checkpoint history of the stream. The checkpoint history holds the MIDI commands that are at risk to packet loss (Appendix A.1 of [RFC4695] precisely defines the checkpoint history). The layout of the RJSS mirrors the hierarchical structure of the recovery journal bitfields.
RJSSは、ストリームのチェックポイント履歴を階層的に表現しています。チェックポイントの履歴には、パケット損失に危険にさらされているMIDIコマンドが保持されます([RFC4695]の付録A.1は、チェックポイント履歴を正確に定義しています)。RJSSのレイアウトは、Recovery Journal Bitfieldsの階層構造を反映しています。
Figure 9 shows an RJSS implementation for a simple sender. The leaf level of the RJSS hierarchy (the jsend_chapter structures) corresponds to channel chapters (Appendices A.2-9 in [RFC4695]). The second level of the hierarchy (jsend_channel) corresponds to the channel journal header (Figure 9 in [RFC4695]). The top level of the hierarchy (jsend_journal) corresponds to the recovery journal header (Figure 8 in [RFC4695]).
図9は、単純な送信者のRJSS実装を示しています。RJSS階層の葉レベル(jsend_chapter構造)は、チャネル章([RFC4695]の付録A.2-9)に対応しています。階層の第2レベル(jsend_channel)は、チャネルジャーナルヘッダーに対応しています([rfc4695]の図9)。階層のトップレベル(jsend_journal)は、回復ジャーナルヘッダーに対応しています([RFC4695]の図8)。
Each RJSS data structure may code several items:
各RJSSデータ構造は、いくつかの項目をコーディングする場合があります。
1. The current contents of the recovery journal bitfield associated with the RJSS structure (jheader[], cheader[], or a chapter bitfield).
1. RJSS構造に関連するRecovery Journal Bitfieldの現在の内容(Jheader []、Cheader []、または章Bitfield)。
2. A seqnum variable. Seqnum codes the extended RTP sequence number of the most recent packet that added information to the RJSS structure. If the seqnum of a structure is updated, the seqnums of all structures above it in the recovery journal hierarchy are also updated. Thus, a packet that caused an update to a specific jsend_chapter structure would update the seqnum values of this structure and of the jsend_channel and jsend_journal structures that contain it.
2. seqnum変数。Seqnumは、RJSS構造に情報を追加した最新のパケットの拡張RTPシーケンス番号をコードします。構造のseqnumが更新された場合、Recovery Journalの階層の上のすべての構造のseqnumも更新されます。したがって、特定のjsend_chapter構造の更新を引き起こしたパケットは、この構造とそれを含むjsend_channelおよびjsend_journal構造のseqnum値を更新します。
3. Ancillary variables used by the sending algorithm.
3. 送信アルゴリズムで使用される補助変数。
A seqnum variable for a level is set to zero if the checkpoint history contains no information at the level of the seqnum variable, and no information at any level below the level of the seqnum variable. This coding scheme assumes that the first sequence number of a stream is normalized to 1, and limits the total number of stream packets to 2^32 - 1.
チェックポイントの履歴にSeqnum変数のレベルに情報が含まれていない場合、seqnum変数のレベル以下のどのレベルでも情報がない場合、aレベルのseqnum変数はゼロに設定されます。このコーディングスキームは、ストリームの最初のシーケンス数が1に正規化されていることを想定しており、ストリームパケットの総数を2^32-1に制限します。
The cm_unused and ch_never parameters in Figures 1-2 define the subset of MIDI commands supported by the sender (see Appendix C.2.3 of [RFC4695] for details). The sender transmits most voice commands but does not transmit system commands. The sender assumes that the MIDI source uses note commands in the typical way. Thus, the sender does not use the Chapter E note resiliency tools (Appendix A.7 of [RFC4695]). The sender does not support Control Change commands for controller numbers with All Notes Off (123-127), All Sound Off (120), and Reset All Controllers (121) semantics and does not support enhanced Chapter C encoding (Appendix A.3.3 of [RFC4695]).
図1-2のCM_UNUSEDおよびCH_NEVERパラメーターは、送信者がサポートするMIDIコマンドのサブセットを定義しています(詳細については、[RFC4695]の付録C.2.3を参照)。送信者はほとんどの音声コマンドを送信しますが、システムコマンドを送信しません。送信者は、MIDIソースが典型的な方法でノートコマンドを使用すると想定しています。したがって、送信者は章Eノートの復元ツールを使用しません([RFC4695]の付録A.7)。送信者は、すべてのメモがオフ(123-127)、すべてのサウンド(120)、およびすべてのコントローラー(121)のセマンティクスをリセットして、コントローラー番号のコントロール変更コマンドをサポートせず(121)セマンティクスをリセットし、拡張された第Cエンコーディングをサポートしていません(付録A.3.3[RFC4695])。
We chose this subset of MIDI commands to simplify the example. In particular, the command restrictions ensure that all commands are active, that all note commands are N-active, and that all Control Change commands are C-active (see Appendix A.1 of [RFC4695] for definitions of active, N-active, and C-active).
この例を簡素化するために、MIDIコマンドのこのサブセットを選択しました。特に、コマンド制限により、すべてのコマンドがアクティブであり、すべてのノートコマンドがnアクティブであり、すべての制御変更コマンドがCアクティブであることを保証します(アクティブ、nアクティブの定義については[RFC4695]の付録A.1を参照してください[RFC4695]、およびcアクティブ)。
In the sections that follow, we describe the tasks a sender performs to manage the recovery journal system.
以下のセクションでは、リカバリジャーナルシステムを管理するために送信者が実行するタスクについて説明します。
At the start of a stream, the sender initializes the RJSS. All seqnum variables are set to zero, including all elements of note_seqnum[] and control_seqnum[].
ストリームの開始時に、送信者はRJSSを初期化します。すべてのseqnum変数は、note_seqnum []およびcontrol_seqnum []のすべての要素を含むゼロに設定されています。
The sender initializes jheader[] to form a recovery journal header that codes an empty journal. The S bit of the header is set to 1, and the A, Y, R, and TOTCHAN header fields are set to zero. The checkpoint packet sequence number field is set to the sequence number of the upcoming first RTP packet (per Appendix A.1 of [RFC4695]).
送信者はJheader []を初期化して、空のジャーナルをコードする回復ジャーナルヘッダーを形成します。ヘッダーのビットは1に設定され、a、y、r、およびtotchanヘッダーフィールドはゼロに設定されています。チェックポイントパケットシーケンス番号フィールドは、今後の最初のRTPパケットのシーケンス番号に設定されています([RFC4695]の付録A.1ごと)。
typedef unsigned char uint8; /* must be 1 octet */ typedef unsigned short uint16; /* must be 2 octet */ typedef unsigned long uint32; /* must be 4 octets */
/**************************************************************/ /* leaf level hierarchy: Chapter W, Appendix A.5 of [RFC4695] */ /**************************************************************/
typedef struct jsend_chapterw { /* Pitch Wheel (0xE) */ uint8 chapterw[2]; /* bitfield Figure A.5.1 [RFC4695] */ uint32 seqnum; /* extended sequence number, or 0 */ } jsend_chapterw;
/**************************************************************/ /* leaf level hierarchy: Chapter N, Appendix A.6 of [RFC4695] */ /**************************************************************/
typedef struct jsend_chaptern { /* Note commands (0x8, 0x9) */
/* chapter N maximum size is 274 octets: a 2 octet header, */ /* and a maximum of 128 2-octet logs and 16 OFFBIT octets */
uint8 chaptern[274]; /* bitfield Figure A.6.1 [RFC4695] */ uint16 size; /* actual size of chaptern[] */ uint32 seqnum; /* extended seq number, or 0 */ uint32 note_seqnum[128]; /* most recent note seqnum, or 0 */ uint32 note_tstamp[128]; /* NoteOn execution timestamp */ uint32 bitfield_ptr[128]; /* points to a chapter log, or 0 */ } jsend_chaptern;
/**************************************************************/ /* leaf level hierarchy: Chapter C, Appendix A.3 of [RFC4695] */ /**************************************************************/
typedef struct jsend_chapterc { /* Control Change (0xB) */
/* chapter C maximum size is 257 octets: a 1 octet header */ /* and a maximum of 128 2-octet logs */
uint8 chapterc[257]; /* bitfield Figure A.3.1 [RFC4695] */ uint16 size; /* actual size of chapterc[] */ uint32 seqnum; /* extended sequence number, or 0 */ uint32 control_seqnum[128]; /* most recent seqnum, or 0 */ uint32 bitfield_ptr[128]; /* points to a chapter log, or 0 */ } jsend_chapterc;
Figure 9. Recovery Journal Sending Structure (part 1)
図9.回復ジャーナル送信構造(パート1)
/**************************************************************/ /* leaf level hierarchy: Chapter P, Appendix A.2 of [RFC4695] */ /**************************************************************/
typedef struct jsend_chapterp { /* MIDI Program Change (0xC) */
uint8 chapterp[3]; /* bitfield Figure A.2.1 [RFC4695] */ uint32 seqnum; /* extended sequence number, or 0 */
} jsend_chapterp;
} jsend_chapterp;
/***************************************************/ /* second-level of hierarchy, for channel journals */ /***************************************************/
typedef struct jsend_channel {
typedef struct jsend_channel {
uint8 cheader[3]; /* header Figure 9 [RFC4695]) */ uint32 seqnum; /* extended sequence number, or 0 */
jsend_chapterp chapterp; /* chapter P info */ jsend_chapterc chapterc; /* chapter C info */ jsend_chapterw chapterw; /* chapter W info */ jsend_chaptern chaptern; /* chapter N info */
} jsend_channel;
} jsend_channel;
/*******************************************************/ /* top level of hierarchy, for recovery journal header */ /*******************************************************/
typedef struct jsend_journal {
typedef struct jsend_journal {
uint8 jheader[3]; /* header Figure 8, [RFC4695] */ /* Note: Empty journal has a header */
uint32 seqnum; /* extended sequence number, or 0 */ /* seqnum = 0 codes empty journal */
jsend_channel channels[16]; /* channel journal state */ /* index is MIDI channel */
} jsend_journal;
} jsend_journal;
Figure 9. Recovery Journal Sending Structure (part 2)
図9.回復ジャーナル送信構造(パート2)
In jsend_chaptern, elements of note_tstamp[] are set to zero. In jsend_chaptern and jsend_chapterc, elements of bitfield_ptr[] are set to the null pointer index value (bitfield_ptr[] is an array whose elements point to the first octet of the note or control log associated with the array index).
jsend_chapternでは、note_tstamp []の要素がゼロに設定されています。jsend_chapternおよびjsend_chaptercでは、bitfield_ptr []の要素がnullポインターインデックス値に設定されています(bitfield_ptr []は、その要素がアレイインデックスに関連付けられたメモまたはコントロールログの最初のオクテットを指す配列です)。
Whenever an RTP packet is created (Step 3 of the algorithm defined in Figure 8), the sender traverses the RJSS to create the recovery journal for the packet. The traversal begins at the top level of the RJSS. The sender copies jheader[] into the packet and then sets the S bit of jheader[] to 1.
RTPパケットが作成されるたびに(図8で定義されているアルゴリズムのステップ3)、送信者はRJSSを横断してパケット用のRecovery Journalを作成します。トラバーサルは、RJSSの最上位レベルで始まります。送信者はjheader []をパケットにコピーし、jheader []のsビットを1に設定します。
The traversal continues depth-first, visiting every jsend_channel whose seqnum variable is non-zero. The sender copies the cheader[] array into the packet and then sets the S bit of cheader[] to 1. After each cheader[] copy, the sender visits each leaf-level chapter, in the order of its appearance in the chapter journal Table of Contents (first P, then C, then W, then N, as shown in Figure 9 of [RFC4695]).
トラバーサルは深さ第一に続き、seqnum変数がゼロではないすべてのjsend_channelを訪問します。送信者は、チーダー[]配列をパケットにコピーしてから、チーダーのビットを1に設定します。目次(最初にP、次にC、次にW、N、[RFC4695]の図9に示すように)。
If a chapter has a non-zero seqnum, the sender copies the chapter bitfield array into the packet and then sets the S bit of the RJSS array to 1. For chaptern[], the B bit is also set to 1. For the variable-length chapters (chaptern[] and chapterc[]), the sender checks the size variable to determine the bitfield length.
章にゼロ以外のseqnumがある場合、送信者はチャプタービットフィールド配列をパケットにコピーし、rjss配列のsビットを1に設定します。チャプター[]の場合、bビットは1に設定されます。 - 長さの章(Chaptern []およびChapterc [])、送信者はサイズ変数をチェックしてビットフィールドの長さを決定します。
Before copying chaptern[], the sender updates the Y bit of each note log to code the onset of the associated NoteOn command (Figure A.6.3 in [RFC4695]). To determine the Y bit value, the sender checks the note_tstamp[] array for note timing information.
After an RTP packet is sent, the sender updates the RJSS to refresh the checkpoint history (Step 5 of the sending algorithm defined in Figure 8). For each command in the MIDI list of the sent packet, the sender performs the update procedure we now describe.
RTPパケットが送信された後、送信者はRJSSを更新してチェックポイント履歴を更新します(図8で定義されている送信アルゴリズムのステップ5)。送信されたパケットのMIDIリストの各コマンドについて、送信者は今説明する更新手順を実行します。
The update procedure begins at the leaf level. The sender generates a new bitfield array for the chapter associated with the MIDI command using the chapter-specific semantics defined in Appendix A of [RFC4695].
更新手順は、葉のレベルで始まります。送信者は、[RFC4695]の付録Aで定義されている章固有のセマンティクスを使用して、MIDIコマンドに関連付けられた章の新しいビットフィールド配列を生成します。
For Chapter N and Chapter C, the sender uses the bitfield_ptr[] array to locate and update an existing log for a note or controller. If a log does not exist, the sender adds a log to the end of the chaptern[] or chapterc[] bitfield and changes the bitfield_ptr[] value to point to the log. For Chapter N, the sender also updates note_tstamp[].
NおよびChapter Cの第N章では、送信者はbitfield_ptr []配列を使用して、メモまたはコントローラーの既存のログを見つけて更新します。ログが存在しない場合、送信者はchaptern []またはchapterc [] bitfieldの最後にログを追加し、bitfield_ptr []値を変更してログを指します。第n章の場合、送信者はnote_tstamp []も更新します。
The sender also clears the S bit of the chapterp[], chapterw[], or chapterc[] bitfield. For chaptern[], the sender clears the S bit or the B bit of the bitfield, as described in Appendix A.6 of [RFC4695].
送信者はまた、Chapterp []、ChapterW []、またはChapterc [] Bitfieldのsビットをクリアします。Chaptern []の場合、送信者は、[RFC4695]の付録A.6に記載されているように、ビットフィールドのsビットまたはbビットをクリアします。
Next, the sender refreshes the upper levels of the RJSS hierarchy. At the second level, the sender updates the cheader[] bitfield of the channel associated with the command. The sender sets the S bit of cheader[] to 0. If the new command forced the addition of a new chapter or channel journal, the sender may also update other cheader[] fields. At the top level, the sender updates the top-level jheader[] bitfield in a similar manner.
次に、送信者はRJSS階層の上位レベルを再表示します。2番目のレベルでは、送信者はコマンドに関連付けられているチャンネルのチーダー[]ビットフィールドを更新します。送信者は、Cheader []のビットを0に設定します。新しいコマンドが新しい章またはチャネルジャーナルの追加を強制した場合、送信者は他のCheader []フィールドを更新することもできます。トップレベルでは、送信者は同様の方法でトップレベルのJheader [] Bitfieldを更新します。
Finally, the sender updates the seqnum variables associated with the changed bitfield arrays. The sender sets the seqnum variables to the extended sequence number of the packet.
最後に、送信者は、変更されたビットフィールド配列に関連付けられたSeqnum変数を更新します。送信者は、seqnum変数をパケットの拡張シーケンス番号に設定します。
At regular intervals, receivers send RTCP receiver reports to the sender (as described in Section 6.4.2 of [RFC3550]). These reports include the extended highest sequence number received (EHSNR) field. This field codes the highest sequence number that the receiver has observed from the sender, extended to disambiguate sequence number rollover.
定期的に、受信者はRTCPレシーバーレポートを送信者に送信します([RFC3550]のセクション6.4.2で説明されています)。これらのレポートには、拡張された最高のシーケンス数(EHSNR)フィールドが含まれます。このフィールドは、受信者が送信者から観察した最高のシーケンス番号をコードし、シーケンス番号のロールオーバーを明確にするように拡張しました。
When the sender receives an RTCP receiver report, it runs the RJSS trimming algorithm. The trimming algorithm uses the EHSNR to trim away parts of the RJSS. In this way, the algorithm reduces the size of recovery journals sent in subsequent RTP packets. The algorithm conforms to the closed-loop sending policy defined in Appendix C.2.2.2 of [RFC4695].
送信者がRTCPレシーバーレポートを受信すると、RJSSトリミングアルゴリズムが実行されます。トリミングアルゴリズムは、EHSNRを使用してRJSSの一部をトリミングします。このようにして、アルゴリズムは、後続のRTPパケットで送信された回復ジャーナルのサイズを削減します。アルゴリズムは、[RFC4695]の付録C.2.2.2で定義されている閉ループ送信ポリシーに準拠しています。
The trimming algorithm relies on the following observation: if the EHSNR indicates that a packet with sequence number K has been received, MIDI commands sent in packets with sequence numbers J <= K may be removed from the RJSS without violating the closed-loop policy.
トリミングアルゴリズムは、次の観察結果に依存しています。EHSNRがシーケンス番号kを持つパケットを受信したことを示した場合、Sequence番号J <= kのパケットで送信されたMIDIコマンドは、閉ループポリシーに違反することなくRJSSから削除される場合があります。
To begin the trimming algorithm, the sender extracts the EHSNR field from the receiver report and adjusts the EHSNR to reflect the sequence number extension prefix of the sender. Then, the sender compares the adjusted EHSNR value with seqnum fields at each level of the RJSS, starting at the top level.
トリミングアルゴリズムを開始するには、送信者はレシーバーレポートからEHSNRフィールドを抽出し、EHSNRを調整して、送信者のシーケンス番号拡張プレフィックスを反映します。次に、送信者は、調整されたEHSNR値を、RJSSの各レベルでSEQNUMフィールドと比較し、上部レベルから開始します。
Levels whose seqnum is less than or equal to the adjusted EHSNR are trimmed, by setting the seqnum to zero. If necessary, the jheader[] and cheader[] arrays above the trimmed level are adjusted to match the new journal layout. The checkpoint packet sequence number field of jheader[] is updated to match the EHSNR.
Seqnumが調整されたEHSNR以下がゼロに設定することにより、調整されたEHSNR以下のレベルがトリミングされます。必要に応じて、トリミングされたレベルの上のJheader []およびCheader []アレイは、新しいジャーナルレイアウトに合わせて調整されます。Jheader []のチェックポイントパケットシーケンス番号フィールドは、EHSNRに一致するように更新されます。
At the leaf level, the sender trims the size of the variable-length chaptern[] and chapterc[] bitfields. The sender loops through the note_seqnum[] or control_seqnum[] array and removes chaptern[] or chapterc[] logs whose seqnum value is less than or equal to the adjusted EHSNR. The sender sets the associated bitfield_ptr[] to null and updates the LENGTH field of the associated cheader[] bitfield.
葉のレベルでは、送信者は可変長のチャプター[]とchapterc []ビットフィールドのサイズをトリミングします。送信者は、note_seqnum []またはcontrol_seqnum [] arrayを介してループし、chaptern []またはchapterc []ログを削除します。送信者は、関連するbitfield_ptr []をNULLに設定し、関連するチーダー[] Bitfieldの長さフィールドを更新します。
Note that the trimming algorithm does not add information to the checkpoint history. As a consequence, the trimming algorithm does not clear the S bit (and for chaptern[], the B bit) of any recovery journal bitfield. As a second consequence, the trimming algorithm does not set RJSS seqnum variables to the EHSNR value.
トリミングアルゴリズムは、チェックポイント履歴に情報を追加しないことに注意してください。結果として、トリミングアルゴリズムは、回復ジャーナルBitfieldのSビット(およびChaptern []、bビット)をクリアしません。2番目の結果として、トリミングアルゴリズムはRJSS Seqnum変数をEHSNR値に設定しません。
For pedagogical purposes, the recovery journal sender we describe has been simplified in several ways. In practice, an implementation would use enhanced versions of the traversing, updating, and trimming algorithms presented in Sections 5.2-5.4.
教育的目的のために、私たちが説明する回復ジャーナル送信者はいくつかの方法で簡素化されています。実際には、実装では、セクション5.2〜5.4に示されているトラバース、更新、およびトリミングアルゴリズムの拡張バージョンを使用します。
In this section, we discuss receiver implementation issues.
このセクションでは、受信機の実装の問題について説明します。
To begin, we imagine that an ideal network carries the RTP stream. Packets are never lost or reordered, and the end-to-end latency is constant. In addition, we assume that all commands coded in the MIDI list of a packet share the same timestamp (an assumption coded by the "rtp_ptime" and "rtp_maxptime" values in Figures 1-2; see Appendix C.4.1 of [RFC4695] for details).
まず、理想的なネットワークがRTPストリームを運ぶと想像します。パケットが失われたり並べ替えられたりすることはなく、エンドツーエンドのレイテンシは一定です。さらに、パケットのMIDIリストにコード化されたすべてのコマンドは、同じタイムスタンプ(図1-2の「rtp_ptime」と「rtp_maxptime」値によってコードされた仮定を共有していると想定しています。[RFC4695]の付録C.4.1を参照詳細)。
Under these conditions, a simple algorithm may be used to render a high-quality performance. Upon receipt of an RTP packet, the receiver immediately executes the commands coded in the MIDI command section of the payload. Commands are executed in the order of their appearance in the MIDI list. The command timestamps are ignored.
これらの条件下では、単純なアルゴリズムを使用して高品質のパフォーマンスを提供する場合があります。RTPパケットを受け取ると、受信機はペイロードのMIDIコマンドセクションでコード化されたコマンドをすぐに実行します。コマンドは、MIDIリストに登場する順序で実行されます。コマンドタイムスタンプは無視されます。
Unfortunately, this simple algorithm breaks down once we relax our assumptions about the network and the MIDI list:
残念ながら、ネットワークとMIDIリストに関する仮定を緩和すると、この単純なアルゴリズムが分解します。
1. If we permit lost and reordered packets to occur in the network, the algorithm may produce unrecoverable rendering artifacts, violating the mandate defined in Section 4 of [RFC4695].
1.
2. If we permit the network to exhibit variable latency, the algorithm modulates the network jitter onto the rendered MIDI command stream.
2. ネットワークが可変遅延を表示できるようにすると、アルゴリズムはネットワークジッターをレンダリングされたMIDIコマンドストリームに変調します。
3. If we permit a MIDI list to code commands with different timestamps, the algorithm adds temporal jitter to the rendered performance, as it ignores MIDI list timestamps.
3. MIDIリストが異なるタイムスタンプを使用してコマンドをコードすることを許可する場合、アルゴリズムはMIDIリストタイムスタンプを無視するため、レンダリングされたパフォーマンスに一時的なジッターを追加します。
In this section, we discuss interactive receiver design techniques under these relaxed assumptions. Section 6.1 describes a receiver design for high-performance Wide Area Networks (WANs), and Section 6.2 discusses design issues for other types of networks.
このセクションでは、これらのリラックスした仮定の下でインタラクティブレシーバーの設計手法について説明します。セクション6.1では、高性能の広域ネットワーク(WAN)のレシーバー設計について説明し、セクション6.2では、他のタイプのネットワークの設計問題について説明します。
The Network Musical Performance (NMP) system [NMP] is an interactive performance application that uses an early version of the RTP MIDI payload format. NMP is designed for use between universities within the State of California, which use the high-performance CalREN2 network.
ネットワークミュージカルパフォーマンス(NMP)システム[NMP]は、RTP MIDIペイロード形式の初期バージョンを使用するインタラクティブなパフォーマンスアプリケーションです。NMPは、カリフォルニア州内の大学間で使用するように設計されており、高性能Calren2ネットワークを使用しています。
In the NMP system, network artifacts may affect how a musician hears the performances of remote players. However, the network does not affect how a musician hears his own performance.
NMPシステムでは、ネットワークアーティファクトがミュージシャンがリモートプレーヤーのパフォーマンスを聞く方法に影響を与える可能性があります。ただし、ネットワークはミュージシャンが自分のパフォーマンスをどのように聞くかに影響しません。
Several aspects of CalREN2 network behavior (as measured in 2001 timeframe, as documented in [NMP]) guided the NMP system design:
Calren2ネットワークの動作のいくつかの側面([NMP]で文書化されているように、2001年の時間枠で測定)がNMPシステムの設計を導きました。
o The median symmetric latency (1/2 the round-trip time) of packets sent between network sites is comparable to the acoustic latency between two musicians located in the same room. For example, the latency between Berkeley and Stanford is 2.1 ms, corresponding to an acoustic distance of 2.4 feet (0.72 meters). These campuses are 40 miles (64 km) apart. Preserving the benefits of the underlying network latency at the application level was a key NMP design goal.
o ネットワークサイト間で送信されたパケットの対称レイテンシの中央値(往復時間の1/2)は、同じ部屋にある2人のミュージシャン間の音響潜時に匹敵します。たとえば、バークレーとスタンフォードの間の遅延は2.1ミリ秒で、2.4フィート(0.72メートル)の音響距離に対応しています。これらのキャンパスは40マイル(64 km)離れています。アプリケーションレベルで基礎となるネットワークレイテンシの利点を維持することは、重要なNMP設計目標でした。
o For most times of day, the nominal temporal jitter is quite short. For Berkeley-Stanford, the standard deviation of the round-trip time was under 200 microseconds.
o ほとんどの場合、名目上の時間ジッターは非常に短いです。バークレー・スタンフォードの場合、往復時間の標準偏差は200マイクロ秒未満でした。
o For most times of day, a few percent (0-4%) of the packets sent arrive significantly late (> 40 ms), probably due to a queuing transient somewhere in the network path. More rarely (< 0.1%), a packet is lost during the transient.
o 1日のほとんどの場合、送信されたパケットの数パーセント(0〜4%)が、おそらくネットワークパスのどこかに一時的なキューイングが原因で、かなり遅れて(> 40ミリ秒)到着します。よりまれに(<0.1%)、一時的にパケットが失われます。
o At predictable times during the day (before lunchtime, at the end of the workday, etc.), network performance deteriorates (10-20% late packets) in a manner that makes the network unsuitable for low-latency interactive use.
o 日中の予測可能な時期(昼食前、仕事の日の終わりなど)では、ネットワークのパフォーマンスは、低遅延のインタラクティブな使用に適していない方法で、ネットワークのパフォーマンスが悪化します(10-20%遅いパケット)。
o CalREN2 has deeply over-provisioned bandwidth, relative to MIDI bandwidth usage.
o Calren2は、MIDI帯域幅の使用に比べて、深く過剰に生成された帯域幅を持っています。
The NMP sender freely uses network bandwidth to improve the performance experience. As soon as a musician generates a MIDI command, an RTP packet coding the command is sent to the other players. This sending algorithm reduces latency at the cost of bandwidth. In addition, guard packets (described in Section 4.2) are sent at frequent intervals to minimize the impact of packet loss.
NMP送信者は、ネットワーク帯域幅を自由に使用して、パフォーマンスエクスペリエンスを向上させます。ミュージシャンがMIDIコマンドを生成するとすぐに、コマンドをコーディングするRTPパケットが他のプレイヤーに送信されます。この送信アルゴリズムは、帯域幅のコストでレイテンシを削減します。さらに、パケット損失の影響を最小限に抑えるために、ガードパケット(セクション4.2で説明)が頻繁に送信されます。
The NMP receiver maintains a model of the stream and uses this model as the basis of its resiliency system. Upon receipt of a packet, the receiver predicts the RTP sequence number and the RTP timestamp (with error bars) of the packet. Under normal network conditions, about 95% of received packets fit the predictions [NMP]. In this common case, the receiver immediately executes the MIDI command coded in the packet.
NMPレシーバーは、ストリームのモデルを維持し、このモデルを回復力システムの基礎として使用します。パケットを受け取ると、受信機はパケットのRTPシーケンス番号とRTPタイムスタンプ(エラーバー付き)を予測します。通常のネットワーク条件下では、受信したパケットの約95%が予測[NMP]に適合します。この一般的なケースでは、受信機はすぐにパケットにコード化されたMIDIコマンドを実行します。
Note that the NMP receiver does not use a playout buffer; the design is optimized for lowest latency at the expense of command jitter. Thus, the NMP receiver design does not completely satisfy the interoperability text in Appendix C.7.2 of [RFC4695], which requires that receivers in network musical performance applications be capable of using a playout buffer.
NMPレシーバーはプレイアウトバッファーを使用していないことに注意してください。この設計は、コマンドジッターを犠牲にして最低のレイテンシのために最適化されています。したがって、NMPレシーバーの設計は、[RFC4695]の付録C.7.2の相互運用性テキストを完全に満たしていません。
Occasionally, an incoming packet fits the sequence number prediction, but falls outside the timestamp prediction error bars (see Appendix B of [NMP] for timestamp model details). In most cases, the receiver still executes the command coded in the packet. However, the receiver discards NoteOn commands with non-zero velocity. By discarding late commands that sound notes, the receiver prevents "straggler notes" from disturbing a performance. By executing all other late commands, the receiver quiets "soft stuck notes" immediately and updates the state of the MIDI system.
時折、着信パケットがシーケンス番号の予測に適合しますが、タイムスタンプの予測エラーバーの外側にあります(タイムスタンプモデルの詳細については[NMP]の付録Bを参照)。ほとんどの場合、受信者はパケットでコード化されたコマンドをまだ実行します。ただし、受信者はノートンコマンドを非ゼロ速度で破棄します。ノートに聞こえる後期コマンドを破棄することにより、受信者は「Straggler Notes」がパフォーマンスを乱すことを防ぎます。他のすべての後期コマンドを実行することにより、受信者は「ソフトスタックノート」をすぐに静かにし、MIDIシステムの状態を更新します。
More rarely, an incoming packet does not fit the sequence number prediction. The receiver keeps track of the highest sequence number received in the stream and predicts that an incoming packet will have a sequence number one greater than this value. If the sequence number of an incoming packet is greater than the prediction, a packet loss has occurred. If the sequence number of the received packet is less than the prediction, the packet has been received out of order. All sequence number calculations are modulo 2^16 and use standard methods (described in [RFC3550]) to avoid tracking errors during rollover.
よりまれに、着信パケットがシーケンス番号の予測に適合しません。受信機は、ストリームで受信された最高のシーケンス番号を追跡し、着信パケットがこの値よりもシーケンスナンバーワン大きいと予測します。着信パケットのシーケンス番号が予測よりも大きい場合、パケット損失が発生しました。受信したパケットのシーケンス番号が予測よりも少ない場合、パケットは順不同で受信されています。すべてのシーケンス数の計算はModulo 2^16であり、標準的な方法([RFC3550]で説明)を使用して、ロールオーバー中の追跡エラーを回避します。
If a packet loss has occurred, the receiver examines the journal section of the received packet and uses it to gracefully recover from the loss episode. We describe this recovery procedure in Section 7 of this memo. The recovery process may result in the execution of one or more MIDI commands. After executing the recovery commands, the receiver processes the MIDI command encoded in the packet using the timestamp model test described above.
パケットの損失が発生した場合、受信者は受信したパケットのジャーナルセクションを調べ、それを使用して損失エピソードから優雅に回復します。このメモのセクション7でこの回復手順について説明します。回復プロセスにより、1つ以上のMIDIコマンドが実行される場合があります。Recoveryコマンドを実行した後、受信機は上記のタイムスタンプモデルテストを使用してパケットにエンコードされたMIDIコマンドを処理します。
If a packet is received out of order, the receiver ignores the packet. The receiver takes this action because a packet received out of order is always preceded by a packet that signalled a loss event. This loss event triggered the recovery process, which may have executed recovery commands. The MIDI command coded in the out-of-order packet might, if executed, duplicate these recovery commands, and this duplication might endanger the integrity of the stream. Thus, ignoring the out-of-order packet is the safe approach.
パケットが故障していない場合、受信者はパケットを無視します。受信者は、故障したパケットの前に常に損失イベントを知らせたパケットが前に行われるため、このアクションを実行します。この損失イベントは、回復コマンドを実行した可能性のある回復プロセスを引き起こしました。オーダーアウトオブオーダーパケットでコード化されたMIDIコマンドは、実行された場合、これらの回復コマンドを複製する可能性があり、この複製はストリームの完全性を危険にさらす可能性があります。したがって、オーダーアウトパケットを無視することは安全なアプローチです。
The NMP receiver targets a network with a particular set of characteristics: low nominal jitter, low packet loss, and occasional outlier packets that arrive very late. In this section, we consider how networks with different characteristics impact receiver design.
NMPレシーバーは、特定の特性セットを備えたネットワークをターゲットにしています。公称ジッターが低い、パケット損失が低い、非常に遅く到着する場合によっては異常値のパケットです。このセクションでは、異なる特性を持つネットワークが受信機の設計にどのように影響するかを検討します。
Networks with significant nominal jitter cannot use the buffer-free receiver design described in Section 6.1. For example, the NMP system performs poorly for musicians that use dial-up modem connections, because the buffer-free receiver design modulates modem jitter onto the performances. Receivers designed for high-jitter networks should use a substantial playout buffer. References [GRAME] and [CCRMA] describe how to use playout buffers in latency-critical applications.
重要な名目ジッターを持つネットワークは、セクション6.1で説明されているバッファフリーの受信機設計を使用できません。たとえば、NMPシステムは、バッファフリーのレシーバー設計がモデムジッターをパフォーマンスに調整するため、ダイヤルアップモデム接続を使用するミュージシャンではパフォーマンスが低下します。高ジッターネットワーク向けに設計されたレシーバーは、かなりのプレイアウトバッファーを使用する必要があります。参考文献[Grame]および[CCRMA]は、レイテンシクリティカルなアプリケーションでプレイアウトバッファーの使用方法を説明しています。
Receivers intended for use on Local Area Networks (LANs) face a different set of issues. A dedicated LAN fabric built with modern hardware is in many ways a predictable environment. The network problems addressed by the NMP receiver design (packet loss and outlier late packets) might only occur under extreme network overload conditions.
ローカルエリアネットワーク(LANS)での使用を目的としたレシーバーは、さまざまな問題に直面しています。最新のハードウェアで構築された専用のLANファブリックは、多くの点で予測可能な環境です。NMP受信機の設計(パケット損失と外れ値パケット)によって対処されるネットワークの問題は、極端なネットワーク過負荷条件下でのみ発生する可能性があります。
Systems designed for this environment may choose to configure streams without the recovery journal system (Appendix C.2.1 of [RFC4695]). Receivers may also wish to forego or simplify the detection of outlier late packets. Receivers should monitor the RTP sequence numbers of incoming packets to detect network unreliability.
この環境向けに設計されたシステムは、回復ジャーナルシステムなしでストリームを構成することを選択できます([RFC4695]の付録C.2.1)。受信者は、外れ値の後期パケットの検出を控えたり、簡素化することもできます。受信機は、ネットワークの信頼性を検出するために、着信パケットのRTPシーケンス番号を監視する必要があります。
However, in some respects, LAN applications may be more demanding than WAN applications. In LAN applications, musicians may be receiving performance feedback from audio that is rendered from the stream. The tolerance a musician has for latency and jitter in this context may be quite low.
ただし、いくつかの点では、LANアプリケーションはWANアプリケーションよりも厳しい場合があります。LANアプリケーションでは、ミュージシャンがストリームからレンダリングされるオーディオからパフォーマンスフィードバックを受け取っている可能性があります。この文脈での潜時とジッターのためにミュージシャンが持っている耐性は非常に低いかもしれません。
To reduce the perceived jitter, receivers may use a small playout buffer (in the range of 100us to 2ms). The buffer adds a small amount of latency to the system, which may be annoying to some players. Receiver designs should include buffer tuning parameters to let musicians adjust the tradeoff between latency and jitter.
知覚されたジッターを減らすために、レシーバーは小さなプレイアウトバッファーを使用する場合があります(100US〜2msの範囲)。バッファは、システムに少量のレイテンシを追加します。これは、一部のプレイヤーにとって迷惑な場合があります。レシーバーの設計には、ミュージシャンがレイテンシとジッターの間のトレードオフを調整できるようにするためのバッファチューニングパラメーターを含める必要があります。
In this section, we describe the recovery algorithm used by the NMP receiver [NMP]. In most ways, the recovery techniques we describe are generally applicable to interactive receiver design. However, a few aspects of the design are specialized for the NMP system:
このセクションでは、NMP受信機[NMP]で使用される回復アルゴリズムについて説明します。ほとんどの点で、私たちが説明する回復手法は、一般的にインタラクティブレシーバーの設計に適用されます。ただし、設計のいくつかの側面は、NMPシステムに特化しています。
o The recovery algorithm covers a subset of the MIDI command set. MIDI Systems (0xF), Poly Aftertouch (0xA), and Channel Aftertouch (0xD) commands are not protected, and Control Change (0xB) command protection is simplified. Note commands for a particular note number are assumed to follow the typical NoteOn->NoteOff->NoteOn ->NoteOff pattern. The cm_unused and ch_never parameters in Figures 1-2 specify this coverage.
o 回復アルゴリズムは、MIDIコマンドセットのサブセットをカバーします。MIDI Systems(0xF)、Poly AfterTouch(0xA)、およびChannel Aftouch(0xD)コマンドは保護されておらず、Control Change(0xB)コマンド保護が簡素化されます。特定のノート番号の注コマンドは、典型的なNoteOn-> NoteOff-> NoteOn-> NoteOffパターンに従うと想定されます。図1-2のCM_UNUSEDおよびCH_NEVERパラメーターは、このカバレッジを指定します。
o The NMP system does not use a playout buffer. Therefore, the recovery algorithm does not address interactions with a playout buffer.
o NMPシステムは、プレイアウトバッファーを使用しません。したがって、回復アルゴリズムは、プレイアウトバッファーとの相互作用に対処しません。
At a high level, the receiver algorithm works as follows. Upon detection of a packet loss, the receiver examines the recovery journal of the packet that ends the loss event. If necessary, the receiver executes one or more MIDI commands to recover from the loss.
高いレベルでは、受信機アルゴリズムは次のように機能します。パケット損失を検出すると、受信者は損失イベントを終了するパケットの回復ジャーナルを調べます。必要に応じて、レシーバーは1つ以上のMIDIコマンドを実行して、損失から回復します。
To prepare for recovery, a receiver maintains a data structure, the Recovery Journal Receiver Structure (RJRS). The RJRS codes information about the MIDI commands the receiver executes (both incoming stream commands and self-generated recovery commands). At the start of the stream, the RJRS is initialized to code that no commands have been executed. Immediately after executing a MIDI command, the receiver updates the RJRS with information about the command.
回復の準備をするために、受信者はデータ構造であるRecovery Journal Receiver構造(RJRS)を維持します。RJRSは、受信者が実行するMIDIコマンドに関する情報をコードします(受信ストリームコマンドと自己生成された回復コマンドの両方)。ストリームの開始時に、RJRSはコマンドが実行されていないというコードに初期化されます。MIDIコマンドを実行した直後に、受信者はコマンドに関する情報を使用してRJRを更新します。
We now describe the recovery algorithm in detail. We begin with two definitions that classify loss events. These definitions assume that the packet that ends the loss event has RTP sequence number I.
次に、回復アルゴリズムについて詳しく説明します。損失イベントを分類する2つの定義から始めます。これらの定義では、損失イベントを終了するパケットにはRTPシーケンス番号Iがあると想定しています。
o Single-packet loss. A single-packet loss occurs if the last packet received before the loss event (excluding out-of-order packets) has the sequence number I-2 (modulo 2^16).
o シングルパケット損失。損失イベントの前に受信した最後のパケット(オーダーアウトオブオーダーパケットを除く)にシーケンス番号I-2(Modulo 2^16)がある場合、単一パケットの損失が発生します。
o Multi-packet loss. A multi-packet loss occurs if the last packet received before the loss event (excluding out-of-order packets) has a sequence number less than I-2 (modulo 2^16).
o マルチパケット損失。損失イベントの前に受信した最後のパケット(注文外のパケットを除く)がI-2未満のシーケンス番号を持っている場合、マルチパケットの損失が発生します(Modulo 2^16)。
Upon detection of a packet loss, the recovery algorithm examines the recovery journal header (Figure 8 of [RFC4695]) to check for special cases:
パケット損失を検出すると、回復アルゴリズムは回復ジャーナルヘッダー([RFC4695]の図8)を調べて、特別なケースを確認します。
o If the header field A is 0, the recovery journal has no channel journals, so no action is taken.
o ヘッダーフィールドAが0の場合、Recovery Journalにはチャネルジャーナルがないため、アクションは実行されません。
o If a single-packet loss has occurred, and if the header S bit is 1, the lost packet has a MIDI command section with an empty MIDI list. No action is taken.
o 単一パケットの損失が発生し、ヘッダーのビットが1の場合、Lost Packetには空のMIDIリストがあるMIDIコマンドセクションがあります。アクションは行われません。
If these checks fail, the algorithm parses the recovery journal body. For each channel journal (Figure 9 in [RFC4695]) in the recovery journal, the receiver compares the data in each chapter journal (Appendix A of [RFC4695]) to the RJRS data for the chapter. If the data are inconsistent, the algorithm infers that MIDI commands related to the chapter journal have been lost. The recovery algorithm executes MIDI commands to repair this loss and updates the RJRS to reflect the repair.
これらのチェックが失敗した場合、アルゴリズムは回復ジャーナルボディを解析します。Recovery Journalの各チャネルジャーナル([RFC4695]の図9)について、受信者は各章ジャーナル([RFC4695]の付録A)のデータを章のRJRSデータと比較します。データが一貫していない場合、アルゴリズムは、チャプタージャーナルに関連するMIDIコマンドが失われていることを推測します。回復アルゴリズムはMIDIコマンドを実行してこの損失を修復し、RJRを更新して修理を反映します。
For single-packet losses, the receiver skips channel and chapter journals whose S bits are set to 1. For multi-packet losses, the receiver parses each channel and chapter journal and checks for inconsistency.
シングルパケットの損失の場合、受信者は、Sビットが1に設定されているチャンネルとチャプタージャーナルをスキップします。マルチパケット損失の場合、受信機は各チャネルと章のジャーナルを解析し、矛盾をチェックします。
In the sections that follow, we describe the recovery steps that are specific to each chapter journal. We cover 4 chapter journal types: P (Program Change, 0xC), C (Control Change, 0xB), W (Pitch Wheel, 0xE), and N (Note, 0x8 and 0x9). Chapters are parsed in the order of their appearance in the channel journal (P, then W, then N, then C).
以下のセクションでは、各チャプタージャーナルに固有の回復手順について説明します。4章のジャーナルタイプをカバーします:P(プログラム変更、0xc)、C(コントロール変更、0xb)、W(ピッチホイール、0xe)、およびN(注、0x8および0x9)。章は、チャンネルジャーナル(P、W、n、c)に登場する順に解析されます。
The sections below reference the C implementation of the RJRS shown in Figure 10. This structure is hierarchical, reflecting the recovery journal architecture. At the leaf level, specialized data structures (jrec_chapterw, jrec_chaptern, jrec_chapterc, and jrec_chapterp) code state variables for a single chapter journal type. A mid-level structure (jrec_channel) represents a single MIDI channel, and a top-level structure (jrec_stream) represents the entire MIDI stream.
以下のセクションは、図10に示すRJRのC実装を参照してください。この構造は、Recovery Journalアーキテクチャを反映した階層的です。リーフレベルでは、特殊なデータ構造(JREC_CHAPTERW、JREC_CHAPTERN、JREC_CHAPTERC、およびJREC_CHAPTERP)コード状態変数1つの章ジャーナルタイプの状態変数。中レベルの構造(JREC_CHANNEL)は単一のMIDIチャネルを表し、トップレベルの構造(JREC_STREAM)はMIDIストリーム全体を表します。
typedef unsigned char uint8; /* must be 1 octet */ typedef unsigned short uint16; /* must be 2 octets */ typedef unsigned long uint32; /* must be 4 octets */
/*****************************************************************/ /* leaf level of hierarchy: Chapter W, Appendix A.5 of [RFC4695] */ /*****************************************************************/
typedef struct jrec_chapterw { /* MIDI Pitch Wheel (0xE) */
uint16 val; /* most recent 14-bit wheel value */
} jrec_chapterw;
} JREC_CHAPTERW;
/*****************************************************************/ /* leaf level of hierarchy: Chapter N, Appendix A.6 of [RFC4695] */ /*****************************************************************/
typedef struct jrec_chaptern { /* Note commands (0x8, 0x9) */
/* arrays of length 128 --> one for each MIDI Note number */
uint32 time[128]; /* exec time of most recent NoteOn */ uint32 extseq[128]; /* extended seqnum for that NoteOn */ uint8 vel[128]; /* NoteOn velocity (0 for NoteOff) */
} jrec_chaptern;
} JREC_CHAPTERN;
/*****************************************************************/ /* leaf level of hierarchy: Chapter C, Appendix A.3 of [RFC4695] */ /*****************************************************************/
typedef struct jrec_chapterc { /* Control Change (0xB) */
/* array of length 128 --> one for each controller number */
uint8 value[128]; /* Chapter C value tool state */ uint8 count[128]; /* Chapter C count tool state */ uint8 toggle[128]; /* Chapter C toggle tool state */
} jrec_chapterc;
} JREC_CHAPTERC;
Figure 10. Recovery Journal Receiving Structure (part 1)
図10.回復ジャーナルの受信構造(パート1)
/*****************************************************************/ /* leaf level of hierarchy: Chapter P, Appendix A.2 of [RFC4695] */ /*****************************************************************/
typedef struct jrec_chapterp { /* MIDI Program Change (0xC) */
uint8 prognum; /* most recent 7-bit program value */ uint8 prognum_qual; /* 1 once first 0xC command arrives */
uint8 bank_msb; /* most recent Bank Select MSB value */ uint8 bank_msb_qual; /* 1 once first 0xBn 0x00 arrives */
uint8 bank_lsb; /* most recent Bank Select LSB value */ uint8 bank_lsb_qual; /* 1 once first 0xBn 0x20 arrives */
} jrec_chapterp;
} JREC_CHAPTERP;
/***************************************************/ /* second-level of hierarchy, for MIDI channels */ /***************************************************/
typedef struct jrec_channel {
typedef struct jrec_channel {
jrec_chapterp chapterp; /* Program Change (0xC) info */ jrec_chapterc chapterc; /* Control Change (0xB) info */ jrec_chapterw chapterw; /* Pitch Wheel (0xE) info */ jrec_chaptern chaptern; /* Note (0x8, 0x9) info */
} jrec_channel;
} JREC_CHANNEL;
/***********************************************/ /* top level of hierarchy, for the MIDI stream */ /***********************************************/
typedef struct jrec_stream {
jrec_channel channels[16]; /* index is MIDI channel */
} jrec_stream;
} JREC_STREAM;
Figure 10. Recovery Journal Receiving Structure (part 2)
図10.回復ジャーナルの受信構造(パート2)
Chapter W of the recovery journal protects against the loss of MIDI Pitch Wheel (0xE) commands. A common use of the Pitch Wheel command is to transmit the current position of a rotary "pitch wheel" controller placed on the side of MIDI piano controllers. Players use the pitch wheel to dynamically alter the pitch of all depressed keys.
Recovery Journalの章Wは、MIDIピッチホイール(0xE)コマンドの喪失から保護しています。ピッチホイールコマンドの一般的な使用は、MIDIピアノコントローラーの側面に配置されたロータリー「ピッチホイール」コントローラーの現在の位置を送信することです。プレイヤーはピッチホイールを使用して、すべての落ち込んだキーのピッチを動的に変更します。
The NMP receiver maintains the jrec_chapterw structure (Figure 10) for each voice channel in jrec_stream to code pitch wheel state information. In jrec_chapterw, val holds the 14-bit data value of the most recent Pitch Wheel command that has arrived on a channel. At the start of the stream, val is initialized to the default pitch wheel value (0x2000).
NMPレシーバーは、JREC_STREAMの各音声チャネルのJREC_CHAPTERW構造(図10)を維持し、ホイールの状態情報をコードします。JREC_CHAPTERWでは、Valはチャネルに到着した最新のピッチホイールコマンドの14ビットデータ値を保持しています。ストリームの開始時に、VALはデフォルトのピッチホイール値(0x2000)に初期化されます。
At the end of a loss event, a receiver may find a Chapter W (Appendix A.5 in [RFC4695]) bitfield in a channel journal. This chapter codes the 14-bit data value of the most recent MIDI Pitch Wheel command in the checkpoint history. If the Chapter W and jrec_chapterw pitch wheel values do not match, one or more commands have been lost.
損失イベントの終わりに、受信者はチャンネルジャーナルにbitfieldの章w([RFC4695]の付録A.5)を見つけることができます。この章では、チェックポイント履歴における最新のMIDIピッチホイールコマンドの14ビットデータ値をコードします。章wとjrec_chapterwピッチホイールの値が一致しない場合、1つ以上のコマンドが失われました。
To recover from this loss, the NMP receiver immediately executes a MIDI Pitch Wheel command on the channel, using the data value coded in the recovery journal. The receiver then updates the jrec_chapterw variables to reflect the executed command.
Chapter N of the recovery journal protects against the loss of MIDI NoteOn (0x9) and NoteOff (0x8) commands. If a NoteOn command is lost, a note is skipped. If a NoteOff command is lost, a note may sound indefinitely. Recall that NoteOn commands with a velocity value of 0 have the semantics of NoteOff commands.
The recovery algorithms in this section only work for MIDI sources that produce NoteOn->NoteOff->NoteOn->NoteOff patterns for a note number. Piano keyboard and drum pad controllers produce these patterns. MIDI sources that use NoteOn->NoteOn->NoteOff->NoteOff patterns for legato repeated notes, such as guitar and wind controllers, require more sophisticated recovery strategies. Chapter E (not used in this example) supports recovery algorithms for atypical note command patterns (see Appendix A.7 of [RFC4695] for details).
このセクションの回復アルゴリズムは、Noteon-> noteOff-> NoteOn->ノート番号のノートオフパターンを生成するMIDIソースでのみ機能します。ピアノキーボードとドラムパッドコントローラーは、これらのパターンを生成します。NoteOn-> NoteOn-> NoteOff-> GuitarやWind ControllersなどのLegatoのノートオフパターンを使用するMIDIソースには、より洗練された回復戦略が必要です。第E章(この例では使用されていません)は、非定型ノートコマンドパターンの回復アルゴリズムをサポートしています(詳細については、[RFC4695]の付録A.7を参照)。
The NMP receiver maintains a jrec_chaptern structure (Figure 10) for each voice channel in jrec_stream to code note-related state information. State is kept for each of the 128 note numbers on a channel, using three arrays of length 128 (vel[], seq[], and time[]). The arrays are initialized to zero at the start of a stream.
NMPレシーバーは、JREC_STREAMの各音声チャネルのJREC_CHAPTERN構造(図10)を維持し、ノート関連状態情報をコードします。状態は、長さ128(Vel []、Seq []、およびTime [])の3つの配列を使用して、チャネル上の128ノート番号のそれぞれに保持されます。配列は、ストリームの開始時にゼロに初期化されます。
The vel[n] array element holds information about the most recent note command for note number n. If this command is a NoteOn command, vel[n] holds the velocity data for the command. If this command is a NoteOff command, vel[n] is set to 0.
Vel [n]配列要素は、ノート番号nの最新のメモコマンドに関する情報を保持します。このコマンドがNoteonコマンドである場合、Vel [n]はコマンドの速度データを保持します。このコマンドがノートオフコマンドの場合、vel [n]が0に設定されています。
The time[n] and extseq[n] array elements code information about the most recently executed NoteOn command. The time[n] element holds the execution time of the command, referenced to the local timebase of the receiver. The extseq[n] element holds the RTP extended sequence number of the packet associated with the command. For incoming stream commands, extseq[n] codes the packet of the associated MIDI list. For commands executed to perform loss recovery, extseq[n] codes the packet of the associated recovery journal.
Time [n]およびextseq [n]配列要素は、最近実行されたNoteonコマンドに関する情報をコードします。時間[n]要素は、レシーバーのローカルタイムベースを参照するコマンドの実行時間を保持します。extseq [n]要素は、コマンドに関連付けられたパケットのRTP拡張シーケンス番号を保持します。着信ストリームコマンドの場合、extseq [n]は、関連するMIDIリストのパケットをコードします。損失回収を実行するために実行されたコマンドの場合、extseq [n]は関連するリカバリジャーナルのパケットをコードします。
The Chapter N recovery journal bitfield (Figure A.6.1 in [RFC4695]) consists of two data structures: a bit array coding recently sent NoteOff commands that are vulnerable to packet loss, and a note log list coding recently sent NoteOn commands that are vulnerable to packet loss.
章n回復ジャーナルBitfield([RFC4695]の図A.6.1)は2つのデータ構造で構成されています。最近、パケット損失に対して脆弱なメモのコマンドを最近送信し、最近脆弱なノートログリストコーディングが最近送信されたノートリストコーディングパケット損失に。
At the end of a loss event, Chapter N recovery processing begins with the NoteOff bit array. For each set bit in the array, the receiver checks the corresponding vel[n] element in jrec_chaptern. If vel[n] is non-zero, a NoteOff command or a NoteOff->NoteOn->NoteOff command sequence has been lost. To recover from this loss, the receiver immediately executes a NoteOff command for the note number on the channel and sets vel[n] to 0.
損失イベントの終わりに、第n回復処理はノートオフビットアレイから始まります。配列内の各セットビットについて、受信者はJREC_CHAPTERNの対応するVEL [n]要素をチェックします。Vel [n]がゼロ以外の場合、ノートオフコマンドまたはノートオフ - > noteOn->ノートオフコマンドシーケンスが失われました。この損失から回復するために、受信者はすぐにチャネル上のメモ番号のメモオフコマンドを実行し、VEL [n]を0に設定します。
The receiver then parses the note log list, using the S bit to skip over "safe" logs in the single-packet loss case. For each at-risk note log, the receiver checks the corresponding vel[n] element.
その後、受信者はノートログリストを解析し、Sビットを使用して、シングルパケット損失ケースの「安全な」ログをスキップします。リスクのあるノートログごとに、受信機は対応するVEL [n]要素をチェックします。
If vel[n] is zero, a NoteOn command or a NoteOn->NoteOff->NoteOn command sequence has been lost. The receiver may execute the most recent lost NoteOn (to play the note) or may take no action (to skip the note), based on criteria we describe at the end of this section. Whether the note is played or skipped, the receiver updates the vel[n], time[n], and extseq[n] elements as if the NoteOn executed.
If vel[n] is non-zero, the receiver performs several checks to test if a NoteOff->NoteOn sequence has been lost.
Vel [n]がゼロ以外の場合、受信者はいくつかのチェックを実行して、Noteoff-> Noteonシーケンスが失われたかどうかをテストします。
o If vel[n] does not match the note log velocity, the note log must code a different NoteOn command, and thus a NoteOff->NoteOn sequence has been lost.
o Vel [n]がノートログ速度と一致しない場合、Noteログは別のNoteonコマンドをコーディングする必要があるため、NoteOff-> Noteonシーケンスが失われました。
o If extseq[n] is less than the (extended) checkpoint packet sequence numbed coded in the recovery journal header (Figure 8 of [RFC4695]), the vel[n] NoteOn command is not in the checkpoint history, and thus a NoteOff->NoteOn sequence has been lost.
o extseq [n]が(拡張)チェックポイントパケットシーケンスが回復ジャーナルヘッダー([rfc4695]の図8)でコード化されたナマニの麻痺したものよりも少ない場合、vel [n] noteonコマンドはチェックポイント履歴ではなく、したがってノートオフ - > Noteonシーケンスが失われました。
o If the Y bit is set to 1, the NoteOn is musically "simultaneous" with the RTP timestamp of the packet. If time[n] codes a time value that is clearly not recent, a NoteOff->NoteOn sequence has been lost.
o yビットが1に設定されている場合、ノートンはパケットのRTPタイムスタンプと音楽的に「同時」です。時間[n]が明らかに最近ではない時間値をコードする場合、NoteOff-> Noteonシーケンスが失われました。
If these tests indicate a lost NoteOff->NoteOn sequence, the receiver immediately executes a NoteOff command. The receiver decides if the most graceful action is to play or to skip the lost NoteOn, using the criteria we describe at the end of this section. Whether or not the receiver issues a NoteOn command, the vel[n], time[n], and extseq[n] arrays are updated as if it did.
これらのテストが紛失したノートオフ - >ノートンシーケンスを示している場合、受信者はすぐにノートオフコマンドを実行します。受信者は、このセクションの最後に記述する基準を使用して、最も優雅なアクションがプレイするか、失われたノートをスキップすることであるかどうかを決定します。受信機がNoteonコマンドを発行するかどうか、Vel [n]、time [n]、およびextseq [n]アレイがあたかも更新されます。
Note that the tests above do not catch all lost NoteOff->NoteOn commands. If a fast NoteOn->NoteOff->NoteOn sequence occurs on a note number with identical velocity values for both NoteOn commands, a lost NoteOff->NoteOn does not result in the recovery algorithm generating a NoteOff command. Instead, the first NoteOn continues to sound, to be terminated by the future NoteOff command. In practice, this (rare) outcome is not musically objectionable.
上記のテストは、すべての紛失したノートオフ - >ノートンコマンドをキャッチしないことに注意してください。高速NoteOn-> NoteOff-> NoteOnシーケンスが両方のNoteONコマンドの同一の速度値を持つノート番号で発生した場合、NoteOff-> NoteOnはノートオフコマンドを生成する回復アルゴリズムになりません。代わりに、最初のNoteonは、将来のNoteoffコマンドによって終了するために、引き続き鳴り続けています。実際には、この(まれな)結果は音楽的に好意的ではありません。
The number of tests in this resiliency algorithm may seem excessive. However, in some common cases, a subset of the tests is not useful. For example, MIDI streams that assigns the same velocity value to all note events are often produced by inexpensive keyboards. The vel[n] tests are not useful for these streams.
この回復力のあるアルゴリズムのテストの数は、過度に見えるかもしれません。ただし、いくつかの一般的な場合、テストのサブセットは役に立ちません。たとえば、すべてのノートイベントに同じ速度値を割り当てるMIDIストリームは、多くの場合、安価なキーボードによって生成されます。Vel [n]テストは、これらのストリームには役に立ちません。
Finally, we discuss how the receiver decides whether to play or to skip a lost NoteOn command. The note log Y bit is set if the NoteOn is "simultaneous" with the RTP timestamp of the packet holding the note log. If Y is 0, the receiver does not execute a NoteOn command. If Y is 1, and if the packet has not arrived late, the receiver immediately executes a NoteOn command for the note number, using the velocity coded in the note log.
最後に、レシーバーがどのようにプレイするかを決定するか、失われたノートンコマンドをスキップするかについて説明します。ノートンがノートログを保持しているパケットのRTPタイムスタンプと「同時」である場合、ノートログyビットが設定されます。yが0の場合、受信機はNoteonコマンドを実行しません。yが1で、パケットが遅れて到着していない場合、受信機はメモログにコード化された速度を使用して、メモ番号のNoteonコマンドをすぐに実行します。
Chapter C (Appendix A.3 in [RFC4695]) protects against the loss of MIDI Control Change commands. A Control Change command alters the 7-bit value of one of the 128 MIDI controllers.
Chapter C([RFC4695]の付録A.3)は、MIDI制御チェンジコマンドの喪失から保護しています。コントロールチェンジコマンドは、128のMIDIコントローラーの1つの7ビット値を変更します。
Chapter C offers three tools for protecting a Control Change command: the value tool (for graded controllers such as sliders), the toggle tool (for on/off switches), and the count tool (for momentary-contact switches). Senders choose a tool to encode recovery information for a controller and encode the tool type along with the data in the journal (Figures A.3.2 and A.3.3 in [RFC4695]).
第C章では、コントロールチェンジコマンドを保護するための3つのツールを提供します。バリューツール(スライダーなどの段階的コントローラー用)、トグルツール(オン/オフスイッチ用)、およびカウントツール(Momentary-Contactスイッチ用)。送信者は、コントローラーの回復情報をエンコードするツールを選択し、ジャーナルのデータとともにツールタイプをエンコードします([RFC4695]の図A.3.2およびA.3.3)。
A few uses of Control Change commands are not solely protected by Chapter C. The protection of controllers 0 and 32 (Bank Select MSB and Bank Select LSB) is shared between Chapter C and Chapter P (Section 7.4).
Chapter M (Appendix A.4 of [RFC4695]) also protects the Control Change command. However, the NMP system does not use this chapter, because MPEG 4 Structured Audio [MPEGSA] does not use the controllers protected by this chapter.
第M章([RFC4695]の付録A.4)は、制御変更コマンドも保護します。ただし、NMPシステムはこの章を使用していません。なぜなら、MPEG 4 Structured Audio [MPEGSA]はこの章で保護されているコントローラーを使用していないためです。
The Chapter C bitfield consists of a list of controller logs. Each log codes the controller number, the tool type, and the state value for the tool.
Chapter C Bitfieldは、コントローラーログのリストで構成されています。各ログは、コントローラー番号、ツールタイプ、およびツールの状態値をコーディングします。
The NMP receiver maintains the jrec_chapterc structure (Figure 10) for each voice channel in jrec_stream to code Control Change state information. The value[] array holds the most recent data values for each controller number. At the start of the stream, value[] is initialized to the default controller data values specified in [MPEGSA].
NMPレシーバーは、jREC_STREAMの各音声チャネルのJREC_CHAPTERC構造(図10)を維持し、CODER CONTROLT状態情報をコードします。値[]配列は、各コントローラー番号の最新のデータ値を保持します。ストリームの開始時に、値[]は[MPEGSA]で指定されたデフォルトのコントローラーデータ値に初期化されます。
The count[] and toggle[] arrays hold the count tool and toggle tool state values. At the start of a stream, these arrays are initialized to zero. Whenever a Control Command executes, the receiver updates the count[] and toggle[] state values, using the algorithms defined in Appendix A.3 of [RFC4695].
count []とトグル[]アレイは、カウントツールを保持し、ツールの状態値を切り替えます。ストリームの開始時に、これらの配列はゼロに初期化されます。コントロールコマンドが実行されるたびに、受信機は[RFC4695]の付録A.3で定義されているアルゴリズムを使用して、カウント[]と状態値をトグル[]を更新します。
At the end of a loss event, the receiver parses the Chapter C controller log list, using the S bit to skip over "safe" logs in the single-packet loss case. For each at-risk controller number n, the receiver determines the tool type in use (value, toggle, or count) and compares the data in the log to the associated jrec_chapterc array element (value[n], toggle[n], or count[n]). If the data do not match, one or more Control Change commands have been lost.
損失イベントの終わりに、受信機はSビットを使用してシングルパケット損失ケースの「安全な」ログをスキップして、Cコントローラーのログリストを解析します。各リスクのコントローラー番号nごとに、受信機は使用中のツールタイプ(値、トグル、またはカウント)を決定し、ログのデータを関連するJREC_CHAPTERCアレイ要素(値[n]、トグル[n]、またはcount [n])。データが一致しない場合、1つ以上の制御変更コマンドが失われました。
The method the receiver uses to recover from this loss depends on the tool type and the controller number. For graded controllers protected by the value tool, the receiver executes a Control Change command using the new data value.
受信機がこの損失から回復するために使用する方法は、ツールタイプとコントローラー番号によって異なります。値ツールによって保護されている段階的なコントローラーの場合、受信機は新しいデータ値を使用してコントロール変更コマンドを実行します。
For the toggle and count tools, the recovery action is more complex. For example, the Damper Pedal (Sustain) controller (number 64) is typically used as a sustain pedal for piano-like sounds and is typically coded using the toggle tool. If Damper Pedal (Sustain) Control Change commands are lost, the receiver takes different actions depending on the starting and ending state of the lost sequence, to ensure that "ringing" piano notes are "damped" to silence.
トグルおよびカウントツールの場合、回復アクションはより複雑です。たとえば、ダンパーペダル(Sustain)コントローラー(ナンバー64)は通常、ピアノのようなサウンドのサステインペダルとして使用され、通常、トグルツールを使用してコード化されます。ダンパーペダル(サステイン)制御チェンジコマンドが失われた場合、レシーバーは失われたシーケンスの開始状態と終了状態に応じて異なるアクションを実行し、「リンギング」ピアノノートが沈黙するために「減衰」されるようにします。
After recovering from the loss, the receiver updates the value[], toggle[], and count[] arrays to reflect the Chapter C data and the executed commands.
損失から回復した後、受信者は値[]、トグル[]、および[]アレイをカウントして、Chapter Cデータと実行されたコマンドを反映します。
Chapter P of the recovery journal protects against the loss of MIDI Program Change (0xC) commands.
Recovery Journalの章Pは、MIDIプログラムの変更(0xc)コマンドの喪失から保護しています。
The 7-bit data value of the Program Change command selects one of 128 possible timbres for the channel. To increase the number of possible timbres, Control Change (0xB) commands may be issued prior to the Program Change command to select a "program bank". The Bank Select MSB (number 0) and Bank Select LSB (number 32) controllers specify the 14-bit bank number that subsequent Program Change commands reference.
プログラム変更コマンドの7ビットデータ値は、チャネルの128の可能な音色のいずれかを選択します。考えられる音色の数を増やすために、「プログラムバンク」を選択するために、プログラム変更コマンドの前にコントロール変更(0xB)コマンドが発行される場合があります。銀行の選択MSB(番号0)および銀行選択LSB(番号32)コントローラーは、その後のプログラム変更コマンドリファレンスを指定します。
The NMP receiver maintains the jrec_chapterp structure (Figure 10) for each voice channel in jrec_stream to code Program Change state information.
NMP Receiverは、jREC_STREAMの各音声チャネルのJREC_CHAPTERP構造(図10)をコードプログラム変更状態情報の変更に維持します。
The prognum variable of jrec_chapterp holds the data value for the most recent Program Change command that has arrived on the stream. The bank_msb and bank_lsb variables of jrec_chapterp code the Bank Select MSB and Bank Select LSB controller data values that were in effect when that Program Change command arrived. The prognum_qual, bank_msb_qual, and bank_lsb_qual variables are initialized to 0 and are set to 1 to qualify the associated data values.
JREC_CHAPTERPのPrognum変数は、ストリームに到着した最新のプログラム変更コマンドのデータ値を保持します。JREC_CHAPTERPコードのbank_msbおよびbank_lsb変数銀行は、そのプログラム変更コマンドが到着したときに有効であったMSBおよび銀行を選択するLSBコントローラーデータ値を選択します。Prognum_Qual、bank_msb_qual、およびbank_lsb_qual変数は0に初期化され、関連するデータ値を修飾するために1に設定されます。
Chapter P fields code the data value for the most recent Program Change command, and the MSB and LSB bank values in effect for that command.
第P章フィールドは、最新のプログラム変更コマンドのデータ値をコードし、そのコマンドのMSBおよびLSB銀行の値を有効にします。
At the end of a loss event, the receiver checks Chapter P to see if the recovery journal fields match the data stored in jrec_chapterp. If these checks fail, one or more Program Change commands have been lost.
損失イベントの終わりに、受信者は第P章をチェックして、Recovery JournalフィールドがJREC_Chapterpに保存されているデータと一致するかどうかを確認します。これらのチェックが失敗した場合、1つ以上のプログラム変更コマンドが失われました。
To recover from this loss, the receiver takes the following steps. If the B bit in Chapter P is set (Figure A.2.1 in [RFC4695]), Control Change bank commands have preceded the Program Change command. The receiver compares the bank data coded by Chapter P with the current bank data for the channel (coded in jrec_channelc).
この損失から回復するために、受信者は次の手順を実行します。第P章のBビットが設定されている場合([RFC4695]の図A.2.1)、Control Change Bank Commandsはプログラム変更コマンドの前にあります。受信機は、チャプターPでコード化された銀行データをチャネルの現在の銀行データ(jREC_CHANNELCでコード化)と比較します。
If the bank data do not agree, the receiver issues Control Change commands to align the stream with Chapter P. The receiver then updates jrec_channelp and jrec_channelc variables to reflect the executed command(s). Finally, the receiver issues a Program Change command that reflects the data in Chapter P and updates the prognum and qual_prognum fields in jrec_channelp.
銀行のデータが同意しない場合、受信者はControl Control CommandコマンドをChapter Pに整列させ、受信機がJREC_CHANNELPおよびJREC_CHANNELC変数を更新して、実行されたコマンドを反映します。最後に、受信者は、第P章のデータを反映したプログラム変更コマンドを発行し、jrec_channelpのPrognumおよびQual_Prognumフィールドを更新します。
Note that this method relies on Chapter P recovery to precede Chapter C recovery during channel journal processing. This ordering ensures that lost Bank Select Control Change commands that occur after a lost Program Change command in a stream are handled correctly.
この方法は、チャンネルジャーナル処理中の第C章の回復の前に、第P章の回復に依存していることに注意してください。この順序により、失われた銀行選択コントロール変更コマンドが、ストリーム内の失われたプログラム変更コマンドが正しく処理されることが保証されます。
Security considerations for the RTP MIDI payload format are discussed in the Security Considerations section of [RFC4695].
RTP MIDIペイロード形式のセキュリティ上の考慮事項については、[RFC4695]のセキュリティに関する考慮事項セクションで説明しています。
IANA considerations for the RTP MIDI payload format are discussed in the IANA Considerations section of [RFC4695].
RTP MIDIペイロード形式に関するIANAの考慮事項については、[RFC4695]のIANA考慮事項セクションで説明しています。
This memo was written in conjunction with [RFC4695], and the Acknowledgements section of [RFC4695] also applies to this memo.
このメモは[RFC4695]と併せて書かれており、[RFC4695]の謝辞セクションもこのメモに適用されます。
[RFC4695] Lazzaro, J. and J. Wawrzynek, "RTP Payload Format for MIDI", RFC 4695, November 2006.
[RFC4695] Lazzaro、J。およびJ. Wawrzynek、「MIDIのRTPペイロード形式」、RFC 4695、2006年11月。
[RFC3550] Schulzrinne, H., Casner, S., Frederick, R., and V. Jacobson, "RTP: A Transport Protocol for Real-Time Applications", STD 64, RFC 3550, July 2003.
[RFC3550] Schulzrinne、H.、Casner、S.、Frederick、R。、およびV. Jacobson、「RTP:リアルタイムアプリケーション用の輸送プロトコル」、STD 64、RFC 3550、2003年7月。
[RFC3551] Schulzrinne, H. and S. Casner, "RTP Profile for Audio and Video Conferences with Minimal Control", STD 65, RFC 3551, July 2003.
[RFC3551] Schulzrinne、H。およびS. Casner、「最小限のコントロールを備えたオーディオおよびビデオ会議のRTPプロファイル」、STD 65、RFC 3551、2003年7月。
[RFC4566] Handley, M., Jacobson, V., and C. Perkins, "SDP: Session Description Protocol", RFC 4566, July 2006.
[RFC4566] Handley、M.、Jacobson、V。、およびC. Perkins、「SDP:セッション説明プロトコル」、RFC 4566、2006年7月。
[MIDI] MIDI Manufacturers Association. "The Complete MIDI 1.0 Detailed Specification", 1996.
[MIDI] MIDI Manufacturers Association。「完全なMIDI 1.0の詳細な仕様」、1996年。
[MPEGSA] International Standards Organization. "ISO/IEC 14496 MPEG-4", Part 3 (Audio), Subpart 5 (Structured Audio), 2001.
[MPEGSA]国際標準組織。「ISO/IEC 14496 MPEG-4」、パート3(オーディオ)、サブパート5(構造化されたオーディオ)、2001年。
[RFC3556] Casner, S., "Session Description Protocol (SDP) Bandwidth Modifiers for RTP Control Protocol (RTCP) Bandwidth", RFC 3556, July 2003.
[NMP] Lazzaro, J. and J. Wawrzynek. "A Case for Network Musical Performance", 11th International Workshop on Network and Operating Systems Support for Digital Audio and Video (NOSSDAV 2001) June 25-26, 2001, Port Jefferson, New York.
[NMP] Lazzaro、J。およびJ. Wawrzynek。「ネットワークミュージカルパフォーマンスのケース」、第11回ネットワークおよびオペレーティングシステムのデジタルオーディオおよびビデオのサポート(NossDav 2001)2001年6月25〜26日、ポートジェファーソン、ニューヨーク。
[RFC3261] Rosenberg, J., Schulzrinne, H., Camarillo, G., Johnston, A., Peterson, J., Sparks, R., Handley, M., and E. Schooler, "SIP: Session Initiation Protocol", RFC 3261, June 2002.
[RFC3261] Rosenberg、J.、Schulzrinne、H.、Camarillo、G.、Johnston、A.、Peterson、J.、Sparks、R.、Handley、M。、およびE. Schooler、「SIP:SESSION INTIANIATION Protocol」、RFC 3261、2002年6月。
[GRAME] Fober, D., Orlarey, Y. and S. Letz. "Real Time Musical Events Streaming over Internet", Proceedings of the International Conference on WEB Delivering of Music 2001, pages 147-154.
[Grame] Fober、D.、Orlarey、Y.、S。Letz。「インターネット上にストリーミングするリアルタイムの音楽イベント」、音楽2001の配信に関する国際会議の議事録、147〜154ページ。
[CCRMA] Chafe C., Wilson S., Leistikow R., Chisholm D., and G. Scavone. "A simplified approach to high quality music and sound over IP", COST-G6 Conference on Digital Audio Effects (DAFx-00), Verona, Italy, December 2000.
[Ccrma] Chafe C.、Wilson S.、Leistikow R.、Chisholm D.、およびG. Scavone。「高品質の音楽とサウンドオーバーIPへの単純化されたアプローチ」、2000年12月、イタリア、ヴェローナ、デジタルオーディオエフェクトに関するCost-G6会議(DAFX-00)。
[RTPBOOK] Perkins, C. "RTP: Audio and Video for the Internet", Addison-Wesley, ISBN 0-672-32249-8, 2003.
[RTPBook] Perkins、C。「RTP:インターネット用のオーディオとビデオ」、Addison-Wesley、ISBN 0-672-32249-8、2003。
[STEVENS] Stevens, R. W, Fenner, B., and A. Rudoff. "Unix Network Programming: The Sockets Networking API", Addison-Wesley, 2003.
[スティーブンス]スティーブンス、R。W、フェナー、B。、およびA.ルドフ。「UNIXネットワークプログラミング:The Sockets Networking API」、Addison-Wesley、2003。
Authors' Addresses
著者のアドレス
John Lazzaro (corresponding author) UC Berkeley CS Division 315 Soda Hall Berkeley CA 94720-1776
ジョン・ラザロ(対応する著者)UCバークレーCS部門315ソーダホールバークレーCA 94720-1776
EMail: lazzaro@cs.berkeley.edu
John Wawrzynek UC Berkeley CS Division 631 Soda Hall Berkeley CA 94720-1776
John Wawrzynek UC Berkeley CS Division 631 Soda Hall Berkeley CA 94720-1776
EMail: johnw@cs.berkeley.edu
Full Copyright Statement
完全な著作権声明
Copyright (C) The IETF Trust (2006).
Copyright(c)The IETF Trust(2006)。
This document is subject to the rights, licenses and restrictions contained in BCP 78, and except as set forth therein, the authors retain all their rights.
この文書は、BCP 78に含まれる権利、ライセンス、および制限の対象となり、そこに記載されている場合を除き、著者はすべての権利を保持しています。
This document and the information contained herein are provided on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST, AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
このドキュメントとここに含まれる情報は、「現状」に基づいて提供され、貢献者、彼/彼女が代表する組織(もしあれば)、インターネット協会、IETFトラスト、インターネットエンジニアリングタスクフォースは免責明示的または暗示されたすべての保証。ここでの情報の使用が、商品性または特定の目的に対する適合性の権利または黙示的な保証を侵害しないという保証を含むがこれらに限定されない。
Intellectual Property
知的財産
The IETF takes no position regarding the validity or scope of any Intellectual Property Rights or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; nor does it represent that it has made any independent effort to identify any such rights. Information on the procedures with respect to rights in RFC documents can be found in BCP 78 and BCP 79.
IETFは、知的財産権またはその他の権利の有効性または範囲に関して、この文書に記載されている技術の実装または使用、またはそのような権利に基づくライセンスがどの程度であるかについての使用に関連すると主張する可能性があるという立場はありません。利用可能になります。また、そのような権利を特定するために独立した努力をしたことも表明していません。RFCドキュメントの権利に関する手順に関する情報は、BCP 78およびBCP 79に記載されています。
Copies of IPR disclosures made to the IETF Secretariat and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementers or users of this specification can be obtained from the IETF on-line IPR repository at http://www.ietf.org/ipr.
IETF事務局に行われたIPR開示のコピーと、利用可能にするライセンスの保証、またはこの仕様の実装者またはユーザーによるそのような独自の権利の使用のための一般的なライセンスまたは許可を取得しようとする試みの結果を取得できます。http://www.ietf.org/iprのIETFオンラインIPRリポジトリから。
The IETF invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights that may cover technology that may be required to implement this standard. Please address the information to the IETF at ietf-ipr@ietf.org.
IETFは、関心のある当事者に、著作権、特許、または特許出願、またはこの基準を実装するために必要な技術をカバーする可能性のあるその他の独自の権利を注意深く招待するよう招待しています。ietf-ipr@ietf.orgのIETFへの情報をお問い合わせください。
Acknowledgement
謝辞
Funding for the RFC Editor function is currently provided by the Internet Society.
RFCエディター機能の資金は現在、インターネット協会によって提供されています。