Skip to content

Commit ae9daba

Browse files
committed
Set/Clear rtp flags explicitly
Not the bug (?) RTP M field should not be set, if if the spec and apple indicate it should be set
1 parent 892c03e commit ae9daba

3 files changed

Lines changed: 68 additions & 20 deletions

File tree

src/AppleMIDI.hpp

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -600,9 +600,37 @@ void AppleMIDISession<UdpClass, Settings, Platform>::writeRtpMidiToAllParticipan
600600
template <class UdpClass, class Settings, class Platform>
601601
void AppleMIDISession<UdpClass, Settings, Platform>::writeRtpMidiBuffer(Participant<Settings>* participant)
602602
{
603+
const auto bufferLen = outMidiBuffer.size();
604+
603605
Rtp rtp;
604-
rtp.vpxcc = 0b10000000; // TODO: fun with flags
605-
rtp.mpayload = PAYLOADTYPE_RTPMIDI; // TODO: set or unset marker
606+
607+
// First octet
608+
rtp.vpxcc = ((RTP_VERSION_2) << 6); // RTP version 2
609+
rtp.vpxcc &= ~RTP_P_FIELD; // no padding
610+
rtp.vpxcc &= ~RTP_X_FIELD; // no extension
611+
// No CSRC
612+
613+
// second octet
614+
rtp.mpayload = PAYLOADTYPE_RTPMIDI;
615+
616+
/*
617+
// The behavior of the 1-bit M field depends on the media type of the
618+
// stream. For native streams, the M bit MUST be set to 1 if the MIDI
619+
// command section has a non-zero LEN field and MUST be set to 0
620+
// otherwise. For mpeg4-generic streams, the M bit MUST be set to 1 for
621+
// all packets (to conform to [RFC3640]).
622+
if (bufferLen != 0)
623+
rtp.mpayload |= RTP_M_FIELD;
624+
else
625+
rtp.mpayload &= ~RTP_M_FIELD;
626+
*/
627+
// Both https://developer.apple.com/library/archive/documentation/Audio/Conceptual/MIDINetworkDriverProtocol/MIDI/MIDI.html
628+
// and https://tools.ietf.org/html/rfc6295#section-2.1 indicate that the M field needs to be set
629+
// if the len in the MIDI section is NON-ZERO.
630+
// However, doing so on, MacOS does not take the given MIDI commands
631+
// Clear the M field
632+
rtp.mpayload &= ~RTP_M_FIELD;
633+
606634
rtp.ssrc = ssrc;
607635

608636
// https://developer.apple.com/library/ios/documentation/CoreMidi/Reference/MIDIServices_Reference/#//apple_ref/doc/uid/TP40010316-CHMIDIServiceshFunctions-SW30
@@ -647,27 +675,30 @@ void AppleMIDISession<UdpClass, Settings, Platform>::writeRtpMidiBuffer(Particip
647675
// write rtp header
648676
dataPort.write((uint8_t *)&rtp, sizeof(rtp));
649677

650-
const auto bufferLen = outMidiBuffer.size();
651-
652678
// Write rtpMIDI section
653679
RtpMIDI_t rtpMidi;
654680

681+
// 0 1 2 3
682+
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
683+
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
684+
// |B|J|Z|P|LEN... | MIDI list ... |
685+
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
686+
687+
rtpMidi.flags = 0;
688+
rtpMidi.flags &= ~RTP_MIDI_CS_FLAG_J; // no journal, clear J-FLAG
689+
rtpMidi.flags &= ~RTP_MIDI_CS_FLAG_Z; // no Delta Time 0 field, clear Z flag
690+
rtpMidi.flags &= ~RTP_MIDI_CS_FLAG_P; // no phantom flag
691+
655692
if (bufferLen <= 0x0F)
656693
{ // Short header
657-
rtpMidi.flags = (uint8_t)bufferLen;
658-
// rtpMidi.flags &= RTP_MIDI_CS_FLAG_B; // TODO: set or clear these flags (no journal)
659-
// rtpMidi.flags &= RTP_MIDI_CS_FLAG_J;
660-
// rtpMidi.flags &= RTP_MIDI_CS_FLAG_Z;
661-
// rtpMidi.flags &= RTP_MIDI_CS_FLAG_P;
694+
rtpMidi.flags |= (uint8_t)bufferLen;
695+
rtpMidi.flags &= ~RTP_MIDI_CS_FLAG_B; // short header, clear B-FLAG
662696
dataPort.write(rtpMidi.flags);
663697
}
664698
else
665699
{ // Long header
666-
rtpMidi.flags = (uint8_t)(bufferLen >> 8);
667-
rtpMidi.flags |= RTP_MIDI_CS_FLAG_B; // set B-FLAG for long header
668-
// rtpMidi.flags &= RTP_MIDI_CS_FLAG_J;
669-
// rtpMidi.flags &= RTP_MIDI_CS_FLAG_Z;
670-
// rtpMidi.flags &= RTP_MIDI_CS_FLAG_P;
700+
rtpMidi.flags |= (uint8_t)(bufferLen >> 8);
701+
rtpMidi.flags |= RTP_MIDI_CS_FLAG_B; // set B-FLAG for long header
671702
dataPort.write(rtpMidi.flags);
672703
dataPort.write((uint8_t)(bufferLen));
673704
}

src/rtpMIDI_Parser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ class rtpMIDIParser
9494
uint8_t csrc_count = RTP_CSRC_COUNT(rtp.vpxcc);
9595
#endif
9696

97-
if (2 != version)
97+
if (RTP_VERSION_2 != version)
9898
{
9999
return parserReturn::UnexpectedData;
100100
}

src/rtp_Defs.h

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,23 @@
44

55
BEGIN_APPLEMIDI_NAMESPACE
66

7+
// 0 1 2 3
8+
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
9+
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
10+
// | V |P|X| CC |M| PT | Sequence number |
11+
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
12+
13+
#define RTP_VERSION_2 2
14+
15+
// first octet
16+
#define RTP_P_FIELD 0x20
17+
#define RTP_X_FIELD 0x10
18+
#define RTP_CC_FIELD 0xF
19+
20+
// second octet
21+
#define RTP_M_FIELD 0x80
22+
#define RTP_PT_FIELD 0x7F
23+
724
/* magic number */
825
#define PAYLOADTYPE_RTPMIDI 97
926

@@ -12,19 +29,19 @@ BEGIN_APPLEMIDI_NAMESPACE
1229

1330
/* Padding is the third bit; No need to shift, because true is any value
1431
other than 0! */
15-
#define RTP_PADDING(octet) ((octet)&0x20)
32+
#define RTP_PADDING(octet) ((octet)&RTP_P_FIELD)
1633

1734
/* Extension bit is the fourth bit */
18-
#define RTP_EXTENSION(octet) ((octet)&0x10)
35+
#define RTP_EXTENSION(octet) ((octet)&RTP_X_FIELD)
1936

2037
/* CSRC count is the last four bits */
21-
#define RTP_CSRC_COUNT(octet) ((octet)&0xF)
38+
#define RTP_CSRC_COUNT(octet) ((octet)&RTP_CC_FIELD)
2239

2340
/* Marker is the first bit of the second octet */
24-
#define RTP_MARKER(octet) ((octet)&0x80)
41+
#define RTP_MARKER(octet) ((octet)&RTP_M_FIELD)
2542

2643
/* Payload type is the last 7 bits */
27-
#define RTP_PAYLOAD_TYPE(octet) ((octet)&0x7F)
44+
#define RTP_PAYLOAD_TYPE(octet) ((octet)&RTP_PT_FIELD)
2845

2946
typedef struct PACKED Rtp
3047
{

0 commit comments

Comments
 (0)