diff --git a/Source/Processors/Channel/InfoObjects.h b/Source/Processors/Channel/InfoObjects.h index 2cf7eb8f34bd3aabe7788a00691a22c7f10b24ee..cc2ea71544f290f0065dd265f14bc0772bede7b0 100644 --- a/Source/Processors/Channel/InfoObjects.h +++ b/Source/Processors/Channel/InfoObjects.h @@ -239,7 +239,7 @@ public: { //Numeration kept to maintain compatibility with old code TTL = 3, - MESSAGE = 5, + TEXT = 5, //generic binary types. These will be treated by the majority of record engines as simple binary blobs, //while having strict typing helps creating stabler plugins INT8_ARRAY = 10, @@ -255,7 +255,7 @@ public: }; /** Default constructor - @param type The type of event this channel represents (TTL, MESSAGE, BYINARY_MSG) + @param type The type of event this channel represents (TTL, TEXT, BYINARY_MSG) @param idx The index of this event channel in the source processor @param typeidx The index of this particular type of event channel in the source processor @param source A pointer to the source processor diff --git a/Source/Processors/Channel/MetaData.cpp b/Source/Processors/Channel/MetaData.cpp index e29e5dd68191a2e6ed521769d46b4c26407aa479..c5b8726963af74c41be5866670a3bc3efd20e6fa 100644 --- a/Source/Processors/Channel/MetaData.cpp +++ b/Source/Processors/Channel/MetaData.cpp @@ -119,7 +119,7 @@ MetaDataValue::MetaDataValue(const MetaDataDescriptor& m) bool MetaDataValue::isOfType(const MetaDataDescriptor& m) const { - return ((m.getType() == m_type) && (m.getLength == m_length)); + return ((m.getType() == m_type) && (m.getLength() == m_length)); } bool MetaDataValue::isOfType(const MetaDataDescriptor* m) const @@ -171,6 +171,7 @@ MetaDataValue& MetaDataValue::operator=(MetaDataValue&& v) m_length = v.m_length; m_type = v.m_type; m_data.swapWith(v.m_data); + return *this; } #endif @@ -193,16 +194,16 @@ void MetaDataValue::getValue(String& data) const template <typename T> void MetaDataValue::setValue(T data) { - jassert(m_numel == 1); + jassert(m_length == 1); jassert(checkMetaDataType<T>(m_type)); - *(static_cast<T*>(m_data.getData())) = data; + *(reinterpret_cast<T*>(m_data.getData())) = data; } template <typename T> void MetaDataValue::getValue(T& data) const { jassert(checkMetaDataType<T>(m_type)); - data = *(static_cast<T*>(m_data.getData())); + data = *(reinterpret_cast<T*>(m_data.getData())); } template <typename T> @@ -230,7 +231,7 @@ template <typename T> void MetaDataValue::getValue(Array<T>& data) const { jassert(checkMetaDataType<T>(m_type)); - data.addArray(m_data.getData(), m_numel); + data.addArray(m_data.getData(), m_length); } //Actual template instantiations at the end of the file @@ -288,7 +289,7 @@ const int MetaDataEventObject::getEventMetaDataCount() const } //MetaDataEvent -void MetaDataEvent::SerializeMetaData(void* dstBuffer) const +void MetaDataEvent::serializeMetaData(void* dstBuffer) const { int metaDataSize = m_metaDataValues.size(); char* buffer = static_cast<char*>(dstBuffer); @@ -296,12 +297,30 @@ void MetaDataEvent::SerializeMetaData(void* dstBuffer) const for (int i = 0; i < metaDataSize; i++) { - MetaDataValue* val = m_metaDataValues[i]; + MetaDataValuePtr val = m_metaDataValues[i]; memcpy(buffer + ptrIndex, val->m_data.getData(), val->m_size); ptrIndex += val->m_size; } } +bool MetaDataEvent::deserializeMetaData(const MetaDataEventObject* info, const void* srcBuffer, int size) +{ + MetaDataValueArray metaData; + int nMetaData = info->getEventMetaDataCount(); + size_t memIndex = 0; + for (int i = 0; i < nMetaData; i++) + { + const MetaDataDescriptor* desc = info->getEventMetaDataDescriptor(i); + size_t dataSize = desc->getDataSize(); + if ((memIndex + dataSize) < size) return false; //check for buffer boundaries + + metaData.add(new MetaDataValue(*desc, (static_cast<const char*>(srcBuffer) + memIndex))); + memIndex += dataSize; + } + m_metaDataValues.swapWith(metaData); + return true; +} + //Specific instantiations for templated metadata members. //This is done this way for two reasons //1-To have the actual binary code in the same translation unit, instead of replicated between GUI and plugins, as would happen if @@ -370,7 +389,7 @@ template void MetaDataValue::setValue<float>(const Array<float>&); template void MetaDataValue::setValue<double>(const Array<double>&); template void MetaDataValue::getValue<char>(Array<char>&) const; -template void MetaDataValue::getValue<int8>(Array<int8>&) const; +/*template void MetaDataValue::getValue<int8>(Array<int8>&) const; template void MetaDataValue::getValue<uint8>(Array<uint8>&) const; template void MetaDataValue::getValue<int16>(Array<int16>&) const; template void MetaDataValue::getValue<uint16>(Array<uint16>&) const; @@ -379,4 +398,5 @@ template void MetaDataValue::getValue<uint32>(Array<uint32>&) const; template void MetaDataValue::getValue<int64>(Array<int64>&) const; template void MetaDataValue::getValue<uint64>(Array<uint64>&) const; template void MetaDataValue::getValue<float>(Array<float>&) const; -template void MetaDataValue::getValue<double>(Array<double>&) const; \ No newline at end of file +template void MetaDataValue::getValue<double>(Array<double>&) const; +*/ \ No newline at end of file diff --git a/Source/Processors/Channel/MetaData.h b/Source/Processors/Channel/MetaData.h index da490689df5fa796fe147b7b35ae32e151f661ed..379c51a0e43c80a71421aa1d2c8f11c520f6502a 100644 --- a/Source/Processors/Channel/MetaData.h +++ b/Source/Processors/Channel/MetaData.h @@ -24,7 +24,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #ifndef METADATA_H_INCLUDED #define METADATA_H_INCLUDED -#include "../../../JuceLibraryCode/JuceHeader.h" +#include <JuceHeader.h> #include "../PluginManager/OpenEphysPlugin.h" class GenericProcessor; @@ -141,6 +141,8 @@ private: typedef ReferenceCountedArray<MetaDataDescriptor> MetaDataDescriptorArray; typedef ReferenceCountedArray<MetaDataValue> MetaDataValueArray; +typedef ReferenceCountedObjectPtr<MetaDataDescriptor> MetaDataDescriptorPtr; +typedef ReferenceCountedObjectPtr<MetaDataValue> MetaDataValuePtr; //Inherited for all info objects that have metadata class PLUGIN_API MetaDataInfoObject @@ -188,10 +190,10 @@ protected: class PLUGIN_API MetaDataEvent { protected: - void SerializeMetaData(void* dstBuffer) const; + void serializeMetaData(void* dstBuffer) const; + bool deserializeMetaData(const MetaDataEventObject* info, const void* srcBuffer, int size); MetaDataEvent(); MetaDataValueArray m_metaDataValues; - }; diff --git a/Source/Processors/Events/Events.cpp b/Source/Processors/Events/Events.cpp index 9cfdf89322515462c896ad721eb28919ab5c43f5..9736213db3736a35fc6b61a6e1a2c84d968f8446 100644 --- a/Source/Processors/Events/Events.cpp +++ b/Source/Processors/Events/Events.cpp @@ -23,7 +23,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include "Events.h" #include "../GenericProcessor/GenericProcessor.h" -#define EVENT_EXTRA_SIZE 16 +#define EVENT_BASE_SIZE 18 //EventBase @@ -99,40 +99,41 @@ EventChannel::EventChannelTypes Event::getEventType(const MidiMessage& msg) return static_cast<EventChannel::EventChannelTypes>(*(data + 1)); } -Event::Event(const EventChannel* channelInfo, uint64 timestamp) +Event::Event(const EventChannel* channelInfo, uint64 timestamp, uint16 channel) : EventBase(PROCESSOR_EVENT, timestamp), + m_channel(channel), m_channelInfo(channelInfo), m_eventType(channelInfo->getChannelType()) {} Event* Event::deserializeFromMessage(const MidiMessage& msg, const EventChannel* channelInfo) { - EventChannel::EventChannelTypes type = channelInfo->getChannelType()); + EventChannel::EventChannelTypes type = channelInfo->getChannelType(); if (type == EventChannel::TTL) return TTLEvent::deserializeFromMessage(msg, channelInfo); - else if (type == EventChannel::MESSAGE) - return MessageEvent::deserializeFromMessage(msg, channelInfo); + else if (type == EventChannel::TEXT) + return TextEvent::deserializeFromMessage(msg, channelInfo); else if (type >= EventChannel::INT8_ARRAY && type <= EventChannel::DOUBLE_ARRAY) return BinaryEvent::deserializeFromMessage(msg, channelInfo); else return nullptr; } +uint16 Event::getChannel() const +{ + return m_channel; +} + //TTLEvent -TTLEvent::TTLEvent(const EventChannel* channelInfo, uint64 timestamp, unsigned int channel, const void* eventData) - : Event(channelInfo, timestamp), m_channel(channel) +TTLEvent::TTLEvent(const EventChannel* channelInfo, uint64 timestamp, uint16 channel, const void* eventData) + : Event(channelInfo, timestamp, channel) { size_t size = m_channelInfo->getDataSize(); m_data.malloc(size); memcpy(m_data.getData(), eventData, size); } -unsigned int TTLEvent::getChannel() const -{ - return m_channel; -} - bool TTLEvent::getState() const { int byteIndex = m_channel / 8; @@ -147,10 +148,10 @@ const void* TTLEvent::getTTLWordPointer() const return m_data.getData(); } -void TTLEvent::Serialize(void* dstBuffer, size_t dstSize) const +void TTLEvent::serialize(void* dstBuffer, size_t dstSize) const { size_t dataSize = m_channelInfo->getDataSize(); - size_t eventSize = dataSize + EVENT_EXTRA_SIZE; + size_t eventSize = dataSize + EVENT_BASE_SIZE; size_t totalSize = eventSize + m_channelInfo->getTotalEventMetaDataSize(); if (totalSize < dstSize) { @@ -166,11 +167,12 @@ void TTLEvent::Serialize(void* dstBuffer, size_t dstSize) const *(reinterpret_cast<uint16*>(buffer + 4)) = m_channelInfo->getSubProcessorIdx(); *(reinterpret_cast<uint16*>(buffer + 6)) = m_channelInfo->getSourceIndex(); *(reinterpret_cast<uint64*>(buffer + 8)) = m_timestamp; - memcpy((buffer + 16), m_data.getData(), dataSize); - SerializeMetaData(buffer + eventSize); + *(reinterpret_cast<uint64*>(buffer + 16)) = m_channel; + memcpy((buffer + 18), m_data.getData(), dataSize); + serializeMetaData(buffer + eventSize); } -TTLEvent* TTLEvent::createTTLEvent(const EventChannel* channelInfo, uint64 timestamp, unsigned int channel, const void* eventData) +TTLEvent* TTLEvent::createTTLEvent(const EventChannel* channelInfo, uint64 timestamp, const void* eventData, uint16 channel) { if (!channelInfo) return nullptr; @@ -181,7 +183,7 @@ TTLEvent* TTLEvent::createTTLEvent(const EventChannel* channelInfo, uint64 times return new TTLEvent(channelInfo, timestamp, channel, eventData); } -TTLEvent* TTLEvent::createTTLEvent(const EventChannel* channelInfo, uint64 timestamp, unsigned int channel, const void* eventData, const MetaDataValueArray& metaData) +TTLEvent* TTLEvent::createTTLEvent(const EventChannel* channelInfo, uint64 timestamp, const void* eventData, const MetaDataValueArray& metaData, uint16 channel) { if (!channelInfo) return nullptr; @@ -198,8 +200,10 @@ TTLEvent* TTLEvent::createTTLEvent(const EventChannel* channelInfo, uint64 times TTLEvent* TTLEvent::deserializeFromMessage(const MidiMessage& msg, const EventChannel* channelInfo) { size_t totalSize = msg.getRawDataSize(); + size_t dataSize = channelInfo->getDataSize(); + size_t metaDataSize = channelInfo->getTotalEventMetaDataSize(); - if (totalSize != (channelInfo->getDataSize() + EVENT_EXTRA_SIZE + channelInfo->getTotalEventMetaDataSize())) + if (totalSize != (dataSize + EVENT_BASE_SIZE + metaDataSize)) { return nullptr; } @@ -207,7 +211,24 @@ TTLEvent* TTLEvent::deserializeFromMessage(const MidiMessage& msg, const EventCh if ((buffer + 0) != PROCESSOR_EVENT) return nullptr; if ((buffer + 1) != EventChannel::TTL) return nullptr; - + uint64 timestamp = *(reinterpret_cast<const uint64*>(buffer + 8)); + uint16 channel = *(reinterpret_cast<const uint16*>(buffer + 16)); + + ScopedPointer<TTLEvent> ttl = new TTLEvent(channelInfo, timestamp, channel, (buffer + 16)); + bool ret; + if (metaDataSize > 0) + ret = ttl->deserializeMetaData(channelInfo, (buffer + EVENT_BASE_SIZE + dataSize), metaDataSize); + if (ret) + return ttl.release(); + else + return nullptr; +} + +//TextEvent + +TextEvent(const EventChannel* channelInfo, uint64 timestamp, uint16 channel, const String& msg) + : Event(channelInfo, timestamp, channel) +{ } \ No newline at end of file diff --git a/Source/Processors/Events/Events.h b/Source/Processors/Events/Events.h index f4546da9c49adac36fecfa624a75445d60d8e931..ec289e1d6c394b03609a3b9d73c1363014fe2a30 100644 --- a/Source/Processors/Events/Events.h +++ b/Source/Processors/Events/Events.h @@ -36,7 +36,8 @@ EventType - 1byte SubType - 1byte Source processor ID - 2bytes Source Subprocessor index - 2 bytes -Source Channel index (except system events) +Source Event index - 2 bytes (except system events) +Event Virtual Channel - 2 byte Timestamp - 8 bytes (except for system events that are not timestamp) data - variable */ @@ -59,7 +60,7 @@ class PLUGIN_API EventBase : public MetaDataEvent { public: - virtual void Serialize(void* dstBuffer, size_t dstSize) const = 0; + virtual void serialize(void* dstBuffer, size_t dstSize) const = 0; EventType getBaseType() const; static EventType getBaseType(const MidiMessage& msg); @@ -78,17 +79,21 @@ class PLUGIN_API Event : public EventBase { public: - virtual void Serialize(void* dstBuffer, size_t dstSize) const override = 0; + virtual void serialize(void* dstBuffer, size_t dstSize) const override = 0; EventChannel::EventChannelTypes getEventType() const; const EventChannel* getChannelInfo() const; + /** Gets the channel that triggered the event */ + uint16 getChannel() const; + static EventChannel::EventChannelTypes getEventType(const MidiMessage& msg); static Event* deserializeFromMessage(const MidiMessage& msg, const EventChannel* channelInfo); protected: - Event(const EventChannel* channelInfo, uint64 timestamp); + Event(const EventChannel* channelInfo, uint64 timestamp, uint16 channel); Event() = delete; + const uint16 m_channel; const EventChannel* m_channelInfo; const EventChannel::EventChannelTypes m_eventType; @@ -98,64 +103,61 @@ class PLUGIN_API TTLEvent : public Event { public: - void Serialize(void* dstBuffer, size_t dstSize) const override; + void serialize(void* dstBuffer, size_t dstSize) const override; - /** Gets the channel that triggered the event */ - unsigned int getChannel() const; /** Gets the state true ='1' false = '0'*/ bool getState() const; const void* getTTLWordPointer() const; - static TTLEvent* createTTLEvent(const EventChannel* channelInfo, uint64 timestamp, unsigned int channel,const void* eventData); - static TTLEvent* createTTLEvent(const EventChannel* channelInfo, uint64 timestamp, unsigned int channel, const void* eventData, const MetaDataValueArray& metaData); + static TTLEvent* createTTLEvent(const EventChannel* channelInfo, uint64 timestamp, const void* eventData, uint16 channel); + static TTLEvent* createTTLEvent(const EventChannel* channelInfo, uint64 timestamp, const void* eventData, const MetaDataValueArray& metaData, uint16 channel); static TTLEvent* deserializeFromMessage(const MidiMessage& msg, const EventChannel* channelInfo); private: TTLEvent() = delete; - TTLEvent(const EventChannel* channelInfo, uint64 timestamp, unsigned int channel, const void* eventData); + TTLEvent(const EventChannel* channelInfo, uint64 timestamp, uint16 channel, const void* eventData); - const unsigned int m_channel; HeapBlock<char> m_data; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(TTLEvent); }; -class PLUGIN_API MessageEvent +class PLUGIN_API TextEvent : public Event { public: - void Serialize(void* dstBuffer, size_t dstSize) const override; - String getMessage() const; + void serialize(void* dstBuffer, size_t dstSize) const override; + String getText() const; - static MessageEvent* createMessageEvent(const EventChannel* channelInfo, uint64 timestamp, const String& msg); - static MessageEvent* createMessageEvent(const EventChannel* channelInfo, uint64 timestamp, const String& msg, const MetaDataValueArray& metaData); - static MessageEvent* deserializeFromMessage(const MidiMessage& msg, const EventChannel* channelInfo); + static TextEvent* createMessageEvent(const EventChannel* channelInfo, uint64 timestamp, const String& msg, uint16 channel = 1); + static TextEvent* createMessageEvent(const EventChannel* channelInfo, uint64 timestamp, const String& msg, const MetaDataValueArray& metaData, uint16 channel = 1); + static TextEvent* deserializeFromMessage(const MidiMessage& msg, const EventChannel* channelInfo); private: - MessageEvent() = delete; - MessageEvent(const EventChannel* channelInfo, uint64 timestamp, const String& msg); + TextEvent() = delete; + TextEvent(const EventChannel* channelInfo, uint64 timestamp, uint16 channel, const String& msg); const String m_msg; - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MessageEvent); + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(TextEvent); }; class PLUGIN_API BinaryEvent : public Event { public: - void Serialize(void* dstBuffer, size_t dstSize) const override; + void serialize(void* dstBuffer, size_t dstSize) const override; const void* getBinaryDataPointer() const; template<typename T> - static BinaryEvent* createBinaryEvent(const EventChannel* channelInfo, uint64 timestamp, const T* data); + static BinaryEvent* createBinaryEvent(const EventChannel* channelInfo, uint64 timestamp, const T* data, uint16 channel = 1); template<typename T> - static BinaryEvent* createBinaryEvent(const EventChannel* channelInfo, uint64 timestamp, const T* data, const MetaDataValueArray& metaData); + static BinaryEvent* createBinaryEvent(const EventChannel* channelInfo, uint64 timestamp, const T* data, const MetaDataValueArray& metaData, uint16 channel = 1); static BinaryEvent* deserializeFromMessage(const MidiMessage& msg, const EventChannel* channelInfo); private: BinaryEvent() = delete; - BinaryEvent(const EventChannel* channelInfo, uint64 timestamp, const void* data); + BinaryEvent(const EventChannel* channelInfo, uint64 timestamp, uint16 channel, const void* data); HeapBlock<char> m_data; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(BinaryEvent); @@ -179,7 +181,7 @@ public: Array<unsigned int> positions; }; - void Serialize(void* dstBuffer, size_t dstSize) const override; + void serialize(void* dstBuffer, size_t dstSize) const override; const float* getDataPointer() const;