12 #ifndef hifi_AudioIOStats_h
13 #define hifi_AudioIOStats_h
15 #include "MovingMinMaxAvg.h"
18 #include <QtCore/QSharedPointer>
20 #include <AudioStreamStats.h>
24 class MixedProcessedAudioStream;
26 #define AUDIO_PROPERTY(TYPE, NAME) \
27 Q_PROPERTY(TYPE NAME READ NAME NOTIFY NAME##Changed) \
29 TYPE NAME() const { return _##NAME; } \
30 void NAME(TYPE value) { \
31 if (_##NAME != value) { \
33 emit NAME##Changed(value); \
36 Q_SIGNAL void NAME##Changed(TYPE value); \
38 TYPE _##NAME{ (TYPE)0 };
40 class AudioStreamStatsInterface :
public QObject {
99 AUDIO_PROPERTY(
float, lossRate)
107 AUDIO_PROPERTY(
float, lossCount)
117 AUDIO_PROPERTY(
float, lossRateWindow)
125 AUDIO_PROPERTY(
float, lossCountWindow)
133 AUDIO_PROPERTY(
int, framesDesired)
141 AUDIO_PROPERTY(
int, framesAvailable)
149 AUDIO_PROPERTY(
int, framesAvailableAvg)
157 AUDIO_PROPERTY(
float, unplayedMsMax)
165 AUDIO_PROPERTY(
int, starveCount)
175 AUDIO_PROPERTY(
int, lastStarveDurationCount)
183 AUDIO_PROPERTY(
int, dropCount)
191 AUDIO_PROPERTY(
int, overflowCount)
199 AUDIO_PROPERTY(quint64, timegapMsMax)
207 AUDIO_PROPERTY(quint64, timegapMsAvg)
215 AUDIO_PROPERTY(quint64, timegapMsMaxWindow)
223 AUDIO_PROPERTY(quint64, timegapMsAvgWindow)
226 void updateStream(
const AudioStreamStats& stats);
229 friend class AudioStatsInterface;
230 AudioStreamStatsInterface(QObject* parent);
233 class AudioStatsInterface :
public QObject {
278 AUDIO_PROPERTY(
float, pingMs);
287 AUDIO_PROPERTY(
float, inputReadMsMax);
296 AUDIO_PROPERTY(
float, inputUnplayedMsMax);
305 AUDIO_PROPERTY(
float, outputUnplayedMsMax);
314 AUDIO_PROPERTY(quint64, sentTimegapMsMax);
322 AUDIO_PROPERTY(quint64, sentTimegapMsAvg);
330 AUDIO_PROPERTY(quint64, sentTimegapMsMaxWindow);
339 AUDIO_PROPERTY(quint64, sentTimegapMsAvgWindow);
341 Q_PROPERTY(AudioStreamStatsInterface* mixerStream READ getMixerStream NOTIFY mixerStreamChanged);
342 Q_PROPERTY(AudioStreamStatsInterface* clientStream READ getClientStream NOTIFY clientStreamChanged);
345 Q_PROPERTY(QObject* injectorStreams READ getInjectorStreams NOTIFY injectorStreamsChanged);
348 AudioStreamStatsInterface* getMixerStream()
const {
return _mixer; }
349 AudioStreamStatsInterface* getClientStream()
const {
return _client; }
350 QObject* getInjectorStreams()
const {
return _injectors; }
352 void updateLocalBuffers(
const MovingMinMaxAvg<float>& inputMsRead,
353 const MovingMinMaxAvg<float>& inputMsUnplayed,
354 const MovingMinMaxAvg<float>& outputMsUnplayed,
355 const MovingMinMaxAvg<quint64>& timegaps);
356 void updateMixerStream(
const AudioStreamStats& stats) { _mixer->updateStream(stats); emit mixerStreamChanged(); }
357 void updateClientStream(
const AudioStreamStats& stats) { _client->updateStream(stats); emit clientStreamChanged(); }
358 void updateInjectorStreams(
const QHash<QUuid, AudioStreamStats>& stats);
367 void mixerStreamChanged();
374 void clientStreamChanged();
382 void injectorStreamsChanged();
385 friend class AudioIOStats;
386 AudioStatsInterface(QObject* parent);
387 AudioStreamStatsInterface* _client;
388 AudioStreamStatsInterface* _mixer;
392 class AudioIOStats :
public QObject {
395 AudioIOStats(MixedProcessedAudioStream* receivedAudioStream);
399 AudioStatsInterface* data()
const {
return _interface; }
401 void updateInputMsRead(
float ms)
const { _inputMsRead.update(ms); }
402 void updateInputMsUnplayed(
float ms)
const { _inputMsUnplayed.update(ms); }
403 void updateOutputMsUnplayed(
float ms)
const { _outputMsUnplayed.update(ms); }
404 void sentPacket()
const;
409 void processStreamStatsPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
412 AudioStatsInterface* _interface;
414 mutable MovingMinMaxAvg<float> _inputMsRead;
415 mutable MovingMinMaxAvg<float> _inputMsUnplayed;
416 mutable MovingMinMaxAvg<float> _outputMsUnplayed;
418 mutable quint64 _lastSentPacketTime;
419 mutable MovingMinMaxAvg<quint64> _packetTimegaps;
421 MixedProcessedAudioStream* _receivedAudioStream;
422 QHash<QUuid, AudioStreamStats> _injectorStreams;