mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-05 07:51:22 +02:00
add audio starvation detection
This commit is contained in:
parent
8fb0ed17b7
commit
1df54cffd6
2 changed files with 30 additions and 2 deletions
|
@ -124,7 +124,7 @@ Audio::Audio(QObject* parent) :
|
|||
_audioOutputMsecsUnplayedStats(1, FRAMES_AVAILABLE_STATS_WINDOW_SECONDS),
|
||||
_lastSentAudioPacket(0),
|
||||
_packetSentTimeGaps(1, APPROXIMATELY_30_SECONDS_OF_AUDIO_PACKETS),
|
||||
_audioOutputIODevice(_receivedAudioStream)
|
||||
_audioOutputIODevice(_receivedAudioStream, this)
|
||||
{
|
||||
// clear the array of locally injected samples
|
||||
memset(_localProceduralSamples, 0, NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL);
|
||||
|
@ -1823,6 +1823,16 @@ bool Audio::switchInputToAudioDevice(const QAudioDeviceInfo& inputDeviceInfo) {
|
|||
return supportedFormat;
|
||||
}
|
||||
|
||||
void Audio::outputNotify() {
|
||||
int recentUnfulfilled = _audioOutputIODevice.getRecentUnfulfilledReads();
|
||||
if (recentUnfulfilled > 0) {
|
||||
qDebug() << "WARNING --- WE HAD at least:" << recentUnfulfilled << "recently unfulfilled readData() calls";
|
||||
|
||||
// TODO: Ryan Huffman -- add code here to increase the AUDIO_OUTPUT_BUFFER_SIZE_FRAMES... this code only
|
||||
// runs in cases where the audio device requested data samples, and ran dry because we couldn't fulfill the request
|
||||
}
|
||||
}
|
||||
|
||||
bool Audio::switchOutputToAudioDevice(const QAudioDeviceInfo& outputDeviceInfo) {
|
||||
bool supportedFormat = false;
|
||||
|
||||
|
@ -1856,6 +1866,8 @@ bool Audio::switchOutputToAudioDevice(const QAudioDeviceInfo& outputDeviceInfo)
|
|||
|
||||
// setup our general output device for audio-mixer audio
|
||||
_audioOutput = new QAudioOutput(outputDeviceInfo, _outputFormat, this);
|
||||
connect(_audioOutput, &QAudioOutput::notify, this, &Audio::outputNotify);
|
||||
|
||||
_audioOutput->setBufferSize(AUDIO_OUTPUT_BUFFER_SIZE_FRAMES * _outputFrameSize * sizeof(int16_t));
|
||||
qDebug() << "Output Buffer capacity in frames: " << _audioOutput->bufferSize() / sizeof(int16_t) / (float)_outputFrameSize;
|
||||
|
||||
|
@ -1934,6 +1946,7 @@ qint64 Audio::AudioOutputIODevice::readData(char * data, qint64 maxSize) {
|
|||
int samplesRequested = maxSize / sizeof(int16_t);
|
||||
int samplesPopped;
|
||||
int bytesWritten;
|
||||
|
||||
if ((samplesPopped = _receivedAudioStream.popSamples(samplesRequested, false)) > 0) {
|
||||
AudioRingBuffer::ConstIterator lastPopOutput = _receivedAudioStream.getLastPopOutput();
|
||||
lastPopOutput.readSamples((int16_t*)data, samplesPopped);
|
||||
|
@ -1943,5 +1956,10 @@ qint64 Audio::AudioOutputIODevice::readData(char * data, qint64 maxSize) {
|
|||
bytesWritten = maxSize;
|
||||
}
|
||||
|
||||
int bytesAudioOutputUnplayed = _audio->_audioOutput->bufferSize() - _audio->_audioOutput->bytesFree();
|
||||
if (bytesAudioOutputUnplayed == 0 && bytesWritten == 0) {
|
||||
_unfulfilledReads++;
|
||||
}
|
||||
|
||||
return bytesWritten;
|
||||
}
|
||||
|
|
|
@ -72,16 +72,22 @@ public:
|
|||
|
||||
class AudioOutputIODevice : public QIODevice {
|
||||
public:
|
||||
AudioOutputIODevice(MixedProcessedAudioStream& receivedAudioStream) : _receivedAudioStream(receivedAudioStream) {};
|
||||
AudioOutputIODevice(MixedProcessedAudioStream& receivedAudioStream, Audio* audio) :
|
||||
_receivedAudioStream(receivedAudioStream), _audio(audio), _unfulfilledReads(0) {};
|
||||
|
||||
void start() { open(QIODevice::ReadOnly); }
|
||||
void stop() { close(); }
|
||||
qint64 readData(char * data, qint64 maxSize);
|
||||
qint64 writeData(const char * data, qint64 maxSize) { return 0; }
|
||||
|
||||
int getRecentUnfulfilledReads() { int unfulfilledReads = _unfulfilledReads; _unfulfilledReads = 0; return unfulfilledReads; }
|
||||
private:
|
||||
MixedProcessedAudioStream& _receivedAudioStream;
|
||||
Audio* _audio;
|
||||
int _unfulfilledReads;
|
||||
};
|
||||
|
||||
friend class AudioOutputIODevice;
|
||||
|
||||
// setup for audio I/O
|
||||
Audio(QObject* parent = 0);
|
||||
|
@ -170,11 +176,15 @@ public slots:
|
|||
const AudioStreamStats& getAudioMixerAvatarStreamAudioStats() const { return _audioMixerAvatarStreamAudioStats; }
|
||||
const QHash<QUuid, AudioStreamStats>& getAudioMixerInjectedStreamAudioStatsMap() const { return _audioMixerInjectedStreamAudioStatsMap; }
|
||||
|
||||
void outputNotify();
|
||||
|
||||
signals:
|
||||
bool muteToggled();
|
||||
void preProcessOriginalInboundAudio(unsigned int sampleTime, QByteArray& samples, const QAudioFormat& format);
|
||||
void processInboundAudio(unsigned int sampleTime, const QByteArray& samples, const QAudioFormat& format);
|
||||
void processLocalAudio(unsigned int sampleTime, const QByteArray& samples, const QAudioFormat& format);
|
||||
|
||||
|
||||
private:
|
||||
void outputFormatChanged();
|
||||
|
||||
|
|
Loading…
Reference in a new issue