Skip to content

Commit 80141cf

Browse files
authored
Merge pull request #80 from lathoub/feat/2.0.0
Feat/2.0.0
2 parents 78dfafd + 81ba8cc commit 80141cf

File tree

83 files changed

+5829
-7700
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+5829
-7700
lines changed

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
11
.DS_Store
22
examples/.DS_Store
33
src/.DS_Store
4+
test/.vs
5+
test/Debug
6+
examples/ESP32_NoteOnOffEverySec/config.h
7+
src/.vscode
8+
test/x64
9+
.development
10+
examples/ESP32_NoteOnOffEverySec/credentials.h

.travis.yml

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,7 @@ cache:
1010
install:
1111
- pip install -U platformio
1212
- platformio update
13-
- platformio lib -g install 870 872
13+
- platformio lib -g install [email protected] 870 872
1414

1515
script:
16-
- platformio ci --board=huzzah --lib=. examples/Esp32_NoteOnOffEverySec/Esp32_NoteOnOffEverySec.ino;
17-
- platformio ci --board=huzzah --lib=. examples/Esp8266_2Sessions_NoteOnOffEverySec/Esp8266_2Sessions_NoteOnOffEverySec.ino;
18-
- platformio ci --board=huzzah --lib=. examples/Esp8266_NoteOnOffEverySec/Esp8266_NoteOnOffEverySec.ino;
19-
- platformio ci --board=uno --lib=. examples/EthernetShield_InitiateSession/EthernetShield_InitiateSession.ino;
20-
- platformio ci --board=uno --lib=. examples/EthernetShield_InitiateSessions/EthernetShield_InitiateSessions.ino;
2116
- platformio ci --board=uno --lib=. examples/EthernetShield_NoteOnOffEverySec/EthernetShield_NoteOnOffEverySec.ino;
22-
- platformio ci --board=uno --lib=. examples/EthernetShield_RealTimeMessages/EthernetShield_RealTimeMessages.ino;
23-
- platformio ci --board=uno --lib=. examples/EthernetShield_ReceiveMTC/EthernetShield_ReceiveMTC.ino;
24-
- platformio ci --board=uno --lib=. examples/EthernetShield_SysEx/EthernetShield_SysEx.ino;
25-
- platformio ci --board=uno --lib=. examples/Wifi_NoteOnOffEverySec/Wifi_NoteOnOffEverySec.ino;

README.md

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
Enables an Arduino with IP/UDP capabilities (Ethernet shield, ESP8266, ESP32, ...) to particpate in an AppleMIDI session.
55

