added input ring buffer stats to interface

This commit is contained in:
wangyix 2014-07-21 15:39:33 -07:00
parent 05ea5f8d21
commit 621f0725cc
4 changed files with 45 additions and 19 deletions

View file

@ -130,7 +130,8 @@ Audio::Audio(int16_t initialJitterBufferSamples, QObject* parent) :
_outgoingAvatarAudioSequenceNumber(0), _outgoingAvatarAudioSequenceNumber(0),
_incomingMixedAudioSequenceNumberStats(INCOMING_SEQ_STATS_HISTORY_LENGTH), _incomingMixedAudioSequenceNumberStats(INCOMING_SEQ_STATS_HISTORY_LENGTH),
_interframeTimeGapStats(TIME_GAPS_STATS_INTERVAL_SAMPLES, TIME_GAP_STATS_WINDOW_INTERVALS), _interframeTimeGapStats(TIME_GAPS_STATS_INTERVAL_SAMPLES, TIME_GAP_STATS_WINDOW_INTERVALS),
_ringBufferFramesAvailableStats(1, FRAMES_AVAILABLE_STATS_WINDOW_SECONDS), _inputRingBufferFramesAvailableStats(1, FRAMES_AVAILABLE_STATS_WINDOW_SECONDS),
_outputRingBufferFramesAvailableStats(1, FRAMES_AVAILABLE_STATS_WINDOW_SECONDS),
_audioOutputBufferFramesAvailableStats(1, FRAMES_AVAILABLE_STATS_WINDOW_SECONDS) _audioOutputBufferFramesAvailableStats(1, FRAMES_AVAILABLE_STATS_WINDOW_SECONDS)
{ {
// clear the array of locally injected samples // clear the array of locally injected samples
@ -795,7 +796,7 @@ AudioStreamStats Audio::getDownstreamAudioStreamStats() const {
stats._timeGapWindowAverage = _interframeTimeGapStats.getWindowAverage(); stats._timeGapWindowAverage = _interframeTimeGapStats.getWindowAverage();
stats._ringBufferFramesAvailable = _ringBuffer.framesAvailable(); stats._ringBufferFramesAvailable = _ringBuffer.framesAvailable();
stats._ringBufferFramesAvailableAverage = _ringBufferFramesAvailableStats.getWindowAverage(); stats._ringBufferFramesAvailableAverage = _outputRingBufferFramesAvailableStats.getWindowAverage();
stats._ringBufferDesiredJitterBufferFrames = getDesiredJitterBufferFrames(); stats._ringBufferDesiredJitterBufferFrames = getDesiredJitterBufferFrames();
stats._ringBufferStarveCount = _starveCount; stats._ringBufferStarveCount = _starveCount;
stats._ringBufferConsecutiveNotMixedCount = _consecutiveNotMixedCount; stats._ringBufferConsecutiveNotMixedCount = _consecutiveNotMixedCount;
@ -810,9 +811,11 @@ AudioStreamStats Audio::getDownstreamAudioStreamStats() const {
void Audio::sendDownstreamAudioStatsPacket() { void Audio::sendDownstreamAudioStatsPacket() {
_inputRingBufferFramesAvailableStats.update(getInputRingBufferFramesAvailable());
// since this function is called every second, we'll sample the number of audio frames available here. // since this function is called every second, we'll sample the number of audio frames available here.
_ringBufferFramesAvailableStats.update(_ringBuffer.framesAvailable()); _outputRingBufferFramesAvailableStats.update(_ringBuffer.framesAvailable());
_audioOutputBufferFramesAvailableStats.update(getFramesAvailableInAudioOutputBuffer()); _audioOutputBufferFramesAvailableStats.update(getOutputRingBufferFramesAvailable());
// push the current seq number stats into history, which moves the history window forward 1s // push the current seq number stats into history, which moves the history window forward 1s
// (since that's how often pushStatsToHistory() is called) // (since that's how often pushStatsToHistory() is called)
@ -1596,7 +1599,7 @@ const float Audio::CALLBACK_ACCELERATOR_RATIO = 2.0f;
const float Audio::CALLBACK_ACCELERATOR_RATIO = 2.0f; const float Audio::CALLBACK_ACCELERATOR_RATIO = 2.0f;
#endif #endif
int Audio::calculateNumberOfInputCallbackBytes(const QAudioFormat& format) { int Audio::calculateNumberOfInputCallbackBytes(const QAudioFormat& format) const {
int numInputCallbackBytes = (int)(((NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL int numInputCallbackBytes = (int)(((NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL
* format.channelCount() * format.channelCount()
* (format.sampleRate() / SAMPLE_RATE)) * (format.sampleRate() / SAMPLE_RATE))
@ -1605,7 +1608,7 @@ int Audio::calculateNumberOfInputCallbackBytes(const QAudioFormat& format) {
return numInputCallbackBytes; return numInputCallbackBytes;
} }
float Audio::calculateDeviceToNetworkInputRatio(int numBytes) { float Audio::calculateDeviceToNetworkInputRatio(int numBytes) const {
float inputToNetworkInputRatio = (int)((_numInputCallbackBytes float inputToNetworkInputRatio = (int)((_numInputCallbackBytes
* CALLBACK_ACCELERATOR_RATIO * CALLBACK_ACCELERATOR_RATIO
/ NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL) + 0.5f); / NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL) + 0.5f);
@ -1613,15 +1616,20 @@ float Audio::calculateDeviceToNetworkInputRatio(int numBytes) {
return inputToNetworkInputRatio; return inputToNetworkInputRatio;
} }
int Audio::calculateNumberOfFrameSamples(int numBytes) { int Audio::calculateNumberOfFrameSamples(int numBytes) const {
int frameSamples = (int)(numBytes * CALLBACK_ACCELERATOR_RATIO + 0.5f) / sizeof(int16_t); int frameSamples = (int)(numBytes * CALLBACK_ACCELERATOR_RATIO + 0.5f) / sizeof(int16_t);
return frameSamples; return frameSamples;
} }
int Audio::getFramesAvailableInAudioOutputBuffer() const { int Audio::getOutputRingBufferFramesAvailable() const {
float networkOutputToOutputRatio = (_desiredOutputFormat.sampleRate() / (float)_outputFormat.sampleRate()) float networkOutputToOutputRatio = (_desiredOutputFormat.sampleRate() / (float)_outputFormat.sampleRate())
* (_desiredOutputFormat.channelCount() / (float)_outputFormat.channelCount()); * (_desiredOutputFormat.channelCount() / (float)_outputFormat.channelCount());
return (_audioOutput->bufferSize() - _audioOutput->bytesFree()) * networkOutputToOutputRatio return (_audioOutput->bufferSize() - _audioOutput->bytesFree()) * networkOutputToOutputRatio
/ (sizeof(int16_t) * _ringBuffer.getNumFrameSamples()); / (sizeof(int16_t) * _ringBuffer.getNumFrameSamples());
} }
int Audio::getInputRingBufferFramesAvailable() const {
float inputToNetworkInputRatio = calculateDeviceToNetworkInputRatio(_numInputCallbackBytes);
return _inputRingBuffer.samplesAvailable() / inputToNetworkInputRatio / _inputRingBuffer.getNumFrameSamples();
}

View file

@ -79,8 +79,11 @@ public:
const SequenceNumberStats& getIncomingMixedAudioSequenceNumberStats() const { return _incomingMixedAudioSequenceNumberStats; } const SequenceNumberStats& getIncomingMixedAudioSequenceNumberStats() const { return _incomingMixedAudioSequenceNumberStats; }
int getFramesAvailableInAudioOutputBuffer() const; int getInputRingBufferFramesAvailable() const;
int getAverageFramesAvailableInAudioOutputBuffer() const { return (int)_audioOutputBufferFramesAvailableStats.getWindowAverage(); } int getInputRingBufferAverageFramesAvailable() const { return (int)_inputRingBufferFramesAvailableStats.getWindowAverage(); }
int getOutputRingBufferFramesAvailable() const;
int getOutputRingBufferAverageFramesAvailable() const { return (int)_audioOutputBufferFramesAvailableStats.getWindowAverage(); }
public slots: public slots:
void start(); void start();
@ -224,9 +227,9 @@ private:
// Callback acceleration dependent calculations // Callback acceleration dependent calculations
static const float CALLBACK_ACCELERATOR_RATIO; static const float CALLBACK_ACCELERATOR_RATIO;
int calculateNumberOfInputCallbackBytes(const QAudioFormat& format); int calculateNumberOfInputCallbackBytes(const QAudioFormat& format) const;
int calculateNumberOfFrameSamples(int numBytes); int calculateNumberOfFrameSamples(int numBytes) const;
float calculateDeviceToNetworkInputRatio(int numBytes); float calculateDeviceToNetworkInputRatio(int numBytes) const;
// Audio scope methods for allocation/deallocation // Audio scope methods for allocation/deallocation
void allocateScope(); void allocateScope();
@ -269,7 +272,10 @@ private:
SequenceNumberStats _incomingMixedAudioSequenceNumberStats; SequenceNumberStats _incomingMixedAudioSequenceNumberStats;
MovingMinMaxAvg<quint64> _interframeTimeGapStats; MovingMinMaxAvg<quint64> _interframeTimeGapStats;
MovingMinMaxAvg<int> _ringBufferFramesAvailableStats;
MovingMinMaxAvg<int> _inputRingBufferFramesAvailableStats;
MovingMinMaxAvg<int> _outputRingBufferFramesAvailableStats;
MovingMinMaxAvg<int> _audioOutputBufferFramesAvailableStats; MovingMinMaxAvg<int> _audioOutputBufferFramesAvailableStats;
}; };

View file

@ -280,7 +280,7 @@ void Stats::display(
Audio* audio = Application::getInstance()->getAudio(); Audio* audio = Application::getInstance()->getAudio();
const QHash<QUuid, AudioStreamStats>& audioMixerInjectedStreamAudioStatsMap = audio->getAudioMixerInjectedStreamAudioStatsMap(); const QHash<QUuid, AudioStreamStats>& audioMixerInjectedStreamAudioStatsMap = audio->getAudioMixerInjectedStreamAudioStatsMap();
lines = _expanded ? 11 + (audioMixerInjectedStreamAudioStatsMap.size() + 2) * 3 : 3; lines = _expanded ? 13 + (audioMixerInjectedStreamAudioStatsMap.size() + 2) * 3 : 3;
drawBackground(backgroundColor, horizontalOffset, 0, _pingStatsWidth, lines * STATS_PELS_PER_LINE + 10); drawBackground(backgroundColor, horizontalOffset, 0, _pingStatsWidth, lines * STATS_PELS_PER_LINE + 10);
horizontalOffset += 5; horizontalOffset += 5;
@ -314,6 +314,18 @@ void Stats::display(
verticalOffset += STATS_PELS_PER_LINE; verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, scale, rotation, font, voxelMaxPing, color); drawText(horizontalOffset, verticalOffset, scale, rotation, font, voxelMaxPing, color);
char inputAudioLabelString[] = "Input: (avail_avg_10s/avail)";
verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, scale, rotation, font, inputAudioLabelString, color);
char inputAudioStatsString[512];
sprintf(inputAudioStatsString, " %d/%d", audio->getInputRingBufferFramesAvailable(),
audio->getInputRingBufferAverageFramesAvailable());
verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, scale, rotation, font, inputAudioStatsString, color);
char audioMixerStatsLabelString[] = "AudioMixer stats:"; char audioMixerStatsLabelString[] = "AudioMixer stats:";
char streamStatsFormatLabelString[] = "lost%/lost_30s%"; char streamStatsFormatLabelString[] = "lost%/lost_30s%";
char streamStatsFormatLabelString2[] = "desired/avail_avg_10s/avail"; char streamStatsFormatLabelString2[] = "desired/avail_avg_10s/avail";
@ -342,8 +354,8 @@ void Stats::display(
sprintf(downstreamAudioStatsString, " mix: %.2f%%/%.2f%%, %u/%u+%d/%u+%d", downstreamAudioStreamStats._packetStreamStats.getLostRate()*100.0f, sprintf(downstreamAudioStatsString, " mix: %.2f%%/%.2f%%, %u/%u+%d/%u+%d", downstreamAudioStreamStats._packetStreamStats.getLostRate()*100.0f,
downstreamAudioStreamStats._packetStreamWindowStats.getLostRate() * 100.0f, downstreamAudioStreamStats._packetStreamWindowStats.getLostRate() * 100.0f,
downstreamAudioStreamStats._ringBufferDesiredJitterBufferFrames, downstreamAudioStreamStats._ringBufferFramesAvailableAverage, downstreamAudioStreamStats._ringBufferDesiredJitterBufferFrames, downstreamAudioStreamStats._ringBufferFramesAvailableAverage,
audio->getAverageFramesAvailableInAudioOutputBuffer(), audio->getOutputRingBufferAverageFramesAvailable(),
downstreamAudioStreamStats._ringBufferFramesAvailable, audio->getFramesAvailableInAudioOutputBuffer()); downstreamAudioStreamStats._ringBufferFramesAvailable, audio->getOutputRingBufferFramesAvailable());
verticalOffset += STATS_PELS_PER_LINE; verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, scale, rotation, font, downstreamAudioStatsString, color); drawText(horizontalOffset, verticalOffset, scale, rotation, font, downstreamAudioStatsString, color);

View file

@ -30,9 +30,9 @@ const int TIME_GAPS_FOR_STATS_PACKET_INTERVAL_SAMPLES = USECS_PER_SECOND / BUFFE
const int TIME_GAPS_FOR_STATS_PACKET_WINDOW_INTERVALS = 30; const int TIME_GAPS_FOR_STATS_PACKET_WINDOW_INTERVALS = 30;
// the stats for calculating the average frames available will recalculate every ~1 second // the stats for calculating the average frames available will recalculate every ~1 second
// and will include data for the past ~2 seconds // and will include data for the past ~10 seconds
const int FRAMES_AVAILABLE_STATS_INTERVAL_SAMPLES = USECS_PER_SECOND / BUFFER_SEND_INTERVAL_USECS; const int FRAMES_AVAILABLE_STATS_INTERVAL_SAMPLES = USECS_PER_SECOND / BUFFER_SEND_INTERVAL_USECS;
const int FRAMES_AVAILABLE_STATS_WINDOW_INTERVALS = 2; const int FRAMES_AVAILABLE_STATS_WINDOW_INTERVALS = 10;
const int AUDIOMIXER_INBOUND_RING_BUFFER_FRAME_CAPACITY = 100; const int AUDIOMIXER_INBOUND_RING_BUFFER_FRAME_CAPACITY = 100;