From 952ca928f195d0535e602d8407f2174f1d1383ca Mon Sep 17 00:00:00 2001 From: matsukaze Date: Wed, 2 Apr 2014 12:28:22 -0700 Subject: [PATCH] More audio fixes. Fix audio buffer size on Win. --- interface/src/Audio.cpp | 67 +++++++++++++++++++++++++++++++---------- interface/src/Audio.h | 7 +++++ 2 files changed, 58 insertions(+), 16 deletions(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 5e2524a54c..8cb4ecfecd 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -282,8 +282,6 @@ void linearResampling(int16_t* sourceSamples, int16_t* destinationSamples, } } -const int CALLBACK_ACCELERATOR_RATIO = 2; - void Audio::start() { // set up the desired audio format @@ -305,8 +303,11 @@ void Audio::start() { qDebug() << "The default audio output device is" << outputDeviceInfo.deviceName(); bool outputFormatSupported = switchOutputToAudioDevice(outputDeviceInfo); - if (!inputFormatSupported || !outputFormatSupported) { - qDebug() << "Unable to set up audio I/O because of a problem with input or output formats."; + if (!inputFormatSupported) { + qDebug() << "Unable to set up audio input because of a problem with input format."; + } + if (!outputFormatSupported) { + qDebug() << "Unable to set up audio output because of a problem with output format."; } } @@ -341,10 +342,9 @@ void Audio::handleAudioInput() { static int16_t* monoAudioSamples = (int16_t*) (monoAudioDataPacket + leadingBytes); - static float inputToNetworkInputRatio = _numInputCallbackBytes * CALLBACK_ACCELERATOR_RATIO - / NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL; + float inputToNetworkInputRatio = calculateDeviceToNetworkInputRatio(_numInputCallbackBytes); - static unsigned int inputSamplesRequired = NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL * inputToNetworkInputRatio; + unsigned int inputSamplesRequired = NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL * inputToNetworkInputRatio; QByteArray inputByteArray = _inputDevice->readAll(); @@ -606,11 +606,6 @@ void Audio::processReceivedAudio(const QByteArray& audioByteArray) { _ringBuffer.parseData(audioByteArray); - float outSampleRate = _outputFormat.sampleRate(); - float desSampleRate = _desiredOutputFormat.sampleRate(); - int outChannelCount = _outputFormat.channelCount(); - int desChannelCount = _desiredOutputFormat.channelCount(); - float myOutputRatio = desSampleRate / outSampleRate * (desChannelCount / outChannelCount); float networkOutputToOutputRatio = (_desiredOutputFormat.sampleRate() / (float) _outputFormat.sampleRate()) * (_desiredOutputFormat.channelCount() / (float) _outputFormat.channelCount()); @@ -861,13 +856,12 @@ bool Audio::switchInputToAudioDevice(const QAudioDeviceInfo& inputDeviceInfo) { qDebug() << "The format to be used for audio input is" << _inputFormat; _audioInput = new QAudioInput(inputDeviceInfo, _inputFormat, this); - _numInputCallbackBytes = NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL * _inputFormat.channelCount() - * (_inputFormat.sampleRate() / SAMPLE_RATE) - / CALLBACK_ACCELERATOR_RATIO; + _numInputCallbackBytes = calculateNumberOfInputCallbackBytes(_inputFormat); _audioInput->setBufferSize(_numInputCallbackBytes); // how do we want to handle input working, but output not working? - _inputRingBuffer.resizeForFrameSize(_numInputCallbackBytes * CALLBACK_ACCELERATOR_RATIO / sizeof(int16_t)); + int numFrameSamples = calculateNumberOfFrameSamples(_numInputCallbackBytes); + _inputRingBuffer.resizeForFrameSize(numFrameSamples); _inputDevice = _audioInput->start(); connect(_inputDevice, SIGNAL(readyRead()), this, SLOT(handleAudioInput())); @@ -924,3 +918,44 @@ bool Audio::switchOutputToAudioDevice(const QAudioDeviceInfo& outputDeviceInfo) } return supportedFormat; } + +// The following constant is operating system dependent due to differences in +// the way input audio is handled. The audio input buffer size is inversely +// proportional to the accelerator ratio. + +#ifdef Q_OS_WIN +const float Audio::CALLBACK_ACCELERATOR_RATIO = 0.4f; +#endif + +#ifdef Q_OS_MAC +const float Audio::CALLBACK_ACCELERATOR_RATIO = 2.0f; +#endif + +#ifdef Q_OS_LINUX +const float Audio::CALLBACK_ACCELERATOR_RATIO = 2.0f; +#endif + +int Audio::calculateNumberOfInputCallbackBytes(const QAudioFormat& format) +{ + int numInputCallbackBytes = (int)(((NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL + * format.channelCount() + * (format.sampleRate() / SAMPLE_RATE)) + / CALLBACK_ACCELERATOR_RATIO) + 0.5f); + + return numInputCallbackBytes; +} + +float Audio::calculateDeviceToNetworkInputRatio(int numBytes) +{ + float inputToNetworkInputRatio = (int)((_numInputCallbackBytes + * CALLBACK_ACCELERATOR_RATIO + / NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL) + 0.5f); + + return inputToNetworkInputRatio; +} + +int Audio::calculateNumberOfFrameSamples(int numBytes) +{ + int frameSamples = (int)(numBytes * CALLBACK_ACCELERATOR_RATIO + 0.5f) / sizeof(int16_t); + return frameSamples; +} diff --git a/interface/src/Audio.h b/interface/src/Audio.h index 1e54fd22eb..896ab3c3fb 100644 --- a/interface/src/Audio.h +++ b/interface/src/Audio.h @@ -178,6 +178,13 @@ private: bool switchInputToAudioDevice(const QAudioDeviceInfo& inputDeviceInfo); bool switchOutputToAudioDevice(const QAudioDeviceInfo& outputDeviceInfo); + + // Callback acceleration dependent calculations + static const float CALLBACK_ACCELERATOR_RATIO; + int calculateNumberOfInputCallbackBytes(const QAudioFormat& format); + int calculateNumberOfFrameSamples(int numBytes); + float calculateDeviceToNetworkInputRatio(int numBytes); + };