21#include <JuceHeader.h>
24#include <Ocp1ObjectDefinitions.h>
187 static constexpr std::int16_t
sc_INV = 0;
206 return juce::String(
sec) +
"/" + juce::String(
pri);
208 return juce::String(
pri);
210 return juce::String(
sec);
212 return juce::String();
216 return juce::String(
pri) +
"," + juce::String(
sec);
218 static juce::String
toString(
const std::vector<RemObjAddr>& RemObjAddrs)
220 auto objectListString = juce::String();
222 for (
auto const& objectAddressing : RemObjAddrs)
223 objectListString << objectAddressing.toString() <<
";";
225 return objectListString;
227 bool fromString(
const juce::String& commaseparatedStringRepresentation)
229 juce::StringArray sa;
230 auto tokens = sa.addTokens(commaseparatedStringRepresentation,
",",
"");
231 if (tokens != 2 || sa.size() != 2)
234 pri = std::int16_t(sa[0].getIntValue());
235 sec = std::int16_t(sa[1].getIntValue());
241 juce::StringArray sa;
242 sa.addTokens(commaseparatedStringRepresentation.trimCharactersAtEnd(
","),
",",
"");
246 return RemObjAddr(std::int16_t(sa[0].getIntValue()), std::int16_t(sa[1].getIntValue()));
250 auto remoteObjects = std::vector<RemObjAddr>();
252 juce::StringArray sa;
253 sa.addTokens(objectListStringRepresentation.trimCharactersAtEnd(
";"),
";",
"");
255 for (
auto const& commaseparatedStringRepresentation : sa)
258 return remoteObjects;
266 return !(*
this == rhs);
275 return (!(*
this < rhs) && (*
this != rhs));
452 return !(*
this == other);
456 return (!(*
this > other) && (*
this != other));
485 return "Device Name";
487 return "General Error";
491 return "Status Text";
493 return "Status AudioNetworkSampleStatus";
495 return "Matrix Input Mute";
497 return "Matrix Input Gain";
499 return "Matrix Input Delay";
501 return "Matrix Input DelayEnable";
503 return "Matrix Input EqEnable";
505 return "Matrix Input Polarity";
507 return "Matrix Input ChannelName";
509 return "Matrix Input LevelMeterPreMute";
511 return "Matrix Input LevelMeterPostMute";
513 return "Matrix Node Enable";
515 return "Matrix Node Gain";
517 return "Matrix Node DelayEnable";
519 return "Matrix Node Delay";
521 return "Matrix Output Mute";
523 return "Matrix Output Gain";
525 return "Matrix Output Delay";
527 return "Matrix Output DelayEnable";
529 return "Matrix Output EqEnable";
531 return "Matrix Output Polarity";
533 return "Matrix Output ChannelName";
535 return "Matrix Output LevelMeterPreMute";
537 return "Matrix Output LevelMeterPostMute";
539 return "Sound Object Spread";
541 return "Sound Object Delay Mode";
543 return "Absolute Sound Object Position XYZ";
545 return "Absolute Sound Object Position XY";
547 return "Absolute Sound Object Position X";
549 return "Absolute Sound Object Position Y";
551 return "Mapped Sound Object Position XYZ";
553 return "Mapped Sound Object Position XY";
555 return "Mapped Sound Object Position X";
557 return "Mapped Sound Object Position Y";
559 return "Matrix Settings ReverbRoomId";
561 return "Matrix Settings ReverbPredelayFactor";
563 return "Matrix Settings ReverbRearLevel";
565 return "Matrix Input ReverbSendGain";
567 return "FunctionGroup Name";
569 return "FunctionGroup Delay";
571 return "FunctionGroup SpreadFactor";
573 return "Reverb Input Gain";
575 return "Reverb Input Processing Mute";
577 return "Reverb Input Processing Gain";
579 return "Reverb Input Processing LevelMeter";
581 return "Reverb Input Processing EqEnable";
583 return "Device Clear";
585 return "Scene Previous";
589 return "Scene Recall";
591 return "Scene SceneIndex";
593 return "Scene SceneName";
595 return "Scene SceneComment";
597 return "Mapping Area P1 real";
599 return "Mapping Area P2 real";
601 return "Mapping Area P3 real";
603 return "Mapping Area P4 real";
605 return "Mapping Area P1 virt";
607 return "Mapping Area P3 virt";
609 return "Mapping Area flip";
611 return "Mapping Area name";
613 return "Speaker Position";
615 return "Soundobject Routing Mute";
617 return "Soundobject Routing Gain";
781 void setState(const
State& s, juce::NotificationType notificationType = juce::sendNotification);
795 void CreateKnownONosMap();
811 std::optional<std::unique_ptr<NanoOcp1::Ocp1CommandDefinition>> GetObjectDefinition(const
RemoteObject::RemObjIdent& roi, const
RemObjAddr& addr,
bool useDefinitionRemapping = false);
825 bool ocp1MessageReceived(const juce::MemoryBlock& data);
831 bool CreateObjectSubscriptions();
837 bool DeleteObjectSubscriptions();
843 bool QueryObjectValues();
862 void AddPendingSubscriptionHandle(const std::uint32_t handle);
863 bool PopPendingSubscriptionHandle(const std::uint32_t handle);
864 bool HasPendingSubscriptions();
866 void AddPendingGetValueHandle(const std::uint32_t handle, const std::uint32_t ONo);
867 const std::uint32_t PopPendingGetValueHandle(const std::uint32_t handle);
868 bool HasPendingGetValues();
870 void AddPendingSetValueHandle(const std::uint32_t handle, const std::uint32_t ONo, const
int externalId);
871 const std::uint32_t PopPendingSetValueHandle(const std::uint32_t handle,
int& externalId);
872 bool HasPendingSetValues();
874 const std::optional<std::pair<std::uint32_t,
int>> HasPendingSetValue(const std::uint32_t ONo);
877 void ClearPendingHandles();
885 bool UpdateObjectValue(NanoOcp1::Ocp1Notification* notifObj);
891 bool UpdateObjectValue(const std::uint32_t ONo, NanoOcp1::Ocp1Response* responseObj);
900 bool UpdateObjectValue(const
RemoteObject::RemObjIdent roi, NanoOcp1::Ocp1Message* msgObj,
901 const std::pair<
RemObjAddr, NanoOcp1::Ocp1CommandDefinition>& objectDetails);
917 void ProcessGuidAndSubscribe(const juce::String newGuid);
942 bool SetOcaRevisionAndDeviceModel(const juce::String& guid);
946 std::mutex m_pendingHandlesMutex;
948 std::vector<std::uint32_t> m_pendingSubscriptionHandles;
950 std::map<std::uint32_t, std::uint32_t> m_pendingGetValueHandlesWithONo;
952 std::map<std::uint32_t, std::pair<std::uint32_t,
int>> m_pendingSetValueHandlesWithONo;
962 std::map<
RemoteObject::RemObjIdent, std::map<
RemObjAddr, NanoOcp1::Ocp1CommandDefinition>> m_ROIsToDefsMap;
978 std::unique_ptr<NanoOcp1::NanoOcp1Client> m_ocp1Connection;
979 juce::IPAddress m_ocp1IPAddress;
984 juce::String m_ocp1DeviceGUID;
989 int m_ocp1DeviceStackIdent = -1;
Carries a decoded RemoteObject across the thread boundary via JUCE's message queue.
RemoteObjectReceivedMessage(const RemoteObject &r)
const RemoteObject & getRemoteObject() const
void setRemoteObject(const RemoteObject &r)
virtual ~RemoteObjectReceivedMessage()=default
RemoteObjectReceivedMessage()=default
Carries a State value across the thread boundary via JUCE's message queue.
StateChangeMessage()=default
virtual ~StateChangeMessage()=default
StateChangeMessage(State s)
Singleton that owns the OCP.1 (AES70) TCP connection to a d&b audiotechnik DS100 device and exposes a...
const State getState() const
Returns the current connection/subscription state.
void timerCallback() override
juce::Timer callback — retries connectToSocket() while in Connecting state.
std::function< bool(const RemoteObject &)> onRemoteObjectReceived
Called on the JUCE message thread when a notification or get-value response is decoded for a subscrib...
static constexpr std::uint16_t sc_MAX_INPUTS_CHANNELS
DbDeviceModel
Identifies which DS100 hardware variant is connected.
@ DS100M
DS100M (Milan network audio variant).
@ DS100D
DS100D (Dante network audio variant).
@ InvalidDev
Not yet determined or unsupported device.
const std::tuple< juce::IPAddress, int, int > getConnectionParameters()
Returns the current connection parameters as {ip, port, timeoutMs}.
bool connect()
Initiates the TCP connection. No-op if not in Disconnected state.
static constexpr std::uint16_t sc_MAX_FUNCTION_GROUPS
void handleMessage(const juce::Message &message) override
juce::MessageListener callback — dispatches messages posted from the socket thread.
bool SetObjectValue(const RemoteObject &remObj)
Sends a SetValue command to the device for the given remote object.
virtual ~DeviceController()
static constexpr std::uint16_t sc_MAX_OUTPUT_CHANNELS
bool SetActiveRemoteObjects(const std::vector< RemoteObject > &remObjs)
Sets the list of remote objects to subscribe to on the next connection.
MappingAreaId
Identifies a DS100 coordinate-mapping area (1–4).
@ InvalidMapId
Sentinel for "no mapping area".
State
Represents the logical phase of the OCP.1 connection.
@ Connected
All subscriptions confirmed and all initial values received.
@ Connecting
TCP connect in progress; timer retries until success.
@ GetValues
GetValue responses being collected.
@ Subscribing
AddSubscription commands sent, awaiting acknowledgements.
@ Disconnected
No TCP connection exists; no resources are allocated.
@ Subscribed
All subscriptions confirmed; GetValue queries still pending.
void setConnectionParameters(juce::IPAddress ip, int port, int timeoutMs=150)
Updates connection parameters and reconnects if currently connected.
const std::vector< RemoteObject > & GetActiveRemoteObjects()
Returns the active subscription list last set by SetActiveRemoteObjects().
static constexpr std::uint16_t sc_MAX_REVERB_ZONES
std::function< void(const State state)> onStateChanged
Called on the JUCE message thread whenever the connection state changes.
void disconnect()
Closes the TCP connection and resets state to Disconnected. Safe to call from any state,...
Two-dimensional address of a remote object on the DS100.
static std::vector< RemObjAddr > createFromListString(const juce::String &objectListStringRepresentation)
bool operator!=(const RemObjAddr &rhs) const
static juce::String toString(const std::vector< RemObjAddr > &RemObjAddrs)
std::int16_t pri
Primary index (channel, speaker, group, zone…). 0 = not used.
juce::String toNiceString() const
static constexpr std::int16_t sc_INV
bool operator>(const RemObjAddr &rhs) const
std::int16_t sec
Secondary index (mapping area, output ch, group…). 0 = not used.
bool operator==(const RemObjAddr &rhs) const
static RemObjAddr createFromString(const juce::String &commaseparatedStringRepresentation)
bool fromString(const juce::String &commaseparatedStringRepresentation)
RemObjAddr(const RemObjAddr &rhs)
RemObjAddr(std::int16_t a, std::int16_t b)
bool operator<(const RemObjAddr &rhs) const
juce::String toString() const
RemObjAddr & operator=(const RemObjAddr &rhs)
A fully-qualified remote parameter including its type, address, and current value.
bool operator!=(const RemoteObject &other) const
RemoteObject(RemObjIdent id, RemObjAddr addr, NanoOcp1::Variant v)
RemoteObject(const RemoteObject &rhs)
bool operator<(const RemoteObject &other) const
static juce::String GetObjectDescription(const RemObjIdent roi)
RemObjIdent
Enumerates every controllable or monitorable parameter on the DS100.
@ CoordinateMappingSettings_P1virtual
@ Positioning_SpeakerPosition
@ CoordinateMapping_SourcePosition_Y
@ CoordinateMapping_SourcePosition
@ Status_AudioNetworkSampleStatus
@ MatrixOutput_LevelMeterPostMute
@ Positioning_SourcePosition_XY
@ CoordinateMappingSettings_P3real
@ CoordinateMappingSettings_P4real
@ Positioning_SourcePosition_Y
@ MatrixInput_ReverbSendGain
@ CoordinateMappingSettings_Name
@ CoordinateMappingSettings_Flip
@ CoordinateMappingSettings_P1real
@ MatrixInput_LevelMeterPostMute
@ CoordinateMapping_SourcePosition_X
@ CoordinateMapping_SourcePosition_XY
@ MatrixSettings_ReverbPredelayFactor
@ Positioning_SourceSpread
@ CoordinateMappingSettings_P3virtual
@ ReverbInputProcessing_Mute
@ Positioning_SourcePosition
@ CoordinateMappingSettings_P2real
@ MatrixOutput_LevelMeterPreMute
@ ReverbInputProcessing_EqEnable
@ Positioning_SourceDelayMode
@ MatrixOutput_DelayEnable
@ SoundObjectRouting_Gain
@ MatrixOutput_ChannelName
@ ReverbInputProcessing_LevelMeter
@ MatrixInput_DelayEnable
@ MatrixInput_LevelMeterPreMute
@ ReverbInputProcessing_Gain
@ Fixed_GUID
Read-only 8-char device GUID; queried before any subscriptions.
@ MatrixSettings_ReverbRearLevel
@ SoundObjectRouting_Mute
@ Positioning_SourcePosition_X
@ MatrixInput_ChannelName
@ MatrixSettings_ReverbRoomId
@ FunctionGroup_SpreadFactor
bool operator==(const RemoteObject &other) const
bool operator>(const RemoteObject &other) const
RemoteObject & operator=(const RemoteObject &other)