Working BLE MIDI (not tested with SysEx)

This commit is contained in:
lathoub 2020-03-03 20:23:16 +01:00
parent 324d0404f5
commit 90b83e2360
10 changed files with 61 additions and 231 deletions

View File

@ -2,9 +2,12 @@
#include <midi_bleTransport.h> #include <midi_bleTransport.h>
#include <Ble_esp32.h> #include <Ble_esp32.h>
bleMidi::BluetoothEsp32 sBluetoothEsp32;
bleMidi::BleMidiTransport<bleMidi::BluetoothEsp32> bm((bleMidi::BluetoothEsp32&) sBluetoothEsp32); typedef BLEMIDI_NAMESPACE::BleMidiTransport<BLEMIDI_NAMESPACE::BluetoothEsp32> bleMIDI_t;
midi::MidiInterface<bleMidi::BleMidiTransport<bleMidi::BluetoothEsp32>> MIDI((bleMidi::BleMidiTransport<bleMidi::BluetoothEsp32>&)bm); bleMIDI_t bm("Huzzah BLE MIDI");
MIDI_NAMESPACE::MidiInterface<bleMIDI_t> MIDI((bleMIDI_t &)bm);
USING_NAMESPACE_BLEMIDI
unsigned long t0 = millis(); unsigned long t0 = millis();
bool isConnected = false; bool isConnected = false;
@ -17,7 +20,7 @@ void setup()
// Serial communications and wait for port to open: // Serial communications and wait for port to open:
DEBUG_BEGIN(115200); DEBUG_BEGIN(115200);
MIDI.begin("Huzzah BLE MIDI", 1); MIDI.begin(1);
bm.onConnected(OnBleMidiConnected); bm.onConnected(OnBleMidiConnected);
bm.onDisconnected(OnBleMidiDisconnected); bm.onDisconnected(OnBleMidiDisconnected);
@ -39,8 +42,8 @@ void loop()
{ {
t0 = millis(); t0 = millis();
MIDI.sendNoteOn(60, 127, 1); // note 60, velocity 127 on channel 1 // MIDI.sendNoteOn(60, 127, 1); // note 60, velocity 127 on channel 1
MIDI.sendNoteOff(60, 127, 1); // MIDI.sendNoteOff(60, 0, 1);
} }
} }
@ -69,7 +72,7 @@ void OnBleMidiDisconnected() {
// received note on // received note on
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void OnBleMidiNoteOn(byte channel, byte note, byte velocity) { void OnBleMidiNoteOn(byte channel, byte note, byte velocity) {
N_DEBUG_PRINT(F("Incoming NoteOn from channel:")); N_DEBUG_PRINT(F("Incoming NoteOn from channel:"));
N_DEBUG_PRINT(channel); N_DEBUG_PRINT(channel);
N_DEBUG_PRINT(F(" note:")); N_DEBUG_PRINT(F(" note:"));
N_DEBUG_PRINT(note); N_DEBUG_PRINT(note);

View File

@ -25,10 +25,6 @@ public:
{ {
} }
~BluetoothEsp32()
{
}
bool begin(const char*, BleMidiTransport<class BluetoothEsp32>*); bool begin(const char*, BleMidiTransport<class BluetoothEsp32>*);
inline void write(uint8_t* data, uint8_t length) inline void write(uint8_t* data, uint8_t length)
@ -84,7 +80,7 @@ protected:
void onWrite(BLECharacteristic * characteristic) { void onWrite(BLECharacteristic * characteristic) {
std::string rxValue = characteristic->getValue(); std::string rxValue = characteristic->getValue();
if (rxValue.length() > 0) { if (rxValue.length() > 2) {
_bluetoothEsp32->receive((uint8_t *)(rxValue.c_str()), rxValue.length()); _bluetoothEsp32->receive((uint8_t *)(rxValue.c_str()), rxValue.length());
} }
} }

View File

@ -3,14 +3,16 @@
#include "midi_bleNamespace.h" #include "midi_bleNamespace.h"
#if ARDUINO #if ARDUINO
#include <Arduino.h> #include <Arduino.h>
#else #else
#include <inttypes.h> #include <inttypes.h>
typedef uint8_t byte; typedef uint8_t byte;
#endif #endif
BEGIN_BLEMIDI_NAMESPACE BEGIN_BLEMIDI_NAMESPACE
#define BleBuffer_t Deque<byte, 44>
/*! \brief Create an instance of the library /*! \brief Create an instance of the library
*/ */
#define BLEMIDI_CREATE_INSTANCE(Type, Name) \ #define BLEMIDI_CREATE_INSTANCE(Type, Name) \

View File

@ -4,6 +4,10 @@
#pragma once #pragma once
#include "utility/midi_feat4_4_0/MIDI.h"
#include "utility/Logging.h"
#include "midi_bleSettings.h" #include "midi_bleSettings.h"
#include "midi_bleDefs.h" #include "midi_bleDefs.h"
@ -15,34 +19,40 @@ template<class BleClass>
class BleMidiTransport class BleMidiTransport
{ {
private: private:
Deque<byte, 44> mRxBuffer; byte mRxBuffer[44];
unsigned mRxIndex = 0;
byte mTxBuffer[44]; byte mTxBuffer[44];
unsigned mTxIndex = 0; unsigned mTxIndex = 0;
char mDeviceName[24];
private: private:
BleClass& mBleClass; BleClass mBleClass;
public: public:
inline BleMidiTransport(BleClass& inBleClass) BleMidiTransport(const char* deviceName)
: mBleClass(inBleClass)
{ {
strncpy(mDeviceName, deviceName, 24);
mRxIndex = 0;
mTxIndex = 0;
} }
inline ~BleMidiTransport() {} void begin(MIDI_NAMESPACE::Channel inChannel = 1)
{
mBleClass.begin(mDeviceName, this);
}
inline bool begin(int baudrate) {} // n/a bool beginTransmission()
inline bool begin(const char* deviceName) { return mBleClass.begin(deviceName, this); }
inline unsigned available() { return mRxBuffer.getLength(); }
inline byte read() { return mRxBuffer.read(); }
inline void beginWrite()
{ {
getMidiTimestamp(&mTxBuffer[0], &mTxBuffer[1]); getMidiTimestamp(&mTxBuffer[0], &mTxBuffer[1]);
mTxIndex = 2; mTxIndex = 2;
return true;
} }
inline void write(byte inData)
void write(byte inData)
{ {
// check for size! SysEx!!! // check for size! SysEx!!!
if (false) if (false)
@ -54,16 +64,32 @@ public:
mTxBuffer[mTxIndex++] = inData; mTxBuffer[mTxIndex++] = inData;
} }
inline void endWrite()
void endTransmission()
{ {
mBleClass.write(mTxBuffer, mTxIndex); mBleClass.write(mTxBuffer, mTxIndex);
mTxIndex = 0;
} }
unsigned available()
{
return mRxIndex;
}
byte read()
{
return mRxBuffer[--mRxIndex];
}
public: public:
void receive(uint8_t* buffer, uint8_t length) void receive(uint8_t* buffer, uint8_t length)
{ {
// TODO: check for size!! (SysEx!!) // drop the first 2 bytes
mRxBuffer.read(buffer, length);
for (int i = 2; i < length; i++)
mRxBuffer[length - i - 1] = buffer[i];
mRxIndex = (length - 2);
} }
protected: protected:

View File

@ -1,5 +1,7 @@
#pragma once #pragma once
#include <stddef.h>
template<typename T, size_t Size> template<typename T, size_t Size>
class Deque { class Deque {
// class iterator; // class iterator;

View File

@ -1,31 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29306.81
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestParser", "TestParser.vcxproj", "{25F82AE6-0CAA-4AF7-A003-BB54DB5EBA5E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{25F82AE6-0CAA-4AF7-A003-BB54DB5EBA5E}.Debug|x64.ActiveCfg = Debug|x64
{25F82AE6-0CAA-4AF7-A003-BB54DB5EBA5E}.Debug|x64.Build.0 = Debug|x64
{25F82AE6-0CAA-4AF7-A003-BB54DB5EBA5E}.Debug|x86.ActiveCfg = Debug|Win32
{25F82AE6-0CAA-4AF7-A003-BB54DB5EBA5E}.Debug|x86.Build.0 = Debug|Win32
{25F82AE6-0CAA-4AF7-A003-BB54DB5EBA5E}.Release|x64.ActiveCfg = Release|x64
{25F82AE6-0CAA-4AF7-A003-BB54DB5EBA5E}.Release|x64.Build.0 = Release|x64
{25F82AE6-0CAA-4AF7-A003-BB54DB5EBA5E}.Release|x86.ActiveCfg = Release|Win32
{25F82AE6-0CAA-4AF7-A003-BB54DB5EBA5E}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E91ABBB5-98C4-4D25-B603-CA43FE39B327}
EndGlobalSection
EndGlobal

View File

@ -1,138 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<ProjectGuid>{25F82AE6-0CAA-4AF7-A003-BB54DB5EBA5E}</ProjectGuid>
<RootNamespace>TestParser</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<LanguageStandard>Default</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="NoteOn.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Arduino.h" />
<ClInclude Include="Ethernet.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,26 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="NoteOn.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Arduino.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Ethernet.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>