66
## Features
7-
* Tested with AppleMIDI on Mac OS (High Sierra) and using [rtpMIDI](https://www.tobias-erichsen.de/software/rtpmidi.html) from Tobias Erichsen on Windows 10
7+
* Tested with AppleMIDI on Mac OS (Catalina) and using [rtpMIDI](https://www.tobias-erichsen.de/software/rtpmidi.html) from Tobias Erichsen on Windows 10
88
* Send and receive all MIDI messages
99
* Uses callbacks to receive MIDI commands (no need for polling)
1010
* Automatic instantiation of AppleMIDI object (see at the end of 'AppleMidi.h')
@@ -15,23 +15,29 @@ From the Arduino IDE Library Manager, search for AppleMIDI
1515

1616
## Basic Usage
1717
```
18-
#include "AppleMidi.h"
18+
#include <Ethernet.h>
19+
#include <AppleMidi.h>
1920
20-
APPLEMIDI_CREATE_DEFAULT_INSTANCE();
21+
APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE();
2122
2223
void setup()
2324
{
24-
// ...setup ethernet connection
25-
AppleMIDI.begin("test"); // 'test' will show up as the session name
25+
MIDI.begin(1);
26+
27+
// Optional
28+
AppleMIDI.setHandleConnected(OnAppleMidiConnected);
2629
}
2730
2831
void loop()
2932
{
30-
AppleMIDI.run();
31-
// ...
33+
// Listen to incoming notes
34+
MIDI.read();
3235
3336
// Send MIDI note 40 on, velocity 55 on channel 1
34-
AppleMIDI.sendNoteOn(40, 55, 1);
37+
MIDI.sendNoteOn(40, 55, 1);
38+
}
39+
40+
void OnAppleMidiConnected(uint32_t ssrc, const char* name) {
3541
}
3642
```
3743
More usages in the `examples` folder
@@ -44,21 +50,21 @@ More usages in the `examples` folder
4450
* Adafruit Feather M0 WiFi - ATSAMD21 + ATWINC1500
4551

4652
## Memory usage
47-
The code has been pseudo optimized to minimize the memory footprint.
48-
Internal buffers also use valuable memory space. The biggest buffer `PACKET_MAX_SIZE` is set to 350 by default in `AppleMidi_Settings.h`. Albeit this number is somewhat arbitratry (large enough to receive full SysEx messages), it can be reduced significantly if you do not have to receive large messages.
53+
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.
4954

50-
On an Arduino, 2 sessions can be active at once (W5100 can have max 4 sockets open at the same time, each session needs 2 UDP sockets). Setting MAX_SESSIONS to 1 saves 228 bytes (each session takes 228 bytes).
55+
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.
5156

52-
Save memory (about 2000 bytes) when the device does not initiate sessions by `#undef APPLEMIDI_REMOTE_SESSIONS` in `AppleMidi_Settings.h`. See the `EthernetShield_NoteOnOffEverySec.ino` example
57+
`MaxNumberOfParticipants` is another way to cut memory - each particpants uses approx 300 bytes. Default number of participants is 1 (using 2 sockets).
58+
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`)
5359

5460
## Network Shields
55-
* Arduino Ethernet shield (Wiznet W5100)
61+
* Arduino Ethernet shield (Wiznet W5100 and W5500)
5662
* Arduino Wifi R3 shield
5763
* MKR ETH shield
5864
* Teensy WIZ820io W5200
5965

6066
## Arduino IDE (arduino.cc)
61-
* 1.8.9
67+
* 1.8.10
6268

6369
## Contributing
6470
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.

examples/Basic_IO/Basic_IO.ino

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#include <Ethernet.h>
2+
#include <AppleMIDI.h>
3+
4+
// Enter a MAC address for your controller below.
5+
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
6+
byte mac[] = {
7+
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
8+
};
9+
10+
// Simple tutorial on how to receive and send MIDI messages.
11+
// Here, when receiving any message on channel 4, the Arduino
12+
// will blink a led and play back a note for 1 second.
13+
14+
APPLEMIDI_CREATE_DEFAULTSESSION_INSTANCE();
15+
16+
void setup()
17+
{
18+
if (Ethernet.begin(mac) == 0) {
19+
Serial.println(F("Failed DHCP, check network cable & reboot"));
20+
for (;;);
21+
}
22+
23+
pinMode(LED_BUILTIN, OUTPUT);
24+
MIDI.begin(4); // Launch MIDI and listen to channel 4
25+
}
26+
27+
void loop()
28+
{
29+
if (MIDI.read()) // If we have received a message
30+
{
31+
digitalWrite(LED_BUILTIN, HIGH);
32+
MIDI.sendNoteOn(42, 127, 1); // Send a Note (pitch 42, velo 127 on channel 1)
33+
delay(1000); // Wait for a second
34+
MIDI.sendNoteOff(42, 0, 1); // Stop the note
35+
digitalWrite(LED_BUILTIN, LOW);
36+
}
37+
}
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,48 @@
1-
// These need to be included when using standard Ethernet
2-
#include <WiFi.h>
3-
#include <WiFiClient.h>
4-
#include <WiFiUdp.h>
1+
#include "ETH_Helper.h"
52

6-
#include "AppleMidi.h"
7-
8-
char ssid[] = "yourNetwork"; // your network SSID (name)
9-
char pass[] = "password"; // your network password (use for WPA, or use as key for WEP)
3+
#include <AppleMIDI.h>
4+
USING_NAMESPACE_APPLEMIDI
105

116
unsigned long t0 = millis();
127
bool isConnected = false;
138

14-
APPLEMIDI_CREATE_INSTANCE(WiFiUDP, AppleMIDI); // see definition in AppleMidi_Defs.h
9+
APPLEMIDI_CREATE_DEFAULTSESSION_ESP32_INSTANCE();
1510

1611
// -----------------------------------------------------------------------------
1712
//
1813
// -----------------------------------------------------------------------------
1914
void setup()
2015
{
21-
// Serial communications and wait for port to open:
2216
Serial.begin(115200);
23-
while (!Serial) {
24-
; // wait for serial port to connect. Needed for Leonardo only
25-
}
26-
27-
Serial.print(F("Getting IP address..."));
28-
17+
while (!Serial);
18+
Serial.println("Booting");
2919

30-
WiFi.begin(ssid, pass);
31-
32-
while (WiFi.status() != WL_CONNECTED) {
33-
delay(500);
34-
Serial.print(F("."));
35-
}
36-
Serial.println(F(""));
37-
Serial.println(F("WiFi connected"));
20+
ETH_startup();
21+
22+
MDNS.begin(AppleMIDI.getName());
3823

39-
40-
Serial.println();
41-
Serial.print(F("IP address is "));
42-
Serial.println(WiFi.localIP());
24+
Serial.print("\nIP address is ");
25+
Serial.println(ETH.localIP());
4326

4427
Serial.println(F("OK, now make sure you an rtpMIDI session that is Enabled"));
4528
Serial.print(F("Add device named Arduino with Host/Port "));
46-
Serial.print(WiFi.localIP());
29+
Serial.print(ETH.localIP());
4730
Serial.println(F(":5004"));
4831
Serial.println(F("Then press the Connect button"));
4932
Serial.println(F("Then open a MIDI listener (eg MIDI-OX) and monitor incoming notes"));
5033

5134
// Create a session and wait for a remote host to connect to us
52-
AppleMIDI.begin("test");
35+
MIDI.begin(1); // listen on channel 1
36+
37+
AppleMIDI.setHandleConnected(OnAppleMidiConnected);
38+
AppleMIDI.setHandleDisconnected(OnAppleMidiDisconnected);
5339

54-
AppleMIDI.OnConnected(OnAppleMidiConnected);
55-
AppleMIDI.OnDisconnected(OnAppleMidiDisconnected);
40+
MIDI.setHandleNoteOn(OnAppleMidiNoteOn);
41+
MIDI.setHandleNoteOff(OnAppleMidiNoteOff);
5642

57-
AppleMIDI.OnReceiveNoteOn(OnAppleMidiNoteOn);
58-
AppleMIDI.OnReceiveNoteOff(OnAppleMidiNoteOff);
43+
MDNS.addService("apple-midi", "udp", AppleMIDI.getPort());
5944

60-
Serial.println(F("Sending NoteOn/Off of note 45, every second"));
45+
Serial.println(F("Every second send a random NoteOn/Off"));
6146
}
6247

6348
// -----------------------------------------------------------------------------
@@ -66,21 +51,21 @@ void setup()
6651
void loop()
6752
{
6853
// Listen to incoming notes
69-
AppleMIDI.read();
54+
MIDI.read();
7055

7156
// send a note every second
7257
// (dont cáll delay(1000) as it will stall the pipeline)
7358
if (isConnected && (millis() - t0) > 1000)
7459
{
7560
t0 = millis();
76-
// Serial.print(".");
61+
// Serial.print(F(".");
7762

78-
byte note = 45;
63+
byte note = random(1, 127);
7964
byte velocity = 55;
8065
byte channel = 1;
8166

82-
AppleMIDI.sendNoteOn(note, velocity, channel);
83-
AppleMIDI.sendNoteOff(note, velocity, channel);
67+
MIDI.sendNoteOn(note, velocity, channel);
68+
MIDI.sendNoteOff(note, velocity, channel);
8469
}
8570
}
8671

@@ -91,42 +76,40 @@ void loop()
9176
// -----------------------------------------------------------------------------
9277
// rtpMIDI session. Device connected
9378
// -----------------------------------------------------------------------------
94-
void OnAppleMidiConnected(uint32_t ssrc, char* name) {
95-
isConnected = true;
79+
void OnAppleMidiConnected(const ssrc_t & ssrc, const char* name) {
80+
isConnected = true;
9681
Serial.print(F("Connected to session "));
9782
Serial.println(name);
9883
}
9984

10085
// -----------------------------------------------------------------------------
10186
// rtpMIDI session. Device disconnected
10287
// -----------------------------------------------------------------------------
103-
void OnAppleMidiDisconnected(uint32_t ssrc) {
104-
isConnected = false;
88+
void OnAppleMidiDisconnected(const ssrc_t & ssrc) {
89+
isConnected = false;
10590
Serial.println(F("Disconnected"));
10691
}
10792

10893
// -----------------------------------------------------------------------------
10994
//
11095
// -----------------------------------------------------------------------------
111-
void OnAppleMidiNoteOn(byte channel, byte note, byte velocity) {
112-
Serial.print(F("Incoming NoteOn from channel:"));
96+
static void OnAppleMidiNoteOn(byte channel, byte note, byte velocity) {
97+
Serial.print(F("Incoming NoteOn from channel: "));
11398
Serial.print(channel);
114-
Serial.print(F(" note:"));
99+
Serial.print(F(", note: "));
115100
Serial.print(note);
116-
Serial.print(F(" velocity:"));
117-
Serial.print(velocity);
118-
Serial.println();
101+
Serial.print(F(", velocity: "));
102+
Serial.println(velocity);
119103
}
120104

121105
// -----------------------------------------------------------------------------
122106
//
123107
// -----------------------------------------------------------------------------
124-
void OnAppleMidiNoteOff(byte channel, byte note, byte velocity) {
125-
Serial.print(F("Incoming NoteOff from channel:"));
108+
static void OnAppleMidiNoteOff(byte channel, byte note, byte velocity) {
109+
Serial.print(F("Incoming NoteOff from channel: "));
126110
Serial.print(channel);
127-
Serial.print(F(" note:"));
111+
Serial.print(F(", note: "));
128112
Serial.print(note);
129-
Serial.print(F(" velocity:"));
130-
Serial.print(velocity);
131-
Serial.println();
113+
Serial.print(F(", velocity: "));
114+
Serial.println(velocity);
132115
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#include <ETH.h>
2+
#include <ESPmDNS.h>
3+
4+
#define ETH_ADDR 1
5+
#define ETH_POWER_PIN 5
6+
#define ETH_MDC_PIN 23
7+
#define ETH_MDIO_PIN 18
8+
#define ETH_TYPE ETH_PHY_IP101
9+
10+
static bool eth_connected = false;
11+
12+
void WiFiEvent(WiFiEvent_t event)
13+
{
14+
switch (event) {
15+
case SYSTEM_EVENT_ETH_START:
16+
Serial.println("ETH Started");
17+
//set eth hostname here
18+
ETH.setHostname("esp32-ethernet");
19+
break;
20+
case SYSTEM_EVENT_ETH_CONNECTED:
21+
Serial.println("ETH Connected");
22+
break;
23+
case SYSTEM_EVENT_ETH_GOT_IP:
24+
Serial.print("ETH MAC: ");
25+
Serial.print(ETH.macAddress());
26+
Serial.print(", IPv4: ");
27+
Serial.print(ETH.localIP());
28+
if (ETH.fullDuplex()) {
29+
Serial.print(", FULL_DUPLEX");
30+
}
31+
Serial.print(", ");
32+
Serial.print(ETH.linkSpeed());
33+
Serial.println("Mbps");
34+
eth_connected = true;
35+
break;
36+
case SYSTEM_EVENT_ETH_DISCONNECTED:
37+
Serial.println("ETH Disconnected");
38+
eth_connected = false;
39+
break;
40+
case SYSTEM_EVENT_ETH_STOP:
41+
Serial.println("ETH Stopped");
42+
eth_connected = false;
43+
break;
44+
default:
45+
break;
46+
}
47+
}
48+
49+
bool ETH_startup()
50+
{
51+
WiFi.onEvent(WiFiEvent);
52+
ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE);
53+
54+
Serial.println(F("Getting IP address..."));
55+
56+
while (!eth_connected)
57+
delay(100);
58+
59+
return true;
60+
}

0 commit comments

Comments
 (0)