updated simulator
simulator using actual BLE parser, using a BLE simulator Note: you need a manually add a path to ../src and arduino_midi_library/src
This commit is contained in:
parent
99abc3ef79
commit
ee85989cd9
|
|
@ -0,0 +1,57 @@
|
|||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
|
||||
#define HEX 0
|
||||
#define DEC 1
|
||||
|
||||
#include <inttypes.h>
|
||||
typedef uint8_t byte;
|
||||
|
||||
void begin();
|
||||
void loop();
|
||||
|
||||
int main()
|
||||
{
|
||||
begin();
|
||||
|
||||
while (true)
|
||||
{
|
||||
loop();
|
||||
}
|
||||
}
|
||||
|
||||
// avoid strncpy security warning
|
||||
#pragma warning(disable:4996)
|
||||
|
||||
#define __attribute__(A) /* do nothing */
|
||||
|
||||
#include <midi_Defs.h>
|
||||
|
||||
float analogRead(int pin)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
void randomSeed(float)
|
||||
{
|
||||
srand(static_cast<unsigned int>(time(0)));
|
||||
}
|
||||
|
||||
unsigned long millis()
|
||||
{
|
||||
auto now = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
|
||||
return (unsigned long)now;
|
||||
}
|
||||
|
||||
int random(int min, int max)
|
||||
{
|
||||
return RAND_MAX % std::rand() % (max - min) + min;
|
||||
}
|
||||
|
||||
template <class T> const T& min(const T& a, const T& b) {
|
||||
return !(b < a) ? a : b; // or: return !comp(b,a)?a:b; for version (2)
|
||||
}
|
||||
|
||||
#define F(x) x
|
||||
|
|
@ -0,0 +1,220 @@
|
|||
#pragma once
|
||||
|
||||
BEGIN_BLEMIDI_NAMESPACE
|
||||
|
||||
template<typename T, int rawSize>
|
||||
class Fifo {
|
||||
public:
|
||||
const size_t size; //speculative feature, in case it's needed
|
||||
|
||||
Fifo() : size(rawSize)
|
||||
{
|
||||
flush();
|
||||
}
|
||||
|
||||
T dequeue()
|
||||
{
|
||||
numberOfElements--;
|
||||
nextOut %= size;
|
||||
return raw[nextOut++];
|
||||
};
|
||||
|
||||
bool enqueue(T element)
|
||||
{
|
||||
if (count() >= rawSize)
|
||||
return false;
|
||||
|
||||
numberOfElements++;
|
||||
nextIn %= size;
|
||||
raw[nextIn] = element;
|
||||
nextIn++; //advance to next index
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
T peek() const
|
||||
{
|
||||
return raw[nextOut % size];
|
||||
}
|
||||
|
||||
void flush()
|
||||
{
|
||||
nextIn = nextOut = numberOfElements = 0;
|
||||
}
|
||||
|
||||
// how many elements are currently in the FIFO?
|
||||
size_t count() { return numberOfElements; }
|
||||
|
||||
private:
|
||||
size_t numberOfElements;
|
||||
size_t nextIn;
|
||||
size_t nextOut;
|
||||
T raw[rawSize];
|
||||
};
|
||||
|
||||
class BLEMIDI_Sim
|
||||
{
|
||||
private:
|
||||
static BLEMIDI_Transport<class BLEMIDI_Sim>* _bleMidiTransport;
|
||||
|
||||
Fifo<byte, 64> mRxBuffer;
|
||||
|
||||
public:
|
||||
BLEMIDI_Sim()
|
||||
{
|
||||
}
|
||||
|
||||
bool begin(const char*, BLEMIDI_Transport<class BLEMIDI_Sim>*);
|
||||
|
||||
void end()
|
||||
{
|
||||
}
|
||||
|
||||
void test()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void write(uint8_t* buffer, size_t size)
|
||||
{
|
||||
}
|
||||
|
||||
bool available(byte* pvBuffer)
|
||||
{
|
||||
if (mRxBuffer.count() > 0) {
|
||||
*pvBuffer = mRxBuffer.dequeue();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void add(byte value)
|
||||
{
|
||||
mRxBuffer.enqueue(value);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
BLEMIDI_Transport<class BLEMIDI_Sim>* BLEMIDI_Sim::_bleMidiTransport = nullptr;
|
||||
|
||||
bool BLEMIDI_Sim::begin(const char* deviceName, BLEMIDI_Transport<class BLEMIDI_Sim>* bleMidiTransport)
|
||||
{
|
||||
_bleMidiTransport = bleMidiTransport;
|
||||
|
||||
byte sysExAndRealTime[] = { 0xB0, 0xF4, // header + timestamp
|
||||
0xF0, // start SysEx
|
||||
0x01, 0x02, 0x03, 0x04, // SysEx data
|
||||
// RealTime message in the middle of a SysEx
|
||||
0xF3, // timestampLow
|
||||
0xFA, // Realtime msg: Start
|
||||
// rest of sysex data
|
||||
0x05, 0x06, 0x07, 0x08,
|
||||
0xF4, // timestampLow
|
||||
0xF7 // end of SysEx
|
||||
};
|
||||
_bleMidiTransport->receive(sysExAndRealTime, sizeof(sysExAndRealTime));
|
||||
|
||||
byte sysExPart[] = { 0xB0, 0xF4, // header + timestamp
|
||||
0xF0, // start SysEx
|
||||
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // sysex data
|
||||
0xF4, // timestampLow
|
||||
0xF7 }; // end of SysEx
|
||||
|
||||
_bleMidiTransport->receive(sysExPart, sizeof(sysExPart));
|
||||
|
||||
byte sysExPart1[] = { 0xB0, 0xF4, // header + timestamp
|
||||
0xF0, // start SysEx
|
||||
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; // sysex data
|
||||
_bleMidiTransport->receive(sysExPart1, sizeof(sysExPart1));
|
||||
|
||||
byte sysExPart2[] = { 0xB0, // 1 byte header
|
||||
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, // sysex data (cont)
|
||||
0xF4, // timestampLow
|
||||
0xF7 }; // end of SysEx
|
||||
_bleMidiTransport->receive(sysExPart2, sizeof(sysExPart2));
|
||||
|
||||
byte blePacketWithOneMIDIMessage[] = { 0xA8, 0xC0,
|
||||
0x90, 0x3E, 0x3E };
|
||||
_bleMidiTransport->receive(blePacketWithOneMIDIMessage, sizeof(blePacketWithOneMIDIMessage));
|
||||
|
||||
byte blePacketWithTwoMIDIMessage[] = { 0xA8, 0xC0,
|
||||
0x90, 0x3E, 0x3E,
|
||||
0xC1,
|
||||
0x91, 0x3E, 0x3E };
|
||||
_bleMidiTransport->receive(blePacketWithTwoMIDIMessage, sizeof(blePacketWithTwoMIDIMessage));
|
||||
|
||||
byte blePacketWithThreeMIDIMessage[] = { 0xA8, 0xC0,
|
||||
0x90, 0x3E, 0x3E,
|
||||
0xC1,
|
||||
0xF0,
|
||||
0x01, 0x02,
|
||||
0xC2,
|
||||
0xF7,
|
||||
0xC3,
|
||||
0x91, 0x3E, 0x3E };
|
||||
_bleMidiTransport->receive(blePacketWithThreeMIDIMessage, sizeof(blePacketWithThreeMIDIMessage));
|
||||
|
||||
byte twoMIDIMessageWithRunningStatus[] = { 0xA9, 0xAD,
|
||||
0xD1, 0x74, //Full Midi 2 bytes(afterTouch)
|
||||
0x73, //running
|
||||
0xAE, //timeStamp
|
||||
0x72, //running after timeStamp
|
||||
0xAF, //timeStamp
|
||||
0x71, //running after timeStamp
|
||||
0x70,
|
||||
0x69,
|
||||
0x68,
|
||||
0xB2, //
|
||||
0x92, 0x36, 0x70, //Full Midi 3 bytes (noteOn)
|
||||
0xB3, //
|
||||
0x93, 0x37, 0x71,
|
||||
0x38, 0x72,
|
||||
0x39, 0x73,
|
||||
0xB4, //
|
||||
0x40, 0x74
|
||||
};
|
||||
_bleMidiTransport->receive(twoMIDIMessageWithRunningStatus, sizeof(twoMIDIMessageWithRunningStatus));
|
||||
|
||||
byte twoMIDIMessageWithRunningStatusPlusSys[] = { 0xA9, 0xAD,
|
||||
0xD1, 0x74, //Full Midi 2 bytes(afterTouch)
|
||||
0x73, //running
|
||||
0xAE, //timeStamp
|
||||
0x72, //running after timeStamp
|
||||
0xAF, //timeStamp
|
||||
0x71, //running after timeStamp
|
||||
0x70,
|
||||
0x69,
|
||||
0x68,
|
||||
0xB2, //
|
||||
0xFA, // <- Sys START
|
||||
0xB2,
|
||||
0x92, 0x36, 0x70, //Full Midi 3 bytes (noteOn)
|
||||
0xB3, //
|
||||
0x93, 0x37, 0x71,
|
||||
0x38, 0x72,
|
||||
0xB3, //
|
||||
0xFC, // <- Sys STOP
|
||||
0xB3,
|
||||
0x39, 0x73,
|
||||
0xB4, //
|
||||
0x40, 0x74
|
||||
};
|
||||
_bleMidiTransport->receive(twoMIDIMessageWithRunningStatusPlusSys, sizeof(twoMIDIMessageWithRunningStatusPlusSys));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*! \brief Create an instance for nRF52 named <DeviceName>
|
||||
*/
|
||||
#define BLEMIDI_CREATE_INSTANCE(DeviceName, Name) \
|
||||
BLEMIDI_NAMESPACE::BLEMIDI_Transport<BLEMIDI_NAMESPACE::BLEMIDI_Sim> BLE##Name(DeviceName); \
|
||||
MIDI_NAMESPACE::MidiInterface<BLEMIDI_NAMESPACE::BLEMIDI_Transport<BLEMIDI_NAMESPACE::BLEMIDI_Sim>, BLEMIDI_NAMESPACE::MySettings> Name((BLEMIDI_NAMESPACE::BLEMIDI_Transport<BLEMIDI_NAMESPACE::BLEMIDI_Sim> &)BLE##Name);
|
||||
|
||||
/*! \brief Create a default instance for nRF52 (Nano 33 BLE) named BLE-MIDI
|
||||
*/
|
||||
#define BLEMIDI_CREATE_DEFAULT_INSTANCE() \
|
||||
BLEMIDI_CREATE_INSTANCE("BLE-MIDI", MIDI)
|
||||
|
||||
END_BLEMIDI_NAMESPACE
|
||||
|
|
@ -1,331 +0,0 @@
|
|||
// ConsoleApplication2.cpp : This file contains the 'main' function. Program execution begins and ends there.
|
||||
//
|
||||
|
||||
#include <iostream>
|
||||
|
||||
typedef unsigned int word;
|
||||
typedef uint8_t boolean;
|
||||
typedef unsigned char byte;
|
||||
|
||||
#define CHECK_BIT(var,pos) (!!((var) & (1<<(pos))))
|
||||
|
||||
//#define RUNNINGSTATUS_ENABLE
|
||||
|
||||
void transmitMIDIonDIN(byte status, byte data1, byte data2)
|
||||
{
|
||||
std::cout << "0x" << std::hex << (int)status;
|
||||
|
||||
if (data1 > 0)
|
||||
std::cout << " 0x" << std::hex << (int)data1;
|
||||
if (data2 > 0)
|
||||
std::cout << " 0x" << std::hex << (int)data2;
|
||||
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
void receive(byte* buffer, size_t length)
|
||||
{
|
||||
// Pointers used to search through payload.
|
||||
int lPtr = 0;
|
||||
int rPtr = 0;
|
||||
|
||||
// lastStatus used to capture runningStatus
|
||||
byte lastStatus;
|
||||
// previousStatus used to continue a runningStatus interrupted by a timeStamp or a System Message.
|
||||
byte previousStatus = 0x00;
|
||||
|
||||
|
||||
byte headerByte = buffer[lPtr++];
|
||||
// auto signatureIs1 = CHECK_BIT(headerByte, 7 - 1);
|
||||
// auto reservedIs0 = !CHECK_BIT(headerByte, 6 - 1);
|
||||
auto timestampHigh = 0x3f & headerByte;
|
||||
|
||||
byte timestampByte = buffer[lPtr++];
|
||||
uint16_t timestamp = 0;
|
||||
|
||||
bool sysExContinuation = false;
|
||||
bool runningStatusContinuation = false;
|
||||
|
||||
|
||||
if (timestampByte >= 80) {
|
||||
auto timestampLow = 0x7f & timestampByte;
|
||||
timestamp = timestampLow + (timestampHigh << 7);
|
||||
}
|
||||
else {
|
||||
sysExContinuation = true;
|
||||
lPtr--; // the second byte is part of the SysEx
|
||||
}
|
||||
|
||||
//While statement contains incrementing pointers and breaks when buffer size exceeded.
|
||||
while (true)
|
||||
{
|
||||
lastStatus = buffer[lPtr];
|
||||
|
||||
if(previousStatus==0x00){
|
||||
if ((lastStatus < 0x80) && !sysExContinuation)
|
||||
return; // Status message not present and it is not a runningStatus continuation, bail
|
||||
}else if(lastStatus < 0x80)
|
||||
{
|
||||
lastStatus = previousStatus;
|
||||
runningStatusContinuation = true;
|
||||
}
|
||||
|
||||
|
||||
// Point to next non-data byte
|
||||
rPtr = lPtr;
|
||||
while ((buffer[rPtr + 1] < 0x80) && (rPtr < (length - 1)))
|
||||
rPtr++;
|
||||
|
||||
if(!runningStatusContinuation){
|
||||
// If not System Common or System Real-Time, send it as running status
|
||||
|
||||
auto midiType = lastStatus & 0xF0;
|
||||
if (sysExContinuation)
|
||||
midiType = 0xF0;
|
||||
|
||||
switch (midiType)
|
||||
{
|
||||
|
||||
// 3 bytes
|
||||
case 0x80:
|
||||
case 0x90:
|
||||
case 0xA0:
|
||||
case 0xB0:
|
||||
case 0xE0:
|
||||
#ifndef RUNNINGSTATUS_ENABLE
|
||||
for (auto i = lPtr; i < rPtr; i = i + 2)
|
||||
{
|
||||
|
||||
transmitMIDIonDIN(lastStatus, buffer[i + 1], buffer[i + 2]);
|
||||
}
|
||||
#else
|
||||
transmitMIDIonDIN(lastStatus, 0, 0);
|
||||
for (auto i = lPtr; i < rPtr; i = i + 2)
|
||||
{
|
||||
|
||||
transmitMIDIonDIN(buffer[i + 1], buffer[i + 2], 0);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
// 2 bytes
|
||||
case 0xC0:
|
||||
case 0xD0:
|
||||
#ifndef RUNNINGSTATUS_ENABLE
|
||||
for (auto i = lPtr; i < rPtr; i = i + 1)
|
||||
{
|
||||
transmitMIDIonDIN(lastStatus, buffer[i + 1], 0);
|
||||
}
|
||||
#else
|
||||
transmitMIDIonDIN(lastStatus, 0, 0);
|
||||
for (auto i = lPtr; i < rPtr; i = i + 1)
|
||||
{
|
||||
|
||||
transmitMIDIonDIN(buffer[i + 1], 0 , 0);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
// 1 byte or n bytes
|
||||
case 0xF0:
|
||||
transmitMIDIonDIN(buffer[lPtr], 0, 0);
|
||||
for (auto i = lPtr; i < rPtr; i++)
|
||||
transmitMIDIonDIN(buffer[i + 1], 0, 0);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
#ifndef RUNNINGSTATUS_ENABLE
|
||||
auto midiType = lastStatus & 0xF0;
|
||||
if (sysExContinuation)
|
||||
midiType = 0xF0;
|
||||
|
||||
switch (midiType)
|
||||
{
|
||||
case 0x80:
|
||||
case 0x90:
|
||||
case 0xA0:
|
||||
case 0xB0:
|
||||
case 0xE0:
|
||||
//3 bytes full Midi -> 2 bytes runningStatus
|
||||
for (auto i = lPtr; i <= rPtr; i = i + 2)
|
||||
{
|
||||
transmitMIDIonDIN(lastStatus, buffer[i], buffer[i + 1]);
|
||||
}
|
||||
break;
|
||||
case 0xC0:
|
||||
case 0xD0:
|
||||
//2 bytes full Midi -> 1 byte runningStatus
|
||||
for (auto i = lPtr; i <= rPtr; i = i + 1)
|
||||
{
|
||||
transmitMIDIonDIN(lastStatus, buffer[i], 0);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#else
|
||||
transmitMIDIonDIN(lastStatus, 0, 0);
|
||||
|
||||
for (auto i = lPtr; i <= rPtr; i++)
|
||||
{
|
||||
transmitMIDIonDIN(buffer[i], 0, 0);
|
||||
}
|
||||
#endif
|
||||
runningStatusContinuation = false;
|
||||
}
|
||||
|
||||
if (++rPtr >= length)
|
||||
return; // end of packet
|
||||
|
||||
if(lastStatus < 0xf0) //exclude System Message. They must not be RunningStatus
|
||||
{
|
||||
previousStatus = lastStatus;
|
||||
}
|
||||
|
||||
timestampByte = buffer[rPtr++];
|
||||
if (timestampByte >= 80) // is bit 7 set?
|
||||
{
|
||||
auto timestampLow = 0x7f & timestampByte;
|
||||
timestamp = timestampLow + (timestampHigh << 7);
|
||||
|
||||
std::cout << "timestamp low is 0x" << std::hex << (int)timestampByte << std::endl;
|
||||
}
|
||||
|
||||
// Point to next status
|
||||
lPtr = rPtr;
|
||||
if (lPtr >= length)
|
||||
return; //end of packet
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << std::endl << "SysEx with RealTime msg in the middle --------" << std::endl;
|
||||
|
||||
byte sysExAndRealTime[] = { 0xB0, 0xF4, // header + timestamp
|
||||
0xF0, // start SysEx
|
||||
0x01, 0x02, 0x03, 0x04, // SysEx data
|
||||
|
||||
// RealTime message in the middle of a SysEx
|
||||
0xF3, // timestampLow
|
||||
0xFA, // Realtime msg: Start
|
||||
|
||||
0x05, 0x06, 0x07, 0x08, // rest of sysex data
|
||||
0xF4, // timestampLow
|
||||
0xF7 }; // end of SysEx
|
||||
|
||||
receive(sysExAndRealTime, sizeof(sysExAndRealTime));
|
||||
|
||||
std::cout << std::endl << "SysEx ---------" << std::endl;
|
||||
|
||||
byte sysExPart[] = { 0xB0, 0xF4, // header + timestamp
|
||||
0xF0, // start SysEx
|
||||
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // sysex data
|
||||
0xF4, // timestampLow
|
||||
0xF7 }; // end of SysEx
|
||||
|
||||
receive(sysExPart, sizeof(sysExPart));
|
||||
|
||||
std::cout << std::endl << "SysEx part 1" << std::endl;
|
||||
|
||||
byte sysExPart1[] = { 0xB0, 0xF4, // header + timestamp
|
||||
0xF0, // start SysEx
|
||||
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; // sysex data
|
||||
receive(sysExPart1, sizeof(sysExPart1));
|
||||
|
||||
std::cout << std::endl << "SysEx part 2" << std::endl;
|
||||
|
||||
byte sysExPart2[] = { 0xB0, // 1 byte header
|
||||
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, // sysex data (cont)
|
||||
0xF4, // timestampLow
|
||||
0xF7 }; // end of SysEx
|
||||
receive(sysExPart2, sizeof(sysExPart2));
|
||||
|
||||
std::cout << "ble Packet with 1 MIDI messages" << std::endl;
|
||||
|
||||
byte blePacketWithOneMIDIMessage[] = { 0xA8, 0xC0,
|
||||
0x90, 0x3E, 0x3E };
|
||||
receive(blePacketWithOneMIDIMessage, sizeof(blePacketWithOneMIDIMessage));
|
||||
|
||||
std::cout << std::endl << "ble Packet with 2 MIDI messages" << std::endl;
|
||||
|
||||
byte blePacketWithTwoMIDIMessage[] = { 0xA8, 0xC0,
|
||||
0x90, 0x3E, 0x3E,
|
||||
0xC1,
|
||||
0x91, 0x3E, 0x3E };
|
||||
receive(blePacketWithTwoMIDIMessage, sizeof(blePacketWithTwoMIDIMessage));
|
||||
|
||||
std::cout << std::endl << "ble Packet with 3 MIDI messages" << std::endl;
|
||||
|
||||
byte blePacketWithThreeMIDIMessage[] = { 0xA8, 0xC0,
|
||||
0x90, 0x3E, 0x3E,
|
||||
0xC1,
|
||||
0xF0,
|
||||
0x01, 0x02,
|
||||
0xC2,
|
||||
0xF7,
|
||||
0xC3,
|
||||
0x91, 0x3E, 0x3E };
|
||||
receive(blePacketWithThreeMIDIMessage, sizeof(blePacketWithThreeMIDIMessage));
|
||||
|
||||
|
||||
std::cout << std::endl << "2 MIDI messages with multiple running status" << std::endl;
|
||||
|
||||
byte twoMIDIMessageWithRunningStatus[] = { 0xA9, 0xAD,
|
||||
0xD1, 0x74, //Full Midi 2 bytes(afterTouch)
|
||||
0x73, //running
|
||||
0xAE, //timeStamp
|
||||
0x72, //running after timeStamp
|
||||
0xAF, //timeStamp
|
||||
0x71, //running after timeStamp
|
||||
0x70,
|
||||
0x69,
|
||||
0x68,
|
||||
0xB2, //
|
||||
0x92, 0x36, 0x70, //Full Midi 3 bytes (noteOn)
|
||||
0xB3, //
|
||||
0x93, 0x37, 0x71,
|
||||
0x38, 0x72,
|
||||
0x39, 0x73,
|
||||
0xB4, //
|
||||
0x40, 0x74
|
||||
};
|
||||
receive(twoMIDIMessageWithRunningStatus, sizeof(twoMIDIMessageWithRunningStatus));
|
||||
|
||||
|
||||
std::cout << std::endl << "2 MIDI messages with multiple running status and a System message in middle" << std::endl;
|
||||
|
||||
byte twoMIDIMessageWithRunningStatusPlusSys[] = { 0xA9, 0xAD,
|
||||
0xD1, 0x74, //Full Midi 2 bytes(afterTouch)
|
||||
0x73, //running
|
||||
0xAE, //timeStamp
|
||||
0x72, //running after timeStamp
|
||||
0xAF, //timeStamp
|
||||
0x71, //running after timeStamp
|
||||
0x70,
|
||||
0x69,
|
||||
0x68,
|
||||
0xB2, //
|
||||
0xFA, // <- Sys START
|
||||
0xB2,
|
||||
0x92, 0x36, 0x70, //Full Midi 3 bytes (noteOn)
|
||||
0xB3, //
|
||||
0x93, 0x37, 0x71,
|
||||
0x38, 0x72,
|
||||
0xB3, //
|
||||
0xFC, // <- Sys STOP
|
||||
0xB3,
|
||||
0x39, 0x73,
|
||||
0xB4, //
|
||||
0x40, 0x74
|
||||
};
|
||||
receive(twoMIDIMessageWithRunningStatusPlusSys, sizeof(twoMIDIMessageWithRunningStatusPlusSys));
|
||||
}
|
||||
|
|
@ -116,6 +116,7 @@
|
|||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>C:\Users\bart\Documents\Arduino\libraries\arduino_midi_library-master\src;C:\Users\bart\Documents\Arduino\libraries\Arduino-BLE-MIDI-master\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
|
@ -139,7 +140,11 @@
|
|||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ConsoleApplication2.cpp" />
|
||||
<ClCompile Include="midiBLE.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Arduino.h" />
|
||||
<ClInclude Include="BLEMIDI_Sim.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
#include "Arduino.h"
|
||||
#include <BLEMIDI_Transport.h>
|
||||
#include "BLEMIDI_Sim.h"
|
||||
|
||||
BLEMIDI_CREATE_DEFAULT_INSTANCE()
|
||||
|
||||
void begin()
|
||||
{
|
||||
MIDI.setHandleNoteOn([](byte channel, byte note, byte velocity) {
|
||||
std::cout << std::hex << "NoteOn from Channel:" << (int)channel << " Note:" << (int)note << " Velocity:" << (int)velocity << std::endl;
|
||||
});
|
||||
MIDI.setHandleNoteOff([](byte channel, byte note, byte velocity) {
|
||||
std::cout << std::hex << "NoteOff from Channel:" << (int)channel << " Note:" << (int)note << " Velocity:" << (int)velocity << std::endl;
|
||||
});
|
||||
MIDI.setHandleNoteOff([](byte channel, byte note, byte velocity) {
|
||||
std::cout << std::hex << "NoteOff from Channel:" << (int)channel << " Note:" << (int)note << " Velocity:" << (int)velocity << std::endl;
|
||||
});
|
||||
MIDI.setHandleControlChange([](byte channel, byte v1, byte v2) {
|
||||
std::cout << std::hex << "ControlChange from Channel:" << (int)channel << " v1:" << (int)v1 << " v2:" << (int)v2 << std::endl;
|
||||
});
|
||||
MIDI.setHandleProgramChange([](byte channel, byte v1) {
|
||||
std::cout << std::hex << "ProgramChange from Channel:" << (int)channel << " v1:" << (int)v1 << std::endl;
|
||||
});
|
||||
MIDI.setHandlePitchBend([](byte channel, int v1) {
|
||||
std::cout << std::hex << "PitchBend from Channel:" << (int)channel << " v1:" << (int)v1 << std::endl;
|
||||
});
|
||||
MIDI.setHandleSystemExclusive([](byte* data, unsigned length) {
|
||||
std::cout << std::hex << "SysEx:";
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
std::cout << std::hex << "0x" << (int)data[i] << " ";
|
||||
std::cout << std::endl;
|
||||
});
|
||||
|
||||
MIDI.begin(MIDI_CHANNEL_OMNI);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
MIDI.read();
|
||||
}
|
||||
Loading…
Reference in New Issue