Merge pull request #3186 from wangyix/master

made Audio::_ringBuffer size 10 frames for non-Windows builds; improved interface downstream audio framesAvailable stat; disable QAudioOutput overflow check by default
This commit is contained in:
Brad Hefta-Gaub 2014-07-21 14:50:15 -07:00
commit fb097c77b5
5 changed files with 25 additions and 15 deletions

View file

@ -85,8 +85,11 @@ Audio::Audio(int16_t initialJitterBufferSamples, QObject* parent) :
// slower than real time (or at least the desired sample rate). If you increase the size of the ring buffer, then it // slower than real time (or at least the desired sample rate). If you increase the size of the ring buffer, then it
// this delay will slowly add up and the longer someone runs, they more delayed their audio will be. // this delay will slowly add up and the longer someone runs, they more delayed their audio will be.
_inputRingBuffer(0), _inputRingBuffer(0),
#ifdef _WIN32
_ringBuffer(NETWORK_BUFFER_LENGTH_SAMPLES_STEREO, false, 100),
#else
_ringBuffer(NETWORK_BUFFER_LENGTH_SAMPLES_STEREO), // DO NOT CHANGE THIS UNLESS YOU SOLVE THE AUDIO DEVICE DRIFT PROBLEM!!! _ringBuffer(NETWORK_BUFFER_LENGTH_SAMPLES_STEREO), // DO NOT CHANGE THIS UNLESS YOU SOLVE THE AUDIO DEVICE DRIFT PROBLEM!!!
#endif
_isStereoInput(false), _isStereoInput(false),
_averagedLatency(0.0), _averagedLatency(0.0),
_measuredJitter(0), _measuredJitter(0),
@ -127,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),
_framesAvailableStats(1, FRAMES_AVAILABLE_STATS_WINDOW_SECONDS) _ringBufferFramesAvailableStats(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
memset(_localProceduralSamples, 0, NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL); memset(_localProceduralSamples, 0, NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL);
@ -790,8 +794,8 @@ AudioStreamStats Audio::getDownstreamAudioStreamStats() const {
stats._timeGapWindowMax = _interframeTimeGapStats.getWindowMax(); stats._timeGapWindowMax = _interframeTimeGapStats.getWindowMax();
stats._timeGapWindowAverage = _interframeTimeGapStats.getWindowAverage(); stats._timeGapWindowAverage = _interframeTimeGapStats.getWindowAverage();
stats._ringBufferFramesAvailable = getFramesAvailableInRingAndAudioOutputBuffers(); stats._ringBufferFramesAvailable = _ringBuffer.framesAvailable();
stats._ringBufferFramesAvailableAverage = _framesAvailableStats.getWindowAverage(); stats._ringBufferFramesAvailableAverage = _ringBufferFramesAvailableStats.getWindowAverage();
stats._ringBufferDesiredJitterBufferFrames = getDesiredJitterBufferFrames(); stats._ringBufferDesiredJitterBufferFrames = getDesiredJitterBufferFrames();
stats._ringBufferStarveCount = _starveCount; stats._ringBufferStarveCount = _starveCount;
stats._ringBufferConsecutiveNotMixedCount = _consecutiveNotMixedCount; stats._ringBufferConsecutiveNotMixedCount = _consecutiveNotMixedCount;
@ -807,7 +811,8 @@ AudioStreamStats Audio::getDownstreamAudioStreamStats() const {
void Audio::sendDownstreamAudioStatsPacket() { void Audio::sendDownstreamAudioStatsPacket() {
// 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.
_framesAvailableStats.update(getFramesAvailableInRingAndAudioOutputBuffers()); _ringBufferFramesAvailableStats.update(_ringBuffer.framesAvailable());
_audioOutputBufferFramesAvailableStats.update(getFramesAvailableInAudioOutputBuffer());
// 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)
@ -1613,8 +1618,10 @@ int Audio::calculateNumberOfFrameSamples(int numBytes) {
return frameSamples; return frameSamples;
} }
int Audio::getFramesAvailableInRingAndAudioOutputBuffers() const { int Audio::getFramesAvailableInAudioOutputBuffer() const {
int framesInAudioOutputBuffer = (_audioOutput->bufferSize() - _audioOutput->bytesFree()) float networkOutputToOutputRatio = (_desiredOutputFormat.sampleRate() / (float)_outputFormat.sampleRate())
* (_desiredOutputFormat.channelCount() / (float)_outputFormat.channelCount());
return (_audioOutput->bufferSize() - _audioOutput->bytesFree()) * networkOutputToOutputRatio
/ (sizeof(int16_t) * _ringBuffer.getNumFrameSamples()); / (sizeof(int16_t) * _ringBuffer.getNumFrameSamples());
return _ringBuffer.framesAvailable() + framesInAudioOutputBuffer;
} }

View file

@ -79,6 +79,9 @@ public:
const SequenceNumberStats& getIncomingMixedAudioSequenceNumberStats() const { return _incomingMixedAudioSequenceNumberStats; } const SequenceNumberStats& getIncomingMixedAudioSequenceNumberStats() const { return _incomingMixedAudioSequenceNumberStats; }
int getFramesAvailableInAudioOutputBuffer() const;
int getAverageFramesAvailableInAudioOutputBuffer() const { return (int)_audioOutputBufferFramesAvailableStats.getWindowAverage(); }
public slots: public slots:
void start(); void start();
void stop(); void stop();
@ -239,8 +242,6 @@ private:
void renderGrid(const float* color, int x, int y, int width, int height, int rows, int cols); void renderGrid(const float* color, int x, int y, int width, int height, int rows, int cols);
void renderLineStrip(const float* color, int x, int y, int n, int offset, const QByteArray* byteArray); void renderLineStrip(const float* color, int x, int y, int n, int offset, const QByteArray* byteArray);
int getFramesAvailableInRingAndAudioOutputBuffers() const;
// Audio scope data // Audio scope data
static const unsigned int NETWORK_SAMPLES_PER_FRAME = NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL; static const unsigned int NETWORK_SAMPLES_PER_FRAME = NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL;
static const unsigned int DEFAULT_FRAMES_PER_SCOPE = 5; static const unsigned int DEFAULT_FRAMES_PER_SCOPE = 5;
@ -268,7 +269,8 @@ private:
SequenceNumberStats _incomingMixedAudioSequenceNumberStats; SequenceNumberStats _incomingMixedAudioSequenceNumberStats;
MovingMinMaxAvg<quint64> _interframeTimeGapStats; MovingMinMaxAvg<quint64> _interframeTimeGapStats;
MovingMinMaxAvg<int> _framesAvailableStats; MovingMinMaxAvg<int> _ringBufferFramesAvailableStats;
MovingMinMaxAvg<int> _audioOutputBufferFramesAvailableStats;
}; };

View file

@ -590,7 +590,7 @@ Menu::Menu() :
Qt::CTRL | Qt::SHIFT | Qt::Key_U, Qt::CTRL | Qt::SHIFT | Qt::Key_U,
false); false);
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::DisableQAudioOutputOverflowCheck, 0, false); addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::DisableQAudioOutputOverflowCheck, 0, true);
addActionToQMenuAndActionHash(developerMenu, MenuOption::PasteToVoxel, addActionToQMenuAndActionHash(developerMenu, MenuOption::PasteToVoxel,
Qt::CTRL | Qt::SHIFT | Qt::Key_V, Qt::CTRL | Qt::SHIFT | Qt::Key_V,

View file

@ -348,7 +348,7 @@ namespace MenuOption {
const QString DisableActivityLogger = "Disable Activity Logger"; const QString DisableActivityLogger = "Disable Activity Logger";
const QString DisableAutoAdjustLOD = "Disable Automatically Adjusting LOD"; const QString DisableAutoAdjustLOD = "Disable Automatically Adjusting LOD";
const QString DisableNackPackets = "Disable NACK Packets"; const QString DisableNackPackets = "Disable NACK Packets";
const QString DisableQAudioOutputOverflowCheck = "Disable QAudioOutput Overflow Check"; const QString DisableQAudioOutputOverflowCheck = "Disable Audio Output Overflow Check";
const QString DisplayFrustum = "Display Frustum"; const QString DisplayFrustum = "Display Frustum";
const QString DisplayHands = "Display Hands"; const QString DisplayHands = "Display Hands";
const QString DisplayHandTargets = "Display Hand Targets"; const QString DisplayHandTargets = "Display Hand Targets";

View file

@ -339,10 +339,11 @@ void Stats::display(
AudioStreamStats downstreamAudioStreamStats = audio->getDownstreamAudioStreamStats(); AudioStreamStats downstreamAudioStreamStats = audio->getDownstreamAudioStreamStats();
sprintf(downstreamAudioStatsString, " mix: %.2f%%/%.2f%%, %u/%u/%u", 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,
downstreamAudioStreamStats._ringBufferFramesAvailable); audio->getAverageFramesAvailableInAudioOutputBuffer(),
downstreamAudioStreamStats._ringBufferFramesAvailable, audio->getFramesAvailableInAudioOutputBuffer());
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);