diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index bb7ee1a704..da10f4cfe1 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -92,7 +92,7 @@ Audio::Audio(int16_t initialJitterBufferSamples, QObject* parent) : _processSpatialAudio(false), _spatialAudioStart(0), _spatialAudioFinish(0), - _spatialAudioRingBuffer(NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL) + _spatialAudioRingBuffer(NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL, true) // random access mode { // clear the array of locally injected samples memset(_localProceduralSamples, 0, NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL); diff --git a/libraries/audio/src/AudioRingBuffer.cpp b/libraries/audio/src/AudioRingBuffer.cpp index 45dafdca58..9b50ed0bcb 100644 --- a/libraries/audio/src/AudioRingBuffer.cpp +++ b/libraries/audio/src/AudioRingBuffer.cpp @@ -18,16 +18,19 @@ #include "AudioRingBuffer.h" -AudioRingBuffer::AudioRingBuffer(int numFrameSamples) : +AudioRingBuffer::AudioRingBuffer(int numFrameSamples, bool randomAccessMode) : NodeData(), _sampleCapacity(numFrameSamples * RING_BUFFER_LENGTH_FRAMES), _numFrameSamples(numFrameSamples), _isStarved(true), - _hasStarted(false) + _hasStarted(false), + _randomAccessMode(randomAccessMode) { if (numFrameSamples) { _buffer = new int16_t[_sampleCapacity]; - memset(_buffer, 0, _sampleCapacity * sizeof(int16_t)); + if (_randomAccessMode) { + memset(_buffer, 0, _sampleCapacity * sizeof(int16_t)); + } _nextOutput = _buffer; _endOfLastWrite = _buffer; } else { @@ -51,7 +54,9 @@ void AudioRingBuffer::resizeForFrameSize(qint64 numFrameSamples) { delete[] _buffer; _sampleCapacity = numFrameSamples * RING_BUFFER_LENGTH_FRAMES; _buffer = new int16_t[_sampleCapacity]; - memset(_buffer, 0, _sampleCapacity * sizeof(int16_t)); + if (_randomAccessMode) { + memset(_buffer, 0, _sampleCapacity * sizeof(int16_t)); + } _nextOutput = _buffer; _endOfLastWrite = _buffer; } @@ -68,8 +73,14 @@ qint64 AudioRingBuffer::readSamples(int16_t* destination, qint64 maxSamples) { qint64 AudioRingBuffer::readData(char *data, qint64 maxSize) { // only copy up to the number of samples we have available - //int numReadSamples = std::min((unsigned) (maxSize / sizeof(int16_t)), samplesAvailable()); - int numReadSamples = _endOfLastWrite ? (maxSize / sizeof(int16_t)) : samplesAvailable(); + int numReadSamples = std::min((unsigned) (maxSize / sizeof(int16_t)), samplesAvailable()); + + // If we're in random access mode, then we consider our number of available read samples slightly + // differently. Namely, if anything has been written, we say we have as many samples as they ask for + // otherwise we say we have nothing available + if (_randomAccessMode) { + numReadSamples = _endOfLastWrite ? (maxSize / sizeof(int16_t)) : 0; + } if (_nextOutput + numReadSamples > _buffer + _sampleCapacity) { // we're going to need to do two reads to get this data, it wraps around the edge @@ -77,15 +88,21 @@ qint64 AudioRingBuffer::readData(char *data, qint64 maxSize) { // read to the end of the buffer int numSamplesToEnd = (_buffer + _sampleCapacity) - _nextOutput; memcpy(data, _nextOutput, numSamplesToEnd * sizeof(int16_t)); - memset(_nextOutput, 0, numSamplesToEnd * sizeof(int16_t)); // clear it + if (_randomAccessMode) { + memset(_nextOutput, 0, numSamplesToEnd * sizeof(int16_t)); // clear it + } // read the rest from the beginning of the buffer memcpy(data + (numSamplesToEnd * sizeof(int16_t)), _buffer, (numReadSamples - numSamplesToEnd) * sizeof(int16_t)); - memset(_buffer, 0, (numReadSamples - numSamplesToEnd) * sizeof(int16_t)); // clear it + if (_randomAccessMode) { + memset(_buffer, 0, (numReadSamples - numSamplesToEnd) * sizeof(int16_t)); // clear it + } } else { // read the data memcpy(data, _nextOutput, numReadSamples * sizeof(int16_t)); - memset(_nextOutput, 0, numReadSamples * sizeof(int16_t)); // clear it + if (_randomAccessMode) { + memset(_nextOutput, 0, numReadSamples * sizeof(int16_t)); // clear it + } } // push the position of _nextOutput by the number of samples read @@ -111,7 +128,7 @@ qint64 AudioRingBuffer::writeData(const char* data, qint64 maxSize) { && (less(_endOfLastWrite, _nextOutput) && lessEqual(_nextOutput, shiftedPositionAccomodatingWrap(_endOfLastWrite, samplesToCopy)))) { // this read will cross the next output, so call us starved and reset the buffer - qDebug() << "Filled the ring buffer. Resetting. <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"; + qDebug() << "Filled the ring buffer. Resetting."; _endOfLastWrite = _buffer; _nextOutput = _buffer; _isStarved = true; @@ -151,13 +168,6 @@ unsigned int AudioRingBuffer::samplesAvailable() const { if (sampleDifference < 0) { sampleDifference += _sampleCapacity; } - - if (sampleDifference == 0) { - qDebug() << "ran dry!!! _endOfLastWrite=" << _endOfLastWrite - << "_nextOutput=" << _nextOutput - << "_buffer + _sampleCapacity=" << (_buffer + _sampleCapacity) - << " samplesAvailable() == 0!!!!!!!!!!!!!!!!!!!!"; - } return sampleDifference; } diff --git a/libraries/audio/src/AudioRingBuffer.h b/libraries/audio/src/AudioRingBuffer.h index 7ec686f1ac..04cc67c8ac 100644 --- a/libraries/audio/src/AudioRingBuffer.h +++ b/libraries/audio/src/AudioRingBuffer.h @@ -39,7 +39,7 @@ const int MIN_SAMPLE_VALUE = std::numeric_limits::min(); class AudioRingBuffer : public NodeData { Q_OBJECT public: - AudioRingBuffer(int numFrameSamples); + AudioRingBuffer(int numFrameSamples, bool randomAccessMode = false); ~AudioRingBuffer(); void reset(); @@ -88,6 +88,7 @@ protected: int16_t* _buffer; bool _isStarved; bool _hasStarted; + bool _randomAccessMode; /// will this ringbuffer be used for random access? if so, do some special processing }; #endif // hifi_AudioRingBuffer_h