mirror of
https://github.com/overte-org/overte.git
synced 2025-04-19 13:43:49 +02:00
mv localInjectorsBuffer to float-based localInjectorsStream
The localInjectorsBuffer is based on AudioRingBuffer, which only accounts for int16_t. Local injectors are mixed, and so they can exceed std::numeric_limits<int16_t> before limiting. This will allow them to remain as float until limiting (in the device callback) - once the new stream is implemented.
This commit is contained in:
parent
c5415f9624
commit
4f7f3c2a60
2 changed files with 35 additions and 32 deletions
|
@ -132,7 +132,7 @@ AudioClient::AudioClient() :
|
|||
_loopbackAudioOutput(NULL),
|
||||
_loopbackOutputDevice(NULL),
|
||||
_inputRingBuffer(0),
|
||||
_localInjectorsBuffer(0),
|
||||
_localInjectorsStream(0),
|
||||
_receivedAudioStream(RECEIVED_AUDIO_STREAM_CAPACITY_FRAMES),
|
||||
_isStereoInput(false),
|
||||
_outputStarveDetectionStartTimeMsec(0),
|
||||
|
@ -154,7 +154,7 @@ AudioClient::AudioClient() :
|
|||
_localAudioThread(this),
|
||||
_audioLimiter(AudioConstants::SAMPLE_RATE, OUTPUT_CHANNEL_COUNT),
|
||||
_outgoingAvatarAudioSequenceNumber(0),
|
||||
_audioOutputIODevice(_localInjectorsBuffer, _receivedAudioStream, this),
|
||||
_audioOutputIODevice(_localInjectorsStream, _receivedAudioStream, this),
|
||||
_stats(&_receivedAudioStream),
|
||||
_inputGate(),
|
||||
_positionGetter(DEFAULT_POSITION_GETTER),
|
||||
|
@ -1072,7 +1072,7 @@ void AudioClient::prepareLocalAudioInjectors() {
|
|||
return;
|
||||
}
|
||||
|
||||
int bufferCapacity = _localInjectorsBuffer.getSampleCapacity();
|
||||
int bufferCapacity = _localInjectorsStream.getSampleCapacity();
|
||||
if (_localToOutputResampler) {
|
||||
// avoid overwriting the buffer
|
||||
bufferCapacity -=
|
||||
|
@ -1086,7 +1086,7 @@ void AudioClient::prepareLocalAudioInjectors() {
|
|||
// lock for every write to avoid locking out the device callback
|
||||
Lock lock(_localAudioMutex);
|
||||
|
||||
samplesNeeded = bufferCapacity - _localInjectorsBuffer.samplesAvailable();
|
||||
samplesNeeded = bufferCapacity - _localInjectorsStream.samplesAvailable();
|
||||
if (samplesNeeded <= 0) {
|
||||
break;
|
||||
}
|
||||
|
@ -1101,22 +1101,20 @@ void AudioClient::prepareLocalAudioInjectors() {
|
|||
_localReverb.render(_localMixBuffer, _localMixBuffer, AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL);
|
||||
}
|
||||
|
||||
convertToScratch(_localScratchBuffer, _localMixBuffer, AudioConstants::NETWORK_FRAME_SAMPLES_STEREO);
|
||||
|
||||
int samples;
|
||||
if (_localToOutputResampler) {
|
||||
// resample to output sample rate
|
||||
int frames = _localToOutputResampler->render(_localScratchBuffer, _localOutputScratchBuffer,
|
||||
int frames = _localToOutputResampler->render(_localMixBuffer, _localOutputMixBuffer,
|
||||
AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL);
|
||||
|
||||
// write to local injectors' ring buffer
|
||||
samples = frames * AudioConstants::STEREO;
|
||||
_localInjectorsBuffer.writeSamples(_localOutputScratchBuffer, samples);
|
||||
_localInjectorsStream.writeSamples(_localOutputMixBuffer, samples);
|
||||
|
||||
} else {
|
||||
// write to local injectors' ring buffer
|
||||
samples = AudioConstants::NETWORK_FRAME_SAMPLES_STEREO;
|
||||
_localInjectorsBuffer.writeSamples(_localScratchBuffer,
|
||||
_localInjectorsStream.writeSamples(_localMixBuffer,
|
||||
AudioConstants::NETWORK_FRAME_SAMPLES_STEREO);
|
||||
}
|
||||
|
||||
|
@ -1440,8 +1438,8 @@ bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo& outputDevice
|
|||
delete[] _outputScratchBuffer;
|
||||
_outputScratchBuffer = NULL;
|
||||
|
||||
delete[] _localOutputScratchBuffer;
|
||||
_localOutputScratchBuffer = NULL;
|
||||
delete[] _localOutputMixBuffer;
|
||||
_localOutputMixBuffer = NULL;
|
||||
}
|
||||
|
||||
if (_networkToOutputResampler) {
|
||||
|
@ -1501,8 +1499,8 @@ bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo& outputDevice
|
|||
_outputPeriod = periodSampleSize * 2;
|
||||
_outputMixBuffer = new float[_outputPeriod];
|
||||
_outputScratchBuffer = new int16_t[_outputPeriod];
|
||||
_localOutputScratchBuffer = new int16_t[_outputPeriod];
|
||||
_localInjectorsBuffer.resizeForFrameSize(_outputPeriod * 2);
|
||||
_localOutputMixBuffer = new float[_outputPeriod];
|
||||
_localInjectorsStream.resizeForFrameSize(_outputPeriod * 2);
|
||||
|
||||
qCDebug(audioclient) << "Output Buffer capacity in frames: " << _audioOutput->bufferSize() / AudioConstants::SAMPLE_SIZE / (float)deviceFrameSize <<
|
||||
"requested bytes:" << requestedSize << "actual bytes:" << _audioOutput->bufferSize() <<
|
||||
|
@ -1630,22 +1628,16 @@ qint64 AudioClient::AudioOutputIODevice::readData(char * data, qint64 maxSize) {
|
|||
samplesRequested = networkSamplesPopped;
|
||||
}
|
||||
|
||||
int injectorSamplesPopped;
|
||||
int injectorSamplesPopped = 0;
|
||||
{
|
||||
Lock lock(_audio->_localAudioMutex);
|
||||
if ((injectorSamplesPopped = _localInjectorsBuffer.readSamples(scratchBuffer, samplesRequested)) > 0) {
|
||||
qCDebug(audiostream, "Read %d samples from injectors (%d available, %d requested)", injectorSamplesPopped, _localInjectorsBuffer.samplesAvailable(), samplesRequested);
|
||||
|
||||
if (_audio->_shouldEchoToServer) {
|
||||
// omit local audio, it should be echoed
|
||||
injectorSamplesPopped = 0;
|
||||
} else if (networkSamplesPopped == 0) {
|
||||
convertToMix(mixBuffer, scratchBuffer, injectorSamplesPopped);
|
||||
} else {
|
||||
// add to mix buffer (float)
|
||||
for (int i = 0; i < injectorSamplesPopped; i++) {
|
||||
mixBuffer[i] += (float)scratchBuffer[i] * (1 / 32768.0f);
|
||||
}
|
||||
if (_audio->_shouldEchoToServer) {
|
||||
// omit local audio, it should be echoed
|
||||
_localInjectorsStream.skipSamples(samplesRequested);
|
||||
} else {
|
||||
bool append = networkSamplesPopped > 0;
|
||||
if ((injectorSamplesPopped = _localInjectorsStream.readSamples(mixBuffer, samplesRequested, append)) > 0) {
|
||||
qCDebug(audiostream, "Read %d samples from injectors (%d available, %d requested)", injectorSamplesPopped, _localInjectorsStream.samplesAvailable(), samplesRequested);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,6 +69,17 @@ class QIODevice;
|
|||
class Transform;
|
||||
class NLPacket;
|
||||
|
||||
class LocalInjectorsStream {
|
||||
public:
|
||||
LocalInjectorsStream(int numFrameSamples);
|
||||
int getSampleCapacity() { return 0; };
|
||||
int samplesAvailable() { return 0; }
|
||||
int writeSamples(const float*, int numSamples) { return 0; }
|
||||
void resizeForFrameSize(int numFrameSamples) {}
|
||||
int skipSamples(int numSamples) { return 0; }
|
||||
int readSamples(float* mixBuffer, int numSamples, bool append) { return 0; }
|
||||
};
|
||||
|
||||
class AudioInjectorsThread : public QThread {
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -97,9 +108,9 @@ public:
|
|||
|
||||
class AudioOutputIODevice : public QIODevice {
|
||||
public:
|
||||
AudioOutputIODevice(AudioRingBuffer& localInjectorsBuffer, MixedProcessedAudioStream& receivedAudioStream,
|
||||
AudioOutputIODevice(LocalInjectorsStream& localInjectorsStream, MixedProcessedAudioStream& receivedAudioStream,
|
||||
AudioClient* audio) :
|
||||
_localInjectorsBuffer(localInjectorsBuffer), _receivedAudioStream(receivedAudioStream),
|
||||
_localInjectorsStream(localInjectorsStream), _receivedAudioStream(receivedAudioStream),
|
||||
_audio(audio), _unfulfilledReads(0) {}
|
||||
|
||||
void start() { open(QIODevice::ReadOnly | QIODevice::Unbuffered); }
|
||||
|
@ -108,7 +119,7 @@ public:
|
|||
qint64 writeData(const char * data, qint64 maxSize) override { return 0; }
|
||||
int getRecentUnfulfilledReads() { int unfulfilledReads = _unfulfilledReads; _unfulfilledReads = 0; return unfulfilledReads; }
|
||||
private:
|
||||
AudioRingBuffer& _localInjectorsBuffer;
|
||||
LocalInjectorsStream& _localInjectorsStream;
|
||||
MixedProcessedAudioStream& _receivedAudioStream;
|
||||
AudioClient* _audio;
|
||||
int _unfulfilledReads;
|
||||
|
@ -277,7 +288,7 @@ private:
|
|||
QAudioOutput* _loopbackAudioOutput;
|
||||
QIODevice* _loopbackOutputDevice;
|
||||
AudioRingBuffer _inputRingBuffer;
|
||||
AudioRingBuffer _localInjectorsBuffer;
|
||||
LocalInjectorsStream _localInjectorsStream;
|
||||
MixedProcessedAudioStream _receivedAudioStream;
|
||||
bool _isStereoInput;
|
||||
|
||||
|
@ -322,7 +333,7 @@ private:
|
|||
// for local audio (used by audio injectors thread)
|
||||
float _localMixBuffer[AudioConstants::NETWORK_FRAME_SAMPLES_STEREO];
|
||||
int16_t _localScratchBuffer[AudioConstants::NETWORK_FRAME_SAMPLES_AMBISONIC];
|
||||
int16_t* _localOutputScratchBuffer { NULL };
|
||||
float* _localOutputMixBuffer { NULL };
|
||||
AudioInjectorsThread _localAudioThread;
|
||||
Mutex _localAudioMutex;
|
||||
|
||||
|
|
Loading…
Reference in a new issue