diff --git a/README.md b/README.md index be32d69..796df44 100755 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ Enables an Arduino with IP/UDP capabilities (Ethernet shield, ESP8266, ESP32, .. * Send and receive all MIDI messages * Uses callbacks to receive MIDI commands (no need for polling) * Automatic instantiation of AppleMIDI object (see at the end of 'AppleMidi.h') +* Compiles on Arduino, MacOS (XCode) and Windows (MSVS) ## Installation From the Arduino IDE Library Manager, search for AppleMIDI diff --git a/examples/EthernetShield_Bonjour/EthernetShield_Bonjour.ino b/examples/EthernetShield_Bonjour/EthernetShield_Bonjour.ino index edcd6a9..be4b5ea 100644 --- a/examples/EthernetShield_Bonjour/EthernetShield_Bonjour.ino +++ b/examples/EthernetShield_Bonjour/EthernetShield_Bonjour.ino @@ -59,7 +59,6 @@ void setup() // Stay informed on connection status AppleMIDI.setHandleConnected(OnAppleMidiConnected); AppleMIDI.setHandleDisconnected(OnAppleMidiDisconnected); - AppleMIDI.setHandleError(OnAppleMidiError); // and let us know ehen notes come in MIDI.setHandleNoteOn(OnMidiNoteOn); @@ -115,14 +114,6 @@ void OnAppleMidiDisconnected(const ssrc_t & ssrc) { Serial.println(F("Disconnected")); } -// ----------------------------------------------------------------------------- -// rtpMIDI session. Error occorded during processing -// ----------------------------------------------------------------------------- -void OnAppleMidiError(const ssrc_t & ssrc, int32_t errorCode) { - Serial.println(F("ERROR")); - exit(1); -} - // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- diff --git a/examples/EthernetShield_Initiator/EthernetShield_Initiator.ino b/examples/EthernetShield_Initiator/EthernetShield_Initiator.ino index f9c3f6f..67aa59c 100644 --- a/examples/EthernetShield_Initiator/EthernetShield_Initiator.ino +++ b/examples/EthernetShield_Initiator/EthernetShield_Initiator.ino @@ -47,13 +47,14 @@ void setup() // Stay informed on connection status AppleMIDI.setHandleConnected(OnAppleMidiConnected); AppleMIDI.setHandleDisconnected(OnAppleMidiDisconnected); + AppleMIDI.setHandleError(OnAppleMidiError); // and let us know ehen notes come in MIDI.setHandleNoteOn(OnMidiNoteOn); MIDI.setHandleNoteOff(OnMidiNoteOff); // Initiate the session - IPAddress remote(192, 168, 1, 156); + IPAddress remote(192, 168, 1, 4); AppleMIDI.sendInvite(remote); // port is 5004 by default Serial.println(F("Every second send a random NoteOn/Off")); @@ -107,6 +108,23 @@ void OnAppleMidiDisconnected(const ssrc_t & ssrc) { Serial.println(ssrc, HEX); } +// ----------------------------------------------------------------------------- +// rtpMIDI session. Device disconnected +// ----------------------------------------------------------------------------- +void OnAppleMidiError(const ssrc_t& ssrc, int32_t err) { + Serial.print (F("Exception ")); + Serial.println(err); + Serial.print (F(" from ssrc 0x")); + Serial.println(ssrc, HEX); + + switch (err) + { + case Exception::NoResponseFromConnectionRequestException: + Serial.println(F("xxx:yyy did't respond to the connection request. Check the address and port, and any firewall or router settings. (time)")); + break; + } +} + // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- @@ -129,4 +147,4 @@ static void OnMidiNoteOff(byte channel, byte note, byte velocity) { Serial.print(note); Serial.print(F(", velocity: ")); Serial.println(velocity); -} +} \ No newline at end of file diff --git a/examples/EthernetShield_RealTimeMessages/EthernetShield_RealTimeMessages.ino b/examples/EthernetShield_RealTimeMessages/EthernetShield_RealTimeMessages.ino index f6052cd..a95f3f6 100644 --- a/examples/EthernetShield_RealTimeMessages/EthernetShield_RealTimeMessages.ino +++ b/examples/EthernetShield_RealTimeMessages/EthernetShield_RealTimeMessages.ino @@ -46,7 +46,6 @@ void setup() // check: zien we de connecttion binnenkomen?? Anders terug een ref van maken AppleMIDI.setHandleConnected(OnAppleMidiConnected); AppleMIDI.setHandleDisconnected(OnAppleMidiDisconnected); - AppleMIDI.setHandleError(OnAppleMidiError); MIDI.setHandleClock(OnMidiClock); MIDI.setHandleStart(OnMidiStart); @@ -81,14 +80,6 @@ void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { Serial.println(name); } -// ----------------------------------------------------------------------------- -// rtpMIDI session. Device disconnected -// ----------------------------------------------------------------------------- -void OnAppleMidiDisconnected(const ssrc_t & ssrc) { - isConnected = false; - Serial.println(F("Disconnected")); -} - // ----------------------------------------------------------------------------- // rtpMIDI session. Error occorded during processing // ----------------------------------------------------------------------------- diff --git a/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino b/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino index a57c7a6..a56fc5d 100644 --- a/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino +++ b/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino @@ -1,5 +1,6 @@ #include "ETH_Helper.h" +#define APPLEMIDI_INITIATOR #include USING_NAMESPACE_APPLEMIDI @@ -8,8 +9,6 @@ bool isConnected = false; APPLEMIDI_CREATE_DEFAULTSESSION_ESP32_INSTANCE(); -//WiFiServer server(80); - // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- @@ -21,9 +20,6 @@ void setup() ETH_startup(); - // Start TCP (HTTP) server - // server.begin(); - MDNS.begin(AppleMIDI.getName()); Serial.print("IP address is "); @@ -40,6 +36,7 @@ void setup() AppleMIDI.setHandleConnected(OnAppleMidiConnected); AppleMIDI.setHandleDisconnected(OnAppleMidiDisconnected); + AppleMIDI.setHandleError(OnAppleMidiError); MIDI.setHandleNoteOn(OnAppleMidiNoteOn); MIDI.setHandleNoteOff(OnAppleMidiNoteOff); @@ -48,6 +45,10 @@ void setup() MDNS.addService("http", "tcp", 80); Serial.println(F("Every second send a random NoteOn/Off")); + + // Initiate the session + IPAddress remote(192, 168, 1, 4); + AppleMIDI.sendInvite(remote); // port is 5004 by default } // ----------------------------------------------------------------------------- @@ -96,7 +97,24 @@ void OnAppleMidiDisconnected(const ssrc_t & ssrc) { } // ----------------------------------------------------------------------------- -// +// rtpMIDI session. Device disconnected +// ----------------------------------------------------------------------------- +void OnAppleMidiError(const ssrc_t& ssrc, int32_t err) { + Serial.print (F("Exception ")); + Serial.print (err); + Serial.print (F(" from ssrc 0x")); + Serial.println(ssrc, HEX); + + switch (err) + { + case Exception::NoResponseFromConnectionRequestException: + Serial.println(F("xxx:yyy did't respond to the connection request. Check the address and port, and any firewall or router settings. (time)")); + break; + } +} + +// ----------------------------------------------------------------------------- +// // ----------------------------------------------------------------------------- static void OnAppleMidiNoteOn(byte channel, byte note, byte velocity) { Serial.print(F("Incoming NoteOn from channel: ")); @@ -117,4 +135,4 @@ static void OnAppleMidiNoteOff(byte channel, byte note, byte velocity) { Serial.print(note); Serial.print(F(", velocity: ")); Serial.println(velocity); -} +} \ No newline at end of file diff --git a/library.properties b/library.properties index 52e1961..7716d43 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=AppleMIDI -version=2.0.5 +version=2.1.0 author=lathoub maintainer=lathoub sentence=AppleMIDI (rtpMIDI) protocol for Arduino diff --git a/src/AppleMIDI.h b/src/AppleMIDI.h index 2e3af38..b11e915 100644 --- a/src/AppleMIDI.h +++ b/src/AppleMIDI.h @@ -7,9 +7,9 @@ using namespace MIDI_NAMESPACE; #include "IPAddress.h" +#include "AppleMIDI_PlatformBegin.h" #include "AppleMIDI_Defs.h" #include "AppleMIDI_Settings.h" -#include "AppleMIDI_Platform.h" #include "rtp_Defs.h" #include "rtpMIDI_Defs.h" @@ -22,10 +22,6 @@ using namespace MIDI_NAMESPACE; #include "AppleMIDI_Namespace.h" -#ifndef UDP_TX_PACKET_MAX_SIZE -#define UDP_TX_PACKET_MAX_SIZE 24 -#endif - BEGIN_APPLEMIDI_NAMESPACE static unsigned long now; @@ -37,7 +33,7 @@ struct AppleMIDISettings : public MIDI_NAMESPACE::DefaultSettings static const bool Use1ByteParsing = false; }; -template +template class AppleMIDISession { typedef _Settings Settings; @@ -47,7 +43,6 @@ class AppleMIDISession // to avoid access by the .ino to internal messages friend class AppleMIDIParser; friend class rtpMIDIParser; - friend class MIDI_NAMESPACE::MidiInterface, AppleMIDISettings>; public: AppleMIDISession(const char *name, const uint16_t port = DEFAULT_CONTROL_PORT) @@ -58,7 +53,7 @@ class AppleMIDISession void setHandleConnected(void (*fptr)(const ssrc_t&, const char*)) { _connectedCallback = fptr; } void setHandleDisconnected(void (*fptr)(const ssrc_t&)) { _disconnectedCallback = fptr; } - void setHandleError(void (*fptr)(const ssrc_t&, int32_t)) { _errorCallback = fptr; } + void setHandleError(void (*fptr)(const ssrc_t&, int32_t)) { _exceptionCallback = fptr; } void setHandleReceivedRtp(void (*fptr)(const ssrc_t&, const Rtp_t&, const int32_t&)) { _receivedRtpCallback = fptr; } void setHandleStartReceivedMidi(void (*fptr)(const ssrc_t&)) { _startReceivedMidiByteCallback = fptr; } void setHandleReceivedMidi(void (*fptr)(const ssrc_t&, byte)) { _receivedMidiByteCallback = fptr; } @@ -72,7 +67,7 @@ class AppleMIDISession #endif void sendEndSession(); -protected: +public: static const bool thruActivated = false; void begin() @@ -150,8 +145,8 @@ class AppleMIDISession } else { - if (NULL != _errorCallback) - _errorCallback(ssrc, -1); + if (NULL != _exceptionCallback) + _exceptionCallback(ssrc, BufferFullException); } } @@ -204,14 +199,17 @@ class AppleMIDISession return byte; }; -private: +protected: UdpClass controlPort; UdpClass dataPort; +private: // reading from the network RtpBuffer_t controlBuffer; RtpBuffer_t dataBuffer; + byte packetBuffer[Settings::UdpTxPacketMaxSize]; + AppleMIDIParser _appleMIDIParser; rtpMIDIParser _rtpMIDIParser; @@ -221,7 +219,7 @@ class AppleMIDISession endReceivedMidiByteCallback _endReceivedMidiByteCallback = nullptr; receivedRtpCallback _receivedRtpCallback = nullptr; disconnectedCallback _disconnectedCallback = nullptr; - errorCallback _errorCallback = nullptr; + exceptionCallback _exceptionCallback = nullptr; // buffer for incoming and outgoing MIDI messages MidiBuffer_t inMidiBuffer; @@ -300,3 +298,5 @@ APPLEMIDI_CREATE_INSTANCE(EthernetUDP, MIDI, "Arduino", DEFAULT_CONTROL_PORT); #define APPLEMIDI_CREATE_DEFAULTSESSION_ESP32_INSTANCE() \ APPLEMIDI_CREATE_INSTANCE(WiFiUDP, MIDI, "ESP32", DEFAULT_CONTROL_PORT); + +#include "AppleMIDI_PlatformEnd.h" diff --git a/src/AppleMIDI.hpp b/src/AppleMIDI.hpp index b90f8ef..1718398 100644 --- a/src/AppleMIDI.hpp +++ b/src/AppleMIDI.hpp @@ -4,8 +4,6 @@ BEGIN_APPLEMIDI_NAMESPACE -static byte packetBuffer[UDP_TX_PACKET_MAX_SIZE]; - template void AppleMIDISession::readControlPackets() { @@ -32,8 +30,8 @@ void AppleMIDISession::parseControlPackets() auto retVal = _appleMIDIParser.parse(controlBuffer, amPortType::Control); if (retVal == parserReturn::UnexpectedData) { - if (NULL != _errorCallback) - _errorCallback(ssrc, -2); + if (NULL != _exceptionCallback) + _exceptionCallback(ssrc, ParseException); controlBuffer.pop_front(); } @@ -82,11 +80,9 @@ void AppleMIDISession::parseDataPackets() if (retVal1 == parserReturn::NotSureGiveMeMoreData || retVal2 == parserReturn::NotSureGiveMeMoreData) break; // one or the other buffer does not have enough data - - // TODO can we ever get here??? - if (NULL != _errorCallback) - _errorCallback(ssrc, -3); + if (NULL != _exceptionCallback) + _exceptionCallback(ssrc, UnexpectedParseException); dataBuffer.pop_front(); } @@ -114,8 +110,8 @@ void AppleMIDISession::ReceivedControlInvitation(A { writeInvitation(controlPort, controlPort.remoteIP(), controlPort.remotePort(), invitation, amInvitationRejected); - if (NULL != _errorCallback) - _errorCallback(ssrc, -33); + if (NULL != _exceptionCallback) + _exceptionCallback(ssrc, TooManyParticipantsException); return; } @@ -144,8 +140,8 @@ void AppleMIDISession::ReceivedDataInvitation(Appl { writeInvitation(dataPort, dataPort.remoteIP(), dataPort.remotePort(), invitation, amInvitationRejected); - if (NULL != _errorCallback) - _errorCallback(ssrc, -4); + if (NULL != _exceptionCallback) + _exceptionCallback(ssrc, ParticipantNotFoundException); return; } @@ -221,6 +217,7 @@ void AppleMIDISession::ReceivedInvitationRejected( if (invitationRejected.ssrc == participants[i].ssrc) { participants.erase(i); + return; } } @@ -357,7 +354,7 @@ void AppleMIDISession::ReceivedEndSession(AppleMID participants.erase(i); if (NULL != _disconnectedCallback) - _disconnectedCallback(endSession.ssrc); + _disconnectedCallback(participants[i].ssrc); return; } @@ -465,6 +462,7 @@ void AppleMIDISession::writeRtpMidiToAllParticipan auto participant = &participants[i]; writeRtpMidiBuffer(participant); } + outMidiBuffer.clear(); } template @@ -474,9 +472,7 @@ void AppleMIDISession::writeRtpMidiBuffer(Particip const uint16_t remotePort = participant->remotePort + 1; if (!dataPort.beginPacket(remoteIP, remotePort)) - { return; - } participant->sequenceNr++; // (modulo 2^16) modulo is automatically done for us () @@ -528,15 +524,10 @@ void AppleMIDISession::writeRtpMidiBuffer(Particip dataPort.write(rtpMidi.flags); dataPort.write((uint8_t)(bufferLen)); } - - // MIDI Section - while (!outMidiBuffer.empty()) - { - auto byte = outMidiBuffer.front(); - outMidiBuffer.pop_front(); - - dataPort.write(byte); - } + + // write out the MIDI Section + for (auto i = 0; i < bufferLen; i++) + dataPort.write(outMidiBuffer[i]); // *No* journal section (Not supported) @@ -579,10 +570,13 @@ void AppleMIDISession::manageSynchronizationListen { auto participant = &participants[i]; - // The initiator must initiate a new sync exchange at least once every 60 seconds; + // The initiator must check in with the listener at least once every 60 seconds; // otherwise the responder may assume that the initiator has died and terminate the session. if (now - participant->lastSyncExchangeTime > Settings::CK_MaxTimeOut) { + if (NULL != _exceptionCallback) + _exceptionCallback(ssrc, ListenerTimeOutException); + sendEndSession(participant); participants.erase(i); @@ -646,6 +640,9 @@ void AppleMIDISession::manageSynchronizationInitia { if (participant->synchronizationCount > DefaultSettings::MaxSynchronizationCK0Attempts) { + if (NULL != _exceptionCallback) + _exceptionCallback(ssrc, MaxAttemptsException); + // After too many attempts, stop. sendEndSession(participant); @@ -702,9 +699,14 @@ void AppleMIDISession::manageSessionInvites() { if (participant->connectionAttempts >= DefaultSettings::MaxSessionInvitesAttempts) { - // too many attempts, give up - indicate this participant slot is free + if (NULL != _exceptionCallback) + _exceptionCallback(ssrc, NoResponseFromConnectionRequestException); + // After too many attempts, stop. + sendEndSession(participant); + participants.erase(i); + continue; } @@ -796,11 +798,10 @@ void AppleMIDISession::sendEndSession() { while (participants.size() > 0) { - auto participant = &participants[0]; - + auto participant = &participants.front(); sendEndSession(participant); - participants.erase(0); + participants.pop_front(); } } diff --git a/src/AppleMIDI_Defs.h b/src/AppleMIDI_Defs.h index eb8ee01..3f372df 100644 --- a/src/AppleMIDI_Defs.h +++ b/src/AppleMIDI_Defs.h @@ -1,7 +1,6 @@ #pragma once #include "AppleMIDI_Settings.h" - #include "AppleMIDI_Namespace.h" BEGIN_APPLEMIDI_NAMESPACE @@ -17,6 +16,15 @@ typedef uint32_t ssrc_t; typedef uint32_t initiatorToken_t; typedef uint64_t timestamp_t; +union conversionBuffer +{ + uint8_t value8; + uint16_t value16; + uint32_t value32; + uint64_t value64; + byte buffer[8]; +}; + #define RtpBuffer_t Deque #define MidiBuffer_t Deque @@ -37,7 +45,7 @@ using receivedMidiByteCallback = void (*)(const ssrc_t&, byte); using endReceivedMidiByteCallback = void (*)(const ssrc_t&); using receivedRtpCallback = void (*)(const ssrc_t&, const Rtp_t&, const int32_t&); using disconnectedCallback = void (*)(const ssrc_t&); -using errorCallback = void (*)(const ssrc_t&, int32_t); +using exceptionCallback = void (*)(const ssrc_t&, int32_t); /* Signature "Magic Value" for Apple network MIDI session establishment */ @@ -59,7 +67,7 @@ const uint8_t SYNC_CK0 = 0; const uint8_t SYNC_CK1 = 1; const uint8_t SYNC_CK2 = 2; -typedef struct __attribute__((packed)) AppleMIDI_Invitation +typedef struct PACKED AppleMIDI_Invitation { initiatorToken_t initiatorToken; ssrc_t ssrc; @@ -71,13 +79,13 @@ typedef struct __attribute__((packed)) AppleMIDI_Invitation } } AppleMIDI_Invitation_t, AppleMIDI_InvitationAccepted_t, AppleMIDI_InvitationRejected_t; -typedef struct __attribute__((packed)) AppleMIDI_BitrateReceiveLimit +typedef struct PACKED AppleMIDI_BitrateReceiveLimit { ssrc_t ssrc; uint32_t bitratelimit; } AppleMIDI_BitrateReceiveLimit_t; -typedef struct __attribute__((packed)) AppleMIDI_Synchronization +typedef struct PACKED AppleMIDI_Synchronization { ssrc_t ssrc; uint8_t count; @@ -85,14 +93,14 @@ typedef struct __attribute__((packed)) AppleMIDI_Synchronization timestamp_t timestamps[3]; } AppleMIDI_Synchronization_t; -typedef struct __attribute__((packed)) AppleMIDI_ReceiverFeedback +typedef struct PACKED AppleMIDI_ReceiverFeedback { ssrc_t ssrc; uint16_t sequenceNr; uint16_t dummy; } AppleMIDI_ReceiverFeedback_t; -typedef struct __attribute__((packed)) AppleMIDI_EndSession +typedef struct PACKED AppleMIDI_EndSession { initiatorToken_t initiatorToken; ssrc_t ssrc; @@ -134,4 +142,16 @@ enum InviteStatus : uint8_t Connected }; +enum Exception : uint8_t +{ + BufferFullException, + ParseException, + UnexpectedParseException, + TooManyParticipantsException, + ParticipantNotFoundException, + ListenerTimeOutException, + MaxAttemptsException, + NoResponseFromConnectionRequestException, +}; + END_APPLEMIDI_NAMESPACE diff --git a/src/AppleMIDI_Parser.h b/src/AppleMIDI_Parser.h index 9a6bd54..cf5e9b0 100644 --- a/src/AppleMIDI_Parser.h +++ b/src/AppleMIDI_Parser.h @@ -1,13 +1,9 @@ #pragma once #include "utility/Deque.h" -#include "utility/endian.h" #include "AppleMIDI_Defs.h" - #include "AppleMIDI_Settings.h" -#include "AppleMIDI_Platform.h" - #include "AppleMIDI_Namespace.h" BEGIN_APPLEMIDI_NAMESPACE @@ -97,8 +93,11 @@ class AppleMIDIParser while ((i < buffer.size()) && (buffer[i] != 0x00)) i++; #endif - if (i == buffer.size() || buffer[i++] != 0x00) - return parserReturn::NotEnoughData; + // session name is optional. + // If i > minimum size (16), then a sessionName was provided and must include 0x00 + if (i > minimumLen) + if (i == buffer.size() || buffer[i++] != 0x00) + return parserReturn::NotEnoughData; while (i--) buffer.pop_front(); // consume all the bytes that made up this message @@ -284,8 +283,11 @@ class AppleMIDIParser while ((i < buffer.size()) && (buffer[i] != 0x00)) i++; #endif - if (i == buffer.size() || buffer[i++] != 0x00) - return parserReturn::NotEnoughData; + // session name is optional. + // If i > minimum size (16), then a sessionName was provided and must include 0x00 + if (i > minimumLen) + if (i == buffer.size() || buffer[i++] != 0x00) + return parserReturn::NotEnoughData; while (i--) buffer.pop_front(); // consume all the bytes that made up this message @@ -343,8 +345,11 @@ class AppleMIDIParser while ((i < buffer.size()) && (buffer[i] != 0x00)) i++; #endif - if (i == buffer.size() || buffer[i++] != 0x00) - return parserReturn::NotEnoughData; + // session name is optional. + // If i > minimum size (16), then a sessionName was provided and must include 0x00 + if (i > minimumLen) + if (i == buffer.size() || buffer[i++] != 0x00) + return parserReturn::NotEnoughData; while (i--) buffer.pop_front(); // consume all the bytes that made up this message diff --git a/src/AppleMIDI_PlatformBegin.h b/src/AppleMIDI_PlatformBegin.h new file mode 100644 index 0000000..9cb35e2 --- /dev/null +++ b/src/AppleMIDI_PlatformBegin.h @@ -0,0 +1,20 @@ +#pragma once + +#include "AppleMIDI_Namespace.h" + +#include "utility/endian.h" + +BEGIN_APPLEMIDI_NAMESPACE + +#ifdef _MSC_VER +#pragma pack(push, 1) +#define PACKED +#else +#define PACKED __attribute__((__packed__)) +#endif + +struct DefaultPlatform +{ +}; + +END_APPLEMIDI_NAMESPACE diff --git a/src/AppleMIDI_Platform.h b/src/AppleMIDI_PlatformEnd.h similarity index 65% rename from src/AppleMIDI_Platform.h rename to src/AppleMIDI_PlatformEnd.h index bda143b..fec7b9f 100644 --- a/src/AppleMIDI_Platform.h +++ b/src/AppleMIDI_PlatformEnd.h @@ -4,8 +4,9 @@ BEGIN_APPLEMIDI_NAMESPACE -struct ArduinoPlatform -{ -}; +#ifdef WIN32 +#pragma pack(pop) +#endif +#undef PACKED END_APPLEMIDI_NAMESPACE diff --git a/src/AppleMIDI_Settings.h b/src/AppleMIDI_Settings.h index 85cd5b2..884ef83 100644 --- a/src/AppleMIDI_Settings.h +++ b/src/AppleMIDI_Settings.h @@ -6,6 +6,8 @@ BEGIN_APPLEMIDI_NAMESPACE struct DefaultSettings { + static const size_t UdpTxPacketMaxSize = 24; + static const size_t MaxBufferSize = 64; static const size_t MaxSessionNameLen = 24; diff --git a/src/rtpMIDI_Clock.h b/src/rtpMIDI_Clock.h index 68898d2..649d84a 100644 --- a/src/rtpMIDI_Clock.h +++ b/src/rtpMIDI_Clock.h @@ -7,8 +7,6 @@ BEGIN_APPLEMIDI_NAMESPACE #define MSEC_PER_SEC 1000 -#define USEC_PER_SEC 1000000 -#define NSEC_PER_SEC 1000000000 typedef struct rtpMidi_Clock { diff --git a/src/rtpMIDI_Defs.h b/src/rtpMIDI_Defs.h index d81326b..4d2aa58 100644 --- a/src/rtpMIDI_Defs.h +++ b/src/rtpMIDI_Defs.h @@ -133,7 +133,7 @@ BEGIN_APPLEMIDI_NAMESPACE #define RTP_MIDI_CJ_CHAPTER_E_MASK_LENGTH 0x7f #define RTP_MIDI_CJ_CHAPTER_A_MASK_LENGTH 0x7f -typedef struct __attribute__((packed)) RtpMIDI +typedef struct PACKED RtpMIDI { uint8_t flags; } RtpMIDI_t; diff --git a/src/rtpMIDI_Parser.h b/src/rtpMIDI_Parser.h index 9053bf4..30e1eb6 100644 --- a/src/rtpMIDI_Parser.h +++ b/src/rtpMIDI_Parser.h @@ -1,7 +1,6 @@ #pragma once #include "utility/Deque.h" -#include "utility/endian.h" #include @@ -9,8 +8,6 @@ #include "rtp_Defs.h" #include "AppleMIDI_Settings.h" -#include "AppleMIDI_Platform.h" - #include "AppleMIDI_Namespace.h" BEGIN_APPLEMIDI_NAMESPACE diff --git a/src/rtp_Defs.h b/src/rtp_Defs.h index d9a90d5..50ac61b 100644 --- a/src/rtp_Defs.h +++ b/src/rtp_Defs.h @@ -26,7 +26,7 @@ other than 0! */ /* Payload type is the last 7 bits */ #define RTP_PAYLOAD_TYPE(octet) ((octet)&0x7F) -typedef struct __attribute__((packed)) Rtp +typedef struct PACKED Rtp { uint8_t vpxcc; uint8_t mpayload; diff --git a/src/utility/endian.h b/src/utility/endian.h index c853ade..2ae8cf0 100644 --- a/src/utility/endian.h +++ b/src/utility/endian.h @@ -1,138 +1,89 @@ #pragma once -#ifndef BYTE_ORDER +#if !defined(BYTE_ORDER) -#ifndef BIG_ENDIAN -#define BIG_ENDIAN 4321 -#endif -#ifndef LITTLE_ENDIAN -#define LITTLE_ENDIAN 1234 -#endif + #ifndef BIG_ENDIANs + #define BIG_ENDIAN 4321 + #endif + #ifndef LITTLE_ENDIAN + #define LITTLE_ENDIAN 1234 + #endif -#define TEST_LITTLE_ENDIAN (((union { unsigned x; unsigned char c; }){1}).c) + #define TEST_LITTLE_ENDIAN (((union { unsigned x; unsigned char c; }){1}).c) -#ifdef TEST_LITTLE_ENDIAN -#define BYTE_ORDER LITTLE_ENDIAN -#else -#define BYTE_ORDER BIG_ENDIAN -#endif + #ifdef TEST_LITTLE_ENDIAN + #define BYTE_ORDER LITTLE_ENDIAN + #else + #define BYTE_ORDER BIG_ENDIAN + #endif -#undef TEST_LITTLE_ENDIAN + #undef TEST_LITTLE_ENDIAN #endif #include #ifndef __bswap16 -#define __bswap16(x) ((uint16_t)((((uint16_t)(x)&0xff00) >> 8) | (((uint16_t)(x)&0x00ff) << 8))) + #define __bswap16(x) ((uint16_t)((((uint16_t)(x)&0xff00) >> 8) | (((uint16_t)(x)&0x00ff) << 8))) #endif #ifndef __bswap32 -#define __bswap32(x) \ - ((uint32_t)((((uint32_t)(x)&0xff000000) >> 24) | (((uint32_t)(x)&0x00ff0000) >> 8) | \ - (((uint32_t)(x)&0x0000ff00) << 8) | (((uint32_t)(x)&0x000000ff) << 24))) + #define __bswap32(x) \ + ((uint32_t)((((uint32_t)(x)&0xff000000) >> 24) | (((uint32_t)(x)&0x00ff0000) >> 8) | \ + (((uint32_t)(x)&0x0000ff00) << 8) | (((uint32_t)(x)&0x000000ff) << 24))) #endif #ifndef __bswap64 -#define __bswap64(x) \ - ((uint64_t)((((uint64_t)(x)&0xff00000000000000ULL) >> 56) | \ - (((uint64_t)(x)&0x00ff000000000000ULL) >> 40) | \ - (((uint64_t)(x)&0x0000ff0000000000ULL) >> 24) | \ - (((uint64_t)(x)&0x000000ff00000000ULL) >> 8) | \ - (((uint64_t)(x)&0x00000000ff000000ULL) << 8) | \ - (((uint64_t)(x)&0x0000000000ff0000ULL) << 24) | \ - (((uint64_t)(x)&0x000000000000ff00ULL) << 40) | \ - (((uint64_t)(x)&0x00000000000000ffULL) << 56))) + #define __bswap64(x) \ + ((uint64_t)((((uint64_t)(x)&0xff00000000000000ULL) >> 56) | \ + (((uint64_t)(x)&0x00ff000000000000ULL) >> 40) | \ + (((uint64_t)(x)&0x0000ff0000000000ULL) >> 24) | \ + (((uint64_t)(x)&0x000000ff00000000ULL) >> 8) | \ + (((uint64_t)(x)&0x00000000ff000000ULL) << 8) | \ + (((uint64_t)(x)&0x0000000000ff0000ULL) << 24) | \ + (((uint64_t)(x)&0x000000000000ff00ULL) << 40) | \ + (((uint64_t)(x)&0x00000000000000ffULL) << 56))) #endif -union conversionBuffer -{ - uint8_t value8; - uint16_t value16; - uint32_t value32; - uint64_t value64; - byte buffer[8]; -}; - #if BYTE_ORDER == LITTLE_ENDIAN -// Definitions from musl libc -#define htobe16(x) __bswap16(x) -#define be16toh(x) __bswap16(x) -#define betoh16(x) __bswap16(x) -#define htobe32(x) __bswap32(x) -#define be32toh(x) __bswap32(x) -#define betoh32(x) __bswap32(x) -#define htobe64(x) __bswap64(x) -#define be64toh(x) __bswap64(x) -#define betoh64(x) __bswap64(x) -#define htole16(x) (uint16_t)(x) -#define le16toh(x) (uint16_t)(x) -#define letoh16(x) (uint16_t)(x) -#define htole32(x) (uint32_t)(x) -#define le32toh(x) (uint32_t)(x) -#define letoh32(x) (uint32_t)(x) -#define htole64(x) (uint64_t)(x) -#define le64toh(x) (uint64_t)(x) -#define letoh64(x) (uint64_t)(x) - -// From Apple Open Source Libc -#define ntohs(x) __bswap16(x) -#define htons(x) __bswap16(x) -#define ntohl(x) __bswap32(x) -#define htonl(x) __bswap32(x) -#define ntohll(x) __bswap64(x) -#define htonll(x) __bswap64(x) - -#define NTOHL(x) (x) = ntohl((uint32_t)x) -#define NTOHS(x) (x) = ntohs((uint16_t)x) -#define NTOHLL(x) (x) = ntohll((uint64_t)x) -#define HTONL(x) (x) = htonl((uint32_t)x) -#define HTONS(x) (x) = htons((uint16_t)x) -#define HTONLL(x) (x) = htonll((uint64_t)x) +#if !defined(ntohs) + #define ntohs(x) __bswap16(x) +#endif +#if !defined(htons) + #define htons(x) __bswap16(x) +#endif +#if !defined(ntohl) + #define ntohl(x) __bswap32(x) +#endif +#if !defined(htonl) + #define htonl(x) __bswap32(x) +#endif +#if !defined(ntohll) + #define ntohll(x) __bswap64(x) +#endif +#if !defined(htonll) + #define htonll(x) __bswap64(x) +#endif #else // BIG_ENDIAN -// Definitions from musl libc - -#define htobe16(x) (uint16_t)(x) -#define be16toh(x) (uint16_t)(x) -#define betoh16(x) (uint16_t)(x) -#define htobe32(x) (uint32_t)(x) -#define be32toh(x) (uint32_t)(x) -#define betoh32(x) (uint32_t)(x) -#define htobe64(x) (uint64_t)(x) -#define be64toh(x) (uint64_t)(x) -#define betoh64(x) (uint64_t)(x) -#define htole16(x) __bswap16(x) -#define le16toh(x) __bswap16(x) -#define letoh16(x) __bswap16(x) -#define htole32(x) __bswap32(x) -#define le32toh(x) __bswap32(x) -#define letoh32(x) __bswap32(x) -#define htole64(x) __bswap64(x) -#define le64toh(x) __bswap64(x) -#define letoh64(x) __bswap64(x) - -// From Apple Open Source libc -#define ntohl(x) ((uint32_t)(x)) -#define ntohs(x) ((uint16_t)(x)) -#define htonl(x) ((uint32_t)(x)) -#define htons(x) ((uint16_t)(x)) -#define ntohll(x) ((uint64_t)(x)) -#define htonll(x) ((uint64_t)(x)) - -#define NTOHL(x) (x) -#define NTOHS(x) (x) -#define NTOHLL(x) (x) -#define HTONL(x) (x) -#define HTONS(x) (x) -#define HTONLL(x) (x) - - -void aa(uint64_t value) -{ - if ( value >= 10 ) - aa(value / 10); -} +#if !defined(ntohs) + #define ntohl(x) ((uint32_t)(x)) +#endif +#if !defined(ntohs) + #define ntohs(x) ((uint16_t)(x)) +#endif +#if !defined(htonl) + #define htonl(x) ((uint32_t)(x)) +#endif +#if !defined(htons) + #define htons(x) ((uint16_t)(x)) +#endif +#if !defined(ntohll) + #define ntohll(x) ((uint64_t)(x)) +#endif +#if !defined(htonll) + #define htonll(x) ((uint64_t)(x)) +#endif #endif diff --git a/test/rtpMidi.xcodeproj/xcshareddata/xcschemes/rtpMidi.xcscheme b/test/rtpMidi.xcodeproj/xcshareddata/xcschemes/rtpMidi.xcscheme index 7b96d37..cdfd28e 100644 --- a/test/rtpMidi.xcodeproj/xcshareddata/xcschemes/rtpMidi.xcscheme +++ b/test/rtpMidi.xcodeproj/xcshareddata/xcschemes/rtpMidi.xcscheme @@ -1,6 +1,6 @@