12 #ifndef hifi_InboundAudioStream_h
13 #define hifi_InboundAudioStream_h
17 #include <NumericalConstants.h>
18 #include <udt/PacketHeaders.h>
19 #include <ReceivedMessage.h>
22 #include <plugins/CodecPlugin.h>
24 #include "AudioRingBuffer.h"
25 #include "MovingMinMaxAvg.h"
26 #include "SequenceNumberStats.h"
27 #include "AudioStreamStats.h"
28 #include "TimeWeightedAvg.h"
31 const int HAS_REVERB_BIT = 0;
33 using StreamSequenceNumber = quint16;
35 class InboundAudioStream :
public NodeData {
40 static const bool DEFAULT_DYNAMIC_JITTER_BUFFER_ENABLED;
41 static const int DEFAULT_STATIC_JITTER_FRAMES;
43 static const int MAX_FRAMES_OVER_DESIRED;
44 static const int WINDOW_STARVE_THRESHOLD;
45 static const int WINDOW_SECONDS_FOR_DESIRED_CALC_ON_TOO_MANY_STARVES;
46 static const int WINDOW_SECONDS_FOR_DESIRED_REDUCTION;
48 static const bool USE_STDEV_FOR_JITTER;
49 static const bool REPETITION_WITH_FADE;
51 InboundAudioStream() =
delete;
52 InboundAudioStream(
int numChannels,
int numFrames,
int numBlocks,
int numStaticJitterBlocks);
53 ~InboundAudioStream();
56 virtual void resetStats();
59 virtual int parseData(ReceivedMessage& packet)
override;
61 int popFrames(
int maxFrames,
bool allOrNothing);
62 int popSamples(
int maxSamples,
bool allOrNothing);
64 bool lastPopSucceeded()
const {
return _lastPopSucceeded; };
65 const AudioRingBuffer::ConstIterator& getLastPopOutput()
const {
return _lastPopOutput; }
67 quint64 usecsSinceLastPacket() {
return usecTimestampNow() - _lastPacketReceivedTime; }
71 void setDynamicJitterBufferEnabled(
bool enable);
72 void setStaticJitterBufferFrames(
int staticJitterBufferFrames);
74 virtual AudioStreamStats getAudioStreamStats()
const;
77 int getCalculatedJitterBufferFrames()
const {
return _calculatedJitterBufferFrames; }
79 bool dynamicJitterBufferEnabled()
const {
return _dynamicJitterBufferEnabled; }
80 int getStaticJitterBufferFrames() {
return _staticJitterBufferFrames; }
81 int getDesiredJitterBufferFrames() {
return _desiredJitterBufferFrames; }
83 int getNumFrameSamples()
const {
return _ringBuffer.getNumFrameSamples(); }
84 int getFrameCapacity()
const {
return _ringBuffer.getFrameCapacity(); }
85 int getFramesAvailable()
const {
return _ringBuffer.framesAvailable(); }
86 double getFramesAvailableAverage()
const {
return _framesAvailableStat.getAverage(); }
87 int getSamplesAvailable()
const {
return _ringBuffer.samplesAvailable(); }
89 bool isStarved()
const {
return _isStarved; }
90 bool hasStarted()
const {
return _hasStarted; }
92 int getConsecutiveNotMixedCount()
const {
return _consecutiveNotMixedCount; }
93 int getStarveCount()
const {
return _starveCount; }
94 int getSilentFramesDropped()
const {
return _silentFramesDropped; }
95 int getOverflowCount()
const {
return _ringBuffer.getOverflowCount(); }
97 int getPacketsReceived()
const {
return _incomingSequenceNumberStats.getReceived(); }
99 bool hasReverb()
const {
return _hasReverb; }
100 float getRevebTime()
const {
return _reverbTime; }
101 float getWetLevel()
const {
return _wetLevel; }
102 void setReverb(
float reverbTime,
float wetLevel);
103 void clearReverb() { _hasReverb =
false; }
105 void setupCodec(CodecPluginPointer codec,
const QString& codecName,
int numChannels);
109 void mismatchedAudioCodec(SharedNodePointer sendingNode,
const QString& currentCodec,
const QString& recievedCodec);
115 void perSecondCallbackForUpdatingStats();
118 void packetReceivedUpdateTimingStats();
120 void popSamplesNoCheck(
int samples);
121 void framesAvailableChanged();
125 InboundAudioStream(
const InboundAudioStream&);
126 InboundAudioStream& operator= (
const InboundAudioStream&);
131 virtual int parseStreamProperties(PacketType type,
const QByteArray& packetAfterSeqNum,
int& networkSamples);
135 virtual int parseAudioData(
const QByteArray& packetAfterStreamProperties);
138 virtual int lostAudioData(
int numPackets);
141 virtual int writeDroppableSilentFrames(
int silentFrames);
145 AudioRingBuffer _ringBuffer;
148 bool _lastPopSucceeded {
false };
149 AudioRingBuffer::ConstIterator _lastPopOutput;
151 bool _dynamicJitterBufferEnabled { DEFAULT_DYNAMIC_JITTER_BUFFER_ENABLED };
152 int _staticJitterBufferFrames { DEFAULT_STATIC_JITTER_FRAMES };
153 int _desiredJitterBufferFrames;
155 bool _isStarved {
true };
156 bool _hasStarted {
false };
160 int _consecutiveNotMixedCount { 0 };
161 int _starveCount { 0 };
162 int _silentFramesDropped { 0 };
163 int _oldFramesDropped { 0 };
165 SequenceNumberStats _incomingSequenceNumberStats;
167 quint64 _lastPacketReceivedTime { 0 };
168 MovingMinMaxAvg<quint64> _timeGapStatsForDesiredCalcOnTooManyStarves { 0, WINDOW_SECONDS_FOR_DESIRED_CALC_ON_TOO_MANY_STARVES };
169 int _calculatedJitterBufferFrames { 0 };
170 MovingMinMaxAvg<quint64> _timeGapStatsForDesiredReduction { 0, WINDOW_SECONDS_FOR_DESIRED_REDUCTION };
172 RingBufferHistory<quint64> _starveHistory;
174 TimeWeightedAvg<int> _framesAvailableStat;
175 MovingMinMaxAvg<float> _unplayedMs;
179 int _currentJitterBufferFrames { 0 };
181 MovingMinMaxAvg<quint64> _timeGapStatsForStatsPacket;
184 bool _hasReverb {
false };
185 float _reverbTime { 0.0f };
186 float _wetLevel { 0.0f };
188 CodecPluginPointer _codec;
189 QString _selectedCodecName;
190 QMutex _decoderMutex;
191 Decoder* _decoder {
nullptr };
192 int _mismatchedAudioCodecCount { 0 };
195 float calculateRepeatedFrameFadeFactor(
int indexOfRepeat);