12 #ifndef hifi_AudioMixerClientData_h
13 #define hifi_AudioMixerClientData_h
17 #if !defined(Q_MOC_RUN)
19 #include <tbb/concurrent_vector.h>
22 #include <QtCore/QJsonObject>
23 #include <QtCore/QSharedPointer>
26 #include <AudioHRTF.h>
27 #include <AudioLimiter.h>
28 #include <UUIDHasher.h>
30 #include <plugins/Forward.h>
31 #include <plugins/CodecPlugin.h>
33 #include "PositionalAudioStream.h"
34 #include "AvatarAudioStream.h"
36 class AudioMixerClientData :
public NodeData {
40 NodeIDStreamID nodeIDStreamID;
41 PositionalAudioStream* positionalStream;
43 AddedStream(QUuid nodeID, Node::LocalID localNodeID,
44 StreamID streamID, PositionalAudioStream* positionalStream) :
45 nodeIDStreamID(nodeID, localNodeID, streamID), positionalStream(positionalStream) {};
48 using ConcurrentAddedStreams = tbb::concurrent_vector<AddedStream>;
50 AudioMixerClientData(
const QUuid& nodeID, Node::LocalID nodeLocalID);
51 ~AudioMixerClientData();
53 using SharedStreamPointer = std::shared_ptr<PositionalAudioStream>;
54 using AudioStreamVector = std::vector<SharedStreamPointer>;
56 void queuePacket(QSharedPointer<ReceivedMessage> packet, SharedNodePointer node);
57 int processPackets(ConcurrentAddedStreams& addedStreams);
59 AudioStreamVector& getAudioStreams() {
return _audioStreams; }
60 AvatarAudioStream* getAvatarAudioStream();
62 void removeAgentAvatarAudioStream();
65 int parseData(ReceivedMessage& message)
override;
66 void processStreamPacket(ReceivedMessage& message, ConcurrentAddedStreams& addedStreams);
67 void negotiateAudioFormat(ReceivedMessage& message,
const SharedNodePointer& node);
68 void parseRequestsDomainListData(ReceivedMessage& message);
69 void parsePerAvatarGainSet(ReceivedMessage& message,
const SharedNodePointer& node);
70 void parseInjectorGainSet(ReceivedMessage& message,
const SharedNodePointer& node);
71 void parseNodeIgnoreRequest(QSharedPointer<ReceivedMessage> message,
const SharedNodePointer& node);
72 void parseRadiusIgnoreRequest(QSharedPointer<ReceivedMessage> message,
const SharedNodePointer& node);
73 void parseSoloRequest(QSharedPointer<ReceivedMessage> message,
const SharedNodePointer& node);
74 void parseStopInjectorPacket(QSharedPointer<ReceivedMessage> packet);
77 int checkBuffersBeforeFrameSend();
79 QJsonObject getAudioStreamStats();
81 void sendAudioStreamStatsPackets(
const SharedNodePointer& destinationNode);
83 void incrementOutgoingMixedAudioSequenceNumber() { _outgoingMixedAudioSequenceNumber++; }
84 quint16 getOutgoingSequenceNumber()
const {
return _outgoingMixedAudioSequenceNumber; }
87 bool shouldSendStats(
int frameNumber);
89 float getMasterAvatarGain()
const {
return _masterAvatarGain; }
90 void setMasterAvatarGain(
float gain) { _masterAvatarGain = gain; }
91 float getMasterInjectorGain()
const {
return _masterInjectorGain; }
92 void setMasterInjectorGain(
float gain) { _masterInjectorGain = gain; }
94 AudioLimiter audioLimiter;
96 void setupCodec(CodecPluginPointer codec,
const QString& codecName);
98 void encode(
const QByteArray& decodedBuffer, QByteArray& encodedBuffer) {
100 _encoder->encode(decodedBuffer, encodedBuffer);
102 encodedBuffer = decodedBuffer;
105 _shouldFlushEncoder =
true;
107 void encodeFrameOfZeros(QByteArray& encodedZeros);
108 bool shouldFlushEncoder() {
return _shouldFlushEncoder; }
110 QString getCodecName() {
return _selectedCodecName; }
112 bool shouldMuteClient() {
return _shouldMuteClient; }
113 void setShouldMuteClient(
bool shouldMuteClient) { _shouldMuteClient = shouldMuteClient; }
114 glm::vec3 getPosition() {
return getAvatarAudioStream() ? getAvatarAudioStream()->getPosition() : glm::vec3(0); }
115 bool getRequestsDomainListData()
const {
return _requestsDomainListData; }
116 void setRequestsDomainListData(
bool requesting) { _requestsDomainListData = requesting; }
118 void setupCodecForReplicatedAgent(QSharedPointer<ReceivedMessage> message);
120 struct MixableStream {
121 float approximateVolume { 0.0f };
122 NodeIDStreamID nodeStreamID;
123 std::unique_ptr<AudioHRTF> hrtf;
124 PositionalAudioStream* positionalStream;
125 bool ignoredByListener {
false };
126 bool ignoringListener {
false };
128 MixableStream(NodeIDStreamID nodeIDStreamID, PositionalAudioStream* positionalStream) :
129 nodeStreamID(nodeIDStreamID), hrtf(new AudioHRTF), positionalStream(positionalStream) {};
130 MixableStream(QUuid nodeID, Node::LocalID localNodeID, StreamID streamID, PositionalAudioStream* positionalStream) :
131 nodeStreamID(nodeID, localNodeID, streamID), hrtf(new AudioHRTF), positionalStream(positionalStream) {};
134 using MixableStreamsVector = std::vector<MixableStream>;
136 MixableStreamsVector active;
137 MixableStreamsVector inactive;
138 MixableStreamsVector skipped;
141 Streams& getStreams() {
return _streams; }
144 void ignoredByNode(QUuid nodeID);
145 void unignoredByNode(QUuid nodeID);
149 const Node::IgnoredNodeIDs& getNewIgnoredNodeIDs()
const {
return _newIgnoredNodeIDs; }
150 const Node::IgnoredNodeIDs& getNewUnignoredNodeIDs()
const {
return _newUnignoredNodeIDs; }
152 using ConcurrentIgnoreNodeIDs = tbb::concurrent_vector<QUuid>;
153 const ConcurrentIgnoreNodeIDs& getNewIgnoringNodeIDs()
const {
return _newIgnoringNodeIDs; }
154 const ConcurrentIgnoreNodeIDs& getNewUnignoringNodeIDs()
const {
return _newUnignoringNodeIDs; }
156 void clearStagedIgnoreChanges();
158 const Node::IgnoredNodeIDs& getIgnoringNodeIDs()
const {
return _ignoringNodeIDs; }
161 const std::vector<QUuid>& getSoloedNodes()
const {
return _soloedNodes; }
163 bool getHasReceivedFirstMix()
const {
return _hasReceivedFirstMix; }
164 void setHasReceivedFirstMix(
bool hasReceivedFirstMix) { _hasReceivedFirstMix = hasReceivedFirstMix; }
169 void injectorStreamFinished(
const QUuid& streamID);
172 void handleMismatchAudioFormat(SharedNodePointer node,
const QString& currentCodec,
const QString& recievedCodec);
173 void sendSelectAudioFormat(SharedNodePointer node,
const QString& selectedCodecName);
176 struct PacketQueue :
public std::queue<QSharedPointer<ReceivedMessage>> {
177 QWeakPointer<Node> node;
179 PacketQueue _packetQueue;
181 AudioStreamVector _audioStreams;
183 void optionallyReplicatePacket(ReceivedMessage& packet,
const Node& node);
185 void setGainForAvatar(QUuid nodeID,
float gain);
187 bool containsValidPosition(ReceivedMessage& message)
const;
191 quint16 _outgoingMixedAudioSequenceNumber;
193 AudioStreamStats _downstreamAudioStreamStats;
195 int _frameToSendStats { 0 };
197 float _masterAvatarGain { 1.0f };
198 float _masterInjectorGain { 1.0f };
200 CodecPluginPointer _codec;
201 QString _selectedCodecName;
202 Encoder* _encoder{
nullptr };
203 Decoder* _decoder{
nullptr };
205 bool _shouldFlushEncoder {
false };
207 bool _shouldMuteClient {
false };
208 bool _requestsDomainListData {
false };
210 std::vector<AddedStream> _newAddedStreams;
212 Node::IgnoredNodeIDs _newIgnoredNodeIDs;
213 Node::IgnoredNodeIDs _newUnignoredNodeIDs;
215 tbb::concurrent_vector<QUuid> _newIgnoringNodeIDs;
216 tbb::concurrent_vector<QUuid> _newUnignoringNodeIDs;
218 std::mutex _ignoringNodeIDsMutex;
219 Node::IgnoredNodeIDs _ignoringNodeIDs;
221 std::atomic_bool _isIgnoreRadiusEnabled {
false };
223 std::vector<QUuid> _soloedNodes;
225 bool _hasReceivedFirstMix {
false };