From 5ecc825098f28acdc48d34380911e41e8ab1c90f Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Fri, 24 Apr 2020 07:19:32 +0200 Subject: [PATCH 001/271] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2b6c4ee..be32d69 100755 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ This will also install [FortySevenEffects MIDI library](https://github.com/Forty ## Basic Usage ``` #include -#include +#include APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); From 8494140cc79b27f0028edfa143a53c64dc992ab9 Mon Sep 17 00:00:00 2001 From: Andrey Prygunkov Date: Fri, 1 May 2020 14:29:44 +0200 Subject: [PATCH 002/271] remove processed rtp-journal data from buffer --- src/rtpMIDI_Parser_JournalSection.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/rtpMIDI_Parser_JournalSection.hpp b/src/rtpMIDI_Parser_JournalSection.hpp index 4669471..2f3f317 100644 --- a/src/rtpMIDI_Parser_JournalSection.hpp +++ b/src/rtpMIDI_Parser_JournalSection.hpp @@ -41,6 +41,8 @@ parserReturn decodeJournalSection(RtpBuffer_t &buffer) if ((flags & RTP_MIDI_JS_FLAG_Y) == 0 && (flags & RTP_MIDI_JS_FLAG_A) == 0) { + while (minimumLen-- > 0) + buffer.pop_front(); return parserReturn::Processed; } From aa89204dc78cc4b717132d715609e5b178db5312 Mon Sep 17 00:00:00 2001 From: lathoub Date: Fri, 1 May 2020 23:25:20 +0200 Subject: [PATCH 003/271] Added Settings to set Use1ByteParsing to false - Packet based protocols prefer the entire message to be parsed as a whole. - Journal section minimum size is 3 --- src/AppleMIDI.h | 22 ++++++++++++++-------- src/rtpMIDI_Parser_JournalSection.hpp | 27 ++++++++++++++------------- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/src/AppleMIDI.h b/src/AppleMIDI.h index d638273..99dfdb1 100644 --- a/src/AppleMIDI.h +++ b/src/AppleMIDI.h @@ -30,6 +30,13 @@ BEGIN_APPLEMIDI_NAMESPACE static unsigned long now; +struct AppleMIDISettings : public MIDI_NAMESPACE::DefaultSettings +{ + // Packet based protocols prefer the entire message to be parsed + // as a whole. + static const bool Use1ByteParsing = false; +}; + template class AppleMIDISession { @@ -40,7 +47,7 @@ class AppleMIDISession // to avoid access by the .ino to internal messages friend class AppleMIDIParser; friend class rtpMIDIParser; - friend class MIDI_NAMESPACE::MidiInterface>; + friend class MIDI_NAMESPACE::MidiInterface, AppleMIDISettings>; public: AppleMIDISession(const char *name, const uint16_t port = DEFAULT_CONTROL_PORT) @@ -66,7 +73,7 @@ class AppleMIDISession void sendEndSession(); protected: - static const bool thruActivated = false; + static const bool thruActivated = false; void begin() { @@ -280,17 +287,16 @@ class AppleMIDISession Participant* getParticipantByInitiatorToken(const uint32_t initiatorToken); }; +END_APPLEMIDI_NAMESPACE + +#include "AppleMIDI.hpp" + #define APPLEMIDI_CREATE_INSTANCE(Type, Name, SessionName, Port) \ APPLEMIDI_NAMESPACE::AppleMIDISession Apple##Name(SessionName, Port); \ - MIDI_NAMESPACE::MidiInterface> Name((APPLEMIDI_NAMESPACE::AppleMIDISession&)Apple##Name); + MIDI_NAMESPACE::MidiInterface, AppleMIDISettings> Name((APPLEMIDI_NAMESPACE::AppleMIDISession&)Apple##Name); #define APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE() \ APPLEMIDI_CREATE_INSTANCE(EthernetUDP, MIDI, "Arduino", DEFAULT_CONTROL_PORT); #define APPLEMIDI_CREATE_DEFAULTSESSION_ESP32_INSTANCE() \ APPLEMIDI_CREATE_INSTANCE(WiFiUDP, MIDI, "ESP32", DEFAULT_CONTROL_PORT); - -END_APPLEMIDI_NAMESPACE - -#include "AppleMIDI.hpp" - diff --git a/src/rtpMIDI_Parser_JournalSection.hpp b/src/rtpMIDI_Parser_JournalSection.hpp index 2f3f317..bd72c29 100644 --- a/src/rtpMIDI_Parser_JournalSection.hpp +++ b/src/rtpMIDI_Parser_JournalSection.hpp @@ -27,25 +27,14 @@ parserReturn decodeJournalSection(RtpBuffer_t &buffer) { size_t i = 0; - minimumLen += 1; + // Minimum size for the Journal section is 3 + minimumLen += 3; if (buffer.size() < minimumLen) return parserReturn::NotEnoughData; /* lets get the main flags from the recovery journal header */ uint8_t flags = buffer[i++]; - // sequenceNr - minimumLen += 2; - if (buffer.size() < minimumLen) - return parserReturn::NotEnoughData; - - if ((flags & RTP_MIDI_JS_FLAG_Y) == 0 && (flags & RTP_MIDI_JS_FLAG_A) == 0) - { - while (minimumLen-- > 0) - buffer.pop_front(); - return parserReturn::Processed; - } - // The 16-bit Checkpoint Packet Seqnum header field codes the sequence // number of the checkpoint packet for this journal, in network byte // order (big-endian). The choice of the checkpoint packet sets the @@ -61,6 +50,18 @@ parserReturn decodeJournalSection(RtpBuffer_t &buffer) cb.buffer[1] = buffer[i++]; uint16_t checkPoint = ntohs(cb.value16); + // (RFC 4695, 5 Recovery Journal Format) + // If A and Y are both zero, the recovery journal only contains its 3- + // octet header and is considered to be an "empty" journal. + if ((flags & RTP_MIDI_JS_FLAG_Y) == 0 && (flags & RTP_MIDI_JS_FLAG_A) == 0) + { + // Big fixed by @hugbug + while (minimumLen-- > 0) + buffer.pop_front(); + + return parserReturn::Processed; + } + // By default, the payload format does not use enhanced Chapter C // encoding. In this default case, the H bit MUST be set to 0 for all // packets in the stream. From be347bfe9fa9bdb99f5a4e079f6f239c7339c3d0 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Fri, 1 May 2020 23:28:34 +0200 Subject: [PATCH 004/271] Update library.properties Bug fix when recovery journal is empty --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 2c9865d..52e1961 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=AppleMIDI -version=2.0.4 +version=2.0.5 author=lathoub maintainer=lathoub sentence=AppleMIDI (rtpMIDI) protocol for Arduino From eddc2a6c965a518fac83dd81354c2929236f6737 Mon Sep 17 00:00:00 2001 From: lathoub Date: Fri, 1 May 2020 23:43:11 +0200 Subject: [PATCH 005/271] added namespace to AppleMIDISettings added namespace to settings --- src/AppleMIDI.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AppleMIDI.h b/src/AppleMIDI.h index 99dfdb1..2e3af38 100644 --- a/src/AppleMIDI.h +++ b/src/AppleMIDI.h @@ -293,7 +293,7 @@ END_APPLEMIDI_NAMESPACE #define APPLEMIDI_CREATE_INSTANCE(Type, Name, SessionName, Port) \ APPLEMIDI_NAMESPACE::AppleMIDISession Apple##Name(SessionName, Port); \ - MIDI_NAMESPACE::MidiInterface, AppleMIDISettings> Name((APPLEMIDI_NAMESPACE::AppleMIDISession&)Apple##Name); + MIDI_NAMESPACE::MidiInterface, APPLEMIDI_NAMESPACE::AppleMIDISettings> Name((APPLEMIDI_NAMESPACE::AppleMIDISession&)Apple##Name); #define APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE() \ APPLEMIDI_CREATE_INSTANCE(EthernetUDP, MIDI, "Arduino", DEFAULT_CONTROL_PORT); From bedcb4b3a57ea9c33766c888675a18159f08bea6 Mon Sep 17 00:00:00 2001 From: lathoub Date: Sat, 2 May 2020 08:16:46 +0200 Subject: [PATCH 006/271] do not clear outMidiBuffer in writeRtpMidiBuffer Bug: only the first of multiple participants would receive bytes as the buffer was cleared in the first pass. Clear the outMidiBuffer after having sent all the bytes --- src/AppleMIDI.hpp | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/AppleMIDI.hpp b/src/AppleMIDI.hpp index b90f8ef..90e7b08 100644 --- a/src/AppleMIDI.hpp +++ b/src/AppleMIDI.hpp @@ -465,6 +465,7 @@ void AppleMIDISession::writeRtpMidiToAllParticipan auto participant = &participants[i]; writeRtpMidiBuffer(participant); } + outMidiBuffer.clear(); } template @@ -474,9 +475,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 +527,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 (int i = 0; i < bufferLen; i++) + dataPort.write(outMidiBuffer[i]); // *No* journal section (Not supported) From f8ad11e9bba008a27770f9360acff4e6165933a8 Mon Sep 17 00:00:00 2001 From: lathoub Date: Sat, 2 May 2020 09:04:43 +0200 Subject: [PATCH 007/271] send Disconnect when erasing participant --- src/AppleMIDI.hpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/AppleMIDI.hpp b/src/AppleMIDI.hpp index 90e7b08..44dd680 100644 --- a/src/AppleMIDI.hpp +++ b/src/AppleMIDI.hpp @@ -357,7 +357,7 @@ void AppleMIDISession::ReceivedEndSession(AppleMID participants.erase(i); if (NULL != _disconnectedCallback) - _disconnectedCallback(endSession.ssrc); + _disconnectedCallback(participants[i].ssrc); return; } @@ -529,7 +529,7 @@ void AppleMIDISession::writeRtpMidiBuffer(Particip } // write out the MIDI Section - for (int i = 0; i < bufferLen; i++) + for (auto i = 0; i < bufferLen; i++) dataPort.write(outMidiBuffer[i]); // *No* journal section (Not supported) @@ -573,7 +573,7 @@ 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) { @@ -696,9 +696,10 @@ void AppleMIDISession::manageSessionInvites() { if (participant->connectionAttempts >= DefaultSettings::MaxSessionInvitesAttempts) { - // too many attempts, give up - indicate this participant slot is free - + // After too many attempts, stop. + sendEndSession(participant); participants.erase(i); + continue; } @@ -790,11 +791,10 @@ void AppleMIDISession::sendEndSession() { while (participants.size() > 0) { - auto participant = &participants[0]; - + auto participant = &participants.front(); sendEndSession(participant); - participants.erase(0); + participants.pop_front(); } } From 19d775eb069aaa48a6de2c2cb7de20b3a4ecffd4 Mon Sep 17 00:00:00 2001 From: lathoub Date: Sat, 2 May 2020 13:57:22 +0200 Subject: [PATCH 008/271] more exception handling --- .../EthernetShield_Bonjour.ino | 9 ------- .../EthernetShield_Initiator.ino | 22 ++++++++++++++-- .../EthernetShield_RealTimeMessages.ino | 9 ------- src/AppleMIDI.h | 8 +++--- src/AppleMIDI.hpp | 26 ++++++++++++++----- src/AppleMIDI_Defs.h | 14 +++++++++- 6 files changed, 56 insertions(+), 32 deletions(-) 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/src/AppleMIDI.h b/src/AppleMIDI.h index 2e3af38..f259ff1 100644 --- a/src/AppleMIDI.h +++ b/src/AppleMIDI.h @@ -58,7 +58,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; } @@ -150,8 +150,8 @@ class AppleMIDISession } else { - if (NULL != _errorCallback) - _errorCallback(ssrc, -1); + if (NULL != _exceptionCallback) + _exceptionCallback(ssrc, BufferFullException); } } @@ -221,7 +221,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; diff --git a/src/AppleMIDI.hpp b/src/AppleMIDI.hpp index 44dd680..c2a7dbd 100644 --- a/src/AppleMIDI.hpp +++ b/src/AppleMIDI.hpp @@ -33,7 +33,8 @@ void AppleMIDISession::parseControlPackets() if (retVal == parserReturn::UnexpectedData) { if (NULL != _errorCallback) - _errorCallback(ssrc, -2); + if (NULL != _exceptionCallback) + _exceptionCallback(ssrc, ParseException); controlBuffer.pop_front(); } @@ -85,8 +86,8 @@ void AppleMIDISession::parseDataPackets() // TODO can we ever get here??? - if (NULL != _errorCallback) - _errorCallback(ssrc, -3); + if (NULL != _exceptionCallback) + _exceptionCallback(ssrc, UnexpectedParseException); dataBuffer.pop_front(); } @@ -114,8 +115,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 +145,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 +222,7 @@ void AppleMIDISession::ReceivedInvitationRejected( if (invitationRejected.ssrc == participants[i].ssrc) { participants.erase(i); + return; } } @@ -577,6 +579,9 @@ void AppleMIDISession::manageSynchronizationListen // 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); @@ -640,6 +645,9 @@ void AppleMIDISession::manageSynchronizationInitia { if (participant->synchronizationCount > DefaultSettings::MaxSynchronizationCK0Attempts) { + if (NULL != _exceptionCallback) + _exceptionCallback(ssrc, MaxAttemptsException); + // After too many attempts, stop. sendEndSession(participant); @@ -696,8 +704,12 @@ void AppleMIDISession::manageSessionInvites() { if (participant->connectionAttempts >= DefaultSettings::MaxSessionInvitesAttempts) { + if (NULL != _exceptionCallback) + _exceptionCallback(ssrc, NoResponseFromConnectionRequestException); + // After too many attempts, stop. sendEndSession(participant); + participants.erase(i); continue; diff --git a/src/AppleMIDI_Defs.h b/src/AppleMIDI_Defs.h index eb8ee01..9eae594 100644 --- a/src/AppleMIDI_Defs.h +++ b/src/AppleMIDI_Defs.h @@ -37,7 +37,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 */ @@ -134,4 +134,16 @@ enum InviteStatus : uint8_t Connected }; +enum Exception : uint8_t +{ + BufferFullException, + ParseException, + UnexpectedParseException, + TooManyParticipantsException, + ParticipantNotFoundException, + ListenerTimeOutException, + MaxAttemptsException, + NoResponseFromConnectionRequestException, +}; + END_APPLEMIDI_NAMESPACE From c834468dc35ae2fb9912b8f082d14b9b496b5020 Mon Sep 17 00:00:00 2001 From: lathoub Date: Sat, 2 May 2020 13:57:38 +0200 Subject: [PATCH 009/271] more exception handling --- src/AppleMIDI.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/AppleMIDI.hpp b/src/AppleMIDI.hpp index c2a7dbd..71e6914 100644 --- a/src/AppleMIDI.hpp +++ b/src/AppleMIDI.hpp @@ -32,7 +32,6 @@ void AppleMIDISession::parseControlPackets() auto retVal = _appleMIDIParser.parse(controlBuffer, amPortType::Control); if (retVal == parserReturn::UnexpectedData) { - if (NULL != _errorCallback) if (NULL != _exceptionCallback) _exceptionCallback(ssrc, ParseException); From db4693f5ffab80c947f99c823ad2d10532684ea9 Mon Sep 17 00:00:00 2001 From: lathoub Date: Sat, 2 May 2020 22:12:26 +0200 Subject: [PATCH 010/271] Big fix: sessionName is an optional element software always expected a sessionName, at minimum 0x00. That is not valid, the sessioname can be completely missing (not even a 0x00) --- src/AppleMIDI_Parser.h | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/AppleMIDI_Parser.h b/src/AppleMIDI_Parser.h index 9a6bd54..d52dd5f 100644 --- a/src/AppleMIDI_Parser.h +++ b/src/AppleMIDI_Parser.h @@ -97,8 +97,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 +287,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 +349,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 From 482ede74f9ddaa5e342583fea602ed3b91340f37 Mon Sep 17 00:00:00 2001 From: lathoub Date: Sat, 2 May 2020 22:25:20 +0200 Subject: [PATCH 011/271] Update wESP32_NoteOnOffEverySec.ino added OnError section --- .../wESP32_NoteOnOffEverySec.ino | 32 +++++++++++++++---- 1 file changed, 25 insertions(+), 7 deletions(-) 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 From 5bdddc5b4e5874cf958935bc03ecb266dd6c4d8b Mon Sep 17 00:00:00 2001 From: lathoub Date: Sun, 3 May 2020 11:44:32 +0200 Subject: [PATCH 012/271] removed comment --- src/AppleMIDI.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/AppleMIDI.hpp b/src/AppleMIDI.hpp index 71e6914..0c25f97 100644 --- a/src/AppleMIDI.hpp +++ b/src/AppleMIDI.hpp @@ -82,8 +82,6 @@ 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 != _exceptionCallback) _exceptionCallback(ssrc, UnexpectedParseException); From cb61d819a2493b537c1456b39a7914683e788332 Mon Sep 17 00:00:00 2001 From: lathoub Date: Sun, 3 May 2020 13:43:27 +0200 Subject: [PATCH 013/271] make controlPort and dataPort protected (was private) --- src/AppleMIDI.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/AppleMIDI.h b/src/AppleMIDI.h index f259ff1..e67ba4e 100644 --- a/src/AppleMIDI.h +++ b/src/AppleMIDI.h @@ -204,10 +204,11 @@ class AppleMIDISession return byte; }; -private: +protected: UdpClass controlPort; UdpClass dataPort; +private: // reading from the network RtpBuffer_t controlBuffer; RtpBuffer_t dataBuffer; From e33462cea92d972293a33e133f13d4717bd2334e Mon Sep 17 00:00:00 2001 From: lathoub Date: Sun, 3 May 2020 13:44:27 +0200 Subject: [PATCH 014/271] removed unwanted restover remove aa method --- src/utility/endian.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/utility/endian.h b/src/utility/endian.h index c853ade..0d5bdae 100644 --- a/src/utility/endian.h +++ b/src/utility/endian.h @@ -128,11 +128,4 @@ union conversionBuffer #define HTONS(x) (x) #define HTONLL(x) (x) - -void aa(uint64_t value) -{ - if ( value >= 10 ) - aa(value / 10); -} - #endif From e745cfaef68b1b604dac392ba390cfd841c300ef Mon Sep 17 00:00:00 2001 From: lathoub Date: Sun, 3 May 2020 13:47:52 +0200 Subject: [PATCH 015/271] remove unused #define for USEC_PER_SEC and NSEC_PER_SEC --- src/rtpMIDI_Clock.h | 2 -- 1 file changed, 2 deletions(-) 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 { From a7142bc91c2a418d98631d7af1c32ef26788394c Mon Sep 17 00:00:00 2001 From: lathoub Date: Sun, 3 May 2020 13:55:56 +0200 Subject: [PATCH 016/271] moved UDP_TX_PACKET_MAX_SIZE to Settings, packetBuffer as a class attribute --- src/AppleMIDI.h | 6 ++---- src/AppleMIDI.hpp | 2 -- src/AppleMIDI_Settings.h | 2 ++ 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/AppleMIDI.h b/src/AppleMIDI.h index e67ba4e..429e95f 100644 --- a/src/AppleMIDI.h +++ b/src/AppleMIDI.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; @@ -213,6 +209,8 @@ class AppleMIDISession RtpBuffer_t controlBuffer; RtpBuffer_t dataBuffer; + byte packetBuffer[Settings::UdpTxPacketMaxSize]; + AppleMIDIParser _appleMIDIParser; rtpMIDIParser _rtpMIDIParser; diff --git a/src/AppleMIDI.hpp b/src/AppleMIDI.hpp index 0c25f97..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() { 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; From 51716c060b9c3f956f1d855d0c3ec91431f583ad Mon Sep 17 00:00:00 2001 From: lathoub Date: Sun, 3 May 2020 14:16:37 +0200 Subject: [PATCH 017/271] move __attribute__((packed)) to Platform.h (multi platform support) --- src/AppleMIDI.h | 6 +++-- src/AppleMIDI_Defs.h | 10 ++++----- src/AppleMIDI_Parser.h | 3 --- src/AppleMIDI_PlatformBegin.h | 22 +++++++++++++++++++ ...IDI_Platform.h => AppleMIDI_PlatformEnd.h} | 7 +++--- src/rtpMIDI_Defs.h | 2 +- src/rtpMIDI_Parser.h | 2 -- src/rtp_Defs.h | 2 +- 8 files changed, 37 insertions(+), 17 deletions(-) create mode 100644 src/AppleMIDI_PlatformBegin.h rename src/{AppleMIDI_Platform.h => AppleMIDI_PlatformEnd.h} (65%) diff --git a/src/AppleMIDI.h b/src/AppleMIDI.h index 429e95f..fe293f2 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" @@ -33,7 +33,7 @@ struct AppleMIDISettings : public MIDI_NAMESPACE::DefaultSettings static const bool Use1ByteParsing = false; }; -template +template class AppleMIDISession { typedef _Settings Settings; @@ -299,3 +299,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_Defs.h b/src/AppleMIDI_Defs.h index 9eae594..9d42cf0 100644 --- a/src/AppleMIDI_Defs.h +++ b/src/AppleMIDI_Defs.h @@ -59,7 +59,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 +71,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 +85,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; diff --git a/src/AppleMIDI_Parser.h b/src/AppleMIDI_Parser.h index d52dd5f..0818f0f 100644 --- a/src/AppleMIDI_Parser.h +++ b/src/AppleMIDI_Parser.h @@ -4,10 +4,7 @@ #include "utility/endian.h" #include "AppleMIDI_Defs.h" - #include "AppleMIDI_Settings.h" -#include "AppleMIDI_Platform.h" - #include "AppleMIDI_Namespace.h" BEGIN_APPLEMIDI_NAMESPACE diff --git a/src/AppleMIDI_PlatformBegin.h b/src/AppleMIDI_PlatformBegin.h new file mode 100644 index 0000000..8ca792a --- /dev/null +++ b/src/AppleMIDI_PlatformBegin.h @@ -0,0 +1,22 @@ +#pragma once + +#include "AppleMIDI_Namespace.h" + +BEGIN_APPLEMIDI_NAMESPACE + +#ifdef WIN32 +#pragma pack(push, 1) +#define PACKED +#elif ARDUINO +#define PACKED __attribute__ ((packed)) +#elif __APPLE__ +#define PACKED +#else +#define 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/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..01ecf5f 100644 --- a/src/rtpMIDI_Parser.h +++ b/src/rtpMIDI_Parser.h @@ -9,8 +9,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; From 4b665aac0ab1bb65fb9c77e08521c1ee6606244a Mon Sep 17 00:00:00 2001 From: lathoub Date: Sun, 3 May 2020 14:38:29 +0200 Subject: [PATCH 018/271] WIN32 MACRO -> _MSC_VER I've changed here WIN32 to _MSC_VER because it's compiler dependent, not platform dependent. Someone using GCC or clang on Windows should use __attribute__((__packed__)) like on other platforms. The __attribute__((__packed__)) is supported by both GCC and clang and we can assume it's the correct attribute for all compilers except VC++. --- src/AppleMIDI_PlatformBegin.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AppleMIDI_PlatformBegin.h b/src/AppleMIDI_PlatformBegin.h index 8ca792a..044a52e 100644 --- a/src/AppleMIDI_PlatformBegin.h +++ b/src/AppleMIDI_PlatformBegin.h @@ -4,7 +4,7 @@ BEGIN_APPLEMIDI_NAMESPACE -#ifdef WIN32 +#ifdef _MSC_VER #pragma pack(push, 1) #define PACKED #elif ARDUINO From 2eee5f9e81873c5578e771a0503e7d02aff0d4f4 Mon Sep 17 00:00:00 2001 From: lathoub Date: Sun, 3 May 2020 14:51:12 +0200 Subject: [PATCH 019/271] __attribute__ ((packed)) should be used on all platforms, not just Arduino! --- src/AppleMIDI_PlatformBegin.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/AppleMIDI_PlatformBegin.h b/src/AppleMIDI_PlatformBegin.h index 044a52e..51a6e56 100644 --- a/src/AppleMIDI_PlatformBegin.h +++ b/src/AppleMIDI_PlatformBegin.h @@ -2,6 +2,8 @@ #include "AppleMIDI_Namespace.h" +#include "utility/endian.h" + BEGIN_APPLEMIDI_NAMESPACE #ifdef _MSC_VER From 93b9c0f6e9cdd9a3a95aeacb555bd4c46bef0a93 Mon Sep 17 00:00:00 2001 From: lathoub Date: Sun, 3 May 2020 14:51:35 +0200 Subject: [PATCH 020/271] __attribute__ ((packed)) should be used on all platforms, not just Arduino! --- src/AppleMIDI_PlatformBegin.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/AppleMIDI_PlatformBegin.h b/src/AppleMIDI_PlatformBegin.h index 51a6e56..9cb35e2 100644 --- a/src/AppleMIDI_PlatformBegin.h +++ b/src/AppleMIDI_PlatformBegin.h @@ -9,12 +9,8 @@ BEGIN_APPLEMIDI_NAMESPACE #ifdef _MSC_VER #pragma pack(push, 1) #define PACKED -#elif ARDUINO -#define PACKED __attribute__ ((packed)) -#elif __APPLE__ -#define PACKED #else -#define PACKED +#define PACKED __attribute__((__packed__)) #endif struct DefaultPlatform From d994a92f856d9b41514ff500128947f08bb21162 Mon Sep 17 00:00:00 2001 From: lathoub Date: Sun, 3 May 2020 14:52:37 +0200 Subject: [PATCH 021/271] moved endian.h to Platform.h and check for defined --- src/AppleMIDI_Defs.h | 10 ++- src/AppleMIDI_Parser.h | 1 - src/rtpMIDI_Parser.h | 1 - src/utility/endian.h | 168 ++++++++++++++++------------------------- 4 files changed, 72 insertions(+), 108 deletions(-) diff --git a/src/AppleMIDI_Defs.h b/src/AppleMIDI_Defs.h index 9d42cf0..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 diff --git a/src/AppleMIDI_Parser.h b/src/AppleMIDI_Parser.h index 0818f0f..cf5e9b0 100644 --- a/src/AppleMIDI_Parser.h +++ b/src/AppleMIDI_Parser.h @@ -1,7 +1,6 @@ #pragma once #include "utility/Deque.h" -#include "utility/endian.h" #include "AppleMIDI_Defs.h" #include "AppleMIDI_Settings.h" diff --git a/src/rtpMIDI_Parser.h b/src/rtpMIDI_Parser.h index 01ecf5f..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 diff --git a/src/utility/endian.h b/src/utility/endian.h index 0d5bdae..2ae8cf0 100644 --- a/src/utility/endian.h +++ b/src/utility/endian.h @@ -1,131 +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) +#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 From bd9fdc40e62e39efdf72d1b8aca720235282914b Mon Sep 17 00:00:00 2001 From: lathoub Date: Sun, 3 May 2020 15:07:21 +0200 Subject: [PATCH 022/271] make static polymorph methods public (was protected) Overriding the Settings makes the friend template declaration unworkable. --- src/AppleMIDI.h | 3 +-- test/rtpMidi.xcodeproj/xcshareddata/xcschemes/rtpMidi.xcscheme | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/AppleMIDI.h b/src/AppleMIDI.h index fe293f2..b11e915 100644 --- a/src/AppleMIDI.h +++ b/src/AppleMIDI.h @@ -43,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) @@ -68,7 +67,7 @@ class AppleMIDISession #endif void sendEndSession(); -protected: +public: static const bool thruActivated = false; void begin() 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 @@ Date: Sun, 3 May 2020 15:38:12 +0200 Subject: [PATCH 023/271] Compiles on MacOS (XCode) and Windows (MSVS) --- README.md | 1 + 1 file changed, 1 insertion(+) 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 From fa1fef33be528ca51e43c5d30a43b2bbe670180f Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sun, 3 May 2020 16:08:02 +0200 Subject: [PATCH 024/271] Update library.properties --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From 0ec106781d5af8589fbd89850594bfae4d1b8277 Mon Sep 17 00:00:00 2001 From: xirion <1120657+xirion@users.noreply.github.com> Date: Sun, 17 May 2020 17:06:39 +0200 Subject: [PATCH 025/271] ignore invitation of a participant already in the participant list --- src/AppleMIDI.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/AppleMIDI.hpp b/src/AppleMIDI.hpp index 1718398..dc64906 100644 --- a/src/AppleMIDI.hpp +++ b/src/AppleMIDI.hpp @@ -100,6 +100,10 @@ void AppleMIDISession::ReceivedInvitation(AppleMID template void AppleMIDISession::ReceivedControlInvitation(AppleMIDI_Invitation_t &invitation) { + // ignore invitation of a participant already in the participant list + if (NULL != getParticipantBySSRC(invitation.ssrc)) + return; + // advertise our own session name #ifdef KEEP_SESSION_NAME strncpy(invitation.sessionName, localName, DefaultSettings::MaxSessionNameLen); From 987fe86f2add288ae24ecc77e3ef27c0ec735ef7 Mon Sep 17 00:00:00 2001 From: xirion <1120657+xirion@users.noreply.github.com> Date: Sun, 17 May 2020 17:09:04 +0200 Subject: [PATCH 026/271] use valid ssrc in disconnect callback --- src/AppleMIDI.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/AppleMIDI.hpp b/src/AppleMIDI.hpp index dc64906..a32cd28 100644 --- a/src/AppleMIDI.hpp +++ b/src/AppleMIDI.hpp @@ -355,10 +355,12 @@ void AppleMIDISession::ReceivedEndSession(AppleMID { if (endSession.ssrc == participants[i].ssrc) { + auto ssrc = participants[i].ssrc; + participants.erase(i); if (NULL != _disconnectedCallback) - _disconnectedCallback(participants[i].ssrc); + _disconnectedCallback(ssrc); return; } From f2c9ad49a5b9588d4329f8c3930f10be827fb653 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Fri, 22 May 2020 21:35:53 +0200 Subject: [PATCH 027/271] Adjust CK_MaxTimeOut to be over 60 seconds as per protocol spec The initiator must initiate a new sync exchange at least once every 60 seconds as in https://developer.apple.com/library/archive/documentation/Audio/Conceptual/MIDINetworkDriverProtocol/MIDI/MIDI.html (signalled in #87) --- src/AppleMIDI_Settings.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/AppleMIDI_Settings.h b/src/AppleMIDI_Settings.h index 884ef83..c5a3e07 100644 --- a/src/AppleMIDI_Settings.h +++ b/src/AppleMIDI_Settings.h @@ -24,10 +24,9 @@ struct DefaultSettings // two sequence numbers. The sender can then free the memory containing old journalling data if necessary. static const unsigned long ReceiversFeedbackThreshold = 1000; - // Should not be lower than 11000 (15s) - // MacOS sends CK messages every 10 seconds - // rtpMIDI on Windows sends CK messages every x seconds - static const unsigned long CK_MaxTimeOut = 45000; + // The initiator must initiate a new sync exchange at least once every 60 seconds + // as in https://developer.apple.com/library/archive/documentation/Audio/Conceptual/MIDINetworkDriverProtocol/MIDI/MIDI.html + static const unsigned long CK_MaxTimeOut = 61000; // when set to true, the lower 32-bits of the rtpClock ae send // when set to false, 0 will be set for immediate playout. From 27382f330503d9eb53cb83ba0ac74dd709bb2fbd Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sat, 19 Sep 2020 07:17:07 +0200 Subject: [PATCH 028/271] Update library.properties consistent naming in sentence for all MID Transport layer of the MIDI library ("MIDI I/Os for Arduino") --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 7716d43..cf1fa80 100644 --- a/library.properties +++ b/library.properties @@ -2,7 +2,7 @@ name=AppleMIDI version=2.1.0 author=lathoub maintainer=lathoub -sentence=AppleMIDI (rtpMIDI) protocol for Arduino +sentence=AppleMIDI (aka rtpMIDI) MIDI I/Os for Arduino paragraph=AppleMIDI (also known as rtpMIDI) is a protocol to transport MIDI messages within RTP (Real-time Protocol) packets over Ethernet and WiFi networks. Major rewrite of the library to be faster and use less memory. Read the Wiki page when migrating from v1.* to v2.* (API changes) category=Communication url=https://github.com/lathoub/Arduino-AppleMidi-Library From 810aa7077a676761a2e12353c925cb295d4341bf Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sun, 11 Oct 2020 12:03:36 +0200 Subject: [PATCH 029/271] added badge for library managed --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 796df44..17520f3 100755 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # AppleMIDI (aka rtpMIDI) for Arduino -[![Build Status](https://travis-ci.org/lathoub/Arduino-AppleMIDI-Library.svg?branch=master)](https://travis-ci.org/lathoub/Arduino-AppleMIDI-Library) [![License: CC BY-SA 4.0](https://img.shields.io/badge/License-CC%20BY--SA%204.0-lightgrey.svg)](http://creativecommons.org/licenses/by-sa/4.0/) [![GitHub version](https://badge.fury.io/gh/lathoub%2FArduino-AppleMidi-Library.svg)](https://badge.fury.io/gh/lathoub%2FArduino-AppleMidi-Library) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/c8be2ccc3f104e0588572a39f8106070)](https://app.codacy.com/app/lathoub/Arduino-AppleMIDI-Library?utm_source=github.com&utm_medium=referral&utm_content=lathoub/Arduino-AppleMIDI-Library&utm_campaign=Badge_Grade_Dashboard) +[![arduino-library-badge](https://www.ardu-badge.com/badge/AppleMIDI.svg?)](https://www.ardu-badge.com/AppleMIDI)[![Build Status](https://travis-ci.org/lathoub/Arduino-AppleMIDI-Library.svg?branch=master)](https://travis-ci.org/lathoub/Arduino-AppleMIDI-Library) [![License: CC BY-SA 4.0](https://img.shields.io/badge/License-CC%20BY--SA%204.0-lightgrey.svg)](http://creativecommons.org/licenses/by-sa/4.0/) [![GitHub version](https://badge.fury.io/gh/lathoub%2FArduino-AppleMidi-Library.svg)](https://badge.fury.io/gh/lathoub%2FArduino-AppleMidi-Library) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/c8be2ccc3f104e0588572a39f8106070)](https://app.codacy.com/app/lathoub/Arduino-AppleMIDI-Library?utm_source=github.com&utm_medium=referral&utm_content=lathoub/Arduino-AppleMIDI-Library&utm_campaign=Badge_Grade_Dashboard) Enables an Arduino with IP/UDP capabilities (Ethernet shield, ESP8266, ESP32, ...) to particpate in an AppleMIDI session. From b521a7049c0d2c6cbb65b03104b1f0c5374d184f Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sun, 11 Oct 2020 12:03:49 +0200 Subject: [PATCH 030/271] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 17520f3..227540c 100755 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # AppleMIDI (aka rtpMIDI) for Arduino -[![arduino-library-badge](https://www.ardu-badge.com/badge/AppleMIDI.svg?)](https://www.ardu-badge.com/AppleMIDI)[![Build Status](https://travis-ci.org/lathoub/Arduino-AppleMIDI-Library.svg?branch=master)](https://travis-ci.org/lathoub/Arduino-AppleMIDI-Library) [![License: CC BY-SA 4.0](https://img.shields.io/badge/License-CC%20BY--SA%204.0-lightgrey.svg)](http://creativecommons.org/licenses/by-sa/4.0/) [![GitHub version](https://badge.fury.io/gh/lathoub%2FArduino-AppleMidi-Library.svg)](https://badge.fury.io/gh/lathoub%2FArduino-AppleMidi-Library) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/c8be2ccc3f104e0588572a39f8106070)](https://app.codacy.com/app/lathoub/Arduino-AppleMIDI-Library?utm_source=github.com&utm_medium=referral&utm_content=lathoub/Arduino-AppleMIDI-Library&utm_campaign=Badge_Grade_Dashboard) +[![arduino-library-badge](https://www.ardu-badge.com/badge/AppleMIDI.svg?)](https://www.ardu-badge.com/AppleMIDI) [![Build Status](https://travis-ci.org/lathoub/Arduino-AppleMIDI-Library.svg?branch=master)](https://travis-ci.org/lathoub/Arduino-AppleMIDI-Library) [![License: CC BY-SA 4.0](https://img.shields.io/badge/License-CC%20BY--SA%204.0-lightgrey.svg)](http://creativecommons.org/licenses/by-sa/4.0/) [![GitHub version](https://badge.fury.io/gh/lathoub%2FArduino-AppleMidi-Library.svg)](https://badge.fury.io/gh/lathoub%2FArduino-AppleMidi-Library) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/c8be2ccc3f104e0588572a39f8106070)](https://app.codacy.com/app/lathoub/Arduino-AppleMIDI-Library?utm_source=github.com&utm_medium=referral&utm_content=lathoub/Arduino-AppleMIDI-Library&utm_campaign=Badge_Grade_Dashboard) Enables an Arduino with IP/UDP capabilities (Ethernet shield, ESP8266, ESP32, ...) to particpate in an AppleMIDI session. From 39b0e417537dcde5ea5b7cafbdc99832839699f9 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sun, 18 Oct 2020 13:51:25 +0200 Subject: [PATCH 031/271] No callbacks were fired when receiving realtime-data - Call callbacks for realtime-data - Added example for ESP32 callbacks - added code for nicer poorman debugging - rollup fix #91 Thank you @yetifrisstlama for the IPAddress comparison fix Thank you @Benceking24 for finding the bug --- examples/ESP32_Callbacks/ESP32_Callbacks.ino | 188 +++++++++++++++++++ library.properties | 2 +- src/AppleMIDI.h | 2 +- src/AppleMIDI_Defs.h | 150 +++++++++------ src/rtpMIDI_Parser_MidiCommandSection.hpp | 4 + 5 files changed, 287 insertions(+), 59 deletions(-) create mode 100644 examples/ESP32_Callbacks/ESP32_Callbacks.ino diff --git a/examples/ESP32_Callbacks/ESP32_Callbacks.ino b/examples/ESP32_Callbacks/ESP32_Callbacks.ino new file mode 100644 index 0000000..f263008 --- /dev/null +++ b/examples/ESP32_Callbacks/ESP32_Callbacks.ino @@ -0,0 +1,188 @@ +#include + +#define SerialMon Serial +#define APPLEMIDI_DEBUG SerialMon +#include +USING_NAMESPACE_APPLEMIDI + +bool isConnected = false; + +APPLEMIDI_CREATE_DEFAULTSESSION_ESP32_INSTANCE(); + +void setup() { + SerialMon.begin(115200); + while (!SerialMon); + + DBG("Booting"); + + WiFi.begin("The Hefty Network", "0208196700"); + while (WiFi.status() != WL_CONNECTED) { + delay(1000); + DBG("Establishing connection to WiFi.."); + } + DBG("Connected to network"); + + DBG(F("OK, now make sure you an rtpMIDI session that is Enabled")); + DBG(F("Add device named Arduino with Host"), WiFi.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); + DBG(F("Then press the Connect button")); + DBG(F("Then open a MIDI listener and monitor incoming notes")); + DBG(F("Every second send a random NoteOn/Off")); + + AppleMIDI.setHandleConnected(OnAppleMidiConnected); + AppleMIDI.setHandleDisconnected(OnAppleMidiDisconnected); + AppleMIDI.setHandleError(OnAppleMidiError); + +#if BYTE_ORDER == LITTLE_ENDIAN + DBG("Little Endian"); +#endif +#if BYTE_ORDER == BIG_ENDIAN + DBG("Big Endian"); +#endif + + MIDI.begin(); + + MIDI.setHandleNoteOff(OnNoteOff); + MIDI.setHandleNoteOn(OnNoteOn); + MIDI.setHandleAfterTouchPoly(OnAfterTouchPoly); + MIDI.setHandleControlChange(OnControlChange); + MIDI.setHandleProgramChange(OnProgramChange); + MIDI.setHandleAfterTouchChannel(OnAfterTouchChannel); + MIDI.setHandlePitchBend(OnPitchBend); + MIDI.setHandleSystemExclusive(OnSystemExclusive); + MIDI.setHandleTimeCodeQuarterFrame(OnTimeCodeQuarterFrame); + MIDI.setHandleSongPosition(OnSongPosition); + MIDI.setHandleSongSelect(OnSongSelect); + MIDI.setHandleTuneRequest(OnTuneRequest); + MIDI.setHandleClock(OnClock); + MIDI.setHandleStart(OnStart); + MIDI.setHandleContinue(OnContinue); + MIDI.setHandleStop(OnStop); + MIDI.setHandleActiveSensing(OnActiveSensing); + MIDI.setHandleSystemReset(OnSystemReset); + + DBG(F("Ready")); +} + +void loop() { + MIDI.read(); +} + +//------ + +void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { + isConnected = true; + DBG(F("Connected to session"), name); +} + +void OnAppleMidiDisconnected(const ssrc_t & ssrc) { + isConnected = false; + DBG(F("Disconnected")); +} + +void OnAppleMidiError(const ssrc_t& ssrc, int32_t err) { + switch (err) + { + case Exception::BufferFullException: + DBG(F("*** BufferFullException")); + break; + case Exception::ParseException: + DBG(F("*** ParseException")); + break; + case Exception::TooManyParticipantsException: + DBG(F("*** TooManyParticipantsException")); + break; + case Exception::UnexpectedInviteException: + DBG(F("*** UnexpectedInviteException")); + break; + case Exception::ParticipantNotFoundException: + DBG(F("*** ParticipantNotFoundException")); + break; + case Exception::ListenerTimeOutException: + DBG(F("*** ListenerTimeOutException")); + break; + case Exception::MaxAttemptsException: + DBG(F("*** MaxAttemptsException")); + break; + case Exception::NoResponseFromConnectionRequestException: + DBG(F("***:yyy did't respond to the connection request. Check the address and port, and any firewall or router settings. (time)")); + break; + } +} + +//------ + +static void OnNoteOff(byte channel, byte note, byte velocity) { + DBG(F("Note Off. Channel:"), channel, " Note:", note, " Velocity:", velocity); +} + +static void OnNoteOn(byte channel, byte note, byte velocity) { + DBG(F("Note On. Channel:"), channel, " Note:", note, " Velocity:", velocity); +} + +static void OnAfterTouchPoly(byte channel, byte note, byte velocity) { + DBG(F("AfterTouchPoly. Channel:"), channel, " Note:", note, " Velocity:", velocity); +} + +static void OnControlChange(byte channel, byte note, byte velocity) { + DBG(F("ControlChange. Channel:"), channel, " Note:", note, " Velocity:", velocity); +} + +static void OnProgramChange(byte channel, byte note) { + DBG(F("ProgramChange. Channel:"), channel, " Note:", note); +} + +static void OnAfterTouchChannel(byte channel, byte note) { + DBG(F("AfterTouchChannel. Channel:"), channel, " Note:", note); +} + +static void OnPitchBend(byte channel, int note) { + DBG(F("PitchBend. Channel:"), channel, " Note:", note); +} + +static void OnSystemExclusive(byte* data, unsigned size) { + DBG(F("System exclusive")); + for (int i = 0; i < size; i++) { + SerialMon.print(F(" 0x")); + SerialMon.print(data[i], HEX); + } +} + +static void OnTimeCodeQuarterFrame(byte data) { + DBG(F("TimeCodeQuarterFrame")); +} + +static void OnSongPosition(unsigned beats) { + DBG(F("SongPosition:"), beats); +} + +static void OnSongSelect(byte songNumber) { + DBG(F("SongSelect"),songNumber); +} + +static void OnTuneRequest() { + DBG(F("Tune request")); +} + +static void OnClock() { + DBG(F("Clock")); +} + +static void OnStart() { + DBG(F("Start")); +} + +static void OnContinue() { + DBG(F("Continue")); +} + +static void OnStop() { + DBG(F("Stop")); +} + +static void OnActiveSensing() { + DBG(F("ActiveSensing")); +} + +static void OnSystemReset() { + DBG(F("SystemReset")); +} diff --git a/library.properties b/library.properties index cf1fa80..add0477 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=AppleMIDI -version=2.1.0 +version=2.2.0 author=lathoub maintainer=lathoub sentence=AppleMIDI (aka rtpMIDI) MIDI I/Os for Arduino diff --git a/src/AppleMIDI.h b/src/AppleMIDI.h index b11e915..8d0331e 100644 --- a/src/AppleMIDI.h +++ b/src/AppleMIDI.h @@ -123,7 +123,7 @@ class AppleMIDISession // of what we are to send (The RtpMidi protocol start with writing the // length of the buffer). So we'll copy to a buffer in the 'write' method, // and actually serialize for real in the endTransmission method - return (dataPort.remoteIP() != 0 && participants.size() > 0); + return (dataPort.remoteIP() != INADDR_NONE && participants.size() > 0); }; void write(byte byte) diff --git a/src/AppleMIDI_Defs.h b/src/AppleMIDI_Defs.h index 3f372df..5eec476 100644 --- a/src/AppleMIDI_Defs.h +++ b/src/AppleMIDI_Defs.h @@ -5,9 +5,9 @@ BEGIN_APPLEMIDI_NAMESPACE -#define APPLEMIDI_LIBRARY_VERSION 0x020000 +#define APPLEMIDI_LIBRARY_VERSION 0x020100 #define APPLEMIDI_LIBRARY_VERSION_MAJOR 2 -#define APPLEMIDI_LIBRARY_VERSION_MINOR 0 +#define APPLEMIDI_LIBRARY_VERSION_MINOR 2 #define APPLEMIDI_LIBRARY_VERSION_PATCH 0 #define DEFAULT_CONTROL_PORT 5004 @@ -25,6 +25,42 @@ union conversionBuffer byte buffer[8]; }; +#if defined(__AVR__) +#define APPLEMIDI_PROGMEM PROGMEM +typedef const __FlashStringHelper* AppleMIDIConstStr; +#define GFP(x) (reinterpret_cast(x)) +#define GF(x) F(x) +#else +#define APPLEMIDI_PROGMEM +typedef const char* AppleMIDIConstStr; +#define GFP(x) x +#define GF(x) x +#endif + +#ifdef APPLEMIDI_DEBUG +namespace { +template +static void DBG_PLAIN(T last) { + APPLEMIDI_DEBUG.println(last); +} + +template +static void DBG_PLAIN(T head, Args... tail) { + APPLEMIDI_DEBUG.print(head); + APPLEMIDI_DEBUG.print(' '); + DBG_PLAIN(tail...); +} + +template +static void DBG(Args... args) { + DBG_PLAIN(args...); +} +} // namespace +#else +#define DBG_PLAIN(...) +#define DBG(...) +#endif + #define RtpBuffer_t Deque #define MidiBuffer_t Deque @@ -39,6 +75,55 @@ union conversionBuffer struct Rtp; typedef Rtp Rtp_t; +// from: https://en.wikipedia.org/wiki/RTP-MIDI +// Apple decided to create their own protocol, imposing all parameters related to +// synchronization like the sampling frequency. This session protocol is called "AppleMIDI" +// in Wireshark software. Session management with AppleMIDI protocol requires two UDP ports, +// the first one is called "Control Port", the second one is called "Data Port". When used +// within a multithread implementation, only the Data port requires a "real-time" thread, +// the other port can be controlled by a normal priority thread. These two ports must be +// located at two consecutive locations (n / n+1); the first one can be any of the 65536 +// possible ports. +enum amPortType : uint8_t +{ + Control = 0, + Data = 1, +}; + +// from: https://en.wikipedia.org/wiki/RTP-MIDI +// AppleMIDI implementation defines two kind of session controllers: session initiators +// and session listeners. Session initiators are in charge of inviting the session listeners, +// and are responsible of the clock synchronization sequence. Session initiators can generally +// be session listeners, but some devices, such as iOS devices, can be session listeners only. +enum ParticipantKind : uint8_t +{ + Listener, + Initiator, +}; + +enum InviteStatus : uint8_t +{ + Initiating, + AwaitingControlInvitationAccepted, + ControlInvitationAccepted, + AwaitingDataInvitationAccepted, + DataInvitationAccepted, + Connected +}; + +enum Exception : uint8_t +{ + BufferFullException, + ParseException, + UnexpectedParseException, + TooManyParticipantsException, + UnexpectedInviteException, + ParticipantNotFoundException, + ListenerTimeOutException, + MaxAttemptsException, + NoResponseFromConnectionRequestException, +}; + using connectedCallback = void (*)(const ssrc_t&, const char *); using startReceivedMidiByteCallback = void (*)(const ssrc_t&); using receivedMidiByteCallback = void (*)(const ssrc_t&, byte); @@ -47,7 +132,6 @@ using receivedRtpCallback = void (*)(const ssrc_t&, const Rtp_t&, cons using disconnectedCallback = void (*)(const ssrc_t&); using exceptionCallback = void (*)(const ssrc_t&, int32_t); - /* Signature "Magic Value" for Apple network MIDI session establishment */ const byte amSignature[] = {0xff, 0xff}; @@ -55,12 +139,12 @@ const byte amSignature[] = {0xff, 0xff}; const byte amProtocolVersion[] = {0x00, 0x00, 0x00, 0x02}; /* Apple network MIDI valid commands */ -const byte amInvitation[] = {'I', 'N'}; -const byte amEndSession[] = {'B', 'Y'}; -const byte amSynchronization[] = {'C', 'K'}; -const byte amInvitationAccepted[] = {'O', 'K'}; -const byte amInvitationRejected[] = {'N', 'O'}; -const byte amReceiverFeedback[] = {'R', 'S'}; +const byte amInvitation[] = {'I', 'N'}; +const byte amEndSession[] = {'B', 'Y'}; +const byte amSynchronization[] = {'C', 'K'}; +const byte amInvitationAccepted[] = {'O', 'K'}; +const byte amInvitationRejected[] = {'N', 'O'}; +const byte amReceiverFeedback[] = {'R', 'S'}; const byte amBitrateReceiveLimit[] = {'R', 'L'}; const uint8_t SYNC_CK0 = 0; @@ -106,52 +190,4 @@ typedef struct PACKED AppleMIDI_EndSession ssrc_t ssrc; } AppleMIDI_EndSession_t; -// from: https://en.wikipedia.org/wiki/RTP-MIDI -// Apple decided to create their own protocol, imposing all parameters related to -// synchronization like the sampling frequency. This session protocol is called "AppleMIDI" -// in Wireshark software. Session management with AppleMIDI protocol requires two UDP ports, -// the first one is called "Control Port", the second one is called "Data Port". When used -// within a multithread implementation, only the Data port requires a "real-time" thread, -// the other port can be controlled by a normal priority thread. These two ports must be -// located at two consecutive locations (n / n+1); the first one can be any of the 65536 -// possible ports. -enum amPortType : uint8_t -{ - Control = 0, - Data = 1, -}; - -// from: https://en.wikipedia.org/wiki/RTP-MIDI -// AppleMIDI implementation defines two kind of session controllers: session initiators -// and session listeners. Session initiators are in charge of inviting the session listeners, -// and are responsible of the clock synchronization sequence. Session initiators can generally -// be session listeners, but some devices, such as iOS devices, can be session listeners only. -enum ParticipantKind : uint8_t -{ - Listener, - Initiator, -}; - -enum InviteStatus : uint8_t -{ - Initiating, - AwaitingControlInvitationAccepted, - ControlInvitationAccepted, - AwaitingDataInvitationAccepted, - DataInvitationAccepted, - Connected -}; - -enum Exception : uint8_t -{ - BufferFullException, - ParseException, - UnexpectedParseException, - TooManyParticipantsException, - ParticipantNotFoundException, - ListenerTimeOutException, - MaxAttemptsException, - NoResponseFromConnectionRequestException, -}; - END_APPLEMIDI_NAMESPACE diff --git a/src/rtpMIDI_Parser_MidiCommandSection.hpp b/src/rtpMIDI_Parser_MidiCommandSection.hpp index 3cbf44a..5b5f8f4 100644 --- a/src/rtpMIDI_Parser_MidiCommandSection.hpp +++ b/src/rtpMIDI_Parser_MidiCommandSection.hpp @@ -78,6 +78,10 @@ size_t decodeMidi(RtpBuffer_t &buffer, uint8_t &runningstatus) * not be intermingled with other MIDI-commands, so we handle this case right here and return */ if (octet >= 0xf8) { + session->StartReceivedMidi(); + session->ReceivedMidi(buffer[0]); + session->EndReceivedMidi(); + return 1; } From d07866af09d02ff4b94de326af2826d25f0b591e Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sun, 18 Oct 2020 15:00:16 +0200 Subject: [PATCH 032/271] Update ESP32_Callbacks.ino --- examples/ESP32_Callbacks/ESP32_Callbacks.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/ESP32_Callbacks/ESP32_Callbacks.ino b/examples/ESP32_Callbacks/ESP32_Callbacks.ino index f263008..f313478 100644 --- a/examples/ESP32_Callbacks/ESP32_Callbacks.ino +++ b/examples/ESP32_Callbacks/ESP32_Callbacks.ino @@ -15,7 +15,7 @@ void setup() { DBG("Booting"); - WiFi.begin("The Hefty Network", "0208196700"); + WiFi.begin("xxxx", "uuuu"); while (WiFi.status() != WL_CONNECTED) { delay(1000); DBG("Establishing connection to WiFi.."); From 1443efa26121ac47eea613c743c5ad3e58240fea Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sun, 18 Oct 2020 15:24:59 +0200 Subject: [PATCH 033/271] Create RFC6295_notes.md riginal by https://github.com/davidmoreno/rtpmidid/blob/master/docs/RFC6295_notes.md --- doc/RFC6295_notes.md | 174 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 doc/RFC6295_notes.md diff --git a/doc/RFC6295_notes.md b/doc/RFC6295_notes.md new file mode 100644 index 0000000..2bd1f39 --- /dev/null +++ b/doc/RFC6295_notes.md @@ -0,0 +1,174 @@ +# Basic RTPMIDI Cheat Sheet + +From https://tools.ietf.org/html/rfc6295 + +## RTP Header + + 0 1 2 3 + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | V |P|X| CC |M| PT | Sequence number | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Timestamp | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | SSRC | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | MIDI command section ... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Journal section ... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +| Bit | pos | description | +| --------------- | :---: | ------------------------------------------------------------------------------------------------------------------------ | +| V | 0-1 | Version. 2. | +| P | 2 | Has paddding. RTP needs it for encryption. 0. | +| X | 3 | Header extension. 0. | +| CC | 4-7 | CSRC count. 0. | +| M | 8 | Has MIDI data. | +| PT | 9-15 | Payload type. Always 0x61. MIDI. | +| Sequence number | 16-31 | Starts random, increase one on each packet. (%2^16). There is an extended one with 32 bits and rollovers. | +| Timestamp | 32-63 | Time this packet was generated. On Apple midi the unit is 0.1 ms. (1^-4 seconds). Real RTPMIDI is at session connection. | +| SSRC | 64-96 | Random unique SSRC for this sender. Same for all the session. | + +Timestamp can be buffered to reduce jitter on the receiving end, creating a +continuous lag of a specific length. + +## MIDI Command section + + 0 1 2 3 + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |B|J|Z|P|LEN... | MIDI list ... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +| Bit | pos | description | +| ------ | :-: | ---------------------------------------------------------------------------------------------------------------- | +| B | 0 | Length is 12 bits. If true length at 4-7 is MSB, and one more byte. | +| J | 1 | There is a journal | +| Z | 2 | First midi command as is in MIDI section. No timestamp for first command. | +| P | 3 | Phantom MIDI command. The first command is a running command from previous stream. | +| length | 4-7 | How many bytes. May be extended with the B bit. | +| MIDI | ... | MIDI data, then timestamp, MIDI data, timestamp and so on.. or timestamp, midi data and so on. Depends on Z bit. | + +Timestamps in running Length encoding. https://en.wikipedia.org/wiki/Run-length_encoding + +# Journal + +## Journal Bits + + 0 1 2 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |S|Y|A|H|TOTCHAN| Checkpoint Packet Seqnum | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +| Bit | pos | description | +| ------------------------ | :--: | ------------------------------------------------------------------------ | +| S | 0 | Single packet loss. To indicate only one packet is described in journal. | +| Y | 1 | Has system journal | +| A | 2 | Has channel journals. Needs totchan. | +| H | 3 | Enhanced Chapter C encoding. | +| TOTCHAN | 4-7 | Nr channels -1 (has totchan + 1 channels) | +| Checkpoint packet seqnum | 8-23 | Seq nr for this journal Normally the one before the current packet. | + +## Channel Journal + +One for each (TOTCHAN + 1) + + 0 1 2 3 + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |S| CHAN |H| LENGTH |P|C|M|W|N|E|T|A| Chapters ... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +| Bit | pos | description | +| ------ | :----: | ------------------------------------------------------------------------ | +| S | 0 | Single packet loss. To indicate only one packet is described in journal. | +| CHAN | 1-4 | Channel number | +| H | 5 | Whether contollers are Ehhanced Chapter C. | +| LENGTH | 6-15 | Lenght of the journal | +| P | 16 / 0 | Chapter P. Program Change. | +| C | 17 / 1 | Chapter C. Control Change. | +| M | 18 / 2 | Chapter M. Parameter System. | +| W | 19 / 3 | Chapter W. Pitch Wheel. | +| N | 20 / 4 | Chapter N. Note On/Off | +| E | 21 / 5 | Chapter E. Note Command Extras | +| T | 22 / 6 | Chapter T. After Touch. | +| A | 23 / 7 | Chapter A. Poly Aftertouch. | + +## Chapter P + + 0 1 2 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |S| PROGRAM |B| BANK-MSB |X| BANK-LSB | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +## Chapter C + + 0 1 2 3 + 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 8 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |S| LEN |S| NUMBER |A| VALUE/ALT |S| NUMBER | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |A| VALUE/ALT | .... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +## Chapter M + + 0 1 2 3 + 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 8 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |S| LEN |S| NUMBER |A| VALUE/ALT |S| NUMBER | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |A| VALUE/ALT | .... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +# Chapter W + + 0 1 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |S| FIRST |R| SECOND | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +## Chapter N + + 0 1 2 3 + 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 8 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |B| LEN | LOW | HIGH |S| NOTENUM |Y| VELOCITY | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |S| NOTENUM |Y| VELOCITY | .... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | OFFBITS | OFFBITS | .... | OFFBITS | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +| Bit | pos | description | +| --- | :-----: | ------------------------------------ | +| B | 0 | S-Style functionality. By default 1. | +| S | 16n | If B is 0, all S are 0. | +| Y | 16n + 8 | Recomendation to play. | + +## Chapter T + + 0 + 0 1 2 3 4 5 6 7 + +-+-+-+-+-+-+-+-+ + |S| PRESSURE | + +-+-+-+-+-+-+-+-+ + +## Chapter A + + 0 1 2 3 + 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 8 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |S| LEN |S| NOTENUM |X| PRESSURE |S| NOTENUM | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |X| PRESSURE | .... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +(original by https://github.com/davidmoreno/rtpmidid/blob/master/docs/RFC6295_notes.md) From a92c780f2ff284b3c774b013db3fe0eabfe3bf1d Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sun, 18 Oct 2020 19:29:41 +0200 Subject: [PATCH 034/271] updated demo's --- .gitignore | 3 +- README.md | 2 +- examples/Basic_IO/Basic_IO.ino | 37 ----- .../ETH_Helper.h | 60 ------- examples/ESP32_Callbacks/ESP32_Callbacks.ino | 41 ++--- .../ESP8266_NoteOnOffEverySec.ino} | 88 +++++----- .../EthernetShield_Bonjour.ino | 139 ---------------- .../EthernetShield_Initiator.ino | 78 +++------ .../EthernetShield_MultipleSessions.ino | 44 ++--- .../EthernetShield_NonDefaultSession.ino} | 70 ++++---- .../EthernetShield_NoteOnOffEverySec.ino | 36 ++--- .../EthernetShield_RealTimeMessages.ino | 153 ------------------ .../EthernetShield_ReceivedRawMidiData.ino | 68 ++++---- .../EthernetShield_SysEx.ino | 53 +++--- examples/MKR_ETH_Bonjour/MKR_ETH_Bonjour.ino | 47 ++++++ .../wESP32_NoteOnOffEverySec/ETH_Helper.h | 23 +-- .../wESP32_NoteOnOffEverySec.ino | 86 +++------- .../AppleMIDITask.h | 102 ------------ .../wESP32_NoteOnOffEverySec_Adv/ETH_Helper.h | 54 ------- .../WebServerTask.h | 63 -------- .../wESP32_NoteOnOffEverySec_Adv.ino | 42 ----- keywords.txt | 3 +- src/AppleMIDI.h | 13 +- test/Ethernet.h | 4 +- test/NoteOn.cpp | 33 ++-- 25 files changed, 316 insertions(+), 1026 deletions(-) delete mode 100644 examples/Basic_IO/Basic_IO.ino delete mode 100644 examples/ESP32-Ethernet-Kit_A_v1.1_NoteOnOffEverySec/ETH_Helper.h rename examples/{ESP32-Ethernet-Kit_A_v1.1_NoteOnOffEverySec/ESP32-Ethernet-Kit_A_v1.1_NoteOnOffEverySec.ino => ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino} (53%) delete mode 100644 examples/EthernetShield_Bonjour/EthernetShield_Bonjour.ino rename examples/{EthernetShield_ReceiveMTC/EthernetShield_ReceiveMTC.ino => EthernetShield_NonDefaultSession/EthernetShield_NonDefaultSession.ino} (54%) delete mode 100644 examples/EthernetShield_RealTimeMessages/EthernetShield_RealTimeMessages.ino create mode 100644 examples/MKR_ETH_Bonjour/MKR_ETH_Bonjour.ino delete mode 100644 examples/wESP32_NoteOnOffEverySec_Adv/AppleMIDITask.h delete mode 100644 examples/wESP32_NoteOnOffEverySec_Adv/ETH_Helper.h delete mode 100644 examples/wESP32_NoteOnOffEverySec_Adv/WebServerTask.h delete mode 100644 examples/wESP32_NoteOnOffEverySec_Adv/wESP32_NoteOnOffEverySec_Adv.ino diff --git a/.gitignore b/.gitignore index 2e3a85c..938aa14 100644 --- a/.gitignore +++ b/.gitignore @@ -3,8 +3,7 @@ examples/.DS_Store src/.DS_Store test/.vs test/Debug -examples/ESP32_NoteOnOffEverySec/config.h src/.vscode test/x64 .development -examples/ESP32_NoteOnOffEverySec/credentials.h +examples/ESP32_Callbacks/arduino_secrets.h diff --git a/README.md b/README.md index 227540c..f3828d7 100755 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); void setup() { - MIDI.begin(1); + MIDI.begin(); // Optional AppleMIDI.setHandleConnected(OnAppleMidiConnected); diff --git a/examples/Basic_IO/Basic_IO.ino b/examples/Basic_IO/Basic_IO.ino deleted file mode 100644 index 65e8a7c..0000000 --- a/examples/Basic_IO/Basic_IO.ino +++ /dev/null @@ -1,37 +0,0 @@ -#include -#include - -// Enter a MAC address for your controller below. -// Newer Ethernet shields have a MAC address printed on a sticker on the shield -byte mac[] = { - 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED -}; - -// Simple tutorial on how to receive and send MIDI messages. -// Here, when receiving any message on channel 4, the Arduino -// will blink a led and play back a note for 1 second. - -APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); - -void setup() -{ - if (Ethernet.begin(mac) == 0) { - Serial.println(F("Failed DHCP, check network cable & reboot")); - for (;;); - } - - pinMode(LED_BUILTIN, OUTPUT); - MIDI.begin(4); // Launch MIDI and listen to channel 4 -} - -void loop() -{ - if (MIDI.read()) // If we have received a message - { - digitalWrite(LED_BUILTIN, HIGH); - MIDI.sendNoteOn(42, 127, 1); // Send a Note (pitch 42, velo 127 on channel 1) - delay(1000); // Wait for a second - MIDI.sendNoteOff(42, 0, 1); // Stop the note - digitalWrite(LED_BUILTIN, LOW); - } -} diff --git a/examples/ESP32-Ethernet-Kit_A_v1.1_NoteOnOffEverySec/ETH_Helper.h b/examples/ESP32-Ethernet-Kit_A_v1.1_NoteOnOffEverySec/ETH_Helper.h deleted file mode 100644 index 25b4532..0000000 --- a/examples/ESP32-Ethernet-Kit_A_v1.1_NoteOnOffEverySec/ETH_Helper.h +++ /dev/null @@ -1,60 +0,0 @@ -#include -#include - -#define ETH_ADDR 1 -#define ETH_POWER_PIN 5 -#define ETH_MDC_PIN 23 -#define ETH_MDIO_PIN 18 -#define ETH_TYPE ETH_PHY_IP101 - -static bool eth_connected = false; - -void WiFiEvent(WiFiEvent_t event) -{ - switch (event) { - case SYSTEM_EVENT_ETH_START: - Serial.println("ETH Started"); - //set eth hostname here - ETH.setHostname("esp32-ethernet"); - break; - case SYSTEM_EVENT_ETH_CONNECTED: - Serial.println("ETH Connected"); - break; - case SYSTEM_EVENT_ETH_GOT_IP: - Serial.print("ETH MAC: "); - Serial.print(ETH.macAddress()); - Serial.print(", IPv4: "); - Serial.print(ETH.localIP()); - if (ETH.fullDuplex()) { - Serial.print(", FULL_DUPLEX"); - } - Serial.print(", "); - Serial.print(ETH.linkSpeed()); - Serial.println("Mbps"); - eth_connected = true; - break; - case SYSTEM_EVENT_ETH_DISCONNECTED: - Serial.println("ETH Disconnected"); - eth_connected = false; - break; - case SYSTEM_EVENT_ETH_STOP: - Serial.println("ETH Stopped"); - eth_connected = false; - break; - default: - break; - } -} - -bool ETH_startup() -{ - WiFi.onEvent(WiFiEvent); - ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE); - - Serial.println(F("Getting IP address...")); - - while (!eth_connected) - delay(100); - - return true; -} diff --git a/examples/ESP32_Callbacks/ESP32_Callbacks.ino b/examples/ESP32_Callbacks/ESP32_Callbacks.ino index f313478..9edb964 100644 --- a/examples/ESP32_Callbacks/ESP32_Callbacks.ino +++ b/examples/ESP32_Callbacks/ESP32_Callbacks.ino @@ -5,9 +5,11 @@ #include USING_NAMESPACE_APPLEMIDI +#include "arduino_secrets.h" + bool isConnected = false; -APPLEMIDI_CREATE_DEFAULTSESSION_ESP32_INSTANCE(); +APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); void setup() { SerialMon.begin(115200); @@ -15,7 +17,7 @@ void setup() { DBG("Booting"); - WiFi.begin("xxxx", "uuuu"); + WiFi.begin(SECRET_SSID, SECRET_PASS); while (WiFi.status() != WL_CONNECTED) { delay(1000); DBG("Establishing connection to WiFi.."); @@ -26,23 +28,16 @@ void setup() { DBG(F("Add device named Arduino with Host"), WiFi.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); DBG(F("Then press the Connect button")); DBG(F("Then open a MIDI listener and monitor incoming notes")); - DBG(F("Every second send a random NoteOn/Off")); + DBG(F("Listen to incoming MIDI commands")); AppleMIDI.setHandleConnected(OnAppleMidiConnected); AppleMIDI.setHandleDisconnected(OnAppleMidiDisconnected); AppleMIDI.setHandleError(OnAppleMidiError); -#if BYTE_ORDER == LITTLE_ENDIAN - DBG("Little Endian"); -#endif -#if BYTE_ORDER == BIG_ENDIAN - DBG("Big Endian"); -#endif - MIDI.begin(); - MIDI.setHandleNoteOff(OnNoteOff); - MIDI.setHandleNoteOn(OnNoteOn); + MIDI.setHandleNoteOff(OnMidiNoteOff); + MIDI.setHandleNoteOn(OnMidiNoteOn); MIDI.setHandleAfterTouchPoly(OnAfterTouchPoly); MIDI.setHandleControlChange(OnControlChange); MIDI.setHandleProgramChange(OnProgramChange); @@ -67,18 +62,25 @@ void loop() { MIDI.read(); } -//------ - +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { isConnected = true; DBG(F("Connected to session"), name); } +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- void OnAppleMidiDisconnected(const ssrc_t & ssrc) { isConnected = false; - DBG(F("Disconnected")); +DBG(F("Disconnected")); } +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- void OnAppleMidiError(const ssrc_t& ssrc, int32_t err) { switch (err) { @@ -111,12 +113,12 @@ void OnAppleMidiError(const ssrc_t& ssrc, int32_t err) { //------ -static void OnNoteOff(byte channel, byte note, byte velocity) { - DBG(F("Note Off. Channel:"), channel, " Note:", note, " Velocity:", velocity); +static void OnMidiNoteOff(byte channel, byte note, byte velocity) { + DBG(F("in\tNote off"), note, " Velocity", velocity, "\t", channel); } -static void OnNoteOn(byte channel, byte note, byte velocity) { - DBG(F("Note On. Channel:"), channel, " Note:", note, " Velocity:", velocity); +static void OnMidiNoteOn(byte channel, byte note, byte velocity) { + DBG(F("in\tNote on"), note, " Velocity", velocity, "\t", channel); } static void OnAfterTouchPoly(byte channel, byte note, byte velocity) { @@ -145,6 +147,7 @@ static void OnSystemExclusive(byte* data, unsigned size) { SerialMon.print(F(" 0x")); SerialMon.print(data[i], HEX); } + SerialMon.println(); } static void OnTimeCodeQuarterFrame(byte data) { diff --git a/examples/ESP32-Ethernet-Kit_A_v1.1_NoteOnOffEverySec/ESP32-Ethernet-Kit_A_v1.1_NoteOnOffEverySec.ino b/examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino similarity index 53% rename from examples/ESP32-Ethernet-Kit_A_v1.1_NoteOnOffEverySec/ESP32-Ethernet-Kit_A_v1.1_NoteOnOffEverySec.ino rename to examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino index 6f496c4..6c4eb84 100644 --- a/examples/ESP32-Ethernet-Kit_A_v1.1_NoteOnOffEverySec/ESP32-Ethernet-Kit_A_v1.1_NoteOnOffEverySec.ino +++ b/examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino @@ -1,48 +1,60 @@ -#include "ETH_Helper.h" +#include +#include +#include +#define SerialMon Serial +#define APPLEMIDI_DEBUG SerialMon #include USING_NAMESPACE_APPLEMIDI +char ssid[] = "yourNetwork"; // your network SSID (name) +char pass[] = "password"; // your network password (use for WPA, or use as key for WEP) + unsigned long t0 = millis(); bool isConnected = false; -APPLEMIDI_CREATE_DEFAULTSESSION_ESP32_INSTANCE(); +APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); + +// Forward declaration +void OnAppleMidiConnected(uint32_t ssrc, char* name); +void OnAppleMidiDisconnected(uint32_t ssrc); +void OnMidiNoteOn(byte channel, byte note, byte velocity); +void OnMidiNoteOff(byte channel, byte note, byte velocity); // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void setup() { - Serial.begin(115200); - while (!Serial); - Serial.println("Booting"); + // Serial communications and wait for port to open: + SerialMon.begin(115200); + while (!SerialMon); - ETH_startup(); - - MDNS.begin(AppleMIDI.getName()); + DBG("Booting"); - Serial.print("\nIP address is "); - Serial.println(ETH.localIP()); + WiFi.begin(ssid, pass); - Serial.println(F("OK, now make sure you an rtpMIDI session that is Enabled")); - Serial.print(F("Add device named Arduino with Host/Port ")); - Serial.print(ETH.localIP()); - Serial.println(F(":5004")); - Serial.println(F("Then press the Connect button")); - Serial.println(F("Then open a MIDI listener (eg MIDI-OX) and monitor incoming notes")); + while (WiFi.status() != WL_CONNECTED) { + delay(500); + DBG("Establishing connection to WiFi.."); + } + DBG("Connected to network"); - // Create a session and wait for a remote host to connect to us - MIDI.begin(1); // listen on channel 1 + DBG(F("OK, now make sure you an rtpMIDI session that is Enabled")); + DBG(F("Add device named Arduino with Host"), WiFi.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); + DBG(F("Then press the Connect button")); + DBG(F("Then open a MIDI listener and monitor incoming notes")); + DBG(F("Listen to incoming MIDI commands")); + + MIDI.begin(); AppleMIDI.setHandleConnected(OnAppleMidiConnected); AppleMIDI.setHandleDisconnected(OnAppleMidiDisconnected); - MIDI.setHandleNoteOn(OnAppleMidiNoteOn); - MIDI.setHandleNoteOff(OnAppleMidiNoteOff); - - MDNS.addService("apple-midi", "udp", AppleMIDI.getPort()); + MIDI.setHandleNoteOn(OnMidiNoteOn); + MIDI.setHandleNoteOff(OnMidiNoteOff); - Serial.println(F("Every second send a random NoteOn/Off")); + DBG(F("Sending NoteOn/Off of note 45, every second")); } // ----------------------------------------------------------------------------- @@ -58,9 +70,8 @@ void loop() if (isConnected && (millis() - t0) > 1000) { t0 = millis(); - // Serial.print(F("."); - byte note = random(1, 127); + byte note = 45; byte velocity = 55; byte channel = 1; @@ -77,39 +88,28 @@ void loop() // rtpMIDI session. Device connected // ----------------------------------------------------------------------------- void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { - isConnected = true; - Serial.print(F("Connected to session ")); - Serial.println(name); + isConnected = true; + DBG(F("Connected to session"), name); } // ----------------------------------------------------------------------------- // rtpMIDI session. Device disconnected // ----------------------------------------------------------------------------- void OnAppleMidiDisconnected(const ssrc_t & ssrc) { - isConnected = false; - Serial.println(F("Disconnected")); + isConnected = false; + DBG(F("Disconnected")); } // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- -static void OnAppleMidiNoteOn(byte channel, byte note, byte velocity) { - Serial.print(F("Incoming NoteOn from channel: ")); - Serial.print(channel); - Serial.print(F(", note: ")); - Serial.print(note); - Serial.print(F(", velocity: ")); - Serial.println(velocity); +void OnMidiNoteOn(byte channel, byte note, byte velocity) { + DBG(F("in\tNote on"), note, " Velocity", velocity, "\t", channel); } // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- -static void OnAppleMidiNoteOff(byte channel, byte note, byte velocity) { - Serial.print(F("Incoming NoteOff from channel: ")); - Serial.print(channel); - Serial.print(F(", note: ")); - Serial.print(note); - Serial.print(F(", velocity: ")); - Serial.println(velocity); +void OnMidiNoteOff(byte channel, byte note, byte velocity) { + DBG(F("in\tNote off"), note, " Velocity", velocity, "\t", channel); } diff --git a/examples/EthernetShield_Bonjour/EthernetShield_Bonjour.ino b/examples/EthernetShield_Bonjour/EthernetShield_Bonjour.ino deleted file mode 100644 index be4b5ea..0000000 --- a/examples/EthernetShield_Bonjour/EthernetShield_Bonjour.ino +++ /dev/null @@ -1,139 +0,0 @@ -#include -#include // https://github.com/TrippyLighting/EthernetBonjour - -#define OPTIONAL_MDNS - -#include -USING_NAMESPACE_APPLEMIDI - -// Enter a MAC address for your controller below. -// Newer Ethernet shields have a MAC address printed on a sticker on the shield -byte mac[] = { - 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED -}; - -unsigned long t1 = millis(); -bool isConnected = false; - -APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); - -// ----------------------------------------------------------------------------- -// -// ----------------------------------------------------------------------------- -void setup() -{ - Serial.begin(115200); - while (!Serial); - Serial.println("Booting"); - - Serial.println(F("Getting IP address...")); - - if (Ethernet.begin(mac) == 0) { - Serial.println(F("Failed DHCP, check network cable & reboot")); - for (;;); - } - - Serial.print(F("IP address is ")); - Serial.println(Ethernet.localIP()); - - Serial.println(F("OK, now make sure you an rtpMIDI session that is Enabled")); - Serial.print(F("Add device named Arduino with Host/Port ")); - Serial.print(Ethernet.localIP()); - Serial.println(F(":5004")); - Serial.println(F("Then press the Connect button")); - Serial.println(F("Then open a MIDI listener (eg MIDI-OX) and monitor incoming notes")); - - // Listen for MIDI messages on channel 1 - MIDI.begin(1); - - // Initialize the Bonjour/MDNS library. You can now reach or ping this - // Arduino via the host name "arduino.local", provided that your operating - // system is Bonjour-enabled (such as MacOS X). - // Always call this before any other method! - EthernetBonjour.begin("arduino"); - - EthernetBonjour.addServiceRecord("Arduino._apple-midi", - AppleMIDI.getPort(), - MDNSServiceUDP); - - // Stay informed on connection status - AppleMIDI.setHandleConnected(OnAppleMidiConnected); - AppleMIDI.setHandleDisconnected(OnAppleMidiDisconnected); - - // and let us know ehen notes come in - MIDI.setHandleNoteOn(OnMidiNoteOn); - MIDI.setHandleNoteOff(OnMidiNoteOff); - - Serial.println(F("Every second send a random NoteOn/Off")); -} - -// ----------------------------------------------------------------------------- -// -// ----------------------------------------------------------------------------- -void loop() -{ - // Listen to incoming notes - MIDI.read(); - - EthernetBonjour.run(); - - // send note on/off every second - // (dont cáll delay(1000) as it will stall the pipeline) - if (isConnected && (millis() - t1) > 1000) - { - t1 = millis(); - // Serial.print(F("."); - - byte note = random(1, 127); - byte velocity = 55; - byte channel = 1; - - MIDI.sendNoteOn(note, velocity, channel); - MIDI.sendNoteOff(note, velocity, channel); - } -} - -// ==================================================================================== -// Event handlers for incoming MIDI messages -// ==================================================================================== - -// ----------------------------------------------------------------------------- -// rtpMIDI session. Device connected -// ----------------------------------------------------------------------------- -void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { - isConnected = true; - Serial.print(F("Connected to session ")); - Serial.println(name); -} - -// ----------------------------------------------------------------------------- -// rtpMIDI session. Device disconnected -// ----------------------------------------------------------------------------- -void OnAppleMidiDisconnected(const ssrc_t & ssrc) { - isConnected = false; - Serial.println(F("Disconnected")); -} - -// ----------------------------------------------------------------------------- -// -// ----------------------------------------------------------------------------- -static void OnMidiNoteOn(byte channel, byte note, byte velocity) { - Serial.print(F("Incoming NoteOn from channel: ")); - Serial.print(channel); - Serial.print(F(", note: ")); - Serial.print(note); - Serial.print(F(", velocity: ")); - Serial.println(velocity); -} - -// ----------------------------------------------------------------------------- -// -// ----------------------------------------------------------------------------- -static void OnMidiNoteOff(byte channel, byte note, byte velocity) { - Serial.print(F("Incoming NoteOff from channel: ")); - Serial.print(channel); - Serial.print(F(", note: ")); - Serial.print(note); - Serial.print(F(", velocity: ")); - Serial.println(velocity); -} diff --git a/examples/EthernetShield_Initiator/EthernetShield_Initiator.ino b/examples/EthernetShield_Initiator/EthernetShield_Initiator.ino index 67aa59c..9b2ab36 100644 --- a/examples/EthernetShield_Initiator/EthernetShield_Initiator.ino +++ b/examples/EthernetShield_Initiator/EthernetShield_Initiator.ino @@ -1,5 +1,7 @@ #include +#define SerialMon Serial +#define APPLEMIDI_DEBUG SerialMon #define APPLEMIDI_INITIATOR #include USING_NAMESPACE_APPLEMIDI @@ -20,34 +22,26 @@ APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); // ----------------------------------------------------------------------------- void setup() { - Serial.begin(115200); - while (!Serial); - Serial.println("Booting"); - - Serial.println(F("Getting IP address...")); + SerialMon.begin(115200); + while (!SerialMon); + DBG("Booting"); if (Ethernet.begin(mac) == 0) { - Serial.println(F("Failed DHCP, check network cable & reboot")); + DBG(F("Failed DHCP, check network cable & reboot")); for (;;); } - Serial.print(F("IP address is ")); - Serial.println(Ethernet.localIP()); - - Serial.println(F("OK, now make sure you an rtpMIDI session that is Enabled")); - Serial.print(F("Add device named Arduino with Host/Port ")); - Serial.print(Ethernet.localIP()); - Serial.println(F(":5004")); - Serial.println(F("Then press the Connect button")); - Serial.println(F("Then open a MIDI listener (eg MIDI-OX) and monitor incoming notes")); + DBG(F("OK, now make sure you an rtpMIDI session that is Enabled")); + DBG(F("Add device named Arduino with Host"), Ethernet.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); + DBG(F("Then press the Connect button")); + DBG(F("Then open a MIDI listener and monitor incoming notes")); + DBG(F("Listen to incoming MIDI commands")); - // Listen for MIDI messages on channel 1 - MIDI.begin(1); + MIDI.begin(); // 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); @@ -55,9 +49,9 @@ void setup() // Initiate the session IPAddress remote(192, 168, 1, 4); - AppleMIDI.sendInvite(remote); // port is 5004 by default + AppleMIDI.sendInvite(remote, DEFAULT_CONTROL_PORT); // port is 5004 by default - Serial.println(F("Every second send a random NoteOn/Off")); + DBG(F("Every second send a random NoteOn/Off")); } // ----------------------------------------------------------------------------- @@ -73,14 +67,13 @@ void loop() if (isConnected && (millis() - t1) > 1000) { t1 = millis(); - // Serial.print(F("."); byte note = random(1, 127); byte velocity = 55; byte channel = 1; - // MIDI.sendNoteOn(note, velocity, channel); - // MIDI.sendNoteOff(note, velocity, channel); + MIDI.sendNoteOn(note, velocity, channel); + MIDI.sendNoteOff(note, velocity, channel); } } @@ -93,10 +86,7 @@ void loop() // ----------------------------------------------------------------------------- void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { isConnected = true; - Serial.print(F("Connected to session ")); - Serial.print(name); - Serial.print(F(" ssrc: 0x")); - Serial.println(ssrc, HEX); + DBG(F("Connected to session"), name); } // ----------------------------------------------------------------------------- @@ -104,47 +94,19 @@ void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { // ----------------------------------------------------------------------------- void OnAppleMidiDisconnected(const ssrc_t & ssrc) { isConnected = false; - Serial.print (F("Disconnected from ssrc 0x")); - 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; - } + DBG(F("Disconnected")); } // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- static void OnMidiNoteOn(byte channel, byte note, byte velocity) { - Serial.print(F("Incoming NoteOn from channel: ")); - Serial.print(channel); - Serial.print(F(", note: ")); - Serial.print(note); - Serial.print(F(", velocity: ")); - Serial.println(velocity); + DBG(F("in\tNote on"), note, " Velocity", velocity, "\t", channel); } // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- static void OnMidiNoteOff(byte channel, byte note, byte velocity) { - Serial.print(F("Incoming NoteOff from channel: ")); - Serial.print(channel); - Serial.print(F(", note: ")); - Serial.print(note); - Serial.print(F(", velocity: ")); - Serial.println(velocity); + DBG(F("in\tNote off"), note, " Velocity", velocity, "\t", channel); } \ No newline at end of file diff --git a/examples/EthernetShield_MultipleSessions/EthernetShield_MultipleSessions.ino b/examples/EthernetShield_MultipleSessions/EthernetShield_MultipleSessions.ino index 75ca6ab..7b6fe77 100644 --- a/examples/EthernetShield_MultipleSessions/EthernetShield_MultipleSessions.ino +++ b/examples/EthernetShield_MultipleSessions/EthernetShield_MultipleSessions.ino @@ -1,5 +1,7 @@ #include +#define SerialMon Serial +#define APPLEMIDI_DEBUG SerialMon #include USING_NAMESPACE_APPLEMIDI @@ -20,26 +22,20 @@ APPLEMIDI_CREATE_INSTANCE(EthernetUDP, MIDI2, "Arduino2", DEFAULT_CONTROL_PORT + // ----------------------------------------------------------------------------- void setup() { - Serial.begin(115200); - while (!Serial); - Serial.println("Booting"); - - Serial.println(F("Getting IP address...")); + SerialMon.begin(115200); + while (!SerialMon); + DBG("Booting"); if (Ethernet.begin(mac) == 0) { - Serial.println(F("Failed DHCP, check network cable & reboot")); + DBG(F("Failed DHCP, check network cable & reboot")); for (;;); } - Serial.print(F("IP address is ")); - Serial.println(Ethernet.localIP()); - - Serial.println(F("OK, now make sure you an rtpMIDI session that is Enabled")); - Serial.print(F("Add device named Arduino with Host/Port ")); - Serial.print(Ethernet.localIP()); - Serial.println(F(":5004")); - Serial.println(F("Then press the Connect button")); - Serial.println(F("Then open a MIDI listener (eg MIDI-OX) and monitor incoming notes")); + DBG(F("OK, now make sure you an rtpMIDI session that is Enabled")); + DBG(F("Add device named Arduino with Host"), Ethernet.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); + DBG(F("Then press the Connect button")); + DBG(F("Then open a MIDI listener and monitor incoming notes")); + DBG(F("Listen to incoming MIDI commands")); // Listen for MIDI messages on channel 1 MIDI1.begin(1); @@ -55,7 +51,7 @@ void setup() MIDI1.setHandleNoteOn(OnMidiNoteOn); MIDI2.setHandleNoteOn(OnMidiNoteOn); - Serial.println(F("Every second send a random NoteOn/Off")); + DBG(F("Every second, send a random NoteOn/Off, from multiple sessions")); } // ----------------------------------------------------------------------------- @@ -72,7 +68,6 @@ void loop() if (isConnected && (millis() - t1) > 1000) { t1 = millis(); - // Serial.print(F("."); byte note = random(1, 127); byte velocity = 55; @@ -91,10 +86,7 @@ void loop() // ----------------------------------------------------------------------------- void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { isConnected = true; - Serial.print(F("Connected to session ")); - Serial.print(name); - Serial.print(" ssrc 0x"); - Serial.println(ssrc, HEX); + DBG(F("Connected to session"), name); } // ----------------------------------------------------------------------------- @@ -102,18 +94,12 @@ void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { // ----------------------------------------------------------------------------- void OnAppleMidiDisconnected(const ssrc_t & ssrc) { isConnected = false; - Serial.print(F("Disconnected from ssrc 0x")); - Serial.println(ssrc, HEX); + DBG(F("Disconnected")); } // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- static void OnMidiNoteOn(byte channel, byte note, byte velocity) { - Serial.print(F("Incoming NoteOn from channel: ")); - Serial.print(channel); - Serial.print(F(", note: ")); - Serial.print(note); - Serial.print(F(", velocity: ")); - Serial.println(velocity); + DBG(F("in\tNote on"), note, " Velocity", velocity, "\t", channel); } diff --git a/examples/EthernetShield_ReceiveMTC/EthernetShield_ReceiveMTC.ino b/examples/EthernetShield_NonDefaultSession/EthernetShield_NonDefaultSession.ino similarity index 54% rename from examples/EthernetShield_ReceiveMTC/EthernetShield_ReceiveMTC.ino rename to examples/EthernetShield_NonDefaultSession/EthernetShield_NonDefaultSession.ino index 7bc351c..279857e 100644 --- a/examples/EthernetShield_ReceiveMTC/EthernetShield_ReceiveMTC.ino +++ b/examples/EthernetShield_NonDefaultSession/EthernetShield_NonDefaultSession.ino @@ -1,5 +1,7 @@ #include +#define SerialMon Serial +#define APPLEMIDI_DEBUG SerialMon #include USING_NAMESPACE_APPLEMIDI @@ -9,46 +11,43 @@ byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; +unsigned long t1 = millis(); bool isConnected = false; -APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); +// Custom name +//APPLEMIDI_CREATE_INSTANCE(EthernetUDP, MIDI, "MyNamedArduino", DEFAULT_CONTROL_PORT); +// custom name and random port +//APPLEMIDI_CREATE_INSTANCE(EthernetUDP, MIDI, "MyNamedArduino", 5200); +// custom name and port +APPLEMIDI_CREATE_INSTANCE(EthernetUDP, MIDI, "MyNamedArduino", DEFAULT_CONTROL_PORT + 2); // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void setup() { - Serial.begin(115200); - while (!Serial); - Serial.println("Booting"); - - Serial.println(F("Getting IP address...")); + SerialMon.begin(115200); + while (!SerialMon); + DBG("Booting"); if (Ethernet.begin(mac) == 0) { - Serial.println(F("Failed DHCP, check network cable & reboot")); + DBG(F("Failed DHCP, check network cable & reboot")); for (;;); } - Serial.print("IP address is "); - Serial.println(Ethernet.localIP()); - - Serial.println(F("OK, now make sure you an rtpMIDI session that is Enabled")); - Serial.print(F("Add device named Arduino with Host/Port ")); - Serial.print(Ethernet.localIP()); - Serial.println(F(":5004")); - Serial.println(F("Then press the Connect button")); - Serial.println(F("Then open a MIDI listener (eg MIDI-OX) and monitor incoming notes")); + DBG(F("OK, now make sure you an rtpMIDI session that is Enabled")); + DBG(F("Add device named Arduino with Host"), Ethernet.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); + DBG(F("Then press the Connect button")); + DBG(F("Then open a MIDI listener and monitor incoming notes")); + DBG(F("Listen to incoming MIDI commands")); - // Create a session and wait for a remote host to connect to us - MIDI.begin(1); + MIDI.begin(); - // check: zien we de connecttion binnenkomen?? Anders terug een ref van maken + // Stay informed on connection status AppleMIDI.setHandleConnected(OnAppleMidiConnected); AppleMIDI.setHandleDisconnected(OnAppleMidiDisconnected); - - MIDI.setHandleTimeCodeQuarterFrame(OnMidiTimeCodeQuarterFrame); - Serial.println(F("Every second send a random NoteOn/Off")); + DBG(F("Send MIDI messages every second")); } // ----------------------------------------------------------------------------- @@ -58,6 +57,20 @@ void loop() { // Listen to incoming notes MIDI.read(); + + // send a note every second + // (dont cáll delay(1000) as it will stall the pipeline) + if (isConnected && (millis() - t1) > 1000) + { + t1 = millis(); + + byte note = random(1, 127); + byte velocity = 55; + byte channel = 1; + + MIDI.sendNoteOn(note, velocity, channel); + MIDI.sendNoteOff(note, velocity, channel); + } } // ==================================================================================== @@ -69,8 +82,7 @@ void loop() // ----------------------------------------------------------------------------- void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { isConnected = true; - Serial.print(F("Connected to session ")); - Serial.println(name); + DBG(F("Connected to session"), name); } // ----------------------------------------------------------------------------- @@ -78,13 +90,5 @@ void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { // ----------------------------------------------------------------------------- void OnAppleMidiDisconnected(const ssrc_t & ssrc) { isConnected = false; - Serial.println(F("Disconnected")); -} - -// ----------------------------------------------------------------------------- -// -// ----------------------------------------------------------------------------- -static void OnMidiTimeCodeQuarterFrame(byte data) { - Serial.print("MTC: "); - Serial.println(data, HEX); + DBG(F("Disconnected")); } diff --git a/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino b/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino index c211404..505eef8 100644 --- a/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino +++ b/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino @@ -1,5 +1,7 @@ #include +#define SerialMon Serial +#define APPLEMIDI_DEBUG SerialMon #include USING_NAMESPACE_APPLEMIDI @@ -19,34 +21,28 @@ APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); // ----------------------------------------------------------------------------- void setup() { - Serial.begin(115200); - while (!Serial); - Serial.println("Booting"); - - Serial.println(F("Getting IP address...")); + SerialMon.begin(115200); + while (!SerialMon); + DBG("Booting"); if (Ethernet.begin(mac) == 0) { - Serial.println(F("Failed DHCP, check network cable & reboot")); + DBG(F("Failed DHCP, check network cable & reboot")); for (;;); } - Serial.print(F("IP address is ")); - Serial.println(Ethernet.localIP()); - - Serial.println(F("OK, now make sure you an rtpMIDI session that is Enabled")); - Serial.print(F("Add device named Arduino with Host/Port ")); - Serial.print(Ethernet.localIP()); - Serial.println(F(":5004")); - Serial.println(F("Then press the Connect button")); + DBG(F("OK, now make sure you an rtpMIDI session that is Enabled")); + DBG(F("Add device named Arduino with Host"), Ethernet.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); + DBG(F("Then press the Connect button")); + DBG(F("Then open a MIDI listener and monitor incoming notes")); + DBG(F("Listen to incoming MIDI commands")); - // Listen for MIDI messages on channel 1 - MIDI.begin(1); + MIDI.begin(); // Stay informed on connection status AppleMIDI.setHandleConnected(OnAppleMidiConnected); AppleMIDI.setHandleDisconnected(OnAppleMidiDisconnected); - Serial.println(F("Send MIDI messages to this session and see the latency on the Serial Monitor")); + DBG(F("Send MIDI messages every second")); } // ----------------------------------------------------------------------------- @@ -62,7 +58,6 @@ void loop() if (isConnected && (millis() - t1) > 1000) { t1 = millis(); - // Serial.print(F("."); byte note = random(1, 127); byte velocity = 55; @@ -82,8 +77,7 @@ void loop() // ----------------------------------------------------------------------------- void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { isConnected = true; - Serial.print(F("Connected to session ")); - Serial.println(name); + DBG(F("Connected to session"), name); } // ----------------------------------------------------------------------------- @@ -91,5 +85,5 @@ void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { // ----------------------------------------------------------------------------- void OnAppleMidiDisconnected(const ssrc_t & ssrc) { isConnected = false; - Serial.println(F("Disconnected")); + DBG(F("Disconnected")); } diff --git a/examples/EthernetShield_RealTimeMessages/EthernetShield_RealTimeMessages.ino b/examples/EthernetShield_RealTimeMessages/EthernetShield_RealTimeMessages.ino deleted file mode 100644 index a95f3f6..0000000 --- a/examples/EthernetShield_RealTimeMessages/EthernetShield_RealTimeMessages.ino +++ /dev/null @@ -1,153 +0,0 @@ -#include - -#include -USING_NAMESPACE_APPLEMIDI - -// Enter a MAC address for your controller below. -// Newer Ethernet shields have a MAC address printed on a sticker on the shield -byte mac[] = { - 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED -}; - -bool isConnected; - -APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); - -// ----------------------------------------------------------------------------- -// -// ----------------------------------------------------------------------------- -void setup() -{ - Serial.begin(115200); - while (!Serial); - Serial.println("Booting"); - - - Serial.println(F("Getting IP address...")); - - if (Ethernet.begin(mac) == 0) { - Serial.println(F("Failed DHCP, check network cable & reboot")); - for (;;); - } - - Serial.print("IP address is "); - Serial.println(Ethernet.localIP()); - - Serial.println(F("OK, now make sure you an rtpMIDI session that is Enabled")); - Serial.print(F("Add device named Arduino with Host/Port ")); - Serial.print(Ethernet.localIP()); - Serial.println(F(":5004")); - Serial.println(F("Then press the Connect button")); - Serial.println(F("Then open a MIDI listener (eg MIDI-OX) and monitor incoming notes")); - - // Create a session and wait for a remote host to connect to us - MIDI.begin(1); - - // check: zien we de connecttion binnenkomen?? Anders terug een ref van maken - AppleMIDI.setHandleConnected(OnAppleMidiConnected); - AppleMIDI.setHandleDisconnected(OnAppleMidiDisconnected); - - MIDI.setHandleClock(OnMidiClock); - MIDI.setHandleStart(OnMidiStart); - MIDI.setHandleStop(OnMidiStop); - MIDI.setHandleContinue(OnMidiContinue); - MIDI.setHandleActiveSensing(OnMidiActiveSensing); - MIDI.setHandleSystemReset(OnMidiSystemReset); - MIDI.setHandleSongPosition(OnMidiSongPosition); - - Serial.println(F("Every second send a random NoteOn/Off")); -} - -// ----------------------------------------------------------------------------- -// -// ----------------------------------------------------------------------------- -void loop() -{ - // Listen to incoming notes - MIDI.read(); -} - -// ==================================================================================== -// Event handlers for incoming MIDI messages -// ==================================================================================== - -// ----------------------------------------------------------------------------- -// rtpMIDI session. Device connected -// ----------------------------------------------------------------------------- -void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { - isConnected = true; - Serial.print(F("Connected to session ")); - Serial.println(name); -} - -// ----------------------------------------------------------------------------- -// rtpMIDI session. Error occorded during processing -// ----------------------------------------------------------------------------- -void OnAppleMidiError(const ssrc_t & ssrc, int32_t errorCode) { - Serial.println(F("ERROR")); - exit(1); -} - -// ----------------------------------------------------------------------------- -// -// ----------------------------------------------------------------------------- -static void OnMidiClock() { - Serial.println(F("Clock")); -} - -// ----------------------------------------------------------------------------- -// -// ----------------------------------------------------------------------------- -static void OnMidiStart() { - Serial.println(F("Start")); -} - -// ----------------------------------------------------------------------------- -// -// ----------------------------------------------------------------------------- -static void OnMidiStop() { - Serial.println(F("Stop")); -} - -// ----------------------------------------------------------------------------- -// -// ----------------------------------------------------------------------------- -static void OnMidiContinue() { - Serial.println(F("Continue")); -} - -// ----------------------------------------------------------------------------- -// (https://www.midi.org/specifications/item/table-1-summary-of-midi-message) -// Active Sensing. -// This message is intended to be sent repeatedly to tell the receiver that a -// connection is alive. Use of this message is optional. When initially received, -// the receiver will expect to receive another Active Sensing message each 300ms (max), -// and if it does not then it will assume that the connection has been terminated. -// At termination, the receiver will turn off all voices and return to normal -// (non- active sensing) operation. -// ----------------------------------------------------------------------------- -static void OnMidiActiveSensing() { - Serial.println(F("ActiveSensing")); -} - -// ----------------------------------------------------------------------------- -// (https://www.midi.org/specifications/item/table-1-summary-of-midi-message) -// Reset. -// Reset all receivers in the system to power-up status. This should be used -// sparingly, preferably under manual control. In particular, it should not be -// sent on power-up. -// ----------------------------------------------------------------------------- -static void OnMidiSystemReset() { - Serial.println(F("SystemReset")); -} - -// ----------------------------------------------------------------------------- -// (https://www.midi.org/specifications/item/table-1-summary-of-midi-message) -// Song Position Pointer. -// This is an internal 14 bit register that holds the number of MIDI beats -// (1 beat= six MIDI clocks) since the start of the song. l is the LSB, m the MSB. -// ----------------------------------------------------------------------------- -static void OnMidiSongPosition(unsigned a) { - Serial.print (F("SongPosition: ")); - Serial.println(a); -} diff --git a/examples/EthernetShield_ReceivedRawMidiData/EthernetShield_ReceivedRawMidiData.ino b/examples/EthernetShield_ReceivedRawMidiData/EthernetShield_ReceivedRawMidiData.ino index c3b026f..49521dc 100644 --- a/examples/EthernetShield_ReceivedRawMidiData/EthernetShield_ReceivedRawMidiData.ino +++ b/examples/EthernetShield_ReceivedRawMidiData/EthernetShield_ReceivedRawMidiData.ino @@ -1,5 +1,7 @@ #include +#define SerialMon Serial +#define APPLEMIDI_DEBUG SerialMon #include USING_NAMESPACE_APPLEMIDI @@ -19,40 +21,35 @@ APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); // ----------------------------------------------------------------------------- void setup() { - Serial.begin(115200); - while (!Serial); - Serial.println("Booting"); + SerialMon.begin(115200); + while (!SerialMon); - - Serial.println(F("Getting IP address...")); + DBG("Booting"); if (Ethernet.begin(mac) == 0) { - Serial.println(F("Failed DHCP, check network cable & reboot")); + DBG(F("Failed DHCP, check network cable & reboot")); for (;;); } - Serial.print(F("IP address is ")); - Serial.println(Ethernet.localIP()); - - Serial.println(F("OK, now make sure you an rtpMIDI session that is Enabled")); - Serial.print(F("Add device named Arduino with Host/Port ")); - Serial.print(Ethernet.localIP()); - Serial.println(F(":5004")); - Serial.println(F("Then press the Connect button")); - Serial.println(F("Then open a MIDI listener (eg MIDI-OX) and monitor incoming notes")); + DBG(F("OK, now make sure you an rtpMIDI session that is Enabled")); + DBG(F("Add device named Arduino with Host"), Ethernet.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); + DBG(F("Then press the Connect button")); + DBG(F("Then open a MIDI listener and monitor incoming notes")); + DBG(F("Listen to incoming MIDI commands")); - // Create a session and wait for a remote host to connect to us - MIDI.begin(1); + MIDI.begin(); // check: zien we de connecttion binnenkomen?? Anders terug een ref van maken AppleMIDI.setHandleConnected(OnAppleMidiConnected); AppleMIDI.setHandleDisconnected(OnAppleMidiDisconnected); + AppleMIDI.setHandleStartReceivedMidi(OnAppleMidiStartReceived); AppleMIDI.setHandleReceivedMidi(OnAppleMidiReceivedByte); + AppleMIDI.setHandleEndReceivedMidi(OnAppleMidiEndReceive); MIDI.setHandleNoteOn(OnMidiNoteOn); MIDI.setHandleNoteOff(OnMidiNoteOff); - Serial.println(F("Waiting for incoming MIDI messages")); + DBG(F("Waiting for incoming MIDI messages")); } // ----------------------------------------------------------------------------- @@ -73,8 +70,7 @@ void loop() // ----------------------------------------------------------------------------- void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { isConnected = true; - Serial.print(F("Connected to session ")); - Serial.println(name); + DBG(F("Connected to session"), name); } // ----------------------------------------------------------------------------- @@ -82,36 +78,40 @@ void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { // ----------------------------------------------------------------------------- void OnAppleMidiDisconnected(const ssrc_t & ssrc) { isConnected = false; - Serial.println(F("Disconnected")); + DBG(F("Disconnected")); +} + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +void OnAppleMidiStartReceived(const ssrc_t & ssrc) { + DBG(F("Start receiving"), ssrc); } // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void OnAppleMidiReceivedByte(const ssrc_t & ssrc, byte data) { - Serial.println(data, HEX); + SerialMon.println(data, HEX); +} + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +void OnAppleMidiEndReceive(const ssrc_t & ssrc) { + DBG(F("End receiving"), ssrc); } // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- static void OnMidiNoteOn(byte channel, byte note, byte velocity) { - Serial.print(F("Incoming NoteOn from channel: ")); - Serial.print(channel); - Serial.print(F(", note: ")); - Serial.print(note); - Serial.print(F(", velocity: ")); - Serial.println(velocity); + DBG(F("in\tNote on"), note, " Velocity", velocity, "\t", channel); } // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- static void OnMidiNoteOff(byte channel, byte note, byte velocity) { - Serial.print(F("Incoming NoteOff from channel: ")); - Serial.print(channel); - Serial.print(F(", note: ")); - Serial.print(note); - Serial.print(F(", velocity: ")); - Serial.println(velocity); + DBG(F("in\tNote off"), note, " Velocity", velocity, "\t", channel); } diff --git a/examples/EthernetShield_SysEx/EthernetShield_SysEx.ino b/examples/EthernetShield_SysEx/EthernetShield_SysEx.ino index fdcb968..0d02e86 100644 --- a/examples/EthernetShield_SysEx/EthernetShield_SysEx.ino +++ b/examples/EthernetShield_SysEx/EthernetShield_SysEx.ino @@ -1,5 +1,7 @@ #include +#define SerialMon Serial +#define APPLEMIDI_DEBUG SerialMon #include USING_NAMESPACE_APPLEMIDI @@ -34,29 +36,23 @@ APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); // ----------------------------------------------------------------------------- void setup() { - Serial.begin(115200); - while (!Serial); - Serial.println("Booting"); - - Serial.println(F("Getting IP address...")); + SerialMon.begin(115200); + while (!SerialMon); + + DBG("Booting"); if (Ethernet.begin(mac) == 0) { - Serial.println(F("Failed DHCP, check network cable & reboot")); + DBG(F("Failed DHCP, check network cable & reboot")); for (;;); } - Serial.print("IP address is "); - Serial.println(Ethernet.localIP()); - - Serial.println(F("OK, now make sure you an rtpMIDI session that is Enabled")); - Serial.print(F("Add device named Arduino with Host/Port ")); - Serial.print(Ethernet.localIP()); - Serial.println(F(":5004")); - Serial.println(F("Then press the Connect button")); - Serial.println(F("Then open a MIDI listener (eg MIDI-OX) and monitor incoming notes")); + DBG(F("OK, now make sure you an rtpMIDI session that is Enabled")); + DBG(F("Add device named Arduino with Host"), Ethernet.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); + DBG(F("Then press the Connect button")); + DBG(F("Then open a MIDI listener and monitor incoming notes")); + DBG(F("Listen to incoming MIDI commands")); - // Create a session and wait for a remote host to connect to us - MIDI.begin(1); + MIDI.begin(); // check: zien we de connecttion binnenkomen?? Anders terug een ref van makenDw AppleMIDI.setHandleConnected(OnAppleMidiConnected); @@ -64,7 +60,7 @@ void setup() MIDI.setHandleSystemExclusive(OnMidiSysEx); - Serial.println(F("Every second send a random NoteOn/Off")); + DBG(F("Send and Receive SysEx")); } // ----------------------------------------------------------------------------- @@ -93,8 +89,7 @@ void loop() // ----------------------------------------------------------------------------- void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { isConnected = true; - Serial.print(F("Connected to session ")); - Serial.println(name); + DBG(F("Connected to session"), name); } // ----------------------------------------------------------------------------- @@ -102,24 +97,24 @@ void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { // ----------------------------------------------------------------------------- void OnAppleMidiDisconnected(const ssrc_t & ssrc) { isConnected = false; - Serial.println(F("Disconnected")); + DBG(F("Disconnected")); } // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void OnMidiSysEx(byte* data, unsigned length) { - Serial.print(F("SYSEX: (")); - Serial.print(getSysExStatus(data, length)); - Serial.print(F(", ")); - Serial.print(length); - Serial.print(F(" bytes) ")); + SerialMon.print(F("SYSEX: (")); + SerialMon.print(getSysExStatus(data, length)); + SerialMon.print(F(", ")); + SerialMon.print(length); + SerialMon.print(F(" bytes) ")); for (uint16_t i = 0; i < length; i++) { - Serial.print(data[i], HEX); - Serial.print(" "); + SerialMon.print(data[i], HEX); + SerialMon.print(" "); } - Serial.println(); + SerialMon.println(); } char getSysExStatus(const byte* data, uint16_t length) diff --git a/examples/MKR_ETH_Bonjour/MKR_ETH_Bonjour.ino b/examples/MKR_ETH_Bonjour/MKR_ETH_Bonjour.ino new file mode 100644 index 0000000..baaaf47 --- /dev/null +++ b/examples/MKR_ETH_Bonjour/MKR_ETH_Bonjour.ino @@ -0,0 +1,47 @@ +#include +#include // https://github.com/TrippyLighting/EthernetBonjour + +#define OPTIONAL_MDNS + +#include +USING_NAMESPACE_APPLEMIDI + +// Enter a MAC address for your controller below. +// Newer Ethernet shields have a MAC address printed on a sticker on the shield +byte mac[] = { + 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED +}; + +APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +void setup() +{ + if (Ethernet.begin(mac) == 0) + for (;;); + + MIDI.begin(); + + // Initialize the Bonjour/MDNS library. You can now reach or ping this + // Arduino via the host name "arduino.local", provided that your operating + // system is Bonjour-enabled (such as MacOS X). + // Always call this before any other method! + EthernetBonjour.begin("arduino"); + + EthernetBonjour.addServiceRecord("Arduino._apple-midi", + AppleMIDI.getPort(), + MDNSServiceUDP); +} + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +void loop() +{ + // Listen to incoming notes + MIDI.read(); + + EthernetBonjour.run(); +} diff --git a/examples/wESP32_NoteOnOffEverySec/ETH_Helper.h b/examples/wESP32_NoteOnOffEverySec/ETH_Helper.h index e997fad..b17969b 100644 --- a/examples/wESP32_NoteOnOffEverySec/ETH_Helper.h +++ b/examples/wESP32_NoteOnOffEverySec/ETH_Helper.h @@ -7,32 +7,25 @@ void WiFiEvent(WiFiEvent_t event) { switch (event) { case SYSTEM_EVENT_ETH_START: - Serial.println("ETH Started"); + DBG("ETH Started"); //set eth hostname here ETH.setHostname("esp32-ethernet"); break; case SYSTEM_EVENT_ETH_CONNECTED: - Serial.println("ETH Connected"); + DBG("ETH Connected"); break; case SYSTEM_EVENT_ETH_GOT_IP: - Serial.print("ETH MAC: "); - Serial.print(ETH.macAddress()); - Serial.print(", IPv4: "); - Serial.print(ETH.localIP()); - if (ETH.fullDuplex()) { - Serial.print(", FULL_DUPLEX"); - } - Serial.print(", "); - Serial.print(ETH.linkSpeed()); - Serial.println("Mbps"); + DBG("ETH MAC:", ETH.macAddress(), "IPv4:", ETH.localIP(), ETH.linkSpeed(), "Mbps"); + if (ETH.fullDuplex()) + DBG("FULL_DUPLEX"); eth_connected = true; break; case SYSTEM_EVENT_ETH_DISCONNECTED: - Serial.println("ETH Disconnected"); + DBG("ETH Disconnected"); eth_connected = false; break; case SYSTEM_EVENT_ETH_STOP: - Serial.println("ETH Stopped"); + DBG("ETH Stopped"); eth_connected = false; break; default: @@ -45,7 +38,7 @@ bool ETH_startup() WiFi.onEvent(WiFiEvent); ETH.begin(); - Serial.println(F("Getting IP address...")); + DBG(F("Getting IP address...")); while (!eth_connected) delay(100); diff --git a/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino b/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino index a56fc5d..3e47216 100644 --- a/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino +++ b/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino @@ -1,54 +1,47 @@ -#include "ETH_Helper.h" - -#define APPLEMIDI_INITIATOR +#define SerialMon Serial +#define APPLEMIDI_DEBUG SerialMon #include USING_NAMESPACE_APPLEMIDI +#include "ETH_Helper.h" + unsigned long t0 = millis(); bool isConnected = false; -APPLEMIDI_CREATE_DEFAULTSESSION_ESP32_INSTANCE(); +APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void setup() { - Serial.begin(115200); - while (!Serial); - Serial.println("Booting"); + SerialMon.begin(115200); + while (!SerialMon); + + DBG("Booting"); ETH_startup(); MDNS.begin(AppleMIDI.getName()); - Serial.print("IP address is "); - Serial.println(ETH.localIP()); + DBG(F("OK, now make sure you an rtpMIDI session that is Enabled")); + DBG(F("Add device named Arduino with Host"), WiFi.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); + DBG(F("Then press the Connect button")); + DBG(F("Then open a MIDI listener and monitor incoming notes")); + DBG(F("Listen to incoming MIDI commands")); - Serial.println(F("OK, now make sure you an rtpMIDI session that is Enabled")); - Serial.print(F("Add device named Arduino with Host/Port ")); - Serial.print(ETH.localIP()); - Serial.println(F(":5004")); - Serial.println(F("Then press the Connect button")); - Serial.println(F("Then open a MIDI listener (eg MIDI-OX) and monitor incoming notes")); - - MIDI.begin(1); // listen on channel 1 + MIDI.begin(); AppleMIDI.setHandleConnected(OnAppleMidiConnected); AppleMIDI.setHandleDisconnected(OnAppleMidiDisconnected); - AppleMIDI.setHandleError(OnAppleMidiError); - MIDI.setHandleNoteOn(OnAppleMidiNoteOn); - MIDI.setHandleNoteOff(OnAppleMidiNoteOff); + MIDI.setHandleNoteOn(OnMidiNoteOn); + MIDI.setHandleNoteOff(OnMidiNoteOff); MDNS.addService("apple-midi", "udp", AppleMIDI.getPort()); 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 + DBG(F("Every second send a random NoteOn/Off")); } // ----------------------------------------------------------------------------- @@ -64,7 +57,6 @@ void loop() if (isConnected && (millis() - t0) > 1000) { t0 = millis(); - // Serial.print(F("."); byte note = random(1, 127); byte velocity = 55; @@ -84,8 +76,7 @@ void loop() // ----------------------------------------------------------------------------- void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { isConnected = true; - Serial.print(F("Connected to session ")); - Serial.println(name); + DBG(F("Connected to session"), name); } // ----------------------------------------------------------------------------- @@ -93,46 +84,19 @@ void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { // ----------------------------------------------------------------------------- void OnAppleMidiDisconnected(const ssrc_t & ssrc) { isConnected = false; - Serial.println(F("Disconnected")); -} - -// ----------------------------------------------------------------------------- -// 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; - } + DBG(F("Disconnected")); } // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- -static void OnAppleMidiNoteOn(byte channel, byte note, byte velocity) { - Serial.print(F("Incoming NoteOn from channel: ")); - Serial.print(channel); - Serial.print(F(", note: ")); - Serial.print(note); - Serial.print(F(", velocity: ")); - Serial.println(velocity); +static void OnMidiNoteOn(byte channel, byte note, byte velocity) { + DBG(F("in\tNote on"), note, " Velocity", velocity, "\t", channel); } // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- -static void OnAppleMidiNoteOff(byte channel, byte note, byte velocity) { - Serial.print(F("Incoming NoteOff from channel: ")); - Serial.print(channel); - Serial.print(F(", note: ")); - Serial.print(note); - Serial.print(F(", velocity: ")); - Serial.println(velocity); -} \ No newline at end of file +static void OnMidiNoteOff(byte channel, byte note, byte velocity) { + DBG(F("in\tNote off"), note, " Velocity", velocity, "\t", channel); +} diff --git a/examples/wESP32_NoteOnOffEverySec_Adv/AppleMIDITask.h b/examples/wESP32_NoteOnOffEverySec_Adv/AppleMIDITask.h deleted file mode 100644 index db700a8..0000000 --- a/examples/wESP32_NoteOnOffEverySec_Adv/AppleMIDITask.h +++ /dev/null @@ -1,102 +0,0 @@ -#include -USING_NAMESPACE_APPLEMIDI - -bool isConnected = false; - -// ==================================================================================== -// Event handlers for incoming MIDI messages -// ==================================================================================== - -// ----------------------------------------------------------------------------- -// rtpMIDI session. Device connected -// ----------------------------------------------------------------------------- -void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { - isConnected = true; - Serial.print(F("Connected to session ")); - Serial.println(name); -} - -// ----------------------------------------------------------------------------- -// rtpMIDI session. Device disconnected -// ----------------------------------------------------------------------------- -void OnAppleMidiDisconnected(const ssrc_t & ssrc) { - isConnected = false; - Serial.println(F("Disconnected")); -} - -// ----------------------------------------------------------------------------- -// -// ----------------------------------------------------------------------------- -static void OnAppleMidiNoteOn(byte channel, byte note, byte velocity) { - Serial.print(F("Incoming NoteOn from channel: ")); - Serial.print(channel); - Serial.print(F(", note: ")); - Serial.print(note); - Serial.print(F(", velocity: ")); - Serial.println(velocity); -} - -// ----------------------------------------------------------------------------- -// -// ----------------------------------------------------------------------------- -static void OnAppleMidiNoteOff(byte channel, byte note, byte velocity) { - Serial.print(F("Incoming NoteOff from channel: ")); - Serial.print(channel); - Serial.print(F(", note: ")); - Serial.print(note); - Serial.print(F(", velocity: ")); - Serial.println(velocity); -} - -void TaskAppleMIDIcode(void* pvParameters) -{ - APPLEMIDI_CREATE_DEFAULTSESSION_ESP32_INSTANCE(); - - Serial.print("AppleMIDI running on core "); - Serial.println(xPortGetCoreID()); - - Serial.println(F("Every second send a random NoteOn/Off")); - - Serial.println(F("OK, now make sure you an rtpMIDI session that is Enabled")); - Serial.print(F("Add device named Arduino with Host/Port ")); - Serial.print(ETH.localIP()); - Serial.println(F(":5004")); - Serial.println(F("Then press the Connect button")); - Serial.println(F("Then open a MIDI listener (eg MIDI-OX) and monitor incoming notes")); - - AppleMIDI.setHandleConnected(OnAppleMidiConnected); - AppleMIDI.setHandleDisconnected(OnAppleMidiDisconnected); - - MIDI.setHandleNoteOn(OnAppleMidiNoteOn); - MIDI.setHandleNoteOff(OnAppleMidiNoteOff); - - MDNS.addService("apple-midi", "udp", AppleMIDI.getPort()); - - MIDI.begin(1); // listen on channel 1 - - auto t0 = millis(); - while (true) - { - // Listen to incoming notes - MIDI.read(); - - // send a note every second - // (dont cáll delay(1000) as it will stall the pipeline) - if ((millis() - t0) > 1000) - { - t0 = millis(); - - if (isConnected) - { - byte note = random(1, 127); - byte velocity = 55; - byte channel = 1; - - Serial.println("Sending notes"); - - MIDI.sendNoteOn(note, velocity, channel); - MIDI.sendNoteOff(note, velocity, channel); - } - } - } -} diff --git a/examples/wESP32_NoteOnOffEverySec_Adv/ETH_Helper.h b/examples/wESP32_NoteOnOffEverySec_Adv/ETH_Helper.h deleted file mode 100644 index e997fad..0000000 --- a/examples/wESP32_NoteOnOffEverySec_Adv/ETH_Helper.h +++ /dev/null @@ -1,54 +0,0 @@ -#include -#include - -static bool eth_connected = false; - -void WiFiEvent(WiFiEvent_t event) -{ - switch (event) { - case SYSTEM_EVENT_ETH_START: - Serial.println("ETH Started"); - //set eth hostname here - ETH.setHostname("esp32-ethernet"); - break; - case SYSTEM_EVENT_ETH_CONNECTED: - Serial.println("ETH Connected"); - break; - case SYSTEM_EVENT_ETH_GOT_IP: - Serial.print("ETH MAC: "); - Serial.print(ETH.macAddress()); - Serial.print(", IPv4: "); - Serial.print(ETH.localIP()); - if (ETH.fullDuplex()) { - Serial.print(", FULL_DUPLEX"); - } - Serial.print(", "); - Serial.print(ETH.linkSpeed()); - Serial.println("Mbps"); - eth_connected = true; - break; - case SYSTEM_EVENT_ETH_DISCONNECTED: - Serial.println("ETH Disconnected"); - eth_connected = false; - break; - case SYSTEM_EVENT_ETH_STOP: - Serial.println("ETH Stopped"); - eth_connected = false; - break; - default: - break; - } -} - -bool ETH_startup() -{ - WiFi.onEvent(WiFiEvent); - ETH.begin(); - - Serial.println(F("Getting IP address...")); - - while (!eth_connected) - delay(100); - - return true; -} diff --git a/examples/wESP32_NoteOnOffEverySec_Adv/WebServerTask.h b/examples/wESP32_NoteOnOffEverySec_Adv/WebServerTask.h deleted file mode 100644 index 932206e..0000000 --- a/examples/wESP32_NoteOnOffEverySec_Adv/WebServerTask.h +++ /dev/null @@ -1,63 +0,0 @@ -void TaskWebServercode(void* pvParameters) -{ - Serial.print("WebServer running on core "); - Serial.println(xPortGetCoreID()); - - MDNS.addService("http", "tcp", 80); - - WiFiServer server(80); - server.begin(); - - while (true) - { - delay(100); - // Check if a client has connected - WiFiClient client = server.available(); - if (!client) - continue; - - Serial.println(""); - Serial.println("New client"); - - // Wait for data from client to become available - while (client.connected() && !client.available()) { - delay(1); - } - - // Read the first line of HTTP request - String req = client.readStringUntil('\r'); - - // First line of HTTP request looks like "GET /path HTTP/1.1" - // Retrieve the "/path" part by finding the spaces - int addr_start = req.indexOf(' '); - int addr_end = req.indexOf(' ', addr_start + 1); - if (addr_start == -1 || addr_end == -1) { - Serial.print("Invalid request: "); - Serial.println(req); - return; - } - req = req.substring(addr_start + 1, addr_end); - Serial.print("Request: "); - Serial.println(req); - - String s; - if (req == "/") - { - IPAddress ip = WiFi.localIP(); - String ipStr = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]); - s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n\r\nHello from ESP32 at "; - s += ipStr; - s += "\r\n\r\n"; - Serial.println("Sending 200"); - } - else - { - s = "HTTP/1.1 404 Not Found\r\n\r\n"; - Serial.println("Sending 404"); - } - client.print(s); - - client.stop(); - Serial.println("Done with client"); - } -} diff --git a/examples/wESP32_NoteOnOffEverySec_Adv/wESP32_NoteOnOffEverySec_Adv.ino b/examples/wESP32_NoteOnOffEverySec_Adv/wESP32_NoteOnOffEverySec_Adv.ino deleted file mode 100644 index 708e9b4..0000000 --- a/examples/wESP32_NoteOnOffEverySec_Adv/wESP32_NoteOnOffEverySec_Adv.ino +++ /dev/null @@ -1,42 +0,0 @@ -#include "ETH_Helper.h" - -#include "WebServerTask.h" -#include "AppleMIDITask.h" - -TaskHandle_t TaskWebServer; -TaskHandle_t TaskAppleMIDI; - -void setup() -{ - Serial.begin(115200); - while (!Serial); - Serial.println("Booting"); - - ETH_startup(); - - MDNS.begin("ESP32"); - - //create a task that will be executed in the Task2code() function, with priority 1 and executed on core 1 - xTaskCreatePinnedToCore( - TaskWebServercode, // Task function. - "WebServer", // name of task. - 10000, // Stack size of task - NULL, // parameter of the task - tskIDLE_PRIORITY, // priority of the task - &TaskWebServer, // Task handle to keep track of created task - 0); // pin task to core 0 - - //create a task that will be executed in the Task1code() function, with priority 1 and executed on core 0 - xTaskCreatePinnedToCore( - TaskAppleMIDIcode, // Task function. - "AppleMIDI", // name of task. - 10000, // Stack size of task - NULL, // parameter of the task - tskIDLE_PRIORITY + 1, // priority of the task - &TaskAppleMIDI, // Task handle to keep track of created task - 1); // pin task to core 1 -} - -void loop() -{ -} diff --git a/keywords.txt b/keywords.txt index 0a0a68d..5f762b5 100644 --- a/keywords.txt +++ b/keywords.txt @@ -14,7 +14,9 @@ AppleMidi KEYWORD1 setHandleConnected KEYWORD2 setHandleDisconnected KEYWORD2 setHandleError KEYWORD2 +setHandleStartReceivedMidi KEYWORD2 setHandleReceivedMidi KEYWORD2 +setHandleEndReceivedMidi KEYWORD2 setHandleReceivedRtp KEYWORD2 setHandleNoteOff KEYWORD2 @@ -73,5 +75,4 @@ MIDI KEYWORD3 ####################################### APPLEMIDI_CREATE_INSTANCE LITERAL1 -APPLEMIDI_CREATE_DEFAULTSESSION_ESP32_INSTANCE LITERAL1 APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE LITERAL1 diff --git a/src/AppleMIDI.h b/src/AppleMIDI.h index 8d0331e..74541e1 100644 --- a/src/AppleMIDI.h +++ b/src/AppleMIDI.h @@ -293,10 +293,15 @@ END_APPLEMIDI_NAMESPACE APPLEMIDI_NAMESPACE::AppleMIDISession Apple##Name(SessionName, Port); \ MIDI_NAMESPACE::MidiInterface, APPLEMIDI_NAMESPACE::AppleMIDISettings> Name((APPLEMIDI_NAMESPACE::AppleMIDISession&)Apple##Name); +#if defined(ARDUINO_ARCH_ESP32) || defined(ESP32) #define APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE() \ -APPLEMIDI_CREATE_INSTANCE(EthernetUDP, MIDI, "Arduino", DEFAULT_CONTROL_PORT); - -#define APPLEMIDI_CREATE_DEFAULTSESSION_ESP32_INSTANCE() \ -APPLEMIDI_CREATE_INSTANCE(WiFiUDP, MIDI, "ESP32", DEFAULT_CONTROL_PORT); +APPLEMIDI_CREATE_INSTANCE(WiFiUDP, MIDI, "AppleMIDI-ESP32", DEFAULT_CONTROL_PORT); +#elif defined(ESP8266) +#define APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE() \ +APPLEMIDI_CREATE_INSTANCE(WiFiUDP, MIDI, "AppleMIDI-ESP8266", DEFAULT_CONTROL_PORT); +#else +#define APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE() \ +APPLEMIDI_CREATE_INSTANCE(EthernetUDP, MIDI, "AppleMIDI-Arduino", DEFAULT_CONTROL_PORT); +#endif #include "AppleMIDI_PlatformEnd.h" diff --git a/test/Ethernet.h b/test/Ethernet.h index 59d9f3b..656a89c 100644 --- a/test/Ethernet.h +++ b/test/Ethernet.h @@ -19,12 +19,12 @@ class EthernetUDP { _port = port; - if (port == 5004 && true) + if (port == DEFAULT_CONTROL_PORT && true) { // AppleMIDI messages } - if (port == 5005 && true) + if (port == (DEFAULT_CONTROL_PORT + 1) && true) { // rtp-MIDI and AppleMIDI messages diff --git a/test/NoteOn.cpp b/test/NoteOn.cpp index a4ab27b..228c6c6 100644 --- a/test/NoteOn.cpp +++ b/test/NoteOn.cpp @@ -35,8 +35,7 @@ APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); // ----------------------------------------------------------------------------- void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { isConnected = true; - N_DEBUG_PRINT(F("Connected to session ")); - N_DEBUG_PRINTLN(name); + DBG(F("Connected to session"), name); } // ----------------------------------------------------------------------------- @@ -59,24 +58,14 @@ void OnAppleMidiByte(const ssrc_t & ssrc, byte data) { // // ----------------------------------------------------------------------------- static void OnMidiNoteOn(byte channel, byte note, byte velocity) { - N_DEBUG_PRINT(F("Incoming NoteOn from channel: ")); - N_DEBUG_PRINT(channel); - N_DEBUG_PRINT(F(", note: ")); - N_DEBUG_PRINT(note); - N_DEBUG_PRINT(F(", velocity: ")); - N_DEBUG_PRINTLN(velocity); + DBG(F("in\tNote on"), note, " Velocity", velocity, "\t", channel); } // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- static void OnMidiNoteOff(byte channel, byte note, byte velocity) { - N_DEBUG_PRINT(F("Incoming NoteOff from channel: ")); - N_DEBUG_PRINT(channel); - N_DEBUG_PRINT(F(", note: ")); - N_DEBUG_PRINT(note); - N_DEBUG_PRINT(F(", velocity: ")); - N_DEBUG_PRINTLN(velocity); + DBG(F("in\tNote off"), note, " Velocity", velocity, "\t", channel); } // ----------------------------------------------------------------------------- @@ -110,14 +99,13 @@ static void OnMidiSystemExclusive(byte* array, unsigned size) { void begin() { - V_DEBUG_PRINTLN(F("OK, now make sure you an rtpMIDI session that is Enabled")); - V_DEBUG_PRINT(F("Add device named Arduino with Host/Port ")); - // V_DEBUG_PRINT(Ethernet.localIP()); - V_DEBUG_PRINTLN(F(":5004")); - V_DEBUG_PRINTLN(F("Then press the Connect button")); - V_DEBUG_PRINTLN(F("Then open a MIDI listener (eg MIDI-OX) and monitor incoming notes")); - - MIDI.begin(1); + DBG(F("OK, now make sure you an rtpMIDI session that is Enabled")); + DBG(F("Add device named Arduino with Host"), Ethernet.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); + DBG(F("Then press the Connect button")); + DBG(F("Then open a MIDI listener and monitor incoming notes")); + DBG(F("Listen to incoming MIDI commands")); + + MIDI.begin(); AppleMIDI.setHandleConnected(OnAppleMidiConnected); AppleMIDI.setHandleDisconnected(OnAppleMidiDisconnected); @@ -140,7 +128,6 @@ void loop() if (isConnected && (millis() - t0) > 10000) { t0 = millis(); - // Serial.print(F("."); byte note = random(1, 127); byte velocity = 55; From d8a85a3c6c85a93e5ff23f25ead2137cd1d2e7bd Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sat, 31 Oct 2020 10:56:42 +0100 Subject: [PATCH 035/271] added getSynchronizationSource --- src/AppleMIDI.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/AppleMIDI.h b/src/AppleMIDI.h index 74541e1..09177f5 100644 --- a/src/AppleMIDI.h +++ b/src/AppleMIDI.h @@ -61,7 +61,8 @@ class AppleMIDISession const char* getName() { return this->localName; }; const uint16_t getPort() { return this->port; }; - + const ssrc_t getSynchronizationSource() { return this->ssrc; }; + #ifdef APPLEMIDI_INITIATOR bool sendInvite(IPAddress ip, uint16_t port = DEFAULT_CONTROL_PORT); #endif From 178d3dc01bc77bfdd05c0dddccd5c25a146553b4 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sun, 22 Nov 2020 15:52:00 +0100 Subject: [PATCH 036/271] add SetName added a setting for the SessionName --- src/AppleMIDI.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/AppleMIDI.h b/src/AppleMIDI.h index 09177f5..23c5fa8 100644 --- a/src/AppleMIDI.h +++ b/src/AppleMIDI.h @@ -45,10 +45,10 @@ class AppleMIDISession friend class rtpMIDIParser; public: - AppleMIDISession(const char *name, const uint16_t port = DEFAULT_CONTROL_PORT) + AppleMIDISession(const char *sessionName, const uint16_t port = DEFAULT_CONTROL_PORT) { this->port = port; - strncpy(this->localName, name, DefaultSettings::MaxSessionNameLen); + strncpy(this->localName, sessionName, DefaultSettings::MaxSessionNameLen); }; void setHandleConnected(void (*fptr)(const ssrc_t&, const char*)) { _connectedCallback = fptr; } @@ -63,6 +63,8 @@ class AppleMIDISession const uint16_t getPort() { return this->port; }; const ssrc_t getSynchronizationSource() { return this->ssrc; }; + void setName(const char *sessionName) { strncpy(this->localName, sessionName, DefaultSettings::MaxSessionNameLen); }; + #ifdef APPLEMIDI_INITIATOR bool sendInvite(IPAddress ip, uint16_t port = DEFAULT_CONTROL_PORT); #endif From ee3e5edf0440c4e8e6a480122d27efb4c04a6132 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Tue, 24 Nov 2020 09:26:54 +0100 Subject: [PATCH 037/271] Create codeql-analysis.yml --- .github/workflows/codeql-analysis.yml | 67 +++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 .github/workflows/codeql-analysis.yml diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 0000000..3925795 --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,67 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ master ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ master ] + schedule: + - cron: '30 16 * * 2' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + language: [ 'cpp' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] + # Learn more: + # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 From 3b5c368868d8bb289ef3658d654a2759cf77ea7b Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sat, 19 Dec 2020 09:12:00 +0100 Subject: [PATCH 038/271] Delete codeql-analysis.yml --- .github/workflows/codeql-analysis.yml | 67 --------------------------- 1 file changed, 67 deletions(-) delete mode 100644 .github/workflows/codeql-analysis.yml diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml deleted file mode 100644 index 3925795..0000000 --- a/.github/workflows/codeql-analysis.yml +++ /dev/null @@ -1,67 +0,0 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# -name: "CodeQL" - -on: - push: - branches: [ master ] - pull_request: - # The branches below must be a subset of the branches above - branches: [ master ] - schedule: - - cron: '30 16 * * 2' - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - - strategy: - fail-fast: false - matrix: - language: [ 'cpp' ] - # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] - # Learn more: - # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed - - steps: - - name: Checkout repository - uses: actions/checkout@v2 - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v1 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main - - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v1 - - # ℹ️ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl - - # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language - - #- run: | - # make bootstrap - # make release - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 From 01b8f829bddd670ae3226442bbfc73887f200abe Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sat, 19 Dec 2020 09:52:17 +0100 Subject: [PATCH 039/271] simply, branch out debug --- .travis.yml | 3 +- examples/ESP32_Callbacks/ESP32_Callbacks.ino | 11 +++---- .../ESP8266_NoteOnOffEverySec.ino | 10 ++----- .../EthernetShield_Initiator.ino | 8 ++--- .../EthernetShield_MultipleSessions.ino | 8 ++--- .../EthernetShield_NonDefaultSession.ino | 8 ++--- .../EthernetShield_NoteOnOffEverySec.ino | 8 ++--- .../EthernetShield_ReceivedRawMidiData.ino | 15 ++++------ .../EthernetShield_SysEx.ino | 10 +++---- examples/MKR_ETH_Bonjour/MKR_ETH_Bonjour.ino | 1 - .../wESP32_NoteOnOffEverySec.ino | 9 ++---- src/AppleMIDI.h | 2 ++ src/AppleMIDI_Debug.h | 29 +++++++++++++++++++ src/AppleMIDI_Defs.h | 24 --------------- test/NoteOn.cpp | 27 +++++++++-------- 15 files changed, 78 insertions(+), 95 deletions(-) create mode 100644 src/AppleMIDI_Debug.h diff --git a/.travis.yml b/.travis.yml index 99f8144..a77ea17 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,4 +13,5 @@ install: - platformio lib -g install 62@5.0.0 870 872 script: -- platformio ci --board=uno --lib=. examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino; +- platformio ci --board=uno --lib=. examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino; +- platformio ci --board=esp32dev --lib=. examples/\ESP8266_NoteOnOffEverySec/\ESP8266_NoteOnOffEverySec.ino; diff --git a/examples/ESP32_Callbacks/ESP32_Callbacks.ino b/examples/ESP32_Callbacks/ESP32_Callbacks.ino index 9edb964..42fd559 100644 --- a/examples/ESP32_Callbacks/ESP32_Callbacks.ino +++ b/examples/ESP32_Callbacks/ESP32_Callbacks.ino @@ -3,7 +3,6 @@ #define SerialMon Serial #define APPLEMIDI_DEBUG SerialMon #include -USING_NAMESPACE_APPLEMIDI #include "arduino_secrets.h" @@ -12,9 +11,7 @@ bool isConnected = false; APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); void setup() { - SerialMon.begin(115200); - while (!SerialMon); - + DBG_SETUP(115200); DBG("Booting"); WiFi.begin(SECRET_SSID, SECRET_PASS); @@ -65,7 +62,7 @@ void loop() { // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- -void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { +void OnAppleMidiConnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { isConnected = true; DBG(F("Connected to session"), name); } @@ -73,7 +70,7 @@ void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- -void OnAppleMidiDisconnected(const ssrc_t & ssrc) { +void OnAppleMidiDisconnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { isConnected = false; DBG(F("Disconnected")); } @@ -81,7 +78,7 @@ DBG(F("Disconnected")); // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- -void OnAppleMidiError(const ssrc_t& ssrc, int32_t err) { +void OnAppleMidiError(const APPLEMIDI_NAMESPACE::ssrc_t& ssrc, int32_t err) { switch (err) { case Exception::BufferFullException: diff --git a/examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino b/examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino index 6c4eb84..db95d13 100644 --- a/examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino +++ b/examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino @@ -5,7 +5,6 @@ #define SerialMon Serial #define APPLEMIDI_DEBUG SerialMon #include -USING_NAMESPACE_APPLEMIDI char ssid[] = "yourNetwork"; // your network SSID (name) char pass[] = "password"; // your network password (use for WPA, or use as key for WEP) @@ -26,10 +25,7 @@ void OnMidiNoteOff(byte channel, byte note, byte velocity); // ----------------------------------------------------------------------------- void setup() { - // Serial communications and wait for port to open: - SerialMon.begin(115200); - while (!SerialMon); - + DBG_SETUP(115200); DBG("Booting"); WiFi.begin(ssid, pass); @@ -87,7 +83,7 @@ void loop() // ----------------------------------------------------------------------------- // rtpMIDI session. Device connected // ----------------------------------------------------------------------------- -void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { +void OnAppleMidiConnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { isConnected = true; DBG(F("Connected to session"), name); } @@ -95,7 +91,7 @@ void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { // ----------------------------------------------------------------------------- // rtpMIDI session. Device disconnected // ----------------------------------------------------------------------------- -void OnAppleMidiDisconnected(const ssrc_t & ssrc) { +void OnAppleMidiDisconnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { isConnected = false; DBG(F("Disconnected")); } diff --git a/examples/EthernetShield_Initiator/EthernetShield_Initiator.ino b/examples/EthernetShield_Initiator/EthernetShield_Initiator.ino index 9b2ab36..5466937 100644 --- a/examples/EthernetShield_Initiator/EthernetShield_Initiator.ino +++ b/examples/EthernetShield_Initiator/EthernetShield_Initiator.ino @@ -4,7 +4,6 @@ #define APPLEMIDI_DEBUG SerialMon #define APPLEMIDI_INITIATOR #include -USING_NAMESPACE_APPLEMIDI // Enter a MAC address for your controller below. // Newer Ethernet shields have a MAC address printed on a sticker on the shield @@ -22,8 +21,7 @@ APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); // ----------------------------------------------------------------------------- void setup() { - SerialMon.begin(115200); - while (!SerialMon); + DBG_SETUP(115200); DBG("Booting"); if (Ethernet.begin(mac) == 0) { @@ -84,7 +82,7 @@ void loop() // ----------------------------------------------------------------------------- // rtpMIDI session. Device connected // ----------------------------------------------------------------------------- -void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { +void OnAppleMidiConnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { isConnected = true; DBG(F("Connected to session"), name); } @@ -92,7 +90,7 @@ void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { // ----------------------------------------------------------------------------- // rtpMIDI session. Device disconnected // ----------------------------------------------------------------------------- -void OnAppleMidiDisconnected(const ssrc_t & ssrc) { +void OnAppleMidiDisconnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { isConnected = false; DBG(F("Disconnected")); } diff --git a/examples/EthernetShield_MultipleSessions/EthernetShield_MultipleSessions.ino b/examples/EthernetShield_MultipleSessions/EthernetShield_MultipleSessions.ino index 7b6fe77..bed7b36 100644 --- a/examples/EthernetShield_MultipleSessions/EthernetShield_MultipleSessions.ino +++ b/examples/EthernetShield_MultipleSessions/EthernetShield_MultipleSessions.ino @@ -3,7 +3,6 @@ #define SerialMon Serial #define APPLEMIDI_DEBUG SerialMon #include -USING_NAMESPACE_APPLEMIDI // Enter a MAC address for your controller below. // Newer Ethernet shields have a MAC address printed on a sticker on the shield @@ -22,8 +21,7 @@ APPLEMIDI_CREATE_INSTANCE(EthernetUDP, MIDI2, "Arduino2", DEFAULT_CONTROL_PORT + // ----------------------------------------------------------------------------- void setup() { - SerialMon.begin(115200); - while (!SerialMon); + DBG_SETUP(115200); DBG("Booting"); if (Ethernet.begin(mac) == 0) { @@ -84,7 +82,7 @@ void loop() // ----------------------------------------------------------------------------- // rtpMIDI session. Device connected // ----------------------------------------------------------------------------- -void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { +void OnAppleMidiConnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { isConnected = true; DBG(F("Connected to session"), name); } @@ -92,7 +90,7 @@ void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { // ----------------------------------------------------------------------------- // rtpMIDI session. Device disconnected // ----------------------------------------------------------------------------- -void OnAppleMidiDisconnected(const ssrc_t & ssrc) { +void OnAppleMidiDisconnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { isConnected = false; DBG(F("Disconnected")); } diff --git a/examples/EthernetShield_NonDefaultSession/EthernetShield_NonDefaultSession.ino b/examples/EthernetShield_NonDefaultSession/EthernetShield_NonDefaultSession.ino index 279857e..8a10c59 100644 --- a/examples/EthernetShield_NonDefaultSession/EthernetShield_NonDefaultSession.ino +++ b/examples/EthernetShield_NonDefaultSession/EthernetShield_NonDefaultSession.ino @@ -3,7 +3,6 @@ #define SerialMon Serial #define APPLEMIDI_DEBUG SerialMon #include -USING_NAMESPACE_APPLEMIDI // Enter a MAC address for your controller below. // Newer Ethernet shields have a MAC address printed on a sticker on the shield @@ -26,8 +25,7 @@ APPLEMIDI_CREATE_INSTANCE(EthernetUDP, MIDI, "MyNamedArduino", DEFAULT_CONTROL_P // ----------------------------------------------------------------------------- void setup() { - SerialMon.begin(115200); - while (!SerialMon); + DBG_SETUP(115200); DBG("Booting"); if (Ethernet.begin(mac) == 0) { @@ -80,7 +78,7 @@ void loop() // ----------------------------------------------------------------------------- // rtpMIDI session. Device connected // ----------------------------------------------------------------------------- -void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { +void OnAppleMidiConnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { isConnected = true; DBG(F("Connected to session"), name); } @@ -88,7 +86,7 @@ void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { // ----------------------------------------------------------------------------- // rtpMIDI session. Device disconnected // ----------------------------------------------------------------------------- -void OnAppleMidiDisconnected(const ssrc_t & ssrc) { +void OnAppleMidiDisconnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { isConnected = false; DBG(F("Disconnected")); } diff --git a/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino b/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino index 505eef8..3c19ef6 100644 --- a/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino +++ b/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino @@ -3,7 +3,6 @@ #define SerialMon Serial #define APPLEMIDI_DEBUG SerialMon #include -USING_NAMESPACE_APPLEMIDI // Enter a MAC address for your controller below. // Newer Ethernet shields have a MAC address printed on a sticker on the shield @@ -21,8 +20,7 @@ APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); // ----------------------------------------------------------------------------- void setup() { - SerialMon.begin(115200); - while (!SerialMon); + DBG_SETUP(115200); DBG("Booting"); if (Ethernet.begin(mac) == 0) { @@ -75,7 +73,7 @@ void loop() // ----------------------------------------------------------------------------- // rtpMIDI session. Device connected // ----------------------------------------------------------------------------- -void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { +void OnAppleMidiConnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { isConnected = true; DBG(F("Connected to session"), name); } @@ -83,7 +81,7 @@ void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { // ----------------------------------------------------------------------------- // rtpMIDI session. Device disconnected // ----------------------------------------------------------------------------- -void OnAppleMidiDisconnected(const ssrc_t & ssrc) { +void OnAppleMidiDisconnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { isConnected = false; DBG(F("Disconnected")); } diff --git a/examples/EthernetShield_ReceivedRawMidiData/EthernetShield_ReceivedRawMidiData.ino b/examples/EthernetShield_ReceivedRawMidiData/EthernetShield_ReceivedRawMidiData.ino index 49521dc..1750a8c 100644 --- a/examples/EthernetShield_ReceivedRawMidiData/EthernetShield_ReceivedRawMidiData.ino +++ b/examples/EthernetShield_ReceivedRawMidiData/EthernetShield_ReceivedRawMidiData.ino @@ -3,7 +3,6 @@ #define SerialMon Serial #define APPLEMIDI_DEBUG SerialMon #include -USING_NAMESPACE_APPLEMIDI // Enter a MAC address for your controller below. // Newer Ethernet shields have a MAC address printed on a sticker on the shield @@ -21,9 +20,7 @@ APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); // ----------------------------------------------------------------------------- void setup() { - SerialMon.begin(115200); - while (!SerialMon); - + DBG_SETUP(115200); DBG("Booting"); if (Ethernet.begin(mac) == 0) { @@ -68,7 +65,7 @@ void loop() // ----------------------------------------------------------------------------- // rtpMIDI session. Device connected // ----------------------------------------------------------------------------- -void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { +void OnAppleMidiConnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { isConnected = true; DBG(F("Connected to session"), name); } @@ -76,7 +73,7 @@ void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { // ----------------------------------------------------------------------------- // rtpMIDI session. Device disconnected // ----------------------------------------------------------------------------- -void OnAppleMidiDisconnected(const ssrc_t & ssrc) { +void OnAppleMidiDisconnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { isConnected = false; DBG(F("Disconnected")); } @@ -84,21 +81,21 @@ void OnAppleMidiDisconnected(const ssrc_t & ssrc) { // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- -void OnAppleMidiStartReceived(const ssrc_t & ssrc) { +void OnAppleMidiStartReceived(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { DBG(F("Start receiving"), ssrc); } // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- -void OnAppleMidiReceivedByte(const ssrc_t & ssrc, byte data) { +void OnAppleMidiReceivedByte(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, byte data) { SerialMon.println(data, HEX); } // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- -void OnAppleMidiEndReceive(const ssrc_t & ssrc) { +void OnAppleMidiEndReceive(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { DBG(F("End receiving"), ssrc); } diff --git a/examples/EthernetShield_SysEx/EthernetShield_SysEx.ino b/examples/EthernetShield_SysEx/EthernetShield_SysEx.ino index 0d02e86..8ffe6ea 100644 --- a/examples/EthernetShield_SysEx/EthernetShield_SysEx.ino +++ b/examples/EthernetShield_SysEx/EthernetShield_SysEx.ino @@ -3,7 +3,7 @@ #define SerialMon Serial #define APPLEMIDI_DEBUG SerialMon #include -USING_NAMESPACE_APPLEMIDI + // Enter a MAC address for your controller below. // Newer Ethernet shields have a MAC address printed on a sticker on the shield @@ -36,9 +36,7 @@ APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); // ----------------------------------------------------------------------------- void setup() { - SerialMon.begin(115200); - while (!SerialMon); - + DBG_SETUP(115200); DBG("Booting"); if (Ethernet.begin(mac) == 0) { @@ -87,7 +85,7 @@ void loop() // ----------------------------------------------------------------------------- // rtpMIDI session. Device connected // ----------------------------------------------------------------------------- -void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { +void OnAppleMidiConnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { isConnected = true; DBG(F("Connected to session"), name); } @@ -95,7 +93,7 @@ void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { // ----------------------------------------------------------------------------- // rtpMIDI session. Device disconnected // ----------------------------------------------------------------------------- -void OnAppleMidiDisconnected(const ssrc_t & ssrc) { +void OnAppleMidiDisconnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { isConnected = false; DBG(F("Disconnected")); } diff --git a/examples/MKR_ETH_Bonjour/MKR_ETH_Bonjour.ino b/examples/MKR_ETH_Bonjour/MKR_ETH_Bonjour.ino index baaaf47..a2e35f0 100644 --- a/examples/MKR_ETH_Bonjour/MKR_ETH_Bonjour.ino +++ b/examples/MKR_ETH_Bonjour/MKR_ETH_Bonjour.ino @@ -4,7 +4,6 @@ #define OPTIONAL_MDNS #include -USING_NAMESPACE_APPLEMIDI // Enter a MAC address for your controller below. // Newer Ethernet shields have a MAC address printed on a sticker on the shield diff --git a/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino b/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino index 3e47216..c997bdf 100644 --- a/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino +++ b/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino @@ -1,7 +1,6 @@ #define SerialMon Serial #define APPLEMIDI_DEBUG SerialMon #include -USING_NAMESPACE_APPLEMIDI #include "ETH_Helper.h" @@ -15,9 +14,7 @@ APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); // ----------------------------------------------------------------------------- void setup() { - SerialMon.begin(115200); - while (!SerialMon); - + DBG_SETUP(115200); DBG("Booting"); ETH_startup(); @@ -74,7 +71,7 @@ void loop() // ----------------------------------------------------------------------------- // rtpMIDI session. Device connected // ----------------------------------------------------------------------------- -void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { +void OnAppleMidiConnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { isConnected = true; DBG(F("Connected to session"), name); } @@ -82,7 +79,7 @@ void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { // ----------------------------------------------------------------------------- // rtpMIDI session. Device disconnected // ----------------------------------------------------------------------------- -void OnAppleMidiDisconnected(const ssrc_t & ssrc) { +void OnAppleMidiDisconnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { isConnected = false; DBG(F("Disconnected")); } diff --git a/src/AppleMIDI.h b/src/AppleMIDI.h index 23c5fa8..bb7da70 100644 --- a/src/AppleMIDI.h +++ b/src/AppleMIDI.h @@ -7,6 +7,8 @@ using namespace MIDI_NAMESPACE; #include "IPAddress.h" +#include "AppleMIDI_Debug.h" + #include "AppleMIDI_PlatformBegin.h" #include "AppleMIDI_Defs.h" #include "AppleMIDI_Settings.h" diff --git a/src/AppleMIDI_Debug.h b/src/AppleMIDI_Debug.h new file mode 100644 index 0000000..3d65291 --- /dev/null +++ b/src/AppleMIDI_Debug.h @@ -0,0 +1,29 @@ +#ifdef APPLEMIDI_DEBUG +namespace { +static void DBG_SETUP(unsigned long baud) { + APPLEMIDI_DEBUG.begin(baud); + while (!APPLEMIDI_DEBUG); +} + +template +static void DBG_PLAIN(T last) { + APPLEMIDI_DEBUG.println(last); +} + +template +static void DBG_PLAIN(T head, Args... tail) { + APPLEMIDI_DEBUG.print(head); + APPLEMIDI_DEBUG.print(' '); + DBG_PLAIN(tail...); +} + +template +static void DBG(Args... args) { + DBG_PLAIN(args...); +} +} // namespace +#else +#define DBG_SETUP(...) +#define DBG_PLAIN(...) +#define DBG(...) +#endif \ No newline at end of file diff --git a/src/AppleMIDI_Defs.h b/src/AppleMIDI_Defs.h index 5eec476..9703c31 100644 --- a/src/AppleMIDI_Defs.h +++ b/src/AppleMIDI_Defs.h @@ -37,30 +37,6 @@ typedef const char* AppleMIDIConstStr; #define GF(x) x #endif -#ifdef APPLEMIDI_DEBUG -namespace { -template -static void DBG_PLAIN(T last) { - APPLEMIDI_DEBUG.println(last); -} - -template -static void DBG_PLAIN(T head, Args... tail) { - APPLEMIDI_DEBUG.print(head); - APPLEMIDI_DEBUG.print(' '); - DBG_PLAIN(tail...); -} - -template -static void DBG(Args... args) { - DBG_PLAIN(args...); -} -} // namespace -#else -#define DBG_PLAIN(...) -#define DBG(...) -#endif - #define RtpBuffer_t Deque #define MidiBuffer_t Deque diff --git a/test/NoteOn.cpp b/test/NoteOn.cpp index 228c6c6..8879397 100644 --- a/test/NoteOn.cpp +++ b/test/NoteOn.cpp @@ -4,7 +4,6 @@ #define APPLEMIDI_INITIATOR #include "AppleMIDI.h" -USING_NAMESPACE_APPLEMIDI unsigned long t0 = millis(); bool isConnected = false; @@ -33,7 +32,7 @@ APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); // ----------------------------------------------------------------------------- // rtpMIDI session. Device connected // ----------------------------------------------------------------------------- -void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { +void OnAppleMidiConnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { isConnected = true; DBG(F("Connected to session"), name); } @@ -41,17 +40,17 @@ void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) { // ----------------------------------------------------------------------------- // rtpMIDI session. Device disconnected // ----------------------------------------------------------------------------- -void OnAppleMidiDisconnected(const ssrc_t & ssrc) { +void OnAppleMidiDisconnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { isConnected = false; - N_DEBUG_PRINTLN(F("Disconnected")); + DBG(F("Disconnected")); } // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- -void OnAppleMidiByte(const ssrc_t & ssrc, byte data) { - N_DEBUG_PRINT(F("MIDI: ")); - N_DEBUG_PRINTLN(data); +void OnAppleMidiByte(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, byte data) { + DBG(F("MIDI: ")); + DBG(data); } // ----------------------------------------------------------------------------- @@ -84,17 +83,17 @@ char getSysExStatus(const byte* data, uint16_t length) } static void OnMidiSystemExclusive(byte* array, unsigned size) { - N_DEBUG_PRINT(F("Incoming SysEx: ")); - N_DEBUG_PRINT(getSysExStatus(array, size)); + DBG(F("Incoming SysEx: ")); + DBG(getSysExStatus(array, size)); unsigned i = 0; for (; i < size - 1; i++) { - N_DEBUG_PRINT(F(" 0x")); - N_DEBUG_PRINT(array[i], HEX); + DBG(F(" 0x")); + DBG(array[i], HEX); } - N_DEBUG_PRINT(F(" 0x")); - N_DEBUG_PRINT(array[i], HEX); - N_DEBUG_PRINTLN(); + DBG(F(" 0x")); + DBG(array[i], HEX); + DBG(); } void begin() From 71d8d5009b8c015b8ffba44407531a3d274c1b28 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sat, 19 Dec 2020 09:57:28 +0100 Subject: [PATCH 040/271] Update EthernetShield_NoteOnOffEverySec.ino --- .../EthernetShield_NoteOnOffEverySec.ino | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino b/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino index 3c19ef6..1c4e46a 100644 --- a/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino +++ b/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino @@ -43,6 +43,22 @@ void setup() DBG(F("Send MIDI messages every second")); } +// ----------------------------------------------------------------------------- +// rtpMIDI session. Device connected +// ----------------------------------------------------------------------------- +void OnAppleMidiConnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { + isConnected = true; + DBG(F("Connected to session"), name); +} + +// ----------------------------------------------------------------------------- +// rtpMIDI session. Device disconnected +// ----------------------------------------------------------------------------- +void OnAppleMidiDisconnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { + isConnected = false; + DBG(F("Disconnected")); +} + // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- @@ -69,19 +85,3 @@ void loop() // ==================================================================================== // Event handlers for incoming MIDI messages // ==================================================================================== - -// ----------------------------------------------------------------------------- -// rtpMIDI session. Device connected -// ----------------------------------------------------------------------------- -void OnAppleMidiConnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { - isConnected = true; - DBG(F("Connected to session"), name); -} - -// ----------------------------------------------------------------------------- -// rtpMIDI session. Device disconnected -// ----------------------------------------------------------------------------- -void OnAppleMidiDisconnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { - isConnected = false; - DBG(F("Disconnected")); -} From d2d7d1e6a7e94f94ded910e6048c341181d3f236 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sat, 19 Dec 2020 10:01:48 +0100 Subject: [PATCH 041/271] Update EthernetShield_NoteOnOffEverySec.ino --- .../EthernetShield_NoteOnOffEverySec.ino | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino b/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino index 1c4e46a..444bb9f 100644 --- a/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino +++ b/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino @@ -15,6 +15,26 @@ bool isConnected = false; APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); +// ==================================================================================== +// Event handlers for incoming MIDI messages +// ==================================================================================== + +// ----------------------------------------------------------------------------- +// rtpMIDI session. Device connected +// ----------------------------------------------------------------------------- +void OnAppleMidiConnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { + isConnected = true; + DBG(F("Connected to session"), name); +} + +// ----------------------------------------------------------------------------- +// rtpMIDI session. Device disconnected +// ----------------------------------------------------------------------------- +void OnAppleMidiDisconnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { + isConnected = false; + DBG(F("Disconnected")); +} + // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- @@ -43,22 +63,6 @@ void setup() DBG(F("Send MIDI messages every second")); } -// ----------------------------------------------------------------------------- -// rtpMIDI session. Device connected -// ----------------------------------------------------------------------------- -void OnAppleMidiConnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { - isConnected = true; - DBG(F("Connected to session"), name); -} - -// ----------------------------------------------------------------------------- -// rtpMIDI session. Device disconnected -// ----------------------------------------------------------------------------- -void OnAppleMidiDisconnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { - isConnected = false; - DBG(F("Disconnected")); -} - // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- @@ -81,7 +85,3 @@ void loop() MIDI.sendNoteOff(note, velocity, channel); } } - -// ==================================================================================== -// Event handlers for incoming MIDI messages -// ==================================================================================== From 3a1264a9aa901593659824f7230407cf88fb8a8b Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sat, 19 Dec 2020 10:10:32 +0100 Subject: [PATCH 042/271] Update EthernetShield_NoteOnOffEverySec.ino --- .../EthernetShield_NoteOnOffEverySec.ino | 36 ++++++++----------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino b/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino index 444bb9f..84ad36c 100644 --- a/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino +++ b/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino @@ -15,26 +15,6 @@ bool isConnected = false; APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); -// ==================================================================================== -// Event handlers for incoming MIDI messages -// ==================================================================================== - -// ----------------------------------------------------------------------------- -// rtpMIDI session. Device connected -// ----------------------------------------------------------------------------- -void OnAppleMidiConnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { - isConnected = true; - DBG(F("Connected to session"), name); -} - -// ----------------------------------------------------------------------------- -// rtpMIDI session. Device disconnected -// ----------------------------------------------------------------------------- -void OnAppleMidiDisconnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { - isConnected = false; - DBG(F("Disconnected")); -} - // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- @@ -57,8 +37,20 @@ void setup() MIDI.begin(); // Stay informed on connection status - AppleMIDI.setHandleConnected(OnAppleMidiConnected); - AppleMIDI.setHandleDisconnected(OnAppleMidiDisconnected); + AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { + isConnected = true; + DBG(F("Connected to session"), name); + }); + AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { + isConnected = false; + DBG(F("Disconnected")); + }); + MIDI.setHandleNoteOn([](byte channel, byte note, byte velocity) { + DBG(F("NoteOn "), note); + }); + MIDI.setHandleNoteOff([](byte channel, byte note, byte velocity) { + DBG(F("NoteOff "), note); + }); DBG(F("Send MIDI messages every second")); } From 06147a4d7d3432d78106e85972c2e8578b1f48a8 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sat, 19 Dec 2020 10:14:57 +0100 Subject: [PATCH 043/271] testing esp8266 --- .travis.yml | 2 +- .../ESP8266_NoteOnOffEverySec.ino | 61 +++++-------------- .../EthernetShield_NoteOnOffEverySec.ino | 1 + 3 files changed, 18 insertions(+), 46 deletions(-) diff --git a/.travis.yml b/.travis.yml index a77ea17..0f4737e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,4 +14,4 @@ install: script: - platformio ci --board=uno --lib=. examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino; -- platformio ci --board=esp32dev --lib=. examples/\ESP8266_NoteOnOffEverySec/\ESP8266_NoteOnOffEverySec.ino; +- platformio ci --board=espressif8266 --lib=. examples/\ESP8266_NoteOnOffEverySec/\ESP8266_NoteOnOffEverySec.ino; diff --git a/examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino b/examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino index db95d13..86098fa 100644 --- a/examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino +++ b/examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino @@ -14,12 +14,6 @@ bool isConnected = false; APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); -// Forward declaration -void OnAppleMidiConnected(uint32_t ssrc, char* name); -void OnAppleMidiDisconnected(uint32_t ssrc); -void OnMidiNoteOn(byte channel, byte note, byte velocity); -void OnMidiNoteOff(byte channel, byte note, byte velocity); - // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- @@ -44,11 +38,22 @@ void setup() MIDI.begin(); - AppleMIDI.setHandleConnected(OnAppleMidiConnected); - AppleMIDI.setHandleDisconnected(OnAppleMidiDisconnected); - - MIDI.setHandleNoteOn(OnMidiNoteOn); - MIDI.setHandleNoteOff(OnMidiNoteOff); + // Stay informed on connection status + AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { + isConnected = true; + DBG(F("Connected to session"), name); + }); + AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { + isConnected = false; + DBG(F("Disconnected")); + }); + + MIDI.setHandleNoteOn([](byte channel, byte note, byte velocity) { + DBG(F("NoteOn "), note); + }); + MIDI.setHandleNoteOff([](byte channel, byte note, byte velocity) { + DBG(F("NoteOff "), note); + }); DBG(F("Sending NoteOn/Off of note 45, every second")); } @@ -75,37 +80,3 @@ void loop() MIDI.sendNoteOff(note, velocity, channel); } } - -// ==================================================================================== -// Event handlers for incoming MIDI messages -// ==================================================================================== - -// ----------------------------------------------------------------------------- -// rtpMIDI session. Device connected -// ----------------------------------------------------------------------------- -void OnAppleMidiConnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { - isConnected = true; - DBG(F("Connected to session"), name); -} - -// ----------------------------------------------------------------------------- -// rtpMIDI session. Device disconnected -// ----------------------------------------------------------------------------- -void OnAppleMidiDisconnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { - isConnected = false; - DBG(F("Disconnected")); -} - -// ----------------------------------------------------------------------------- -// -// ----------------------------------------------------------------------------- -void OnMidiNoteOn(byte channel, byte note, byte velocity) { - DBG(F("in\tNote on"), note, " Velocity", velocity, "\t", channel); -} - -// ----------------------------------------------------------------------------- -// -// ----------------------------------------------------------------------------- -void OnMidiNoteOff(byte channel, byte note, byte velocity) { - DBG(F("in\tNote off"), note, " Velocity", velocity, "\t", channel); -} diff --git a/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino b/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino index 84ad36c..d9e4198 100644 --- a/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino +++ b/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino @@ -45,6 +45,7 @@ void setup() isConnected = false; DBG(F("Disconnected")); }); + MIDI.setHandleNoteOn([](byte channel, byte note, byte velocity) { DBG(F("NoteOn "), note); }); From 9ba46b1035d4b608449f38b895c6b9758ccdde3e Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sat, 19 Dec 2020 10:26:24 +0100 Subject: [PATCH 044/271] Update .travis.yml --- .travis.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0f4737e..c111536 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,11 +7,13 @@ cache: directories: - "~/.platformio" +env: + - PLATFORMIO_CI_SRC=examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino + install: - pip install -U platformio - platformio update - platformio lib -g install 62@5.0.0 870 872 script: -- platformio ci --board=uno --lib=. examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino; -- platformio ci --board=espressif8266 --lib=. examples/\ESP8266_NoteOnOffEverySec/\ESP8266_NoteOnOffEverySec.ino; +- pio ci --board=uno From ed6ebc6825b426dcee553a984fc08daa2901cf3b Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sat, 19 Dec 2020 10:28:52 +0100 Subject: [PATCH 045/271] Update .travis.yml --- .travis.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index c111536..f189e73 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,13 +7,10 @@ cache: directories: - "~/.platformio" -env: - - PLATFORMIO_CI_SRC=examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino - install: - pip install -U platformio - platformio update - platformio lib -g install 62@5.0.0 870 872 script: -- pio ci --board=uno +- pio ci --board=uno --lib=. examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino; From 0a7f096009716ee6a997502fcb8b1824f6cda2cf Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sat, 19 Dec 2020 10:40:37 +0100 Subject: [PATCH 046/271] fixed warnings --- src/AppleMIDI.hpp | 2 +- src/rtpMIDI_Parser_JournalSection.hpp | 4 ++-- src/rtpMIDI_Parser_MidiCommandSection.hpp | 4 ---- src/utility/Deque.h | 2 -- 4 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/AppleMIDI.hpp b/src/AppleMIDI.hpp index a32cd28..07ec39c 100644 --- a/src/AppleMIDI.hpp +++ b/src/AppleMIDI.hpp @@ -532,7 +532,7 @@ void AppleMIDISession::writeRtpMidiBuffer(Particip } // write out the MIDI Section - for (auto i = 0; i < bufferLen; i++) + for (size_t i = 0; i < bufferLen; i++) dataPort.write(outMidiBuffer[i]); // *No* journal section (Not supported) diff --git a/src/rtpMIDI_Parser_JournalSection.hpp b/src/rtpMIDI_Parser_JournalSection.hpp index bd72c29..41b0def 100644 --- a/src/rtpMIDI_Parser_JournalSection.hpp +++ b/src/rtpMIDI_Parser_JournalSection.hpp @@ -48,7 +48,7 @@ parserReturn decodeJournalSection(RtpBuffer_t &buffer) // stream (modulo 2^16). cb.buffer[0] = buffer[i++]; cb.buffer[1] = buffer[i++]; - uint16_t checkPoint = ntohs(cb.value16); + uint16_t checkPoint = ntohs(cb.value16); // unused // (RFC 4695, 5 Recovery Journal Format) // If A and Y are both zero, the recovery journal only contains its 3- @@ -132,7 +132,7 @@ parserReturn decodeJournalSection(RtpBuffer_t &buffer) uint32_t chanflags = ntohl(cb.value32); uint16_t chanjourlen = (chanflags & RTP_MIDI_CJ_MASK_LENGTH) >> 8; - uint16_t channelNr = (chanflags & RTP_MIDI_CJ_MASK_CHANNEL) >> RTP_MIDI_CJ_CHANNEL_SHIFT; + // uint16_t channelNr = (chanflags & RTP_MIDI_CJ_MASK_CHANNEL) >> RTP_MIDI_CJ_CHANNEL_SHIFT; // unused // We have the most important bit of information - the length of the channel information // no more need to further parse. diff --git a/src/rtpMIDI_Parser_MidiCommandSection.hpp b/src/rtpMIDI_Parser_MidiCommandSection.hpp index 5b5f8f4..2f3711e 100644 --- a/src/rtpMIDI_Parser_MidiCommandSection.hpp +++ b/src/rtpMIDI_Parser_MidiCommandSection.hpp @@ -72,7 +72,6 @@ size_t decodeMidi(RtpBuffer_t &buffer, uint8_t &runningstatus) size_t consumed = 0; auto octet = buffer[0]; - bool using_rs; /* MIDI realtime-data -> one octet -- unlike serial-wired MIDI realtime-commands in RTP-MIDI will * not be intermingled with other MIDI-commands, so we handle this case right here and return */ @@ -96,12 +95,9 @@ size_t decodeMidi(RtpBuffer_t &buffer, uint8_t &runningstatus) /* our first octet is "virtual" coming from a preceding MIDI-command, * so actually we have not really consumed anything yet */ octet = runningstatus; - using_rs = true; } else { - /* We have a "real" status-byte */ - using_rs = false; /* Let's see how this octet influences our running-status */ /* if we have a "normal" MIDI-command then the new status replaces the current running-status */ if (octet < 0xf0) diff --git a/src/utility/Deque.h b/src/utility/Deque.h index afc0eac..76a0988 100644 --- a/src/utility/Deque.h +++ b/src/utility/Deque.h @@ -32,8 +32,6 @@ class Deque { const T& at(size_t) const; void clear(); - - // iterator begin(); // iterator end(); From ba6ecea5b22403bf8c5f440b7c5983f69ee4935d Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sat, 19 Dec 2020 11:14:33 +0100 Subject: [PATCH 047/271] explcit namespace --- examples/ESP32_Callbacks/ESP32_Callbacks.ino | 17 +++--- .../ESP8266_NoteOnOffEverySec.ino | 1 - .../EthernetShield_Initiator.ino | 59 +++++-------------- .../EthernetShield_MultipleSessions.ino | 4 +- .../EthernetShield_NonDefaultSession.ino | 40 ++++--------- .../EthernetShield_NoteOnOffEverySec.ino | 3 +- .../EthernetShield_ReceivedRawMidiData.ino | 51 +++++----------- .../EthernetShield_SysEx.ino | 35 +++-------- examples/MKR_ETH_Bonjour/MKR_ETH_Bonjour.ino | 2 - .../wESP32_NoteOnOffEverySec.ino | 58 +++++------------- test/NoteOn.cpp | 1 - 11 files changed, 75 insertions(+), 196 deletions(-) diff --git a/examples/ESP32_Callbacks/ESP32_Callbacks.ino b/examples/ESP32_Callbacks/ESP32_Callbacks.ino index 42fd559..9186add 100644 --- a/examples/ESP32_Callbacks/ESP32_Callbacks.ino +++ b/examples/ESP32_Callbacks/ESP32_Callbacks.ino @@ -25,7 +25,6 @@ void setup() { DBG(F("Add device named Arduino with Host"), WiFi.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); DBG(F("Then press the Connect button")); DBG(F("Then open a MIDI listener and monitor incoming notes")); - DBG(F("Listen to incoming MIDI commands")); AppleMIDI.setHandleConnected(OnAppleMidiConnected); AppleMIDI.setHandleDisconnected(OnAppleMidiDisconnected); @@ -81,28 +80,28 @@ DBG(F("Disconnected")); void OnAppleMidiError(const APPLEMIDI_NAMESPACE::ssrc_t& ssrc, int32_t err) { switch (err) { - case Exception::BufferFullException: + case APPLEMIDI_NAMESPACE::Exception::BufferFullException: DBG(F("*** BufferFullException")); break; - case Exception::ParseException: + case APPLEMIDI_NAMESPACE::Exception::ParseException: DBG(F("*** ParseException")); break; - case Exception::TooManyParticipantsException: + case APPLEMIDI_NAMESPACE::Exception::TooManyParticipantsException: DBG(F("*** TooManyParticipantsException")); break; - case Exception::UnexpectedInviteException: + case APPLEMIDI_NAMESPACE::Exception::UnexpectedInviteException: DBG(F("*** UnexpectedInviteException")); break; - case Exception::ParticipantNotFoundException: + case APPLEMIDI_NAMESPACE::Exception::ParticipantNotFoundException: DBG(F("*** ParticipantNotFoundException")); break; - case Exception::ListenerTimeOutException: + case APPLEMIDI_NAMESPACE::Exception::ListenerTimeOutException: DBG(F("*** ListenerTimeOutException")); break; - case Exception::MaxAttemptsException: + case APPLEMIDI_NAMESPACE::Exception::MaxAttemptsException: DBG(F("*** MaxAttemptsException")); break; - case Exception::NoResponseFromConnectionRequestException: + case APPLEMIDI_NAMESPACE::Exception::NoResponseFromConnectionRequestException: DBG(F("***:yyy did't respond to the connection request. Check the address and port, and any firewall or router settings. (time)")); break; } diff --git a/examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino b/examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino index 86098fa..244560f 100644 --- a/examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino +++ b/examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino @@ -38,7 +38,6 @@ void setup() MIDI.begin(); - // Stay informed on connection status AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { isConnected = true; DBG(F("Connected to session"), name); diff --git a/examples/EthernetShield_Initiator/EthernetShield_Initiator.ino b/examples/EthernetShield_Initiator/EthernetShield_Initiator.ino index 5466937..c52689e 100644 --- a/examples/EthernetShield_Initiator/EthernetShield_Initiator.ino +++ b/examples/EthernetShield_Initiator/EthernetShield_Initiator.ino @@ -33,23 +33,30 @@ void setup() DBG(F("Add device named Arduino with Host"), Ethernet.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); DBG(F("Then press the Connect button")); DBG(F("Then open a MIDI listener and monitor incoming notes")); - DBG(F("Listen to incoming MIDI commands")); MIDI.begin(); - // Stay informed on connection status - AppleMIDI.setHandleConnected(OnAppleMidiConnected); - AppleMIDI.setHandleDisconnected(OnAppleMidiDisconnected); - - // and let us know ehen notes come in - MIDI.setHandleNoteOn(OnMidiNoteOn); - MIDI.setHandleNoteOff(OnMidiNoteOff); + AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { + isConnected = true; + DBG(F("Connected to session"), name); + }); + AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { + isConnected = false; + DBG(F("Disconnected")); + }); + + MIDI.setHandleNoteOn([](byte channel, byte note, byte velocity) { + DBG(F("NoteOn "), note); + }); + MIDI.setHandleNoteOff([](byte channel, byte note, byte velocity) { + DBG(F("NoteOff "), note); + }); // Initiate the session IPAddress remote(192, 168, 1, 4); AppleMIDI.sendInvite(remote, DEFAULT_CONTROL_PORT); // port is 5004 by default - DBG(F("Every second send a random NoteOn/Off")); + DBG(F("Sending a random NoteOn/Off every second")); } // ----------------------------------------------------------------------------- @@ -74,37 +81,3 @@ void loop() MIDI.sendNoteOff(note, velocity, channel); } } - -// ==================================================================================== -// Event handlers for incoming MIDI messages -// ==================================================================================== - -// ----------------------------------------------------------------------------- -// rtpMIDI session. Device connected -// ----------------------------------------------------------------------------- -void OnAppleMidiConnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { - isConnected = true; - DBG(F("Connected to session"), name); -} - -// ----------------------------------------------------------------------------- -// rtpMIDI session. Device disconnected -// ----------------------------------------------------------------------------- -void OnAppleMidiDisconnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { - isConnected = false; - DBG(F("Disconnected")); -} - -// ----------------------------------------------------------------------------- -// -// ----------------------------------------------------------------------------- -static void OnMidiNoteOn(byte channel, byte note, byte velocity) { - DBG(F("in\tNote on"), note, " Velocity", velocity, "\t", channel); -} - -// ----------------------------------------------------------------------------- -// -// ----------------------------------------------------------------------------- -static void OnMidiNoteOff(byte channel, byte note, byte velocity) { - DBG(F("in\tNote off"), note, " Velocity", velocity, "\t", channel); -} \ No newline at end of file diff --git a/examples/EthernetShield_MultipleSessions/EthernetShield_MultipleSessions.ino b/examples/EthernetShield_MultipleSessions/EthernetShield_MultipleSessions.ino index bed7b36..293d659 100644 --- a/examples/EthernetShield_MultipleSessions/EthernetShield_MultipleSessions.ino +++ b/examples/EthernetShield_MultipleSessions/EthernetShield_MultipleSessions.ino @@ -30,10 +30,10 @@ void setup() } DBG(F("OK, now make sure you an rtpMIDI session that is Enabled")); - DBG(F("Add device named Arduino with Host"), Ethernet.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); + DBG(F("Add device named Arduino with Host"), Ethernet.localIP(), "Port", AppleMIDI1.getPort(), "(Name", AppleMIDI1.getName(), ")"); + DBG(F("Add device named Arduino with Host"), Ethernet.localIP(), "Port", AppleMIDI2.getPort(), "(Name", AppleMIDI2.getName(), ")"); DBG(F("Then press the Connect button")); DBG(F("Then open a MIDI listener and monitor incoming notes")); - DBG(F("Listen to incoming MIDI commands")); // Listen for MIDI messages on channel 1 MIDI1.begin(1); diff --git a/examples/EthernetShield_NonDefaultSession/EthernetShield_NonDefaultSession.ino b/examples/EthernetShield_NonDefaultSession/EthernetShield_NonDefaultSession.ino index 8a10c59..e97c356 100644 --- a/examples/EthernetShield_NonDefaultSession/EthernetShield_NonDefaultSession.ino +++ b/examples/EthernetShield_NonDefaultSession/EthernetShield_NonDefaultSession.ino @@ -13,12 +13,8 @@ byte mac[] = { unsigned long t1 = millis(); bool isConnected = false; -// Custom name -//APPLEMIDI_CREATE_INSTANCE(EthernetUDP, MIDI, "MyNamedArduino", DEFAULT_CONTROL_PORT); -// custom name and random port -//APPLEMIDI_CREATE_INSTANCE(EthernetUDP, MIDI, "MyNamedArduino", 5200); -// custom name and port -APPLEMIDI_CREATE_INSTANCE(EthernetUDP, MIDI, "MyNamedArduino", DEFAULT_CONTROL_PORT + 2); +// Non default portnr +APPLEMIDI_CREATE_INSTANCE(EthernetUDP, MIDI, "MyNamedArduino", 5200); // ----------------------------------------------------------------------------- // @@ -37,13 +33,17 @@ void setup() DBG(F("Add device named Arduino with Host"), Ethernet.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); DBG(F("Then press the Connect button")); DBG(F("Then open a MIDI listener and monitor incoming notes")); - DBG(F("Listen to incoming MIDI commands")); MIDI.begin(); - // Stay informed on connection status - AppleMIDI.setHandleConnected(OnAppleMidiConnected); - AppleMIDI.setHandleDisconnected(OnAppleMidiDisconnected); + AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { + isConnected = true; + DBG(F("Connected to session"), name); + }); + AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { + isConnected = false; + DBG(F("Disconnected")); + }); DBG(F("Send MIDI messages every second")); } @@ -70,23 +70,3 @@ void loop() MIDI.sendNoteOff(note, velocity, channel); } } - -// ==================================================================================== -// Event handlers for incoming MIDI messages -// ==================================================================================== - -// ----------------------------------------------------------------------------- -// rtpMIDI session. Device connected -// ----------------------------------------------------------------------------- -void OnAppleMidiConnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { - isConnected = true; - DBG(F("Connected to session"), name); -} - -// ----------------------------------------------------------------------------- -// rtpMIDI session. Device disconnected -// ----------------------------------------------------------------------------- -void OnAppleMidiDisconnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { - isConnected = false; - DBG(F("Disconnected")); -} diff --git a/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino b/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino index d9e4198..2bde13d 100644 --- a/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino +++ b/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino @@ -32,7 +32,6 @@ void setup() DBG(F("Add device named Arduino with Host"), Ethernet.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); DBG(F("Then press the Connect button")); DBG(F("Then open a MIDI listener and monitor incoming notes")); - DBG(F("Listen to incoming MIDI commands")); MIDI.begin(); @@ -53,7 +52,7 @@ void setup() DBG(F("NoteOff "), note); }); - DBG(F("Send MIDI messages every second")); + DBG(F("Sending MIDI messages every second")); } // ----------------------------------------------------------------------------- diff --git a/examples/EthernetShield_ReceivedRawMidiData/EthernetShield_ReceivedRawMidiData.ino b/examples/EthernetShield_ReceivedRawMidiData/EthernetShield_ReceivedRawMidiData.ino index 1750a8c..aa3e441 100644 --- a/examples/EthernetShield_ReceivedRawMidiData/EthernetShield_ReceivedRawMidiData.ino +++ b/examples/EthernetShield_ReceivedRawMidiData/EthernetShield_ReceivedRawMidiData.ino @@ -32,21 +32,28 @@ void setup() DBG(F("Add device named Arduino with Host"), Ethernet.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); DBG(F("Then press the Connect button")); DBG(F("Then open a MIDI listener and monitor incoming notes")); - DBG(F("Listen to incoming MIDI commands")); MIDI.begin(); // check: zien we de connecttion binnenkomen?? Anders terug een ref van maken - AppleMIDI.setHandleConnected(OnAppleMidiConnected); - AppleMIDI.setHandleDisconnected(OnAppleMidiDisconnected); + AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { + isConnected = true; + DBG(F("Connected to session"), name); + }); + AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { + isConnected = false; + DBG(F("Disconnected")); + }); AppleMIDI.setHandleStartReceivedMidi(OnAppleMidiStartReceived); AppleMIDI.setHandleReceivedMidi(OnAppleMidiReceivedByte); AppleMIDI.setHandleEndReceivedMidi(OnAppleMidiEndReceive); - MIDI.setHandleNoteOn(OnMidiNoteOn); - MIDI.setHandleNoteOff(OnMidiNoteOff); - - DBG(F("Waiting for incoming MIDI messages")); + MIDI.setHandleNoteOn([](byte channel, byte note, byte velocity) { + DBG(F("NoteOn "), note); + }); + MIDI.setHandleNoteOff([](byte channel, byte note, byte velocity) { + DBG(F("NoteOff "), note); + }); } // ----------------------------------------------------------------------------- @@ -62,22 +69,6 @@ void loop() // Event handlers for incoming MIDI messages // ==================================================================================== -// ----------------------------------------------------------------------------- -// rtpMIDI session. Device connected -// ----------------------------------------------------------------------------- -void OnAppleMidiConnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { - isConnected = true; - DBG(F("Connected to session"), name); -} - -// ----------------------------------------------------------------------------- -// rtpMIDI session. Device disconnected -// ----------------------------------------------------------------------------- -void OnAppleMidiDisconnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { - isConnected = false; - DBG(F("Disconnected")); -} - // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- @@ -98,17 +89,3 @@ void OnAppleMidiReceivedByte(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, byte data void OnAppleMidiEndReceive(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { DBG(F("End receiving"), ssrc); } - -// ----------------------------------------------------------------------------- -// -// ----------------------------------------------------------------------------- -static void OnMidiNoteOn(byte channel, byte note, byte velocity) { - DBG(F("in\tNote on"), note, " Velocity", velocity, "\t", channel); -} - -// ----------------------------------------------------------------------------- -// -// ----------------------------------------------------------------------------- -static void OnMidiNoteOff(byte channel, byte note, byte velocity) { - DBG(F("in\tNote off"), note, " Velocity", velocity, "\t", channel); -} diff --git a/examples/EthernetShield_SysEx/EthernetShield_SysEx.ino b/examples/EthernetShield_SysEx/EthernetShield_SysEx.ino index 8ffe6ea..801b2e3 100644 --- a/examples/EthernetShield_SysEx/EthernetShield_SysEx.ino +++ b/examples/EthernetShield_SysEx/EthernetShield_SysEx.ino @@ -4,7 +4,6 @@ #define APPLEMIDI_DEBUG SerialMon #include - // Enter a MAC address for your controller below. // Newer Ethernet shields have a MAC address printed on a sticker on the shield byte mac[] = { @@ -25,7 +24,6 @@ byte sysexBig[] = { 0xF0, 0x41, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, - 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0xF7 }; @@ -48,17 +46,21 @@ void setup() DBG(F("Add device named Arduino with Host"), Ethernet.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); DBG(F("Then press the Connect button")); DBG(F("Then open a MIDI listener and monitor incoming notes")); - DBG(F("Listen to incoming MIDI commands")); MIDI.begin(); - // check: zien we de connecttion binnenkomen?? Anders terug een ref van makenDw - AppleMIDI.setHandleConnected(OnAppleMidiConnected); - AppleMIDI.setHandleDisconnected(OnAppleMidiDisconnected); + AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { + isConnected = true; + DBG(F("Connected to session"), name); + }); + AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { + isConnected = false; + DBG(F("Disconnected")); + }); MIDI.setHandleSystemExclusive(OnMidiSysEx); - DBG(F("Send and Receive SysEx")); + DBG(F("Send SysEx every second")); } // ----------------------------------------------------------------------------- @@ -82,25 +84,6 @@ void loop() // Event handlers for incoming MIDI messages // ==================================================================================== -// ----------------------------------------------------------------------------- -// rtpMIDI session. Device connected -// ----------------------------------------------------------------------------- -void OnAppleMidiConnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { - isConnected = true; - DBG(F("Connected to session"), name); -} - -// ----------------------------------------------------------------------------- -// rtpMIDI session. Device disconnected -// ----------------------------------------------------------------------------- -void OnAppleMidiDisconnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { - isConnected = false; - DBG(F("Disconnected")); -} - -// ----------------------------------------------------------------------------- -// -// ----------------------------------------------------------------------------- void OnMidiSysEx(byte* data, unsigned length) { SerialMon.print(F("SYSEX: (")); SerialMon.print(getSysExStatus(data, length)); diff --git a/examples/MKR_ETH_Bonjour/MKR_ETH_Bonjour.ino b/examples/MKR_ETH_Bonjour/MKR_ETH_Bonjour.ino index a2e35f0..ae73f26 100644 --- a/examples/MKR_ETH_Bonjour/MKR_ETH_Bonjour.ino +++ b/examples/MKR_ETH_Bonjour/MKR_ETH_Bonjour.ino @@ -1,8 +1,6 @@ #include #include // https://github.com/TrippyLighting/EthernetBonjour -#define OPTIONAL_MDNS - #include // Enter a MAC address for your controller below. diff --git a/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino b/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino index c997bdf..e95d787 100644 --- a/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino +++ b/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino @@ -25,20 +25,26 @@ void setup() DBG(F("Add device named Arduino with Host"), WiFi.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); DBG(F("Then press the Connect button")); DBG(F("Then open a MIDI listener and monitor incoming notes")); - DBG(F("Listen to incoming MIDI commands")); MIDI.begin(); - AppleMIDI.setHandleConnected(OnAppleMidiConnected); - AppleMIDI.setHandleDisconnected(OnAppleMidiDisconnected); - - MIDI.setHandleNoteOn(OnMidiNoteOn); - MIDI.setHandleNoteOff(OnMidiNoteOff); + AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { + isConnected = true; + DBG(F("Connected to session"), name); + }); + AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { + isConnected = false; + DBG(F("Disconnected")); + }); + + MIDI.setHandleNoteOn([](byte channel, byte note, byte velocity) { + DBG(F("NoteOn "), note); + }); + MIDI.setHandleNoteOff([](byte channel, byte note, byte velocity) { + DBG(F("NoteOff "), note); + }); MDNS.addService("apple-midi", "udp", AppleMIDI.getPort()); - MDNS.addService("http", "tcp", 80); - - DBG(F("Every second send a random NoteOn/Off")); } // ----------------------------------------------------------------------------- @@ -63,37 +69,3 @@ void loop() MIDI.sendNoteOff(note, velocity, channel); } } - -// ==================================================================================== -// Event handlers for incoming MIDI messages -// ==================================================================================== - -// ----------------------------------------------------------------------------- -// rtpMIDI session. Device connected -// ----------------------------------------------------------------------------- -void OnAppleMidiConnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { - isConnected = true; - DBG(F("Connected to session"), name); -} - -// ----------------------------------------------------------------------------- -// rtpMIDI session. Device disconnected -// ----------------------------------------------------------------------------- -void OnAppleMidiDisconnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { - isConnected = false; - DBG(F("Disconnected")); -} - -// ----------------------------------------------------------------------------- -// -// ----------------------------------------------------------------------------- -static void OnMidiNoteOn(byte channel, byte note, byte velocity) { - DBG(F("in\tNote on"), note, " Velocity", velocity, "\t", channel); -} - -// ----------------------------------------------------------------------------- -// -// ----------------------------------------------------------------------------- -static void OnMidiNoteOff(byte channel, byte note, byte velocity) { - DBG(F("in\tNote off"), note, " Velocity", velocity, "\t", channel); -} diff --git a/test/NoteOn.cpp b/test/NoteOn.cpp index 8879397..b0cb7cc 100644 --- a/test/NoteOn.cpp +++ b/test/NoteOn.cpp @@ -102,7 +102,6 @@ void begin() DBG(F("Add device named Arduino with Host"), Ethernet.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); DBG(F("Then press the Connect button")); DBG(F("Then open a MIDI listener and monitor incoming notes")); - DBG(F("Listen to incoming MIDI commands")); MIDI.begin(); From 3301d94f0df9aac410fda11b6164583944f9bec0 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sat, 19 Dec 2020 16:36:38 +0100 Subject: [PATCH 048/271] cleanup examples --- examples/ESP32_Callbacks/ESP32_Callbacks.ino | 2 +- .../ESP8266_NoteOnOffEverySec.ino | 4 +-- .../EthernetShield_Initiator.ino | 4 +-- .../EthernetShield_NoteOnOffEverySec.ino | 6 ++-- .../EthernetShield_ReceivedRawMidiData.ino | 4 +-- .../EthernetShield_SysEx.ino | 28 ++----------------- .../wESP32_NoteOnOffEverySec.ino | 4 +-- 7 files changed, 14 insertions(+), 38 deletions(-) diff --git a/examples/ESP32_Callbacks/ESP32_Callbacks.ino b/examples/ESP32_Callbacks/ESP32_Callbacks.ino index 9186add..a431508 100644 --- a/examples/ESP32_Callbacks/ESP32_Callbacks.ino +++ b/examples/ESP32_Callbacks/ESP32_Callbacks.ino @@ -4,7 +4,7 @@ #define APPLEMIDI_DEBUG SerialMon #include -#include "arduino_secrets.h" +#include "arduino_secrets.h" // contains SECRET_SSID and SECRET_PASS bool isConnected = false; diff --git a/examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino b/examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino index 244560f..4552a6d 100644 --- a/examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino +++ b/examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino @@ -48,10 +48,10 @@ void setup() }); MIDI.setHandleNoteOn([](byte channel, byte note, byte velocity) { - DBG(F("NoteOn "), note); + DBG(F("NoteOn"), note); }); MIDI.setHandleNoteOff([](byte channel, byte note, byte velocity) { - DBG(F("NoteOff "), note); + DBG(F("NoteOff"), note); }); DBG(F("Sending NoteOn/Off of note 45, every second")); diff --git a/examples/EthernetShield_Initiator/EthernetShield_Initiator.ino b/examples/EthernetShield_Initiator/EthernetShield_Initiator.ino index c52689e..010dc29 100644 --- a/examples/EthernetShield_Initiator/EthernetShield_Initiator.ino +++ b/examples/EthernetShield_Initiator/EthernetShield_Initiator.ino @@ -46,10 +46,10 @@ void setup() }); MIDI.setHandleNoteOn([](byte channel, byte note, byte velocity) { - DBG(F("NoteOn "), note); + DBG(F("NoteOn"), note); }); MIDI.setHandleNoteOff([](byte channel, byte note, byte velocity) { - DBG(F("NoteOff "), note); + DBG(F("NoteOff"), note); }); // Initiate the session diff --git a/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino b/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino index 2bde13d..066fbbc 100644 --- a/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino +++ b/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino @@ -46,10 +46,10 @@ void setup() }); MIDI.setHandleNoteOn([](byte channel, byte note, byte velocity) { - DBG(F("NoteOn "), note); + DBG(F("NoteOn"), note); }); MIDI.setHandleNoteOff([](byte channel, byte note, byte velocity) { - DBG(F("NoteOff "), note); + DBG(F("NoteOff"), note); }); DBG(F("Sending MIDI messages every second")); @@ -74,6 +74,6 @@ void loop() byte channel = 1; MIDI.sendNoteOn(note, velocity, channel); - MIDI.sendNoteOff(note, velocity, channel); +// MIDI.sendNoteOff(note, velocity, channel); } } diff --git a/examples/EthernetShield_ReceivedRawMidiData/EthernetShield_ReceivedRawMidiData.ino b/examples/EthernetShield_ReceivedRawMidiData/EthernetShield_ReceivedRawMidiData.ino index aa3e441..da139f0 100644 --- a/examples/EthernetShield_ReceivedRawMidiData/EthernetShield_ReceivedRawMidiData.ino +++ b/examples/EthernetShield_ReceivedRawMidiData/EthernetShield_ReceivedRawMidiData.ino @@ -49,10 +49,10 @@ void setup() AppleMIDI.setHandleEndReceivedMidi(OnAppleMidiEndReceive); MIDI.setHandleNoteOn([](byte channel, byte note, byte velocity) { - DBG(F("NoteOn "), note); + DBG(F("NoteOn"), note); }); MIDI.setHandleNoteOff([](byte channel, byte note, byte velocity) { - DBG(F("NoteOff "), note); + DBG(F("NoteOff"), note); }); } diff --git a/examples/EthernetShield_SysEx/EthernetShield_SysEx.ino b/examples/EthernetShield_SysEx/EthernetShield_SysEx.ino index 801b2e3..60ea425 100644 --- a/examples/EthernetShield_SysEx/EthernetShield_SysEx.ino +++ b/examples/EthernetShield_SysEx/EthernetShield_SysEx.ino @@ -1,8 +1,4 @@ -#include - -#define SerialMon Serial -#define APPLEMIDI_DEBUG SerialMon -#include +#include // Enter a MAC address for your controller below. // Newer Ethernet shields have a MAC address printed on a sticker on the shield @@ -27,7 +23,7 @@ byte sysexBig[] = { 0xF0, 0x41, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0xF7 }; -APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); +MIDI_CREATE_DEFAULT_INSTANCE(); // ----------------------------------------------------------------------------- // @@ -37,27 +33,7 @@ void setup() DBG_SETUP(115200); DBG("Booting"); - if (Ethernet.begin(mac) == 0) { - DBG(F("Failed DHCP, check network cable & reboot")); - for (;;); - } - - DBG(F("OK, now make sure you an rtpMIDI session that is Enabled")); - DBG(F("Add device named Arduino with Host"), Ethernet.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); - DBG(F("Then press the Connect button")); - DBG(F("Then open a MIDI listener and monitor incoming notes")); - MIDI.begin(); - - AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { - isConnected = true; - DBG(F("Connected to session"), name); - }); - AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { - isConnected = false; - DBG(F("Disconnected")); - }); - MIDI.setHandleSystemExclusive(OnMidiSysEx); DBG(F("Send SysEx every second")); diff --git a/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino b/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino index e95d787..30d402d 100644 --- a/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino +++ b/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino @@ -38,10 +38,10 @@ void setup() }); MIDI.setHandleNoteOn([](byte channel, byte note, byte velocity) { - DBG(F("NoteOn "), note); + DBG(F("NoteOn"), note); }); MIDI.setHandleNoteOff([](byte channel, byte note, byte velocity) { - DBG(F("NoteOff "), note); + DBG(F("NoteOff"), note); }); MDNS.addService("apple-midi", "udp", AppleMIDI.getPort()); From 64a2f6c6a73116c0a2a2a09bba6112afadf1ddee Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sat, 19 Dec 2020 16:37:16 +0100 Subject: [PATCH 049/271] remove unneeded initialisation --- src/AppleMIDI_Participant.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AppleMIDI_Participant.h b/src/AppleMIDI_Participant.h index 859c807..f1099cf 100644 --- a/src/AppleMIDI_Participant.h +++ b/src/AppleMIDI_Participant.h @@ -16,7 +16,7 @@ struct Participant unsigned long receiverFeedbackStartTime; bool doReceiverFeedback = false; - uint16_t sequenceNr = random(1, UINT16_MAX); // http://www.rfc-editor.org/rfc/rfc6295.txt , 2.1. RTP Header + uint16_t sequenceNr; unsigned long lastSyncExchangeTime; #ifdef APPLEMIDI_INITIATOR From 71a8010ceefcd2dfb46cd232575abc967168cc4b Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sat, 19 Dec 2020 16:38:25 +0100 Subject: [PATCH 050/271] fix bug where using wrong sequenceNr --- src/AppleMIDI.h | 3 ++- src/AppleMIDI.hpp | 18 ++++++++++-------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/AppleMIDI.h b/src/AppleMIDI.h index bb7da70..86832a7 100644 --- a/src/AppleMIDI.h +++ b/src/AppleMIDI.h @@ -63,7 +63,7 @@ class AppleMIDISession const char* getName() { return this->localName; }; const uint16_t getPort() { return this->port; }; - const ssrc_t getSynchronizationSource() { return this->ssrc; }; + const ssrc_t getSynchronizationSource() { return this->ssrc; }; void setName(const char *sessionName) { strncpy(this->localName, sessionName, DefaultSettings::MaxSessionNameLen); }; @@ -237,6 +237,7 @@ class AppleMIDISession uint16_t port = DEFAULT_CONTROL_PORT; Deque, Settings::MaxNumberOfParticipants> participants; int32_t latencyAdjustment = 0; + uint16_t sequenceNr = random(1, UINT16_MAX); private: void readControlPackets(); diff --git a/src/AppleMIDI.hpp b/src/AppleMIDI.hpp index 07ec39c..10bb292 100644 --- a/src/AppleMIDI.hpp +++ b/src/AppleMIDI.hpp @@ -126,7 +126,6 @@ void AppleMIDISession::ReceivedControlInvitation(A participant.remoteIP = controlPort.remoteIP(); participant.remotePort = controlPort.remotePort(); participant.lastSyncExchangeTime = now; - participant.sequenceNr = random(1, UINT16_MAX); // // http://www.rfc-editor.org/rfc/rfc6295.txt , 2.1. RTP Header #ifdef KEEP_SESSION_NAME strncpy(participant.sessionName, invitation.sessionName, DefaultSettings::MaxSessionNameLen); #endif @@ -345,7 +344,8 @@ void AppleMIDISession::ReceivedSynchronization(App template void AppleMIDISession::ReceivedReceiverFeedback(AppleMIDI_ReceiverFeedback_t &receiverFeedback) { - // As we do not keep any recovery journals, no command history, nothing! + // We do not keep any recovery journals, no command history, nothing! + // If we did, then we can flush the previous sent buffer until receiverFeedback.sequenceNr } template @@ -479,9 +479,7 @@ void AppleMIDISession::writeRtpMidiBuffer(Particip if (!dataPort.beginPacket(remoteIP, remotePort)) return; - - participant->sequenceNr++; // (modulo 2^16) modulo is automatically done for us () - + Rtp rtp; rtp.vpxcc = 0b10000000; // TODO: fun with flags rtp.mpayload = PAYLOADTYPE_RTPMIDI; // TODO: set or unset marker @@ -502,8 +500,12 @@ void AppleMIDISession::writeRtpMidiBuffer(Particip // prepared to defer rendering the messages until the proper time.) // rtp.timestamp = (Settings::TimestampRtpPackets) ? htonl(rtpMidiClock.Now()) : 0; - - rtp.sequenceNr = htons(participant->sequenceNr); + + // + sequenceNr++; // (modulo 2^16) modulo is automatically done for us () + rtp.sequenceNr = htons(sequenceNr); + + dataPort.write((uint8_t *)&rtp, sizeof(rtp)); // only now the length is known @@ -841,7 +843,7 @@ void AppleMIDISession::ReceivedRtp(const Rtp_t& rt auto latency = 0; #endif participant->sequenceNr = rtp.sequenceNr; - + if (NULL != _receivedRtpCallback) _receivedRtpCallback(0, rtp, latency); } From 51ae878c49a8f65e6a5751980921f149b6b3ad20 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sat, 19 Dec 2020 20:25:39 +0100 Subject: [PATCH 051/271] Update EthernetShield_Initiator.ino --- .../EthernetShield_Initiator.ino | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/examples/EthernetShield_Initiator/EthernetShield_Initiator.ino b/examples/EthernetShield_Initiator/EthernetShield_Initiator.ino index 010dc29..1201965 100644 --- a/examples/EthernetShield_Initiator/EthernetShield_Initiator.ino +++ b/examples/EthernetShield_Initiator/EthernetShield_Initiator.ino @@ -30,9 +30,6 @@ void setup() } DBG(F("OK, now make sure you an rtpMIDI session that is Enabled")); - DBG(F("Add device named Arduino with Host"), Ethernet.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); - DBG(F("Then press the Connect button")); - DBG(F("Then open a MIDI listener and monitor incoming notes")); MIDI.begin(); @@ -53,9 +50,13 @@ void setup() }); // Initiate the session - IPAddress remote(192, 168, 1, 4); + IPAddress remote(192, 168, 1, 65); AppleMIDI.sendInvite(remote, DEFAULT_CONTROL_PORT); // port is 5004 by default + DBG(F("Connecting to "), remote, "Port", DEFAULT_CONTROL_PORT, "(Name", AppleMIDI.getName(), ")"); + DBG(F("Watch as this session is added to the Participants list")); + DBG(F("Then open a MIDI listener and monitor incoming notes")); + DBG(F("Sending a random NoteOn/Off every second")); } @@ -77,7 +78,7 @@ void loop() byte velocity = 55; byte channel = 1; - MIDI.sendNoteOn(note, velocity, channel); - MIDI.sendNoteOff(note, velocity, channel); + // MIDI.sendNoteOn(note, velocity, channel); + // MIDI.sendNoteOff(note, velocity, channel); } } From d6087cbd886c6bc9c24029813350762ec813da94 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sat, 19 Dec 2020 20:30:51 +0100 Subject: [PATCH 052/271] Update AppleMIDI_Defs.h --- src/AppleMIDI_Defs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AppleMIDI_Defs.h b/src/AppleMIDI_Defs.h index 9703c31..66b143a 100644 --- a/src/AppleMIDI_Defs.h +++ b/src/AppleMIDI_Defs.h @@ -149,7 +149,7 @@ typedef struct PACKED AppleMIDI_Synchronization { ssrc_t ssrc; uint8_t count; - uint8_t padding[3]; + uint8_t padding[3] = {0,0,0}; timestamp_t timestamps[3]; } AppleMIDI_Synchronization_t; From 9fba5d9afaccc168b6e85f08af19d90b826abc7a Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sat, 19 Dec 2020 21:05:47 +0100 Subject: [PATCH 053/271] Update wESP32_NoteOnOffEverySec.ino --- examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino b/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino index 30d402d..195e12d 100644 --- a/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino +++ b/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino @@ -22,7 +22,7 @@ void setup() MDNS.begin(AppleMIDI.getName()); DBG(F("OK, now make sure you an rtpMIDI session that is Enabled")); - DBG(F("Add device named Arduino with Host"), WiFi.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); + DBG(F("Add device named Arduino with Host"), ETH.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); DBG(F("Then press the Connect button")); DBG(F("Then open a MIDI listener and monitor incoming notes")); From a84ca70f7e0c887c9fddf082c7ccc616fc03eab2 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sat, 19 Dec 2020 21:06:14 +0100 Subject: [PATCH 054/271] Update AppleMIDI.hpp fixed htonl changing the ssrc --- src/AppleMIDI.hpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/AppleMIDI.hpp b/src/AppleMIDI.hpp index 10bb292..e9a041e 100644 --- a/src/AppleMIDI.hpp +++ b/src/AppleMIDI.hpp @@ -395,7 +395,8 @@ void AppleMIDISession::writeInvitation(UdpClass &p port.write((uint8_t *)command, sizeof(amInvitation)); port.write((uint8_t *)amProtocolVersion, sizeof(amProtocolVersion)); invitation.initiatorToken = htonl(invitation.initiatorToken); - invitation.ssrc = htonl(ssrc); + invitation.ssrc = ssrc; + invitation.ssrc = htonl(invitation.ssrc); port.write(reinterpret_cast(&invitation), invitation.getLength()); port.endPacket(); @@ -429,7 +430,8 @@ void AppleMIDISession::writeSynchronization(const { dataPort.write((uint8_t *)amSignature, sizeof(amSignature)); dataPort.write((uint8_t *)amSynchronization, sizeof(amSynchronization)); - synchronization.ssrc = htonl(this->ssrc); + synchronization.ssrc = ssrc; + synchronization.ssrc = htonl(synchronization.ssrc); synchronization.timestamps[0] = htonll(synchronization.timestamps[0]); synchronization.timestamps[1] = htonll(synchronization.timestamps[1]); @@ -483,7 +485,8 @@ void AppleMIDISession::writeRtpMidiBuffer(Particip Rtp rtp; rtp.vpxcc = 0b10000000; // TODO: fun with flags rtp.mpayload = PAYLOADTYPE_RTPMIDI; // TODO: set or unset marker - rtp.ssrc = htonl(ssrc); + rtp.ssrc = ssrc; + rtp.ssrc = htonl(rtp.ssrc); // https://developer.apple.com/library/ios/documentation/CoreMidi/Reference/MIDIServices_Reference/#//apple_ref/doc/uid/TP40010316-CHMIDIServiceshFunctions-SW30 // The time at which the events occurred, if receiving MIDI, or, if sending MIDI, @@ -503,8 +506,9 @@ void AppleMIDISession::writeRtpMidiBuffer(Particip // sequenceNr++; // (modulo 2^16) modulo is automatically done for us () - rtp.sequenceNr = htons(sequenceNr); + rtp.sequenceNr = sequenceNr; + rtp.sequenceNr = htons(rtp.sequenceNr); dataPort.write((uint8_t *)&rtp, sizeof(rtp)); From cd149374467caedc25d75cd4e72d06e10c4b6ae8 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sat, 19 Dec 2020 21:53:54 +0100 Subject: [PATCH 055/271] Update EthernetShield_SysEx.ino --- .../EthernetShield_SysEx.ino | 52 ++++++++++++++----- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/examples/EthernetShield_SysEx/EthernetShield_SysEx.ino b/examples/EthernetShield_SysEx/EthernetShield_SysEx.ino index 60ea425..2296d8c 100644 --- a/examples/EthernetShield_SysEx/EthernetShield_SysEx.ino +++ b/examples/EthernetShield_SysEx/EthernetShield_SysEx.ino @@ -1,4 +1,8 @@ -#include +#include + +#define SerialMon Serial +#define APPLEMIDI_DEBUG SerialMon +#include // Enter a MAC address for your controller below. // Newer Ethernet shields have a MAC address printed on a sticker on the shield @@ -13,17 +17,18 @@ byte sysex14[] = { 0xF0, 0x43, 0x20, 0x7E, 0x4C, 0x4D, 0x20, 0x20, 0x38, 0x39, 0 byte sysex15[] = { 0xF0, 0x43, 0x20, 0x7E, 0x4C, 0x4D, 0x20, 0x20, 0x38, 0x39, 0x37, 0x33, 0x50, 0x4D, 0xF7 }; byte sysex16[] = { 0xF0, 0x43, 0x20, 0x7E, 0x4C, 0x4D, 0x20, 0x20, 0x38, 0x39, 0x37, 0x33, 0x32, 0x50, 0x4D, 0xF7 }; byte sysexBig[] = { 0xF0, 0x41, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, - 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x7a, - 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, - 0xF7 }; - -MIDI_CREATE_DEFAULT_INSTANCE(); + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, + 0x7a, + 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0xF7 + }; + +APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); // ----------------------------------------------------------------------------- // @@ -33,6 +38,25 @@ void setup() DBG_SETUP(115200); DBG("Booting"); + if (Ethernet.begin(mac) == 0) { + DBG(F("Failed DHCP, check network cable & reboot")); + for (;;); + } + + DBG(F("OK, now make sure you an rtpMIDI session that is Enabled")); + DBG(F("Add device named Arduino with Host"), Ethernet.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); + DBG(F("Then press the Connect button")); + DBG(F("Then open a MIDI listener and monitor incoming notes")); + + AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { + isConnected = true; + DBG(F("Connected to session"), name); + }); + AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { + isConnected = false; + DBG(F("Disconnected")); + }); + MIDI.begin(); MIDI.setHandleSystemExclusive(OnMidiSysEx); @@ -51,8 +75,8 @@ void loop() // (dont cáll delay(1000) as it will stall the pipeline) if (isConnected && (millis() - t1) > 1000) { - MIDI.sendSysEx(sizeof(sysexBig), sysexBig, true); - t1 = millis(); + MIDI.sendSysEx(sizeof(sysexBig), sysexBig, true); + t1 = millis(); } } From 59bd1cdec7784391f2426b35ca9bf97999f54cb7 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sun, 20 Dec 2020 08:31:09 +0100 Subject: [PATCH 056/271] removed version badge - already in Arduino Lib badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f3828d7..9b61192 100755 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # AppleMIDI (aka rtpMIDI) for Arduino -[![arduino-library-badge](https://www.ardu-badge.com/badge/AppleMIDI.svg?)](https://www.ardu-badge.com/AppleMIDI) [![Build Status](https://travis-ci.org/lathoub/Arduino-AppleMIDI-Library.svg?branch=master)](https://travis-ci.org/lathoub/Arduino-AppleMIDI-Library) [![License: CC BY-SA 4.0](https://img.shields.io/badge/License-CC%20BY--SA%204.0-lightgrey.svg)](http://creativecommons.org/licenses/by-sa/4.0/) [![GitHub version](https://badge.fury.io/gh/lathoub%2FArduino-AppleMidi-Library.svg)](https://badge.fury.io/gh/lathoub%2FArduino-AppleMidi-Library) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/c8be2ccc3f104e0588572a39f8106070)](https://app.codacy.com/app/lathoub/Arduino-AppleMIDI-Library?utm_source=github.com&utm_medium=referral&utm_content=lathoub/Arduino-AppleMIDI-Library&utm_campaign=Badge_Grade_Dashboard) +[![arduino-library-badge](https://www.ardu-badge.com/badge/AppleMIDI.svg?)](https://www.ardu-badge.com/AppleMIDI) [![Build Status](https://travis-ci.org/lathoub/Arduino-AppleMIDI-Library.svg?branch=master)](https://travis-ci.org/lathoub/Arduino-AppleMIDI-Library) [![License: CC BY-SA 4.0](https://img.shields.io/badge/License-CC%20BY--SA%204.0-lightgrey.svg)](http://creativecommons.org/licenses/by-sa/4.0/) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/c8be2ccc3f104e0588572a39f8106070)](https://app.codacy.com/app/lathoub/Arduino-AppleMIDI-Library?utm_source=github.com&utm_medium=referral&utm_content=lathoub/Arduino-AppleMIDI-Library&utm_campaign=Badge_Grade_Dashboard) Enables an Arduino with IP/UDP capabilities (Ethernet shield, ESP8266, ESP32, ...) to particpate in an AppleMIDI session. From e12eb30c1358c291c8bee0b6702dbc4a6191ff37 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Mon, 21 Dec 2020 21:55:54 +0100 Subject: [PATCH 057/271] debug text update (very minor update) --- examples/ESP32_Callbacks/ESP32_Callbacks.ino | 2 +- .../ESP8266_NoteOnOffEverySec.ino | 2 +- .../EthernetShield_MultipleSessions.ino | 2 +- .../EthernetShield_NonDefaultSession.ino | 2 +- .../EthernetShield_NoteOnOffEverySec.ino | 2 +- .../EthernetShield_ReceivedRawMidiData.ino | 2 +- .../EthernetShield_SysEx.ino | 2 +- keywords.txt | 47 +------------------ 8 files changed, 8 insertions(+), 53 deletions(-) diff --git a/examples/ESP32_Callbacks/ESP32_Callbacks.ino b/examples/ESP32_Callbacks/ESP32_Callbacks.ino index a431508..5568e5c 100644 --- a/examples/ESP32_Callbacks/ESP32_Callbacks.ino +++ b/examples/ESP32_Callbacks/ESP32_Callbacks.ino @@ -23,7 +23,7 @@ void setup() { DBG(F("OK, now make sure you an rtpMIDI session that is Enabled")); DBG(F("Add device named Arduino with Host"), WiFi.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); - DBG(F("Then press the Connect button")); + DBG(F("Select and then press the Connect button")); DBG(F("Then open a MIDI listener and monitor incoming notes")); AppleMIDI.setHandleConnected(OnAppleMidiConnected); diff --git a/examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino b/examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino index 4552a6d..c45e9fb 100644 --- a/examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino +++ b/examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino @@ -32,7 +32,7 @@ void setup() DBG(F("OK, now make sure you an rtpMIDI session that is Enabled")); DBG(F("Add device named Arduino with Host"), WiFi.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); - DBG(F("Then press the Connect button")); + DBG(F("Select and then press the Connect button")); DBG(F("Then open a MIDI listener and monitor incoming notes")); DBG(F("Listen to incoming MIDI commands")); diff --git a/examples/EthernetShield_MultipleSessions/EthernetShield_MultipleSessions.ino b/examples/EthernetShield_MultipleSessions/EthernetShield_MultipleSessions.ino index 293d659..95cbb8b 100644 --- a/examples/EthernetShield_MultipleSessions/EthernetShield_MultipleSessions.ino +++ b/examples/EthernetShield_MultipleSessions/EthernetShield_MultipleSessions.ino @@ -32,7 +32,7 @@ void setup() DBG(F("OK, now make sure you an rtpMIDI session that is Enabled")); DBG(F("Add device named Arduino with Host"), Ethernet.localIP(), "Port", AppleMIDI1.getPort(), "(Name", AppleMIDI1.getName(), ")"); DBG(F("Add device named Arduino with Host"), Ethernet.localIP(), "Port", AppleMIDI2.getPort(), "(Name", AppleMIDI2.getName(), ")"); - DBG(F("Then press the Connect button")); + DBG(F("Select and then press the Connect button")); DBG(F("Then open a MIDI listener and monitor incoming notes")); // Listen for MIDI messages on channel 1 diff --git a/examples/EthernetShield_NonDefaultSession/EthernetShield_NonDefaultSession.ino b/examples/EthernetShield_NonDefaultSession/EthernetShield_NonDefaultSession.ino index e97c356..797cb07 100644 --- a/examples/EthernetShield_NonDefaultSession/EthernetShield_NonDefaultSession.ino +++ b/examples/EthernetShield_NonDefaultSession/EthernetShield_NonDefaultSession.ino @@ -31,7 +31,7 @@ void setup() DBG(F("OK, now make sure you an rtpMIDI session that is Enabled")); DBG(F("Add device named Arduino with Host"), Ethernet.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); - DBG(F("Then press the Connect button")); + DBG(F("Select and then press the Connect button")); DBG(F("Then open a MIDI listener and monitor incoming notes")); MIDI.begin(); diff --git a/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino b/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino index 066fbbc..23d5f58 100644 --- a/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino +++ b/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino @@ -30,7 +30,7 @@ void setup() DBG(F("OK, now make sure you an rtpMIDI session that is Enabled")); DBG(F("Add device named Arduino with Host"), Ethernet.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); - DBG(F("Then press the Connect button")); + DBG(F("Select and then press the Connect button")); DBG(F("Then open a MIDI listener and monitor incoming notes")); MIDI.begin(); diff --git a/examples/EthernetShield_ReceivedRawMidiData/EthernetShield_ReceivedRawMidiData.ino b/examples/EthernetShield_ReceivedRawMidiData/EthernetShield_ReceivedRawMidiData.ino index da139f0..ba61901 100644 --- a/examples/EthernetShield_ReceivedRawMidiData/EthernetShield_ReceivedRawMidiData.ino +++ b/examples/EthernetShield_ReceivedRawMidiData/EthernetShield_ReceivedRawMidiData.ino @@ -30,7 +30,7 @@ void setup() DBG(F("OK, now make sure you an rtpMIDI session that is Enabled")); DBG(F("Add device named Arduino with Host"), Ethernet.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); - DBG(F("Then press the Connect button")); + DBG(F("Select and then press the Connect button")); DBG(F("Then open a MIDI listener and monitor incoming notes")); MIDI.begin(); diff --git a/examples/EthernetShield_SysEx/EthernetShield_SysEx.ino b/examples/EthernetShield_SysEx/EthernetShield_SysEx.ino index 2296d8c..eb023aa 100644 --- a/examples/EthernetShield_SysEx/EthernetShield_SysEx.ino +++ b/examples/EthernetShield_SysEx/EthernetShield_SysEx.ino @@ -45,7 +45,7 @@ void setup() DBG(F("OK, now make sure you an rtpMIDI session that is Enabled")); DBG(F("Add device named Arduino with Host"), Ethernet.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); - DBG(F("Then press the Connect button")); + DBG(F("Select and then press the Connect button")); DBG(F("Then open a MIDI listener and monitor incoming notes")); AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { diff --git a/keywords.txt b/keywords.txt index 5f762b5..f8577b8 100644 --- a/keywords.txt +++ b/keywords.txt @@ -14,61 +14,16 @@ AppleMidi KEYWORD1 setHandleConnected KEYWORD2 setHandleDisconnected KEYWORD2 setHandleError KEYWORD2 +setHandleException KEYWORD2 setHandleStartReceivedMidi KEYWORD2 setHandleReceivedMidi KEYWORD2 setHandleEndReceivedMidi KEYWORD2 setHandleReceivedRtp KEYWORD2 -setHandleNoteOff KEYWORD2 -setHandleNoteOn KEYWORD2 -setHandleAfterTouchPoly KEYWORD2 -setHandleControlChange KEYWORD2 -setHandleProgramChange KEYWORD2 -setHandleAfterTouchChannel KEYWORD2 -setHandlePitchBend KEYWORD2 -setHandleSystemExclusive KEYWORD2 -setHandleTimeCodeQuarterFrame KEYWORD2 -setHandleSongPosition KEYWORD2 -setHandleSongSelect KEYWORD2 -setHandleTuneRequest KEYWORD2 -setHandleClock KEYWORD2 -setHandleStart KEYWORD2 -setHandleContinue KEYWORD2 -setHandleStop KEYWORD2 -setHandleActiveSensing KEYWORD2 -setHandleSystemReset KEYWORD2 - -begin KEYWORD2 -run KEYWORD2 -sendNoteOn KEYWORD2 -sendNoteOff KEYWORD2 -sendAfterTouchPoly KEYWORD2 -sendControlChange KEYWORD2 -sendProgramChange KEYWORD2 -sendAfterTouchChannel KEYWORD2 -sendPitchBend KEYWORD2 -sendSystemEx KEYWORD2 -sendTimeCodeQuarterFrame KEYWORD2 -sendSongPosition KEYWORD2 -sendSongSelect KEYWORD2 -sendTuneRequest KEYWORD2 -sendClock KEYWORD2 -sendStart KEYWORD2 -sendContinue KEYWORD2 -sendStop KEYWORD2 -sendActiveSensing KEYWORD2 -sendSystemReset KEYWORD2 -sendTimeCodeQuarterFrame KEYWORD2 -sendSysEx KEYWORD2 -sendAfterTouch KEYWORD2 -sendPolyPressure KEYWORD2 -sendTick KEYWORD2 - ####################################### # Instances (KEYWORD3) ####################################### AppleMIDI KEYWORD3 -MIDI KEYWORD3 ####################################### # Constants (LITERAL1) From 28a84a75c6cbb711a6fcfafd52a11d34f568b015 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Mon, 21 Dec 2020 21:56:59 +0100 Subject: [PATCH 058/271] debug update --- test/NoteOn.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/NoteOn.cpp b/test/NoteOn.cpp index b0cb7cc..b36d3b0 100644 --- a/test/NoteOn.cpp +++ b/test/NoteOn.cpp @@ -100,7 +100,7 @@ void begin() { DBG(F("OK, now make sure you an rtpMIDI session that is Enabled")); DBG(F("Add device named Arduino with Host"), Ethernet.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); - DBG(F("Then press the Connect button")); + DBG(F("Select and then press the Connect button")); DBG(F("Then open a MIDI listener and monitor incoming notes")); MIDI.begin(); From 9d47f3192ac35aac51cc96c96db715e182d018a0 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Mon, 21 Dec 2020 21:57:31 +0100 Subject: [PATCH 059/271] deprecate Error callback, replace with Exception callback --- .../wESP32_NoteOnOffEverySec.ino | 18 +++-- src/AppleMIDI.h | 9 ++- src/AppleMIDI.hpp | 73 +++++++++++++------ src/AppleMIDI_Defs.h | 5 +- src/AppleMIDI_Participant.h | 6 +- 5 files changed, 76 insertions(+), 35 deletions(-) diff --git a/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino b/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino index 195e12d..11d793a 100644 --- a/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino +++ b/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino @@ -19,11 +19,13 @@ void setup() ETH_startup(); - MDNS.begin(AppleMIDI.getName()); + if (!MDNS.begin(AppleMIDI.getName())) + DBG(F("Error setting up MDNS responder")); DBG(F("OK, now make sure you an rtpMIDI session that is Enabled")); - DBG(F("Add device named Arduino with Host"), ETH.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); - DBG(F("Then press the Connect button")); + DBG(F("Add device named Arduino with Host"), ETH.localIP(), "Port", AppleMIDI.getPort()); + DBG(F("The device should also be visible in the directory as"), AppleMIDI.getName()); + DBG(F("Select and then press the Connect button")); DBG(F("Then open a MIDI listener and monitor incoming notes")); MIDI.begin(); @@ -36,7 +38,13 @@ void setup() isConnected = false; DBG(F("Disconnected")); }); - + AppleMIDI.setHandleError([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, int32_t e) { + DBG(F("______________Error"), e); + }); + AppleMIDI.setHandleException([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const APPLEMIDI_NAMESPACE::Exception & e, const int32_t value) { + DBG(F("______________Exception"), e, value); + }); + MIDI.setHandleNoteOn([](byte channel, byte note, byte velocity) { DBG(F("NoteOn"), note); }); @@ -66,6 +74,6 @@ void loop() byte channel = 1; MIDI.sendNoteOn(note, velocity, channel); - MIDI.sendNoteOff(note, velocity, channel); + // MIDI.sendNoteOff(note, velocity, channel); } } diff --git a/src/AppleMIDI.h b/src/AppleMIDI.h index 86832a7..6876d50 100644 --- a/src/AppleMIDI.h +++ b/src/AppleMIDI.h @@ -55,7 +55,8 @@ 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)) { _exceptionCallback = fptr; } + void setHandleError(void (*fptr)(const ssrc_t&, int32_t)) __attribute__ ((deprecated)) { _errorCallback = fptr; } // deprecated + void setHandleException(void (*fptr)(const ssrc_t&, const Exception&, const int32_t value)) { _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; } @@ -150,8 +151,8 @@ class AppleMIDISession } else { - if (NULL != _exceptionCallback) - _exceptionCallback(ssrc, BufferFullException); + if (NULL != _errorCallback) + _errorCallback(ssrc, BufferFullException); } } @@ -224,6 +225,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 @@ -237,7 +239,6 @@ class AppleMIDISession uint16_t port = DEFAULT_CONTROL_PORT; Deque, Settings::MaxNumberOfParticipants> participants; int32_t latencyAdjustment = 0; - uint16_t sequenceNr = random(1, UINT16_MAX); private: void readControlPackets(); diff --git a/src/AppleMIDI.hpp b/src/AppleMIDI.hpp index e9a041e..0a07a53 100644 --- a/src/AppleMIDI.hpp +++ b/src/AppleMIDI.hpp @@ -30,8 +30,8 @@ void AppleMIDISession::parseControlPackets() auto retVal = _appleMIDIParser.parse(controlBuffer, amPortType::Control); if (retVal == parserReturn::UnexpectedData) { - if (NULL != _exceptionCallback) - _exceptionCallback(ssrc, ParseException); + if (NULL != _errorCallback) + _errorCallback(ssrc, ParseException); controlBuffer.pop_front(); } @@ -81,8 +81,8 @@ void AppleMIDISession::parseDataPackets() || retVal2 == parserReturn::NotSureGiveMeMoreData) break; // one or the other buffer does not have enough data - if (NULL != _exceptionCallback) - _exceptionCallback(ssrc, UnexpectedParseException); + if (NULL != _errorCallback) + _errorCallback(ssrc, UnexpectedParseException); dataBuffer.pop_front(); } @@ -114,8 +114,8 @@ void AppleMIDISession::ReceivedControlInvitation(A { writeInvitation(controlPort, controlPort.remoteIP(), controlPort.remotePort(), invitation, amInvitationRejected); - if (NULL != _exceptionCallback) - _exceptionCallback(ssrc, TooManyParticipantsException); + if (NULL != _errorCallback) + _errorCallback(ssrc, TooManyParticipantsException); return; } @@ -143,8 +143,8 @@ void AppleMIDISession::ReceivedDataInvitation(Appl { writeInvitation(dataPort, dataPort.remoteIP(), dataPort.remotePort(), invitation, amInvitationRejected); - if (NULL != _exceptionCallback) - _exceptionCallback(ssrc, ParticipantNotFoundException); + if (NULL != _errorCallback) + _errorCallback(ssrc, ParticipantNotFoundException); return; } @@ -344,8 +344,23 @@ void AppleMIDISession::ReceivedSynchronization(App template void AppleMIDISession::ReceivedReceiverFeedback(AppleMIDI_ReceiverFeedback_t &receiverFeedback) { - // We do not keep any recovery journals, no command history, nothing! - // If we did, then we can flush the previous sent buffer until receiverFeedback.sequenceNr + // We do not keep any recovery journals, no command history, nothing! + // Here is where you would correct if packets are dropped (send them again) + + auto participant = getParticipantBySSRC(receiverFeedback.ssrc); + if (NULL != participant) { + if (participant->sendSequenceNr != receiverFeedback.sequenceNr) + { + Serial.print("ERRORRORORORORORORRROROROROROROR"); + + if (NULL != _exceptionCallback) + _exceptionCallback(ssrc, SendPacketsDropped, participant->sendSequenceNr - receiverFeedback.sequenceNr); + + Serial.print(participant->sendSequenceNr); + Serial.print(" "); + Serial.println(receiverFeedback.sequenceNr); + } + } } template @@ -504,10 +519,10 @@ void AppleMIDISession::writeRtpMidiBuffer(Particip // rtp.timestamp = (Settings::TimestampRtpPackets) ? htonl(rtpMidiClock.Now()) : 0; - // - sequenceNr++; // (modulo 2^16) modulo is automatically done for us () + // increament the sequenceNr + participant->sendSequenceNr++; - rtp.sequenceNr = sequenceNr; + rtp.sequenceNr = participant->sendSequenceNr; rtp.sequenceNr = htons(rtp.sequenceNr); dataPort.write((uint8_t *)&rtp, sizeof(rtp)); @@ -586,8 +601,8 @@ void AppleMIDISession::manageSynchronizationListen // 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); + if (NULL != _errorCallback) + _errorCallback(ssrc, ListenerTimeOutException); sendEndSession(participant); @@ -652,8 +667,8 @@ void AppleMIDISession::manageSynchronizationInitia { if (participant->synchronizationCount > DefaultSettings::MaxSynchronizationCK0Attempts) { - if (NULL != _exceptionCallback) - _exceptionCallback(ssrc, MaxAttemptsException); + if (NULL != _errorCallback) + _errorCallback(ssrc, MaxAttemptsException); // After too many attempts, stop. sendEndSession(participant); @@ -711,8 +726,8 @@ void AppleMIDISession::manageSessionInvites() { if (participant->connectionAttempts >= DefaultSettings::MaxSessionInvitesAttempts) { - if (NULL != _exceptionCallback) - _exceptionCallback(ssrc, NoResponseFromConnectionRequestException); + if (NULL != _errorCallback) + _errorCallback(ssrc, NoResponseFromConnectionRequestException); // After too many attempts, stop. sendEndSession(participant); @@ -770,7 +785,7 @@ void AppleMIDISession::manageReceiverFeedback() { AppleMIDI_ReceiverFeedback_t rf; rf.ssrc = ssrc; - rf.sequenceNr = participant->sequenceNr; + rf.sequenceNr = participant->receiveSequenceNr; writeReceiverFeedback(participant->remoteIP, participant->remotePort, rf); // reset the clock. It is started when we receive MIDI @@ -795,8 +810,8 @@ bool AppleMIDISession::sendInvite(IPAddress ip, ui participant.remotePort = port; participant.lastInviteSentTime = now - 1000; // forces invite to be send immediately participant.lastSyncExchangeTime = now; - participant.initiatorToken = random(1, INT32_MAX) * 2; // 0xb7062030; - participant.sequenceNr = random(1, UINT16_MAX); // // http://www.rfc-editor.org/rfc/rfc6295.txt , 2.1. RTP Header + participant.initiatorToken = random(1, INT32_MAX) * 2; + participant.sequenceNr; participants.push_back(participant); @@ -846,7 +861,19 @@ void AppleMIDISession::ReceivedRtp(const Rtp_t& rt #else auto latency = 0; #endif - participant->sequenceNr = rtp.sequenceNr; + + if (participant->receiveSequenceNr + 1 != rtp.sequenceNr) { + + if (NULL != _exceptionCallback) + _exceptionCallback(ssrc, ReceivedPacketsDropped, participant->receiveSequenceNr + 1 - rtp.sequenceNr); + + Serial.print("___ERROR____"); + Serial.print(participant->receiveSequenceNr); + Serial.print(" "); + Serial.println(rtp.sequenceNr); + } + + participant->receiveSequenceNr = rtp.sequenceNr; if (NULL != _receivedRtpCallback) _receivedRtpCallback(0, rtp, latency); diff --git a/src/AppleMIDI_Defs.h b/src/AppleMIDI_Defs.h index 66b143a..7ae69f2 100644 --- a/src/AppleMIDI_Defs.h +++ b/src/AppleMIDI_Defs.h @@ -98,6 +98,8 @@ enum Exception : uint8_t ListenerTimeOutException, MaxAttemptsException, NoResponseFromConnectionRequestException, + SendPacketsDropped, + ReceivedPacketsDropped, }; using connectedCallback = void (*)(const ssrc_t&, const char *); @@ -106,7 +108,8 @@ 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 exceptionCallback = void (*)(const ssrc_t&, int32_t); +using errorCallback = void (*)(const ssrc_t&, int32_t); +using exceptionCallback = void (*)(const ssrc_t&, const Exception&, const int32_t value); /* Signature "Magic Value" for Apple network MIDI session establishment */ const byte amSignature[] = {0xff, 0xff}; diff --git a/src/AppleMIDI_Participant.h b/src/AppleMIDI_Participant.h index f1099cf..878dd8d 100644 --- a/src/AppleMIDI_Participant.h +++ b/src/AppleMIDI_Participant.h @@ -13,10 +13,12 @@ struct Participant ssrc_t ssrc; IPAddress remoteIP; uint16_t remotePort; - + unsigned long receiverFeedbackStartTime; bool doReceiverFeedback = false; - uint16_t sequenceNr; + + uint16_t sendSequenceNr = random(1, UINT16_MAX); // http://www.rfc-editor.org/rfc/rfc6295.txt , 2.1. RTP Header + uint16_t receiveSequenceNr; unsigned long lastSyncExchangeTime; #ifdef APPLEMIDI_INITIATOR From 1db81addc83c44f995a02decb85f835348fde074 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Mon, 21 Dec 2020 22:42:33 +0100 Subject: [PATCH 060/271] removed error callback, replace with Exception --- examples/ESP32_Callbacks/ESP32_Callbacks.ino | 24 ++++++++++++---- .../wESP32_NoteOnOffEverySec.ino | 3 -- keywords.txt | 1 - src/AppleMIDI.h | 7 ++--- src/AppleMIDI.hpp | 28 +++++++++---------- src/AppleMIDI_Defs.h | 1 - 6 files changed, 34 insertions(+), 30 deletions(-) diff --git a/examples/ESP32_Callbacks/ESP32_Callbacks.ino b/examples/ESP32_Callbacks/ESP32_Callbacks.ino index 5568e5c..30718da 100644 --- a/examples/ESP32_Callbacks/ESP32_Callbacks.ino +++ b/examples/ESP32_Callbacks/ESP32_Callbacks.ino @@ -26,9 +26,15 @@ void setup() { DBG(F("Select and then press the Connect button")); DBG(F("Then open a MIDI listener and monitor incoming notes")); - AppleMIDI.setHandleConnected(OnAppleMidiConnected); - AppleMIDI.setHandleDisconnected(OnAppleMidiDisconnected); - AppleMIDI.setHandleError(OnAppleMidiError); + AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { + isConnected = true; + DBG(F("Connected to session"), name); + }); + AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { + isConnected = false; + DBG(F("Disconnected")); + }); + AppleMIDI.setHandleException(OnAppleMidiException); MIDI.begin(); @@ -77,8 +83,8 @@ DBG(F("Disconnected")); // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- -void OnAppleMidiError(const APPLEMIDI_NAMESPACE::ssrc_t& ssrc, int32_t err) { - switch (err) +void OnAppleMidiException(const APPLEMIDI_NAMESPACE::ssrc_t& ssrc, const APPLEMIDI_NAMESPACE::Exception& e, const int32_t value ) { + switch (e) { case APPLEMIDI_NAMESPACE::Exception::BufferFullException: DBG(F("*** BufferFullException")); @@ -93,7 +99,7 @@ void OnAppleMidiError(const APPLEMIDI_NAMESPACE::ssrc_t& ssrc, int32_t err) { DBG(F("*** UnexpectedInviteException")); break; case APPLEMIDI_NAMESPACE::Exception::ParticipantNotFoundException: - DBG(F("*** ParticipantNotFoundException")); + DBG(F("*** ParticipantNotFoundException"), value); break; case APPLEMIDI_NAMESPACE::Exception::ListenerTimeOutException: DBG(F("*** ListenerTimeOutException")); @@ -104,6 +110,12 @@ void OnAppleMidiError(const APPLEMIDI_NAMESPACE::ssrc_t& ssrc, int32_t err) { case APPLEMIDI_NAMESPACE::Exception::NoResponseFromConnectionRequestException: DBG(F("***:yyy did't respond to the connection request. Check the address and port, and any firewall or router settings. (time)")); break; + case APPLEMIDI_NAMESPACE::Exception::SendPacketsDropped: + DBG(F("*** SendPacketsDropped"), value); + break; + case APPLEMIDI_NAMESPACE::Exception::ReceivedPacketsDropped: + DBG(F("*** ReceivedPacketsDropped"), value); + break; } } diff --git a/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino b/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino index 11d793a..fc2b413 100644 --- a/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino +++ b/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino @@ -38,9 +38,6 @@ void setup() isConnected = false; DBG(F("Disconnected")); }); - AppleMIDI.setHandleError([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, int32_t e) { - DBG(F("______________Error"), e); - }); AppleMIDI.setHandleException([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const APPLEMIDI_NAMESPACE::Exception & e, const int32_t value) { DBG(F("______________Exception"), e, value); }); diff --git a/keywords.txt b/keywords.txt index f8577b8..aa7c88f 100644 --- a/keywords.txt +++ b/keywords.txt @@ -13,7 +13,6 @@ AppleMidi KEYWORD1 setHandleConnected KEYWORD2 setHandleDisconnected KEYWORD2 -setHandleError KEYWORD2 setHandleException KEYWORD2 setHandleStartReceivedMidi KEYWORD2 setHandleReceivedMidi KEYWORD2 diff --git a/src/AppleMIDI.h b/src/AppleMIDI.h index 6876d50..a6078f8 100644 --- a/src/AppleMIDI.h +++ b/src/AppleMIDI.h @@ -55,7 +55,6 @@ 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)) __attribute__ ((deprecated)) { _errorCallback = fptr; } // deprecated void setHandleException(void (*fptr)(const ssrc_t&, const Exception&, const int32_t value)) { _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; } @@ -151,8 +150,8 @@ class AppleMIDISession } else { - if (NULL != _errorCallback) - _errorCallback(ssrc, BufferFullException); + if (NULL != _exceptionCallback) + _exceptionCallback(ssrc, BufferFullException, 0); } } @@ -210,7 +209,6 @@ class AppleMIDISession UdpClass dataPort; private: - // reading from the network RtpBuffer_t controlBuffer; RtpBuffer_t dataBuffer; @@ -225,7 +223,6 @@ class AppleMIDISession endReceivedMidiByteCallback _endReceivedMidiByteCallback = nullptr; receivedRtpCallback _receivedRtpCallback = nullptr; disconnectedCallback _disconnectedCallback = nullptr; - errorCallback _errorCallback = nullptr; exceptionCallback _exceptionCallback = nullptr; // buffer for incoming and outgoing MIDI messages diff --git a/src/AppleMIDI.hpp b/src/AppleMIDI.hpp index 0a07a53..297eaf7 100644 --- a/src/AppleMIDI.hpp +++ b/src/AppleMIDI.hpp @@ -30,8 +30,8 @@ void AppleMIDISession::parseControlPackets() auto retVal = _appleMIDIParser.parse(controlBuffer, amPortType::Control); if (retVal == parserReturn::UnexpectedData) { - if (NULL != _errorCallback) - _errorCallback(ssrc, ParseException); + if (NULL != _exceptionCallback) + _exceptionCallback(ssrc, ParseException, 0); controlBuffer.pop_front(); } @@ -81,8 +81,8 @@ void AppleMIDISession::parseDataPackets() || retVal2 == parserReturn::NotSureGiveMeMoreData) break; // one or the other buffer does not have enough data - if (NULL != _errorCallback) - _errorCallback(ssrc, UnexpectedParseException); + if (NULL != _exceptionCallback) + _exceptionCallback(ssrc, UnexpectedParseException, 0); dataBuffer.pop_front(); } @@ -114,8 +114,8 @@ void AppleMIDISession::ReceivedControlInvitation(A { writeInvitation(controlPort, controlPort.remoteIP(), controlPort.remotePort(), invitation, amInvitationRejected); - if (NULL != _errorCallback) - _errorCallback(ssrc, TooManyParticipantsException); + if (NULL != _exceptionCallback) + _exceptionCallback(ssrc, TooManyParticipantsException, 0); return; } @@ -143,8 +143,8 @@ void AppleMIDISession::ReceivedDataInvitation(Appl { writeInvitation(dataPort, dataPort.remoteIP(), dataPort.remotePort(), invitation, amInvitationRejected); - if (NULL != _errorCallback) - _errorCallback(ssrc, ParticipantNotFoundException); + if (NULL != _exceptionCallback) + _exceptionCallback(ssrc, ParticipantNotFoundException, invitation.ssrc); return; } @@ -601,8 +601,8 @@ void AppleMIDISession::manageSynchronizationListen // otherwise the responder may assume that the initiator has died and terminate the session. if (now - participant->lastSyncExchangeTime > Settings::CK_MaxTimeOut) { - if (NULL != _errorCallback) - _errorCallback(ssrc, ListenerTimeOutException); + if (NULL != _exceptionCallback) + _exceptionCallback(ssrc, ListenerTimeOutException, 0); sendEndSession(participant); @@ -667,8 +667,8 @@ void AppleMIDISession::manageSynchronizationInitia { if (participant->synchronizationCount > DefaultSettings::MaxSynchronizationCK0Attempts) { - if (NULL != _errorCallback) - _errorCallback(ssrc, MaxAttemptsException); + if (NULL != _exceptionCallback) + _exceptionCallback(ssrc, MaxAttemptsException, 0); // After too many attempts, stop. sendEndSession(participant); @@ -726,8 +726,8 @@ void AppleMIDISession::manageSessionInvites() { if (participant->connectionAttempts >= DefaultSettings::MaxSessionInvitesAttempts) { - if (NULL != _errorCallback) - _errorCallback(ssrc, NoResponseFromConnectionRequestException); + if (NULL != _exceptionCallback) + _exceptionCallback(ssrc, NoResponseFromConnectionRequestException, 0); // After too many attempts, stop. sendEndSession(participant); diff --git a/src/AppleMIDI_Defs.h b/src/AppleMIDI_Defs.h index 7ae69f2..18a5dd7 100644 --- a/src/AppleMIDI_Defs.h +++ b/src/AppleMIDI_Defs.h @@ -108,7 +108,6 @@ 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&, const Exception&, const int32_t value); /* Signature "Magic Value" for Apple network MIDI session establishment */ From 4e5cba45f16704e3d19cf9cb01d36622c4f9dc5b Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Mon, 21 Dec 2020 23:20:05 +0100 Subject: [PATCH 061/271] NULL => nullptr --- src/AppleMIDI.h | 2 +- src/AppleMIDI.hpp | 56 +++++++++++++++++++++++------------------------ test/Arduino.h | 4 ++-- 3 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/AppleMIDI.h b/src/AppleMIDI.h index a6078f8..2c18d75 100644 --- a/src/AppleMIDI.h +++ b/src/AppleMIDI.h @@ -150,7 +150,7 @@ class AppleMIDISession } else { - if (NULL != _exceptionCallback) + if (nullptr != _exceptionCallback) _exceptionCallback(ssrc, BufferFullException, 0); } } diff --git a/src/AppleMIDI.hpp b/src/AppleMIDI.hpp index 297eaf7..65d09af 100644 --- a/src/AppleMIDI.hpp +++ b/src/AppleMIDI.hpp @@ -30,7 +30,7 @@ void AppleMIDISession::parseControlPackets() auto retVal = _appleMIDIParser.parse(controlBuffer, amPortType::Control); if (retVal == parserReturn::UnexpectedData) { - if (NULL != _exceptionCallback) + if (nullptr != _exceptionCallback) _exceptionCallback(ssrc, ParseException, 0); controlBuffer.pop_front(); @@ -81,7 +81,7 @@ void AppleMIDISession::parseDataPackets() || retVal2 == parserReturn::NotSureGiveMeMoreData) break; // one or the other buffer does not have enough data - if (NULL != _exceptionCallback) + if (nullptr != _exceptionCallback) _exceptionCallback(ssrc, UnexpectedParseException, 0); dataBuffer.pop_front(); @@ -101,7 +101,7 @@ template void AppleMIDISession::ReceivedControlInvitation(AppleMIDI_Invitation_t &invitation) { // ignore invitation of a participant already in the participant list - if (NULL != getParticipantBySSRC(invitation.ssrc)) + if (nullptr != getParticipantBySSRC(invitation.ssrc)) return; // advertise our own session name @@ -114,7 +114,7 @@ void AppleMIDISession::ReceivedControlInvitation(A { writeInvitation(controlPort, controlPort.remoteIP(), controlPort.remotePort(), invitation, amInvitationRejected); - if (NULL != _exceptionCallback) + if (nullptr != _exceptionCallback) _exceptionCallback(ssrc, TooManyParticipantsException, 0); return; @@ -139,11 +139,11 @@ template void AppleMIDISession::ReceivedDataInvitation(AppleMIDI_Invitation &invitation) { auto participant = getParticipantBySSRC(invitation.ssrc); - if (NULL == participant) + if (nullptr == participant) { writeInvitation(dataPort, dataPort.remoteIP(), dataPort.remotePort(), invitation, amInvitationRejected); - if (NULL != _exceptionCallback) + if (nullptr != _exceptionCallback) _exceptionCallback(ssrc, ParticipantNotFoundException, invitation.ssrc); return; @@ -159,11 +159,11 @@ void AppleMIDISession::ReceivedDataInvitation(Appl participant->kind = Listener; // Inform that we have an established connection - if (NULL != _connectedCallback) + if (nullptr != _connectedCallback) #ifdef KEEP_SESSION_NAME _connectedCallback(ssrc_, invitation.sessionName); #else - _connectedCallback(ssrc_, NULL); + _connectedCallback(ssrc_, nullptr); #endif } @@ -185,7 +185,7 @@ template void AppleMIDISession::ReceivedControlInvitationAccepted(AppleMIDI_InvitationAccepted_t &invitationAccepted) { auto participant = this->getParticipantByInitiatorToken(invitationAccepted.initiatorToken); - if (NULL == participant) + if (nullptr == participant) { return; } @@ -204,7 +204,7 @@ template void AppleMIDISession::ReceivedDataInvitationAccepted(AppleMIDI_InvitationAccepted_t &invitationAccepted) { auto participant = this->getParticipantByInitiatorToken(invitationAccepted.initiatorToken); - if (NULL == participant) + if (nullptr == participant) { return; } @@ -257,7 +257,7 @@ template void AppleMIDISession::ReceivedSynchronization(AppleMIDI_Synchronization_t &synchronization) { auto participant = getParticipantBySSRC(synchronization.ssrc); - if (NULL == participant) + if (nullptr == participant) { return; } @@ -348,12 +348,12 @@ void AppleMIDISession::ReceivedReceiverFeedback(Ap // Here is where you would correct if packets are dropped (send them again) auto participant = getParticipantBySSRC(receiverFeedback.ssrc); - if (NULL != participant) { + if (nullptr != participant) { if (participant->sendSequenceNr != receiverFeedback.sequenceNr) { Serial.print("ERRORRORORORORORORRROROROROROROR"); - if (NULL != _exceptionCallback) + if (nullptr != _exceptionCallback) _exceptionCallback(ssrc, SendPacketsDropped, participant->sendSequenceNr - receiverFeedback.sequenceNr); Serial.print(participant->sendSequenceNr); @@ -374,7 +374,7 @@ void AppleMIDISession::ReceivedEndSession(AppleMID participants.erase(i); - if (NULL != _disconnectedCallback) + if (nullptr != _disconnectedCallback) _disconnectedCallback(ssrc); return; @@ -388,7 +388,7 @@ Participant* AppleMIDISession::getPartic for (size_t i = 0; i < participants.size(); i++) if (ssrc == participants[i].ssrc) return &participants[i]; - return NULL; + return nullptr; } template @@ -397,7 +397,7 @@ Participant* AppleMIDISession::getPartic for (auto i = 0; i < participants.size(); i++) if (initiatorToken == participants[i].initiatorToken) return &participants[i]; - return NULL; + return nullptr; } template @@ -601,7 +601,7 @@ void AppleMIDISession::manageSynchronizationListen // otherwise the responder may assume that the initiator has died and terminate the session. if (now - participant->lastSyncExchangeTime > Settings::CK_MaxTimeOut) { - if (NULL != _exceptionCallback) + if (nullptr != _exceptionCallback) _exceptionCallback(ssrc, ListenerTimeOutException, 0); sendEndSession(participant); @@ -667,7 +667,7 @@ void AppleMIDISession::manageSynchronizationInitia { if (participant->synchronizationCount > DefaultSettings::MaxSynchronizationCK0Attempts) { - if (NULL != _exceptionCallback) + if (nullptr != _exceptionCallback) _exceptionCallback(ssrc, MaxAttemptsException, 0); // After too many attempts, stop. @@ -709,11 +709,11 @@ void AppleMIDISession::manageSessionInvites() if (participant->invitationStatus == DataInvitationAccepted) { // Inform that we have an established connection - if (NULL != _connectedCallback) + if (nullptr != _connectedCallback) #ifdef KEEP_SESSION_NAME _connectedCallback(participant->ssrc, participant->sessionName); #else - _connectedCallback(participant->ssrc, NULL); + _connectedCallback(participant->ssrc, nullptr); #endif participant->invitationStatus = Connected; } @@ -726,7 +726,7 @@ void AppleMIDISession::manageSessionInvites() { if (participant->connectionAttempts >= DefaultSettings::MaxSessionInvitesAttempts) { - if (NULL != _exceptionCallback) + if (nullptr != _exceptionCallback) _exceptionCallback(ssrc, NoResponseFromConnectionRequestException, 0); // After too many attempts, stop. @@ -840,7 +840,7 @@ void AppleMIDISession::sendEndSession(Participant< endSession.ssrc = this->ssrc; writeEndSession(participant->remoteIP, participant->remotePort, endSession); - if (NULL != _disconnectedCallback) + if (nullptr != _disconnectedCallback) _disconnectedCallback(participant->ssrc); } @@ -849,7 +849,7 @@ void AppleMIDISession::ReceivedRtp(const Rtp_t& rt { auto participant = getParticipantBySSRC(rtp.ssrc); - if (NULL != participant) + if (nullptr != participant) { if (participant->doReceiverFeedback == false) participant->receiverFeedbackStartTime = now; @@ -864,7 +864,7 @@ void AppleMIDISession::ReceivedRtp(const Rtp_t& rt if (participant->receiveSequenceNr + 1 != rtp.sequenceNr) { - if (NULL != _exceptionCallback) + if (nullptr != _exceptionCallback) _exceptionCallback(ssrc, ReceivedPacketsDropped, participant->receiveSequenceNr + 1 - rtp.sequenceNr); Serial.print("___ERROR____"); @@ -875,7 +875,7 @@ void AppleMIDISession::ReceivedRtp(const Rtp_t& rt participant->receiveSequenceNr = rtp.sequenceNr; - if (NULL != _receivedRtpCallback) + if (nullptr != _receivedRtpCallback) _receivedRtpCallback(0, rtp, latency); } else @@ -887,14 +887,14 @@ void AppleMIDISession::ReceivedRtp(const Rtp_t& rt template void AppleMIDISession::StartReceivedMidi() { - if (NULL != _startReceivedMidiByteCallback) + if (nullptr != _startReceivedMidiByteCallback) _startReceivedMidiByteCallback(0); } template void AppleMIDISession::ReceivedMidi(byte value) { - if (NULL != _receivedMidiByteCallback) + if (nullptr != _receivedMidiByteCallback) _receivedMidiByteCallback(0, value); inMidiBuffer.push_back(value); @@ -903,7 +903,7 @@ void AppleMIDISession::ReceivedMidi(byte value) template void AppleMIDISession::EndReceivedMidi() { - if (NULL != _endReceivedMidiByteCallback) + if (nullptr != _endReceivedMidiByteCallback) _endReceivedMidiByteCallback(0); } diff --git a/test/Arduino.h b/test/Arduino.h index afb5e0d..ccacad5 100644 --- a/test/Arduino.h +++ b/test/Arduino.h @@ -19,7 +19,7 @@ class _serial void print(long a, int format = DEC) { std::cout << (format == DEC ? std::dec : std::hex) << a; }; void print(unsigned long a, int format = DEC) { std::cout << (format == DEC ? std::dec : std::hex) << a; }; void print(double a, int = 2) { std::cout << a; }; - void print(struct tm * timeinfo, const char * format = NULL) {}; + void print(struct tm * timeinfo, const char * format = nullptr) {}; void print(IPAddress) {}; void println(const char a[]) { std::cout << a << "\n"; }; @@ -30,7 +30,7 @@ class _serial void println(long a, int format = DEC) { std::cout << (format == DEC ? std::dec : std::hex) << a << "\n"; }; void println(unsigned long a, int format = DEC) { std::cout << (format == DEC ? std::dec : std::hex) << a << "\n"; }; void println(double a, int format = 2) { std::cout << a << "\n"; }; - void println(struct tm * timeinfo, const char * format = NULL) {}; + void println(struct tm * timeinfo, const char * format = nullptr) {}; void println(IPAddress) {}; void println(void) { std::cout << "\n"; }; }; From a7917d163e262a2b9672df8bdb55489f5da33938 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Mon, 21 Dec 2020 23:20:18 +0100 Subject: [PATCH 062/271] Update library.properties prep v3 --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index add0477..dc7f7f3 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=AppleMIDI -version=2.2.0 +version=3.0.0 author=lathoub maintainer=lathoub sentence=AppleMIDI (aka rtpMIDI) MIDI I/Os for Arduino From 80624d7c98b45eb7a6b55c11181762d8bffdfedd Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Mon, 21 Dec 2020 23:27:03 +0100 Subject: [PATCH 063/271] Update ESP32_Callbacks.ino cleanup --- examples/ESP32_Callbacks/ESP32_Callbacks.ino | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/examples/ESP32_Callbacks/ESP32_Callbacks.ino b/examples/ESP32_Callbacks/ESP32_Callbacks.ino index 30718da..241f388 100644 --- a/examples/ESP32_Callbacks/ESP32_Callbacks.ino +++ b/examples/ESP32_Callbacks/ESP32_Callbacks.ino @@ -64,22 +64,6 @@ void loop() { MIDI.read(); } -// ----------------------------------------------------------------------------- -// -// ----------------------------------------------------------------------------- -void OnAppleMidiConnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { - isConnected = true; - DBG(F("Connected to session"), name); -} - -// ----------------------------------------------------------------------------- -// -// ----------------------------------------------------------------------------- -void OnAppleMidiDisconnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { - isConnected = false; -DBG(F("Disconnected")); -} - // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- From 38a07cb0fadfd16caed9441ab03b28a90cd8c48a Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Tue, 22 Dec 2020 00:29:21 +0100 Subject: [PATCH 064/271] advance callbacks, added sendRtp --- examples/ESP32_Callbacks/ESP32_Callbacks.ino | 24 +++++++++++++++++++- keywords.txt | 1 + src/AppleMIDI.h | 4 +++- src/AppleMIDI.hpp | 11 ++++++--- src/AppleMIDI_Defs.h | 3 ++- 5 files changed, 37 insertions(+), 6 deletions(-) diff --git a/examples/ESP32_Callbacks/ESP32_Callbacks.ino b/examples/ESP32_Callbacks/ESP32_Callbacks.ino index 241f388..a0b6e25 100644 --- a/examples/ESP32_Callbacks/ESP32_Callbacks.ino +++ b/examples/ESP32_Callbacks/ESP32_Callbacks.ino @@ -1,4 +1,5 @@ #include +#include #define SerialMon Serial #define APPLEMIDI_DEBUG SerialMon @@ -21,6 +22,8 @@ void setup() { } DBG("Connected to network"); + MDNS.begin(AppleMIDI.getName()); + DBG(F("OK, now make sure you an rtpMIDI session that is Enabled")); DBG(F("Add device named Arduino with Host"), WiFi.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); DBG(F("Select and then press the Connect button")); @@ -34,6 +37,23 @@ void setup() { isConnected = false; DBG(F("Disconnected")); }); + + AppleMIDI.setHandleSendRtp([](const APPLEMIDI_NAMESPACE::Rtp_t& rtp) { + DBG(F("setHandleSendRtp"), rtp.sequenceNr); + }); + AppleMIDI.setHandleReceivedRtp([](const APPLEMIDI_NAMESPACE::Rtp_t& rtp, const int32_t& latency) { + DBG(F("setHandleReceivedRtp"), rtp.sequenceNr ,latency); + }); + AppleMIDI.setHandleStartReceivedMidi([](const APPLEMIDI_NAMESPACE::ssrc_t&) { + DBG(F("setHandleStartReceivedMidi")); + }); + AppleMIDI.setHandleReceivedMidi([](const APPLEMIDI_NAMESPACE::ssrc_t&, byte value) { + DBG(F("setHandleReceivedMidi"), value); + }); + AppleMIDI.setHandleEndReceivedMidi([](const APPLEMIDI_NAMESPACE::ssrc_t&) { + DBG(F("setHandleEndReceivedMidi")); + }); + AppleMIDI.setHandleException(OnAppleMidiException); MIDI.begin(); @@ -57,6 +77,8 @@ void setup() { MIDI.setHandleActiveSensing(OnActiveSensing); MIDI.setHandleSystemReset(OnSystemReset); + MDNS.addService("apple-midi", "udp", AppleMIDI.getPort()); + DBG(F("Ready")); } @@ -151,7 +173,7 @@ static void OnSongPosition(unsigned beats) { } static void OnSongSelect(byte songNumber) { - DBG(F("SongSelect"),songNumber); + DBG(F("SongSelect"), songNumber); } static void OnTuneRequest() { diff --git a/keywords.txt b/keywords.txt index aa7c88f..f25cf1d 100644 --- a/keywords.txt +++ b/keywords.txt @@ -18,6 +18,7 @@ setHandleStartReceivedMidi KEYWORD2 setHandleReceivedMidi KEYWORD2 setHandleEndReceivedMidi KEYWORD2 setHandleReceivedRtp KEYWORD2 +setHandleSendRtp KEYWORD2 ####################################### # Instances (KEYWORD3) diff --git a/src/AppleMIDI.h b/src/AppleMIDI.h index 2c18d75..0fee8f4 100644 --- a/src/AppleMIDI.h +++ b/src/AppleMIDI.h @@ -56,10 +56,11 @@ class AppleMIDISession void setHandleConnected(void (*fptr)(const ssrc_t&, const char*)) { _connectedCallback = fptr; } void setHandleDisconnected(void (*fptr)(const ssrc_t&)) { _disconnectedCallback = fptr; } void setHandleException(void (*fptr)(const ssrc_t&, const Exception&, const int32_t value)) { _exceptionCallback = fptr; } - void setHandleReceivedRtp(void (*fptr)(const ssrc_t&, const Rtp_t&, const int32_t&)) { _receivedRtpCallback = fptr; } + void setHandleReceivedRtp(void (*fptr)(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; } void setHandleEndReceivedMidi(void (*fptr)(const ssrc_t&)) { _endReceivedMidiByteCallback = fptr; } + void setHandleSendRtp(void (*fptr)(const Rtp_t&)) { _sendRtpCallback = fptr; } const char* getName() { return this->localName; }; const uint16_t getPort() { return this->port; }; @@ -224,6 +225,7 @@ class AppleMIDISession receivedRtpCallback _receivedRtpCallback = nullptr; disconnectedCallback _disconnectedCallback = nullptr; exceptionCallback _exceptionCallback = nullptr; + sendRtpCallback _sendRtpCallback = nullptr; // buffer for incoming and outgoing MIDI messages MidiBuffer_t inMidiBuffer; diff --git a/src/AppleMIDI.hpp b/src/AppleMIDI.hpp index 65d09af..64ac286 100644 --- a/src/AppleMIDI.hpp +++ b/src/AppleMIDI.hpp @@ -501,7 +501,6 @@ void AppleMIDISession::writeRtpMidiBuffer(Particip rtp.vpxcc = 0b10000000; // TODO: fun with flags rtp.mpayload = PAYLOADTYPE_RTPMIDI; // TODO: set or unset marker rtp.ssrc = ssrc; - rtp.ssrc = htonl(rtp.ssrc); // https://developer.apple.com/library/ios/documentation/CoreMidi/Reference/MIDIServices_Reference/#//apple_ref/doc/uid/TP40010316-CHMIDIServiceshFunctions-SW30 // The time at which the events occurred, if receiving MIDI, or, if sending MIDI, @@ -519,10 +518,15 @@ void AppleMIDISession::writeRtpMidiBuffer(Particip // rtp.timestamp = (Settings::TimestampRtpPackets) ? htonl(rtpMidiClock.Now()) : 0; - // increament the sequenceNr + // increment the sequenceNr participant->sendSequenceNr++; rtp.sequenceNr = participant->sendSequenceNr; + + if (_sendRtpCallback) + _sendRtpCallback(rtp); + + rtp.ssrc = htonl(rtp.ssrc); rtp.sequenceNr = htons(rtp.sequenceNr); dataPort.write((uint8_t *)&rtp, sizeof(rtp)); @@ -560,6 +564,7 @@ void AppleMIDISession::writeRtpMidiBuffer(Particip dataPort.endPacket(); dataPort.flush(); + } // @@ -876,7 +881,7 @@ void AppleMIDISession::ReceivedRtp(const Rtp_t& rt participant->receiveSequenceNr = rtp.sequenceNr; if (nullptr != _receivedRtpCallback) - _receivedRtpCallback(0, rtp, latency); + _receivedRtpCallback(rtp, latency); } else { diff --git a/src/AppleMIDI_Defs.h b/src/AppleMIDI_Defs.h index 18a5dd7..db4a749 100644 --- a/src/AppleMIDI_Defs.h +++ b/src/AppleMIDI_Defs.h @@ -106,9 +106,10 @@ using connectedCallback = void (*)(const ssrc_t&, const char *); using startReceivedMidiByteCallback = void (*)(const ssrc_t&); 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 receivedRtpCallback = void (*)(const Rtp_t&, const int32_t&); using disconnectedCallback = void (*)(const ssrc_t&); using exceptionCallback = void (*)(const ssrc_t&, const Exception&, const int32_t value); +using sendRtpCallback = void (*)(const Rtp_t&); /* Signature "Magic Value" for Apple network MIDI session establishment */ const byte amSignature[] = {0xff, 0xff}; From 4120625540af35caf74745e2bc8fcd268fed0b5a Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Tue, 22 Dec 2020 11:21:36 +0100 Subject: [PATCH 065/271] extented callbacks now optional to save weight --- .../EthernetShield_Callbacks.ino | 82 ++++++++++++++++++ src/AppleMIDI.h | 17 ++-- src/AppleMIDI.hpp | 83 ++++++++++--------- src/AppleMIDI_Defs.h | 19 +++-- src/AppleMIDI_Parser.h | 9 +- 5 files changed, 155 insertions(+), 55 deletions(-) create mode 100644 examples/EthernetShield_Callbacks/EthernetShield_Callbacks.ino diff --git a/examples/EthernetShield_Callbacks/EthernetShield_Callbacks.ino b/examples/EthernetShield_Callbacks/EthernetShield_Callbacks.ino new file mode 100644 index 0000000..e32e513 --- /dev/null +++ b/examples/EthernetShield_Callbacks/EthernetShield_Callbacks.ino @@ -0,0 +1,82 @@ +#include + +#define DISCARD_SESSION_NAME +#define NO_LATENCY_CALCULATION +#define NO_EXT_CALLBACKS +#define SerialMon Serial +#define APPLEMIDI_DEBUG SerialMon +#include + +// Enter a MAC address for your controller below. +// Newer Ethernet shields have a MAC address printed on a sticker on the shield +byte mac[] = { + 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED +}; + +unsigned long t1 = millis(); +bool isConnected = false; + +APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +void setup() +{ + DBG_SETUP(115200); + DBG("Booting"); + + if (Ethernet.begin(mac) == 0) { + DBG(F("Failed DHCP, check network cable & reboot")); + for (;;); + } + + DBG(F("OK, now make sure you an rtpMIDI session that is Enabled")); + DBG(F("Add device named Arduino with Host"), Ethernet.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); + DBG(F("Select and then press the Connect button")); + DBG(F("Then open a MIDI listener and monitor incoming notes")); + + MIDI.begin(); + + // Stay informed on connection status + AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { + isConnected = true; + DBG(F("Connected to session"), name); + }); + AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { + isConnected = false; + DBG(F("Disconnected")); + }); + + MIDI.setHandleNoteOn([](byte channel, byte note, byte velocity) { + DBG(F("NoteOn"), note); + }); + MIDI.setHandleNoteOff([](byte channel, byte note, byte velocity) { + DBG(F("NoteOff"), note); + }); + + DBG(F("Sending MIDI messages every second")); +} + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +void loop() +{ + // Listen to incoming notes + MIDI.read(); + + // send a note every second + // (dont cáll delay(1000) as it will stall the pipeline) + if (isConnected && (millis() - t1) > 1000) + { + t1 = millis(); + + byte note = random(1, 127); + byte velocity = 55; + byte channel = 1; + + MIDI.sendNoteOn(note, velocity, channel); +// MIDI.sendNoteOff(note, velocity, channel); + } +} diff --git a/src/AppleMIDI.h b/src/AppleMIDI.h index 0fee8f4..2d1a477 100644 --- a/src/AppleMIDI.h +++ b/src/AppleMIDI.h @@ -55,12 +55,14 @@ class AppleMIDISession void setHandleConnected(void (*fptr)(const ssrc_t&, const char*)) { _connectedCallback = fptr; } void setHandleDisconnected(void (*fptr)(const ssrc_t&)) { _disconnectedCallback = fptr; } - void setHandleException(void (*fptr)(const ssrc_t&, const Exception&, const int32_t value)) { _exceptionCallback = fptr; } +#ifdef USE_EXT_CALLBACKS + void setHandleException(void (*fptr)(const ssrc_t&, const Exception&, const int32_t value)) { _exceptionCallback = fptr; } void setHandleReceivedRtp(void (*fptr)(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; } void setHandleEndReceivedMidi(void (*fptr)(const ssrc_t&)) { _endReceivedMidiByteCallback = fptr; } void setHandleSendRtp(void (*fptr)(const Rtp_t&)) { _sendRtpCallback = fptr; } +#endif const char* getName() { return this->localName; }; const uint16_t getPort() { return this->port; }; @@ -74,6 +76,7 @@ class AppleMIDISession void sendEndSession(); public: + // Override default thruActivated static const bool thruActivated = false; void begin() @@ -91,7 +94,6 @@ class AppleMIDISession // this is our SSRC // // NOTE: Arduino random only goes to INT32_MAX (not UINT32_MAX) - this->ssrc = random(1, INT32_MAX) * 2; controlPort.begin(port); @@ -151,8 +153,10 @@ class AppleMIDISession } else { +#ifdef USE_EXT_CALLBACKS if (nullptr != _exceptionCallback) _exceptionCallback(ssrc, BufferFullException, 0); +#endif } } @@ -219,14 +223,15 @@ class AppleMIDISession rtpMIDIParser _rtpMIDIParser; connectedCallback _connectedCallback = nullptr; + disconnectedCallback _disconnectedCallback = nullptr; +#ifdef USE_EXT_CALLBACKS startReceivedMidiByteCallback _startReceivedMidiByteCallback = nullptr; receivedMidiByteCallback _receivedMidiByteCallback = nullptr; endReceivedMidiByteCallback _endReceivedMidiByteCallback = nullptr; receivedRtpCallback _receivedRtpCallback = nullptr; - disconnectedCallback _disconnectedCallback = nullptr; - exceptionCallback _exceptionCallback = nullptr; sendRtpCallback _sendRtpCallback = nullptr; - + exceptionCallback _exceptionCallback = nullptr; +#endif // buffer for incoming and outgoing MIDI messages MidiBuffer_t inMidiBuffer; MidiBuffer_t outMidiBuffer; @@ -237,7 +242,7 @@ class AppleMIDISession char localName[DefaultSettings::MaxSessionNameLen + 1]; uint16_t port = DEFAULT_CONTROL_PORT; Deque, Settings::MaxNumberOfParticipants> participants; - int32_t latencyAdjustment = 0; +// int32_t latencyAdjustment = 0; // not used private: void readControlPackets(); diff --git a/src/AppleMIDI.hpp b/src/AppleMIDI.hpp index 64ac286..a172dca 100644 --- a/src/AppleMIDI.hpp +++ b/src/AppleMIDI.hpp @@ -30,9 +30,10 @@ void AppleMIDISession::parseControlPackets() auto retVal = _appleMIDIParser.parse(controlBuffer, amPortType::Control); if (retVal == parserReturn::UnexpectedData) { +#ifdef USE_EXT_CALLBACKS if (nullptr != _exceptionCallback) _exceptionCallback(ssrc, ParseException, 0); - +#endif controlBuffer.pop_front(); } } @@ -81,9 +82,10 @@ void AppleMIDISession::parseDataPackets() || retVal2 == parserReturn::NotSureGiveMeMoreData) break; // one or the other buffer does not have enough data +#ifdef USE_EXT_CALLBACKS if (nullptr != _exceptionCallback) _exceptionCallback(ssrc, UnexpectedParseException, 0); - +#endif dataBuffer.pop_front(); } } @@ -114,9 +116,10 @@ void AppleMIDISession::ReceivedControlInvitation(A { writeInvitation(controlPort, controlPort.remoteIP(), controlPort.remotePort(), invitation, amInvitationRejected); +#ifdef USE_EXT_CALLBACKS if (nullptr != _exceptionCallback) _exceptionCallback(ssrc, TooManyParticipantsException, 0); - +#endif return; } @@ -143,9 +146,10 @@ void AppleMIDISession::ReceivedDataInvitation(Appl { writeInvitation(dataPort, dataPort.remoteIP(), dataPort.remotePort(), invitation, amInvitationRejected); +#ifdef USE_EXT_CALLBACKS if (nullptr != _exceptionCallback) _exceptionCallback(ssrc, ParticipantNotFoundException, invitation.ssrc); - +#endif return; } @@ -259,6 +263,11 @@ void AppleMIDISession::ReceivedSynchronization(App auto participant = getParticipantBySSRC(synchronization.ssrc); if (nullptr == participant) { +#ifdef USE_EXT_CALLBACKS + if (nullptr != _exceptionCallback) + _exceptionCallback(ssrc, ParticipantNotFoundException, synchronization.ssrc); +#endif + return; } @@ -313,19 +322,6 @@ void AppleMIDISession::ReceivedSynchronization(App #ifdef LATENCY_CALCULATION // each party can estimate the offset between the two clocks using the following formula participant->offsetEstimate = (uint32_t)(((synchronization.timestamps[2] + synchronization.timestamps[0]) / 2) - synchronization.timestamps[1]); -/* - uint64_t remoteAverage = ((synchronization.timestamps[2] + synchronization.timestamps[0]) / 2); - uint64_t localAverage = synchronization.timestamps[1]; - - static uint64_t oldRemoteAverage = 0; - static uint64_t oldLocalAverage = 0; - - uint64_t r = (remoteAverage - oldRemoteAverage); - uint64_t l = (localAverage - oldLocalAverage); - - oldRemoteAverage = remoteAverage; - oldLocalAverage = localAverage; -*/ #endif break; } @@ -348,18 +344,20 @@ void AppleMIDISession::ReceivedReceiverFeedback(Ap // Here is where you would correct if packets are dropped (send them again) auto participant = getParticipantBySSRC(receiverFeedback.ssrc); - if (nullptr != participant) { - if (participant->sendSequenceNr != receiverFeedback.sequenceNr) - { - Serial.print("ERRORRORORORORORORRROROROROROROR"); - - if (nullptr != _exceptionCallback) - _exceptionCallback(ssrc, SendPacketsDropped, participant->sendSequenceNr - receiverFeedback.sequenceNr); + if (nullptr == participant) { +#ifdef USE_EXT_CALLBACKS + if (nullptr != _exceptionCallback) + _exceptionCallback(ssrc, ParticipantNotFoundException, receiverFeedback.ssrc); +#endif + return; + } - Serial.print(participant->sendSequenceNr); - Serial.print(" "); - Serial.println(receiverFeedback.sequenceNr); - } + if (participant->sendSequenceNr != receiverFeedback.sequenceNr) + { +#ifdef USE_EXT_CALLBACKS + if (nullptr != _exceptionCallback) + _exceptionCallback(ssrc, SendPacketsDropped, participant->sendSequenceNr - receiverFeedback.sequenceNr); +#endif } } @@ -516,16 +514,19 @@ void AppleMIDISession::writeRtpMidiBuffer(Particip // have an option to not transmit messages with future timestamps, to accommodate hardware not // prepared to defer rendering the messages until the proper time.) // - rtp.timestamp = (Settings::TimestampRtpPackets) ? htonl(rtpMidiClock.Now()) : 0; + rtp.timestamp = (Settings::TimestampRtpPackets) ? rtpMidiClock.Now() : 0; // increment the sequenceNr participant->sendSequenceNr++; rtp.sequenceNr = participant->sendSequenceNr; +#ifdef USE_EXT_CALLBACKS if (_sendRtpCallback) _sendRtpCallback(rtp); +#endif + rtp.timestamp = htonl(rtp.timestamp); rtp.ssrc = htonl(rtp.ssrc); rtp.sequenceNr = htons(rtp.sequenceNr); @@ -606,9 +607,10 @@ void AppleMIDISession::manageSynchronizationListen // otherwise the responder may assume that the initiator has died and terminate the session. if (now - participant->lastSyncExchangeTime > Settings::CK_MaxTimeOut) { +#ifdef USE_EXT_CALLBACKS if (nullptr != _exceptionCallback) _exceptionCallback(ssrc, ListenerTimeOutException, 0); - +#endif sendEndSession(participant); participants.erase(i); @@ -672,9 +674,10 @@ void AppleMIDISession::manageSynchronizationInitia { if (participant->synchronizationCount > DefaultSettings::MaxSynchronizationCK0Attempts) { +#ifdef USE_EXT_CALLBACKS if (nullptr != _exceptionCallback) _exceptionCallback(ssrc, MaxAttemptsException, 0); - +#endif // After too many attempts, stop. sendEndSession(participant); @@ -731,9 +734,10 @@ void AppleMIDISession::manageSessionInvites() { if (participant->connectionAttempts >= DefaultSettings::MaxSessionInvitesAttempts) { +#ifdef USE_EXT_CALLBACKS if (nullptr != _exceptionCallback) _exceptionCallback(ssrc, NoResponseFromConnectionRequestException, 0); - +#endif // After too many attempts, stop. sendEndSession(participant); @@ -869,19 +873,18 @@ void AppleMIDISession::ReceivedRtp(const Rtp_t& rt if (participant->receiveSequenceNr + 1 != rtp.sequenceNr) { +#ifdef USE_EXT_CALLBACKS if (nullptr != _exceptionCallback) _exceptionCallback(ssrc, ReceivedPacketsDropped, participant->receiveSequenceNr + 1 - rtp.sequenceNr); - - Serial.print("___ERROR____"); - Serial.print(participant->receiveSequenceNr); - Serial.print(" "); - Serial.println(rtp.sequenceNr); +#endif } participant->receiveSequenceNr = rtp.sequenceNr; +#ifdef USE_EXT_CALLBACKS if (nullptr != _receivedRtpCallback) _receivedRtpCallback(rtp, latency); +#endif } else { @@ -892,15 +895,19 @@ void AppleMIDISession::ReceivedRtp(const Rtp_t& rt template void AppleMIDISession::StartReceivedMidi() { +#ifdef USE_EXT_CALLBACKS if (nullptr != _startReceivedMidiByteCallback) _startReceivedMidiByteCallback(0); +#endif } template void AppleMIDISession::ReceivedMidi(byte value) { +#ifdef USE_EXT_CALLBACKS if (nullptr != _receivedMidiByteCallback) _receivedMidiByteCallback(0, value); +#endif inMidiBuffer.push_back(value); } @@ -908,8 +915,10 @@ void AppleMIDISession::ReceivedMidi(byte value) template void AppleMIDISession::EndReceivedMidi() { +#ifdef USE_EXT_CALLBACKS if (nullptr != _endReceivedMidiByteCallback) _endReceivedMidiByteCallback(0); +#endif } END_APPLEMIDI_NAMESPACE diff --git a/src/AppleMIDI_Defs.h b/src/AppleMIDI_Defs.h index db4a749..ae88f68 100644 --- a/src/AppleMIDI_Defs.h +++ b/src/AppleMIDI_Defs.h @@ -5,9 +5,9 @@ BEGIN_APPLEMIDI_NAMESPACE -#define APPLEMIDI_LIBRARY_VERSION 0x020100 -#define APPLEMIDI_LIBRARY_VERSION_MAJOR 2 -#define APPLEMIDI_LIBRARY_VERSION_MINOR 2 +#define APPLEMIDI_LIBRARY_VERSION 0x030000 +#define APPLEMIDI_LIBRARY_VERSION_MAJOR 3 +#define APPLEMIDI_LIBRARY_VERSION_MINOR 0 #define APPLEMIDI_LIBRARY_VERSION_PATCH 0 #define DEFAULT_CONTROL_PORT 5004 @@ -40,9 +40,16 @@ typedef const char* AppleMIDIConstStr; #define RtpBuffer_t Deque #define MidiBuffer_t Deque -#define APPLEMIDI_LISTENER +// Way to reduce memory usage, by giving up functionality +#ifndef DISCARD_SESSION_NAME #define KEEP_SESSION_NAME +#endif +#ifndef NO_LATENCY_CALCULATION #define LATENCY_CALCULATION +#endif +#ifndef NO_EXT_CALLBACKS +#define USE_EXT_CALLBACKS +#endif #define MIDI_SAMPLING_RATE_176K4HZ 176400 #define MIDI_SAMPLING_RATE_192KHZ 192000 @@ -103,13 +110,15 @@ enum Exception : uint8_t }; using connectedCallback = void (*)(const ssrc_t&, const char *); +using disconnectedCallback = void (*)(const ssrc_t&); +#ifdef USE_EXT_CALLBACKS using startReceivedMidiByteCallback = void (*)(const ssrc_t&); using receivedMidiByteCallback = void (*)(const ssrc_t&, byte); using endReceivedMidiByteCallback = void (*)(const ssrc_t&); using receivedRtpCallback = void (*)(const Rtp_t&, const int32_t&); -using disconnectedCallback = void (*)(const ssrc_t&); using exceptionCallback = void (*)(const ssrc_t&, const Exception&, const int32_t value); using sendRtpCallback = void (*)(const Rtp_t&); +#endif /* Signature "Magic Value" for Apple network MIDI session establishment */ const byte amSignature[] = {0xff, 0xff}; diff --git a/src/AppleMIDI_Parser.h b/src/AppleMIDI_Parser.h index cf5e9b0..74fbe8d 100644 --- a/src/AppleMIDI_Parser.h +++ b/src/AppleMIDI_Parser.h @@ -40,11 +40,7 @@ class AppleMIDIParser command[0] = buffer[i++]; command[1] = buffer[i++]; - if (false) - { - } -#ifdef APPLEMIDI_LISTENER - else if (0 == memcmp(command, amInvitation, sizeof(amInvitation))) + if (0 == memcmp(command, amInvitation, sizeof(amInvitation))) { byte protocolVersion[4]; @@ -232,7 +228,6 @@ class AppleMIDIParser return parserReturn::Processed; } -#endif #ifdef APPLEMIDI_INITIATOR else if (0 == memcmp(command, amInvitationAccepted, sizeof(amInvitationAccepted))) { @@ -270,7 +265,7 @@ class AppleMIDIParser cb.buffer[3] = buffer[i++]; invitationAccepted.ssrc = ntohl(cb.value32); - #ifdef KEEP_SESSION_NAME +#ifdef KEEP_SESSION_NAME uint16_t bi = 0; while ((i < buffer.size()) && (buffer[i] != 0x00)) { From 7bf2d0dd0ac84dd8b630efbc2f6194ebfffcc2dd Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Tue, 22 Dec 2020 11:36:35 +0100 Subject: [PATCH 066/271] minimum memory usage example --- .../EthernetShield_Callbacks.ino | 2 +- .../EthernetShield_MinMemUsage.ino | 65 +++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 examples/EthernetShield_MinMemUsage/EthernetShield_MinMemUsage.ino diff --git a/examples/EthernetShield_Callbacks/EthernetShield_Callbacks.ino b/examples/EthernetShield_Callbacks/EthernetShield_Callbacks.ino index e32e513..1ee20ae 100644 --- a/examples/EthernetShield_Callbacks/EthernetShield_Callbacks.ino +++ b/examples/EthernetShield_Callbacks/EthernetShield_Callbacks.ino @@ -34,7 +34,7 @@ void setup() DBG(F("OK, now make sure you an rtpMIDI session that is Enabled")); DBG(F("Add device named Arduino with Host"), Ethernet.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); DBG(F("Select and then press the Connect button")); - DBG(F("Then open a MIDI listener and monitor incoming notes")); + DBG(F("Then open a MIDI listener and monitor incoming notes"));+- MIDI.begin(); diff --git a/examples/EthernetShield_MinMemUsage/EthernetShield_MinMemUsage.ino b/examples/EthernetShield_MinMemUsage/EthernetShield_MinMemUsage.ino new file mode 100644 index 0000000..c2d8db5 --- /dev/null +++ b/examples/EthernetShield_MinMemUsage/EthernetShield_MinMemUsage.ino @@ -0,0 +1,65 @@ +#include + +#define DISCARD_SESSION_NAME +#define NO_LATENCY_CALCULATION +#define NO_EXT_CALLBACKS +#include + +// Enter a MAC address for your controller below. +// Newer Ethernet shields have a MAC address printed on a sticker on the shield +byte mac[] = { + 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED +}; + +unsigned long t1 = millis(); +bool isConnected = false; + +APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +void setup() +{ + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, LOW); + + if (Ethernet.begin(mac) == 0) for (;;); + + MIDI.begin(); + + // Stay informed on connection status + AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char*) { + isConnected = true; + digitalWrite(LED_BUILTIN, HIGH); + }); + AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { + isConnected = false; + digitalWrite(LED_BUILTIN, LOW); + }); + + MIDI.setHandleNoteOn([](byte channel, byte note, byte velocity) { + digitalWrite(LED_BUILTIN, LOW); + }); + MIDI.setHandleNoteOff([](byte channel, byte note, byte velocity) { + digitalWrite(LED_BUILTIN, HIGH); + }); +} + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +void loop() +{ + // Listen to incoming notes + MIDI.read(); + + // send a note every second + // (dont cáll delay(1000) as it will stall the pipeline) + if (isConnected && (millis() - t1) > 1000) + { + t1 = millis(); + + MIDI.sendNoteOn(54, 100, 1); + } +} From 397eab2afb74b1b1e224b3188e43616cee07eb6a Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Tue, 22 Dec 2020 23:05:37 +0100 Subject: [PATCH 067/271] renamed EthernetShield to AVR for AVR type Arduino's --- examples/AVR_Callbacks/AVR_Callbacks.ino | 134 ++++++++++++++++++ .../AVR_Initiator.ino} | 0 .../AVR_MinMemUsage.ino} | 0 .../AVR_MultipleSessions.ino} | 0 .../AVR_NonDefaultSession.ino} | 0 .../AVR_NoteOnOffEverySec.ino} | 0 .../AVR_ReceivedRawMidiData.ino} | 0 .../AVR_SysEx.ino} | 0 .../EthernetShield_Callbacks.ino | 82 ----------- .../SAMD_Bonjour.ino} | 0 10 files changed, 134 insertions(+), 82 deletions(-) create mode 100644 examples/AVR_Callbacks/AVR_Callbacks.ino rename examples/{EthernetShield_Initiator/EthernetShield_Initiator.ino => AVR_Initiator/AVR_Initiator.ino} (100%) rename examples/{EthernetShield_MinMemUsage/EthernetShield_MinMemUsage.ino => AVR_MinMemUsage/AVR_MinMemUsage.ino} (100%) rename examples/{EthernetShield_MultipleSessions/EthernetShield_MultipleSessions.ino => AVR_MultipleSessions/AVR_MultipleSessions.ino} (100%) rename examples/{EthernetShield_NonDefaultSession/EthernetShield_NonDefaultSession.ino => AVR_NonDefaultSession/AVR_NonDefaultSession.ino} (100%) rename examples/{EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino => AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino} (100%) rename examples/{EthernetShield_ReceivedRawMidiData/EthernetShield_ReceivedRawMidiData.ino => AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino} (100%) rename examples/{EthernetShield_SysEx/EthernetShield_SysEx.ino => AVR_SysEx/AVR_SysEx.ino} (100%) delete mode 100644 examples/EthernetShield_Callbacks/EthernetShield_Callbacks.ino rename examples/{MKR_ETH_Bonjour/MKR_ETH_Bonjour.ino => SAMD_Bonjour/SAMD_Bonjour.ino} (100%) diff --git a/examples/AVR_Callbacks/AVR_Callbacks.ino b/examples/AVR_Callbacks/AVR_Callbacks.ino new file mode 100644 index 0000000..21e7fce --- /dev/null +++ b/examples/AVR_Callbacks/AVR_Callbacks.ino @@ -0,0 +1,134 @@ +#include + +#include + +// Enter a MAC address for your controller below. +// Newer Ethernet shields have a MAC address printed on a sticker on the shield +byte mac[] = { + 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED +}; + +unsigned long t1 = millis(); +bool isConnected = false; + +APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +void setup() +{ + DBG_SETUP(115200); + DBG("Booting"); + + if (Ethernet.begin(mac) == 0) { + DBG(F("Failed DHCP, check network cable & reboot")); + for (;;); + } + + DBG(F("OK, now make sure you an rtpMIDI session that is Enabled")); + DBG(F("Add device named Arduino with Host"), Ethernet.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); + DBG(F("Select and then press the Connect button")); + DBG(F("Then open a MIDI listener and monitor incoming notes")); + + MIDI.begin(); + + // Stay informed on connection status + AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { + isConnected = true; + DBG(F("Connected to session"), name); + }); + AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { + isConnected = false; + DBG(F("Disconnected")); + }); + + AppleMIDI.setHandleSendRtp([](const APPLEMIDI_NAMESPACE::Rtp_t & rtp) { + DBG(F("setHandleSendRtp"), rtp.sequenceNr); + }); + AppleMIDI.setHandleReceivedRtp([](const APPLEMIDI_NAMESPACE::Rtp_t & rtp, const int32_t& latency) { + DBG(F("setHandleReceivedRtp"), rtp.sequenceNr , latency); + }); + AppleMIDI.setHandleStartReceivedMidi([](const APPLEMIDI_NAMESPACE::ssrc_t&) { + DBG(F("setHandleStartReceivedMidi")); + }); + AppleMIDI.setHandleReceivedMidi([](const APPLEMIDI_NAMESPACE::ssrc_t&, byte value) { + DBG(F("setHandleReceivedMidi"), value); + }); + AppleMIDI.setHandleEndReceivedMidi([](const APPLEMIDI_NAMESPACE::ssrc_t&) { + DBG(F("setHandleEndReceivedMidi")); + }); + + AppleMIDI.setHandleException(OnAppleMidiException); + + MIDI.setHandleNoteOn([](byte channel, byte note, byte velocity) { + DBG(F("NoteOn"), note); + }); + MIDI.setHandleNoteOff([](byte channel, byte note, byte velocity) { + DBG(F("NoteOff"), note); + }); + + DBG(F("Sending MIDI messages every second")); +} + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +void loop() +{ + // Listen to incoming notes + MIDI.read(); + + // send a note every second + // (dont cáll delay(1000) as it will stall the pipeline) + if (isConnected && (millis() - t1) > 1000) + { + t1 = millis(); + + byte note = random(1, 127); + byte velocity = 55; + byte channel = 1; + + MIDI.sendNoteOn(note, velocity, channel); + // MIDI.sendNoteOff(note, velocity, channel); + } +} + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +void OnAppleMidiException(const APPLEMIDI_NAMESPACE::ssrc_t& ssrc, const APPLEMIDI_NAMESPACE::Exception& e, const int32_t value ) { + switch (e) + { + case APPLEMIDI_NAMESPACE::Exception::BufferFullException: + DBG(F("*** BufferFullException")); + break; + case APPLEMIDI_NAMESPACE::Exception::ParseException: + DBG(F("*** ParseException")); + break; + case APPLEMIDI_NAMESPACE::Exception::TooManyParticipantsException: + DBG(F("*** TooManyParticipantsException")); + break; + case APPLEMIDI_NAMESPACE::Exception::UnexpectedInviteException: + DBG(F("*** UnexpectedInviteException")); + break; + case APPLEMIDI_NAMESPACE::Exception::ParticipantNotFoundException: + DBG(F("*** ParticipantNotFoundException"), value); + break; + case APPLEMIDI_NAMESPACE::Exception::ListenerTimeOutException: + DBG(F("*** ListenerTimeOutException")); + break; + case APPLEMIDI_NAMESPACE::Exception::MaxAttemptsException: + DBG(F("*** MaxAttemptsException")); + break; + case APPLEMIDI_NAMESPACE::Exception::NoResponseFromConnectionRequestException: + DBG(F("***:yyy did't respond to the connection request. Check the address and port, and any firewall or router settings. (time)")); + break; + case APPLEMIDI_NAMESPACE::Exception::SendPacketsDropped: + DBG(F("*** SendPacketsDropped"), value); + break; + case APPLEMIDI_NAMESPACE::Exception::ReceivedPacketsDropped: + DBG(F("*** ReceivedPacketsDropped"), value); + break; + } +} diff --git a/examples/EthernetShield_Initiator/EthernetShield_Initiator.ino b/examples/AVR_Initiator/AVR_Initiator.ino similarity index 100% rename from examples/EthernetShield_Initiator/EthernetShield_Initiator.ino rename to examples/AVR_Initiator/AVR_Initiator.ino diff --git a/examples/EthernetShield_MinMemUsage/EthernetShield_MinMemUsage.ino b/examples/AVR_MinMemUsage/AVR_MinMemUsage.ino similarity index 100% rename from examples/EthernetShield_MinMemUsage/EthernetShield_MinMemUsage.ino rename to examples/AVR_MinMemUsage/AVR_MinMemUsage.ino diff --git a/examples/EthernetShield_MultipleSessions/EthernetShield_MultipleSessions.ino b/examples/AVR_MultipleSessions/AVR_MultipleSessions.ino similarity index 100% rename from examples/EthernetShield_MultipleSessions/EthernetShield_MultipleSessions.ino rename to examples/AVR_MultipleSessions/AVR_MultipleSessions.ino diff --git a/examples/EthernetShield_NonDefaultSession/EthernetShield_NonDefaultSession.ino b/examples/AVR_NonDefaultSession/AVR_NonDefaultSession.ino similarity index 100% rename from examples/EthernetShield_NonDefaultSession/EthernetShield_NonDefaultSession.ino rename to examples/AVR_NonDefaultSession/AVR_NonDefaultSession.ino diff --git a/examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino b/examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino similarity index 100% rename from examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino rename to examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino diff --git a/examples/EthernetShield_ReceivedRawMidiData/EthernetShield_ReceivedRawMidiData.ino b/examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino similarity index 100% rename from examples/EthernetShield_ReceivedRawMidiData/EthernetShield_ReceivedRawMidiData.ino rename to examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino diff --git a/examples/EthernetShield_SysEx/EthernetShield_SysEx.ino b/examples/AVR_SysEx/AVR_SysEx.ino similarity index 100% rename from examples/EthernetShield_SysEx/EthernetShield_SysEx.ino rename to examples/AVR_SysEx/AVR_SysEx.ino diff --git a/examples/EthernetShield_Callbacks/EthernetShield_Callbacks.ino b/examples/EthernetShield_Callbacks/EthernetShield_Callbacks.ino deleted file mode 100644 index 1ee20ae..0000000 --- a/examples/EthernetShield_Callbacks/EthernetShield_Callbacks.ino +++ /dev/null @@ -1,82 +0,0 @@ -#include - -#define DISCARD_SESSION_NAME -#define NO_LATENCY_CALCULATION -#define NO_EXT_CALLBACKS -#define SerialMon Serial -#define APPLEMIDI_DEBUG SerialMon -#include - -// Enter a MAC address for your controller below. -// Newer Ethernet shields have a MAC address printed on a sticker on the shield -byte mac[] = { - 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED -}; - -unsigned long t1 = millis(); -bool isConnected = false; - -APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); - -// ----------------------------------------------------------------------------- -// -// ----------------------------------------------------------------------------- -void setup() -{ - DBG_SETUP(115200); - DBG("Booting"); - - if (Ethernet.begin(mac) == 0) { - DBG(F("Failed DHCP, check network cable & reboot")); - for (;;); - } - - DBG(F("OK, now make sure you an rtpMIDI session that is Enabled")); - DBG(F("Add device named Arduino with Host"), Ethernet.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); - DBG(F("Select and then press the Connect button")); - DBG(F("Then open a MIDI listener and monitor incoming notes"));+- - - MIDI.begin(); - - // Stay informed on connection status - AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { - isConnected = true; - DBG(F("Connected to session"), name); - }); - AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { - isConnected = false; - DBG(F("Disconnected")); - }); - - MIDI.setHandleNoteOn([](byte channel, byte note, byte velocity) { - DBG(F("NoteOn"), note); - }); - MIDI.setHandleNoteOff([](byte channel, byte note, byte velocity) { - DBG(F("NoteOff"), note); - }); - - DBG(F("Sending MIDI messages every second")); -} - -// ----------------------------------------------------------------------------- -// -// ----------------------------------------------------------------------------- -void loop() -{ - // Listen to incoming notes - MIDI.read(); - - // send a note every second - // (dont cáll delay(1000) as it will stall the pipeline) - if (isConnected && (millis() - t1) > 1000) - { - t1 = millis(); - - byte note = random(1, 127); - byte velocity = 55; - byte channel = 1; - - MIDI.sendNoteOn(note, velocity, channel); -// MIDI.sendNoteOff(note, velocity, channel); - } -} diff --git a/examples/MKR_ETH_Bonjour/MKR_ETH_Bonjour.ino b/examples/SAMD_Bonjour/SAMD_Bonjour.ino similarity index 100% rename from examples/MKR_ETH_Bonjour/MKR_ETH_Bonjour.ino rename to examples/SAMD_Bonjour/SAMD_Bonjour.ino From c51c9827cfd5f36a523997d767af2ff0f4c6cf72 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Tue, 22 Dec 2020 23:21:47 +0100 Subject: [PATCH 068/271] Update README.md --- README.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9b61192..42771c3 100755 --- a/README.md +++ b/README.md @@ -65,6 +65,19 @@ The minimum buffer size (`MaxBufferSize`) should be set to 64 bytes (also the de `MaxNumberOfParticipants` is another way to cut memory - each particpants uses approx 300 bytes. Default number of participants is 1 (using 2 sockets). Beware: the number of sockets on the Arduino is limited. The W5100 support 4, the W5200 and W5500 based IP chips can use 8 sockets. (Each participant uses 2 sockets: port 5004 and 5004+1). (Base port can be set in `APPLEMIDI_CREATE_DEFAULT_INSTANCE`) + +### 3 ways to reduce the memory footprint: +* DISCARD_SESSION_NAME + +#define'ing DISCARD_SESSION_NAME remove the need for memory for `DefaultSettings::MaxSessionNameLen` bytes + +* NO_LATENCY_CALCULATION + +Saves about 100 bytes no calculating the latency from incoming messages. + +* NO_EXT_CALLBACKS + +Saves 500 bytes if you do not want to use AppleMIDI callbacks (Connected and Disconnected remain) ## Network Shields * Arduino Ethernet shield (Wiznet W5100 and W5500) @@ -73,7 +86,7 @@ Beware: the number of sockets on the Arduino is limited. The W5100 support 4, th * Teensy WIZ820io W5200 ## Arduino IDE (arduino.cc) -* 1.8.10 +* 1.8.13 ## Contributing I would love to include your enhancements or bug fixes! In lieu of a formal styleguide, please take care to maintain the existing coding style. Please test your code before sending a pull request. It would be very helpful if you include a detailed explanation of your changes in the pull request. From 799a3ede2f5d4f902ec6183b3e568473a5f1dde4 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Tue, 22 Dec 2020 23:25:43 +0100 Subject: [PATCH 069/271] Update README.md --- README.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 42771c3..4869de6 100755 --- a/README.md +++ b/README.md @@ -67,17 +67,14 @@ The minimum buffer size (`MaxBufferSize`) should be set to 64 bytes (also the de Beware: the number of sockets on the Arduino is limited. The W5100 support 4, the W5200 and W5500 based IP chips can use 8 sockets. (Each participant uses 2 sockets: port 5004 and 5004+1). (Base port can be set in `APPLEMIDI_CREATE_DEFAULT_INSTANCE`) ### 3 ways to reduce the memory footprint: -* DISCARD_SESSION_NAME -#define'ing DISCARD_SESSION_NAME remove the need for memory for `DefaultSettings::MaxSessionNameLen` bytes +* #define NO_LATENCY_CALCULATION -* NO_LATENCY_CALCULATION +Saves 282 bytes, not calculating the latency from incoming messages. -Saves about 100 bytes no calculating the latency from incoming messages. +* #define NO_EXT_CALLBACKS -* NO_EXT_CALLBACKS - -Saves 500 bytes if you do not want to use AppleMIDI callbacks (Connected and Disconnected remain) +Saves 1150 bytes if you do not want to use AppleMIDI callbacks (but Connected and Disconnected remain) ## Network Shields * Arduino Ethernet shield (Wiznet W5100 and W5500) From ef407bad88828f0bd0bf428b8b827e1f0708fa41 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Tue, 22 Dec 2020 23:34:26 +0100 Subject: [PATCH 070/271] Update README.md --- README.md | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 4869de6..3e69b00 100755 --- a/README.md +++ b/README.md @@ -59,22 +59,15 @@ More usages in the [examples](https://github.com/lathoub/Arduino-AppleMIDI-Libra * Adafruit Feather M0 WiFi - ATSAMD21 + ATWINC1500 ## Memory usage +Out of the box, this library has been setup to use a minimum amount of memory. Extended callbacks are not enabled by default, and can be anabled by USE_EXT_CALLBACKS (and +LATENCY_CALCULATION). See the callback examamples. + This library is not using any dynamic memory allocation methods - all buffers have a fixed size, set in the `AppleMIDI_Settings.h` file, avoiding potential memory leaks and memory fragmentation. The minimum buffer size (`MaxBufferSize`) should be set to 64 bytes (also the default). Setting it to a higher value will make sending larger SysEx messages more efficiant (large SysEx messages are chopped in pieces, the larger the buffer, the less pieces needed), at the price of a bigger memory footprint. `MaxNumberOfParticipants` is another way to cut memory - each particpants uses approx 300 bytes. Default number of participants is 1 (using 2 sockets). Beware: the number of sockets on the Arduino is limited. The W5100 support 4, the W5200 and W5500 based IP chips can use 8 sockets. (Each participant uses 2 sockets: port 5004 and 5004+1). (Base port can be set in `APPLEMIDI_CREATE_DEFAULT_INSTANCE`) - -### 3 ways to reduce the memory footprint: - -* #define NO_LATENCY_CALCULATION - -Saves 282 bytes, not calculating the latency from incoming messages. - -* #define NO_EXT_CALLBACKS - -Saves 1150 bytes if you do not want to use AppleMIDI callbacks (but Connected and Disconnected remain) ## Network Shields * Arduino Ethernet shield (Wiznet W5100 and W5500) From e29094ddba3f90e500f1a107a376d35e0897a73c Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Tue, 22 Dec 2020 23:38:01 +0100 Subject: [PATCH 071/271] min memory setup, #defines for add functions --- examples/AVR_Callbacks/AVR_Callbacks.ino | 4 ++++ examples/AVR_MinMemUsage/AVR_MinMemUsage.ino | 4 ++-- examples/ESP32_Callbacks/ESP32_Callbacks.ino | 2 ++ .../wESP32_NoteOnOffEverySec.ino | 1 + src/AppleMIDI_Defs.h | 13 +++---------- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/examples/AVR_Callbacks/AVR_Callbacks.ino b/examples/AVR_Callbacks/AVR_Callbacks.ino index 21e7fce..c79155e 100644 --- a/examples/AVR_Callbacks/AVR_Callbacks.ino +++ b/examples/AVR_Callbacks/AVR_Callbacks.ino @@ -1,5 +1,9 @@ #include +#define LATENCY_CALCULATION +#define USE_EXT_CALLBACKS +#define SerialMon Serial +#define APPLEMIDI_DEBUG SerialMon #include // Enter a MAC address for your controller below. diff --git a/examples/AVR_MinMemUsage/AVR_MinMemUsage.ino b/examples/AVR_MinMemUsage/AVR_MinMemUsage.ino index c2d8db5..9324441 100644 --- a/examples/AVR_MinMemUsage/AVR_MinMemUsage.ino +++ b/examples/AVR_MinMemUsage/AVR_MinMemUsage.ino @@ -1,7 +1,7 @@ #include -#define DISCARD_SESSION_NAME -#define NO_LATENCY_CALCULATION +//#define DISCARD_SESSION_NAME +//#define NO_LATENCY_CALCULATION #define NO_EXT_CALLBACKS #include diff --git a/examples/ESP32_Callbacks/ESP32_Callbacks.ino b/examples/ESP32_Callbacks/ESP32_Callbacks.ino index a0b6e25..6245bdf 100644 --- a/examples/ESP32_Callbacks/ESP32_Callbacks.ino +++ b/examples/ESP32_Callbacks/ESP32_Callbacks.ino @@ -1,6 +1,8 @@ #include #include +#define LATENCY_CALCULATION +#define USE_EXT_CALLBACKS #define SerialMon Serial #define APPLEMIDI_DEBUG SerialMon #include diff --git a/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino b/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino index fc2b413..052bec4 100644 --- a/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino +++ b/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino @@ -1,3 +1,4 @@ +#define USE_EXT_CALLBACKS #define SerialMon Serial #define APPLEMIDI_DEBUG SerialMon #include diff --git a/src/AppleMIDI_Defs.h b/src/AppleMIDI_Defs.h index ae88f68..4192c40 100644 --- a/src/AppleMIDI_Defs.h +++ b/src/AppleMIDI_Defs.h @@ -40,16 +40,9 @@ typedef const char* AppleMIDIConstStr; #define RtpBuffer_t Deque #define MidiBuffer_t Deque -// Way to reduce memory usage, by giving up functionality -#ifndef DISCARD_SESSION_NAME -#define KEEP_SESSION_NAME -#endif -#ifndef NO_LATENCY_CALCULATION -#define LATENCY_CALCULATION -#endif -#ifndef NO_EXT_CALLBACKS -#define USE_EXT_CALLBACKS -#endif +// Add extended callbacks to enabling these #defines +// #define LATENCY_CALCULATION +// #define USE_EXT_CALLBACKS #define MIDI_SAMPLING_RATE_176K4HZ 176400 #define MIDI_SAMPLING_RATE_192KHZ 192000 From a87452132fe9809905e33043040c6c3507feb19c Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Tue, 22 Dec 2020 23:38:54 +0100 Subject: [PATCH 072/271] Update README.md --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f3828d7..3e69b00 100755 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # AppleMIDI (aka rtpMIDI) for Arduino -[![arduino-library-badge](https://www.ardu-badge.com/badge/AppleMIDI.svg?)](https://www.ardu-badge.com/AppleMIDI) [![Build Status](https://travis-ci.org/lathoub/Arduino-AppleMIDI-Library.svg?branch=master)](https://travis-ci.org/lathoub/Arduino-AppleMIDI-Library) [![License: CC BY-SA 4.0](https://img.shields.io/badge/License-CC%20BY--SA%204.0-lightgrey.svg)](http://creativecommons.org/licenses/by-sa/4.0/) [![GitHub version](https://badge.fury.io/gh/lathoub%2FArduino-AppleMidi-Library.svg)](https://badge.fury.io/gh/lathoub%2FArduino-AppleMidi-Library) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/c8be2ccc3f104e0588572a39f8106070)](https://app.codacy.com/app/lathoub/Arduino-AppleMIDI-Library?utm_source=github.com&utm_medium=referral&utm_content=lathoub/Arduino-AppleMIDI-Library&utm_campaign=Badge_Grade_Dashboard) +[![arduino-library-badge](https://www.ardu-badge.com/badge/AppleMIDI.svg?)](https://www.ardu-badge.com/AppleMIDI) [![Build Status](https://travis-ci.org/lathoub/Arduino-AppleMIDI-Library.svg?branch=master)](https://travis-ci.org/lathoub/Arduino-AppleMIDI-Library) [![License: CC BY-SA 4.0](https://img.shields.io/badge/License-CC%20BY--SA%204.0-lightgrey.svg)](http://creativecommons.org/licenses/by-sa/4.0/) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/c8be2ccc3f104e0588572a39f8106070)](https://app.codacy.com/app/lathoub/Arduino-AppleMIDI-Library?utm_source=github.com&utm_medium=referral&utm_content=lathoub/Arduino-AppleMIDI-Library&utm_campaign=Badge_Grade_Dashboard) Enables an Arduino with IP/UDP capabilities (Ethernet shield, ESP8266, ESP32, ...) to particpate in an AppleMIDI session. @@ -59,6 +59,9 @@ More usages in the [examples](https://github.com/lathoub/Arduino-AppleMIDI-Libra * Adafruit Feather M0 WiFi - ATSAMD21 + ATWINC1500 ## Memory usage +Out of the box, this library has been setup to use a minimum amount of memory. Extended callbacks are not enabled by default, and can be anabled by USE_EXT_CALLBACKS (and +LATENCY_CALCULATION). See the callback examamples. + This library is not using any dynamic memory allocation methods - all buffers have a fixed size, set in the `AppleMIDI_Settings.h` file, avoiding potential memory leaks and memory fragmentation. The minimum buffer size (`MaxBufferSize`) should be set to 64 bytes (also the default). Setting it to a higher value will make sending larger SysEx messages more efficiant (large SysEx messages are chopped in pieces, the larger the buffer, the less pieces needed), at the price of a bigger memory footprint. @@ -73,7 +76,7 @@ Beware: the number of sockets on the Arduino is limited. The W5100 support 4, th * Teensy WIZ820io W5200 ## Arduino IDE (arduino.cc) -* 1.8.10 +* 1.8.13 ## Contributing I would love to include your enhancements or bug fixes! In lieu of a formal styleguide, please take care to maintain the existing coding style. Please test your code before sending a pull request. It would be very helpful if you include a detailed explanation of your changes in the pull request. From ba3db187764bc44f8ccc18e49f8532e86e48d043 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Tue, 22 Dec 2020 23:39:12 +0100 Subject: [PATCH 073/271] Update README.md --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index 3e69b00..89b3b0a 100755 --- a/README.md +++ b/README.md @@ -59,9 +59,6 @@ More usages in the [examples](https://github.com/lathoub/Arduino-AppleMIDI-Libra * Adafruit Feather M0 WiFi - ATSAMD21 + ATWINC1500 ## Memory usage -Out of the box, this library has been setup to use a minimum amount of memory. Extended callbacks are not enabled by default, and can be anabled by USE_EXT_CALLBACKS (and -LATENCY_CALCULATION). See the callback examamples. - This library is not using any dynamic memory allocation methods - all buffers have a fixed size, set in the `AppleMIDI_Settings.h` file, avoiding potential memory leaks and memory fragmentation. The minimum buffer size (`MaxBufferSize`) should be set to 64 bytes (also the default). Setting it to a higher value will make sending larger SysEx messages more efficiant (large SysEx messages are chopped in pieces, the larger the buffer, the less pieces needed), at the price of a bigger memory footprint. From 2777a9952fa8cd7d5b2d135ba348d6be3e5adf20 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Wed, 23 Dec 2020 06:31:48 +0100 Subject: [PATCH 074/271] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 3e69b00..85897c9 100755 --- a/README.md +++ b/README.md @@ -68,6 +68,8 @@ The minimum buffer size (`MaxBufferSize`) should be set to 64 bytes (also the de `MaxNumberOfParticipants` is another way to cut memory - each particpants uses approx 300 bytes. Default number of participants is 1 (using 2 sockets). Beware: the number of sockets on the Arduino is limited. The W5100 support 4, the W5200 and W5500 based IP chips can use 8 sockets. (Each participant uses 2 sockets: port 5004 and 5004+1). (Base port can be set in `APPLEMIDI_CREATE_DEFAULT_INSTANCE`) + +Reduce the memory footprint by a further 500 by `#define NO_SESSION_NAME` before `#include `. This will leave out all the code to manage the optional session name. By default the session name is kept. ## Network Shields * Arduino Ethernet shield (Wiznet W5100 and W5500) From cd5a8fd3c3394b5d38350b8cef597d282ae5536c Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Wed, 23 Dec 2020 06:32:07 +0100 Subject: [PATCH 075/271] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 85897c9..a78cbe5 100755 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ The minimum buffer size (`MaxBufferSize`) should be set to 64 bytes (also the de `MaxNumberOfParticipants` is another way to cut memory - each particpants uses approx 300 bytes. Default number of participants is 1 (using 2 sockets). Beware: the number of sockets on the Arduino is limited. The W5100 support 4, the W5200 and W5500 based IP chips can use 8 sockets. (Each participant uses 2 sockets: port 5004 and 5004+1). (Base port can be set in `APPLEMIDI_CREATE_DEFAULT_INSTANCE`) -Reduce the memory footprint by a further 500 by `#define NO_SESSION_NAME` before `#include `. This will leave out all the code to manage the optional session name. By default the session name is kept. +Reduce the memory footprint by a further 500 bytes by `#define NO_SESSION_NAME` before `#include `. This will leave out all the code to manage the optional session name. By default the session name is kept. ## Network Shields * Arduino Ethernet shield (Wiznet W5100 and W5500) From d83529637e81946ec2a23b23ed2db96d4d2499a9 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Wed, 23 Dec 2020 12:33:50 +0100 Subject: [PATCH 076/271] further weight reduction #define ONE_PARTICIPANT --- examples/AVR_MinMemUsage/AVR_MinMemUsage.ino | 5 +- .../AVR_NoteOnOffEverySec.ino | 1 + src/AppleMIDI.h | 33 +- src/AppleMIDI.hpp | 355 ++++++++++++------ src/AppleMIDI_Debug.h | 2 + src/AppleMIDI_Defs.h | 23 +- src/AppleMIDI_Participant.h | 6 +- src/AppleMIDI_Settings.h | 2 + 8 files changed, 293 insertions(+), 134 deletions(-) diff --git a/examples/AVR_MinMemUsage/AVR_MinMemUsage.ino b/examples/AVR_MinMemUsage/AVR_MinMemUsage.ino index 9324441..1f7cee4 100644 --- a/examples/AVR_MinMemUsage/AVR_MinMemUsage.ino +++ b/examples/AVR_MinMemUsage/AVR_MinMemUsage.ino @@ -1,8 +1,7 @@ #include -//#define DISCARD_SESSION_NAME -//#define NO_LATENCY_CALCULATION -#define NO_EXT_CALLBACKS +#define ONE_PARTICIPANT +#define NO_SESSION_NAME #include // Enter a MAC address for your controller below. diff --git a/examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino b/examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino index 23d5f58..6489cd0 100644 --- a/examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino +++ b/examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino @@ -1,5 +1,6 @@ #include +//#define ONE_PARTICIPANT #define SerialMon Serial #define APPLEMIDI_DEBUG SerialMon #include diff --git a/src/AppleMIDI.h b/src/AppleMIDI.h index 2d1a477..4d8a60e 100644 --- a/src/AppleMIDI.h +++ b/src/AppleMIDI.h @@ -50,7 +50,9 @@ class AppleMIDISession AppleMIDISession(const char *sessionName, const uint16_t port = DEFAULT_CONTROL_PORT) { this->port = port; +#ifdef KEEP_SESSION_NAME strncpy(this->localName, sessionName, DefaultSettings::MaxSessionNameLen); +#endif }; void setHandleConnected(void (*fptr)(const ssrc_t&, const char*)) { _connectedCallback = fptr; } @@ -64,12 +66,16 @@ class AppleMIDISession void setHandleSendRtp(void (*fptr)(const Rtp_t&)) { _sendRtpCallback = fptr; } #endif +#ifdef KEEP_SESSION_NAME const char* getName() { return this->localName; }; + void setName(const char *sessionName) { strncpy(this->localName, sessionName, DefaultSettings::MaxSessionNameLen); }; +#else + const char* getName() { return nullptr; }; + void setName(const char *sessionName) { }; +#endif const uint16_t getPort() { return this->port; }; const ssrc_t getSynchronizationSource() { return this->ssrc; }; - void setName(const char *sessionName) { strncpy(this->localName, sessionName, DefaultSettings::MaxSessionNameLen); }; - #ifdef APPLEMIDI_INITIATOR bool sendInvite(IPAddress ip, uint16_t port = DEFAULT_CONTROL_PORT); #endif @@ -131,7 +137,11 @@ class AppleMIDISession // of what we are to send (The RtpMidi protocol start with writing the // length of the buffer). So we'll copy to a buffer in the 'write' method, // and actually serialize for real in the endTransmission method +#ifndef ONE_PARTICIPANT return (dataPort.remoteIP() != INADDR_NONE && participants.size() > 0); +#else + return (dataPort.remoteIP() != INADDR_NONE && participant.remoteIP != INADDR_NONE); +#endif }; void write(byte byte) @@ -239,11 +249,21 @@ class AppleMIDISession rtpMidi_Clock rtpMidiClock; ssrc_t ssrc = 0; - char localName[DefaultSettings::MaxSessionNameLen + 1]; uint16_t port = DEFAULT_CONTROL_PORT; + WhoCanConnectToMe whoCanConnectToMe = Anyone; +#ifdef ONE_PARTICIPANT + Participant participant; +#else Deque, Settings::MaxNumberOfParticipants> participants; -// int32_t latencyAdjustment = 0; // not used - +#endif +#ifdef USE_DIRECTORY + Deque directory; +#endif + +#ifdef KEEP_SESSION_NAME + char localName[DefaultSettings::MaxSessionNameLen + 1]; +#endif + private: void readControlPackets(); void readDataPackets(); @@ -285,15 +305,16 @@ class AppleMIDISession void manageSessionInvites(); void manageSynchronization(); - void manageSynchronizationListener(size_t); void manageSynchronizationInitiator(); void manageSynchronizationInitiatorHeartBeat(size_t); void manageSynchronizationInitiatorInvites(size_t); void sendSynchronization(Participant*); +#ifndef ONE_PARTICIPANT Participant* getParticipantBySSRC(const ssrc_t ssrc); Participant* getParticipantByInitiatorToken(const uint32_t initiatorToken); +#endif }; END_APPLEMIDI_NAMESPACE diff --git a/src/AppleMIDI.hpp b/src/AppleMIDI.hpp index a172dca..f10083f 100644 --- a/src/AppleMIDI.hpp +++ b/src/AppleMIDI.hpp @@ -93,7 +93,7 @@ void AppleMIDISession::parseDataPackets() template void AppleMIDISession::ReceivedInvitation(AppleMIDI_Invitation_t &invitation, const amPortType &portType) { - if (portType == amPortType::Control) + if (portType == amPortType::Control) ReceivedControlInvitation(invitation); else ReceivedDataInvitation(invitation); @@ -103,7 +103,11 @@ template void AppleMIDISession::ReceivedControlInvitation(AppleMIDI_Invitation_t &invitation) { // ignore invitation of a participant already in the participant list +#ifndef ONE_PARTICIPANT if (nullptr != getParticipantBySSRC(invitation.ssrc)) +#else + if (participant.ssrc == invitation.ssrc) +#endif return; // advertise our own session name @@ -112,7 +116,11 @@ void AppleMIDISession::ReceivedControlInvitation(A invitation.sessionName[DefaultSettings::MaxSessionNameLen] = '\0'; #endif +#ifndef ONE_PARTICIPANT if (participants.full()) +#else + if (participant.remoteIP != INADDR_NONE) +#endif { writeInvitation(controlPort, controlPort.remoteIP(), controlPort.remotePort(), invitation, amInvitationRejected); @@ -123,7 +131,9 @@ void AppleMIDISession::ReceivedControlInvitation(A return; } +#ifndef ONE_PARTICIPANT Participant participant; +#endif participant.kind = Listener; participant.ssrc = invitation.ssrc; participant.remoteIP = controlPort.remoteIP(); @@ -133,7 +143,9 @@ void AppleMIDISession::ReceivedControlInvitation(A strncpy(participant.sessionName, invitation.sessionName, DefaultSettings::MaxSessionNameLen); #endif +#ifndef ONE_PARTICIPANT participants.push_back(participant); +#endif writeInvitation(controlPort, participant.remoteIP, participant.remotePort, invitation, amInvitationAccepted); } @@ -141,8 +153,12 @@ void AppleMIDISession::ReceivedControlInvitation(A template void AppleMIDISession::ReceivedDataInvitation(AppleMIDI_Invitation &invitation) { - auto participant = getParticipantBySSRC(invitation.ssrc); - if (nullptr == participant) +#ifndef ONE_PARTICIPANT + auto pParticipant = getParticipantBySSRC(invitation.ssrc); +#else + auto pParticipant = (participant.ssrc == invitation.ssrc) ? &participant : nullptr; +#endif + if (nullptr == pParticipant) { writeInvitation(dataPort, dataPort.remoteIP(), dataPort.remotePort(), invitation, amInvitationRejected); @@ -158,9 +174,9 @@ void AppleMIDISession::ReceivedDataInvitation(Appl // of the ssrc here. auto ssrc_ = invitation.ssrc; - writeInvitation(dataPort, participant->remoteIP, participant->remotePort + 1, invitation, amInvitationAccepted); + writeInvitation(dataPort, pParticipant->remoteIP, pParticipant->remotePort + 1, invitation, amInvitationAccepted); - participant->kind = Listener; + pParticipant->kind = Listener; // Inform that we have an established connection if (nullptr != _connectedCallback) @@ -176,6 +192,7 @@ void AppleMIDISession::ReceivedBitrateReceiveLimit { } +#ifdef APPLEMIDI_INITIATOR template void AppleMIDISession::ReceivedInvitationAccepted(AppleMIDI_InvitationAccepted_t &invitationAccepted, const amPortType &portType) { @@ -188,32 +205,40 @@ void AppleMIDISession::ReceivedInvitationAccepted( template void AppleMIDISession::ReceivedControlInvitationAccepted(AppleMIDI_InvitationAccepted_t &invitationAccepted) { - auto participant = this->getParticipantByInitiatorToken(invitationAccepted.initiatorToken); - if (nullptr == participant) +#ifndef ONE_PARTICIPANT + auto pParticipant = this->getParticipantByInitiatorToken(invitationAccepted.initiatorToken); +#else + auto pParticipant = (participant.initiatorToken == invitationAccepted.initiatorToken) ? &participant : nullptr; +#endif + if (nullptr == pParticipant) { return; } - participant->ssrc = invitationAccepted.ssrc; - participant->lastInviteSentTime = now - 1000; // forces invite to be send - participant->connectionAttempts = 0; // reset back to 0 - participant->invitationStatus = ControlInvitationAccepted; // step it up + pParticipant->ssrc = invitationAccepted.ssrc; + pParticipant->lastInviteSentTime = now - 1000; // forces invite to be send + pParticipant->connectionAttempts = 0; // reset back to 0 + pParticipant->invitationStatus = ControlInvitationAccepted; // step it up #ifdef KEEP_SESSION_NAME - strncpy(participant->sessionName, invitationAccepted.sessionName, DefaultSettings::MaxSessionNameLen); - participant->sessionName[DefaultSettings::MaxSessionNameLen] = '\0'; + strncpy(pParticipant->sessionName, invitationAccepted.sessionName, DefaultSettings::MaxSessionNameLen); + pParticipant->sessionName[DefaultSettings::MaxSessionNameLen] = '\0'; #endif } template void AppleMIDISession::ReceivedDataInvitationAccepted(AppleMIDI_InvitationAccepted_t &invitationAccepted) { - auto participant = this->getParticipantByInitiatorToken(invitationAccepted.initiatorToken); - if (nullptr == participant) +#ifndef ONE_PARTICIPANT + auto pParticipant = this->getParticipantByInitiatorToken(invitationAccepted.initiatorToken); +#else + auto pParticipant = (participant.initiatorToken == invitationAccepted.initiatorToken) ? &participant : nullptr; +#endif + if (nullptr == pParticipant) { return; } - participant->invitationStatus = DataInvitationAccepted; + pParticipant->invitationStatus = DataInvitationAccepted; } template @@ -223,12 +248,17 @@ void AppleMIDISession::ReceivedInvitationRejected( { if (invitationRejected.ssrc == participants[i].ssrc) { +#ifndef ONE_PARTICIPANT participants.erase(i); - +#else + participant.ssrc = 0; + participant.remoteIP = INADDR_NONE; +#endif return; } } } +#endif /*! \brief . @@ -260,8 +290,12 @@ user to choose between a new connection attempt or closing the session. template void AppleMIDISession::ReceivedSynchronization(AppleMIDI_Synchronization_t &synchronization) { - auto participant = getParticipantBySSRC(synchronization.ssrc); - if (nullptr == participant) +#ifndef ONE_PARTICIPANT + auto pParticipant = getParticipantBySSRC(synchronization.ssrc); +#else + auto pParticipant = (participant.ssrc == synchronization.ssrc) ? &participant : nullptr; +#endif + if (nullptr == pParticipant) { #ifdef USE_EXT_CALLBACKS if (nullptr != _exceptionCallback) @@ -307,28 +341,28 @@ void AppleMIDISession::ReceivedSynchronization(App case SYNC_CK0: /* From session APPLEMIDI_INITIATOR */ synchronization.timestamps[SYNC_CK1] = rtpMidiClock.Now(); synchronization.count = SYNC_CK1; - writeSynchronization(participant->remoteIP, participant->remotePort + 1, synchronization); + writeSynchronization(pParticipant->remoteIP, pParticipant->remotePort + 1, synchronization); break; case SYNC_CK1: /* From session LISTENER */ #ifdef APPLEMIDI_INITIATOR synchronization.timestamps[SYNC_CK2] = rtpMidiClock.Now(); synchronization.count = SYNC_CK2; - writeSynchronization(participant->remoteIP, participant->remotePort + 1, synchronization); - participant->synchronizing = false; + writeSynchronization(pParticipant->remoteIP, pParticipant->remotePort + 1, synchronization); + pParticipant->synchronizing = false; #endif break; case SYNC_CK2: /* From session APPLEMIDI_INITIATOR */ #ifdef LATENCY_CALCULATION // each party can estimate the offset between the two clocks using the following formula - participant->offsetEstimate = (uint32_t)(((synchronization.timestamps[2] + synchronization.timestamps[0]) / 2) - synchronization.timestamps[1]); + pParticipant->offsetEstimate = (uint32_t)(((synchronization.timestamps[2] + synchronization.timestamps[0]) / 2) - synchronization.timestamps[1]); #endif break; } // All particpants need to check in regularly, // failing to do so will result in a lost connection. - participant->lastSyncExchangeTime = now; + pParticipant->lastSyncExchangeTime = now; } // The recovery journal mechanism requires that the receiver periodically @@ -342,9 +376,12 @@ void AppleMIDISession::ReceivedReceiverFeedback(Ap { // We do not keep any recovery journals, no command history, nothing! // Here is where you would correct if packets are dropped (send them again) - - auto participant = getParticipantBySSRC(receiverFeedback.ssrc); - if (nullptr == participant) { +#ifndef ONE_PARTICIPANT + auto pParticipant = getParticipantBySSRC(receiverFeedback.ssrc); +#else + auto pParticipant = (participant.ssrc == receiverFeedback.ssrc) ? &participant : nullptr; +#endif + if (nullptr == pParticipant) { #ifdef USE_EXT_CALLBACKS if (nullptr != _exceptionCallback) _exceptionCallback(ssrc, ParticipantNotFoundException, receiverFeedback.ssrc); @@ -352,11 +389,11 @@ void AppleMIDISession::ReceivedReceiverFeedback(Ap return; } - if (participant->sendSequenceNr != receiverFeedback.sequenceNr) + if (pParticipant->sendSequenceNr != receiverFeedback.sequenceNr) { #ifdef USE_EXT_CALLBACKS if (nullptr != _exceptionCallback) - _exceptionCallback(ssrc, SendPacketsDropped, participant->sendSequenceNr - receiverFeedback.sequenceNr); + _exceptionCallback(ssrc, SendPacketsDropped, pParticipant->sendSequenceNr - receiverFeedback.sequenceNr); #endif } } @@ -364,14 +401,23 @@ void AppleMIDISession::ReceivedReceiverFeedback(Ap template void AppleMIDISession::ReceivedEndSession(AppleMIDI_EndSession_t &endSession) { +#ifndef ONE_PARTICIPANT for (size_t i = 0; i < participants.size(); i++) { - if (endSession.ssrc == participants[i].ssrc) + auto participant = participants[i]; +#else + { +#endif + if (endSession.ssrc == participant.ssrc) { - auto ssrc = participants[i].ssrc; + auto ssrc = participant.ssrc; +#ifndef ONE_PARTICIPANT participants.erase(i); - +#else + participant.ssrc = 0; + participant.remoteIP = INADDR_NONE; +#endif if (nullptr != _disconnectedCallback) _disconnectedCallback(ssrc); @@ -380,6 +426,7 @@ void AppleMIDISession::ReceivedEndSession(AppleMID } } +#ifndef ONE_PARTICIPANT template Participant* AppleMIDISession::getParticipantBySSRC(const ssrc_t ssrc) { @@ -397,6 +444,7 @@ Participant* AppleMIDISession::getPartic return &participants[i]; return nullptr; } +#endif template void AppleMIDISession::writeInvitation(UdpClass &port, IPAddress remoteIP, uint16_t remotePort, AppleMIDI_Invitation_t & invitation, const byte *command) @@ -478,16 +526,21 @@ void AppleMIDISession::writeEndSession(const IPAdd template void AppleMIDISession::writeRtpMidiToAllParticipants() { +#ifndef ONE_PARTICIPANT for (size_t i = 0; i < participants.size(); i++) { - auto participant = &participants[i]; - writeRtpMidiBuffer(participant); + auto pParticipant = &participants[i]; + + writeRtpMidiBuffer(pParticipant); } +#else + writeRtpMidiBuffer(&participant); +#endif outMidiBuffer.clear(); } template -void AppleMIDISession::writeRtpMidiBuffer(Participant * participant) +void AppleMIDISession::writeRtpMidiBuffer(Participant* participant) { const IPAddress remoteIP = participant->remoteIP; const uint16_t remotePort = participant->remotePort + 1; @@ -565,7 +618,6 @@ void AppleMIDISession::writeRtpMidiBuffer(Particip dataPort.endPacket(); dataPort.flush(); - } // @@ -574,50 +626,53 @@ void AppleMIDISession::writeRtpMidiBuffer(Particip template void AppleMIDISession::manageSynchronization() { +#ifndef ONE_PARTICIPANT for (size_t i = 0; i < participants.size(); i++) +#endif { +#ifndef ONE_PARTICIPANT + auto pParticipant = &participants[i]; + if (pParticipant->remoteIP == INADDR_NONE) continue; +#else + auto pParticipant = &participant; + if (pParticipant->remoteIP == INADDR_NONE) return; +#endif #ifdef APPLEMIDI_INITIATOR - auto participant = &participants[i]; - - if (participant->invitationStatus != Connected) + if (pParticipant->invitationStatus != Connected) continue; // Only for Initiators that are Connected - if (participant->kind == Listener) + if (pParticipant->kind == Listener) { #endif - manageSynchronizationListener(i); + // 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 - pParticipant->lastSyncExchangeTime > Settings::CK_MaxTimeOut) + { +#ifdef USE_EXT_CALLBACKS + if (nullptr != _exceptionCallback) + _exceptionCallback(ssrc, ListenerTimeOutException, 0); +#endif + sendEndSession(pParticipant); +#ifndef ONE_PARTICIPANT + participants.erase(i); +#else + participant.ssrc = 0; + participant.remoteIP = INADDR_NONE; +#endif + } #ifdef APPLEMIDI_INITIATOR } else { - (participant->synchronizing) ? manageSynchronizationInitiatorInvites(i) - : manageSynchronizationInitiatorHeartBeat(i); + (pParticipant->synchronizing) ? manageSynchronizationInitiatorInvites(i) + : manageSynchronizationInitiatorHeartBeat(pParticipant); } #endif } } -template -void AppleMIDISession::manageSynchronizationListener(size_t i) -{ - auto participant = &participants[i]; - - // 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) - { -#ifdef USE_EXT_CALLBACKS - if (nullptr != _exceptionCallback) - _exceptionCallback(ssrc, ListenerTimeOutException, 0); -#endif - sendEndSession(participant); - - participants.erase(i); - - return; - } -} +#ifdef APPLEMIDI_INITIATOR // // The initiator of the session polls if remote station is still alive. @@ -627,32 +682,30 @@ void AppleMIDISession::manageSynchronizationListen // otherwise the responder may assume that the initiator has died and terminate the session. // template -void AppleMIDISession::manageSynchronizationInitiatorHeartBeat(size_t i) +void AppleMIDISession::manageSynchronizationInitiatorHeartBeat(Participant* pParticipant) { - auto participant = &participants[i]; - // Note: During startup, the initiator should send synchronization exchanges more frequently; // empirical testing has determined that sending a few exchanges improves clock // synchronization accuracy. // (Here: twice every 0.5 seconds, then 6 times every 1.5 seconds, then every 10 seconds.) bool doSyncronize = false; - if (participant->synchronizationHeartBeats < 2) + if (pParticipant->synchronizationHeartBeats < 2) { - if (now - participant->lastInviteSentTime > 500) // 2 x every 0.5 seconds + if (now - pParticipant->lastInviteSentTime > 500) // 2 x every 0.5 seconds { - participant->synchronizationHeartBeats++; + pParticipant->synchronizationHeartBeats++; doSyncronize = true; } } - else if (participant->synchronizationHeartBeats < 7) + else if (pParticipant->synchronizationHeartBeats < 7) { - if (now - participant->lastInviteSentTime > 1500) // 5 x every 1.5 seconds + if (now - pParticipant->lastInviteSentTime > 1500) // 5 x every 1.5 seconds { - participant->synchronizationHeartBeats++; + pParticipant->synchronizationHeartBeats++; doSyncronize = true; } } - else if (now - participant->lastInviteSentTime > DefaultSettings::SynchronizationHeartBeat) + else if (now - pParticipant->lastInviteSentTime > DefaultSettings::SynchronizationHeartBeat) { doSyncronize = true; } @@ -660,34 +713,41 @@ void AppleMIDISession::manageSynchronizationInitia if (!doSyncronize) return; - participant->synchronizationCount = 0; - sendSynchronization(participant); + pParticipant->synchronizationCount = 0; + sendSynchronization(pParticipant); } // checks for template void AppleMIDISession::manageSynchronizationInitiatorInvites(size_t i) { - auto participant = &participants[i]; + auto pParticipant = &participants[i]; - if (now - participant->lastInviteSentTime > 10000) + if (now - pParticipant->lastInviteSentTime > 10000) { - if (participant->synchronizationCount > DefaultSettings::MaxSynchronizationCK0Attempts) + if (pParticipant->synchronizationCount > DefaultSettings::MaxSynchronizationCK0Attempts) { #ifdef USE_EXT_CALLBACKS if (nullptr != _exceptionCallback) _exceptionCallback(ssrc, MaxAttemptsException, 0); #endif // After too many attempts, stop. - sendEndSession(participant); + sendEndSession(pParticipant); +#ifndef ONE_PARTICIPANT participants.erase(i); +#else + participant.ssrc = 0; + participant.remoteIP = INADDR_NONE; +#endif return; } - sendSynchronization(participant); + sendSynchronization(pParticipant); } } +#endif + template void AppleMIDISession::sendSynchronization(Participant* participant) { @@ -707,67 +767,88 @@ void AppleMIDISession::sendSynchronization(Partici template void AppleMIDISession::manageSessionInvites() { +#ifndef ONE_PARTICIPANT for (auto i = 0; i < participants.size(); i++) +#endif { - auto participant = &participants[i]; +#ifndef ONE_PARTICIPANT + auto pParticipant = &participants[i]; +#else + auto pParticipant = &participant; +#endif - if (participant->kind == Listener) + if (pParticipant->kind == Listener) +#ifndef ONE_PARTICIPANT continue; - - if (participant->invitationStatus == DataInvitationAccepted) +#else + return; +#endif + if (pParticipant->invitationStatus == DataInvitationAccepted) { // Inform that we have an established connection if (nullptr != _connectedCallback) #ifdef KEEP_SESSION_NAME - _connectedCallback(participant->ssrc, participant->sessionName); + _connectedCallback(pParticipant->ssrc, pParticipant->sessionName); #else - _connectedCallback(participant->ssrc, nullptr); + _connectedCallback(pParticipant->ssrc, nullptr); #endif - participant->invitationStatus = Connected; + pParticipant->invitationStatus = Connected; } - if (participant->invitationStatus == Connected) - continue; // We are done here + if (pParticipant->invitationStatus == Connected) +#ifndef ONE_PARTICIPANT + continue; +#else + return; +#endif // try to connect every 1 second (1000 ms) - if (now - participant->lastInviteSentTime > 1000) + if (now - pParticipant->lastInviteSentTime > 1000) { - if (participant->connectionAttempts >= DefaultSettings::MaxSessionInvitesAttempts) + if (pParticipant->connectionAttempts >= DefaultSettings::MaxSessionInvitesAttempts) { #ifdef USE_EXT_CALLBACKS if (nullptr != _exceptionCallback) _exceptionCallback(ssrc, NoResponseFromConnectionRequestException, 0); #endif // After too many attempts, stop. - sendEndSession(participant); + sendEndSession(pParticipant); +#ifndef ONE_PARTICIPANT participants.erase(i); - +#else + participant.ssrc = 0; + pParticipant->remoteIP = INADDR_NONE; +#endif +#ifndef ONE_PARTICIPANT continue; +#else + return; +#endif } - participant->lastInviteSentTime = now; - participant->connectionAttempts++; + pParticipant->lastInviteSentTime = now; + pParticipant->connectionAttempts++; AppleMIDI_Invitation invitation; invitation.ssrc = this->ssrc; - invitation.initiatorToken = participant->initiatorToken; + invitation.initiatorToken = pParticipant->initiatorToken; #ifdef KEEP_SESSION_NAME strncpy(invitation.sessionName, this->localName, DefaultSettings::MaxSessionNameLen); invitation.sessionName[DefaultSettings::MaxSessionNameLen] = '\0'; #endif - if (participant->invitationStatus == Initiating - || participant->invitationStatus == AwaitingControlInvitationAccepted) + if (pParticipant->invitationStatus == Initiating + || pParticipant->invitationStatus == AwaitingControlInvitationAccepted) { - writeInvitation(controlPort, participant->remoteIP, participant->remotePort, invitation, amInvitation); - participant->invitationStatus = AwaitingControlInvitationAccepted; + writeInvitation(controlPort, pParticipant->remoteIP, pParticipant->remotePort, invitation, amInvitation); + pParticipant->invitationStatus = AwaitingControlInvitationAccepted; } else - if (participant->invitationStatus == ControlInvitationAccepted - || participant->invitationStatus == AwaitingDataInvitationAccepted) + if (pParticipant->invitationStatus == ControlInvitationAccepted + || pParticipant->invitationStatus == AwaitingDataInvitationAccepted) { - writeInvitation(dataPort, participant->remoteIP, participant->remotePort + 1, invitation, amInvitation); - participant->invitationStatus = AwaitingDataInvitationAccepted; + writeInvitation(dataPort, pParticipant->remoteIP, pParticipant->remotePort + 1, invitation, amInvitation); + pParticipant->invitationStatus = AwaitingDataInvitationAccepted; } } } @@ -783,22 +864,34 @@ void AppleMIDISession::manageSessionInvites() template void AppleMIDISession::manageReceiverFeedback() { - for (size_t i = 0; i < participants.size(); i++) +#ifndef ONE_PARTICIPANT + for (auto i = 0; i < participants.size(); i++) +#endif { - auto participant = &participants[i]; - - if (participant->doReceiverFeedback == false) +#ifndef ONE_PARTICIPANT + auto pParticipant = &participants[i]; + if (pParticipant->remoteIP == INADDR_NONE) continue; +#else + auto pParticipant = &participant; + if (pParticipant->remoteIP == INADDR_NONE) return; +#endif + + if (pParticipant->doReceiverFeedback == false) +#ifndef ONE_PARTICIPANT continue; +#else + return; +#endif - if ((now - participant->receiverFeedbackStartTime) > Settings::ReceiversFeedbackThreshold) + if ((now - pParticipant->receiverFeedbackStartTime) > Settings::ReceiversFeedbackThreshold) { AppleMIDI_ReceiverFeedback_t rf; rf.ssrc = ssrc; - rf.sequenceNr = participant->receiveSequenceNr; - writeReceiverFeedback(participant->remoteIP, participant->remotePort, rf); + rf.sequenceNr = pParticipant->receiveSequenceNr; + writeReceiverFeedback(pParticipant->remoteIP, pParticipant->remotePort, rf); // reset the clock. It is started when we receive MIDI - participant->doReceiverFeedback = false; + pParticipant->doReceiverFeedback = false; } } } @@ -808,12 +901,18 @@ void AppleMIDISession::manageReceiverFeedback() template bool AppleMIDISession::sendInvite(IPAddress ip, uint16_t port) { +#ifndef ONE_PARTICIPANT if (participants.full()) +#else + if (participant.remoteIP != INADDR_NONE) +#endif { return false; } - + +#ifndef ONE_PARTICIPANT Participant participant; +#endif participant.kind = Initiator; participant.remoteIP = ip; participant.remotePort = port; @@ -822,7 +921,9 @@ bool AppleMIDISession::sendInvite(IPAddress ip, ui participant.initiatorToken = random(1, INT32_MAX) * 2; participant.sequenceNr; +#ifndef ONE_PARTICIPANT participants.push_back(participant); +#endif return true; } @@ -832,6 +933,7 @@ bool AppleMIDISession::sendInvite(IPAddress ip, ui template void AppleMIDISession::sendEndSession() { +#ifndef ONE_PARTICIPANT while (participants.size() > 0) { auto participant = &participants.front(); @@ -839,6 +941,13 @@ void AppleMIDISession::sendEndSession() participants.pop_front(); } +#else + if (participant.remoteIP != INADDR_NONE) + { + sendEndSession(&participant); + participant.remoteIP = INADDR_NONE; + } +#endif } template @@ -856,13 +965,17 @@ void AppleMIDISession::sendEndSession(Participant< template void AppleMIDISession::ReceivedRtp(const Rtp_t& rtp) { - auto participant = getParticipantBySSRC(rtp.ssrc); +#ifndef ONE_PARTICIPANT + auto pParticipant = getParticipantBySSRC(rtp.ssrc); +#else + auto pParticipant = (participant.ssrc == rtp.ssrc) ? &participant : nullptr; +#endif - if (nullptr != participant) + if (nullptr != pParticipant) { - if (participant->doReceiverFeedback == false) - participant->receiverFeedbackStartTime = now; - participant->doReceiverFeedback = true; + if (pParticipant->doReceiverFeedback == false) + pParticipant->receiverFeedbackStartTime = now; + pParticipant->doReceiverFeedback = true; #ifdef LATENCY_CALCULATION auto offset = (rtp.timestamp - participant->offsetEstimate); @@ -871,15 +984,15 @@ void AppleMIDISession::ReceivedRtp(const Rtp_t& rt auto latency = 0; #endif - if (participant->receiveSequenceNr + 1 != rtp.sequenceNr) { + if (pParticipant->receiveSequenceNr + 1 != rtp.sequenceNr) { #ifdef USE_EXT_CALLBACKS if (nullptr != _exceptionCallback) - _exceptionCallback(ssrc, ReceivedPacketsDropped, participant->receiveSequenceNr + 1 - rtp.sequenceNr); + _exceptionCallback(ssrc, ReceivedPacketsDropped, pParticipant->receiveSequenceNr + 1 - rtp.sequenceNr); #endif } - participant->receiveSequenceNr = rtp.sequenceNr; + pParticipant->receiveSequenceNr = rtp.sequenceNr; #ifdef USE_EXT_CALLBACKS if (nullptr != _receivedRtpCallback) diff --git a/src/AppleMIDI_Debug.h b/src/AppleMIDI_Debug.h index 3d65291..342cc81 100644 --- a/src/AppleMIDI_Debug.h +++ b/src/AppleMIDI_Debug.h @@ -2,7 +2,9 @@ namespace { static void DBG_SETUP(unsigned long baud) { APPLEMIDI_DEBUG.begin(baud); + #ifdef __AVR_ATmega32U4__ while (!APPLEMIDI_DEBUG); + #endif } template diff --git a/src/AppleMIDI_Defs.h b/src/AppleMIDI_Defs.h index 4192c40..b43db88 100644 --- a/src/AppleMIDI_Defs.h +++ b/src/AppleMIDI_Defs.h @@ -43,6 +43,13 @@ typedef const char* AppleMIDIConstStr; // Add extended callbacks to enabling these #defines // #define LATENCY_CALCULATION // #define USE_EXT_CALLBACKS +// #define ONE_PARTICIPANT // TODO +// #define USE_DIRECTORY + +// By defining NO_SESSION_NAME in the sketch, you can save 100 bytes +#ifndef NO_SESSION_NAME +#define KEEP_SESSION_NAME +#endif #define MIDI_SAMPLING_RATE_176K4HZ 176400 #define MIDI_SAMPLING_RATE_192KHZ 192000 @@ -51,6 +58,13 @@ typedef const char* AppleMIDIConstStr; struct Rtp; typedef Rtp Rtp_t; +enum WhoCanConnectToMe : uint8_t +{ + None, + OnlyComputersInMyDirectory, + Anyone, +}; + // from: https://en.wikipedia.org/wiki/RTP-MIDI // Apple decided to create their own protocol, imposing all parameters related to // synchronization like the sampling frequency. This session protocol is called "AppleMIDI" @@ -136,12 +150,19 @@ typedef struct PACKED AppleMIDI_Invitation { initiatorToken_t initiatorToken; ssrc_t ssrc; - char sessionName[DefaultSettings::MaxSessionNameLen + 1]; +#ifdef KEEP_SESSION_NAME + char sessionName[DefaultSettings::MaxSessionNameLen + 1]; const size_t getLength() const { return sizeof(AppleMIDI_Invitation) - (DefaultSettings::MaxSessionNameLen) + strlen(sessionName); } +#else + const size_t getLength() const + { + return sizeof(AppleMIDI_Invitation); + } +#endif } AppleMIDI_Invitation_t, AppleMIDI_InvitationAccepted_t, AppleMIDI_InvitationRejected_t; typedef struct PACKED AppleMIDI_BitrateReceiveLimit diff --git a/src/AppleMIDI_Participant.h b/src/AppleMIDI_Participant.h index 878dd8d..e0ba1a5 100644 --- a/src/AppleMIDI_Participant.h +++ b/src/AppleMIDI_Participant.h @@ -10,9 +10,9 @@ template struct Participant { ParticipantKind kind; - ssrc_t ssrc; - IPAddress remoteIP; - uint16_t remotePort; + ssrc_t ssrc = 0; + IPAddress remoteIP = INADDR_NONE; + uint16_t remotePort = 0; unsigned long receiverFeedbackStartTime; bool doReceiverFeedback = false; diff --git a/src/AppleMIDI_Settings.h b/src/AppleMIDI_Settings.h index c5a3e07..346c188 100644 --- a/src/AppleMIDI_Settings.h +++ b/src/AppleMIDI_Settings.h @@ -13,6 +13,8 @@ struct DefaultSettings static const size_t MaxSessionNameLen = 24; static const uint8_t MaxNumberOfParticipants = 2; + + static const uint8_t MaxNumberOfComputersInDirectory = 2; // The recovery journal mechanism requires that the receiver periodically // inform the sender of the sequence number of the most recently received packet. From cf1ba1a52fff45337ed92ca5cd9db7f6346feea4 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Wed, 23 Dec 2020 12:42:04 +0100 Subject: [PATCH 077/271] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index a78cbe5..1cf1289 100755 --- a/README.md +++ b/README.md @@ -70,6 +70,9 @@ The minimum buffer size (`MaxBufferSize`) should be set to 64 bytes (also the de Beware: the number of sockets on the Arduino is limited. The W5100 support 4, the W5200 and W5500 based IP chips can use 8 sockets. (Each participant uses 2 sockets: port 5004 and 5004+1). (Base port can be set in `APPLEMIDI_CREATE_DEFAULT_INSTANCE`) Reduce the memory footprint by a further 500 bytes by `#define NO_SESSION_NAME` before `#include `. This will leave out all the code to manage the optional session name. By default the session name is kept. + +Even further reduce the memory footprint by `#define ONE_PARTICIPANT` limiting the number of particpants to just 1. +On an UNO the absolute minimum memory footprint is 22142 bytes (68%) and 946 global variables (46%). ## Network Shields * Arduino Ethernet shield (Wiznet W5100 and W5500) From f4251637c91dcb31c83b31c4af4afdfe73dfa675 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Wed, 23 Dec 2020 12:58:02 +0100 Subject: [PATCH 078/271] furtner memory reduction --- .../AVR_NoteOnOffEverySec.ino | 2 +- src/AppleMIDI.h | 2 +- src/AppleMIDI.hpp | 22 +++++++------------ 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino b/examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino index 6489cd0..52c28d3 100644 --- a/examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino +++ b/examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino @@ -1,6 +1,6 @@ #include -//#define ONE_PARTICIPANT +#define ONE_PARTICIPANT #define SerialMon Serial #define APPLEMIDI_DEBUG SerialMon #include diff --git a/src/AppleMIDI.h b/src/AppleMIDI.h index 4d8a60e..95826be 100644 --- a/src/AppleMIDI.h +++ b/src/AppleMIDI.h @@ -140,7 +140,7 @@ class AppleMIDISession #ifndef ONE_PARTICIPANT return (dataPort.remoteIP() != INADDR_NONE && participants.size() > 0); #else - return (dataPort.remoteIP() != INADDR_NONE && participant.remoteIP != INADDR_NONE); + return (dataPort.remoteIP() != INADDR_NONE && participant.ssrc != 0); #endif }; diff --git a/src/AppleMIDI.hpp b/src/AppleMIDI.hpp index f10083f..b3b9ea2 100644 --- a/src/AppleMIDI.hpp +++ b/src/AppleMIDI.hpp @@ -110,7 +110,6 @@ void AppleMIDISession::ReceivedControlInvitation(A #endif return; - // advertise our own session name #ifdef KEEP_SESSION_NAME strncpy(invitation.sessionName, localName, DefaultSettings::MaxSessionNameLen); invitation.sessionName[DefaultSettings::MaxSessionNameLen] = '\0'; @@ -119,7 +118,7 @@ void AppleMIDISession::ReceivedControlInvitation(A #ifndef ONE_PARTICIPANT if (participants.full()) #else - if (participant.remoteIP != INADDR_NONE) + if (participant.ssrc != 0) #endif { writeInvitation(controlPort, controlPort.remoteIP(), controlPort.remotePort(), invitation, amInvitationRejected); @@ -252,7 +251,6 @@ void AppleMIDISession::ReceivedInvitationRejected( participants.erase(i); #else participant.ssrc = 0; - participant.remoteIP = INADDR_NONE; #endif return; } @@ -416,7 +414,6 @@ void AppleMIDISession::ReceivedEndSession(AppleMID participants.erase(i); #else participant.ssrc = 0; - participant.remoteIP = INADDR_NONE; #endif if (nullptr != _disconnectedCallback) _disconnectedCallback(ssrc); @@ -632,10 +629,10 @@ void AppleMIDISession::manageSynchronization() { #ifndef ONE_PARTICIPANT auto pParticipant = &participants[i]; - if (pParticipant->remoteIP == INADDR_NONE) continue; + if (pParticipant->ssrc == 0) continue; #else auto pParticipant = &participant; - if (pParticipant->remoteIP == INADDR_NONE) return; + if (pParticipant->ssrc == 0) return; #endif #ifdef APPLEMIDI_INITIATOR if (pParticipant->invitationStatus != Connected) @@ -658,7 +655,6 @@ void AppleMIDISession::manageSynchronization() participants.erase(i); #else participant.ssrc = 0; - participant.remoteIP = INADDR_NONE; #endif } #ifdef APPLEMIDI_INITIATOR @@ -738,7 +734,6 @@ void AppleMIDISession::manageSynchronizationInitia participants.erase(i); #else participant.ssrc = 0; - participant.remoteIP = INADDR_NONE; #endif return; } @@ -818,7 +813,6 @@ void AppleMIDISession::manageSessionInvites() participants.erase(i); #else participant.ssrc = 0; - pParticipant->remoteIP = INADDR_NONE; #endif #ifndef ONE_PARTICIPANT continue; @@ -870,10 +864,10 @@ void AppleMIDISession::manageReceiverFeedback() { #ifndef ONE_PARTICIPANT auto pParticipant = &participants[i]; - if (pParticipant->remoteIP == INADDR_NONE) continue; + if (pParticipant->ssrc == 0) continue; #else auto pParticipant = &participant; - if (pParticipant->remoteIP == INADDR_NONE) return; + if (pParticipant->ssrc == 0) return; #endif if (pParticipant->doReceiverFeedback == false) @@ -904,7 +898,7 @@ bool AppleMIDISession::sendInvite(IPAddress ip, ui #ifndef ONE_PARTICIPANT if (participants.full()) #else - if (participant.remoteIP != INADDR_NONE) + if (participant.ssrc != 0) #endif { return false; @@ -942,10 +936,10 @@ void AppleMIDISession::sendEndSession() participants.pop_front(); } #else - if (participant.remoteIP != INADDR_NONE) + if (participant.src != 0) { sendEndSession(&participant); - participant.remoteIP = INADDR_NONE; + participant.ssrc = 0; } #endif } From 952c31dfc478ff0d99b7dd62d139442b71b7921a Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Wed, 23 Dec 2020 12:59:27 +0100 Subject: [PATCH 079/271] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1cf1289..f5bbff9 100755 --- a/README.md +++ b/README.md @@ -72,7 +72,7 @@ Beware: the number of sockets on the Arduino is limited. The W5100 support 4, th Reduce the memory footprint by a further 500 bytes by `#define NO_SESSION_NAME` before `#include `. This will leave out all the code to manage the optional session name. By default the session name is kept. Even further reduce the memory footprint by `#define ONE_PARTICIPANT` limiting the number of particpants to just 1. -On an UNO the absolute minimum memory footprint is 22142 bytes (68%) and 946 global variables (46%). +On an UNO the absolute minimum memory footprint is 21976 bytes (68%) and 946 global variables (46%). ## Network Shields * Arduino Ethernet shield (Wiznet W5100 and W5500) From 8654ca3225d010a4dd59ea0fabd693b9bc0466f2 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Wed, 23 Dec 2020 14:53:18 +0100 Subject: [PATCH 080/271] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f5bbff9..d1ca3ec 100755 --- a/README.md +++ b/README.md @@ -72,7 +72,7 @@ Beware: the number of sockets on the Arduino is limited. The W5100 support 4, th Reduce the memory footprint by a further 500 bytes by `#define NO_SESSION_NAME` before `#include `. This will leave out all the code to manage the optional session name. By default the session name is kept. Even further reduce the memory footprint by `#define ONE_PARTICIPANT` limiting the number of particpants to just 1. -On an UNO the absolute minimum memory footprint is 21976 bytes (68%) and 946 global variables (46%). +On an UNO the absolute minimum memory footprint is 21976 bytes (68%) and 946 global variables (46%). For a Leonardo that is 24916 bytes (86%) and 1112 bytes (43%) of global variables. ## Network Shields * Arduino Ethernet shield (Wiznet W5100 and W5500) From 8a138d17f0486956255b2a7f96546df26f785aec Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Wed, 23 Dec 2020 14:56:19 +0100 Subject: [PATCH 081/271] Update README.md --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index d1ca3ec..c7781a3 100755 --- a/README.md +++ b/README.md @@ -57,7 +57,13 @@ More usages in the [examples](https://github.com/lathoub/Arduino-AppleMIDI-Libra * ESP32 (Adafruit HUZZAH32 – ESP32 Feather Board) * Teensy 3.2 * Adafruit Feather M0 WiFi - ATSAMD21 + ATWINC1500 - + +## Network Shields +* Arduino Ethernet shield (Wiznet W5100 and W5500) +* Arduino Wifi R3 shield +* MKR ETH shield +* Teensy WIZ820io W5200 + ## Memory usage Out of the box, this library has been setup to use a minimum amount of memory. Extended callbacks are not enabled by default, and can be anabled by USE_EXT_CALLBACKS (and LATENCY_CALCULATION). See the callback examamples. @@ -74,12 +80,6 @@ Reduce the memory footprint by a further 500 bytes by `#define NO_SESSION_NAME` Even further reduce the memory footprint by `#define ONE_PARTICIPANT` limiting the number of particpants to just 1. On an UNO the absolute minimum memory footprint is 21976 bytes (68%) and 946 global variables (46%). For a Leonardo that is 24916 bytes (86%) and 1112 bytes (43%) of global variables. -## Network Shields -* Arduino Ethernet shield (Wiznet W5100 and W5500) -* Arduino Wifi R3 shield -* MKR ETH shield -* Teensy WIZ820io W5200 - ## Arduino IDE (arduino.cc) * 1.8.13 From 777a69882bd989d18a932719f51619057d52ffe3 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Wed, 23 Dec 2020 20:33:35 +0100 Subject: [PATCH 082/271] Update AVR_NoteOnOffEverySec.ino --- examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino b/examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino index 52c28d3..23d5f58 100644 --- a/examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino +++ b/examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino @@ -1,6 +1,5 @@ #include -#define ONE_PARTICIPANT #define SerialMon Serial #define APPLEMIDI_DEBUG SerialMon #include From df64cae89bd425e7a5e3d40c64b41c2a37605f81 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Thu, 24 Dec 2020 07:17:02 +0100 Subject: [PATCH 083/271] added Directory --- examples/AVR_Callbacks/AVR_Callbacks.ino | 6 + examples/AVR_Directory/AVR_Directory.ino | 86 ++++++++ examples/ESP32_Callbacks/ESP32_Callbacks.ino | 207 ------------------- src/AppleMIDI.h | 18 +- src/AppleMIDI.hpp | 53 ++++- src/AppleMIDI_Defs.h | 9 +- src/AppleMIDI_Settings.h | 2 +- 7 files changed, 152 insertions(+), 229 deletions(-) create mode 100644 examples/AVR_Directory/AVR_Directory.ino delete mode 100644 examples/ESP32_Callbacks/ESP32_Callbacks.ino diff --git a/examples/AVR_Callbacks/AVR_Callbacks.ino b/examples/AVR_Callbacks/AVR_Callbacks.ino index c79155e..bf76501 100644 --- a/examples/AVR_Callbacks/AVR_Callbacks.ino +++ b/examples/AVR_Callbacks/AVR_Callbacks.ino @@ -119,6 +119,12 @@ void OnAppleMidiException(const APPLEMIDI_NAMESPACE::ssrc_t& ssrc, const APPLEMI case APPLEMIDI_NAMESPACE::Exception::ParticipantNotFoundException: DBG(F("*** ParticipantNotFoundException"), value); break; + case APPLEMIDI_NAMESPACE::Exception::ComputerNotInDirectory: + DBG(F("*** ComputerNotInDirectory"), value); + break; + case APPLEMIDI_NAMESPACE::Exception::NotAcceptingAnyone: + DBG(F("*** NotAcceptingAnyone"), value); + break; case APPLEMIDI_NAMESPACE::Exception::ListenerTimeOutException: DBG(F("*** ListenerTimeOutException")); break; diff --git a/examples/AVR_Directory/AVR_Directory.ino b/examples/AVR_Directory/AVR_Directory.ino new file mode 100644 index 0000000..9487ef5 --- /dev/null +++ b/examples/AVR_Directory/AVR_Directory.ino @@ -0,0 +1,86 @@ +#include + +#define USE_DIRECTORY +#define SerialMon Serial +#define APPLEMIDI_DEBUG SerialMon +#include + +// Enter a MAC address for your controller below. +// Newer Ethernet shields have a MAC address printed on a sticker on the shield +byte mac[] = { + 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED +}; + +unsigned long t1 = millis(); +bool isConnected = false; + +APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +void setup() +{ + DBG_SETUP(115200); + DBG("Booting"); + + if (Ethernet.begin(mac) == 0) { + DBG(F("Failed DHCP, check network cable & reboot")); + for (;;); + } + + AppleMIDI.directory.push_back(IPAddress(192, 168, 1, 63)); + AppleMIDI.directory.push_back(IPAddress(192, 168, 1, 66)); +// AppleMIDI.whoCanConnectToMe = APPLEMIDI_NAMESPACE::None; + AppleMIDI.whoCanConnectToMe = APPLEMIDI_NAMESPACE::OnlyComputersInMyDirectory; +// AppleMIDI.whoCanConnectToMe = APPLEMIDI_NAMESPACE::Anyone; + + DBG(F("OK, now make sure you an rtpMIDI session that is Enabled")); + DBG(F("Add device named Arduino with Host"), Ethernet.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); + DBG(F("Select and then press the Connect button")); + DBG(F("Then open a MIDI listener and monitor incoming notes")); + + MIDI.begin(); + + // Stay informed on connection status + AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { + isConnected = true; + DBG(F("Connected to session"), name); + }); + AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { + isConnected = false; + DBG(F("Disconnected")); + }); + + MIDI.setHandleNoteOn([](byte channel, byte note, byte velocity) { + DBG(F("NoteOn"), note); + }); + MIDI.setHandleNoteOff([](byte channel, byte note, byte velocity) { + DBG(F("NoteOff"), note); + }); + + DBG(F("Sending MIDI messages every second")); +} + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +void loop() +{ + // Listen to incoming notes + MIDI.read(); + + // send a note every second + // (dont cáll delay(1000) as it will stall the pipeline) + if (isConnected && (millis() - t1) > 1000) + { + t1 = millis(); + + byte note = random(1, 127); + byte velocity = 55; + byte channel = 1; + + MIDI.sendNoteOn(note, velocity, channel); + // MIDI.sendNoteOff(note, velocity, channel); + } +} diff --git a/examples/ESP32_Callbacks/ESP32_Callbacks.ino b/examples/ESP32_Callbacks/ESP32_Callbacks.ino deleted file mode 100644 index 6245bdf..0000000 --- a/examples/ESP32_Callbacks/ESP32_Callbacks.ino +++ /dev/null @@ -1,207 +0,0 @@ -#include -#include - -#define LATENCY_CALCULATION -#define USE_EXT_CALLBACKS -#define SerialMon Serial -#define APPLEMIDI_DEBUG SerialMon -#include - -#include "arduino_secrets.h" // contains SECRET_SSID and SECRET_PASS - -bool isConnected = false; - -APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); - -void setup() { - DBG_SETUP(115200); - DBG("Booting"); - - WiFi.begin(SECRET_SSID, SECRET_PASS); - while (WiFi.status() != WL_CONNECTED) { - delay(1000); - DBG("Establishing connection to WiFi.."); - } - DBG("Connected to network"); - - MDNS.begin(AppleMIDI.getName()); - - DBG(F("OK, now make sure you an rtpMIDI session that is Enabled")); - DBG(F("Add device named Arduino with Host"), WiFi.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); - DBG(F("Select and then press the Connect button")); - DBG(F("Then open a MIDI listener and monitor incoming notes")); - - AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { - isConnected = true; - DBG(F("Connected to session"), name); - }); - AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { - isConnected = false; - DBG(F("Disconnected")); - }); - - AppleMIDI.setHandleSendRtp([](const APPLEMIDI_NAMESPACE::Rtp_t& rtp) { - DBG(F("setHandleSendRtp"), rtp.sequenceNr); - }); - AppleMIDI.setHandleReceivedRtp([](const APPLEMIDI_NAMESPACE::Rtp_t& rtp, const int32_t& latency) { - DBG(F("setHandleReceivedRtp"), rtp.sequenceNr ,latency); - }); - AppleMIDI.setHandleStartReceivedMidi([](const APPLEMIDI_NAMESPACE::ssrc_t&) { - DBG(F("setHandleStartReceivedMidi")); - }); - AppleMIDI.setHandleReceivedMidi([](const APPLEMIDI_NAMESPACE::ssrc_t&, byte value) { - DBG(F("setHandleReceivedMidi"), value); - }); - AppleMIDI.setHandleEndReceivedMidi([](const APPLEMIDI_NAMESPACE::ssrc_t&) { - DBG(F("setHandleEndReceivedMidi")); - }); - - AppleMIDI.setHandleException(OnAppleMidiException); - - MIDI.begin(); - - MIDI.setHandleNoteOff(OnMidiNoteOff); - MIDI.setHandleNoteOn(OnMidiNoteOn); - MIDI.setHandleAfterTouchPoly(OnAfterTouchPoly); - MIDI.setHandleControlChange(OnControlChange); - MIDI.setHandleProgramChange(OnProgramChange); - MIDI.setHandleAfterTouchChannel(OnAfterTouchChannel); - MIDI.setHandlePitchBend(OnPitchBend); - MIDI.setHandleSystemExclusive(OnSystemExclusive); - MIDI.setHandleTimeCodeQuarterFrame(OnTimeCodeQuarterFrame); - MIDI.setHandleSongPosition(OnSongPosition); - MIDI.setHandleSongSelect(OnSongSelect); - MIDI.setHandleTuneRequest(OnTuneRequest); - MIDI.setHandleClock(OnClock); - MIDI.setHandleStart(OnStart); - MIDI.setHandleContinue(OnContinue); - MIDI.setHandleStop(OnStop); - MIDI.setHandleActiveSensing(OnActiveSensing); - MIDI.setHandleSystemReset(OnSystemReset); - - MDNS.addService("apple-midi", "udp", AppleMIDI.getPort()); - - DBG(F("Ready")); -} - -void loop() { - MIDI.read(); -} - -// ----------------------------------------------------------------------------- -// -// ----------------------------------------------------------------------------- -void OnAppleMidiException(const APPLEMIDI_NAMESPACE::ssrc_t& ssrc, const APPLEMIDI_NAMESPACE::Exception& e, const int32_t value ) { - switch (e) - { - case APPLEMIDI_NAMESPACE::Exception::BufferFullException: - DBG(F("*** BufferFullException")); - break; - case APPLEMIDI_NAMESPACE::Exception::ParseException: - DBG(F("*** ParseException")); - break; - case APPLEMIDI_NAMESPACE::Exception::TooManyParticipantsException: - DBG(F("*** TooManyParticipantsException")); - break; - case APPLEMIDI_NAMESPACE::Exception::UnexpectedInviteException: - DBG(F("*** UnexpectedInviteException")); - break; - case APPLEMIDI_NAMESPACE::Exception::ParticipantNotFoundException: - DBG(F("*** ParticipantNotFoundException"), value); - break; - case APPLEMIDI_NAMESPACE::Exception::ListenerTimeOutException: - DBG(F("*** ListenerTimeOutException")); - break; - case APPLEMIDI_NAMESPACE::Exception::MaxAttemptsException: - DBG(F("*** MaxAttemptsException")); - break; - case APPLEMIDI_NAMESPACE::Exception::NoResponseFromConnectionRequestException: - DBG(F("***:yyy did't respond to the connection request. Check the address and port, and any firewall or router settings. (time)")); - break; - case APPLEMIDI_NAMESPACE::Exception::SendPacketsDropped: - DBG(F("*** SendPacketsDropped"), value); - break; - case APPLEMIDI_NAMESPACE::Exception::ReceivedPacketsDropped: - DBG(F("*** ReceivedPacketsDropped"), value); - break; - } -} - -//------ - -static void OnMidiNoteOff(byte channel, byte note, byte velocity) { - DBG(F("in\tNote off"), note, " Velocity", velocity, "\t", channel); -} - -static void OnMidiNoteOn(byte channel, byte note, byte velocity) { - DBG(F("in\tNote on"), note, " Velocity", velocity, "\t", channel); -} - -static void OnAfterTouchPoly(byte channel, byte note, byte velocity) { - DBG(F("AfterTouchPoly. Channel:"), channel, " Note:", note, " Velocity:", velocity); -} - -static void OnControlChange(byte channel, byte note, byte velocity) { - DBG(F("ControlChange. Channel:"), channel, " Note:", note, " Velocity:", velocity); -} - -static void OnProgramChange(byte channel, byte note) { - DBG(F("ProgramChange. Channel:"), channel, " Note:", note); -} - -static void OnAfterTouchChannel(byte channel, byte note) { - DBG(F("AfterTouchChannel. Channel:"), channel, " Note:", note); -} - -static void OnPitchBend(byte channel, int note) { - DBG(F("PitchBend. Channel:"), channel, " Note:", note); -} - -static void OnSystemExclusive(byte* data, unsigned size) { - DBG(F("System exclusive")); - for (int i = 0; i < size; i++) { - SerialMon.print(F(" 0x")); - SerialMon.print(data[i], HEX); - } - SerialMon.println(); -} - -static void OnTimeCodeQuarterFrame(byte data) { - DBG(F("TimeCodeQuarterFrame")); -} - -static void OnSongPosition(unsigned beats) { - DBG(F("SongPosition:"), beats); -} - -static void OnSongSelect(byte songNumber) { - DBG(F("SongSelect"), songNumber); -} - -static void OnTuneRequest() { - DBG(F("Tune request")); -} - -static void OnClock() { - DBG(F("Clock")); -} - -static void OnStart() { - DBG(F("Start")); -} - -static void OnContinue() { - DBG(F("Continue")); -} - -static void OnStop() { - DBG(F("Stop")); -} - -static void OnActiveSensing() { - DBG(F("ActiveSensing")); -} - -static void OnSystemReset() { - DBG(F("SystemReset")); -} diff --git a/src/AppleMIDI.h b/src/AppleMIDI.h index 95826be..6556c6e 100644 --- a/src/AppleMIDI.h +++ b/src/AppleMIDI.h @@ -85,6 +85,11 @@ class AppleMIDISession // Override default thruActivated static const bool thruActivated = false; +#ifdef USE_DIRECTORY + Deque directory; + WhoCanConnectToMe whoCanConnectToMe = Anyone; +#endif + void begin() { _appleMIDIParser.session = this; @@ -250,15 +255,11 @@ class AppleMIDISession ssrc_t ssrc = 0; uint16_t port = DEFAULT_CONTROL_PORT; - WhoCanConnectToMe whoCanConnectToMe = Anyone; #ifdef ONE_PARTICIPANT Participant participant; #else Deque, Settings::MaxNumberOfParticipants> participants; #endif -#ifdef USE_DIRECTORY - Deque directory; -#endif #ifdef KEEP_SESSION_NAME char localName[DefaultSettings::MaxSessionNameLen + 1]; @@ -291,7 +292,7 @@ class AppleMIDISession void EndReceivedMidi(); // Helpers - void writeInvitation (UdpClass &, IPAddress, uint16_t, AppleMIDI_Invitation_t &, const byte *command); + void writeInvitation (UdpClass &, const IPAddress &, const uint16_t &, AppleMIDI_Invitation_t &, const byte *command); void writeReceiverFeedback(const IPAddress &, const uint16_t &, AppleMIDI_ReceiverFeedback_t &); void writeSynchronization (const IPAddress &, const uint16_t &, AppleMIDI_Synchronization_t &); void writeEndSession (const IPAddress &, const uint16_t &, AppleMIDI_EndSession_t &); @@ -312,8 +313,11 @@ class AppleMIDISession void sendSynchronization(Participant*); #ifndef ONE_PARTICIPANT - Participant* getParticipantBySSRC(const ssrc_t ssrc); - Participant* getParticipantByInitiatorToken(const uint32_t initiatorToken); + Participant* getParticipantBySSRC(const ssrc_t&); + Participant* getParticipantByInitiatorToken(const uint32_t& initiatorToken); +#endif +#ifdef USE_DIRECTORY + bool IsComputerInDirectory(const IPAddress&); #endif }; diff --git a/src/AppleMIDI.hpp b/src/AppleMIDI.hpp index b3b9ea2..42e2bfd 100644 --- a/src/AppleMIDI.hpp +++ b/src/AppleMIDI.hpp @@ -102,6 +102,32 @@ void AppleMIDISession::ReceivedInvitation(AppleMID template void AppleMIDISession::ReceivedControlInvitation(AppleMIDI_Invitation_t &invitation) { +#ifdef KEEP_SESSION_NAME + strncpy(invitation.sessionName, localName, DefaultSettings::MaxSessionNameLen); + invitation.sessionName[DefaultSettings::MaxSessionNameLen] = '\0'; +#endif + +#ifdef USE_DIRECTORY + switch (whoCanConnectToMe) { + case None: + writeInvitation(controlPort, controlPort.remoteIP(), controlPort.remotePort(), invitation, amInvitationRejected); +#ifdef USE_EXT_CALLBACKS + if (nullptr != _exceptionCallback) + _exceptionCallback(ssrc, NotAcceptingAnyone, 0); +#endif + return; + case OnlyComputersInMyDirectory: + if (!IsComputerInDirectory(controlPort.remoteIP())) { + writeInvitation(controlPort, controlPort.remoteIP(), controlPort.remotePort(), invitation, amInvitationRejected); +#ifdef USE_EXT_CALLBACKS + if (nullptr != _exceptionCallback) + _exceptionCallback(ssrc, ComputerNotInDirectory, 0); +#endif + return; + } + } +#endif + // ignore invitation of a participant already in the participant list #ifndef ONE_PARTICIPANT if (nullptr != getParticipantBySSRC(invitation.ssrc)) @@ -109,20 +135,14 @@ void AppleMIDISession::ReceivedControlInvitation(A if (participant.ssrc == invitation.ssrc) #endif return; - -#ifdef KEEP_SESSION_NAME - strncpy(invitation.sessionName, localName, DefaultSettings::MaxSessionNameLen); - invitation.sessionName[DefaultSettings::MaxSessionNameLen] = '\0'; -#endif - + #ifndef ONE_PARTICIPANT if (participants.full()) #else if (participant.ssrc != 0) #endif { - writeInvitation(controlPort, controlPort.remoteIP(), controlPort.remotePort(), invitation, amInvitationRejected); - + writeInvitation(controlPort, controlPort.remoteIP(), controlPort.remotePort(), invitation, amInvitationRejected); #ifdef USE_EXT_CALLBACKS if (nullptr != _exceptionCallback) _exceptionCallback(ssrc, TooManyParticipantsException, 0); @@ -423,9 +443,20 @@ void AppleMIDISession::ReceivedEndSession(AppleMID } } +#ifdef USE_DIRECTORY +template +bool AppleMIDISession::IsComputerInDirectory(const IPAddress& remoteIP) +{ + for (size_t i = 0; i < directory.size(); i++) + if (remoteIP == directory[i]) + return true; + return false; +} +#endif + #ifndef ONE_PARTICIPANT template -Participant* AppleMIDISession::getParticipantBySSRC(const ssrc_t ssrc) +Participant* AppleMIDISession::getParticipantBySSRC(const ssrc_t& ssrc) { for (size_t i = 0; i < participants.size(); i++) if (ssrc == participants[i].ssrc) @@ -434,7 +465,7 @@ Participant* AppleMIDISession::getPartic } template -Participant* AppleMIDISession::getParticipantByInitiatorToken(const uint32_t initiatorToken) +Participant* AppleMIDISession::getParticipantByInitiatorToken(const uint32_t& initiatorToken) { for (auto i = 0; i < participants.size(); i++) if (initiatorToken == participants[i].initiatorToken) @@ -444,7 +475,7 @@ Participant* AppleMIDISession::getPartic #endif template -void AppleMIDISession::writeInvitation(UdpClass &port, IPAddress remoteIP, uint16_t remotePort, AppleMIDI_Invitation_t & invitation, const byte *command) +void AppleMIDISession::writeInvitation(UdpClass &port, const IPAddress& remoteIP, const uint16_t& remotePort, AppleMIDI_Invitation_t & invitation, const byte *command) { if (port.beginPacket(remoteIP, remotePort)) { diff --git a/src/AppleMIDI_Defs.h b/src/AppleMIDI_Defs.h index b43db88..faa6087 100644 --- a/src/AppleMIDI_Defs.h +++ b/src/AppleMIDI_Defs.h @@ -40,10 +40,9 @@ typedef const char* AppleMIDIConstStr; #define RtpBuffer_t Deque #define MidiBuffer_t Deque -// Add extended callbacks to enabling these #defines -// #define LATENCY_CALCULATION // #define USE_EXT_CALLBACKS -// #define ONE_PARTICIPANT // TODO +// #define LATENCY_CALCULATION // only usefull when declaring USE_EXT_CALLBACKS +// #define ONE_PARTICIPANT // memory optimization // #define USE_DIRECTORY // By defining NO_SESSION_NAME in the sketch, you can save 100 bytes @@ -58,12 +57,14 @@ typedef const char* AppleMIDIConstStr; struct Rtp; typedef Rtp Rtp_t; +#ifdef USE_DIRECTORY enum WhoCanConnectToMe : uint8_t { None, OnlyComputersInMyDirectory, Anyone, }; +#endif // from: https://en.wikipedia.org/wiki/RTP-MIDI // Apple decided to create their own protocol, imposing all parameters related to @@ -107,6 +108,8 @@ enum Exception : uint8_t ParseException, UnexpectedParseException, TooManyParticipantsException, + ComputerNotInDirectory, + NotAcceptingAnyone, UnexpectedInviteException, ParticipantNotFoundException, ListenerTimeOutException, diff --git a/src/AppleMIDI_Settings.h b/src/AppleMIDI_Settings.h index 346c188..31bc41a 100644 --- a/src/AppleMIDI_Settings.h +++ b/src/AppleMIDI_Settings.h @@ -14,7 +14,7 @@ struct DefaultSettings static const uint8_t MaxNumberOfParticipants = 2; - static const uint8_t MaxNumberOfComputersInDirectory = 2; + static const uint8_t MaxNumberOfComputersInDirectory = 5; // The recovery journal mechanism requires that the receiver periodically // inform the sender of the sequence number of the most recently received packet. From b4a0b24e0f002fc86a2355042a8c67f646028abf Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Thu, 24 Dec 2020 14:50:13 +0100 Subject: [PATCH 084/271] joined USE_EXT_CALLBACKS, LATENCY_CALCULATION --- README.md | 3 +-- examples/AVR_Callbacks/AVR_Callbacks.ino | 1 - src/AppleMIDI.hpp | 15 +++++++-------- src/AppleMIDI_Defs.h | 1 - src/AppleMIDI_Participant.h | 2 +- src/rtpMIDI_Parser_JournalSection.hpp | 2 +- 6 files changed, 10 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index c7781a3..f1651a0 100755 --- a/README.md +++ b/README.md @@ -65,8 +65,7 @@ More usages in the [examples](https://github.com/lathoub/Arduino-AppleMIDI-Libra * Teensy WIZ820io W5200 ## Memory usage -Out of the box, this library has been setup to use a minimum amount of memory. Extended callbacks are not enabled by default, and can be anabled by USE_EXT_CALLBACKS (and -LATENCY_CALCULATION). See the callback examamples. +Out of the box, this library has been setup to use a minimum amount of memory. Extended callbacks are not enabled by default, and can be anabled by USE_EXT_CALLBACKS. See the callback examamples. This library is not using any dynamic memory allocation methods - all buffers have a fixed size, set in the `AppleMIDI_Settings.h` file, avoiding potential memory leaks and memory fragmentation. diff --git a/examples/AVR_Callbacks/AVR_Callbacks.ino b/examples/AVR_Callbacks/AVR_Callbacks.ino index bf76501..7b728bf 100644 --- a/examples/AVR_Callbacks/AVR_Callbacks.ino +++ b/examples/AVR_Callbacks/AVR_Callbacks.ino @@ -1,6 +1,5 @@ #include -#define LATENCY_CALCULATION #define USE_EXT_CALLBACKS #define SerialMon Serial #define APPLEMIDI_DEBUG SerialMon diff --git a/src/AppleMIDI.hpp b/src/AppleMIDI.hpp index 42e2bfd..d6ceb79 100644 --- a/src/AppleMIDI.hpp +++ b/src/AppleMIDI.hpp @@ -125,6 +125,8 @@ void AppleMIDISession::ReceivedControlInvitation(A #endif return; } + case Anyone: + break; } #endif @@ -371,7 +373,7 @@ void AppleMIDISession::ReceivedSynchronization(App break; case SYNC_CK2: /* From session APPLEMIDI_INITIATOR */ -#ifdef LATENCY_CALCULATION +#ifdef USE_EXT_CALLBACKS // each party can estimate the offset between the two clocks using the following formula pParticipant->offsetEstimate = (uint32_t)(((synchronization.timestamps[2] + synchronization.timestamps[0]) / 2) - synchronization.timestamps[1]); #endif @@ -445,7 +447,7 @@ void AppleMIDISession::ReceivedEndSession(AppleMID #ifdef USE_DIRECTORY template -bool AppleMIDISession::IsComputerInDirectory(const IPAddress& remoteIP) +bool AppleMIDISession::IsComputerInDirectory(IPAddress remoteIP) const { for (size_t i = 0; i < directory.size(); i++) if (remoteIP == directory[i]) @@ -890,7 +892,7 @@ template void AppleMIDISession::manageReceiverFeedback() { #ifndef ONE_PARTICIPANT - for (auto i = 0; i < participants.size(); i++) + for (uint8_t i = 0; i < participants.size(); i++) #endif { #ifndef ONE_PARTICIPANT @@ -1002,13 +1004,10 @@ void AppleMIDISession::ReceivedRtp(const Rtp_t& rt pParticipant->receiverFeedbackStartTime = now; pParticipant->doReceiverFeedback = true; -#ifdef LATENCY_CALCULATION - auto offset = (rtp.timestamp - participant->offsetEstimate); +#ifdef USE_EXT_CALLBACKS + auto offset = (rtp.timestamp - pParticipant->offsetEstimate); auto latency = (int32_t)(rtpMidiClock.Now() - offset); -#else - auto latency = 0; #endif - if (pParticipant->receiveSequenceNr + 1 != rtp.sequenceNr) { #ifdef USE_EXT_CALLBACKS diff --git a/src/AppleMIDI_Defs.h b/src/AppleMIDI_Defs.h index faa6087..ba99a4c 100644 --- a/src/AppleMIDI_Defs.h +++ b/src/AppleMIDI_Defs.h @@ -41,7 +41,6 @@ typedef const char* AppleMIDIConstStr; #define MidiBuffer_t Deque // #define USE_EXT_CALLBACKS -// #define LATENCY_CALCULATION // only usefull when declaring USE_EXT_CALLBACKS // #define ONE_PARTICIPANT // memory optimization // #define USE_DIRECTORY diff --git a/src/AppleMIDI_Participant.h b/src/AppleMIDI_Participant.h index e0ba1a5..28dcfcf 100644 --- a/src/AppleMIDI_Participant.h +++ b/src/AppleMIDI_Participant.h @@ -32,7 +32,7 @@ struct Participant bool synchronizing = false; #endif -#ifdef LATENCY_CALCULATION +#ifdef USE_EXT_CALLBACKS uint32_t offsetEstimate; #endif diff --git a/src/rtpMIDI_Parser_JournalSection.hpp b/src/rtpMIDI_Parser_JournalSection.hpp index 41b0def..1606224 100644 --- a/src/rtpMIDI_Parser_JournalSection.hpp +++ b/src/rtpMIDI_Parser_JournalSection.hpp @@ -48,7 +48,7 @@ parserReturn decodeJournalSection(RtpBuffer_t &buffer) // stream (modulo 2^16). cb.buffer[0] = buffer[i++]; cb.buffer[1] = buffer[i++]; - uint16_t checkPoint = ntohs(cb.value16); // unused + // uint16_t checkPoint = ntohs(cb.value16); ; // unused // (RFC 4695, 5 Recovery Journal Format) // If A and Y are both zero, the recovery journal only contains its 3- From 68c9082a89ab7b20f84cc89905bff0dde8d97e2a Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Thu, 24 Dec 2020 14:50:45 +0100 Subject: [PATCH 085/271] Update AppleMIDI.h cast INADDR_NONE to avoid compilation errors --- src/AppleMIDI.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/AppleMIDI.h b/src/AppleMIDI.h index 6556c6e..4ea6d82 100644 --- a/src/AppleMIDI.h +++ b/src/AppleMIDI.h @@ -143,9 +143,9 @@ class AppleMIDISession // length of the buffer). So we'll copy to a buffer in the 'write' method, // and actually serialize for real in the endTransmission method #ifndef ONE_PARTICIPANT - return (dataPort.remoteIP() != INADDR_NONE && participants.size() > 0); + return (dataPort.remoteIP() != (IPAddress)INADDR_NONE && participants.size() > 0); #else - return (dataPort.remoteIP() != INADDR_NONE && participant.ssrc != 0); + return (dataPort.remoteIP() != (IPAddress)INADDR_NONE && participant.ssrc != 0); #endif }; @@ -317,7 +317,7 @@ class AppleMIDISession Participant* getParticipantByInitiatorToken(const uint32_t& initiatorToken); #endif #ifdef USE_DIRECTORY - bool IsComputerInDirectory(const IPAddress&); + bool IsComputerInDirectory(IPAddress) const; #endif }; From 88850b3e0ad9fa2468f6fde2bde20c883366f335 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Mon, 28 Dec 2020 11:16:56 +0100 Subject: [PATCH 086/271] fixed crash when session name is too long (> MaxSessionName) --- src/AppleMIDI_Parser.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/AppleMIDI_Parser.h b/src/AppleMIDI_Parser.h index 74fbe8d..6c4dd8a 100644 --- a/src/AppleMIDI_Parser.h +++ b/src/AppleMIDI_Parser.h @@ -80,7 +80,7 @@ class AppleMIDIParser uint16_t bi = 0; while ((i < buffer.size()) && (buffer[i] != 0x00)) { - if (bi <= DefaultSettings::MaxSessionNameLen) + if (bi < DefaultSettings::MaxSessionNameLen) invitation.sessionName[bi++] = buffer[i]; i++; } @@ -269,7 +269,7 @@ class AppleMIDIParser uint16_t bi = 0; while ((i < buffer.size()) && (buffer[i] != 0x00)) { - if (bi <= DefaultSettings::MaxSessionNameLen) + if (bi < DefaultSettings::MaxSessionNameLen) invitationAccepted.sessionName[bi++] = buffer[i]; i++; } @@ -331,7 +331,7 @@ class AppleMIDIParser uint16_t bi = 0; while ((i < buffer.size()) && (buffer[i] != 0x00)) { - if (bi <= DefaultSettings::MaxSessionNameLen) + if (bi < DefaultSettings::MaxSessionNameLen) invitationRejected.sessionName[bi++] = buffer[i]; i++; } From 095e6d402ef517a7b104c61539f4ebc0e1cf0af4 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Mon, 28 Dec 2020 11:18:41 +0100 Subject: [PATCH 087/271] Create ESP32_NoteOnOffEverySec.ino --- .../ESP32_NoteOnOffEverySec.ino | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 examples/ESP32_NoteOnOffEverySec/ESP32_NoteOnOffEverySec.ino diff --git a/examples/ESP32_NoteOnOffEverySec/ESP32_NoteOnOffEverySec.ino b/examples/ESP32_NoteOnOffEverySec/ESP32_NoteOnOffEverySec.ino new file mode 100644 index 0000000..0368967 --- /dev/null +++ b/examples/ESP32_NoteOnOffEverySec/ESP32_NoteOnOffEverySec.ino @@ -0,0 +1,82 @@ +#include +#include +#include + +#define NO_SESSION_NAME +#define SerialMon Serial +#define APPLEMIDI_DEBUG SerialMon +#include + +char ssid[] = "ssid"; // your network SSID (name) +char pass[] = "password"; // your network password (use for WPA, or use as key for WEP) + +unsigned long t0 = millis(); +bool isConnected = false; + +APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +void setup() +{ + DBG_SETUP(115200); + DBG("Booting"); + + WiFi.begin(ssid, pass); + + while (WiFi.status() != WL_CONNECTED) { + delay(500); + DBG("Establishing connection to WiFi.."); + } + DBG("Connected to network"); + + DBG(F("OK, now make sure you an rtpMIDI session that is Enabled")); + DBG(F("Add device named Arduino with Host"), WiFi.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); + DBG(F("Select and then press the Connect button")); + DBG(F("Then open a MIDI listener and monitor incoming notes")); + DBG(F("Listen to incoming MIDI commands")); + + MIDI.begin(); + + AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { + isConnected = true; + DBG(F("Connected to session"), name); + }); + AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { + isConnected = false; + DBG(F("Disconnected")); + }); + + MIDI.setHandleNoteOn([](byte channel, byte note, byte velocity) { + DBG(F("NoteOn"), note); + }); + MIDI.setHandleNoteOff([](byte channel, byte note, byte velocity) { + DBG(F("NoteOff"), note); + }); + + DBG(F("Sending NoteOn/Off of note 45, every second")); +} + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +void loop() +{ + // Listen to incoming notes + MIDI.read(); + + // send a note every second + // (dont cáll delay(1000) as it will stall the pipeline) + if (isConnected && (millis() - t0) > 1000) + { + t0 = millis(); + + byte note = 45; + byte velocity = 55; + byte channel = 1; + + MIDI.sendNoteOn(note, velocity, channel); + MIDI.sendNoteOff(note, velocity, channel); + } +} From 2f6d510ce8ace7d2a3deb7a326235e2895fffd83 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Mon, 28 Dec 2020 11:19:11 +0100 Subject: [PATCH 088/271] get* as const functions --- src/AppleMIDI.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/AppleMIDI.h b/src/AppleMIDI.h index 4ea6d82..82d0edf 100644 --- a/src/AppleMIDI.h +++ b/src/AppleMIDI.h @@ -67,14 +67,14 @@ class AppleMIDISession #endif #ifdef KEEP_SESSION_NAME - const char* getName() { return this->localName; }; + const char* getName() const { return this->localName; }; void setName(const char *sessionName) { strncpy(this->localName, sessionName, DefaultSettings::MaxSessionNameLen); }; #else - const char* getName() { return nullptr; }; + const char* getName() const { return nullptr; }; void setName(const char *sessionName) { }; #endif - const uint16_t getPort() { return this->port; }; - const ssrc_t getSynchronizationSource() { return this->ssrc; }; + const uint16_t getPort() const { return this->port; }; + const ssrc_t getSynchronizationSource() const { return this->ssrc; }; #ifdef APPLEMIDI_INITIATOR bool sendInvite(IPAddress ip, uint16_t port = DEFAULT_CONTROL_PORT); From 613b7672f992a71c4faebe3a385733650850f254 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Mon, 28 Dec 2020 11:39:01 +0100 Subject: [PATCH 089/271] Update README.md --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f1651a0..127d277 100755 --- a/README.md +++ b/README.md @@ -78,7 +78,10 @@ Reduce the memory footprint by a further 500 bytes by `#define NO_SESSION_NAME` Even further reduce the memory footprint by `#define ONE_PARTICIPANT` limiting the number of particpants to just 1. On an UNO the absolute minimum memory footprint is 21976 bytes (68%) and 946 global variables (46%). For a Leonardo that is 24916 bytes (86%) and 1112 bytes (43%) of global variables. - + +## Notes +Session names can get really long on Macs (eg 'Macbook Pro of Johann Gambolputty de von Ausfern-schplenden-schlitter-crasscrenbon-fried-digger-dingle-dangle-dongle-dungle-burstein-von-knacker-thrasher-apple-banger-horowitz-ticolensic-grander-knotty-spelltinkle-grandlich-grumblemeyer-spelterwasser-kurstlich-himbleeisen-bahnwagen-gutenabend-bitte-ein-nürnburger-bratwustle-gerspurten-mitzweimache-luber-hundsfut-gumberaber-shönendanker-kalbsfleisch-mittler-aucher von Hautkopft of Ulm') and will be trunctated to the `MaxSessionNameLen` (as set in the settings file). + ## Arduino IDE (arduino.cc) * 1.8.13 From 4526bfbbdd5885ee3a22992b530b40a238b1f60d Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Mon, 28 Dec 2020 13:59:20 +0100 Subject: [PATCH 090/271] Update AppleMIDI.h --- src/AppleMIDI.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/AppleMIDI.h b/src/AppleMIDI.h index 82d0edf..786836f 100644 --- a/src/AppleMIDI.h +++ b/src/AppleMIDI.h @@ -55,15 +55,15 @@ class AppleMIDISession #endif }; - void setHandleConnected(void (*fptr)(const ssrc_t&, const char*)) { _connectedCallback = fptr; } - void setHandleDisconnected(void (*fptr)(const ssrc_t&)) { _disconnectedCallback = fptr; } + void setHandleConnected (void (*fptr)(const ssrc_t&, const char*)) { _connectedCallback = fptr; } + void setHandleDisconnected (void (*fptr)(const ssrc_t&)) { _disconnectedCallback = fptr; } #ifdef USE_EXT_CALLBACKS - void setHandleException(void (*fptr)(const ssrc_t&, const Exception&, const int32_t value)) { _exceptionCallback = fptr; } - void setHandleReceivedRtp(void (*fptr)(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; } - void setHandleEndReceivedMidi(void (*fptr)(const ssrc_t&)) { _endReceivedMidiByteCallback = fptr; } - void setHandleSendRtp(void (*fptr)(const Rtp_t&)) { _sendRtpCallback = fptr; } + void setHandleException (void (*fptr)(const ssrc_t&, const Exception&, const int32_t value)) { _exceptionCallback = fptr; } + void setHandleReceivedRtp (void (*fptr)(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; } + void setHandleEndReceivedMidi (void (*fptr)(const ssrc_t&)) { _endReceivedMidiByteCallback = fptr; } + void setHandleSendRtp (void (*fptr)(const Rtp_t&)) { _sendRtpCallback = fptr; } #endif #ifdef KEEP_SESSION_NAME @@ -82,7 +82,7 @@ class AppleMIDISession void sendEndSession(); public: - // Override default thruActivated + // Override default thruActivated. Must be false for all packet based messages static const bool thruActivated = false; #ifdef USE_DIRECTORY From 93039452dd3a4f925613bd565a0a0b06f8ddb679 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Mon, 28 Dec 2020 13:59:41 +0100 Subject: [PATCH 091/271] removed extented callback from wESP32 demo --- .../wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino | 4 ---- 1 file changed, 4 deletions(-) diff --git a/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino b/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino index 052bec4..7285659 100644 --- a/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino +++ b/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino @@ -1,4 +1,3 @@ -#define USE_EXT_CALLBACKS #define SerialMon Serial #define APPLEMIDI_DEBUG SerialMon #include @@ -39,9 +38,6 @@ void setup() isConnected = false; DBG(F("Disconnected")); }); - AppleMIDI.setHandleException([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const APPLEMIDI_NAMESPACE::Exception & e, const int32_t value) { - DBG(F("______________Exception"), e, value); - }); MIDI.setHandleNoteOn([](byte channel, byte note, byte velocity) { DBG(F("NoteOn"), note); From 49e5121fdf62f478d7fc92354f88cface1fb879d Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Mon, 28 Dec 2020 15:48:35 +0100 Subject: [PATCH 092/271] added sentRtpMidiCallback, renamed send -> sent --- examples/AVR_Callbacks/AVR_Callbacks.ino | 28 ++++++++++++++---------- src/AppleMIDI.h | 6 +++-- src/AppleMIDI.hpp | 11 +++++++--- src/AppleMIDI_Defs.h | 6 ++++- 4 files changed, 33 insertions(+), 18 deletions(-) diff --git a/examples/AVR_Callbacks/AVR_Callbacks.ino b/examples/AVR_Callbacks/AVR_Callbacks.ino index 7b728bf..b6fd907 100644 --- a/examples/AVR_Callbacks/AVR_Callbacks.ino +++ b/examples/AVR_Callbacks/AVR_Callbacks.ino @@ -22,7 +22,7 @@ APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); void setup() { DBG_SETUP(115200); - DBG("Booting"); + DBG("Das Booting"); if (Ethernet.begin(mac) == 0) { DBG(F("Failed DHCP, check network cable & reboot")); @@ -36,6 +36,7 @@ void setup() MIDI.begin(); + // Normal callbacks - always available // Stay informed on connection status AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { isConnected = true; @@ -45,23 +46,26 @@ void setup() isConnected = false; DBG(F("Disconnected")); }); - - AppleMIDI.setHandleSendRtp([](const APPLEMIDI_NAMESPACE::Rtp_t & rtp) { - DBG(F("setHandleSendRtp"), rtp.sequenceNr); + + // Extended callback, only available when defining USE_EXT_CALLBACKS + AppleMIDI.setHandleSentRtp([](const APPLEMIDI_NAMESPACE::Rtp_t & rtp) { + DBG(F("an rtpMessage has been sent with sequenceNr"), rtp.sequenceNr); + }); + AppleMIDI.setHandleSentRtpMidi([](const APPLEMIDI_NAMESPACE::RtpMIDI_t& rtpMidi) { + DBG(F("an rtpMidiMessage has been sent"), rtpMidi.flags); }); AppleMIDI.setHandleReceivedRtp([](const APPLEMIDI_NAMESPACE::Rtp_t & rtp, const int32_t& latency) { - DBG(F("setHandleReceivedRtp"), rtp.sequenceNr , latency); + DBG(F("setHandleReceivedRtp"), rtp.sequenceNr , "with", latency, "ms latency"); }); - AppleMIDI.setHandleStartReceivedMidi([](const APPLEMIDI_NAMESPACE::ssrc_t&) { - DBG(F("setHandleStartReceivedMidi")); + AppleMIDI.setHandleStartReceivedMidi([](const APPLEMIDI_NAMESPACE::ssrc_t& ssrc) { + DBG(F("setHandleStartReceivedMidi from SSRC"), ssrc); }); - AppleMIDI.setHandleReceivedMidi([](const APPLEMIDI_NAMESPACE::ssrc_t&, byte value) { - DBG(F("setHandleReceivedMidi"), value); + AppleMIDI.setHandleReceivedMidi([](const APPLEMIDI_NAMESPACE::ssrc_t& ssrc, byte value) { + DBG(F("setHandleReceivedMidi from SSRC"), ssrc, ", value:", value); }); - AppleMIDI.setHandleEndReceivedMidi([](const APPLEMIDI_NAMESPACE::ssrc_t&) { - DBG(F("setHandleEndReceivedMidi")); + AppleMIDI.setHandleEndReceivedMidi([](const APPLEMIDI_NAMESPACE::ssrc_t& ssrc) { + DBG(F("setHandleEndReceivedMidi from SSRC"), ssrc); }); - AppleMIDI.setHandleException(OnAppleMidiException); MIDI.setHandleNoteOn([](byte channel, byte note, byte velocity) { diff --git a/src/AppleMIDI.h b/src/AppleMIDI.h index 786836f..133288e 100644 --- a/src/AppleMIDI.h +++ b/src/AppleMIDI.h @@ -63,7 +63,8 @@ class AppleMIDISession void setHandleStartReceivedMidi (void (*fptr)(const ssrc_t&)) { _startReceivedMidiByteCallback = fptr; } void setHandleReceivedMidi (void (*fptr)(const ssrc_t&, byte)) { _receivedMidiByteCallback = fptr; } void setHandleEndReceivedMidi (void (*fptr)(const ssrc_t&)) { _endReceivedMidiByteCallback = fptr; } - void setHandleSendRtp (void (*fptr)(const Rtp_t&)) { _sendRtpCallback = fptr; } + void setHandleSentRtp (void (*fptr)(const Rtp_t&)) { _sentRtpCallback = fptr; } + void setHandleSentRtpMidi (void (*fptr)(const RtpMIDI_t&)) { _sentRtpMidiCallback = fptr; } #endif #ifdef KEEP_SESSION_NAME @@ -244,7 +245,8 @@ class AppleMIDISession receivedMidiByteCallback _receivedMidiByteCallback = nullptr; endReceivedMidiByteCallback _endReceivedMidiByteCallback = nullptr; receivedRtpCallback _receivedRtpCallback = nullptr; - sendRtpCallback _sendRtpCallback = nullptr; + sentRtpCallback _sentRtpCallback = nullptr; + sentRtpMidiCallback _sentRtpMidiCallback = nullptr; exceptionCallback _exceptionCallback = nullptr; #endif // buffer for incoming and outgoing MIDI messages diff --git a/src/AppleMIDI.hpp b/src/AppleMIDI.hpp index d6ceb79..5b03834 100644 --- a/src/AppleMIDI.hpp +++ b/src/AppleMIDI.hpp @@ -605,8 +605,8 @@ void AppleMIDISession::writeRtpMidiBuffer(Particip rtp.sequenceNr = participant->sendSequenceNr; #ifdef USE_EXT_CALLBACKS - if (_sendRtpCallback) - _sendRtpCallback(rtp); + if (_sentRtpCallback) + _sentRtpCallback(rtp); #endif rtp.timestamp = htonl(rtp.timestamp); @@ -643,8 +643,13 @@ void AppleMIDISession::writeRtpMidiBuffer(Particip // write out the MIDI Section for (size_t i = 0; i < bufferLen; i++) dataPort.write(outMidiBuffer[i]); - + // *No* journal section (Not supported) + +#ifdef USE_EXT_CALLBACKS + if (_sentRtpMidiCallback) + _sentRtpMidiCallback(rtpMidi); +#endif dataPort.endPacket(); dataPort.flush(); diff --git a/src/AppleMIDI_Defs.h b/src/AppleMIDI_Defs.h index ba99a4c..902cb6e 100644 --- a/src/AppleMIDI_Defs.h +++ b/src/AppleMIDI_Defs.h @@ -56,6 +56,9 @@ typedef const char* AppleMIDIConstStr; struct Rtp; typedef Rtp Rtp_t; +struct RtpMIDI; +typedef RtpMIDI RtpMIDI_t; + #ifdef USE_DIRECTORY enum WhoCanConnectToMe : uint8_t { @@ -126,7 +129,8 @@ using receivedMidiByteCallback = void (*)(const ssrc_t&, byte); using endReceivedMidiByteCallback = void (*)(const ssrc_t&); using receivedRtpCallback = void (*)(const Rtp_t&, const int32_t&); using exceptionCallback = void (*)(const ssrc_t&, const Exception&, const int32_t value); -using sendRtpCallback = void (*)(const Rtp_t&); +using sentRtpCallback = void (*)(const Rtp_t&); +using sentRtpMidiCallback = void (*)(const RtpMIDI_t&); #endif /* Signature "Magic Value" for Apple network MIDI session establishment */ From 2467d2d8add48b9dd093c5cd69f98a1e27104b89 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Mon, 28 Dec 2020 16:19:11 +0100 Subject: [PATCH 093/271] added ssrc to ReceiveMidi calls (private functions) --- src/AppleMIDI.h | 6 +++--- src/AppleMIDI.hpp | 12 +++++------ src/rtpMIDI_Parser_MidiCommandSection.hpp | 26 +++++++++++------------ 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/AppleMIDI.h b/src/AppleMIDI.h index 133288e..b57bb31 100644 --- a/src/AppleMIDI.h +++ b/src/AppleMIDI.h @@ -289,9 +289,9 @@ class AppleMIDISession // rtpMIDI callback from parser void ReceivedRtp(const Rtp_t &); - void StartReceivedMidi(); - void ReceivedMidi(byte data); - void EndReceivedMidi(); + void StartReceivedMidi(const ssrc_t&); + void ReceivedMidi(const ssrc_t&, byte data); + void EndReceivedMidi(const ssrc_t&); // Helpers void writeInvitation (UdpClass &, const IPAddress &, const uint16_t &, AppleMIDI_Invitation_t &, const byte *command); diff --git a/src/AppleMIDI.hpp b/src/AppleMIDI.hpp index 5b03834..7a2f4e4 100644 --- a/src/AppleMIDI.hpp +++ b/src/AppleMIDI.hpp @@ -1035,31 +1035,31 @@ void AppleMIDISession::ReceivedRtp(const Rtp_t& rt } template -void AppleMIDISession::StartReceivedMidi() +void AppleMIDISession::StartReceivedMidi(const ssrc_t& ssrc) { #ifdef USE_EXT_CALLBACKS if (nullptr != _startReceivedMidiByteCallback) - _startReceivedMidiByteCallback(0); + _startReceivedMidiByteCallback(ssrc); #endif } template -void AppleMIDISession::ReceivedMidi(byte value) +void AppleMIDISession::ReceivedMidi(const ssrc_t& ssrc, byte value) { #ifdef USE_EXT_CALLBACKS if (nullptr != _receivedMidiByteCallback) - _receivedMidiByteCallback(0, value); + _receivedMidiByteCallback(ssrc, value); #endif inMidiBuffer.push_back(value); } template -void AppleMIDISession::EndReceivedMidi() +void AppleMIDISession::EndReceivedMidi(const ssrc_t& ssrc) { #ifdef USE_EXT_CALLBACKS if (nullptr != _endReceivedMidiByteCallback) - _endReceivedMidiByteCallback(0); + _endReceivedMidiByteCallback(ssrc); #endif } diff --git a/src/rtpMIDI_Parser_MidiCommandSection.hpp b/src/rtpMIDI_Parser_MidiCommandSection.hpp index 2f3711e..d4b5407 100644 --- a/src/rtpMIDI_Parser_MidiCommandSection.hpp +++ b/src/rtpMIDI_Parser_MidiCommandSection.hpp @@ -77,9 +77,9 @@ size_t decodeMidi(RtpBuffer_t &buffer, uint8_t &runningstatus) * not be intermingled with other MIDI-commands, so we handle this case right here and return */ if (octet >= 0xf8) { - session->StartReceivedMidi(); - session->ReceivedMidi(buffer[0]); - session->EndReceivedMidi(); + session->StartReceivedMidi(session->getSynchronizationSource()); + session->ReceivedMidi(session->getSynchronizationSource(), buffer[0]); + session->EndReceivedMidi(session->getSynchronizationSource()); return 1; } @@ -145,10 +145,10 @@ size_t decodeMidi(RtpBuffer_t &buffer, uint8_t &runningstatus) break; } - session->StartReceivedMidi(); + session->StartReceivedMidi(session->getSynchronizationSource()); for (size_t j = 0; j < consumed; j++) - session->ReceivedMidi(buffer[j]); - session->EndReceivedMidi(); + session->ReceivedMidi(session->getSynchronizationSource(), buffer[j]); + session->EndReceivedMidi(session->getSynchronizationSource()); return consumed; } @@ -175,10 +175,10 @@ size_t decodeMidi(RtpBuffer_t &buffer, uint8_t &runningstatus) break; } - session->StartReceivedMidi(); + session->StartReceivedMidi(session->getSynchronizationSource()); for (size_t j = 0; j < consumed; j++) - session->ReceivedMidi(buffer[j]); - session->EndReceivedMidi(); + session->ReceivedMidi(session->getSynchronizationSource(), buffer[j]); + session->EndReceivedMidi(session->getSynchronizationSource()); return consumed; } @@ -208,11 +208,11 @@ size_t decodeMidiSysEx(RtpBuffer_t &buffer) consumed--; // send MIDI data - session->StartReceivedMidi(); + session->StartReceivedMidi(session->getSynchronizationSource()); for (size_t j = 0; j < consumed; j++) - session->ReceivedMidi(buffer[j]); - session->ReceivedMidi(MIDI_NAMESPACE::MidiType::SystemExclusiveStart); - session->EndReceivedMidi(); + session->ReceivedMidi(session->getSynchronizationSource(), buffer[j]); + session->ReceivedMidi(session->getSynchronizationSource(), MIDI_NAMESPACE::MidiType::SystemExclusiveStart); + session->EndReceivedMidi(session->getSynchronizationSource()); // Remove the bytes that were submitted for (size_t j = 0; j < consumed; j++) From 5e3678d3cc47f2dfa64145136767d4ae76896bc1 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Tue, 29 Dec 2020 13:52:43 +0100 Subject: [PATCH 094/271] receiverFeedback test is < not != --- examples/AVR_Callbacks/AVR_Callbacks.ino | 12 ++++---- examples/AVR_Directory/AVR_Directory.ino | 8 ++--- examples/AVR_Initiator/AVR_Initiator.ino | 8 ++--- examples/AVR_MinMemUsage/AVR_MinMemUsage.ino | 8 ++--- .../AVR_MultipleSessions.ino | 8 ++--- .../AVR_NonDefaultSession.ino | 8 ++--- .../AVR_NoteOnOffEverySec.ino | 8 ++--- .../AVR_ReceivedRawMidiData.ino | 6 ++-- examples/AVR_SysEx/AVR_SysEx.ino | 10 +++---- .../ESP32_NoteOnOffEverySec.ino | 8 ++--- .../ESP8266_NoteOnOffEverySec.ino | 8 ++--- .../wESP32_NoteOnOffEverySec.ino | 8 ++--- src/AppleMIDI.h | 22 +++++++------- src/AppleMIDI.hpp | 10 +++---- src/rtpMIDI_Parser_MidiCommandSection.hpp | 30 +++++++++---------- test/NoteOn.cpp | 8 ++--- 16 files changed, 87 insertions(+), 83 deletions(-) diff --git a/examples/AVR_Callbacks/AVR_Callbacks.ino b/examples/AVR_Callbacks/AVR_Callbacks.ino index b6fd907..dc4c270 100644 --- a/examples/AVR_Callbacks/AVR_Callbacks.ino +++ b/examples/AVR_Callbacks/AVR_Callbacks.ino @@ -12,7 +12,7 @@ byte mac[] = { }; unsigned long t1 = millis(); -bool isConnected = false; +int8_t isConnected = 0; APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); @@ -39,11 +39,11 @@ void setup() // Normal callbacks - always available // Stay informed on connection status AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { - isConnected = true; + isConnected++; DBG(F("Connected to session"), name); }); AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { - isConnected = false; + isConnected--; DBG(F("Disconnected")); }); @@ -88,7 +88,7 @@ void loop() // send a note every second // (dont cáll delay(1000) as it will stall the pipeline) - if (isConnected && (millis() - t1) > 1000) + if ((isConnected > 0) && (millis() - t1) > 1000) { t1 = millis(); @@ -96,8 +96,10 @@ void loop() byte velocity = 55; byte channel = 1; + DBG(F("\nsendNoteOn"), note, velocity, channel); MIDI.sendNoteOn(note, velocity, channel); - // MIDI.sendNoteOff(note, velocity, channel); + //MIDI.sendNoteOff(note, velocity, channel); + } } diff --git a/examples/AVR_Directory/AVR_Directory.ino b/examples/AVR_Directory/AVR_Directory.ino index 9487ef5..597c6c4 100644 --- a/examples/AVR_Directory/AVR_Directory.ino +++ b/examples/AVR_Directory/AVR_Directory.ino @@ -12,7 +12,7 @@ byte mac[] = { }; unsigned long t1 = millis(); -bool isConnected = false; +int8_t isConnected = 0; APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); @@ -44,11 +44,11 @@ void setup() // Stay informed on connection status AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { - isConnected = true; + isConnected++; DBG(F("Connected to session"), name); }); AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { - isConnected = false; + isConnected--; DBG(F("Disconnected")); }); @@ -72,7 +72,7 @@ void loop() // send a note every second // (dont cáll delay(1000) as it will stall the pipeline) - if (isConnected && (millis() - t1) > 1000) + if ((isConnected > 0) && (millis() - t1) > 1000) { t1 = millis(); diff --git a/examples/AVR_Initiator/AVR_Initiator.ino b/examples/AVR_Initiator/AVR_Initiator.ino index 1201965..46ab35c 100644 --- a/examples/AVR_Initiator/AVR_Initiator.ino +++ b/examples/AVR_Initiator/AVR_Initiator.ino @@ -12,7 +12,7 @@ byte mac[] = { }; unsigned long t1 = millis(); -bool isConnected = false; +int8_t isConnected = 0; APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); @@ -34,11 +34,11 @@ void setup() MIDI.begin(); AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { - isConnected = true; + isConnected++; DBG(F("Connected to session"), name); }); AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { - isConnected = false; + isConnected--; DBG(F("Disconnected")); }); @@ -70,7 +70,7 @@ void loop() // send note on/off every second // (dont cáll delay(1000) as it will stall the pipeline) - if (isConnected && (millis() - t1) > 1000) + if ((isConnected > 0) && (millis() - t1) > 1000) { t1 = millis(); diff --git a/examples/AVR_MinMemUsage/AVR_MinMemUsage.ino b/examples/AVR_MinMemUsage/AVR_MinMemUsage.ino index 1f7cee4..165a8cb 100644 --- a/examples/AVR_MinMemUsage/AVR_MinMemUsage.ino +++ b/examples/AVR_MinMemUsage/AVR_MinMemUsage.ino @@ -11,7 +11,7 @@ byte mac[] = { }; unsigned long t1 = millis(); -bool isConnected = false; +int8_t isConnected = 0; APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); @@ -29,11 +29,11 @@ void setup() // Stay informed on connection status AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char*) { - isConnected = true; + isConnected++; digitalWrite(LED_BUILTIN, HIGH); }); AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { - isConnected = false; + isConnected--; digitalWrite(LED_BUILTIN, LOW); }); @@ -55,7 +55,7 @@ void loop() // send a note every second // (dont cáll delay(1000) as it will stall the pipeline) - if (isConnected && (millis() - t1) > 1000) + if ((isConnected > 0) && (millis() - t1) > 1000) { t1 = millis(); diff --git a/examples/AVR_MultipleSessions/AVR_MultipleSessions.ino b/examples/AVR_MultipleSessions/AVR_MultipleSessions.ino index 95cbb8b..dda747e 100644 --- a/examples/AVR_MultipleSessions/AVR_MultipleSessions.ino +++ b/examples/AVR_MultipleSessions/AVR_MultipleSessions.ino @@ -11,7 +11,7 @@ byte mac[] = { }; unsigned long t1 = millis(); -bool isConnected = false; +int8_t isConnected = 0; APPLEMIDI_CREATE_INSTANCE(EthernetUDP, MIDI1, "Arduino1", DEFAULT_CONTROL_PORT); APPLEMIDI_CREATE_INSTANCE(EthernetUDP, MIDI2, "Arduino2", DEFAULT_CONTROL_PORT + 2); @@ -63,7 +63,7 @@ void loop() // send note on/off every second // (dont cáll delay(1000) as it will stall the pipeline) - if (isConnected && (millis() - t1) > 1000) + if ((isConnected > 0) && (millis() - t1) > 1000) { t1 = millis(); @@ -83,7 +83,7 @@ void loop() // rtpMIDI session. Device connected // ----------------------------------------------------------------------------- void OnAppleMidiConnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { - isConnected = true; + isConnected++; DBG(F("Connected to session"), name); } @@ -91,7 +91,7 @@ void OnAppleMidiConnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* // rtpMIDI session. Device disconnected // ----------------------------------------------------------------------------- void OnAppleMidiDisconnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { - isConnected = false; + isConnected--; DBG(F("Disconnected")); } diff --git a/examples/AVR_NonDefaultSession/AVR_NonDefaultSession.ino b/examples/AVR_NonDefaultSession/AVR_NonDefaultSession.ino index 797cb07..b988d02 100644 --- a/examples/AVR_NonDefaultSession/AVR_NonDefaultSession.ino +++ b/examples/AVR_NonDefaultSession/AVR_NonDefaultSession.ino @@ -11,7 +11,7 @@ byte mac[] = { }; unsigned long t1 = millis(); -bool isConnected = false; +int8_t isConnected = 0; // Non default portnr APPLEMIDI_CREATE_INSTANCE(EthernetUDP, MIDI, "MyNamedArduino", 5200); @@ -37,11 +37,11 @@ void setup() MIDI.begin(); AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { - isConnected = true; + isConnected++; DBG(F("Connected to session"), name); }); AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { - isConnected = false; + isConnected--; DBG(F("Disconnected")); }); @@ -58,7 +58,7 @@ void loop() // send a note every second // (dont cáll delay(1000) as it will stall the pipeline) - if (isConnected && (millis() - t1) > 1000) + if ((isConnected > 0) && (millis() - t1) > 1000) { t1 = millis(); diff --git a/examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino b/examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino index 23d5f58..df29e87 100644 --- a/examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino +++ b/examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino @@ -11,7 +11,7 @@ byte mac[] = { }; unsigned long t1 = millis(); -bool isConnected = false; +int8_t isConnected = 0; APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); @@ -37,11 +37,11 @@ void setup() // Stay informed on connection status AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { - isConnected = true; + isConnected++; DBG(F("Connected to session"), name); }); AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { - isConnected = false; + isConnected--; DBG(F("Disconnected")); }); @@ -65,7 +65,7 @@ void loop() // send a note every second // (dont cáll delay(1000) as it will stall the pipeline) - if (isConnected && (millis() - t1) > 1000) + if ((isConnected > 0) && (millis() - t1) > 1000) { t1 = millis(); diff --git a/examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino b/examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino index ba61901..0b5e0d4 100644 --- a/examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino +++ b/examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino @@ -11,7 +11,7 @@ byte mac[] = { }; unsigned long t1 = millis(); -bool isConnected = false; +int8_t isConnected = 0; APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); @@ -37,11 +37,11 @@ void setup() // check: zien we de connecttion binnenkomen?? Anders terug een ref van maken AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { - isConnected = true; + isConnected++; DBG(F("Connected to session"), name); }); AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { - isConnected = false; + isConnected--; DBG(F("Disconnected")); }); AppleMIDI.setHandleStartReceivedMidi(OnAppleMidiStartReceived); diff --git a/examples/AVR_SysEx/AVR_SysEx.ino b/examples/AVR_SysEx/AVR_SysEx.ino index eb023aa..d22046b 100644 --- a/examples/AVR_SysEx/AVR_SysEx.ino +++ b/examples/AVR_SysEx/AVR_SysEx.ino @@ -11,7 +11,7 @@ byte mac[] = { }; unsigned long t1 = millis(); -bool isConnected; +int8_t isConnected = 0; byte sysex14[] = { 0xF0, 0x43, 0x20, 0x7E, 0x4C, 0x4D, 0x20, 0x20, 0x38, 0x39, 0x37, 0x33, 0x50, 0xF7 }; byte sysex15[] = { 0xF0, 0x43, 0x20, 0x7E, 0x4C, 0x4D, 0x20, 0x20, 0x38, 0x39, 0x37, 0x33, 0x50, 0x4D, 0xF7 }; @@ -49,11 +49,11 @@ void setup() DBG(F("Then open a MIDI listener and monitor incoming notes")); AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { - isConnected = true; + isConnected++; DBG(F("Connected to session"), name); }); AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { - isConnected = false; + isConnected--; DBG(F("Disconnected")); }); @@ -73,9 +73,9 @@ void loop() // send a note every second // (dont cáll delay(1000) as it will stall the pipeline) - if (isConnected && (millis() - t1) > 1000) + if ((isConnected > 0) && (millis() - t1) > 1000) { - MIDI.sendSysEx(sizeof(sysexBig), sysexBig, true); + // MIDI.sendSysEx(sizeof(sysexBig), sysexBig, true); t1 = millis(); } } diff --git a/examples/ESP32_NoteOnOffEverySec/ESP32_NoteOnOffEverySec.ino b/examples/ESP32_NoteOnOffEverySec/ESP32_NoteOnOffEverySec.ino index 0368967..856f57f 100644 --- a/examples/ESP32_NoteOnOffEverySec/ESP32_NoteOnOffEverySec.ino +++ b/examples/ESP32_NoteOnOffEverySec/ESP32_NoteOnOffEverySec.ino @@ -11,7 +11,7 @@ char ssid[] = "ssid"; // your network SSID (name) char pass[] = "password"; // your network password (use for WPA, or use as key for WEP) unsigned long t0 = millis(); -bool isConnected = false; +int8_t isConnected = 0; APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); @@ -40,11 +40,11 @@ void setup() MIDI.begin(); AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { - isConnected = true; + isConnected++; DBG(F("Connected to session"), name); }); AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { - isConnected = false; + isConnected--; DBG(F("Disconnected")); }); @@ -68,7 +68,7 @@ void loop() // send a note every second // (dont cáll delay(1000) as it will stall the pipeline) - if (isConnected && (millis() - t0) > 1000) + if ((isConnected > 0) && (millis() - t0) > 1000) { t0 = millis(); diff --git a/examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino b/examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino index c45e9fb..dd3ea14 100644 --- a/examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino +++ b/examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino @@ -10,7 +10,7 @@ char ssid[] = "yourNetwork"; // your network SSID (name) char pass[] = "password"; // your network password (use for WPA, or use as key for WEP) unsigned long t0 = millis(); -bool isConnected = false; +int8_t isConnected = 0; APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); @@ -39,11 +39,11 @@ void setup() MIDI.begin(); AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { - isConnected = true; + isConnected++; DBG(F("Connected to session"), name); }); AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { - isConnected = false; + isConnected--; DBG(F("Disconnected")); }); @@ -67,7 +67,7 @@ void loop() // send a note every second // (dont cáll delay(1000) as it will stall the pipeline) - if (isConnected && (millis() - t0) > 1000) + if ((isConnected > 0) && (millis() - t0) > 1000) { t0 = millis(); diff --git a/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino b/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino index 7285659..48a2864 100644 --- a/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino +++ b/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino @@ -5,7 +5,7 @@ #include "ETH_Helper.h" unsigned long t0 = millis(); -bool isConnected = false; +int8_t isConnected = 0; APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); @@ -31,11 +31,11 @@ void setup() MIDI.begin(); AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { - isConnected = true; + isConnected++; DBG(F("Connected to session"), name); }); AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { - isConnected = false; + isConnected--; DBG(F("Disconnected")); }); @@ -59,7 +59,7 @@ void loop() // send a note every second // (dont cáll delay(1000) as it will stall the pipeline) - if (isConnected && (millis() - t0) > 1000) + if ((isConnected > 0) && (millis() - t0) > 1000) { t0 = millis(); diff --git a/src/AppleMIDI.h b/src/AppleMIDI.h index b57bb31..e519b15 100644 --- a/src/AppleMIDI.h +++ b/src/AppleMIDI.h @@ -64,7 +64,7 @@ class AppleMIDISession void setHandleReceivedMidi (void (*fptr)(const ssrc_t&, byte)) { _receivedMidiByteCallback = fptr; } void setHandleEndReceivedMidi (void (*fptr)(const ssrc_t&)) { _endReceivedMidiByteCallback = fptr; } void setHandleSentRtp (void (*fptr)(const Rtp_t&)) { _sentRtpCallback = fptr; } - void setHandleSentRtpMidi (void (*fptr)(const RtpMIDI_t&)) { _sentRtpMidiCallback = fptr; } + void setHandleSentRtpMidi (void (*fptr)(const RtpMIDI_t&)) { _sentRtpMidiCallback = fptr; } #endif #ifdef KEEP_SESSION_NAME @@ -203,13 +203,15 @@ class AppleMIDISession if (inMidiBuffer.size() > 0) return true; - // read packets from both UDP sockets - readDataPackets(); // from socket into dataBuffer - readControlPackets(); // from socket into controlBuffer + { + // read packets from both UDP sockets + readDataPackets(); // from socket into dataBuffer + readControlPackets(); // from socket into controlBuffer - // parses buffer and places MIDI into inMidiBuffer - parseDataPackets(); // from dataBuffer into inMidiBuffer - parseControlPackets(); // from controlBuffer + // parses buffer and places MIDI into inMidiBuffer + parseDataPackets(); // from dataBuffer into inMidiBuffer + parseControlPackets(); // from controlBuffer + } manageReceiverFeedback(); manageSynchronization(); @@ -289,9 +291,9 @@ class AppleMIDISession // rtpMIDI callback from parser void ReceivedRtp(const Rtp_t &); - void StartReceivedMidi(const ssrc_t&); - void ReceivedMidi(const ssrc_t&, byte data); - void EndReceivedMidi(const ssrc_t&); + void StartReceivedMidi(); + void ReceivedMidi(byte data); + void EndReceivedMidi(); // Helpers void writeInvitation (UdpClass &, const IPAddress &, const uint16_t &, AppleMIDI_Invitation_t &, const byte *command); diff --git a/src/AppleMIDI.hpp b/src/AppleMIDI.hpp index 7a2f4e4..e6cd76f 100644 --- a/src/AppleMIDI.hpp +++ b/src/AppleMIDI.hpp @@ -409,11 +409,11 @@ void AppleMIDISession::ReceivedReceiverFeedback(Ap return; } - if (pParticipant->sendSequenceNr != receiverFeedback.sequenceNr) + if (pParticipant->sendSequenceNr < receiverFeedback.sequenceNr) { #ifdef USE_EXT_CALLBACKS if (nullptr != _exceptionCallback) - _exceptionCallback(ssrc, SendPacketsDropped, pParticipant->sendSequenceNr - receiverFeedback.sequenceNr); + _exceptionCallback(pParticipant->ssrc, SendPacketsDropped, pParticipant->sendSequenceNr - receiverFeedback.sequenceNr); #endif } } @@ -1035,7 +1035,7 @@ void AppleMIDISession::ReceivedRtp(const Rtp_t& rt } template -void AppleMIDISession::StartReceivedMidi(const ssrc_t& ssrc) +void AppleMIDISession::StartReceivedMidi() { #ifdef USE_EXT_CALLBACKS if (nullptr != _startReceivedMidiByteCallback) @@ -1044,7 +1044,7 @@ void AppleMIDISession::StartReceivedMidi(const ssr } template -void AppleMIDISession::ReceivedMidi(const ssrc_t& ssrc, byte value) +void AppleMIDISession::ReceivedMidi(byte value) { #ifdef USE_EXT_CALLBACKS if (nullptr != _receivedMidiByteCallback) @@ -1055,7 +1055,7 @@ void AppleMIDISession::ReceivedMidi(const ssrc_t& } template -void AppleMIDISession::EndReceivedMidi(const ssrc_t& ssrc) +void AppleMIDISession::EndReceivedMidi() { #ifdef USE_EXT_CALLBACKS if (nullptr != _endReceivedMidiByteCallback) diff --git a/src/rtpMIDI_Parser_MidiCommandSection.hpp b/src/rtpMIDI_Parser_MidiCommandSection.hpp index d4b5407..9063066 100644 --- a/src/rtpMIDI_Parser_MidiCommandSection.hpp +++ b/src/rtpMIDI_Parser_MidiCommandSection.hpp @@ -77,9 +77,9 @@ size_t decodeMidi(RtpBuffer_t &buffer, uint8_t &runningstatus) * not be intermingled with other MIDI-commands, so we handle this case right here and return */ if (octet >= 0xf8) { - session->StartReceivedMidi(session->getSynchronizationSource()); - session->ReceivedMidi(session->getSynchronizationSource(), buffer[0]); - session->EndReceivedMidi(session->getSynchronizationSource()); + session->StartReceivedMidi(); + session->ReceivedMidi(buffer[0]); + session->EndReceivedMidi(); return 1; } @@ -145,10 +145,10 @@ size_t decodeMidi(RtpBuffer_t &buffer, uint8_t &runningstatus) break; } - session->StartReceivedMidi(session->getSynchronizationSource()); + session->StartReceivedMidi(); for (size_t j = 0; j < consumed; j++) - session->ReceivedMidi(session->getSynchronizationSource(), buffer[j]); - session->EndReceivedMidi(session->getSynchronizationSource()); + session->ReceivedMidi(buffer[j]); + session->EndReceivedMidi(); return consumed; } @@ -175,10 +175,10 @@ size_t decodeMidi(RtpBuffer_t &buffer, uint8_t &runningstatus) break; } - session->StartReceivedMidi(session->getSynchronizationSource()); + session->StartReceivedMidi(); for (size_t j = 0; j < consumed; j++) - session->ReceivedMidi(session->getSynchronizationSource(), buffer[j]); - session->EndReceivedMidi(session->getSynchronizationSource()); + session->ReceivedMidi(buffer[j]); + session->EndReceivedMidi(); return consumed; } @@ -206,13 +206,13 @@ size_t decodeMidiSysEx(RtpBuffer_t &buffer) // to compensate for adding the sysex at the end. consumed--; - + // send MIDI data - session->StartReceivedMidi(session->getSynchronizationSource()); + session->StartReceivedMidi(); for (size_t j = 0; j < consumed; j++) - session->ReceivedMidi(session->getSynchronizationSource(), buffer[j]); - session->ReceivedMidi(session->getSynchronizationSource(), MIDI_NAMESPACE::MidiType::SystemExclusiveStart); - session->EndReceivedMidi(session->getSynchronizationSource()); + session->ReceivedMidi(buffer[j]); + session->ReceivedMidi(MIDI_NAMESPACE::MidiType::SystemExclusiveStart); + session->EndReceivedMidi(); // Remove the bytes that were submitted for (size_t j = 0; j < consumed; j++) @@ -221,7 +221,7 @@ size_t decodeMidiSysEx(RtpBuffer_t &buffer) midiCommandLength -= consumed; midiCommandLength += 1; // adding the manual SysEx SystemExclusiveEnd - + // indicates split SysEx return buffer.max_size() + 1; } diff --git a/test/NoteOn.cpp b/test/NoteOn.cpp index b36d3b0..262b217 100644 --- a/test/NoteOn.cpp +++ b/test/NoteOn.cpp @@ -6,7 +6,7 @@ #include "AppleMIDI.h" unsigned long t0 = millis(); -bool isConnected = false; +bool isConnected--; byte sysex14[] = { 0xF0, 0x43, 0x20, 0x7E, 0x4C, 0x4D, 0x20, 0x20, 0x38, 0x39, 0x37, 0x33, 0x50, 0xF7 }; byte sysex15[] = { 0xF0, 0x43, 0x20, 0x7E, 0x4C, 0x4D, 0x20, 0x20, 0x38, 0x39, 0x37, 0x33, 0x50, 0x4D, 0xF7 }; @@ -33,7 +33,7 @@ APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); // rtpMIDI session. Device connected // ----------------------------------------------------------------------------- void OnAppleMidiConnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { - isConnected = true; + isConnected++; DBG(F("Connected to session"), name); } @@ -41,7 +41,7 @@ void OnAppleMidiConnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* // rtpMIDI session. Device disconnected // ----------------------------------------------------------------------------- void OnAppleMidiDisconnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { - isConnected = false; + isConnected--; DBG(F("Disconnected")); } @@ -123,7 +123,7 @@ void loop() // send a note every second // (dont cáll delay(1000) as it will stall the pipeline) - if (isConnected && (millis() - t0) > 10000) + if ((isConnected > 0) && (millis() - t0) > 10000) { t0 = millis(); From ce7e8a714b9a31c5078273594b6416dedb04e603 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Tue, 29 Dec 2020 15:43:21 +0100 Subject: [PATCH 095/271] receivedRtpCallback with ssrc, disconnect with ssrc --- examples/AVR_Callbacks/AVR_Callbacks.ino | 8 ++++---- examples/AVR_Directory/AVR_Directory.ino | 4 ++-- examples/AVR_Initiator/AVR_Initiator.ino | 4 ++-- examples/AVR_MultipleSessions/AVR_MultipleSessions.ino | 4 ++-- examples/AVR_NonDefaultSession/AVR_NonDefaultSession.ino | 4 ++-- examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino | 4 ++-- .../AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino | 4 ++-- examples/AVR_SysEx/AVR_SysEx.ino | 4 ++-- .../ESP32_NoteOnOffEverySec/ESP32_NoteOnOffEverySec.ino | 4 ++-- .../ESP8266_NoteOnOffEverySec.ino | 4 ++-- .../wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino | 4 ++-- src/AppleMIDI.h | 2 +- src/AppleMIDI.hpp | 2 +- src/AppleMIDI_Defs.h | 2 +- test/NoteOn.cpp | 4 ++-- 15 files changed, 29 insertions(+), 29 deletions(-) diff --git a/examples/AVR_Callbacks/AVR_Callbacks.ino b/examples/AVR_Callbacks/AVR_Callbacks.ino index dc4c270..41568a0 100644 --- a/examples/AVR_Callbacks/AVR_Callbacks.ino +++ b/examples/AVR_Callbacks/AVR_Callbacks.ino @@ -40,11 +40,11 @@ void setup() // Stay informed on connection status AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { isConnected++; - DBG(F("Connected to session"), name); + DBG(F("Connected to session"), ssrc, name); }); AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { isConnected--; - DBG(F("Disconnected")); + DBG(F("Disconnected"), ssrc); }); // Extended callback, only available when defining USE_EXT_CALLBACKS @@ -54,8 +54,8 @@ void setup() AppleMIDI.setHandleSentRtpMidi([](const APPLEMIDI_NAMESPACE::RtpMIDI_t& rtpMidi) { DBG(F("an rtpMidiMessage has been sent"), rtpMidi.flags); }); - AppleMIDI.setHandleReceivedRtp([](const APPLEMIDI_NAMESPACE::Rtp_t & rtp, const int32_t& latency) { - DBG(F("setHandleReceivedRtp"), rtp.sequenceNr , "with", latency, "ms latency"); + AppleMIDI.setHandleReceivedRtp([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const APPLEMIDI_NAMESPACE::Rtp_t & rtp, const int32_t& latency) { + DBG(F("setHandleReceivedRtp"), ssrc, rtp.sequenceNr , "with", latency, "ms latency"); }); AppleMIDI.setHandleStartReceivedMidi([](const APPLEMIDI_NAMESPACE::ssrc_t& ssrc) { DBG(F("setHandleStartReceivedMidi from SSRC"), ssrc); diff --git a/examples/AVR_Directory/AVR_Directory.ino b/examples/AVR_Directory/AVR_Directory.ino index 597c6c4..7d0f1b8 100644 --- a/examples/AVR_Directory/AVR_Directory.ino +++ b/examples/AVR_Directory/AVR_Directory.ino @@ -45,11 +45,11 @@ void setup() // Stay informed on connection status AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { isConnected++; - DBG(F("Connected to session"), name); + DBG(F("Connected to session"), ssrc, name); }); AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { isConnected--; - DBG(F("Disconnected")); + DBG(F("Disconnected"), ssrc); }); MIDI.setHandleNoteOn([](byte channel, byte note, byte velocity) { diff --git a/examples/AVR_Initiator/AVR_Initiator.ino b/examples/AVR_Initiator/AVR_Initiator.ino index 46ab35c..095ca04 100644 --- a/examples/AVR_Initiator/AVR_Initiator.ino +++ b/examples/AVR_Initiator/AVR_Initiator.ino @@ -35,11 +35,11 @@ void setup() AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { isConnected++; - DBG(F("Connected to session"), name); + DBG(F("Connected to session"), ssrc, name); }); AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { isConnected--; - DBG(F("Disconnected")); + DBG(F("Disconnected"), ssrc); }); MIDI.setHandleNoteOn([](byte channel, byte note, byte velocity) { diff --git a/examples/AVR_MultipleSessions/AVR_MultipleSessions.ino b/examples/AVR_MultipleSessions/AVR_MultipleSessions.ino index dda747e..cc4a1d3 100644 --- a/examples/AVR_MultipleSessions/AVR_MultipleSessions.ino +++ b/examples/AVR_MultipleSessions/AVR_MultipleSessions.ino @@ -84,7 +84,7 @@ void loop() // ----------------------------------------------------------------------------- void OnAppleMidiConnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { isConnected++; - DBG(F("Connected to session"), name); + DBG(F("Connected to session"), ssrc, name); } // ----------------------------------------------------------------------------- @@ -92,7 +92,7 @@ void OnAppleMidiConnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* // ----------------------------------------------------------------------------- void OnAppleMidiDisconnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { isConnected--; - DBG(F("Disconnected")); + DBG(F("Disconnected"), ssrc); } // ----------------------------------------------------------------------------- diff --git a/examples/AVR_NonDefaultSession/AVR_NonDefaultSession.ino b/examples/AVR_NonDefaultSession/AVR_NonDefaultSession.ino index b988d02..fef1455 100644 --- a/examples/AVR_NonDefaultSession/AVR_NonDefaultSession.ino +++ b/examples/AVR_NonDefaultSession/AVR_NonDefaultSession.ino @@ -38,11 +38,11 @@ void setup() AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { isConnected++; - DBG(F("Connected to session"), name); + DBG(F("Connected to session"), ssrc, name); }); AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { isConnected--; - DBG(F("Disconnected")); + DBG(F("Disconnected"), ssrc); }); DBG(F("Send MIDI messages every second")); diff --git a/examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino b/examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino index df29e87..d5fd0b1 100644 --- a/examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino +++ b/examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino @@ -38,11 +38,11 @@ void setup() // Stay informed on connection status AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { isConnected++; - DBG(F("Connected to session"), name); + DBG(F("Connected to session"), ssrc, name); }); AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { isConnected--; - DBG(F("Disconnected")); + DBG(F("Disconnected"), ssrc); }); MIDI.setHandleNoteOn([](byte channel, byte note, byte velocity) { diff --git a/examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino b/examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino index 0b5e0d4..fb815bd 100644 --- a/examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino +++ b/examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino @@ -38,11 +38,11 @@ void setup() // check: zien we de connecttion binnenkomen?? Anders terug een ref van maken AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { isConnected++; - DBG(F("Connected to session"), name); + DBG(F("Connected to session"), ssrc, name); }); AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { isConnected--; - DBG(F("Disconnected")); + DBG(F("Disconnected"), ssrc); }); AppleMIDI.setHandleStartReceivedMidi(OnAppleMidiStartReceived); AppleMIDI.setHandleReceivedMidi(OnAppleMidiReceivedByte); diff --git a/examples/AVR_SysEx/AVR_SysEx.ino b/examples/AVR_SysEx/AVR_SysEx.ino index d22046b..e258848 100644 --- a/examples/AVR_SysEx/AVR_SysEx.ino +++ b/examples/AVR_SysEx/AVR_SysEx.ino @@ -50,11 +50,11 @@ void setup() AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { isConnected++; - DBG(F("Connected to session"), name); + DBG(F("Connected to session"), ssrc, name); }); AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { isConnected--; - DBG(F("Disconnected")); + DBG(F("Disconnected"), ssrc); }); MIDI.begin(); diff --git a/examples/ESP32_NoteOnOffEverySec/ESP32_NoteOnOffEverySec.ino b/examples/ESP32_NoteOnOffEverySec/ESP32_NoteOnOffEverySec.ino index 856f57f..1fee9a5 100644 --- a/examples/ESP32_NoteOnOffEverySec/ESP32_NoteOnOffEverySec.ino +++ b/examples/ESP32_NoteOnOffEverySec/ESP32_NoteOnOffEverySec.ino @@ -41,11 +41,11 @@ void setup() AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { isConnected++; - DBG(F("Connected to session"), name); + DBG(F("Connected to session"), ssrc, name); }); AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { isConnected--; - DBG(F("Disconnected")); + DBG(F("Disconnected"), ssrc); }); MIDI.setHandleNoteOn([](byte channel, byte note, byte velocity) { diff --git a/examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino b/examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino index dd3ea14..3385371 100644 --- a/examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino +++ b/examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino @@ -40,11 +40,11 @@ void setup() AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { isConnected++; - DBG(F("Connected to session"), name); + DBG(F("Connected to session"), ssrc, name); }); AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { isConnected--; - DBG(F("Disconnected")); + DBG(F("Disconnected"), ssrc); }); MIDI.setHandleNoteOn([](byte channel, byte note, byte velocity) { diff --git a/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino b/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino index 48a2864..75f0ed2 100644 --- a/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino +++ b/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino @@ -32,11 +32,11 @@ void setup() AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { isConnected++; - DBG(F("Connected to session"), name); + DBG(F("Connected to session"), ssrc, name); }); AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { isConnected--; - DBG(F("Disconnected")); + DBG(F("Disconnected"), ssrc); }); MIDI.setHandleNoteOn([](byte channel, byte note, byte velocity) { diff --git a/src/AppleMIDI.h b/src/AppleMIDI.h index e519b15..3b1dce8 100644 --- a/src/AppleMIDI.h +++ b/src/AppleMIDI.h @@ -59,7 +59,7 @@ class AppleMIDISession void setHandleDisconnected (void (*fptr)(const ssrc_t&)) { _disconnectedCallback = fptr; } #ifdef USE_EXT_CALLBACKS void setHandleException (void (*fptr)(const ssrc_t&, const Exception&, const int32_t value)) { _exceptionCallback = fptr; } - void setHandleReceivedRtp (void (*fptr)(const Rtp_t&, const int32_t&)) { _receivedRtpCallback = 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; } void setHandleEndReceivedMidi (void (*fptr)(const ssrc_t&)) { _endReceivedMidiByteCallback = fptr; } diff --git a/src/AppleMIDI.hpp b/src/AppleMIDI.hpp index e6cd76f..1efe2d5 100644 --- a/src/AppleMIDI.hpp +++ b/src/AppleMIDI.hpp @@ -1025,7 +1025,7 @@ void AppleMIDISession::ReceivedRtp(const Rtp_t& rt #ifdef USE_EXT_CALLBACKS if (nullptr != _receivedRtpCallback) - _receivedRtpCallback(rtp, latency); + _receivedRtpCallback(pParticipant->ssrc, rtp, latency); #endif } else diff --git a/src/AppleMIDI_Defs.h b/src/AppleMIDI_Defs.h index 902cb6e..0fc7541 100644 --- a/src/AppleMIDI_Defs.h +++ b/src/AppleMIDI_Defs.h @@ -127,7 +127,7 @@ using disconnectedCallback = void (*)(const ssrc_t&); using startReceivedMidiByteCallback = void (*)(const ssrc_t&); using receivedMidiByteCallback = void (*)(const ssrc_t&, byte); using endReceivedMidiByteCallback = void (*)(const ssrc_t&); -using receivedRtpCallback = void (*)(const Rtp_t&, const int32_t&); +using receivedRtpCallback = void (*)(const ssrc_t&, const Rtp_t&, const int32_t&); using exceptionCallback = void (*)(const ssrc_t&, const Exception&, const int32_t value); using sentRtpCallback = void (*)(const Rtp_t&); using sentRtpMidiCallback = void (*)(const RtpMIDI_t&); diff --git a/test/NoteOn.cpp b/test/NoteOn.cpp index 262b217..ccec4d7 100644 --- a/test/NoteOn.cpp +++ b/test/NoteOn.cpp @@ -34,7 +34,7 @@ APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); // ----------------------------------------------------------------------------- void OnAppleMidiConnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { isConnected++; - DBG(F("Connected to session"), name); + DBG(F("Connected to session"), ssrc, name); } // ----------------------------------------------------------------------------- @@ -42,7 +42,7 @@ void OnAppleMidiConnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* // ----------------------------------------------------------------------------- void OnAppleMidiDisconnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { isConnected--; - DBG(F("Disconnected")); + DBG(F("Disconnected"), ssrc); } // ----------------------------------------------------------------------------- From 296717cf13fc5de0dc64659aa38579575fef4848 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Tue, 29 Dec 2020 16:30:01 +0100 Subject: [PATCH 096/271] Update .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f189e73..f1f886e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,4 +13,4 @@ install: - platformio lib -g install 62@5.0.0 870 872 script: -- pio ci --board=uno --lib=. examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino; +- pio ci --board=uno --lib=. examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino; From 8117dd35246cba0abb6a2b8e92f40e6803f92882 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Tue, 29 Dec 2020 16:38:35 +0100 Subject: [PATCH 097/271] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 127d277..55a6c61 100755 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # AppleMIDI (aka rtpMIDI) for Arduino -[![arduino-library-badge](https://www.ardu-badge.com/badge/AppleMIDI.svg?)](https://www.ardu-badge.com/AppleMIDI) [![Build Status](https://travis-ci.org/lathoub/Arduino-AppleMIDI-Library.svg?branch=master)](https://travis-ci.org/lathoub/Arduino-AppleMIDI-Library) [![License: CC BY-SA 4.0](https://img.shields.io/badge/License-CC%20BY--SA%204.0-lightgrey.svg)](http://creativecommons.org/licenses/by-sa/4.0/) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/c8be2ccc3f104e0588572a39f8106070)](https://app.codacy.com/app/lathoub/Arduino-AppleMIDI-Library?utm_source=github.com&utm_medium=referral&utm_content=lathoub/Arduino-AppleMIDI-Library&utm_campaign=Badge_Grade_Dashboard) +[![arduino-library-badge](https://www.ardu-badge.com/badge/AppleMIDI.svg?)](https://www.ardu-badge.com/AppleMIDI) [![Build Status](https://travis-ci.com/lathoub/Arduino-AppleMIDI-Library.svg?branch=master)](https://travis-ci.com/lathoub/Arduino-AppleMIDI-Library) [![License: CC BY-SA 4.0](https://img.shields.io/badge/License-CC%20BY--SA%204.0-lightgrey.svg)](http://creativecommons.org/licenses/by-sa/4.0/) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/c8be2ccc3f104e0588572a39f8106070)](https://app.codacy.com/app/lathoub/Arduino-AppleMIDI-Library?utm_source=github.com&utm_medium=referral&utm_content=lathoub/Arduino-AppleMIDI-Library&utm_campaign=Badge_Grade_Dashboard) Enables an Arduino with IP/UDP capabilities (Ethernet shield, ESP8266, ESP32, ...) to particpate in an AppleMIDI session. From 9294a504a3e7f7c70c1dd6c4f31297a5854559d2 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Tue, 29 Dec 2020 16:39:08 +0100 Subject: [PATCH 098/271] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 55a6c61..127d277 100755 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # AppleMIDI (aka rtpMIDI) for Arduino -[![arduino-library-badge](https://www.ardu-badge.com/badge/AppleMIDI.svg?)](https://www.ardu-badge.com/AppleMIDI) [![Build Status](https://travis-ci.com/lathoub/Arduino-AppleMIDI-Library.svg?branch=master)](https://travis-ci.com/lathoub/Arduino-AppleMIDI-Library) [![License: CC BY-SA 4.0](https://img.shields.io/badge/License-CC%20BY--SA%204.0-lightgrey.svg)](http://creativecommons.org/licenses/by-sa/4.0/) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/c8be2ccc3f104e0588572a39f8106070)](https://app.codacy.com/app/lathoub/Arduino-AppleMIDI-Library?utm_source=github.com&utm_medium=referral&utm_content=lathoub/Arduino-AppleMIDI-Library&utm_campaign=Badge_Grade_Dashboard) +[![arduino-library-badge](https://www.ardu-badge.com/badge/AppleMIDI.svg?)](https://www.ardu-badge.com/AppleMIDI) [![Build Status](https://travis-ci.org/lathoub/Arduino-AppleMIDI-Library.svg?branch=master)](https://travis-ci.org/lathoub/Arduino-AppleMIDI-Library) [![License: CC BY-SA 4.0](https://img.shields.io/badge/License-CC%20BY--SA%204.0-lightgrey.svg)](http://creativecommons.org/licenses/by-sa/4.0/) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/c8be2ccc3f104e0588572a39f8106070)](https://app.codacy.com/app/lathoub/Arduino-AppleMIDI-Library?utm_source=github.com&utm_medium=referral&utm_content=lathoub/Arduino-AppleMIDI-Library&utm_campaign=Badge_Grade_Dashboard) Enables an Arduino with IP/UDP capabilities (Ethernet shield, ESP8266, ESP32, ...) to particpate in an AppleMIDI session. From 299004cd99e58bbc1a4e74be57295276685d96cb Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Tue, 29 Dec 2020 16:42:16 +0100 Subject: [PATCH 099/271] Update .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f1f886e..96a3952 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,4 +13,4 @@ install: - platformio lib -g install 62@5.0.0 870 872 script: -- pio ci --board=uno --lib=. examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino; +- pio ci --board=uno --lib=. examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino examples/AVR_MinMemUsage/AVR_MinMemUsage.ino; From 2739ce6368c226e77606e462b60681750899c8d1 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Tue, 29 Dec 2020 16:51:05 +0100 Subject: [PATCH 100/271] Update .travis.yml --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 96a3952..498d9d1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,4 +13,5 @@ install: - platformio lib -g install 62@5.0.0 870 872 script: -- pio ci --board=uno --lib=. examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino examples/AVR_MinMemUsage/AVR_MinMemUsage.ino; +- pio ci --board=uno --lib=. examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino +- pio ci --board=uno --lib=. examples/AVR_MinMemUsage/AVR_MinMemUsage.ino From 3c95ee1840008d352b53f8e7078619339ebf59b8 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Tue, 29 Dec 2020 17:20:16 +0100 Subject: [PATCH 101/271] Update .travis.yml --- .travis.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 498d9d1..6e3d79e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,5 +13,12 @@ install: - platformio lib -g install 62@5.0.0 870 872 script: -- pio ci --board=uno --lib=. examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino +- pio ci --board=uno --lib=. examples/AVR_Callbacks/AVR_Callbacks.ino +- pio ci --board=uno --lib=. examples/AVR_Directory/AVR_Directory.ino +- pio ci --board=uno --lib=. examples/AVR_Initiator/AVR_Initiator.ino - pio ci --board=uno --lib=. examples/AVR_MinMemUsage/AVR_MinMemUsage.ino +- pio ci --board=uno --lib=. examples/AVR_MultipleSessions/AVR_MultipleSessions.ino +- pio ci --board=uno --lib=. examples/AVR_NonDefaultSession/AVR_NonDefaultSession.ino +- pio ci --board=uno --lib=. examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino +- pio ci --board=uno --lib=. examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino +- pio ci --board=uno --lib=. examples/AVR_SysEx/AVR_SysEx.ino From 4f7f9ab61f1cb7418b257f0402a51dae398f0a9f Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Tue, 29 Dec 2020 17:28:36 +0100 Subject: [PATCH 102/271] Update .travis.yml --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 6e3d79e..89a1bd4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,3 +22,4 @@ script: - pio ci --board=uno --lib=. examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino - pio ci --board=uno --lib=. examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino - pio ci --board=uno --lib=. examples/AVR_SysEx/AVR_SysEx.ino +- pio ci --board=zero --lib=. examples/SAMD_Bonjour/SAMD_Bonjour.ino From 5aa8c69f1ba40df8434fe022a160ebf980895bb8 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Tue, 29 Dec 2020 19:12:16 +0100 Subject: [PATCH 103/271] update examples --- examples/AVR_Initiator/AVR_Initiator.ino | 8 ++++---- .../AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino | 1 + src/AppleMIDI.h | 2 +- src/AppleMIDI.hpp | 1 - 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/AVR_Initiator/AVR_Initiator.ino b/examples/AVR_Initiator/AVR_Initiator.ino index 095ca04..b116c22 100644 --- a/examples/AVR_Initiator/AVR_Initiator.ino +++ b/examples/AVR_Initiator/AVR_Initiator.ino @@ -1,8 +1,8 @@ #include +#define APPLEMIDI_INITIATOR #define SerialMon Serial #define APPLEMIDI_DEBUG SerialMon -#define APPLEMIDI_INITIATOR #include // Enter a MAC address for your controller below. @@ -41,7 +41,7 @@ void setup() isConnected--; DBG(F("Disconnected"), ssrc); }); - + MIDI.setHandleNoteOn([](byte channel, byte note, byte velocity) { DBG(F("NoteOn"), note); }); @@ -78,7 +78,7 @@ void loop() byte velocity = 55; byte channel = 1; - // MIDI.sendNoteOn(note, velocity, channel); - // MIDI.sendNoteOff(note, velocity, channel); + MIDI.sendNoteOn(note, velocity, channel); + MIDI.sendNoteOff(note, velocity, channel); } } diff --git a/examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino b/examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino index fb815bd..db54cad 100644 --- a/examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino +++ b/examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino @@ -1,5 +1,6 @@ #include +#define USE_EXT_CALLBACKS #define SerialMon Serial #define APPLEMIDI_DEBUG SerialMon #include diff --git a/src/AppleMIDI.h b/src/AppleMIDI.h index 3b1dce8..dc52ca4 100644 --- a/src/AppleMIDI.h +++ b/src/AppleMIDI.h @@ -311,7 +311,7 @@ class AppleMIDISession void manageSessionInvites(); void manageSynchronization(); void manageSynchronizationInitiator(); - void manageSynchronizationInitiatorHeartBeat(size_t); + void manageSynchronizationInitiatorHeartBeat(Participant*); void manageSynchronizationInitiatorInvites(size_t); void sendSynchronization(Participant*); diff --git a/src/AppleMIDI.hpp b/src/AppleMIDI.hpp index 1efe2d5..aa4d656 100644 --- a/src/AppleMIDI.hpp +++ b/src/AppleMIDI.hpp @@ -951,7 +951,6 @@ bool AppleMIDISession::sendInvite(IPAddress ip, ui participant.lastInviteSentTime = now - 1000; // forces invite to be send immediately participant.lastSyncExchangeTime = now; participant.initiatorToken = random(1, INT32_MAX) * 2; - participant.sequenceNr; #ifndef ONE_PARTICIPANT participants.push_back(participant); From 9c6d4c3fbb207a92730d6b4d98b412cb5c6eb99e Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Tue, 29 Dec 2020 19:27:20 +0100 Subject: [PATCH 104/271] Update .travis.yml --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 89a1bd4..6e3d79e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,4 +22,3 @@ script: - pio ci --board=uno --lib=. examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino - pio ci --board=uno --lib=. examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino - pio ci --board=uno --lib=. examples/AVR_SysEx/AVR_SysEx.ino -- pio ci --board=zero --lib=. examples/SAMD_Bonjour/SAMD_Bonjour.ino From 33be4a494eccde71ff26ad6f4a6caef1d09d33bc Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Tue, 29 Dec 2020 19:34:22 +0100 Subject: [PATCH 105/271] fixing examples --- examples/AVR_Callbacks/AVR_Callbacks.ino | 2 ++ examples/AVR_MultipleSessions/AVR_MultipleSessions.ino | 4 ++++ examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino | 4 ++++ 3 files changed, 10 insertions(+) diff --git a/examples/AVR_Callbacks/AVR_Callbacks.ino b/examples/AVR_Callbacks/AVR_Callbacks.ino index 41568a0..6ca0634 100644 --- a/examples/AVR_Callbacks/AVR_Callbacks.ino +++ b/examples/AVR_Callbacks/AVR_Callbacks.ino @@ -16,6 +16,8 @@ int8_t isConnected = 0; APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); +void OnAppleMidiException(const APPLEMIDI_NAMESPACE::ssrc_t&, const APPLEMIDI_NAMESPACE::Exception&, const int32_t); + // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- diff --git a/examples/AVR_MultipleSessions/AVR_MultipleSessions.ino b/examples/AVR_MultipleSessions/AVR_MultipleSessions.ino index cc4a1d3..2f49232 100644 --- a/examples/AVR_MultipleSessions/AVR_MultipleSessions.ino +++ b/examples/AVR_MultipleSessions/AVR_MultipleSessions.ino @@ -16,6 +16,10 @@ int8_t isConnected = 0; APPLEMIDI_CREATE_INSTANCE(EthernetUDP, MIDI1, "Arduino1", DEFAULT_CONTROL_PORT); APPLEMIDI_CREATE_INSTANCE(EthernetUDP, MIDI2, "Arduino2", DEFAULT_CONTROL_PORT + 2); +void OnAppleMidiConnected(const APPLEMIDI_NAMESPACE::ssrc_t&, const char*); +void OnAppleMidiDisconnected(const APPLEMIDI_NAMESPACE::ssrc_t &); +void OnMidiNoteOn(byte channel, byte note, byte velocity); + // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- diff --git a/examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino b/examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino index db54cad..e4c1bad 100644 --- a/examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino +++ b/examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino @@ -16,6 +16,10 @@ int8_t isConnected = 0; APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); +void OnAppleMidiStartReceived(const APPLEMIDI_NAMESPACE::ssrc_t&); +void OnAppleMidiReceivedByte(const APPLEMIDI_NAMESPACE::ssrc_t&, byte); +void OnAppleMidiEndReceive(const APPLEMIDI_NAMESPACE::ssrc_t&); + // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- From 8936cd72abf42509a2fa1c07105535fb7cb83b34 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Tue, 29 Dec 2020 20:21:54 +0100 Subject: [PATCH 106/271] Update .travis.yml --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 6e3d79e..73b46ef 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,3 +22,4 @@ script: - pio ci --board=uno --lib=. examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino - pio ci --board=uno --lib=. examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino - pio ci --board=uno --lib=. examples/AVR_SysEx/AVR_SysEx.ino +- pio ci --board=esp8266:esp8266:generic:xtal=80,eesz=4M1M,FlashMode=qio,FlashFreq=80,dbg=Serial,lvl=CORE examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino From 08366e5250d4788e087b7b59fb3b92672911c2db Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Tue, 29 Dec 2020 20:56:57 +0100 Subject: [PATCH 107/271] Update .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 73b46ef..1468d55 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,4 +22,4 @@ script: - pio ci --board=uno --lib=. examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino - pio ci --board=uno --lib=. examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino - pio ci --board=uno --lib=. examples/AVR_SysEx/AVR_SysEx.ino -- pio ci --board=esp8266:esp8266:generic:xtal=80,eesz=4M1M,FlashMode=qio,FlashFreq=80,dbg=Serial,lvl=CORE examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino +- pio ci --platform=espressif8266 --board=huzzah examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino From ca50b41c37df8c47a19c9694f01e6738d236e335 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Tue, 29 Dec 2020 20:59:11 +0100 Subject: [PATCH 108/271] Update .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1468d55..3882b7a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,4 +22,4 @@ script: - pio ci --board=uno --lib=. examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino - pio ci --board=uno --lib=. examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino - pio ci --board=uno --lib=. examples/AVR_SysEx/AVR_SysEx.ino -- pio ci --platform=espressif8266 --board=huzzah examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino +- pio ci --board=huzzah examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino From e069ffbc8d6a89dfa42c0368fb3c9a19ce83ed41 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Tue, 29 Dec 2020 21:22:47 +0100 Subject: [PATCH 109/271] Update .travis.yml --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 3882b7a..62de280 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,3 +23,4 @@ script: - pio ci --board=uno --lib=. examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino - pio ci --board=uno --lib=. examples/AVR_SysEx/AVR_SysEx.ino - pio ci --board=huzzah examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino +- pio ci --board=featheresp32 examples/ESP32_NoteOnOffEverySec/ESP32_NoteOnOffEverySec.ino From 0fc91fd0071690d8a126845fe8edc041ab1b820b Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Tue, 29 Dec 2020 21:23:08 +0100 Subject: [PATCH 110/271] Update .travis.yml --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 62de280..c00fc45 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,5 +22,5 @@ script: - pio ci --board=uno --lib=. examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino - pio ci --board=uno --lib=. examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino - pio ci --board=uno --lib=. examples/AVR_SysEx/AVR_SysEx.ino -- pio ci --board=huzzah examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino -- pio ci --board=featheresp32 examples/ESP32_NoteOnOffEverySec/ESP32_NoteOnOffEverySec.ino +- pio ci --board=huzzah --lib=. examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino +- pio ci --board=featheresp32 --lib=. examples/ESP32_NoteOnOffEverySec/ESP32_NoteOnOffEverySec.ino From 122f77874ae204a3c23ab73b2cd5d3f3edd9d7bc Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Tue, 29 Dec 2020 23:24:53 +0100 Subject: [PATCH 111/271] Create AVR_E3_NoteOnOffEverySec.ino --- .../AVR_E3_NoteOnOffEverySec.ino | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 examples/AVR_E3_NoteOnOffEverySec/AVR_E3_NoteOnOffEverySec.ino diff --git a/examples/AVR_E3_NoteOnOffEverySec/AVR_E3_NoteOnOffEverySec.ino b/examples/AVR_E3_NoteOnOffEverySec/AVR_E3_NoteOnOffEverySec.ino new file mode 100644 index 0000000..28517b4 --- /dev/null +++ b/examples/AVR_E3_NoteOnOffEverySec/AVR_E3_NoteOnOffEverySec.ino @@ -0,0 +1,79 @@ +#include // from https://github.com/sstaub/Ethernet3 + +#define SerialMon Serial +#define APPLEMIDI_DEBUG SerialMon +#include + +// Enter a MAC address for your controller below. +// Newer Ethernet shields have a MAC address printed on a sticker on the shield +byte mac[] = { + 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED +}; + +unsigned long t1 = millis(); +int8_t isConnected = 0; + +APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +void setup() +{ + DBG_SETUP(115200); + DBG("Booting"); + + if (Ethernet.begin(mac) == 0) { + DBG(F("Failed DHCP, check network cable & reboot")); + for (;;); + } + + DBG(F("OK, now make sure you an rtpMIDI session that is Enabled")); + DBG(F("Add device named Arduino with Host"), Ethernet.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); + DBG(F("Select and then press the Connect button")); + DBG(F("Then open a MIDI listener and monitor incoming notes")); + + MIDI.begin(); + + // Stay informed on connection status + AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { + isConnected++; + DBG(F("Connected to session"), ssrc, name); + }); + AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { + isConnected--; + DBG(F("Disconnected"), ssrc); + }); + + MIDI.setHandleNoteOn([](byte channel, byte note, byte velocity) { + DBG(F("NoteOn"), note); + }); + MIDI.setHandleNoteOff([](byte channel, byte note, byte velocity) { + DBG(F("NoteOff"), note); + }); + + DBG(F("Sending MIDI messages every second")); +} + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +void loop() +{ + // Listen to incoming notes + MIDI.read(); + + // send a note every second + // (dont cáll delay(1000) as it will stall the pipeline) + if ((isConnected > 0) && (millis() - t1) > 1000) + { + t1 = millis(); + + byte note = random(1, 127); + byte velocity = 55; + byte channel = 1; + + MIDI.sendNoteOn(note, velocity, channel); +// MIDI.sendNoteOff(note, velocity, channel); + } +} From c0a99a5f6f37b42e699d04f1e83b2ea77522a0ca Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Wed, 30 Dec 2020 06:58:45 +0100 Subject: [PATCH 112/271] Update .travis.yml --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index c00fc45..13a86d5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ cache: install: - pip install -U platformio - platformio update - - platformio lib -g install 62@5.0.0 870 872 + - platformio lib -g install 62@5.0.0 870 872 236 script: - pio ci --board=uno --lib=. examples/AVR_Callbacks/AVR_Callbacks.ino @@ -22,5 +22,7 @@ script: - pio ci --board=uno --lib=. examples/AVR_NoteOnOffEverySec/AVR_NoteOnOffEverySec.ino - pio ci --board=uno --lib=. examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino - pio ci --board=uno --lib=. examples/AVR_SysEx/AVR_SysEx.ino +- pio ci --board=mkrzero --lib=. examples/SAMD_Bonjour/SAMD_Bonjour.ino - pio ci --board=huzzah --lib=. examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino - pio ci --board=featheresp32 --lib=. examples/ESP32_NoteOnOffEverySec/ESP32_NoteOnOffEverySec.ino +- pio ci --board=wesp32 --lib=. examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino From 09f5f1674d8e265c335af3c8061373c4eae895ae Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Wed, 30 Dec 2020 07:07:02 +0100 Subject: [PATCH 113/271] Update wESP32_NoteOnOffEverySec.ino --- examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino b/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino index 75f0ed2..c7bc21d 100644 --- a/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino +++ b/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino @@ -2,7 +2,7 @@ #define APPLEMIDI_DEBUG SerialMon #include -#include "ETH_Helper.h" +#include "./ETH_Helper.h" unsigned long t0 = millis(); int8_t isConnected = 0; From 79cbccf8bed605ff142be21ab32847e5b12a9e78 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Wed, 30 Dec 2020 07:10:07 +0100 Subject: [PATCH 114/271] Update .travis.yml --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 13a86d5..0446ebf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,4 +25,3 @@ script: - pio ci --board=mkrzero --lib=. examples/SAMD_Bonjour/SAMD_Bonjour.ino - pio ci --board=huzzah --lib=. examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino - pio ci --board=featheresp32 --lib=. examples/ESP32_NoteOnOffEverySec/ESP32_NoteOnOffEverySec.ino -- pio ci --board=wesp32 --lib=. examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino From ebf3cb531e40c6a50218947e1dc562305a7b9b4c Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Wed, 30 Dec 2020 07:16:34 +0100 Subject: [PATCH 115/271] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 127d277..d528db5 100755 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ Beware: the number of sockets on the Arduino is limited. The W5100 support 4, th Reduce the memory footprint by a further 500 bytes by `#define NO_SESSION_NAME` before `#include `. This will leave out all the code to manage the optional session name. By default the session name is kept. Even further reduce the memory footprint by `#define ONE_PARTICIPANT` limiting the number of particpants to just 1. -On an UNO the absolute minimum memory footprint is 21976 bytes (68%) and 946 global variables (46%). For a Leonardo that is 24916 bytes (86%) and 1112 bytes (43%) of global variables. +On an UNO the absolute minimum memory footprint is 21966 bytes (68%) and 945 global variables (46%). For a Leonardo that is 24916 bytes (86%) and 1112 bytes (43%) of global variables. ## Notes Session names can get really long on Macs (eg 'Macbook Pro of Johann Gambolputty de von Ausfern-schplenden-schlitter-crasscrenbon-fried-digger-dingle-dangle-dongle-dungle-burstein-von-knacker-thrasher-apple-banger-horowitz-ticolensic-grander-knotty-spelltinkle-grandlich-grumblemeyer-spelterwasser-kurstlich-himbleeisen-bahnwagen-gutenabend-bitte-ein-nürnburger-bratwustle-gerspurten-mitzweimache-luber-hundsfut-gumberaber-shönendanker-kalbsfleisch-mittler-aucher von Hautkopft of Ulm') and will be trunctated to the `MaxSessionNameLen` (as set in the settings file). From 2bb78db3416ff9a78ea8b43ce3e6c3f310570ca9 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Wed, 30 Dec 2020 07:17:21 +0100 Subject: [PATCH 116/271] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d528db5..8d3d510 100755 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ Beware: the number of sockets on the Arduino is limited. The W5100 support 4, th Reduce the memory footprint by a further 500 bytes by `#define NO_SESSION_NAME` before `#include `. This will leave out all the code to manage the optional session name. By default the session name is kept. Even further reduce the memory footprint by `#define ONE_PARTICIPANT` limiting the number of particpants to just 1. -On an UNO the absolute minimum memory footprint is 21966 bytes (68%) and 945 global variables (46%). For a Leonardo that is 24916 bytes (86%) and 1112 bytes (43%) of global variables. +On an UNO the absolute minimum memory footprint is 21966 bytes (68%) and 945 global variables (46%). For a Leonardo that is 24906 bytes (86%) and 1111 bytes (43%) of global variables. ## Notes Session names can get really long on Macs (eg 'Macbook Pro of Johann Gambolputty de von Ausfern-schplenden-schlitter-crasscrenbon-fried-digger-dingle-dangle-dongle-dungle-burstein-von-knacker-thrasher-apple-banger-horowitz-ticolensic-grander-knotty-spelltinkle-grandlich-grumblemeyer-spelterwasser-kurstlich-himbleeisen-bahnwagen-gutenabend-bitte-ein-nürnburger-bratwustle-gerspurten-mitzweimache-luber-hundsfut-gumberaber-shönendanker-kalbsfleisch-mittler-aucher von Hautkopft of Ulm') and will be trunctated to the `MaxSessionNameLen` (as set in the settings file). From c9a3e81308e7fcf33dff04136c4260b8a43a3013 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Wed, 30 Dec 2020 07:20:51 +0100 Subject: [PATCH 117/271] Update README.md --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8d3d510..fae754b 100755 --- a/README.md +++ b/README.md @@ -5,12 +5,17 @@ Enables an Arduino with IP/UDP capabilities (Ethernet shield, ESP8266, ESP32, .. ## Features * Build on top of the popular [FortySevenEffects MIDI library](https://github.com/FortySevenEffects/arduino_midi_library) -* Tested with AppleMIDI on Mac OS (Catalina) and using [rtpMIDI](https://www.tobias-erichsen.de/software/rtpmidi.html) from Tobias Erichsen on Windows 10 +* Tested with AppleMIDI on Mac OS (Big Sur) and using [rtpMIDI](https://www.tobias-erichsen.de/software/rtpmidi.html) from Tobias Erichsen on Windows 10 * 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) +## New in 3.0.0 +* Bug Fixes (long session names get cropped) +* Reduced memory footprint (see AVR_MinMemUsage example) +* Extended and revised callbacks to receive AppleMIDI protocol feedback + ## Installation From the Arduino IDE Library Manager, search for AppleMIDI From 24e92b8ec07c2ef62afb14375d99f799669f3c98 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Wed, 30 Dec 2020 07:35:46 +0100 Subject: [PATCH 118/271] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index fae754b..6321efe 100755 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ Enables an Arduino with IP/UDP capabilities (Ethernet shield, ESP8266, ESP32, .. * Bug Fixes (long session names get cropped) * Reduced memory footprint (see AVR_MinMemUsage example) * Extended and revised callbacks to receive AppleMIDI protocol feedback +* Who may connect to me (Directory) (see AVR_Directory example) ## Installation From the Arduino IDE Library Manager, search for AppleMIDI From 299286b50ff4646a7995a356fec80e1d3a0dbe56 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Wed, 30 Dec 2020 07:37:27 +0100 Subject: [PATCH 119/271] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6321efe..221e4f4 100755 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Enables an Arduino with IP/UDP capabilities (Ethernet shield, ESP8266, ESP32, .. ## New in 3.0.0 * Bug Fixes (long session names get cropped) -* Reduced memory footprint (see AVR_MinMemUsage example) +* Reduced memory footprint (see AVR_MinMemUsage example and note below) * Extended and revised callbacks to receive AppleMIDI protocol feedback * Who may connect to me (Directory) (see AVR_Directory example) @@ -86,7 +86,7 @@ Even further reduce the memory footprint by `#define ONE_PARTICIPANT` limiting t On an UNO the absolute minimum memory footprint is 21966 bytes (68%) and 945 global variables (46%). For a Leonardo that is 24906 bytes (86%) and 1111 bytes (43%) of global variables. ## Notes -Session names can get really long on Macs (eg 'Macbook Pro of Johann Gambolputty de von Ausfern-schplenden-schlitter-crasscrenbon-fried-digger-dingle-dangle-dongle-dungle-burstein-von-knacker-thrasher-apple-banger-horowitz-ticolensic-grander-knotty-spelltinkle-grandlich-grumblemeyer-spelterwasser-kurstlich-himbleeisen-bahnwagen-gutenabend-bitte-ein-nürnburger-bratwustle-gerspurten-mitzweimache-luber-hundsfut-gumberaber-shönendanker-kalbsfleisch-mittler-aucher von Hautkopft of Ulm') and will be trunctated to the `MaxSessionNameLen` (as set in the settings file). +Session names can get really long on Macs (eg 'Macbook Pro of Johann Gambolputty .. von Hautkopft of Ulm') and will be trunctated to the `MaxSessionNameLen` (as set in the settings file). ## Arduino IDE (arduino.cc) * 1.8.13 From 4dd5446945d86e398dd565ab67e3311c869b4dd9 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Wed, 30 Dec 2020 07:39:38 +0100 Subject: [PATCH 120/271] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 221e4f4..ab438c2 100755 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Enables an Arduino with IP/UDP capabilities (Ethernet shield, ESP8266, ESP32, .. ## New in 3.0.0 * Bug Fixes (long session names get cropped) * Reduced memory footprint (see AVR_MinMemUsage example and note below) -* Extended and revised callbacks to receive AppleMIDI protocol feedback +* Extended and revised callbacks to receive AppleMIDI protocol feedback (see AVR_Callbacks example) * Who may connect to me (Directory) (see AVR_Directory example) ## Installation From f61d156bdd98bd694570ec923fa34fa4c99c2848 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Wed, 30 Dec 2020 11:05:10 +0100 Subject: [PATCH 121/271] Update library.properties --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index dc7f7f3..72c0552 100644 --- a/library.properties +++ b/library.properties @@ -3,7 +3,7 @@ version=3.0.0 author=lathoub maintainer=lathoub sentence=AppleMIDI (aka rtpMIDI) MIDI I/Os for Arduino -paragraph=AppleMIDI (also known as rtpMIDI) is a protocol to transport MIDI messages within RTP (Real-time Protocol) packets over Ethernet and WiFi networks. Major rewrite of the library to be faster and use less memory. Read the Wiki page when migrating from v1.* to v2.* (API changes) +paragraph=AppleMIDI (also known as rtpMIDI) is a protocol to transport MIDI messages within RTP (Real-time Protocol) packets over Ethernet and WiFi networks. Major rewrite of the library to be faster and use less memory. Read the Wiki page when migrating from v2.* to v3.* (API changes) category=Communication url=https://github.com/lathoub/Arduino-AppleMidi-Library architectures=* From 9bf017614a666b7d735dcfc3457abde3051b9afa Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Thu, 31 Dec 2020 07:40:20 +0100 Subject: [PATCH 122/271] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ab438c2..fde035c 100755 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ More usages in the [examples](https://github.com/lathoub/Arduino-AppleMIDI-Libra * Teensy WIZ820io W5200 ## Memory usage -Out of the box, this library has been setup to use a minimum amount of memory. Extended callbacks are not enabled by default, and can be anabled by USE_EXT_CALLBACKS. See the callback examamples. +Out of the box, this library has been setup to use a minimum amount of memory. Extended callbacks are not enabled by default, and can be anabled by `#USE_EXT_CALLBACKS`. See the callback examamples. This library is not using any dynamic memory allocation methods - all buffers have a fixed size, set in the `AppleMIDI_Settings.h` file, avoiding potential memory leaks and memory fragmentation. From 1ef5ba5a439c85655da37d5acb79a51560144a05 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Thu, 31 Dec 2020 07:41:45 +0100 Subject: [PATCH 123/271] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fde035c..4814116 100755 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ More usages in the [examples](https://github.com/lathoub/Arduino-AppleMIDI-Libra * Teensy WIZ820io W5200 ## Memory usage -Out of the box, this library has been setup to use a minimum amount of memory. Extended callbacks are not enabled by default, and can be anabled by `#USE_EXT_CALLBACKS`. See the callback examamples. +Out of the box, this library has been setup to 'medium' amount of memory (memory usage can be reduced, read below). Extended callbacks are not enabled by default, and can be anabled by `#USE_EXT_CALLBACKS`. See the callback examples. This library is not using any dynamic memory allocation methods - all buffers have a fixed size, set in the `AppleMIDI_Settings.h` file, avoiding potential memory leaks and memory fragmentation. From 2b56848ed503354d90db8b4d95f4cda2c31e04be Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Thu, 31 Dec 2020 07:43:09 +0100 Subject: [PATCH 124/271] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4814116..cd337ed 100755 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ More usages in the [examples](https://github.com/lathoub/Arduino-AppleMIDI-Libra ## Memory usage Out of the box, this library has been setup to 'medium' amount of memory (memory usage can be reduced, read below). Extended callbacks are not enabled by default, and can be anabled by `#USE_EXT_CALLBACKS`. See the callback examples. -This library is not using any dynamic memory allocation methods - all buffers have a fixed size, set in the `AppleMIDI_Settings.h` file, avoiding potential memory leaks and memory fragmentation. +This library is **not using any dynamic memory allocation** methods - all buffers have a fixed size, set in the `AppleMIDI_Settings.h` file, avoiding potential memory leaks and memory fragmentation. The minimum buffer size (`MaxBufferSize`) should be set to 64 bytes (also the default). Setting it to a higher value will make sending larger SysEx messages more efficiant (large SysEx messages are chopped in pieces, the larger the buffer, the less pieces needed), at the price of a bigger memory footprint. From d451d8f9e7b043e469655fe5b2cbbd4acdfc800a Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Thu, 31 Dec 2020 07:44:15 +0100 Subject: [PATCH 125/271] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cd337ed..a78f6af 100755 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ More usages in the [examples](https://github.com/lathoub/Arduino-AppleMIDI-Libra ## Memory usage Out of the box, this library has been setup to 'medium' amount of memory (memory usage can be reduced, read below). Extended callbacks are not enabled by default, and can be anabled by `#USE_EXT_CALLBACKS`. See the callback examples. -This library is **not using any dynamic memory allocation** methods - all buffers have a fixed size, set in the `AppleMIDI_Settings.h` file, avoiding potential memory leaks and memory fragmentation. +This library is **not using any dynamic memory** allocation methods - all buffers have a fixed size, set in the `AppleMIDI_Settings.h` file, avoiding potential memory leaks and memory fragmentation (also, no usage of the String() class). The minimum buffer size (`MaxBufferSize`) should be set to 64 bytes (also the default). Setting it to a higher value will make sending larger SysEx messages more efficiant (large SysEx messages are chopped in pieces, the larger the buffer, the less pieces needed), at the price of a bigger memory footprint. From 564064efeffd592f48701c42f3acad690733527f Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Thu, 31 Dec 2020 07:47:43 +0100 Subject: [PATCH 126/271] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a78f6af..3010f4a 100755 --- a/README.md +++ b/README.md @@ -77,10 +77,10 @@ This library is **not using any dynamic memory** allocation methods - all buffer The minimum buffer size (`MaxBufferSize`) should be set to 64 bytes (also the default). Setting it to a higher value will make sending larger SysEx messages more efficiant (large SysEx messages are chopped in pieces, the larger the buffer, the less pieces needed), at the price of a bigger memory footprint. -`MaxNumberOfParticipants` is another way to cut memory - each particpants uses approx 300 bytes. Default number of participants is 1 (using 2 sockets). -Beware: the number of sockets on the Arduino is limited. The W5100 support 4, the W5200 and W5500 based IP chips can use 8 sockets. (Each participant uses 2 sockets: port 5004 and 5004+1). (Base port can be set in `APPLEMIDI_CREATE_DEFAULT_INSTANCE`) +`MaxNumberOfParticipants` is another way to cut memory - each session particpant uses approx 300 bytes. Default number of participants is 2 (each using 2 sockets). +Beware: the number of sockets on the Arduino is limited. The W5100 support 4 (hance default number of participants is 2), the W5200 and W5500 based IP chips can use 8 sockets. (Base port can be set in `APPLEMIDI_CREATE_DEFAULT_INSTANCE`) -Reduce the memory footprint by a further 500 bytes by `#define NO_SESSION_NAME` before `#include `. This will leave out all the code to manage the optional session name. By default the session name is kept. +Reduce the memory footprint by a further wopping 500 bytes by `#define NO_SESSION_NAME` before `#include `. This will leave out all the code to manage the optional session name. The RtpMIDI service client will show the name as (manually) defined in the directory. Even further reduce the memory footprint by `#define ONE_PARTICIPANT` limiting the number of particpants to just 1. On an UNO the absolute minimum memory footprint is 21966 bytes (68%) and 945 global variables (46%). For a Leonardo that is 24906 bytes (86%) and 1111 bytes (43%) of global variables. From 43964865206c5343898db0324d45e74185c578c6 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Thu, 31 Dec 2020 07:53:45 +0100 Subject: [PATCH 127/271] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3010f4a..e7dceb3 100755 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ From the Arduino IDE Library Manager, search for AppleMIDI This will also install [FortySevenEffects MIDI library](https://github.com/FortySevenEffects/arduino_midi_library) ## Basic Usage -``` +```cpp #include #include @@ -48,7 +48,7 @@ void loop() MIDI.sendNoteOn(40, 55, 1); } -void OnAppleMidiConnected(uint32_t ssrc, const char* name) { +void OnAppleMidiConnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char*) { } ``` From 4f9fbc9741f71fe3420bf5e1d34c26fdb6bf92b8 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Thu, 31 Dec 2020 07:54:36 +0100 Subject: [PATCH 128/271] Update README.md --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e7dceb3..f106ddf 100755 --- a/README.md +++ b/README.md @@ -44,8 +44,11 @@ void loop() // Listen to incoming notes MIDI.read(); - // Send MIDI note 40 on, velocity 55 on channel 1 - MIDI.sendNoteOn(40, 55, 1); + .... + if (something) { + // Send MIDI note 40 on, velocity 55 on channel 1 + MIDI.sendNoteOn(40, 55, 1); + } } void OnAppleMidiConnected(const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char*) { From 3e2e2a698fb75a13cbd629b8d3063785e8678708 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Thu, 31 Dec 2020 08:00:36 +0100 Subject: [PATCH 129/271] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f106ddf..b33ceae 100755 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ More usages in the [examples](https://github.com/lathoub/Arduino-AppleMIDI-Libra * Teensy WIZ820io W5200 ## Memory usage -Out of the box, this library has been setup to 'medium' amount of memory (memory usage can be reduced, read below). Extended callbacks are not enabled by default, and can be anabled by `#USE_EXT_CALLBACKS`. See the callback examples. +Out of the box, this library has been setup to use a 'medium' amount of memory (read below how to reduce the memory footprint). Extended callbacks are not enabled by default, and can be anabled by `#USE_EXT_CALLBACKS`. See the callback examples. This library is **not using any dynamic memory** allocation methods - all buffers have a fixed size, set in the `AppleMIDI_Settings.h` file, avoiding potential memory leaks and memory fragmentation (also, no usage of the String() class). From 3504cfcdab68cbda04f1e15c37ef6750b16927dc Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Fri, 15 Jan 2021 23:18:41 +0100 Subject: [PATCH 130/271] Fixed receive sequenceNr checking bug pParticipant->receiveSequenceNr is a uInt16_t, adding 1 when the value is 0xFFFF does not overflow (due to cast to int (1 is an int by default)). Thank you @bjoernbau for reporting and suggesting the fix --- src/AppleMIDI.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/AppleMIDI.hpp b/src/AppleMIDI.hpp index aa4d656..5a4a43b 100644 --- a/src/AppleMIDI.hpp +++ b/src/AppleMIDI.hpp @@ -1012,11 +1012,11 @@ void AppleMIDISession::ReceivedRtp(const Rtp_t& rt auto offset = (rtp.timestamp - pParticipant->offsetEstimate); auto latency = (int32_t)(rtpMidiClock.Now() - offset); #endif - if (pParticipant->receiveSequenceNr + 1 != rtp.sequenceNr) { + if (rtp.sequenceNr - pParticipant->receiveSequenceNr - 1 != 0) { #ifdef USE_EXT_CALLBACKS if (nullptr != _exceptionCallback) - _exceptionCallback(ssrc, ReceivedPacketsDropped, pParticipant->receiveSequenceNr + 1 - rtp.sequenceNr); + _exceptionCallback(ssrc, ReceivedPacketsDropped, rtp.sequenceNr - pParticipant->receiveSequenceNr - 1); #endif } From 84f3dcae8a0a425c56b9d01d6bdbbcacb5e0a24b Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sat, 16 Jan 2021 06:57:59 +0100 Subject: [PATCH 131/271] avoid ReceivedPacketsDropped for first received packet added firstMessageReceived to the Particpant struct. Set to false when packet is receievd. Only when USE_EXT_CALLBACKS is defined --- src/AppleMIDI.hpp | 14 +++++++------- src/AppleMIDI_Participant.h | 4 +++- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/AppleMIDI.hpp b/src/AppleMIDI.hpp index 5a4a43b..28101a0 100644 --- a/src/AppleMIDI.hpp +++ b/src/AppleMIDI.hpp @@ -1011,21 +1011,21 @@ void AppleMIDISession::ReceivedRtp(const Rtp_t& rt #ifdef USE_EXT_CALLBACKS auto offset = (rtp.timestamp - pParticipant->offsetEstimate); auto latency = (int32_t)(rtpMidiClock.Now() - offset); -#endif - if (rtp.sequenceNr - pParticipant->receiveSequenceNr - 1 != 0) { -#ifdef USE_EXT_CALLBACKS + if (pParticipant->firstMessageReceived == false + && rtp.sequenceNr - pParticipant->receiveSequenceNr - 1 != 0) { + // avoids first message to generate sequence exception + // as we do not know the last sequenceNr received. + pParticipant->firstMessageReceived = false; if (nullptr != _exceptionCallback) _exceptionCallback(ssrc, ReceivedPacketsDropped, rtp.sequenceNr - pParticipant->receiveSequenceNr - 1); -#endif } - pParticipant->receiveSequenceNr = rtp.sequenceNr; - -#ifdef USE_EXT_CALLBACKS if (nullptr != _receivedRtpCallback) _receivedRtpCallback(pParticipant->ssrc, rtp, latency); #endif + + pParticipant->receiveSequenceNr = rtp.sequenceNr; } else { diff --git a/src/AppleMIDI_Participant.h b/src/AppleMIDI_Participant.h index 28dcfcf..fffeb12 100644 --- a/src/AppleMIDI_Participant.h +++ b/src/AppleMIDI_Participant.h @@ -18,7 +18,8 @@ struct Participant bool doReceiverFeedback = false; uint16_t sendSequenceNr = random(1, UINT16_MAX); // http://www.rfc-editor.org/rfc/rfc6295.txt , 2.1. RTP Header - uint16_t receiveSequenceNr; + uint16_t receiveSequenceNr = 0; + unsigned long lastSyncExchangeTime; #ifdef APPLEMIDI_INITIATOR @@ -33,6 +34,7 @@ struct Participant #endif #ifdef USE_EXT_CALLBACKS + bool firstMessageReceived = true; uint32_t offsetEstimate; #endif From e0d38ff602e91fced11c0a6773833b254a7a987e Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sat, 16 Jan 2021 07:14:46 +0100 Subject: [PATCH 132/271] added warning: UDP can drop message when logging in Serial in callback --- examples/AVR_Callbacks/AVR_Callbacks.ino | 6 ++++++ .../AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/examples/AVR_Callbacks/AVR_Callbacks.ino b/examples/AVR_Callbacks/AVR_Callbacks.ino index 6ca0634..c2a7a01 100644 --- a/examples/AVR_Callbacks/AVR_Callbacks.ino +++ b/examples/AVR_Callbacks/AVR_Callbacks.ino @@ -1,5 +1,11 @@ #include + // * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * W A R N I N G * * * * * * * + // logging messages to the Serial port in callback + // can result in dropped UDP messages! + // * * * * * * * * * * * * * * * * * * * * * * + #define USE_EXT_CALLBACKS #define SerialMon Serial #define APPLEMIDI_DEBUG SerialMon diff --git a/examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino b/examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino index e4c1bad..c1c0fa2 100644 --- a/examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino +++ b/examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino @@ -1,5 +1,11 @@ #include + // * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * W A R N I N G * * * * * * * + // logging messages to the Serial port in callback + // can result in dropped UDP messages! + // * * * * * * * * * * * * * * * * * * * * * * + #define USE_EXT_CALLBACKS #define SerialMon Serial #define APPLEMIDI_DEBUG SerialMon From 30d569ec2e4f55881b3d9d7a17414975870cc9cf Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sat, 16 Jan 2021 14:37:10 +0100 Subject: [PATCH 133/271] Create Teensy41_NoteOnOffEverySec.ino --- .../Teensy41_NoteOnOffEverySec.ino | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 examples/Teensy41_NoteOnOffEverySec/Teensy41_NoteOnOffEverySec.ino diff --git a/examples/Teensy41_NoteOnOffEverySec/Teensy41_NoteOnOffEverySec.ino b/examples/Teensy41_NoteOnOffEverySec/Teensy41_NoteOnOffEverySec.ino new file mode 100644 index 0000000..0c686fd --- /dev/null +++ b/examples/Teensy41_NoteOnOffEverySec/Teensy41_NoteOnOffEverySec.ino @@ -0,0 +1,91 @@ +#include + +#define SerialMon Serial +#define APPLEMIDI_DEBUG SerialMon +#include + +// Enter a MAC address for your controller below. +// Newer Ethernet shields have a MAC address printed on a sticker on the shield +byte mac[] = { + 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED +}; + +unsigned long t1 = millis(); +int8_t isConnected = 0; + +APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +void setup() +{ + DBG_SETUP(115200); + DBG("Booting"); + + if (Ethernet.begin(mac) == 0) { + DBG(F("Failed DHCP, check network cable & reboot")); + for (;;); + } + + // Check for Ethernet hardware present + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + DBG("Ethernet shield was not found. Sorry, can't run without hardware. :("); + while (true) { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + while (Ethernet.linkStatus() == LinkOFF) { + DBG("Ethernet cable is not connected."); + delay(500); + } + + DBG(F("OK, now make sure you an rtpMIDI session that is Enabled")); + DBG(F("Add device named Arduino with Host"), Ethernet.localIP(), "Port", AppleMIDI.getPort(), "(Name", AppleMIDI.getName(), ")"); + DBG(F("Select and then press the Connect button")); + DBG(F("Then open a MIDI listener and monitor incoming notes")); + + MIDI.begin(); + + // Stay informed on connection status + AppleMIDI.setHandleConnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const char* name) { + isConnected++; + DBG(F("Connected to session"), ssrc, name); + }); + AppleMIDI.setHandleDisconnected([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc) { + isConnected--; + DBG(F("Disconnected"), ssrc); + }); + + MIDI.setHandleNoteOn([](byte channel, byte note, byte velocity) { + DBG(F("NoteOn"), note); + }); + MIDI.setHandleNoteOff([](byte channel, byte note, byte velocity) { + DBG(F("NoteOff"), note); + }); + + DBG(F("Sending MIDI messages every second")); +} + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +void loop() +{ + // Listen to incoming notes + MIDI.read(); + + // send a note every second + // (dont cáll delay(1000) as it will stall the pipeline) + if ((isConnected > 0) && (millis() - t1) > 1000) + { + t1 = millis(); + + byte note = random(1, 127); + byte velocity = 55; + byte channel = 1; + + MIDI.sendNoteOn(note, velocity, channel); +// MIDI.sendNoteOff(note, velocity, channel); + } +} From d111e9eec5a20916c3ecd672a598f99d331f9551 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sat, 16 Jan 2021 22:13:04 +0100 Subject: [PATCH 134/271] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b33ceae..8bcfad6 100755 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # AppleMIDI (aka rtpMIDI) for Arduino -[![arduino-library-badge](https://www.ardu-badge.com/badge/AppleMIDI.svg?)](https://www.ardu-badge.com/AppleMIDI) [![Build Status](https://travis-ci.org/lathoub/Arduino-AppleMIDI-Library.svg?branch=master)](https://travis-ci.org/lathoub/Arduino-AppleMIDI-Library) [![License: CC BY-SA 4.0](https://img.shields.io/badge/License-CC%20BY--SA%204.0-lightgrey.svg)](http://creativecommons.org/licenses/by-sa/4.0/) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/c8be2ccc3f104e0588572a39f8106070)](https://app.codacy.com/app/lathoub/Arduino-AppleMIDI-Library?utm_source=github.com&utm_medium=referral&utm_content=lathoub/Arduino-AppleMIDI-Library&utm_campaign=Badge_Grade_Dashboard) +[![arduino-library-badge](https://www.ardu-badge.com/badge/AppleMIDI.svg?)](https://www.ardu-badge.com/AppleMIDI) [![Build Status](https://travis-ci.org/lathoub/Arduino-AppleMIDI-Library.svg?branch=master)](https://travis-ci.org/lathoub/Arduino-AppleMIDI-Library) [![License: CC BY-SA 4.0](https://img.shields.io/badge/License-CC%20BY--SA%204.0-lightgrey.svg)](http://creativecommons.org/licenses/by-sa/4.0/) Enables an Arduino with IP/UDP capabilities (Ethernet shield, ESP8266, ESP32, ...) to particpate in an AppleMIDI session. From 6649a4536e6465095b5570bb8c2b1b42e6b4516a Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sun, 17 Jan 2021 21:35:11 +0100 Subject: [PATCH 135/271] bugfix to avoid dropped package thanks @bjoernbau --- src/AppleMIDI.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/AppleMIDI.hpp b/src/AppleMIDI.hpp index 28101a0..a274008 100644 --- a/src/AppleMIDI.hpp +++ b/src/AppleMIDI.hpp @@ -1012,11 +1012,11 @@ void AppleMIDISession::ReceivedRtp(const Rtp_t& rt auto offset = (rtp.timestamp - pParticipant->offsetEstimate); auto latency = (int32_t)(rtpMidiClock.Now() - offset); - if (pParticipant->firstMessageReceived == false - && rtp.sequenceNr - pParticipant->receiveSequenceNr - 1 != 0) { - // avoids first message to generate sequence exception - // as we do not know the last sequenceNr received. + if (pParticipant->firstMessageReceived == true) + // avoids first message to generate sequence exception + // as we do not know the last sequenceNr received. pParticipant->firstMessageReceived = false; + else if (rtp.sequenceNr - pParticipant->receiveSequenceNr - 1 != 0) { if (nullptr != _exceptionCallback) _exceptionCallback(ssrc, ReceivedPacketsDropped, rtp.sequenceNr - pParticipant->receiveSequenceNr - 1); } From cb72859458a3cb53ee3d798e703852327b263baf Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sun, 17 Jan 2021 21:35:37 +0100 Subject: [PATCH 136/271] added setHandleException handler --- .../wESP32_NoteOnOffEverySec.ino | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino b/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino index c7bc21d..0357980 100644 --- a/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino +++ b/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino @@ -1,4 +1,11 @@ + // * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * W A R N I N G * * * * * * * + // logging messages to the Serial port in callback + // can result in dropped UDP messages! + // * * * * * * * * * * * * * * * * * * * * * * + #define SerialMon Serial +#define USE_EXT_CALLBACKS #define APPLEMIDI_DEBUG SerialMon #include @@ -9,6 +16,8 @@ int8_t isConnected = 0; APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE(); +void OnAppleMidiException(const APPLEMIDI_NAMESPACE::ssrc_t&, const APPLEMIDI_NAMESPACE::Exception&, const int32_t); + // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- @@ -38,6 +47,7 @@ void setup() isConnected--; DBG(F("Disconnected"), ssrc); }); + AppleMIDI.setHandleException(OnAppleMidiException); MIDI.setHandleNoteOn([](byte channel, byte note, byte velocity) { DBG(F("NoteOn"), note); @@ -71,3 +81,49 @@ void loop() // MIDI.sendNoteOff(note, velocity, channel); } } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +void OnAppleMidiException(const APPLEMIDI_NAMESPACE::ssrc_t& ssrc, const APPLEMIDI_NAMESPACE::Exception& e, const int32_t value ) { + switch (e) + { + case APPLEMIDI_NAMESPACE::Exception::BufferFullException: + DBG(F("*** BufferFullException")); + break; + case APPLEMIDI_NAMESPACE::Exception::ParseException: + DBG(F("*** ParseException")); + break; + case APPLEMIDI_NAMESPACE::Exception::TooManyParticipantsException: + DBG(F("*** TooManyParticipantsException")); + break; + case APPLEMIDI_NAMESPACE::Exception::UnexpectedInviteException: + DBG(F("*** UnexpectedInviteException")); + break; + case APPLEMIDI_NAMESPACE::Exception::ParticipantNotFoundException: + DBG(F("*** ParticipantNotFoundException"), value); + break; + case APPLEMIDI_NAMESPACE::Exception::ComputerNotInDirectory: + DBG(F("*** ComputerNotInDirectory"), value); + break; + case APPLEMIDI_NAMESPACE::Exception::NotAcceptingAnyone: + DBG(F("*** NotAcceptingAnyone"), value); + break; + case APPLEMIDI_NAMESPACE::Exception::ListenerTimeOutException: + DBG(F("*** ListenerTimeOutException")); + break; + case APPLEMIDI_NAMESPACE::Exception::MaxAttemptsException: + DBG(F("*** MaxAttemptsException")); + break; + case APPLEMIDI_NAMESPACE::Exception::NoResponseFromConnectionRequestException: + DBG(F("***:yyy did't respond to the connection request. Check the address and port, and any firewall or router settings. (time)")); + break; + case APPLEMIDI_NAMESPACE::Exception::SendPacketsDropped: + DBG(F("*** SendPacketsDropped"), value); + break; + case APPLEMIDI_NAMESPACE::Exception::ReceivedPacketsDropped: + DBG(F("*** ReceivedPacketsDropped"), value); + break; + } +} From cdf410e3475132c8079905bc698f571136b63a5e Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sat, 23 Jan 2021 20:48:23 +0100 Subject: [PATCH 137/271] reorg readPacket and ParsePacket --- src/AppleMIDI.h | 21 +++++++++------------ src/AppleMIDI.hpp | 12 ++++++++++-- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/AppleMIDI.h b/src/AppleMIDI.h index dc52ca4..59950ef 100644 --- a/src/AppleMIDI.h +++ b/src/AppleMIDI.h @@ -201,22 +201,19 @@ class AppleMIDISession // assert(outMidiBuffer.size() == 0); // must be empty if (inMidiBuffer.size() > 0) - return true; + return inMidiBuffer.size(); - { - // read packets from both UDP sockets - readDataPackets(); // from socket into dataBuffer - readControlPackets(); // from socket into controlBuffer + // read packets from both UDP sockets + while (readDataPackets()) // from socket into dataBuffer + parseDataPackets(); // from dataBuffer into inMidiBuffer - // parses buffer and places MIDI into inMidiBuffer - parseDataPackets(); // from dataBuffer into inMidiBuffer - parseControlPackets(); // from controlBuffer - } + while (readControlPackets()) // from socket into controlBuffer + parseControlPackets(); // from controlBuffer to AppleMIDI manageReceiverFeedback(); manageSynchronization(); - return false; + return inMidiBuffer.size(); }; byte read() @@ -270,8 +267,8 @@ class AppleMIDISession #endif private: - void readControlPackets(); - void readDataPackets(); + size_t readControlPackets(); + size_t readDataPackets(); void parseControlPackets(); void parseDataPackets(); diff --git a/src/AppleMIDI.hpp b/src/AppleMIDI.hpp index a274008..2211adf 100644 --- a/src/AppleMIDI.hpp +++ b/src/AppleMIDI.hpp @@ -5,7 +5,7 @@ BEGIN_APPLEMIDI_NAMESPACE template -void AppleMIDISession::readControlPackets() +size_t AppleMIDISession::readControlPackets() { size_t packetSize = controlPort.available(); if (packetSize == 0) @@ -20,6 +20,8 @@ void AppleMIDISession::readControlPackets() for (auto i = 0; i < bytesRead; i++) controlBuffer.push_back(packetBuffer[i]); } + + return controlBuffer.size(); } template @@ -40,7 +42,7 @@ void AppleMIDISession::parseControlPackets() } template -void AppleMIDISession::readDataPackets() +size_t AppleMIDISession::readDataPackets() { size_t packetSize = dataPort.available(); if (packetSize == 0) @@ -55,6 +57,8 @@ void AppleMIDISession::readDataPackets() for (auto i = 0; i < bytesRead; i++) dataBuffer.push_back(packetBuffer[i]); } + + return dataBuffer.size(); } template @@ -1017,6 +1021,10 @@ void AppleMIDISession::ReceivedRtp(const Rtp_t& rt // as we do not know the last sequenceNr received. pParticipant->firstMessageReceived = false; else if (rtp.sequenceNr - pParticipant->receiveSequenceNr - 1 != 0) { + + DBG(F("*** rtp.sequenceNr"), rtp.sequenceNr); + DBG(F("*** pParticipant->receiveSequenceNr"), pParticipant->receiveSequenceNr); + if (nullptr != _exceptionCallback) _exceptionCallback(ssrc, ReceivedPacketsDropped, rtp.sequenceNr - pParticipant->receiveSequenceNr - 1); } From 4c57fb66fb4e8e5deb2be7916818d05513f5150a Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sat, 23 Jan 2021 21:01:04 +0100 Subject: [PATCH 138/271] removed warning removed warning for dropped messages --- examples/AVR_Callbacks/AVR_Callbacks.ino | 7 ------- .../AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino | 6 ------ .../wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino | 6 ------ 3 files changed, 19 deletions(-) diff --git a/examples/AVR_Callbacks/AVR_Callbacks.ino b/examples/AVR_Callbacks/AVR_Callbacks.ino index c2a7a01..a920cfd 100644 --- a/examples/AVR_Callbacks/AVR_Callbacks.ino +++ b/examples/AVR_Callbacks/AVR_Callbacks.ino @@ -1,11 +1,5 @@ #include - // * * * * * * * * * * * * * * * * * * * * * * - // * * * * * * * * W A R N I N G * * * * * * * - // logging messages to the Serial port in callback - // can result in dropped UDP messages! - // * * * * * * * * * * * * * * * * * * * * * * - #define USE_EXT_CALLBACKS #define SerialMon Serial #define APPLEMIDI_DEBUG SerialMon @@ -107,7 +101,6 @@ void loop() DBG(F("\nsendNoteOn"), note, velocity, channel); MIDI.sendNoteOn(note, velocity, channel); //MIDI.sendNoteOff(note, velocity, channel); - } } diff --git a/examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino b/examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino index c1c0fa2..e4c1bad 100644 --- a/examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino +++ b/examples/AVR_ReceivedRawMidiData/AVR_ReceivedRawMidiData.ino @@ -1,11 +1,5 @@ #include - // * * * * * * * * * * * * * * * * * * * * * * - // * * * * * * * * W A R N I N G * * * * * * * - // logging messages to the Serial port in callback - // can result in dropped UDP messages! - // * * * * * * * * * * * * * * * * * * * * * * - #define USE_EXT_CALLBACKS #define SerialMon Serial #define APPLEMIDI_DEBUG SerialMon diff --git a/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino b/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino index 0357980..56de14c 100644 --- a/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino +++ b/examples/wESP32_NoteOnOffEverySec/wESP32_NoteOnOffEverySec.ino @@ -1,9 +1,3 @@ - // * * * * * * * * * * * * * * * * * * * * * * - // * * * * * * * * W A R N I N G * * * * * * * - // logging messages to the Serial port in callback - // can result in dropped UDP messages! - // * * * * * * * * * * * * * * * * * * * * * * - #define SerialMon Serial #define USE_EXT_CALLBACKS #define APPLEMIDI_DEBUG SerialMon From 4cecbb0dc5a936ea4debbd0da70d0a357149edc3 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sun, 24 Jan 2021 10:52:40 +0100 Subject: [PATCH 139/271] cosmetic update --- examples/ESP32_NoteOnOffEverySec/ESP32_NoteOnOffEverySec.ino | 1 - .../ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/ESP32_NoteOnOffEverySec/ESP32_NoteOnOffEverySec.ino b/examples/ESP32_NoteOnOffEverySec/ESP32_NoteOnOffEverySec.ino index 1fee9a5..b15e875 100644 --- a/examples/ESP32_NoteOnOffEverySec/ESP32_NoteOnOffEverySec.ino +++ b/examples/ESP32_NoteOnOffEverySec/ESP32_NoteOnOffEverySec.ino @@ -2,7 +2,6 @@ #include #include -#define NO_SESSION_NAME #define SerialMon Serial #define APPLEMIDI_DEBUG SerialMon #include diff --git a/examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino b/examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino index 3385371..bb1dd44 100644 --- a/examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino +++ b/examples/ESP8266_NoteOnOffEverySec/ESP8266_NoteOnOffEverySec.ino @@ -6,7 +6,7 @@ #define APPLEMIDI_DEBUG SerialMon #include -char ssid[] = "yourNetwork"; // your network SSID (name) +char ssid[] = "ssid"; // your network SSID (name) char pass[] = "password"; // your network password (use for WPA, or use as key for WEP) unsigned long t0 = millis(); From a87b1800dfc1e1c9160eef0797778d0f30856969 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sun, 24 Jan 2021 10:57:46 +0100 Subject: [PATCH 140/271] remove debug messages --- src/AppleMIDI.hpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/AppleMIDI.hpp b/src/AppleMIDI.hpp index 2211adf..a6eaf5c 100644 --- a/src/AppleMIDI.hpp +++ b/src/AppleMIDI.hpp @@ -1021,10 +1021,6 @@ void AppleMIDISession::ReceivedRtp(const Rtp_t& rt // as we do not know the last sequenceNr received. pParticipant->firstMessageReceived = false; else if (rtp.sequenceNr - pParticipant->receiveSequenceNr - 1 != 0) { - - DBG(F("*** rtp.sequenceNr"), rtp.sequenceNr); - DBG(F("*** pParticipant->receiveSequenceNr"), pParticipant->receiveSequenceNr); - if (nullptr != _exceptionCallback) _exceptionCallback(ssrc, ReceivedPacketsDropped, rtp.sequenceNr - pParticipant->receiveSequenceNr - 1); } From 7204f7a4cb867b0e3a6bf9e86ded48778a332b27 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sun, 24 Jan 2021 17:59:09 +0100 Subject: [PATCH 141/271] overhaul of endianness def (align with SAMD stack) adding __: htonl > __htonl --- src/AppleMIDI.hpp | 26 +++--- src/AppleMIDI_Debug.h | 2 - src/AppleMIDI_Parser.h | 34 +++---- src/rtpMIDI_Parser.h | 6 +- src/rtpMIDI_Parser_JournalSection.hpp | 6 +- src/utility/endian.h | 127 ++++++++++++-------------- 6 files changed, 94 insertions(+), 107 deletions(-) diff --git a/src/AppleMIDI.hpp b/src/AppleMIDI.hpp index a6eaf5c..f494d8e 100644 --- a/src/AppleMIDI.hpp +++ b/src/AppleMIDI.hpp @@ -489,9 +489,9 @@ void AppleMIDISession::writeInvitation(UdpClass &p port.write((uint8_t *)command, sizeof(amInvitation)); port.write((uint8_t *)amProtocolVersion, sizeof(amProtocolVersion)); - invitation.initiatorToken = htonl(invitation.initiatorToken); + invitation.initiatorToken = __htonl(invitation.initiatorToken); invitation.ssrc = ssrc; - invitation.ssrc = htonl(invitation.ssrc); + invitation.ssrc = __htonl(invitation.ssrc); port.write(reinterpret_cast(&invitation), invitation.getLength()); port.endPacket(); @@ -508,8 +508,8 @@ void AppleMIDISession::writeReceiverFeedback(const controlPort.write((uint8_t *)amReceiverFeedback, sizeof(amReceiverFeedback)); - receiverFeedback.ssrc = htonl(receiverFeedback.ssrc); - receiverFeedback.sequenceNr = htons(receiverFeedback.sequenceNr); + receiverFeedback.ssrc = __htonl(receiverFeedback.ssrc); + receiverFeedback.sequenceNr = __htons(receiverFeedback.sequenceNr); controlPort.write(reinterpret_cast(&receiverFeedback), sizeof(AppleMIDI_ReceiverFeedback)); @@ -526,11 +526,11 @@ void AppleMIDISession::writeSynchronization(const dataPort.write((uint8_t *)amSignature, sizeof(amSignature)); dataPort.write((uint8_t *)amSynchronization, sizeof(amSynchronization)); synchronization.ssrc = ssrc; - synchronization.ssrc = htonl(synchronization.ssrc); + synchronization.ssrc = __htonl(synchronization.ssrc); - synchronization.timestamps[0] = htonll(synchronization.timestamps[0]); - synchronization.timestamps[1] = htonll(synchronization.timestamps[1]); - synchronization.timestamps[2] = htonll(synchronization.timestamps[2]); + synchronization.timestamps[0] = __htonll(synchronization.timestamps[0]); + synchronization.timestamps[1] = __htonll(synchronization.timestamps[1]); + synchronization.timestamps[2] = __htonll(synchronization.timestamps[2]); dataPort.write(reinterpret_cast(&synchronization), sizeof(synchronization)); dataPort.endPacket(); @@ -547,8 +547,8 @@ void AppleMIDISession::writeEndSession(const IPAdd controlPort.write((uint8_t *)amEndSession, sizeof(amEndSession)); controlPort.write((uint8_t *)amProtocolVersion, sizeof(amProtocolVersion)); - endSession.initiatorToken = htonl(endSession.initiatorToken); - endSession.ssrc = htonl(endSession.ssrc); + endSession.initiatorToken = __htonl(endSession.initiatorToken); + endSession.ssrc = __htonl(endSession.ssrc); controlPort.write(reinterpret_cast(&endSession), sizeof(endSession)); @@ -613,9 +613,9 @@ void AppleMIDISession::writeRtpMidiBuffer(Particip _sentRtpCallback(rtp); #endif - rtp.timestamp = htonl(rtp.timestamp); - rtp.ssrc = htonl(rtp.ssrc); - rtp.sequenceNr = htons(rtp.sequenceNr); + rtp.timestamp = __htonl(rtp.timestamp); + rtp.ssrc = __htonl(rtp.ssrc); + rtp.sequenceNr = __htons(rtp.sequenceNr); dataPort.write((uint8_t *)&rtp, sizeof(rtp)); diff --git a/src/AppleMIDI_Debug.h b/src/AppleMIDI_Debug.h index 342cc81..3d65291 100644 --- a/src/AppleMIDI_Debug.h +++ b/src/AppleMIDI_Debug.h @@ -2,9 +2,7 @@ namespace { static void DBG_SETUP(unsigned long baud) { APPLEMIDI_DEBUG.begin(baud); - #ifdef __AVR_ATmega32U4__ while (!APPLEMIDI_DEBUG); - #endif } template diff --git a/src/AppleMIDI_Parser.h b/src/AppleMIDI_Parser.h index 6c4dd8a..198740e 100644 --- a/src/AppleMIDI_Parser.h +++ b/src/AppleMIDI_Parser.h @@ -67,14 +67,14 @@ class AppleMIDIParser cb.buffer[1] = buffer[i++]; cb.buffer[2] = buffer[i++]; cb.buffer[3] = buffer[i++]; - invitation.initiatorToken = ntohl(cb.value32); + invitation.initiatorToken = __ntohl(cb.value32); // The sender's synchronization source identifier. cb.buffer[0] = buffer[i++]; cb.buffer[1] = buffer[i++]; cb.buffer[2] = buffer[i++]; cb.buffer[3] = buffer[i++]; - invitation.ssrc = ntohl(cb.value32); + invitation.ssrc = __ntohl(cb.value32); #ifdef KEEP_SESSION_NAME uint16_t bi = 0; @@ -127,14 +127,14 @@ class AppleMIDIParser cb.buffer[1] = buffer[i++]; cb.buffer[2] = buffer[i++]; cb.buffer[3] = buffer[i++]; - endSession.initiatorToken = ntohl(cb.value32); + endSession.initiatorToken = __ntohl(cb.value32); // The sender's synchronization source identifier. cb.buffer[0] = buffer[i++]; cb.buffer[1] = buffer[i++]; cb.buffer[2] = buffer[i++]; cb.buffer[3] = buffer[i++]; - endSession.ssrc = ntohl(cb.value32); + endSession.ssrc = __ntohl(cb.value32); while (i--) buffer.pop_front(); // consume all the bytes that made up this message @@ -157,7 +157,7 @@ class AppleMIDIParser cb.buffer[1] = buffer[i++]; cb.buffer[2] = buffer[i++]; cb.buffer[3] = buffer[i++]; - synchronization.ssrc = ntohl(cb.value32); + synchronization.ssrc = __ntohl(cb.value32); synchronization.count = buffer[i++]; buffer[i++]; @@ -171,7 +171,7 @@ class AppleMIDIParser cb.buffer[5] = buffer[i++]; cb.buffer[6] = buffer[i++]; cb.buffer[7] = buffer[i++]; - synchronization.timestamps[0] = ntohll(cb.value64); + synchronization.timestamps[0] = __ntohll(cb.value64); cb.buffer[0] = buffer[i++]; cb.buffer[1] = buffer[i++]; @@ -181,7 +181,7 @@ class AppleMIDIParser cb.buffer[5] = buffer[i++]; cb.buffer[6] = buffer[i++]; cb.buffer[7] = buffer[i++]; - synchronization.timestamps[1] = ntohll(cb.value64); + synchronization.timestamps[1] = __ntohll(cb.value64); cb.buffer[0] = buffer[i++]; cb.buffer[1] = buffer[i++]; @@ -191,7 +191,7 @@ class AppleMIDIParser cb.buffer[5] = buffer[i++]; cb.buffer[6] = buffer[i++]; cb.buffer[7] = buffer[i++]; - synchronization.timestamps[2] = ntohll(cb.value64); + synchronization.timestamps[2] = __ntohll(cb.value64); while (i--) buffer.pop_front(); // consume all the bytes that made up this message @@ -212,14 +212,14 @@ class AppleMIDIParser cb.buffer[1] = buffer[i++]; cb.buffer[2] = buffer[i++]; cb.buffer[3] = buffer[i++]; - receiverFeedback.ssrc = ntohl(cb.value32); + receiverFeedback.ssrc = __ntohl(cb.value32); cb.buffer[0] = buffer[i++]; cb.buffer[1] = buffer[i++]; - receiverFeedback.sequenceNr = ntohs(cb.value16); + receiverFeedback.sequenceNr = __ntohs(cb.value16); cb.buffer[0] = buffer[i++]; cb.buffer[1] = buffer[i++]; - receiverFeedback.dummy = ntohs(cb.value16); + receiverFeedback.dummy = __ntohs(cb.value16); while (i--) buffer.pop_front(); // consume all the bytes that made up this message @@ -256,14 +256,14 @@ class AppleMIDIParser cb.buffer[1] = buffer[i++]; cb.buffer[2] = buffer[i++]; cb.buffer[3] = buffer[i++]; - invitationAccepted.initiatorToken = ntohl(cb.value32); + invitationAccepted.initiatorToken = __ntohl(cb.value32); // The sender's synchronization source identifier. cb.buffer[0] = buffer[i++]; cb.buffer[1] = buffer[i++]; cb.buffer[2] = buffer[i++]; cb.buffer[3] = buffer[i++]; - invitationAccepted.ssrc = ntohl(cb.value32); + invitationAccepted.ssrc = __ntohl(cb.value32); #ifdef KEEP_SESSION_NAME uint16_t bi = 0; @@ -318,14 +318,14 @@ class AppleMIDIParser cb.buffer[1] = buffer[i++]; cb.buffer[2] = buffer[i++]; cb.buffer[3] = buffer[i++]; - invitationRejected.initiatorToken = ntohl(cb.value32); + invitationRejected.initiatorToken = __ntohl(cb.value32); // The sender's synchronization source identifier. cb.buffer[0] = buffer[i++]; cb.buffer[1] = buffer[i++]; cb.buffer[2] = buffer[i++]; cb.buffer[3] = buffer[i++]; - invitationRejected.ssrc = ntohl(cb.value32); + invitationRejected.ssrc = __ntohl(cb.value32); #ifdef KEEP_SESSION_NAME uint16_t bi = 0; @@ -365,13 +365,13 @@ class AppleMIDIParser cb.buffer[1] = buffer[i++]; cb.buffer[2] = buffer[i++]; cb.buffer[3] = buffer[i++]; - bitrateReceiveLimit.ssrc = ntohl(cb.value32); + bitrateReceiveLimit.ssrc = __ntohl(cb.value32); cb.buffer[0] = buffer[i++]; cb.buffer[1] = buffer[i++]; cb.buffer[2] = buffer[i++]; cb.buffer[3] = buffer[i++]; - bitrateReceiveLimit.bitratelimit = ntohl(cb.value32); + bitrateReceiveLimit.bitratelimit = __ntohl(cb.value32); while (i--) buffer.pop_front(); // consume all the bytes that made up this message diff --git a/src/rtpMIDI_Parser.h b/src/rtpMIDI_Parser.h index 30e1eb6..2095b84 100644 --- a/src/rtpMIDI_Parser.h +++ b/src/rtpMIDI_Parser.h @@ -75,17 +75,17 @@ class rtpMIDIParser cb.buffer[0] = buffer[i++]; cb.buffer[1] = buffer[i++]; - rtp.sequenceNr = ntohs(cb.value16); + rtp.sequenceNr = __ntohs(cb.value16); cb.buffer[0] = buffer[i++]; cb.buffer[1] = buffer[i++]; cb.buffer[2] = buffer[i++]; cb.buffer[3] = buffer[i++]; - rtp.timestamp = ntohl(cb.value32); + rtp.timestamp = __ntohl(cb.value32); cb.buffer[0] = buffer[i++]; cb.buffer[1] = buffer[i++]; cb.buffer[2] = buffer[i++]; cb.buffer[3] = buffer[i++]; - rtp.ssrc = ntohl(cb.value32); + rtp.ssrc = __ntohl(cb.value32); uint8_t version = RTP_VERSION(rtp.vpxcc); #ifdef DEBUG diff --git a/src/rtpMIDI_Parser_JournalSection.hpp b/src/rtpMIDI_Parser_JournalSection.hpp index 1606224..b6edebe 100644 --- a/src/rtpMIDI_Parser_JournalSection.hpp +++ b/src/rtpMIDI_Parser_JournalSection.hpp @@ -48,7 +48,7 @@ parserReturn decodeJournalSection(RtpBuffer_t &buffer) // stream (modulo 2^16). cb.buffer[0] = buffer[i++]; cb.buffer[1] = buffer[i++]; - // uint16_t checkPoint = ntohs(cb.value16); ; // unused + // uint16_t checkPoint = __ntohs(cb.value16); ; // unused // (RFC 4695, 5 Recovery Journal Format) // If A and Y are both zero, the recovery journal only contains its 3- @@ -90,7 +90,7 @@ parserReturn decodeJournalSection(RtpBuffer_t &buffer) cb.buffer[0] = buffer[i++]; cb.buffer[1] = buffer[i++]; - uint16_t systemflags = ntohs(cb.value16); + uint16_t systemflags = __ntohs(cb.value16); uint16_t sysjourlen = systemflags & RTP_MIDI_SJ_MASK_LENGTH; uint16_t remainingBytes = sysjourlen - 2; @@ -129,7 +129,7 @@ parserReturn decodeJournalSection(RtpBuffer_t &buffer) cb.buffer[1] = buffer[0]; cb.buffer[2] = buffer[1]; cb.buffer[3] = buffer[2]; - uint32_t chanflags = ntohl(cb.value32); + uint32_t chanflags = __ntohl(cb.value32); uint16_t chanjourlen = (chanflags & RTP_MIDI_CJ_MASK_LENGTH) >> 8; // uint16_t channelNr = (chanflags & RTP_MIDI_CJ_MASK_CHANNEL) >> RTP_MIDI_CJ_CHANNEL_SHIFT; // unused diff --git a/src/utility/endian.h b/src/utility/endian.h index 2ae8cf0..b4de809 100644 --- a/src/utility/endian.h +++ b/src/utility/endian.h @@ -1,89 +1,78 @@ #pragma once -#if !defined(BYTE_ORDER) +#if !defined(_BYTE_ORDER) - #ifndef BIG_ENDIANs - #define BIG_ENDIAN 4321 - #endif - #ifndef LITTLE_ENDIAN - #define LITTLE_ENDIAN 1234 - #endif + #define _BIG_ENDIAN 4321 + #define _LITTLE_ENDIAN 1234 #define TEST_LITTLE_ENDIAN (((union { unsigned x; unsigned char c; }){1}).c) #ifdef TEST_LITTLE_ENDIAN - #define BYTE_ORDER LITTLE_ENDIAN + #define _BYTE_ORDER _LITTLE_ENDIAN #else - #define BYTE_ORDER BIG_ENDIAN + #define _BYTE_ORDER _BIG_ENDIAN #endif #undef TEST_LITTLE_ENDIAN -#endif -#include + #include -#ifndef __bswap16 - #define __bswap16(x) ((uint16_t)((((uint16_t)(x)&0xff00) >> 8) | (((uint16_t)(x)&0x00ff) << 8))) -#endif + #ifdef __GNUC__ + #define __bswap16(_x) __builtin_bswap16(_x) + #define __bswap32(_x) __builtin_bswap32(_x) + #define __bswap64(_x) __builtin_bswap64(_x) + #else /* __GNUC__ */ -#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))) -#endif + static __inline __uint16_t + __bswap16(__uint16_t _x) + { + return ((__uint16_t)((_x >> 8) | ((_x << 8) & 0xff00))); + } -#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))) -#endif + static __inline __uint32_t + __bswap32(__uint32_t _x) + { + return ((__uint32_t)((_x >> 24) | ((_x >> 8) & 0xff00) | + ((_x << 8) & 0xff0000) | ((_x << 24) & 0xff000000))); + } -#if BYTE_ORDER == LITTLE_ENDIAN - -#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 + static __inline __uint64_t + __bswap64(__uint64_t _x) + { + return ((__uint64_t)((_x >> 56) | ((_x >> 40) & 0xff00) | + ((_x >> 24) & 0xff0000) | ((_x >> 8) & 0xff000000) | + ((_x << 8) & ((__uint64_t)0xff << 32)) | + ((_x << 24) & ((__uint64_t)0xff << 40)) | + ((_x << 40) & ((__uint64_t)0xff << 48)) | ((_x << 56)))); + } + #endif /* !__GNUC__ */ -#else // BIG_ENDIAN + #ifndef __machine_host_to_from_network_defined + #if _BYTE_ORDER == _LITTLE_ENDIAN + #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) + #else // BIG_ENDIAN + #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)) + #endif + #endif /* __machine_host_to_from_network_defined */ -#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 /* _BYTE_ORDER */ +#ifndef __machine_host_to_from_network_defined +#if _BYTE_ORDER == _LITTLE_ENDIAN +#define __ntohll(x) __bswap64(x) +#define __htonll(x) __bswap64(x) +#else // BIG_ENDIAN +#define __ntohll(x) ((uint64_t)(x)) +#define __htonll(x) ((uint64_t)(x)) #endif +#endif /* __machine_host_to_from_network_defined */ From 1fb132123fff751f9b5407ba3f47dc1c264d664f Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sun, 24 Jan 2021 20:43:28 +0100 Subject: [PATCH 142/271] Update AppleMIDI.h Read followed by PacketParse reduce the need for a larger buffer --- src/AppleMIDI.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/AppleMIDI.h b/src/AppleMIDI.h index 59950ef..02b081d 100644 --- a/src/AppleMIDI.h +++ b/src/AppleMIDI.h @@ -204,10 +204,10 @@ class AppleMIDISession return inMidiBuffer.size(); // read packets from both UDP sockets - while (readDataPackets()) // from socket into dataBuffer + (readDataPackets()); // from socket into dataBuffer parseDataPackets(); // from dataBuffer into inMidiBuffer - while (readControlPackets()) // from socket into controlBuffer + (readControlPackets()); // from socket into controlBuffer parseControlPackets(); // from controlBuffer to AppleMIDI manageReceiverFeedback(); From 85aa498cd7d9fb3d7d58c75b476fccd8135be612 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sun, 24 Jan 2021 22:20:50 +0100 Subject: [PATCH 143/271] added callbacks, optimize packet reading --- examples/AVR_Callbacks/AVR_Callbacks.ino | 31 +++++++++++++++--------- src/AppleMIDI.h | 7 +++--- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/examples/AVR_Callbacks/AVR_Callbacks.ino b/examples/AVR_Callbacks/AVR_Callbacks.ino index a920cfd..30141d2 100644 --- a/examples/AVR_Callbacks/AVR_Callbacks.ino +++ b/examples/AVR_Callbacks/AVR_Callbacks.ino @@ -36,7 +36,7 @@ void setup() DBG(F("Select and then press the Connect button")); DBG(F("Then open a MIDI listener and monitor incoming notes")); - MIDI.begin(); + MIDI.begin(MIDI_CHANNEL_OMNI); // Normal callbacks - always available // Stay informed on connection status @@ -51,30 +51,39 @@ void setup() // Extended callback, only available when defining USE_EXT_CALLBACKS AppleMIDI.setHandleSentRtp([](const APPLEMIDI_NAMESPACE::Rtp_t & rtp) { - DBG(F("an rtpMessage has been sent with sequenceNr"), rtp.sequenceNr); + // DBG(F("an rtpMessage has been sent with sequenceNr"), rtp.sequenceNr); }); AppleMIDI.setHandleSentRtpMidi([](const APPLEMIDI_NAMESPACE::RtpMIDI_t& rtpMidi) { - DBG(F("an rtpMidiMessage has been sent"), rtpMidi.flags); + // DBG(F("an rtpMidiMessage has been sent"), rtpMidi.flags); }); AppleMIDI.setHandleReceivedRtp([](const APPLEMIDI_NAMESPACE::ssrc_t & ssrc, const APPLEMIDI_NAMESPACE::Rtp_t & rtp, const int32_t& latency) { - DBG(F("setHandleReceivedRtp"), ssrc, rtp.sequenceNr , "with", latency, "ms latency"); + // DBG(F("setHandleReceivedRtp"), ssrc, rtp.sequenceNr , "with", latency, "ms latency"); }); AppleMIDI.setHandleStartReceivedMidi([](const APPLEMIDI_NAMESPACE::ssrc_t& ssrc) { - DBG(F("setHandleStartReceivedMidi from SSRC"), ssrc); + // DBG(F("setHandleStartReceivedMidi from SSRC"), ssrc); }); AppleMIDI.setHandleReceivedMidi([](const APPLEMIDI_NAMESPACE::ssrc_t& ssrc, byte value) { - DBG(F("setHandleReceivedMidi from SSRC"), ssrc, ", value:", value); + // DBG(F("setHandleReceivedMidi from SSRC"), ssrc, ", value:", value); }); AppleMIDI.setHandleEndReceivedMidi([](const APPLEMIDI_NAMESPACE::ssrc_t& ssrc) { - DBG(F("setHandleEndReceivedMidi from SSRC"), ssrc); + // DBG(F("setHandleEndReceivedMidi from SSRC"), ssrc); }); AppleMIDI.setHandleException(OnAppleMidiException); + MIDI.setHandleControlChange([](Channel channel, byte v1, byte v2) { + DBG(F("ControlChange"), channel, v1, v2); + }); + MIDI.setHandleProgramChange([](Channel channel, byte v1) { + DBG(F("ProgramChange"), channel, v1); + }); + MIDI.setHandlePitchBend([](Channel channel, int v1) { + DBG(F("PitchBend"), channel, v1); + }); MIDI.setHandleNoteOn([](byte channel, byte note, byte velocity) { - DBG(F("NoteOn"), note); + DBG(F("NoteOn"), channel, note, velocity); }); MIDI.setHandleNoteOff([](byte channel, byte note, byte velocity) { - DBG(F("NoteOff"), note); + DBG(F("NoteOff"), channel, note, velocity); }); DBG(F("Sending MIDI messages every second")); @@ -98,8 +107,8 @@ void loop() byte velocity = 55; byte channel = 1; - DBG(F("\nsendNoteOn"), note, velocity, channel); - MIDI.sendNoteOn(note, velocity, channel); + // DBG(F("\nsendNoteOn"), note, velocity, channel); + // MIDI.sendNoteOn(note, velocity, channel); //MIDI.sendNoteOff(note, velocity, channel); } } diff --git a/src/AppleMIDI.h b/src/AppleMIDI.h index 02b081d..20c0f2f 100644 --- a/src/AppleMIDI.h +++ b/src/AppleMIDI.h @@ -203,12 +203,11 @@ class AppleMIDISession if (inMidiBuffer.size() > 0) return inMidiBuffer.size(); - // read packets from both UDP sockets - (readDataPackets()); // from socket into dataBuffer + if (readDataPackets()) // from socket into dataBuffer parseDataPackets(); // from dataBuffer into inMidiBuffer - (readControlPackets()); // from socket into controlBuffer - parseControlPackets(); // from controlBuffer to AppleMIDI + if (readControlPackets()) // from socket into controlBuffer + parseControlPackets(); // from controlBuffer to AppleMIDI manageReceiverFeedback(); manageSynchronization(); From dafc07792860512ae2ba45e52510bade4dfc70a8 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Wed, 27 Jan 2021 08:44:42 +0100 Subject: [PATCH 144/271] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 38 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 20 ++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..dd84ea7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,38 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..bbcbbe7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. From 066d657fca431196d70b164ba18e3a83c0643967 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Wed, 27 Jan 2021 08:46:35 +0100 Subject: [PATCH 145/271] Create config.yml --- .github/ISSUE_TEMPLATE/config.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/config.yml diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..0261b2b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: Discussions + url: https://github.com/lathoub/Arduino-AppleMIDI-Library/discussions + about: Not a bug or a feature request ? Discuss your problem, ask for help or show what you've built in Discussions. From 7be676a09d4a2d518f55055ab37c469a656eeada Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Wed, 27 Jan 2021 08:53:04 +0100 Subject: [PATCH 146/271] Update bug_report.md --- .github/ISSUE_TEMPLATE/bug_report.md | 81 +++++++++++++++++++--------- 1 file changed, 56 insertions(+), 25 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index dd84ea7..b5eb826 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,38 +1,69 @@ --- name: Bug report -about: Create a report to help us improve +about: Report something that does not work as intended title: '' -labels: '' +labels: bug assignees: '' --- -**Describe the bug** -A clear and concise description of what the bug is. + -**Expected behavior** -A clear and concise description of what you expected to happen. +## Context -**Screenshots** -If applicable, add screenshots to help explain your problem. +Please answer a few questions to help us understand your problem better and guide you to a solution: -**Desktop (please complete the following information):** - - OS: [e.g. iOS] - - Browser [e.g. chrome, safari] - - Version [e.g. 22] + -**Additional context** -Add any other context about the problem here. +- What board are you using ? + - `example: Arduino Leonardo` + - _Please list any shields or other **relevant** hardware you're using_ +- What version of the Arduino IDE are you using ? + - `example: 1.8.5` +- What Operating System are you using for the DAW + - [ ] Windows + - [ ] MacOS + - [ ] Linux + - [ ] Other (please specify) +- Is your problem related to: + - [ ] Setup + - [ ] Connecting + - [ ] AppleMIDI <> MIDI + - [ ] Dropped messages +- How comfortable are you with code ? + - [ ] Complete beginner + - [ ] I've done basic projects + - [ ] I know my way around C/C++ + - [ ] Advanced / professional + +## Describe your project and what you expect to happen: + + + +## Describe your problem (what does not work): + + + +## Steps to reproduce + + From 63d1bba301d9400388640d6d86763e1e3b54c305 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Wed, 27 Jan 2021 08:54:17 +0100 Subject: [PATCH 147/271] Update bug_report.md --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index b5eb826..0aa3ff0 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -18,7 +18,7 @@ https://github.com/lathoub/Arduino-AppleMIDI-Library/discussions/new ## Context -Please answer a few questions to help us understand your problem better and guide you to a solution: +Using the English language, please answer a few questions to help us understand your problem better and guide you to a solution: