21#include <JuceHeader.h>
23#include <CustomLookAndFeel.h>
35class EnvironmentParametersMessage;
36class AnalyzerParametersMessage;
37class ReinitIOCountMessage;
38class AudioInputBufferMessage;
39class AudioOutputBufferMessage;
40class DataTrafficTypeSelectionMessage;
41class ControlParametersMessage;
42class PluginParameterInfosMessage;
43class PluginParameterValueMessage;
44class PluginProcessingStateMessage;
116 size_t contentSize = 0;
117 juce::MemoryBlock blob;
120 blob.append(sc.getData(), contentSize);
134 jassert(blob.getSize() >= minSize);
135 if (blob.getSize() < minSize)
142 return reinterpret_cast<SerializableMessage*
>(std::make_unique<EnvironmentParametersMessage>(blob).release());
144 return reinterpret_cast<SerializableMessage*
>(std::make_unique<AnalyzerParametersMessage>(blob).release());
146 return reinterpret_cast<SerializableMessage*
>(std::make_unique<ReinitIOCountMessage>(blob).release());
148 return reinterpret_cast<SerializableMessage*
>(std::make_unique<AudioInputBufferMessage>(blob).release());
150 return reinterpret_cast<SerializableMessage*
>(std::make_unique<AudioOutputBufferMessage>(blob).release());
152 return reinterpret_cast<SerializableMessage*
>(std::make_unique<DataTrafficTypeSelectionMessage>(blob).release());
154 return reinterpret_cast<SerializableMessage*
>(std::make_unique<ControlParametersMessage>(blob).release());
156 return reinterpret_cast<SerializableMessage*
>(std::make_unique<PluginParameterInfosMessage>(blob).release());
158 return reinterpret_cast<SerializableMessage*
>(std::make_unique<PluginParameterValueMessage>(blob).release());
160 return reinterpret_cast<SerializableMessage*
>(std::make_unique<PluginProcessingStateMessage>(blob).release());
174 if (
nullptr != message)
185 auto riocm = std::unique_ptr<ReinitIOCountMessage>(
reinterpret_cast<ReinitIOCountMessage*
>(message));
243 return (((
static_cast<std::uint8_t
>(buffer[0]) << 24) & 0xff000000) +
244 ((
static_cast<std::uint8_t
>(buffer[1]) << 16) & 0x00ff0000) +
245 ((
static_cast<std::uint8_t
>(buffer[2]) << 8) & 0x0000ff00) +
246 static_cast<std::uint8_t
>(buffer[3]));
251 return (((
static_cast<std::uint8_t
>(buffer[0]) << 8) & 0xff00) +
252 static_cast<std::uint8_t
>(buffer[1]));
282 blob.copyTo(&m_paletteStyle,
sizeof(
SerializableMessageType),
sizeof(JUCEAppBasics::CustomLookAndFeel::PaletteStyle));
288 JUCEAppBasics::CustomLookAndFeel::PaletteStyle
getPaletteStyle()
const {
return m_paletteStyle; };
293 juce::MemoryBlock blob;
294 blob.append(&m_paletteStyle,
sizeof(JUCEAppBasics::CustomLookAndFeel::PaletteStyle));
295 contentSize = blob.getSize();
300 JUCEAppBasics::CustomLookAndFeel::PaletteStyle m_paletteStyle = JUCEAppBasics::CustomLookAndFeel::PS_Dark;
326 blob.copyTo(&m_maximumExpectedSamplesPerBlock,
sizeof(
SerializableMessageType) +
sizeof(std::uint16_t),
sizeof(std::uint16_t));
339 juce::MemoryBlock blob;
340 blob.append(&m_sampleRate,
sizeof(std::uint16_t));
341 blob.append(&m_maximumExpectedSamplesPerBlock,
sizeof(std::uint16_t));
342 contentSize = blob.getSize();
347 std::uint16_t m_sampleRate = 0;
348 std::uint16_t m_maximumExpectedSamplesPerBlock = 0;
387 juce::MemoryBlock blob;
388 blob.append(&m_inputCount,
sizeof(std::uint16_t));
389 blob.append(&m_outputCount,
sizeof(std::uint16_t));
390 contentSize = blob.getSize();
395 std::uint16_t m_inputCount = 0;
396 std::uint16_t m_outputCount = 0;
439 auto numChannels = std::uint16_t(
m_buffer.getNumChannels());
440 auto numSamples = std::uint16_t(
m_buffer.getNumSamples());
441 juce::MemoryBlock blob;
443 blob.append(&numChannels,
sizeof(std::uint16_t));
444 blob.append(&numSamples,
sizeof(std::uint16_t));
445 for (
int channelNumber = 0; channelNumber < numChannels; channelNumber++)
446 blob.append(
m_buffer.getReadPointer(channelNumber),
sizeof(
float) * numSamples);
447 contentSize = blob.getSize();
483 auto numChannels = std::uint16_t(0);
484 blob.copyTo(&numChannels, readPos,
sizeof(std::uint16_t));
485 readPos +=
sizeof(std::uint16_t);
486 auto numSamples = std::uint16_t(0);
487 blob.copyTo(&numSamples, readPos,
sizeof(std::uint16_t));
488 readPos +=
sizeof(std::uint16_t);
489 auto data =
reinterpret_cast<const float*
>(blob.begin() + readPos);
491 m_buffer = juce::AudioBuffer<float>(numChannels, numSamples);
493 for (
int i = 0; i < numChannels; i++)
495 m_buffer.copyFrom(i, 0, data + samplePos, numSamples);
496 samplePos += numSamples;
526 auto numChannels = std::uint16_t(0);
527 blob.copyTo(&numChannels, readPos,
sizeof(std::uint16_t));
528 readPos +=
sizeof(std::uint16_t);
529 auto numSamples = std::uint16_t(0);
530 blob.copyTo(&numSamples, readPos,
sizeof(std::uint16_t));
531 readPos +=
sizeof(std::uint16_t);
532 auto data =
reinterpret_cast<const float*
>(blob.begin() + readPos);
534 m_buffer = juce::AudioBuffer<float>(numChannels, numSamples);
536 for (
int i = 0; i < numChannels; i++)
538 m_buffer.copyFrom(i, 0, data + samplePos, numSamples);
539 samplePos += numSamples;
574 std::uint16_t typesCount;
575 blob.copyTo(&typesCount, readPos,
sizeof(std::uint16_t));
576 readPos +=
sizeof(std::uint16_t);
577 m_trafficTypes.resize(typesCount);
578 for (
int i = 0; i < typesCount; i++)
588 const std::vector<SerializableMessageType>&
getTrafficTypes()
const {
return m_trafficTypes; };
593 juce::MemoryBlock blob;
594 auto typesCount = std::uint16_t(m_trafficTypes.size());
595 blob.append(&typesCount,
sizeof(std::uint16_t));
596 for (
auto& trafficType : m_trafficTypes)
598 contentSize = blob.getSize();
603 std::vector<SerializableMessageType> m_trafficTypes;
639 ControlParametersMessage(
const std::map<std::uint16_t, bool>& inputMuteStates,
const std::map<std::uint16_t, bool>& outputMuteStates,
640 const std::map<std::uint16_t, std::map<std::uint16_t, bool>>& crosspointStates,
const std::map<std::uint16_t, std::map<std::uint16_t, float>>& crosspointValues)
644 auto crosspointStateOutCount = size_t(0);
645 if (0 != crosspointStates.size())
647 crosspointStateOutCount = crosspointStates.begin()->second.size();
648 for (
auto const& cpStatKV : crosspointStates)
650 jassert(crosspointStateOutCount == cpStatKV.second.size());
655 auto crosspointValOutCount = size_t(0);
656 if (0 != crosspointValues.size())
658 crosspointValOutCount = crosspointValues.begin()->second.size();
659 for (
auto const& cpValKV : crosspointValues)
661 jassert(crosspointValOutCount == cpValKV.second.size());
667 m_inputMuteStates = inputMuteStates;
668 m_outputMuteStates = outputMuteStates;
669 m_crosspointStates = crosspointStates;
670 m_crosspointValues = crosspointValues;
680 std::uint16_t inputMuteStatesCount;
681 blob.copyTo(&inputMuteStatesCount, readPos,
sizeof(std::uint16_t));
682 readPos +=
sizeof(inputMuteStatesCount);
683 for (
int i = 0; i < inputMuteStatesCount; i++)
685 std::pair<std::uint16_t, bool> inputMuteState;
686 blob.copyTo(&inputMuteState.first, readPos,
sizeof(inputMuteState.first));
687 readPos +=
sizeof(inputMuteState.first);
688 blob.copyTo(&inputMuteState.second, readPos,
sizeof(inputMuteState.second));
689 readPos +=
sizeof(inputMuteState.second);
691 m_inputMuteStates[inputMuteState.first] = inputMuteState.second;
694 std::uint16_t outputMuteStatesCount;
695 blob.copyTo(&outputMuteStatesCount, readPos,
sizeof(std::uint16_t));
696 readPos +=
sizeof(outputMuteStatesCount);
697 for (
int i = 0; i < outputMuteStatesCount; i++)
699 std::pair<std::uint16_t, bool> outputMuteState;
700 blob.copyTo(&outputMuteState.first, readPos,
sizeof(outputMuteState.first));
701 readPos +=
sizeof(outputMuteState.first);
702 blob.copyTo(&outputMuteState.second, readPos,
sizeof(outputMuteState.second));
703 readPos +=
sizeof(outputMuteState.second);
705 m_outputMuteStates[outputMuteState.first] = outputMuteState.second;
708 std::uint16_t crosspointStatesCount;
709 blob.copyTo(&crosspointStatesCount, readPos,
sizeof(std::uint16_t));
710 readPos +=
sizeof(crosspointStatesCount);
711 for (
int i = 0; i < crosspointStatesCount; i++)
713 std::uint16_t in, out;
715 blob.copyTo(&in, readPos,
sizeof(in));
716 readPos +=
sizeof(in);
717 blob.copyTo(&out, readPos,
sizeof(out));
718 readPos +=
sizeof(out);
719 blob.copyTo(&state, readPos,
sizeof(state));
720 readPos +=
sizeof(state);
722 m_crosspointStates[in][out] = state;
725 std::uint16_t crosspointValuesCount;
726 blob.copyTo(&crosspointValuesCount, readPos,
sizeof(std::uint16_t));
727 readPos +=
sizeof(crosspointValuesCount);
728 for (
int i = 0; i < crosspointValuesCount; i++)
730 std::uint16_t in, out;
732 blob.copyTo(&in, readPos,
sizeof(in));
733 readPos +=
sizeof(in);
734 blob.copyTo(&out, readPos,
sizeof(out));
735 readPos +=
sizeof(out);
736 blob.copyTo(&value, readPos,
sizeof(value));
737 readPos +=
sizeof(value);
739 m_crosspointValues[in][out] = value;
749 const std::map<std::uint16_t, std::map<std::uint16_t, bool>>&
getCrosspointStates()
const {
return m_crosspointStates; };
751 const std::map<std::uint16_t, std::map<std::uint16_t, float>>&
getCrosspointValues()
const {
return m_crosspointValues; };
756 juce::MemoryBlock blob;
758 auto inputMuteStatesCount = std::uint16_t(m_inputMuteStates.size());
759 blob.append(&inputMuteStatesCount,
sizeof(inputMuteStatesCount));
760 for (
auto& inputMuteStateKV : m_inputMuteStates)
762 blob.append(&inputMuteStateKV.first,
sizeof(inputMuteStateKV.first));
763 blob.append(&inputMuteStateKV.second,
sizeof(inputMuteStateKV.second));
766 auto outputMuteStatesCount = std::uint16_t(m_outputMuteStates.size());
767 blob.append(&outputMuteStatesCount,
sizeof(outputMuteStatesCount));
768 for (
auto& outputMuteStateKV : m_outputMuteStates)
770 blob.append(&outputMuteStateKV.first,
sizeof(outputMuteStateKV.first));
771 blob.append(&outputMuteStateKV.second,
sizeof(outputMuteStateKV.second));
774 auto crosspointStatesCount = std::uint16_t(0);
775 if (0 < m_crosspointStates.size())
776 crosspointStatesCount = std::uint16_t(m_crosspointStates.size() * m_crosspointStates.begin()->second.size());
777 blob.append(&crosspointStatesCount,
sizeof(crosspointStatesCount));
778 auto crosspointStatesCountRef = std::uint16_t(0);
779 for (
auto& crosspointStatesFirstDKV : m_crosspointStates)
781 for (
auto& crosspointStatesSecDKV : crosspointStatesFirstDKV.second)
783 auto& in = crosspointStatesFirstDKV.first;
784 blob.append(&in,
sizeof(in));
785 auto& out = crosspointStatesSecDKV.first;
786 blob.append(&out,
sizeof(out));
787 auto& state = crosspointStatesSecDKV.second;
788 blob.append(&state,
sizeof(state));
789 crosspointStatesCountRef++;
792 jassert(crosspointStatesCount == crosspointStatesCountRef);
794 auto crosspointValuesCount = std::uint16_t(0);
795 if (0 < m_crosspointValues.size())
796 crosspointValuesCount = std::uint16_t(m_crosspointValues.size() * m_crosspointValues.begin()->second.size());
797 blob.append(&crosspointValuesCount,
sizeof(crosspointValuesCount));
798 auto crosspointValuesCountRef = std::uint16_t(0);
799 for (
auto& crosspointValuesFirstDKV : m_crosspointValues)
801 for (
auto& crosspointValuesSecDKV : crosspointValuesFirstDKV.second)
803 auto& in = crosspointValuesFirstDKV.first;
804 blob.append(&in,
sizeof(in));
805 auto& out = crosspointValuesSecDKV.first;
806 blob.append(&out,
sizeof(out));
807 auto& value = crosspointValuesSecDKV.second;
808 blob.append(&value,
sizeof(value));
809 crosspointValuesCountRef++;
812 jassert(crosspointValuesCount == crosspointValuesCountRef);
814 contentSize = blob.getSize();
819 std::map<std::uint16_t, bool> m_inputMuteStates;
820 std::map<std::uint16_t, bool> m_outputMuteStates;
821 std::map<std::uint16_t, std::map<std::uint16_t, bool>> m_crosspointStates;
822 std::map<std::uint16_t, std::map<std::uint16_t, float>> m_crosspointValues;
848 PluginParameterInfosMessage(
const std::string& pluginName,
bool pluginEnabled,
bool pluginPost,
const std::vector<PluginParameterInfo>& parameterInfos)
851 m_parameterInfos = parameterInfos;
852 m_pluginName = pluginName;
853 m_pluginEnabled = pluginEnabled;
854 m_pluginPost = pluginPost;
866 std::uint16_t pluginNameLength;
867 blob.copyTo(&pluginNameLength, readPos,
sizeof(std::uint16_t));
868 readPos +=
sizeof(std::uint16_t);
869 m_pluginName = juce::String(juce::CharPointer_UTF8(
static_cast<const char*
>(blob.begin()) + readPos), pluginNameLength);
870 readPos += pluginNameLength;
873 blob.copyTo(&m_pluginEnabled, readPos,
sizeof(
bool));
874 readPos +=
sizeof(bool);
875 blob.copyTo(&m_pluginPost, readPos,
sizeof(
bool));
876 readPos +=
sizeof(bool);
878 std::uint16_t paramCount;
879 blob.copyTo(¶mCount, readPos,
sizeof(std::uint16_t));
880 readPos +=
sizeof(std::uint16_t);
882 m_parameterInfos.reserve(paramCount);
884 for (
int i = 0; i < paramCount; i++)
890 blob.copyTo(&index, readPos,
sizeof(std::int32_t));
892 readPos +=
sizeof(std::int32_t);
895 std::uint16_t idLength;
896 blob.copyTo(&idLength, readPos,
sizeof(std::uint16_t));
897 readPos +=
sizeof(std::uint16_t);
898 info.
id = juce::String(juce::CharPointer_UTF8(
static_cast<const char*
>(blob.begin()) + readPos), idLength);
902 std::uint16_t nameLength;
903 blob.copyTo(&nameLength, readPos,
sizeof(std::uint16_t));
904 readPos +=
sizeof(std::uint16_t);
905 info.
name = juce::String(juce::CharPointer_UTF8(
static_cast<const char*
>(blob.begin()) + readPos), nameLength);
906 readPos += nameLength;
909 blob.copyTo(&info.
defaultValue, readPos,
sizeof(
float));
910 readPos +=
sizeof(float);
911 blob.copyTo(&info.
currentValue, readPos,
sizeof(
float));
912 readPos +=
sizeof(float);
915 std::uint16_t labelLength;
916 blob.copyTo(&labelLength, readPos,
sizeof(std::uint16_t));
917 readPos +=
sizeof(std::uint16_t);
918 info.
label = juce::String(juce::CharPointer_UTF8(
static_cast<const char*
>(blob.begin()) + readPos), labelLength);
919 readPos += labelLength;
923 readPos +=
sizeof(bool);
925 readPos +=
sizeof(bool);
928 std::int32_t categoryInt;
929 blob.copyTo(&categoryInt, readPos,
sizeof(std::int32_t));
930 info.
category =
static_cast<juce::AudioProcessorParameter::Category
>(categoryInt);
931 readPos +=
sizeof(std::int32_t);
934 blob.copyTo(&info.
minValue, readPos,
sizeof(
float));
935 readPos +=
sizeof(float);
936 blob.copyTo(&info.
maxValue, readPos,
sizeof(
float));
937 readPos +=
sizeof(float);
938 blob.copyTo(&info.
stepSize, readPos,
sizeof(
float));
939 readPos +=
sizeof(float);
940 blob.copyTo(&info.
isDiscrete, readPos,
sizeof(
bool));
941 readPos +=
sizeof(bool);
944 blob.copyTo(&info.
type, readPos,
sizeof(ParameterControlType));
945 readPos +=
sizeof(ParameterControlType);
948 std::int32_t stepCount;
949 blob.copyTo(&stepCount, readPos,
sizeof(std::int32_t));
951 readPos +=
sizeof(std::int32_t);
954 for (
int s = 0; s < stepCount; s++)
956 std::uint16_t stepNameLength;
957 blob.copyTo(&stepNameLength, readPos,
sizeof(std::uint16_t));
958 readPos +=
sizeof(std::uint16_t);
959 auto stepName = juce::String(juce::CharPointer_UTF8(
960 static_cast<const char*
>(blob.begin()) + readPos), stepNameLength);
961 readPos += stepNameLength;
962 info.
stepNames.push_back(stepName.toStdString());
965 m_parameterInfos.push_back(info);
983 juce::MemoryBlock blob;
986 auto pluginNameUtf8 = m_pluginName.toUTF8();
987 std::uint16_t pluginNameLength = std::uint16_t(strlen(pluginNameUtf8));
988 blob.append(&pluginNameLength,
sizeof(std::uint16_t));
989 blob.append(pluginNameUtf8, pluginNameLength);
992 blob.append(&m_pluginEnabled,
sizeof(
bool));
993 blob.append(&m_pluginPost,
sizeof(
bool));
995 auto paramCount = std::uint16_t(m_parameterInfos.size());
996 blob.append(¶mCount,
sizeof(std::uint16_t));
998 for (
const auto& info : m_parameterInfos)
1001 std::int32_t index = info.index;
1002 blob.append(&index,
sizeof(std::int32_t));
1005 auto idUtf8 = info.id.toUTF8();
1006 std::uint16_t idLength = std::uint16_t(strlen(idUtf8));
1007 blob.append(&idLength,
sizeof(std::uint16_t));
1008 blob.append(idUtf8, idLength);
1011 auto nameUtf8 = info.name.toUTF8();
1012 std::uint16_t nameLength = std::uint16_t(strlen(nameUtf8));
1013 blob.append(&nameLength,
sizeof(std::uint16_t));
1014 blob.append(nameUtf8, nameLength);
1017 blob.append(&info.defaultValue,
sizeof(
float));
1018 blob.append(&info.currentValue,
sizeof(
float));
1021 auto labelUtf8 = info.label.toUTF8();
1022 std::uint16_t labelLength = std::uint16_t(strlen(labelUtf8));
1023 blob.append(&labelLength,
sizeof(std::uint16_t));
1024 blob.append(labelUtf8, labelLength);
1027 blob.append(&info.isAutomatable,
sizeof(
bool));
1028 blob.append(&info.isRemoteControllable,
sizeof(
bool));
1031 std::int32_t categoryInt =
static_cast<std::int32_t
>(info.category);
1032 blob.append(&categoryInt,
sizeof(std::int32_t));
1035 blob.append(&info.minValue,
sizeof(
float));
1036 blob.append(&info.maxValue,
sizeof(
float));
1037 blob.append(&info.stepSize,
sizeof(
float));
1038 blob.append(&info.isDiscrete,
sizeof(
bool));
1041 blob.append(&info.type,
sizeof(ParameterControlType));
1044 std::int32_t stepCount = info.stepCount;
1045 blob.append(&stepCount,
sizeof(std::int32_t));
1048 for (
const auto& stepName : info.stepNames)
1050 juce::String juceStepName(stepName);
1051 auto stepNameUtf8 = juceStepName.toUTF8();
1052 std::uint16_t stepNameLength = std::uint16_t(strlen(stepNameUtf8));
1053 blob.append(&stepNameLength,
sizeof(std::uint16_t));
1054 blob.append(stepNameUtf8, stepNameLength);
1058 contentSize = blob.getSize();
1063 std::vector<PluginParameterInfo> m_parameterInfos;
1064 juce::String m_pluginName;
1065 bool m_pluginEnabled =
false;
1066 bool m_pluginPost =
false;
1091 m_parameterIndex = parameterIndex;
1092 m_parameterId = parameterId;
1093 m_currentValue = value;
1105 blob.copyTo(&m_parameterIndex, readPos,
sizeof(std::uint16_t));
1106 readPos +=
sizeof(std::uint16_t);
1109 std::uint16_t idLength;
1110 blob.copyTo(&idLength, readPos,
sizeof(std::uint16_t));
1111 readPos +=
sizeof(std::uint16_t);
1112 m_parameterId = juce::String(juce::CharPointer_UTF8(
static_cast<const char*
>(blob.begin()) + readPos), idLength);
1113 readPos += idLength;
1116 blob.copyTo(&m_currentValue, readPos,
sizeof(
float));
1117 readPos +=
sizeof(float);
1132 juce::MemoryBlock blob;
1135 blob.append(&m_parameterIndex,
sizeof(std::uint16_t));
1138 auto idUtf8 = m_parameterId.toUTF8();
1139 std::uint16_t idLength = std::uint16_t(strlen(idUtf8));
1140 blob.append(&idLength,
sizeof(std::uint16_t));
1141 blob.append(idUtf8, idLength);
1144 blob.append(&m_currentValue,
sizeof(
float));
1146 contentSize = blob.getSize();
1151 std::uint16_t m_parameterIndex = 0;
1152 juce::String m_parameterId;
1153 float m_currentValue = 0.0f;
1174 m_enabled = enabled;
1186 blob.copyTo(&m_enabled, readPos,
sizeof(
bool));
1187 readPos +=
sizeof(bool);
1188 blob.copyTo(&m_post, readPos,
sizeof(
bool));
1189 readPos +=
sizeof(bool);
1202 juce::MemoryBlock blob;
1203 blob.append(&m_enabled,
sizeof(
bool));
1204 blob.append(&m_post,
sizeof(
bool));
1205 contentSize = blob.getSize();
1210 bool m_enabled =
false;
1211 bool m_post =
false;
1216#define RUN_MESSAGE_TESTS
1218#ifdef RUN_MESSAGE_TESTS
1219static void runTests()
1223 auto buffer = juce::AudioBuffer<float>();
1224 auto refSample = 11.11f;
1229 auto apm = std::make_unique<AnalyzerParametersMessage>(sr, mespb);
1230 auto apmb = apm->getSerializedMessage();
1231 auto apmcpy = AnalyzerParametersMessage(apmb);
1232 auto test5 = apmcpy.getSampleRate();
1233 auto test6 = apmcpy.getMaximumExpectedSamplesPerBlock();
1234 jassert(test5 == sr);
1235 jassert(test6 == mespb);
1238 auto rcm = std::make_unique<ReinitIOCountMessage>(inputs, outputs);
1239 auto rcmb = rcm->getSerializedMessage();
1240 auto rcmcpy = ReinitIOCountMessage(rcmb);
1241 auto test7 = rcmcpy.getInputCount();
1242 auto test8 = rcmcpy.getOutputCount();
1243 jassert(test7 == inputs);
1244 jassert(test8 == outputs);
1247 auto channelCount = 2;
1248 auto sampleCount = 6;
1249 buffer.setSize(channelCount, sampleCount,
false,
true,
false);
1250 for (
int i = 0; i < channelCount; i++)
1252 for (
int j = 0; j < sampleCount; j++)
1254 buffer.setSample(i, j, ++refSample);
1257 auto rrefSample1 = refSample;
1258 auto aibm1 = std::make_unique<AudioInputBufferMessage>(buffer);
1259 for (
int i = channelCount - 1; i >= 0; i--)
1261 for (
int j = sampleCount - 1; j >= 0; j--)
1263 auto test1 = aibm1->getAudioBuffer().getSample(i, j);
1264 jassert(
int(test1) ==
int(refSample));
1268 auto aibmb1 = aibm1->getSerializedMessage();
1269 auto aibmcpy1 = AudioInputBufferMessage(aibmb1);
1270 for (
int i = channelCount - 1; i >= 0; i--)
1272 for (
int j = sampleCount - 1; j >= 0; j--)
1274 auto test1 = aibmcpy1.getAudioBuffer().getSample(i, j);
1275 jassert(
int(test1) ==
int(rrefSample1));
1281 buffer.setSize(channelCount, sampleCount,
false,
true,
false);
1282 for (
int i = 0; i < channelCount; i++)
1284 for (
int j = 0; j < sampleCount; j++)
1286 buffer.setSample(i, j, ++refSample);
1289 auto rrefSample2 = refSample;
1290 auto aibm2 = std::make_unique<AudioOutputBufferMessage>(buffer);
1291 for (
int i = channelCount - 1; i >= 0; i--)
1293 for (
int j = sampleCount - 1; j >= 0; j--)
1295 auto test2 = aibm2->getAudioBuffer().getSample(i, j);
1296 jassert(
int(test2) ==
int(rrefSample2));
1300 auto aibmb2 = aibm2->getSerializedMessage();
1301 auto aibmcpy2 = AudioOutputBufferMessage(aibmb2);
1302 for (
int i = channelCount - 1; i >= 0; i--)
1304 for (
int j = sampleCount - 1; j >= 0; j--)
1306 auto test2 = aibmcpy2.getAudioBuffer().getSample(i, j);
1307 jassert(
int(test2) ==
int(refSample));
1313 auto paletteStyle = JUCEAppBasics::CustomLookAndFeel::PaletteStyle::PS_Light;
1314 auto epm = std::make_unique<EnvironmentParametersMessage>(paletteStyle);
1315 auto epmb = epm->getSerializedMessage();
1316 auto epmcpy = EnvironmentParametersMessage(epmb);
1317 auto test9 = epmcpy.getPaletteStyle();
1318 jassert(test9 == paletteStyle);
1322 auto dttm = std::make_unique<DataTrafficTypeSelectionMessage>(trafficTypes);
1323 auto dttmb = dttm->getSerializedMessage();
1324 auto dttmcpy = DataTrafficTypeSelectionMessage(dttmb);
1325 auto test10 = dttmcpy.getTrafficTypes();
1326 jassert(test10 == trafficTypes);
1329 auto inputMuteStates = std::map<std::uint16_t, bool>{ { std::uint16_t(1),
true}, { std::uint16_t(2),
false}, { std::uint16_t(3),
true} };
1330 auto outputMuteStates = std::map<std::uint16_t, bool>{ { std::uint16_t(4),
false}, { std::uint16_t(5),
true}, { std::uint16_t(6),
false} };
1331 auto crosspointStates = std::map<std::uint16_t, std::map<std::uint16_t, bool>>();
1332 auto crosspointValues = std::map<std::uint16_t, std::map<std::uint16_t, float>>();
1333 crosspointStates[1][1] =
false;
1334 crosspointStates[1][2] =
true;
1335 crosspointStates[2][1] =
true;
1336 crosspointStates[2][2] =
true;
1337 crosspointValues[1][1] = 0.0f;
1338 crosspointValues[1][2] = 1.0f;
1339 crosspointValues[2][1] = 0.5f;
1340 crosspointValues[2][2] = 0.7f;
1341 auto cpm = std::make_unique<ControlParametersMessage>(inputMuteStates, outputMuteStates, crosspointStates, crosspointValues);
1342 auto cpmb = cpm->getSerializedMessage();
1343 auto cpmcpy = ControlParametersMessage(cpmb);
1344 auto test11 = cpmcpy.getInputMuteStates();
1345 auto test12 = cpmcpy.getOutputMuteStates();
1346 auto test13 = cpmcpy.getCrosspointStates();
1347 auto test14 = cpmcpy.getCrosspointValues();
1348 jassert(test11 == inputMuteStates);
1349 jassert(test12 == outputMuteStates);
1350 jassert(test13 == crosspointStates);
1351 jassert(test14 == crosspointValues);
Carries audio-device parameters (sample rate, block size) from Mema to clients.
int getSampleRate() const
Returns the audio device sample rate in Hz.
int getMaximumExpectedSamplesPerBlock() const
Returns the maximum number of samples per processing block.
AnalyzerParametersMessage()=default
AnalyzerParametersMessage(int sampleRate, int maximumExpectedSamplesPerBlock)
juce::MemoryBlock createSerializedContent(size_t &contentSize) const override
Subclass hook — produces the type-specific payload bytes (everything after the type discriminator).
AnalyzerParametersMessage(const juce::MemoryBlock &blob)
~AnalyzerParametersMessage()=default
Base message carrying a serialised audio buffer and its flow-direction metadata.
juce::MemoryBlock createSerializedContent(size_t &contentSize) const
Subclass hook — produces the type-specific payload bytes (everything after the type discriminator).
FlowDirection
Identifies whether the buffer contains pre-matrix input or post-matrix output samples.
@ Invalid
Uninitialised direction.
@ Input
Pre-matrix input samples (as seen by the input analyzers).
@ Output
Post-matrix output samples (as seen by the output analyzers).
~AudioBufferMessage()=default
FlowDirection m_direction
Input or output flow direction.
const juce::AudioBuffer< float > & getAudioBuffer() const
Returns a const reference to the decoded audio buffer.
const FlowDirection getFlowDirection() const
Returns the flow direction encoded in the message.
AudioBufferMessage()=default
juce::AudioBuffer< float > m_buffer
Decoded float audio buffer.
AudioBufferMessage(juce::AudioBuffer< float > &buffer)
Carries a post-matrix output audio buffer streamed continuously from Mema to subscribed clients.
AudioOutputBufferMessage(const juce::MemoryBlock &blob)
~AudioOutputBufferMessage()=default
AudioOutputBufferMessage()=default
AudioOutputBufferMessage(juce::AudioBuffer< float > &buffer)
Full routing-matrix state snapshot exchanged bidirectionally between Mema and Mema....
const std::map< std::uint16_t, std::map< std::uint16_t, bool > > & getCrosspointStates() const
Returns the crosspoint enable matrix (input index → output index → enabled).
const std::map< std::uint16_t, bool > & getOutputMuteStates() const
Returns the per-output mute states (channel index → muted).
ControlParametersMessage(const juce::MemoryBlock &blob)
ControlParametersMessage()=default
~ControlParametersMessage()=default
const std::map< std::uint16_t, std::map< std::uint16_t, float > > & getCrosspointValues() const
Returns the crosspoint gain matrix (input index → output index → linear gain [0, 1]).
ControlParametersMessage(const std::map< std::uint16_t, bool > &inputMuteStates, const std::map< std::uint16_t, bool > &outputMuteStates, const std::map< std::uint16_t, std::map< std::uint16_t, bool > > &crosspointStates, const std::map< std::uint16_t, std::map< std::uint16_t, float > > &crosspointValues)
const std::map< std::uint16_t, bool > & getInputMuteStates() const
Returns the per-input mute states (channel index → muted).
juce::MemoryBlock createSerializedContent(size_t &contentSize) const override
Subclass hook — produces the type-specific payload bytes (everything after the type discriminator).
Sent by a client to opt in to receiving specific message types from Mema.
DataTrafficTypeSelectionMessage(const juce::MemoryBlock &blob)
juce::MemoryBlock createSerializedContent(size_t &contentSize) const override
Subclass hook — produces the type-specific payload bytes (everything after the type discriminator).
DataTrafficTypeSelectionMessage(const std::vector< SerializableMessageType > &trafficTypes)
const std::vector< SerializableMessageType > & getTrafficTypes() const
Returns the list of message types this client wants to receive.
DataTrafficTypeSelectionMessage()=default
~DataTrafficTypeSelectionMessage()=default
Carries the active look-and-feel palette style from Mema to connected clients.
~EnvironmentParametersMessage()=default
EnvironmentParametersMessage(JUCEAppBasics::CustomLookAndFeel::PaletteStyle paletteStyle)
juce::MemoryBlock createSerializedContent(size_t &contentSize) const override
Subclass hook — produces the type-specific payload bytes (everything after the type discriminator).
EnvironmentParametersMessage(const juce::MemoryBlock &blob)
EnvironmentParametersMessage()=default
JUCEAppBasics::CustomLookAndFeel::PaletteStyle getPaletteStyle() const
Returns the palette style carried by this message.
Carries the plugin name and complete parameter descriptor list from Mema to Mema.Re clients.
const std::vector< PluginParameterInfo > & getParameterInfos() const
Returns the ordered list of parameter descriptors for the loaded plugin.
PluginParameterInfosMessage()=default
PluginParameterInfosMessage(const juce::MemoryBlock &blob)
bool isPluginEnabled() const
Returns whether plugin processing is currently enabled.
PluginParameterInfosMessage(const std::string &pluginName, bool pluginEnabled, bool pluginPost, const std::vector< PluginParameterInfo > ¶meterInfos)
~PluginParameterInfosMessage()=default
const juce::String & getPluginName() const
Returns the display name of the currently loaded plugin.
bool isPluginPost() const
Returns whether the plugin is inserted post-matrix (true) or pre-matrix (false).
juce::MemoryBlock createSerializedContent(size_t &contentSize) const override
Subclass hook — produces the type-specific payload bytes (everything after the type discriminator).
Carries a single normalised plugin parameter value from Mema.Re to Mema.
float getCurrentValue() const
Returns the normalised parameter value in [0, 1].
juce::MemoryBlock createSerializedContent(size_t &contentSize) const override
Subclass hook — produces the type-specific payload bytes (everything after the type discriminator).
const juce::String & getParameterId() const
Returns the stable string identifier of the parameter (used for cross-session safety).
PluginParameterValueMessage(std::uint16_t parameterIndex, const juce::String ¶meterId, float value)
~PluginParameterValueMessage()=default
PluginParameterValueMessage()=default
std::uint16_t getParameterIndex() const
Returns the zero-based parameter index within the plugin's parameter list.
PluginParameterValueMessage(const juce::MemoryBlock &blob)
Carries the plugin enabled and pre/post insertion state between Mema and Mema.Re.
PluginProcessingStateMessage(const juce::MemoryBlock &blob)
PluginProcessingStateMessage()=default
bool isEnabled() const
Returns whether plugin processing is enabled.
PluginProcessingStateMessage(bool enabled, bool post)
~PluginProcessingStateMessage()=default
bool isPost() const
Returns whether the plugin is inserted post-matrix (true) or pre-matrix (false).
juce::MemoryBlock createSerializedContent(size_t &contentSize) const override
Subclass hook — produces the type-specific payload bytes (everything after the type discriminator).
Instructs clients to tear down and rebuild their UI for a new channel count.
ReinitIOCountMessage(const juce::MemoryBlock &blob)
ReinitIOCountMessage(int inputs, int outputs)
std::uint16_t getInputCount() const
Returns the new number of active input channels.
~ReinitIOCountMessage()=default
std::uint16_t getOutputCount() const
Returns the new number of active output channels.
juce::MemoryBlock createSerializedContent(size_t &contentSize) const override
Subclass hook — produces the type-specific payload bytes (everything after the type discriminator).
ReinitIOCountMessage()=default
Base class for all messages exchanged between Mema, Mema.Mo, and Mema.Re over TCP.
juce::MemoryBlock getSerializedMessage() const
Serialises the message to a MemoryBlock ready to send over the socket.
virtual juce::MemoryBlock createSerializedContent(size_t &contentSize) const =0
Subclass hook — produces the type-specific payload bytes (everything after the type discriminator).
const SerializableMessageType getType() const
Returns the concrete message type discriminator.
std::uint32_t ReadUint32(const char *buffer)
Reads a big-endian uint32 from buffer.
static void freeMessageData(SerializableMessage *message)
Type-correctly destroys a SerializableMessage* returned by initFromMemoryBlock().
void setId(int id)
Tags the message with a connection-id used for echo-suppression on the server.
int m_userId
Optional connection-id tag for echo-suppression (-1 = not set).
int getId() const
Returns the connection-id tag, or -1 if not set.
bool hasUserId() const
Returns true when a non-default connection-id has been assigned.
static SerializableMessage * initFromMemoryBlock(const juce::MemoryBlock &blob)
Deserialises a raw TCP frame into the correct concrete SerializableMessage subclass.
std::uint16_t ReadUint16(const char *buffer)
Reads a big-endian uint16 from buffer.
SerializableMessage()=default
@ None
Sentinel / uninitialised type.
@ PluginParameterValue
Single parameter value update sent from Mema.Re to Mema.
@ DataTrafficTypeSelection
Sent by a client to opt in/out of specific message types (bandwidth control).
@ AnalyzerParameters
Audio device sample rate and block size; lets clients initialise their local ProcessorDataAnalyzer.
@ ReinitIOCount
New input/output channel count; clients must rebuild their UI accordingly.
@ PluginProcessingState
Plugin enabled and pre/post processing state; sent bidirectionally between Mema and Mema....
@ ControlParameters
Full routing-matrix state snapshot; sent by Mema on connect and echoed by Mema.Re on change.
@ AudioInputBuffer
Raw PCM input buffer streamed from Mema to subscribed clients.
@ AudioOutputBuffer
Raw PCM output buffer streamed from Mema to subscribed clients.
@ EnvironmentParameters
Look-and-feel palette sent by Mema to clients on connect.
@ PluginParameterInfos
Plugin name and full parameter descriptor list; sent by Mema when a plugin is loaded or changed.
virtual ~SerializableMessage()=default
SerializableMessageType m_type
Type discriminator stored in the first 4 bytes of every serialised frame.
Metadata describing a single plugin parameter exposed for remote control.
std::vector< std::string > stepNames
Display names for each discrete step.
juce::String name
Human-readable parameter name.
bool isRemoteControllable
Whether this parameter is exposed for remote control.
int stepCount
Number of discrete steps (0 if continuous).
bool isAutomatable
Whether the host can automate this parameter.
int index
Zero-based parameter index within the plugin.
ParameterControlType type
Control widget type (slider, combo, toggle).
float defaultValue
Factory default value (normalised 0..1).
juce::String id
Unique string identifier of the parameter.
float stepSize
Step interval for discrete parameters (0 = continuous).
float minValue
Minimum value in the parameter's native range.
float currentValue
Current parameter value (normalised 0..1).
float maxValue
Maximum value in the parameter's native range.
bool isDiscrete
True if the parameter has a finite set of steps.
juce::AudioProcessorParameter::Category category
JUCE parameter category.
juce::String label
Unit label (e.g. "dB", "Hz").