| @@ -88,14 +88,20 @@ struct ConnectedDeviceGroup : private juce::AsyncUpdater, | |||
| ConnectedDeviceGroup (Detector& d, const juce::String& name, PhysicalTopologySource::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())) | |||
| { | |||
| depreciatedVersionReader = std::make_unique<DepreciatedVersionReader> (*midiDeviceConnection); | |||
| juce::ScopedLock lock (midiDeviceConnection->criticalSecton); | |||
| setMidiMessageCallback(); | |||
| } | |||
| else | |||
| { | |||
| setMidiMessageCallback(); | |||
| } | |||
| startTimer (200); | |||
| sendTopologyRequest(); | |||
| } | |||
| @@ -372,6 +378,15 @@ private: | |||
| Block::UID masterBlock = 0; | |||
| //============================================================================== | |||
| void setMidiMessageCallback() | |||
| { | |||
| deviceConnection->handleMessageFromDevice = [this] (const void* data, size_t dataSize) | |||
| { | |||
| this->handleIncomingMessage (data, dataSize); | |||
| }; | |||
| } | |||
| //============================================================================== | |||
| juce::Time lastTopologyRequestTime, lastTopologyReceiveTime; | |||
| int numTopologyRequestsSent = 0; | |||
| @@ -70,10 +70,10 @@ private: | |||
| static constexpr size_t numFirmwareApps = 3; | |||
| BlocksProtocol::VersionNumber result[numFirmwareApps]; | |||
| 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() | |||
| @@ -83,17 +83,17 @@ private: | |||
| { 0xf0, 0x00, 0x21, 0x10, 0x47, 0x03, 0x01, 0xf7 }, // Stm32 | |||
| { 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) | |||
| { | |||
| if (currentRequest >= numFirmwareApps || size < 1 || size - 1 > VersionNumber::maxLength) | |||
| if (currentRequest.get() >= numFirmwareApps || size < 1 || size - 1 > VersionNumber::maxLength) | |||
| 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; | |||
| @@ -63,11 +63,13 @@ struct MIDIDeviceConnection : public PhysicalTopologySource::DeviceConnection, | |||
| void addListener (Listener* l) | |||
| { | |||
| juce::ScopedLock scopedLock (criticalSecton); | |||
| listeners.add (l); | |||
| } | |||
| void removeListener (Listener* l) | |||
| { | |||
| juce::ScopedLock scopedLock (criticalSecton); | |||
| listeners.remove (l); | |||
| } | |||
| @@ -90,20 +92,27 @@ struct MIDIDeviceConnection : public PhysicalTopologySource::DeviceConnection, | |||
| 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::MidiOutput> midiOutput; | |||
| juce::CriticalSection criticalSecton; | |||
| private: | |||
| juce::ListenerList<Listener> listeners; | |||
| std::unique_ptr<juce::InterProcessLock> interprocessLock; | |||