Umsci
Upmix Spatial Control Interface — OCA/OCP.1 spatial audio utility
Loading...
Searching...
No Matches
UmsciControlComponent.h
Go to the documentation of this file.
1/* Copyright (c) 2026, Christian Ahrens
2 *
3 * This file is part of Umsci <https://github.com/ChristianAhrens/Umsci>
4 *
5 * This tool is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU Lesser General Public License version 3.0 as published
7 * by the Free Software Foundation.
8 *
9 * This tool is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12 * details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this tool; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19#pragma once
20
21#include <JuceHeader.h>
22
23
25#include "DeviceController.h"
26
27
30
31/*Fwd decls*/
34
91class UmsciControlComponent : public juce::Component, public UmsciAppConfiguration::XmlConfigurableElement
92{
93public:
95 ~UmsciControlComponent() override;
96
97 //==============================================================================
98 void resized() override;
99 void paint(juce::Graphics& g) override;
100 void parentHierarchyChanged() override;
101
102 //==============================================================================
103 std::unique_ptr<XmlElement> createStateXml() override;
104 bool setStateXml(XmlElement* stateXml) override;
105
106 //==============================================================================
121 const std::pair<int, int>& getOcp1IOSize();
122 void setOcp1IOSize(const std::pair<int, int>& ioSize);
123
124 //==============================================================================
126 void setDeviceName(const std::string& name);
127
133 void setSourceName(std::int16_t sourceId, const std::string& name);
134 void setSourceMute(std::int16_t sourceId, const std::uint8_t& mute);
135 void setSourceGain(std::int16_t sourceId, const std::float_t& gain);
137 void setSourcePosition(std::int16_t sourceId, const std::array<std::float_t, 3>& position);
139 void setSourceDelayMode(std::int16_t sourceId, const std::uint16_t& delayMode);
141 void setSourceSpread(std::int16_t sourceId, const std::float_t& spread);
149 void setSpeakerName(std::int16_t speakerId, const std::string& name);
150 void setSpeakerMute(std::int16_t speakerId, const std::uint8_t& mute);
151 void setSpeakerGain(std::int16_t speakerId, const std::float_t& gain);
160 void setSpeakerPosition(std::int16_t speakerId, const std::array<std::float_t, 6>& position);
163 //==============================================================================
184 void setUpmixChannelConfiguration(const juce::AudioChannelSet& upmixChannelConfig);
185 const juce::AudioChannelSet getUpmixChannelConfiguration();
186 void setUpmixSourceStartId(int startId);
187 int getUpmixSourceStartId() const;
188 void setUpmixLiveMode(bool liveMode);
189 bool getUpmixLiveMode() const;
194 //==============================================================================
205 void setUpmixTransform(float rot, float trans, float heightTrans, float angleStretch = 1.0f);
206 float getUpmixRot() const;
207 float getUpmixTrans() const;
208 float getUpmixHeightTrans() const;
209 float getUpmixAngleStretch() const;
212 //==============================================================================
218 void setUpmixOffset(float x, float y);
219 float getUpmixOffsetX() const;
220 float getUpmixOffsetY() const;
223 //==============================================================================
233
242
243 //==============================================================================
249 void setShowAllSources(bool showAll);
250 bool getShowAllSources() const;
251
252 //==============================================================================
256
257 //==============================================================================
259 void resetData();
260
261 //==============================================================================
267 std::function<void()> onDatabaseComplete;
268
273 std::function<void()> onUpmixTransformChanged;
274
275private:
276 //==============================================================================
277 void rebuildOcp1ObjectTree();
278 void updatePaintComponents();
279 void updateSourceIdFilter();
280
281 void setRemoteObject(const DeviceController::RemoteObject& obj);
282
283 bool checkIsDatabaseComplete();
284 bool isDatabaseComplete();
285 void setDatabaseComplete(bool complete);
286
287 const juce::Rectangle<float> getRealBoundingRect();
288 const std::array<float, 6> getRealBoundingCube();
289
290 //==============================================================================
291 std::unique_ptr<UmsciLoudspeakersPaintComponent> m_loudspeakersInAreaPaintComponent;
292 std::unique_ptr<UmsciSoundobjectsPaintComponent> m_soundobjectsInAreaPaintComponent;
293 std::unique_ptr<UmsciUpmixIndicatorPaintNControlComponent> m_upmixIndicatorPaintAndControlComponent;
294
295 std::pair<int, int> m_ocp1IOSize;
296
297 bool m_showAllSources = true;
298
299 bool m_databaseComplete = false;
300
301 juce::Rectangle<float> m_boundsRealRef;
302
303 std::string m_deviceName;
304
305 std::map<std::int16_t, std::string> m_sourceName;
306 std::map<std::int16_t, bool> m_sourceMute;
307 std::map<std::int16_t, std::float_t> m_sourceGain;
308 std::map<std::int16_t, std::array<std::float_t, 3>> m_sourcePosition;
309 std::map<std::int16_t, std::uint16_t> m_sourceDelayMode;
310 std::map<std::int16_t, std::float_t> m_sourceSpread;
311
312 std::map<std::int16_t, std::string> m_speakerName;
313 std::map<std::int16_t, bool> m_speakerMute;
314 std::map<std::int16_t, std::float_t> m_speakerGain;
315 std::map<std::int16_t, std::array<std::float_t, 6>> m_speakerPosition;
316
317#if JUCE_IOS
318 void* m_nativePinchViewHandle = nullptr;
319#endif
320
321 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UmsciControlComponent)
322};
323
The main visualisation and interaction surface for Umsci.
float getUpmixTrans() const
Radial scale factor.
void setUpmixChannelConfiguration(const juce::AudioChannelSet &upmixChannelConfig)
void setSpeakerGain(std::int16_t speakerId, const std::float_t &gain)
void setUpmixTransform(float rot, float trans, float heightTrans, float angleStretch=1.0f)
void setUpmixShape(UmsciUpmixIndicatorPaintNControlComponent::IndicatorShape shape)
UmsciUpmixIndicatorPaintNControlComponent::IndicatorShape getUpmixShape() const
void setSpeakerPosition(std::int16_t speakerId, const std::array< std::float_t, 6 > &position)
Sets the 6-component speaker position: {X, Y, Z, horizontal angle, vertical angle,...
void setSourceName(std::int16_t sourceId, const std::string &name)
void setSourceDelayMode(std::int16_t sourceId, const std::uint16_t &delayMode)
Delay mode: 0 = off, 1 = compensate, 2 = reflect (DS100-specific enum).
void setShowAllSources(bool showAll)
When false, only sound objects that are part of the upmix group (i.e. channels >= sourceStartId withi...
std::unique_ptr< XmlElement > createStateXml() override
void setControlsSize(UmsciPaintNControlComponentBase::ControlsSize size)
Sets the visual size of source/speaker icons (small / medium / large).
void setUpmixOffset(float x, float y)
std::function< void()> onUpmixTransformChanged
Fired on the message thread whenever the user changes any upmix transform parameter via the on-screen...
const juce::AudioChannelSet getUpmixChannelConfiguration()
const std::pair< int, int > & getOcp1IOSize()
Sets the DS100 input/output channel count for this session.
void triggerUpmixTransformApplied()
Fires live-mode position callbacks and onUpmixTransformChanged after a programmatic transform update ...
bool setStateXml(XmlElement *stateXml) override
float getUpmixHeightTrans() const
Height (Z) translation.
void setUpmixLiveMode(bool liveMode)
true = follow live DS100 positions.
void setSourceGain(std::int16_t sourceId, const std::float_t &gain)
Gain in dB.
void setOcp1IOSize(const std::pair< int, int > &ioSize)
void resetData()
Clears all cached source/speaker data and marks the database incomplete.
void setSourcePosition(std::int16_t sourceId, const std::array< std::float_t, 3 > &position)
Sets the 3-component (X, Y, Z) absolute position in normalised real-world coordinates.
void triggerUpmixFlashCheck()
Starts the flash animation on the upmix indicator if the ideal ring positions diverge from the curren...
void setSpeakerName(std::int16_t speakerId, const std::string &name)
void setSpeakerMute(std::int16_t speakerId, const std::uint8_t &mute)
void setUpmixSourceStartId(int startId)
1-based DS100 channel of the first upmix input.
void setDeviceName(const std::string &name)
Updates the device name label (shown as a title/overlay in the UI).
std::function< void()> onDatabaseComplete
Fired on the message thread when all initially subscribed values have been received from the DS100 (i...
float getUpmixAngleStretch() const
Per-angle stretch factor (1.0 = uniform).
UmsciPaintNControlComponentBase::ControlsSize getControlsSize() const
void setSourceMute(std::int16_t sourceId, const std::uint8_t &mute)
0 = unmuted, nonzero = muted.
void paint(juce::Graphics &g) override
void setSourceSpread(std::int16_t sourceId, const std::float_t &spread)
Spread factor 0.0–1.0 (0 = point source, 1 = full spread).
float getUpmixRot() const
Ring rotation in normalised units (0–1 → 0–360°).
The bottom layer of the UmsciControlComponent stack — paints a speaker SVG icon at each loudspeaker's...
ControlsSize
Visual size of source/speaker icons. Multiplier accessible via getControlsSizeMultiplier().
The middle layer of the UmsciControlComponent stack — paints a filled circle for each sound object an...
IndicatorShape
The geometric shape used to draw the upmix speaker ring.
A fully-qualified remote parameter including its type, address, and current value.