| @@ -88,14 +88,20 @@ struct ConnectedDeviceGroup : private juce::AsyncUpdater, | |||||
| ConnectedDeviceGroup (Detector& d, const juce::String& name, PhysicalTopologySource::DeviceConnection* connection) | ConnectedDeviceGroup (Detector& d, const juce::String& name, PhysicalTopologySource::DeviceConnection* connection) | ||||
| : detector (d), deviceName (name), deviceConnection (connection) | : detector (d), deviceName (name), deviceConnection (connection) | ||||
| { | { | ||||
| deviceConnection->handleMessageFromDevice = [this] (const void* data, size_t dataSize) | |||||
| { | |||||
| this->handleIncomingMessage (data, dataSize); | |||||
| }; | |||||
| if (auto midiDeviceConnection = static_cast<MIDIDeviceConnection*> (deviceConnection.get())) | if (auto midiDeviceConnection = static_cast<MIDIDeviceConnection*> (deviceConnection.get())) | ||||
| { | |||||
| depreciatedVersionReader = std::make_unique<DepreciatedVersionReader> (*midiDeviceConnection); | depreciatedVersionReader = std::make_unique<DepreciatedVersionReader> (*midiDeviceConnection); | ||||
| juce::ScopedLock lock (midiDeviceConnection->criticalSecton); | |||||
| setMidiMessageCallback(); | |||||
| } | |||||
| else | |||||
| { | |||||
| setMidiMessageCallback(); | |||||
| } | |||||
| startTimer (200); | startTimer (200); | ||||
| sendTopologyRequest(); | sendTopologyRequest(); | ||||
| } | } | ||||
| @@ -372,6 +378,15 @@ private: | |||||
| Block::UID masterBlock = 0; | Block::UID masterBlock = 0; | ||||
| //============================================================================== | |||||
| void setMidiMessageCallback() | |||||
| { | |||||
| deviceConnection->handleMessageFromDevice = [this] (const void* data, size_t dataSize) | |||||
| { | |||||
| this->handleIncomingMessage (data, dataSize); | |||||
| }; | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| juce::Time lastTopologyRequestTime, lastTopologyReceiveTime; | juce::Time lastTopologyRequestTime, lastTopologyReceiveTime; | ||||
| int numTopologyRequestsSent = 0; | int numTopologyRequestsSent = 0; | ||||
| @@ -70,10 +70,10 @@ private: | |||||
| static constexpr size_t numFirmwareApps = 3; | static constexpr size_t numFirmwareApps = 3; | ||||
| BlocksProtocol::VersionNumber result[numFirmwareApps]; | BlocksProtocol::VersionNumber result[numFirmwareApps]; | ||||
| MIDIDeviceConnection& deviceConnection; | MIDIDeviceConnection& deviceConnection; | ||||
| size_t currentRequest = 0; | |||||
| juce::Atomic<size_t> currentRequest = 0; | |||||
| //============================================================================== | //============================================================================== | ||||
| bool allRequestsComplete() const { return currentRequest >= numFirmwareApps; } | |||||
| bool allRequestsComplete() const { return currentRequest.get() >= numFirmwareApps; } | |||||
| //============================================================================== | //============================================================================== | ||||
| void makeNextRequest() | void makeNextRequest() | ||||
| @@ -83,17 +83,17 @@ private: | |||||
| { 0xf0, 0x00, 0x21, 0x10, 0x47, 0x03, 0x01, 0xf7 }, // Stm32 | { 0xf0, 0x00, 0x21, 0x10, 0x47, 0x03, 0x01, 0xf7 }, // Stm32 | ||||
| { 0xf0, 0x00, 0x21, 0x10, 0x47, 0x03, 0x03, 0xf7 }}; // Bootloader | { 0xf0, 0x00, 0x21, 0x10, 0x47, 0x03, 0x03, 0xf7 }}; // Bootloader | ||||
| deviceConnection.sendMessageToDevice (&requests[currentRequest][0], requestSize); | |||||
| deviceConnection.sendMessageToDevice (&requests[currentRequest.get()][0], requestSize); | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| void processVersionMessage (const uint8* data, const size_t size) | void processVersionMessage (const uint8* data, const size_t size) | ||||
| { | { | ||||
| if (currentRequest >= numFirmwareApps || size < 1 || size - 1 > VersionNumber::maxLength) | |||||
| if (currentRequest.get() >= numFirmwareApps || size < 1 || size - 1 > VersionNumber::maxLength) | |||||
| return; | return; | ||||
| result[currentRequest].length = uint8 (size - 1); | |||||
| memcpy (result[currentRequest].data, data, result[currentRequest].length); | |||||
| result[currentRequest.get()].length = uint8 (size - 1); | |||||
| memcpy (result[currentRequest.get()].data, data, result[currentRequest.get()].length); | |||||
| ++currentRequest; | ++currentRequest; | ||||
| @@ -63,11 +63,13 @@ struct MIDIDeviceConnection : public PhysicalTopologySource::DeviceConnection, | |||||
| void addListener (Listener* l) | void addListener (Listener* l) | ||||
| { | { | ||||
| juce::ScopedLock scopedLock (criticalSecton); | |||||
| listeners.add (l); | listeners.add (l); | ||||
| } | } | ||||
| void removeListener (Listener* l) | void removeListener (Listener* l) | ||||
| { | { | ||||
| juce::ScopedLock scopedLock (criticalSecton); | |||||
| listeners.remove (l); | listeners.remove (l); | ||||
| } | } | ||||
| @@ -90,20 +92,27 @@ struct MIDIDeviceConnection : public PhysicalTopologySource::DeviceConnection, | |||||
| void handleIncomingMidiMessage (juce::MidiInput*, const juce::MidiMessage& message) override | void handleIncomingMidiMessage (juce::MidiInput*, const juce::MidiMessage& message) override | ||||
| { | { | ||||
| const auto data = message.getRawData(); | |||||
| const int dataSize = message.getRawDataSize(); | |||||
| const int bodySize = dataSize - (int) (sizeof (BlocksProtocol::roliSysexHeader) + 1); | |||||
| juce::ScopedTryLock lock (criticalSecton); | |||||
| if (bodySize > 0 && memcmp (data, BlocksProtocol::roliSysexHeader, sizeof (BlocksProtocol::roliSysexHeader)) == 0) | |||||
| if (handleMessageFromDevice != nullptr) | |||||
| handleMessageFromDevice (data + sizeof (BlocksProtocol::roliSysexHeader), (size_t) bodySize); | |||||
| if (lock.isLocked()) | |||||
| { | |||||
| const auto data = message.getRawData(); | |||||
| const int dataSize = message.getRawDataSize(); | |||||
| const int bodySize = dataSize - (int) (sizeof (BlocksProtocol::roliSysexHeader) + 1); | |||||
| if (bodySize > 0 && memcmp (data, BlocksProtocol::roliSysexHeader, sizeof (BlocksProtocol::roliSysexHeader)) == 0) | |||||
| if (handleMessageFromDevice != nullptr) | |||||
| handleMessageFromDevice (data + sizeof (BlocksProtocol::roliSysexHeader), (size_t) bodySize); | |||||
| listeners.call ([&] (Listener& l) { l.handleIncomingMidiMessage (message); }); | |||||
| listeners.call ([&] (Listener& l) { l.handleIncomingMidiMessage (message); }); | |||||
| } | |||||
| } | } | ||||
| std::unique_ptr<juce::MidiInput> midiInput; | std::unique_ptr<juce::MidiInput> midiInput; | ||||
| std::unique_ptr<juce::MidiOutput> midiOutput; | std::unique_ptr<juce::MidiOutput> midiOutput; | ||||
| juce::CriticalSection criticalSecton; | |||||
| private: | private: | ||||
| juce::ListenerList<Listener> listeners; | juce::ListenerList<Listener> listeners; | ||||
| std::unique_ptr<juce::InterProcessLock> interprocessLock; | std::unique_ptr<juce::InterProcessLock> interprocessLock; | ||||