From 491cca381982f9d9f5e2b78674a982921c12ddb8 Mon Sep 17 00:00:00 2001 From: Alfred Date: Wed, 4 Jul 2018 21:54:03 +0200 Subject: [PATCH 1/3] MaschineMK1 MIDI OUT enqueuing --- src/devices/ni/MaschineMK1.cpp | 36 +++++++++++++++++++++++++++------- src/devices/ni/MaschineMK1.h | 5 +++++ 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/devices/ni/MaschineMK1.cpp b/src/devices/ni/MaschineMK1.cpp index 1ece218..f5c61a0 100644 --- a/src/devices/ni/MaschineMK1.cpp +++ b/src/devices/ni/MaschineMK1.cpp @@ -181,10 +181,7 @@ void MaschineMK1::setKeyLed(unsigned index_, const Color& color_) void MaschineMK1::sendMidiMsg(tRawData midiMsg_) { - uint8_t lengthH = (midiMsg_.size() >> 8) & 0xFF; - uint8_t lengthL = midiMsg_.size() & 0xFF; - writeToDeviceHandle( - Transfer({0x07, lengthH, lengthL}, midiMsg_.data(), midiMsg_.size()), kMASMK1_epOut); + m_MidiOutQueue.push_back(midiMsg_); } //-------------------------------------------------------------------------------------------------- @@ -226,14 +223,17 @@ bool MaschineMK1::tick() { success = sendLeds(); } + else if (state == 3) + { + success = writeMidiMsg(); + } if (!success) { - std::string strStepName(state == 0 ? "sendFrame" : (state == 1 ? "read" : "sendLeds")); - M_LOG("[MaschineMK1] tick: error in step #" << state << " (" << strStepName << ")"); + M_LOG("[MaschineMK1] tick: error in step #" << state); } - if (++state >= 3) + if (++state > 3) { state = 0; } @@ -416,6 +416,28 @@ bool MaschineMK1::read() //-------------------------------------------------------------------------------------------------- +bool MaschineMK1::writeMidiMsg() +{ + while(!m_MidiOutQueue.empty()) + { + tRawData midiMsg_ = m_MidiOutQueue.front(); + m_MidiOutQueue.pop_front(); + + uint8_t lengthH = (midiMsg_.size() >> 8) & 0xFF; + uint8_t lengthL = midiMsg_.size() & 0xFF; + Transfer transfer({0x07, lengthH, lengthL}, midiMsg_.data(), midiMsg_.size()); + + if (!writeToDeviceHandle(transfer, kMASMK1_epOut)) + { + M_LOG("[MaschineMK1] sendLeds: error writing midi message"); + return false; + } + } + return true; +} + +//-------------------------------------------------------------------------------------------------- + void MaschineMK1::processPads(const Transfer& input_) { for (int i = 1; i < kMASMK1_padDataSize - 1; i += 2) diff --git a/src/devices/ni/MaschineMK1.h b/src/devices/ni/MaschineMK1.h index 63980cb..1f885bf 100644 --- a/src/devices/ni/MaschineMK1.h +++ b/src/devices/ni/MaschineMK1.h @@ -8,6 +8,7 @@ #pragma once #include +#include #include "cabl/comm/Transfer.h" #include "cabl/devices/Device.h" @@ -76,6 +77,7 @@ class MaschineMK1 : public Device bool sendFrame(uint8_t displayIndex_); bool sendLeds(); bool read(); + bool writeMidiMsg(); void processPads(const Transfer&); void processButtons(const Transfer&); @@ -105,6 +107,9 @@ class MaschineMK1 : public Device bool m_isDirtyLedGroup0{true}; bool m_isDirtyLedGroup1{true}; bool m_encodersInitialized{false}; + + std::deque m_MidiOutQueue; + }; //-------------------------------------------------------------------------------------------------- From 3f55e2d51158bf473e782e77ec518d2be73e7a71 Mon Sep 17 00:00:00 2001 From: Alfred Date: Thu, 5 Jul 2018 22:04:38 +0200 Subject: [PATCH 2/3] MaschineMK1 MIDI IN decoding --- src/devices/ni/MaschineMK1.cpp | 76 +++++++++++++++++++++++++++++++++- src/devices/ni/MaschineMK1.h | 3 ++ 2 files changed, 77 insertions(+), 2 deletions(-) diff --git a/src/devices/ni/MaschineMK1.cpp b/src/devices/ni/MaschineMK1.cpp index f5c61a0..18fcfd1 100644 --- a/src/devices/ni/MaschineMK1.cpp +++ b/src/devices/ni/MaschineMK1.cpp @@ -8,6 +8,8 @@ #include "devices/ni/MaschineMK1.h" #include +#include +#include #include "cabl/comm/Driver.h" #include "cabl/comm/Transfer.h" @@ -161,6 +163,19 @@ enum class MaschineMK1::Button : uint8_t MaschineMK1::MaschineMK1() { m_leds.resize(kMASMK1_ledsDataSize); + + try + { + m_pVirtualMidiIn.reset(new RtMidiOut(RtMidi::UNSPECIFIED,"Maschine MK1")); + m_pVirtualMidiIn->openVirtualPort("Received MIDI IN"); + } + catch (std::exception const & e) + { + M_LOG("[MaschineMK1] Could not init virtual MIDI IN port: " << e.what()); + m_pVirtualMidiIn.reset(); + } + + } //-------------------------------------------------------------------------------------------------- @@ -464,6 +479,64 @@ void MaschineMK1::processPads(const Transfer& input_) } } } +// +//-------------------------------------------------------------------------------------------------- + +bool popCompleteMidiMsg( std::deque & midi_buffer, tRawData & out_msg ) +{ + while ( !midi_buffer.empty() + && ( midi_buffer[0]&0x80 == 0 // Skipping until first command bit. + || midi_buffer[0]&0xF0 == 0xF0 ) ) // Skipping non music commands. + { + midi_buffer.pop_front(); + } + + if (midi_buffer.empty()) + { + return false; + } + + uint8_t msg_type = midi_buffer[0]; + + uint8_t expected_size = 3; + if ( msg_type & 0xC0 // MidiMessage::Type::ProgramChange + || msg_type & 0xD0 ) // MidiMessage::Type::ChannelPressure + { + expected_size = 2; + } + + if (midi_buffer.size() < expected_size) + { + //Should wait for next chunk of message. + return false; + } + + out_msg.clear(); + for ( size_t i=0 ; isendMessage( &msg ); + } + } +} //-------------------------------------------------------------------------------------------------- @@ -757,8 +830,7 @@ void MaschineMK1::cbRead(Transfer input_) } else if (input_[0] == 0x06) { - M_LOG("[MaschineMK1] read: received MIDI message"); - //!\todo Add MIDI in parsing + processMidiIn(input_); } } diff --git a/src/devices/ni/MaschineMK1.h b/src/devices/ni/MaschineMK1.h index 1f885bf..168325a 100644 --- a/src/devices/ni/MaschineMK1.h +++ b/src/devices/ni/MaschineMK1.h @@ -82,6 +82,7 @@ class MaschineMK1 : public Device void processPads(const Transfer&); void processButtons(const Transfer&); void processEncoders(const Transfer&); + void processMidiIn(const Transfer&); void setLedImpl(Led, const Color&); Led led(Device::Button) const noexcept; @@ -109,7 +110,9 @@ class MaschineMK1 : public Device bool m_encodersInitialized{false}; std::deque m_MidiOutQueue; + std::deque m_MidiInBuffer; + std::unique_ptr m_pVirtualMidiIn; }; //-------------------------------------------------------------------------------------------------- From e9c71f02c8eecfeddfe95b01f759a3f6bd028d31 Mon Sep 17 00:00:00 2001 From: Alfred Date: Tue, 10 Jul 2018 21:47:37 +0200 Subject: [PATCH 3/3] MaschineMK1 virtual MIDI OUT port --- src/devices/ni/MaschineMK1.cpp | 36 ++++++++++++++++++++++++++++++---- src/devices/ni/MaschineMK1.h | 3 +++ 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/devices/ni/MaschineMK1.cpp b/src/devices/ni/MaschineMK1.cpp index 18fcfd1..e43d512 100644 --- a/src/devices/ni/MaschineMK1.cpp +++ b/src/devices/ni/MaschineMK1.cpp @@ -175,6 +175,17 @@ MaschineMK1::MaschineMK1() m_pVirtualMidiIn.reset(); } + try + { + m_pVirtualMidiOut.reset(new RtMidiIn(RtMidi::UNSPECIFIED,"Maschine MK1")); + m_pVirtualMidiOut->ignoreTypes(false,false,false); // sends everything. + m_pVirtualMidiOut->openVirtualPort("send MIDI OUT"); + } + catch (std::exception const & e) + { + M_LOG("[MaschineMK1] Could not init virtual MIDI OUT port: " << e.what()); + m_pVirtualMidiOut.reset(); + } } @@ -431,13 +442,30 @@ bool MaschineMK1::read() //-------------------------------------------------------------------------------------------------- +bool MaschineMK1::getNextMidiOutMsg(tRawData & midiMsg_) +{ + if (!m_MidiOutQueue.empty()) + { + midiMsg_ = std::move(m_MidiOutQueue.front()); + m_MidiOutQueue.pop_front(); + return true; + } + + if (m_pVirtualMidiOut) + { + m_pVirtualMidiOut->getMessage(&midiMsg_); + return !midiMsg_.empty(); + } + + return false; +} + bool MaschineMK1::writeMidiMsg() { - while(!m_MidiOutQueue.empty()) - { - tRawData midiMsg_ = m_MidiOutQueue.front(); - m_MidiOutQueue.pop_front(); + static tRawData midiMsg_; + while (getNextMidiOutMsg(midiMsg_)) + { uint8_t lengthH = (midiMsg_.size() >> 8) & 0xFF; uint8_t lengthL = midiMsg_.size() & 0xFF; Transfer transfer({0x07, lengthH, lengthL}, midiMsg_.data(), midiMsg_.size()); diff --git a/src/devices/ni/MaschineMK1.h b/src/devices/ni/MaschineMK1.h index 168325a..7a1ea4d 100644 --- a/src/devices/ni/MaschineMK1.h +++ b/src/devices/ni/MaschineMK1.h @@ -77,6 +77,8 @@ class MaschineMK1 : public Device bool sendFrame(uint8_t displayIndex_); bool sendLeds(); bool read(); + + bool getNextMidiOutMsg(tRawData & midiMsg_); bool writeMidiMsg(); void processPads(const Transfer&); @@ -113,6 +115,7 @@ class MaschineMK1 : public Device std::deque m_MidiInBuffer; std::unique_ptr m_pVirtualMidiIn; + std::unique_ptr m_pVirtualMidiOut; }; //--------------------------------------------------------------------------------------------------