diff --git a/README.md b/README.md index a999437..e7e02ec 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,21 @@ MidiLogLevel = MidiDebug; // or MidiInfo, MidiWarning, MidiError All the midi classes are defined using the midi namespace. If you include Midi.h the using namespace is already defined. However, if you include the individual class specific header files you need to add a using namespace midi; in your sketch. +### Class Templates / Alternatives Networking Stacks + +The following classes support class templates for selecting the networking stack: + +- ```AppleMidiServer``` (= ```AppleMidiServer``` ) +- ```MidiIpserver``` (= ```AppleMidiServer``` ) +- ```MidiUdp``` (= ```MidiUdp``` ) +- ```MidiUdpServer``` (= ```MidiUdpServer``` ) + +By default the WiFi classes are used. If you want to use it with Ethernet please use the corresponding class template parameters: + +- ```AppleMidiServer``` +- ```MidiIpserver``` +- ```MidiUdp``` +- ```MidiUdpServer``` ### Installation in Arduino diff --git a/docs/html/_apple_midi_server_8h_source.html b/docs/html/_apple_midi_server_8h_source.html index dcaf9c7..cadd9d2 100644 --- a/docs/html/_apple_midi_server_8h_source.html +++ b/docs/html/_apple_midi_server_8h_source.html @@ -73,86 +73,193 @@
2 #include "ConfigMidi.h"
3 #if TCP_ACTIVE
4 #include <WiFi.h>
-
5 #include "MidiAction.h"
-
6 #include "MidiCommon.h"
-
7 #include "MidiLogger.h"
-
8 #include "apple-midi/applemidi.h"
-
9 #include <WiFiUdp.h>
-
10 #if MDNS_ACTIVE
-
11 #include <ESPmDNS.h>
-
12 #endif
-
13 
-
14 #define MIDI_BUFFER_SIZE 80
-
15 
-
16 namespace midi {
-
17 
-
18 class AppleMidiServer;
-
19 extern AppleMidiServer *SelfAppleMidi;
-
20 typedef void* apple_midi_cb_t;
-
21 
-
22 /***************************************************/
-
32 /***************************************************/
-
33 
-
34 class AppleMidiServer : public MidiCommon {
-
35  public:
-
36  AppleMidiServer() {
-
37  SelfAppleMidi = this;
-
38  };
-
39 
-
40  AppleMidiServer(MidiAction *action, int midiPort=-1){
-
41  SelfAppleMidi = this;
-
42  apple_event_handler.begin(action, midiPort);
-
43  }
-
44 
-
46  void setName(const char* name){
-
47  dns_name = name;
-
48  }
-
49 
-
51  bool begin(int control_port=APPLEMIDI_DEFAULT_PORT);
-
53  bool begin(IPAddress adress, int control_port=APPLEMIDI_DEFAULT_PORT, int data_port_opt=-1);
-
55  void end();
-
57  bool loop() {
-
58  return tick(millis());
-
59  }
-
60 
-
61  protected:
-
62  MidiParser apple_event_handler;
-
63  WiFiUDP udpControl;
-
64  WiFiUDP udpData;
-
65  uint8_t rx_buffer[MIDI_BUFFER_SIZE];
-
66  int remote_port;
-
67  bool is_setup = false;
-
68  const char* dns_name = "AppleMidi";
-
69 
-
71  virtual bool tick(uint32_t timestamp);
-
73  virtual void writeData(MidiMessage *msg, int len);
-
75  virtual void setupMDns(int port);
-
77  const char* toStr(IPAddress &adress);
-
79  void setupLogger();
-
81  static void applemidi_callback_midi_message_received(uint8_t port, uint32_t timestamp, uint8_t midi_status, uint8_t *remaining_message, size_t len, size_t continued_sysex_pos);
-
83  static int32_t applemidi_if_send_udp_datagram(uint8_t *ip_addr, uint16_t port, uint8_t *tx_data, size_t tx_len);
-
84 
-
85 
-
86 };
-
87 
-
88 }
-
89 #endif
-
A Sender and Receiver which supports Apple Midi using the implementation from midibox....
Definition: AppleMidiServer.h:34
-
bool loop()
Processing logic to be executed in loop.
Definition: AppleMidiServer.h:57
-
virtual void setupMDns(int port)
Setup MDNS apple-midi service.
Definition: AppleMidiServer.cpp:96
-
virtual bool tick(uint32_t timestamp)
process input from the control and the data port
Definition: AppleMidiServer.cpp:61
-
static void applemidi_callback_midi_message_received(uint8_t port, uint32_t timestamp, uint8_t midi_status, uint8_t *remaining_message, size_t len, size_t continued_sysex_pos)
Callback method to parse midi message.
Definition: AppleMidiServer.cpp:127
-
void setupLogger()
Activate apple midi debug messages.
Definition: AppleMidiServer.cpp:109
-
const char * toStr(IPAddress &adress)
provides the network address as string
Definition: AppleMidiServer.cpp:47
-
void end()
Closes the connections.
Definition: AppleMidiServer.cpp:54
-
bool begin(int control_port=APPLEMIDI_DEFAULT_PORT)
Starts the listening.
Definition: AppleMidiServer.cpp:9
-
void setName(const char *name)
Defines the dns name.
Definition: AppleMidiServer.h:46
-
static int32_t applemidi_if_send_udp_datagram(uint8_t *ip_addr, uint16_t port, uint8_t *tx_data, size_t tx_len)
Callback method to send UDP message with the help of the Arduino API.
Definition: AppleMidiServer.cpp:137
-
virtual void writeData(MidiMessage *msg, int len)
MidiCommon implementation.
Definition: AppleMidiServer.cpp:90
+
5 #include <WiFiUdp.h>
+
6 
+
7 #include "MidiAction.h"
+
8 #include "MidiCommon.h"
+
9 #include "MidiLogger.h"
+
10 #include "apple-midi/applemidi.h"
+
11 #if MDNS_ACTIVE
+
12 #include <ESPmDNS.h>
+
13 #endif
+
14 
+
15 #define MIDI_BUFFER_SIZE 80
+
16 
+
17 namespace midi {
+
18 
+
19 typedef void* apple_midi_cb_t;
+
20 
+
21 /***************************************************/
+
31 /***************************************************/
+
32 template <class UDPClass = WiFiUDP>
+
33 class AppleMidiServer : public MidiCommon {
+
34  public:
+
35  AppleMidiServer() {
+
36  _instance = this;
+
37  };
+
38 
+
39  AppleMidiServer(MidiAction* action, int midiPort = -1) {
+
40  _instance = this;
+
41  apple_event_handler.begin(action, midiPort);
+
42  }
+
43 
+
44  void setName(const char* name) { dns_name = name; }
+
45 
+
46  bool begin(int control_port = APPLEMIDI_DEFAULT_PORT) {
+
47  MIDI_LOGI(__PRETTY_FUNCTION__);
+
48  setupLogger();
+
49  setupMDns(control_port);
+
50  MIDI_LOGI("MIDI using port: %d", control_port);
+
51  applemidi_init((apple_midi_cb_t)applemidi_callback_midi_message_received,
+
52  (apple_midi_cb_t)applemidi_if_send_udp_datagram);
+
53  udpControl.begin(control_port); // control port
+
54  udpData.begin(control_port + 1); // data port
+
55  return true;
+
56  }
+
57 
+
58  bool begin(IPAddress adress, int control_port = APPLEMIDI_DEFAULT_PORT,
+
59  int data_port_opt = -1) {
+
60  _instance = this;
+
61  MIDI_LOGI(__PRETTY_FUNCTION__);
+
62  setupLogger();
+
63  setupMDns(control_port);
+
64  applemidi_init((apple_midi_cb_t)applemidi_callback_midi_message_received,
+
65  (apple_midi_cb_t)applemidi_if_send_udp_datagram);
+
66  int data_port = data_port_opt > 0 ? data_port_opt : control_port + 1;
+
67  MIDI_LOGI("MIDI using address: %s port: %d", toStr(adress), control_port);
+
68  udpControl.begin(control_port);
+
69  udpData.begin(data_port);
+
70  int status =
+
71  applemidi_start_session(data_port, (uint8_t*)&adress, control_port);
+
72  return status >= 0;
+
73  }
+
74 
+
75  void end() {
+
76  MIDI_LOGI(__PRETTY_FUNCTION__);
+
77  udpControl.stop();
+
78  udpData.stop();
+
79  }
+
80 
+
81  bool loop() { return tick(millis()); }
+
82 
+
83  protected:
+
84  MidiParser apple_event_handler;
+
85  UDPClass udpControl;
+
86  UDPClass udpData;
+
87  uint8_t rx_buffer[MIDI_BUFFER_SIZE];
+
88  int remote_port;
+
89  bool is_setup = false;
+
90  const char* dns_name = "AppleMidi";
+
91  static AppleMidiServer<UDPClass>* _instance;
+
92 
+
93  virtual bool tick(uint32_t timestamp) {
+
94  bool active = false;
+
95  int packetSize = udpControl.parsePacket();
+
96  remote_port = udpControl.remotePort();
+
97  if (packetSize > 0) {
+
98  IPAddress remote_address = udpControl.remoteIP();
+
99  int len = udpControl.read(rx_buffer, MIDI_BUFFER_SIZE);
+
100  MIDI_LOGD("control: %d -> %d ", remote_port, len);
+
101  applemidi_parse_udp_datagram((uint8_t*)&remote_address, remote_port,
+
102  rx_buffer, len, false);
+
103  active = true;
+
104  }
+
105  packetSize = udpData.parsePacket();
+
106  if (packetSize > 0) {
+
107  int remote_port = udpData.remotePort();
+
108  IPAddress remote_address = udpData.remoteIP();
+
109  int len = udpData.read(rx_buffer, MIDI_BUFFER_SIZE);
+
110  MIDI_LOGD("data: %d -> %d", remote_port, len);
+
111  applemidi_parse_udp_datagram((uint8_t*)&remote_address, remote_port,
+
112  rx_buffer, len, true);
+
113  active = true;
+
114  }
+
115  return active;
+
116  }
+
117 
+
118  virtual void writeData(MidiMessage* msg, int len) {
+
119  MIDI_LOGI(__PRETTY_FUNCTION__);
+
120  applemidi_send_message(remote_port, (uint8_t*)msg,
+
121  len * sizeof(MidiMessage));
+
122  }
+
123 
+
124  virtual void setupMDns(int port) {
+
125 #if MDNS_ACTIVE
+
126  if (MDNS.begin(dns_name)) {
+
127  MDNS.addService("_apple-midi", "_udp", port);
+
128  } else {
+
129  MIDI_LOGE("Error starting mDNS");
+
130  }
+
131 #else
+
132  MIDI_LOGW("MDNS has been deactivated");
+
133 #endif
+
134  }
+
135 
+
136  const char* toStr(IPAddress& adress) {
+
137  static char networ_str[20];
+
138  sprintf(networ_str, "%u.%u.%u.%u", adress[0], adress[1], adress[2],
+
139  adress[3]);
+
140  return networ_str;
+
141  }
+
142 
+
143  void setupLogger() {
+
144  switch (MidiLogLevel) {
+
145  case MidiInfo:
+
146  applemidi_set_debug_level(2);
+
147  break;
+
148  case MidiDebug:
+
149  applemidi_set_debug_level(3);
+
150  break;
+
151  case MidiWarning:
+
152  applemidi_set_debug_level(1);
+
153  break;
+
154  case MidiError:
+
155  applemidi_set_debug_level(1);
+
156  break;
+
157  }
+
158  }
+
159 
+
160  static void applemidi_callback_midi_message_received(
+
161  uint8_t port, uint32_t timestamp, uint8_t midi_status,
+
162  uint8_t* remaining_message, size_t len, size_t continued_sysex_pos) {
+
163  MIDI_LOGI("applemidi_callback_midi_message_received: port=%d", port);
+
164  if (_instance) {
+
165  uint8_t message[len + 1];
+
166  message[0] = midi_status;
+
167  memmove(message + 1, remaining_message, len);
+
168  _instance->apple_event_handler.parse(message, len + 1);
+
169  }
+
170  }
+
171 
+
172  static int32_t applemidi_if_send_udp_datagram(uint8_t* ip_addr, uint16_t port,
+
173  uint8_t* tx_data,
+
174  size_t tx_len) {
+
175  MIDI_LOGD("applemidi_if_send_udp_datagram: port=%d", port);
+
176  if (_instance) {
+
177  IPAddress* p_adr = (IPAddress*)ip_addr;
+
178  UDPClass* p_udp = port == _instance->remote_port
+
179  ? &(_instance->udpControl)
+
180  : &(_instance->udpData);
+
181  p_udp->beginPacket(*p_adr, port);
+
182  int32_t result = p_udp->write(tx_data, tx_len);
+
183  p_udp->endPacket();
+
184  return result;
+
185  }
+
186  return 0;
+
187  }
+
188 };
+
189 
+
190 template <class UDPClass>
+ +
192 
+
193 } // namespace midi
+
194 #endif
+
A Sender and Receiver which supports Apple Midi using the implementation from midibox....
Definition: AppleMidiServer.h:33
Abstract class for a MidiAction.
Definition: MidiAction.h:15
The common methods provided by all Arduino Midi subclasses which can be used to generate Midi message...
Definition: MidiCommon.h:75
A simple Midi Parser which calls the corresponding events. It supports Midi and BLE Midi messages....
Definition: MidiParser.h:29
void begin(MidiAction *MidiAction, int filter_channel=-1)
Assigns the MidiAction and optinally defines a midi channel.
Definition: MidiParser.cpp:14
+
void parse(uint8_t *msg, uint8_t len)
Parse a string into midi messages.
Definition: MidiParser.cpp:25
The content of the midi message: timestamp, status, arg1 and arg2.
Definition: MidiCommon.h:48
diff --git a/docs/html/_midi_common_8h_source.html b/docs/html/_midi_common_8h_source.html index 2680c8f..06ed16c 100644 --- a/docs/html/_midi_common_8h_source.html +++ b/docs/html/_midi_common_8h_source.html @@ -171,40 +171,41 @@
132  void setConnectionStatus(ConnectionStatus status) {connectionStatus=status; }
133  void updateTimestamp(MidiMessage *pMsg);
134  virtual void writeData(MidiMessage *msg, int len);
-
135 
-
136  ConnectionStatus connectionStatus;
-
137  MidiAction *pMidiAction;
-
138  MidiMessage outMessage;
-
139  int receivingChannel = -1;
-
140  uint8_t sendingChannel = 0;
-
141  uint8_t timestampLow;
-
142  uint8_t timestampHigh;
-
143  char *name;
-
144 };
-
145 
+
135  uint8_t getChannel(uint8_t ch);
+
136 
+
137  ConnectionStatus connectionStatus;
+
138  MidiAction *pMidiAction;
+
139  MidiMessage outMessage;
+
140  int receivingChannel = -1;
+
141  uint8_t sendingChannel = 0;
+
142  uint8_t timestampLow;
+
143  uint8_t timestampHigh;
+
144  char *name;
+
145 };
146 
-
147 } // namespace
-
148 
-
149 #endif
+
147 
+
148 } // namespace
+
149 
+
150 #endif
Abstract class for a MidiAction.
Definition: MidiAction.h:15
The common methods provided by all Arduino Midi subclasses which can be used to generate Midi message...
Definition: MidiCommon.h:75
-
virtual void polyPressure(uint8_t valuePar, int8_t channel=-1)
Sends a polyPressure MIDI command to the output.
Definition: MidiCommon.cpp:68
+
virtual void polyPressure(uint8_t valuePar, int8_t channel=-1)
Sends a polyPressure MIDI command to the output.
Definition: MidiCommon.cpp:69
virtual void setFilterReceivingChannel(int channel)
Activates a filter on receiving messages to the indicated channel.
Definition: MidiCommon.cpp:19
-
virtual void localControl(bool active, int8_t channel=-1)
Sends a localControl MIDI command to the output.
Definition: MidiCommon.cpp:90
+
virtual void localControl(bool active, int8_t channel=-1)
Sends a localControl MIDI command to the output.
Definition: MidiCommon.cpp:93
virtual void setDefaultSendingChannel(int8_t channel)
Sets the default channel for the sending commands.
Definition: MidiCommon.cpp:15
-
static uint8_t frequencyToNote(float freq)
Converts a Frequency (in Hz) to a MIDI note.
Definition: MidiCommon.cpp:106
+
static uint8_t frequencyToNote(float freq)
Converts a Frequency (in Hz) to a MIDI note.
Definition: MidiCommon.cpp:110
virtual void channelPressure(uint8_t value, int8_t channel=-1)
Sends a channelPressure MIDI command to the output.
Definition: MidiCommon.cpp:61
MidiCommon()
Default Constructor.
Definition: MidiCommon.cpp:5
-
virtual void resetAllControllers(int8_t channel=-1)
Sends a resetAllControllers MIDI command to the output.
Definition: MidiCommon.cpp:86
+
virtual void resetAllControllers(int8_t channel=-1)
Sends a resetAllControllers MIDI command to the output.
Definition: MidiCommon.cpp:89
virtual void noteOff(uint8_t note, uint8_t velocity, int8_t channel=-1)
Sends a noteOff MIDI command to the output.
Definition: MidiCommon.cpp:45
virtual void noteOn(uint8_t note, uint8_t velocity, int8_t channel=-1)
Sends a noteOn MIDI command to the output.
Definition: MidiCommon.cpp:37
-
static float noteToFrequency(uint8_t note)
Converts a MIDI note to a frequency in Hz.
Definition: MidiCommon.cpp:101
-
virtual void controlChange(uint8_t msg, uint8_t value, int8_t channel=-1)
Sends a control change MIDI command to the output.
Definition: MidiCommon.cpp:94
-
void write(MidiMessage *msg, int len)
write multiple MidiMessage objects to final output
Definition: MidiCommon.cpp:113
+
static float noteToFrequency(uint8_t note)
Converts a MIDI note to a frequency in Hz.
Definition: MidiCommon.cpp:105
+
virtual void controlChange(uint8_t msg, uint8_t value, int8_t channel=-1)
Sends a control change MIDI command to the output.
Definition: MidiCommon.cpp:97
+
void write(MidiMessage *msg, int len)
write multiple MidiMessage objects to final output
Definition: MidiCommon.cpp:117
virtual ConnectionStatus getConnectionStatus()
Determines the connection status.
Definition: MidiCommon.h:126
virtual void pitchBend(uint16_t value, int8_t channel=-1)
Sends a pitchBend MIDI command to the output.
Definition: MidiCommon.cpp:53
-
virtual void allNotesOff(int8_t channel=-1)
Sends a allNotesOff MIDI command to the output.
Definition: MidiCommon.cpp:82
-
virtual void programChange(uint8_t program, int8_t channel=-1)
Sends a programChange MIDI command to the output.
Definition: MidiCommon.cpp:75
+
virtual void allNotesOff(int8_t channel=-1)
Sends a allNotesOff MIDI command to the output.
Definition: MidiCommon.cpp:85
+
virtual void programChange(uint8_t program, int8_t channel=-1)
Sends a programChange MIDI command to the output.
Definition: MidiCommon.cpp:77
virtual void setMidiAction(MidiAction &MidiAction)
Defines the voice which is used in inbound processing.
Definition: MidiCommon.cpp:11
The content of the midi message: timestamp, status, arg1 and arg2.
Definition: MidiCommon.h:48
diff --git a/docs/html/_midi_ip_server_8h_source.html b/docs/html/_midi_ip_server_8h_source.html index f22dec4..c558f21 100644 --- a/docs/html/_midi_ip_server_8h_source.html +++ b/docs/html/_midi_ip_server_8h_source.html @@ -82,7 +82,7 @@
11 
12 /***************************************************/
19 /***************************************************/
-
20 
+
20 template <class ServerClass = WiFiServer, class ClientClass = WiFiClient>
21 class MidiIpServer : public MidiServer {
22  public:
23  MidiIpServer(MidiAction *action) : MidiServer(action){
@@ -97,58 +97,55 @@
32  bool begin(int serverPort=5008){
33  MIDI_LOGI( __PRETTY_FUNCTION__);
34 
-
35  if (WiFi.status() != WL_CONNECTED){
-
36  MIDI_LOGE("WiFi not connected");
-
37  return false;
-
38  }
-
39 
-
40  if (p_wifi_server==nullptr){
-
41  p_wifi_server = new WiFiServer(serverPort);
-
42  }
-
43  p_wifi_server->begin();
-
44  MIDI_LOGI("server started on port %d", serverPort);
-
45  return true;
-
46  }
-
47 
-
48  void end() {
-
49  if (p_wifi_server!=nullptr){
-
50  delete p_wifi_server;
-
51  p_wifi_server = nullptr;
-
52  }
-
53  }
-
54 
-
55  void loop() {
-
56  if (p_wifi_server!=nullptr){
-
57  if (!client.connected()){
-
58  client = p_wifi_server->accept();
-
59  if (client.connected()){
-
60  MIDI_LOGI("MidiIpServer->connected");
-
61  in.setup(&client, new MidiParser(p_action), true);
-
62  out.setup(&client);
-
63  out.resetAllControllers();
-
64  }
-
65  } else {
-
66  MIDI_LOGD("MidiIpServer::loop");
-
67  in.loop();
-
68  }
-
69  }
-
70  }
-
71 
-
72  protected:
-
73  WiFiServer *p_wifi_server = nullptr;
-
74  WiFiClient client;
+
35  if (p_wifi_server==nullptr){
+
36  p_wifi_server = new WiFiServer(serverPort);
+
37  }
+
38  p_wifi_server->begin();
+
39  MIDI_LOGI("server started on port %d", serverPort);
+
40  return true;
+
41  }
+
42 
+
43  void end() {
+
44  if (p_wifi_server!=nullptr){
+
45  delete p_wifi_server;
+
46  p_wifi_server = nullptr;
+
47  }
+
48  }
+
49 
+
50  void loop() {
+
51  if (p_wifi_server!=nullptr){
+
52  if (!client.connected()){
+
53  client = p_wifi_server->accept();
+
54  if (client.connected()){
+
55  MIDI_LOGI("MidiIpServer->connected");
+
56  in.setup(&client, new MidiParser(p_action), true);
+
57  out.setup(&client);
+
58  out.resetAllControllers();
+
59  }
+
60  } else {
+
61  MIDI_LOGD("MidiIpServer::loop");
+
62  in.loop();
+
63  }
+
64  }
+
65  }
+
66 
+
67  protected:
+
68  ServerClass *p_wifi_server = nullptr;
+
69  ClientClass client;
+
70 
+
71 };
+
72 
+
73 
+
74 }
75 
-
76 };
-
77 
-
78 
-
79 }
-
80 
-
81 #endif
+
76 #endif
Abstract class for a MidiAction.
Definition: MidiAction.h:15
-
virtual void resetAllControllers(int8_t channel=-1)
Sends a resetAllControllers MIDI command to the output.
Definition: MidiCommon.cpp:86
+
virtual void resetAllControllers(int8_t channel=-1)
Sends a resetAllControllers MIDI command to the output.
Definition: MidiCommon.cpp:89
A simple IP Server which which receives and creates MIDI messages.
Definition: MidiIpServer.h:21
A simple Midi Parser which calls the corresponding events. It supports Midi and BLE Midi messages....
Definition: MidiParser.h:29
A simple Serial Server which which receives and creates MIDI messages.
Definition: MidiServer.h:20
+
void setup(Stream *stream, MidiParser *handler, bool releaseHandler)
Call setup when created with empty constructor.
Definition: MidiStreamIn.cpp:25
+
virtual void setup(Print *stream)
Call setup when created with empty constructor.
Definition: MidiStreamOut.cpp:12