From 6a5f3fa6c75edd6dd3458d485cdac32e11aefd06 Mon Sep 17 00:00:00 2001 From: amerhifi Date: Thu, 5 Sep 2019 16:59:18 -0700 Subject: [PATCH 01/27] forcing lzma compression on the package --- tools/ci-scripts/postbuild.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/ci-scripts/postbuild.py b/tools/ci-scripts/postbuild.py index b93ed5a664..8e165f05b7 100644 --- a/tools/ci-scripts/postbuild.py +++ b/tools/ci-scripts/postbuild.py @@ -220,7 +220,8 @@ cpackCommand = [ 'cpack', '-G', 'ZIP', '-D', "CPACK_PACKAGE_FILE_NAME={}".format(archiveName), - '-D', "CPACK_INCLUDE_TOPLEVEL_DIRECTORY=OFF" + '-D', "CPACK_INCLUDE_TOPLEVEL_DIRECTORY=OFF", + '-D', "CPACK_RPM_COMPRESSION_TYPE=lzma" ] print("Create ZIP version of installer archive") From cc11bd9552fe8f0e01ddb7bba1eb623974c1a38f Mon Sep 17 00:00:00 2001 From: amerhifi Date: Fri, 13 Sep 2019 11:24:41 -0700 Subject: [PATCH 02/27] created new AudioWrapper --- interface/src/scripting/Audio.cpp | 4 +- interface/src/scripting/Audio.h | 5 +- interface/src/scripting/AudioDevices.cpp | 52 +-- interface/src/scripting/AudioDevices.h | 32 +- libraries/audio-client/src/AudioClient.cpp | 456 +++++++++----------- libraries/audio-client/src/AudioClient.h | 131 +++--- libraries/ui/src/ui/OffscreenQmlSurface.cpp | 2 +- 7 files changed, 324 insertions(+), 358 deletions(-) diff --git a/interface/src/scripting/Audio.cpp b/interface/src/scripting/Audio.cpp index ba392f0cd1..43958188e3 100644 --- a/interface/src/scripting/Audio.cpp +++ b/interface/src/scripting/Audio.cpp @@ -440,13 +440,13 @@ void Audio::handlePushedToTalk(bool enabled) { } } -void Audio::setInputDevice(const QAudioDeviceInfo& device, bool isHMD) { +void Audio::setInputDevice(const HifiAudioDeviceInfo& device, bool isHMD) { withWriteLock([&] { _devices.chooseInputDevice(device, isHMD); }); } -void Audio::setOutputDevice(const QAudioDeviceInfo& device, bool isHMD) { +void Audio::setOutputDevice(const HifiAudioDeviceInfo& device, bool isHMD) { withWriteLock([&] { _devices.chooseOutputDevice(device, isHMD); }); diff --git a/interface/src/scripting/Audio.h b/interface/src/scripting/Audio.h index d3bc6b9449..ab4fe89ce9 100644 --- a/interface/src/scripting/Audio.h +++ b/interface/src/scripting/Audio.h @@ -19,6 +19,7 @@ #include "SettingHandle.h" #include "AudioFileWav.h" #include +#include "HifiAudioDeviceInfo.h" using MutedGetter = std::function; using MutedSetter = std::function; @@ -158,7 +159,7 @@ public: * @param {boolean} isHMD - Is HMD. * @deprecated This function is deprecated and will be removed. */ - Q_INVOKABLE void setInputDevice(const QAudioDeviceInfo& device, bool isHMD); + Q_INVOKABLE void setInputDevice(const HifiAudioDeviceInfo& device, bool isHMD); /**jsdoc * @function Audio.setOutputDevice @@ -166,7 +167,7 @@ public: * @param {boolean} isHMD - Is HMD. * @deprecated This function is deprecated and will be removed. */ - Q_INVOKABLE void setOutputDevice(const QAudioDeviceInfo& device, bool isHMD); + Q_INVOKABLE void setOutputDevice(const HifiAudioDeviceInfo& device, bool isHMD); /**jsdoc * Enables or disables reverberation. Reverberation is done by the client on the post-mix audio. The reverberation options diff --git a/interface/src/scripting/AudioDevices.cpp b/interface/src/scripting/AudioDevices.cpp index 02072d3ff0..dbdd0c4852 100644 --- a/interface/src/scripting/AudioDevices.cpp +++ b/interface/src/scripting/AudioDevices.cpp @@ -29,6 +29,8 @@ static Setting::Handle desktopOutputDeviceSetting { QStringList { Audio static Setting::Handle hmdInputDeviceSetting { QStringList { Audio::AUDIO, Audio::HMD, "INPUT" }}; static Setting::Handle hmdOutputDeviceSetting { QStringList { Audio::AUDIO, Audio::HMD, "OUTPUT" }}; +Q_DECLARE_METATYPE(HifiAudioDeviceInfo); + Setting::Handle& getSetting(bool contextIsHMD, QAudio::Mode mode) { if (mode == QAudio::AudioInput) { return contextIsHMD ? hmdInputDeviceSetting : desktopInputDeviceSetting; @@ -139,7 +141,7 @@ QVariant AudioDeviceList::data(const QModelIndex& index, int role) const { } else if (role == SelectedHMDRole) { return _devices.at(index.row())->selectedHMD; } else if (role == InfoRole) { - return QVariant::fromValue(_devices.at(index.row())->info); + return QVariant::fromValue(_devices.at(index.row())->info); } else { return QVariant(); } @@ -191,8 +193,8 @@ void AudioDeviceList::resetDevice(bool contextIsHMD) { #endif } -void AudioDeviceList::onDeviceChanged(const QAudioDeviceInfo& device, bool isHMD) { - QAudioDeviceInfo& selectedDevice = isHMD ? _selectedHMDDevice : _selectedDesktopDevice; +void AudioDeviceList::onDeviceChanged(const HifiAudioDeviceInfo& device, bool isHMD) { + HifiAudioDeviceInfo& selectedDevice = isHMD ? _selectedHMDDevice : _selectedDesktopDevice; selectedDevice = device; for (auto i = 0; i < _devices.size(); ++i) { @@ -259,25 +261,25 @@ std::shared_ptr getSimilarDevice(const QString& deviceNa return devices[minDistanceIndex]; } -void AudioDeviceList::onDevicesChanged(const QList& devices) { +void AudioDeviceList::onDevicesChanged(const QList& devices) { beginResetModel(); QList> newDevices; bool hmdIsSelected = false; bool desktopIsSelected = false; - foreach(const QAudioDeviceInfo& deviceInfo, devices) { + foreach(const HifiAudioDeviceInfo& deviceInfo, devices) { for (bool isHMD : {false, true}) { auto& backupSelectedDeviceName = isHMD ? _backupSelectedHMDDeviceName : _backupSelectedDesktopDeviceName; if (deviceInfo.deviceName() == backupSelectedDeviceName) { - QAudioDeviceInfo& selectedDevice = isHMD ? _selectedHMDDevice : _selectedDesktopDevice; + HifiAudioDeviceInfo& selectedDevice = isHMD ? _selectedHMDDevice : _selectedDesktopDevice; selectedDevice = deviceInfo; backupSelectedDeviceName.clear(); } } } - foreach(const QAudioDeviceInfo& deviceInfo, devices) { + foreach(const HifiAudioDeviceInfo& deviceInfo, devices) { AudioDevice device; device.info = deviceInfo; device.display = device.info.deviceName() @@ -286,10 +288,10 @@ void AudioDeviceList::onDevicesChanged(const QList& devices) { .replace(" )", ")"); for (bool isHMD : {false, true}) { - QAudioDeviceInfo& selectedDevice = isHMD ? _selectedHMDDevice : _selectedDesktopDevice; + HifiAudioDeviceInfo& selectedDevice = isHMD ? _selectedHMDDevice : _selectedDesktopDevice; bool& isSelected = isHMD ? device.selectedHMD : device.selectedDesktop; - if (!selectedDevice.isNull()) { + if (!selectedDevice.getDevice().isNull()) { isSelected = (device.info == selectedDevice); } else { @@ -325,13 +327,13 @@ void AudioDeviceList::onDevicesChanged(const QList& devices) { if (!newDevices.isEmpty()) { if (!hmdIsSelected) { - _backupSelectedHMDDeviceName = !_selectedHMDDevice.isNull() ? _selectedHMDDevice.deviceName() : _hmdSavedDeviceName; + _backupSelectedHMDDeviceName = !_selectedHMDDevice.getDevice().isNull() ? _selectedHMDDevice.deviceName() : _hmdSavedDeviceName; auto device = getSimilarDevice(_backupSelectedHMDDeviceName, newDevices); device->selectedHMD = true; emit selectedDevicePlugged(device->info, true); } if (!desktopIsSelected) { - _backupSelectedDesktopDeviceName = !_selectedDesktopDevice.isNull() ? _selectedDesktopDevice.deviceName() : _desktopSavedDeviceName; + _backupSelectedDesktopDeviceName = !_selectedDesktopDevice.getDevice().isNull() ? _selectedDesktopDevice.deviceName() : _desktopSavedDeviceName; auto device = getSimilarDevice(_backupSelectedDesktopDeviceName, newDevices); device->selectedDesktop = true; emit selectedDevicePlugged(device->info, false); @@ -382,8 +384,8 @@ AudioDevices::AudioDevices(bool& contextIsHMD) : _contextIsHMD(contextIsHMD) { _outputs.onDeviceChanged(client->getActiveAudioDevice(QAudio::AudioOutput), contextIsHMD); // connections are made after client is initialized, so we must also fetch the devices - const QList& devicesInput = client->getAudioDevices(QAudio::AudioInput); - const QList& devicesOutput = client->getAudioDevices(QAudio::AudioOutput); + const QList& devicesInput = client->getAudioDevices(QAudio::AudioInput); + const QList& devicesOutput = client->getAudioDevices(QAudio::AudioOutput); //setup devices _inputs.onDevicesChanged(devicesInput); @@ -397,9 +399,9 @@ void AudioDevices::onContextChanged(const QString& context) { _outputs.resetDevice(_contextIsHMD); } -void AudioDevices::onDeviceSelected(QAudio::Mode mode, const QAudioDeviceInfo& device, - const QAudioDeviceInfo& previousDevice, bool isHMD) { - QString deviceName = device.isNull() ? QString() : device.deviceName(); +void AudioDevices::onDeviceSelected(QAudio::Mode mode, const HifiAudioDeviceInfo& device, + const HifiAudioDeviceInfo& previousDevice, bool isHMD) { + QString deviceName = device.getDevice().isNull() ? QString() : device.deviceName(); auto& setting = getSetting(isHMD, mode); @@ -410,7 +412,7 @@ void AudioDevices::onDeviceSelected(QAudio::Mode mode, const QAudioDeviceInfo& d setting.set(deviceName); // log the selected device - if (!device.isNull()) { + if (!device.getDevice().isNull()) { QJsonObject data; const QString MODE = "audio_mode"; @@ -434,13 +436,13 @@ void AudioDevices::onDeviceSelected(QAudio::Mode mode, const QAudioDeviceInfo& d } } -void AudioDevices::onDeviceChanged(QAudio::Mode mode, const QAudioDeviceInfo& device) { +void AudioDevices::onDeviceChanged(QAudio::Mode mode, const HifiAudioDeviceInfo& device) { if (mode == QAudio::AudioInput) { if (_requestedInputDevice == device) { onDeviceSelected(QAudio::AudioInput, device, _contextIsHMD ? _inputs._selectedHMDDevice : _inputs._selectedDesktopDevice, _contextIsHMD); - _requestedInputDevice = QAudioDeviceInfo(); + _requestedInputDevice = HifiAudioDeviceInfo(); } _inputs.onDeviceChanged(device, _contextIsHMD); } else { // if (mode == QAudio::AudioOutput) @@ -448,13 +450,13 @@ void AudioDevices::onDeviceChanged(QAudio::Mode mode, const QAudioDeviceInfo& de onDeviceSelected(QAudio::AudioOutput, device, _contextIsHMD ? _outputs._selectedHMDDevice : _outputs._selectedDesktopDevice, _contextIsHMD); - _requestedOutputDevice = QAudioDeviceInfo(); + _requestedOutputDevice = HifiAudioDeviceInfo(); } _outputs.onDeviceChanged(device, _contextIsHMD); } } -void AudioDevices::onDevicesChanged(QAudio::Mode mode, const QList& devices) { +void AudioDevices::onDevicesChanged(QAudio::Mode mode, const QList& devices) { static std::once_flag once; std::call_once(once, [&] { //readout settings @@ -503,14 +505,14 @@ void AudioDevices::onDevicesChanged(QAudio::Mode mode, const QList().data(); _requestedInputDevice = device; QMetaObject::invokeMethod(client, "switchAudioDevice", Q_ARG(QAudio::Mode, QAudio::AudioInput), - Q_ARG(const QAudioDeviceInfo&, device)); + Q_ARG(const QAudioDeviceInfo&, device.getDevice())); } else { //context is different. just save device in settings onDeviceSelected(QAudio::AudioInput, device, @@ -520,14 +522,14 @@ void AudioDevices::chooseInputDevice(const QAudioDeviceInfo& device, bool isHMD) } } -void AudioDevices::chooseOutputDevice(const QAudioDeviceInfo& device, bool isHMD) { +void AudioDevices::chooseOutputDevice(const HifiAudioDeviceInfo& device, bool isHMD) { //check if current context equals device to change if (_contextIsHMD == isHMD) { auto client = DependencyManager::get().data(); _requestedOutputDevice = device; QMetaObject::invokeMethod(client, "switchAudioDevice", Q_ARG(QAudio::Mode, QAudio::AudioOutput), - Q_ARG(const QAudioDeviceInfo&, device)); + Q_ARG(const QAudioDeviceInfo&, device.getDevice())); } else { //context is different. just save device in settings onDeviceSelected(QAudio::AudioOutput, device, diff --git a/interface/src/scripting/AudioDevices.h b/interface/src/scripting/AudioDevices.h index 2ea034d9fe..21cd875f7b 100644 --- a/interface/src/scripting/AudioDevices.h +++ b/interface/src/scripting/AudioDevices.h @@ -19,11 +19,13 @@ #include #include +#include "HifiAudioDeviceInfo.h" + namespace scripting { class AudioDevice { public: - QAudioDeviceInfo info; + HifiAudioDeviceInfo info; QString display; bool selectedDesktop { false }; bool selectedHMD { false }; @@ -50,12 +52,12 @@ public: void resetDevice(bool contextIsHMD); signals: - void deviceChanged(const QAudioDeviceInfo& device); - void selectedDevicePlugged(const QAudioDeviceInfo& device, bool isHMD); + void deviceChanged(const HifiAudioDeviceInfo& device); + void selectedDevicePlugged(const HifiAudioDeviceInfo& device, bool isHMD); protected slots: - void onDeviceChanged(const QAudioDeviceInfo& device, bool isHMD); - void onDevicesChanged(const QList& devices); + void onDeviceChanged(const HifiAudioDeviceInfo& device, bool isHMD); + void onDevicesChanged(const QList& devices); protected: friend class AudioDevices; @@ -63,8 +65,8 @@ protected: static QHash _roles; static Qt::ItemFlags _flags; const QAudio::Mode _mode; - QAudioDeviceInfo _selectedDesktopDevice; - QAudioDeviceInfo _selectedHMDDevice; + HifiAudioDeviceInfo _selectedDesktopDevice; + HifiAudioDeviceInfo _selectedHMDDevice; QString _backupSelectedDesktopDeviceName; QString _backupSelectedHMDDeviceName; QList> _devices; @@ -124,14 +126,14 @@ signals: void nop(); private slots: - void chooseInputDevice(const QAudioDeviceInfo& device, bool isHMD); - void chooseOutputDevice(const QAudioDeviceInfo& device, bool isHMD); + void chooseInputDevice(const HifiAudioDeviceInfo& device, bool isHMD); + void chooseOutputDevice(const HifiAudioDeviceInfo& device, bool isHMD); void onContextChanged(const QString& context); - void onDeviceSelected(QAudio::Mode mode, const QAudioDeviceInfo& device, - const QAudioDeviceInfo& previousDevice, bool isHMD); - void onDeviceChanged(QAudio::Mode mode, const QAudioDeviceInfo& device); - void onDevicesChanged(QAudio::Mode mode, const QList& devices); + void onDeviceSelected(QAudio::Mode mode, const HifiAudioDeviceInfo& device, + const HifiAudioDeviceInfo& previousDevice, bool isHMD); + void onDeviceChanged(QAudio::Mode mode, const HifiAudioDeviceInfo& device); + void onDevicesChanged(QAudio::Mode mode, const QList& devices); private: friend class Audio; @@ -141,8 +143,8 @@ private: AudioInputDeviceList _inputs; AudioDeviceList _outputs { QAudio::AudioOutput }; - QAudioDeviceInfo _requestedOutputDevice; - QAudioDeviceInfo _requestedInputDevice; + HifiAudioDeviceInfo _requestedOutputDevice; + HifiAudioDeviceInfo _requestedInputDevice; const bool& _contextIsHMD; }; diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 6add52141c..195afc619c 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -67,7 +67,7 @@ static const int CHECK_INPUT_READS_MSECS = 2000; static const int MIN_READS_TO_CONSIDER_INPUT_ALIVE = 10; #endif -static const auto DEFAULT_POSITION_GETTER = []{ return Vectors::ZERO; }; +static const auto DEFAULT_POSITION_GETTER = [] { return Vectors::ZERO; }; static const auto DEFAULT_ORIENTATION_GETTER = [] { return Quaternions::IDENTITY; }; static const int DEFAULT_BUFFER_FRAMES = 1; @@ -78,12 +78,11 @@ static const int OUTPUT_CHANNEL_COUNT = 2; static const bool DEFAULT_STARVE_DETECTION_ENABLED = true; static const int STARVE_DETECTION_THRESHOLD = 3; -static const int STARVE_DETECTION_PERIOD = 10 * 1000; // 10 Seconds +static const int STARVE_DETECTION_PERIOD = 10 * 1000; // 10 Seconds Setting::Handle dynamicJitterBufferEnabled("dynamicJitterBuffersEnabled", - InboundAudioStream::DEFAULT_DYNAMIC_JITTER_BUFFER_ENABLED); -Setting::Handle staticJitterBufferFrames("staticJitterBufferFrames", - InboundAudioStream::DEFAULT_STATIC_JITTER_FRAMES); + InboundAudioStream::DEFAULT_DYNAMIC_JITTER_BUFFER_ENABLED); +Setting::Handle staticJitterBufferFrames("staticJitterBufferFrames", InboundAudioStream::DEFAULT_STATIC_JITTER_FRAMES); // protect the Qt internal device list using Mutex = std::mutex; @@ -92,10 +91,25 @@ Mutex _deviceMutex; Mutex _recordMutex; // thread-safe -QList getAvailableDevices(QAudio::Mode mode) { +QList getAvailableDevices(QAudio::Mode mode) { // NOTE: availableDevices() clobbers the Qt internal device list Lock lock(_deviceMutex); - return QAudioDeviceInfo::availableDevices(mode); + auto devices = QAudioDeviceInfo::availableDevices(mode); + + QList newDevices; + QAudioDeviceInfo::defaultOutputDevice(); + + for (auto& device : devices) { + bool isDefault = false; + if (mode == QAudio::Mode::AudioInput) { + isDefault = device == QAudioDeviceInfo::defaultInputDevice(); + } else { + isDefault = device == QAudioDeviceInfo::defaultOutputDevice(); + } + newDevices.push_back(HifiAudioDeviceInfo(device, isDefault, mode)); + } + + return newDevices; } // now called from a background thread, to keep blocking operations off the audio thread @@ -122,29 +136,28 @@ void AudioClient::checkDevices() { } } -QAudioDeviceInfo AudioClient::getActiveAudioDevice(QAudio::Mode mode) const { +HifiAudioDeviceInfo AudioClient::getActiveAudioDevice(QAudio::Mode mode) const { Lock lock(_deviceMutex); if (mode == QAudio::AudioInput) { return _inputDeviceInfo; - } else { // if (mode == QAudio::AudioOutput) + } else { return _outputDeviceInfo; } } -QList AudioClient::getAudioDevices(QAudio::Mode mode) const { +QList AudioClient::getAudioDevices(QAudio::Mode mode) const { Lock lock(_deviceMutex); if (mode == QAudio::AudioInput) { return _inputDevices; - } else { // if (mode == QAudio::AudioOutput) + } else { // if (mode == QAudio::AudioOutput) return _outputDevices; } } static void channelUpmix(int16_t* source, int16_t* dest, int numSamples, int numExtraChannels) { - for (int i = 0; i < numSamples/2; i++) { - + for (int i = 0; i < numSamples / 2; i++) { // read 2 samples int16_t left = *source++; int16_t right = *source++; @@ -159,8 +172,7 @@ static void channelUpmix(int16_t* source, int16_t* dest, int numSamples, int num } static void channelDownmix(int16_t* source, int16_t* dest, int numSamples) { - for (int i = 0; i < numSamples/2; i++) { - + for (int i = 0; i < numSamples / 2; i++) { // read 2 samples int16_t left = *source++; int16_t right = *source++; @@ -171,9 +183,8 @@ static void channelDownmix(int16_t* source, int16_t* dest, int numSamples) { } static bool detectClipping(int16_t* samples, int numSamples, int numChannels) { - - const int32_t CLIPPING_THRESHOLD = 32392; // -0.1 dBFS - const int CLIPPING_DETECTION = 3; // consecutive samples over threshold + const int32_t CLIPPING_THRESHOLD = 32392; // -0.1 dBFS + const int CLIPPING_DETECTION = 3; // consecutive samples over threshold bool isClipping = false; @@ -181,9 +192,9 @@ static bool detectClipping(int16_t* samples, int numSamples, int numChannels) { int oversLeft = 0; int oversRight = 0; - for (int i = 0; i < numSamples/2; i++) { - int32_t left = std::abs((int32_t)samples[2*i+0]); - int32_t right = std::abs((int32_t)samples[2*i+1]); + for (int i = 0; i < numSamples / 2; i++) { + int32_t left = std::abs((int32_t)samples[2 * i + 0]); + int32_t right = std::abs((int32_t)samples[2 * i + 1]); if (left > CLIPPING_THRESHOLD) { isClipping |= (++oversLeft >= CLIPPING_DETECTION); @@ -214,7 +225,6 @@ static bool detectClipping(int16_t* samples, int numSamples, int numChannels) { } static float computeLoudness(int16_t* samples, int numSamples) { - float scale = numSamples ? 1.0f / numSamples : 0.0f; int32_t loudness = 0; @@ -226,7 +236,6 @@ static float computeLoudness(int16_t* samples, int numSamples) { template static void applyGainSmoothing(float* buffer, int numFrames, float gain0, float gain1) { - // fast path for unity gain if (gain0 == 1.0f && gain1 == 1.0f) { return; @@ -241,14 +250,13 @@ static void applyGainSmoothing(float* buffer, int numFrames, float gain0, float float tStep = 1.0f / numFrames; for (int i = 0; i < numFrames; i++) { - // evaluate poly over t=[0,1) float gain = (c3 * t + c2) * t * t + c0; t += tStep; // apply gain to all channels for (int ch = 0; ch < NUM_CHANNELS; ch++) { - buffer[NUM_CHANNELS*i + ch] *= gain; + buffer[NUM_CHANNELS * i + ch] *= gain; } } } @@ -258,52 +266,22 @@ static inline float convertToFloat(int16_t sample) { } AudioClient::AudioClient() : - AbstractAudioInterface(), - _gate(this), - _audioInput(NULL), - _dummyAudioInput(NULL), - _desiredInputFormat(), - _inputFormat(), - _numInputCallbackBytes(0), - _audioOutput(NULL), - _desiredOutputFormat(), - _outputFormat(), - _outputFrameSize(0), - _numOutputCallbackBytes(0), - _loopbackAudioOutput(NULL), - _loopbackOutputDevice(NULL), - _inputRingBuffer(0), - _localInjectorsStream(0, 1), - _receivedAudioStream(RECEIVED_AUDIO_STREAM_CAPACITY_FRAMES), - _isStereoInput(false), - _outputStarveDetectionStartTimeMsec(0), - _outputStarveDetectionCount(0), + AbstractAudioInterface(), _gate(this), _audioInput(NULL), _dummyAudioInput(NULL), _desiredInputFormat(), _inputFormat(), + _numInputCallbackBytes(0), _audioOutput(NULL), _desiredOutputFormat(), _outputFormat(), _outputFrameSize(0), + _numOutputCallbackBytes(0), _loopbackAudioOutput(NULL), _loopbackOutputDevice(NULL), _inputRingBuffer(0), + _localInjectorsStream(0, 1), _receivedAudioStream(RECEIVED_AUDIO_STREAM_CAPACITY_FRAMES), _isStereoInput(false), + _outputStarveDetectionStartTimeMsec(0), _outputStarveDetectionCount(0), _outputBufferSizeFrames("audioOutputBufferFrames", DEFAULT_BUFFER_FRAMES), _sessionOutputBufferSizeFrames(_outputBufferSizeFrames.get()), _outputStarveDetectionEnabled("audioOutputStarveDetectionEnabled", DEFAULT_STARVE_DETECTION_ENABLED), - _lastRawInputLoudness(0.0f), - _lastSmoothedRawInputLoudness(0.0f), - _lastInputLoudness(0.0f), - _timeSinceLastClip(-1.0f), - _muted(false), - _shouldEchoLocally(false), - _shouldEchoToServer(false), - _isNoiseGateEnabled(true), - _isAECEnabled(true), - _reverb(false), - _reverbOptions(&_scriptReverbOptions), - _inputToNetworkResampler(NULL), - _networkToOutputResampler(NULL), - _localToOutputResampler(NULL), - _loopbackResampler(NULL), - _audioLimiter(AudioConstants::SAMPLE_RATE, OUTPUT_CHANNEL_COUNT), - _outgoingAvatarAudioSequenceNumber(0), - _audioOutputIODevice(_localInjectorsStream, _receivedAudioStream, this), - _stats(&_receivedAudioStream), - _positionGetter(DEFAULT_POSITION_GETTER), + _lastRawInputLoudness(0.0f), _lastSmoothedRawInputLoudness(0.0f), _lastInputLoudness(0.0f), _timeSinceLastClip(-1.0f), + _muted(false), _shouldEchoLocally(false), _shouldEchoToServer(false), _isNoiseGateEnabled(true), _isAECEnabled(true), + _reverb(false), _reverbOptions(&_scriptReverbOptions), _inputToNetworkResampler(NULL), _networkToOutputResampler(NULL), + _localToOutputResampler(NULL), _loopbackResampler(NULL), _audioLimiter(AudioConstants::SAMPLE_RATE, OUTPUT_CHANNEL_COUNT), + _outgoingAvatarAudioSequenceNumber(0), _audioOutputIODevice(_localInjectorsStream, _receivedAudioStream, this), + _stats(&_receivedAudioStream), _positionGetter(DEFAULT_POSITION_GETTER), #if defined(Q_OS_ANDROID) - _checkInputTimer(this), - _isHeadsetPluggedIn(false), + _checkInputTimer(this), _isHeadsetPluggedIn(false), #endif _orientationGetter(DEFAULT_ORIENTATION_GETTER) { @@ -314,17 +292,21 @@ AudioClient::AudioClient() : { Setting::Handle::Deprecated("maxFramesOverDesired", InboundAudioStream::MAX_FRAMES_OVER_DESIRED); Setting::Handle::Deprecated("windowStarveThreshold", InboundAudioStream::WINDOW_STARVE_THRESHOLD); - Setting::Handle::Deprecated("windowSecondsForDesiredCalcOnTooManyStarves", InboundAudioStream::WINDOW_SECONDS_FOR_DESIRED_CALC_ON_TOO_MANY_STARVES); - Setting::Handle::Deprecated("windowSecondsForDesiredReduction", InboundAudioStream::WINDOW_SECONDS_FOR_DESIRED_REDUCTION); + Setting::Handle::Deprecated("windowSecondsForDesiredCalcOnTooManyStarves", + InboundAudioStream::WINDOW_SECONDS_FOR_DESIRED_CALC_ON_TOO_MANY_STARVES); + Setting::Handle::Deprecated("windowSecondsForDesiredReduction", + InboundAudioStream::WINDOW_SECONDS_FOR_DESIRED_REDUCTION); Setting::Handle::Deprecated("useStDevForJitterCalc", InboundAudioStream::USE_STDEV_FOR_JITTER); Setting::Handle::Deprecated("repetitionWithFade", InboundAudioStream::REPETITION_WITH_FADE); } - connect(&_receivedAudioStream, &MixedProcessedAudioStream::processSamples, - this, &AudioClient::processReceivedSamples, Qt::DirectConnection); - connect(this, &AudioClient::changeDevice, this, [=](const QAudioDeviceInfo& outputDeviceInfo) { - qCDebug(audioclient) << "got AudioClient::changeDevice signal, about to call switchOutputToAudioDevice() outputDeviceInfo: [" << outputDeviceInfo.deviceName() << "]"; - switchOutputToAudioDevice(outputDeviceInfo); + connect(&_receivedAudioStream, &MixedProcessedAudioStream::processSamples, this, &AudioClient::processReceivedSamples, + Qt::DirectConnection); + connect(this, &AudioClient::changeDevice, this, [=](const HifiAudioDeviceInfo& outputDeviceInfo) { + qCDebug(audioclient) + << "got AudioClient::changeDevice signal, about to call switchOutputToAudioDevice() outputDeviceInfo: [" + << outputDeviceInfo.deviceName() << "]"; + switchOutputToAudioDevice(outputDeviceInfo.getDevice()); }); connect(&_receivedAudioStream, &InboundAudioStream::mismatchedAudioCodec, this, &AudioClient::handleMismatchAudioFormat); @@ -350,9 +332,8 @@ AudioClient::AudioClient() : // start a thread to detect peak value changes _checkPeakValuesTimer = new QTimer(this); - connect(_checkPeakValuesTimer, &QTimer::timeout, this, [this] { - QtConcurrent::run(QThreadPool::globalInstance(), [this] { checkPeakValues(); }); - }); + connect(_checkPeakValuesTimer, &QTimer::timeout, this, + [this] { QtConcurrent::run(QThreadPool::globalInstance(), [this] { checkPeakValues(); }); }); const unsigned long PEAK_VALUES_CHECK_INTERVAL_MSECS = 50; _checkPeakValuesTimer->start(PEAK_VALUES_CHECK_INTERVAL_MSECS); @@ -373,9 +354,7 @@ AudioClient::AudioClient() : packetReceiver.registerListener(PacketType::SelectedAudioFormat, this, "handleSelectedAudioFormat"); auto& domainHandler = nodeList->getDomainHandler(); - connect(&domainHandler, &DomainHandler::disconnectedFromDomain, this, [this] { - _solo.reset(); - }); + connect(&domainHandler, &DomainHandler::disconnectedFromDomain, this, [this] { _solo.reset(); }); connect(nodeList.data(), &NodeList::nodeActivated, this, [this](SharedNodePointer node) { if (node->getType() == NodeType::AudioMixer) { _solo.resend(); @@ -384,7 +363,6 @@ AudioClient::AudioClient() : } AudioClient::~AudioClient() { - stop(); if (_codec && _encoder) { @@ -401,11 +379,11 @@ void AudioClient::customDeleter() { } void AudioClient::handleMismatchAudioFormat(SharedNodePointer node, const QString& currentCodec, const QString& recievedCodec) { - qCDebug(audioclient) << __FUNCTION__ << "sendingNode:" << *node << "currentCodec:" << currentCodec << "recievedCodec:" << recievedCodec; + qCDebug(audioclient) << __FUNCTION__ << "sendingNode:" << *node << "currentCodec:" << currentCodec + << "recievedCodec:" << recievedCodec; selectAudioFormat(recievedCodec); } - void AudioClient::reset() { _receivedAudioStream.reset(); _stats.reset(); @@ -433,9 +411,9 @@ void AudioClient::setAudioPaused(bool pause) { QAudioDeviceInfo getNamedAudioDeviceForMode(QAudio::Mode mode, const QString& deviceName) { QAudioDeviceInfo result; - foreach(QAudioDeviceInfo audioDevice, getAvailableDevices(mode)) { + foreach (HifiAudioDeviceInfo audioDevice, getAvailableDevices(mode)) { if (audioDevice.deviceName().trimmed() == deviceName.trimmed()) { - result = audioDevice; + result = audioDevice.getDevice(); break; } } @@ -468,7 +446,8 @@ QString AudioClient::getWinDeviceName(wchar_t* guid) { HRESULT hr = S_OK; CoInitialize(nullptr); IMMDeviceEnumerator* pMMDeviceEnumerator = nullptr; - CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&pMMDeviceEnumerator); + CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), + (void**)&pMMDeviceEnumerator); IMMDevice* pEndpoint; hr = pMMDeviceEnumerator->GetDevice(guid, &pEndpoint); if (hr == E_NOTFOUND) { @@ -492,34 +471,26 @@ QAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { if (getAvailableDevices(mode).size() > 1) { AudioDeviceID defaultDeviceID = 0; uint32_t propertySize = sizeof(AudioDeviceID); - AudioObjectPropertyAddress propertyAddress = { - kAudioHardwarePropertyDefaultInputDevice, - kAudioObjectPropertyScopeGlobal, - kAudioObjectPropertyElementMaster - }; + AudioObjectPropertyAddress propertyAddress = { kAudioHardwarePropertyDefaultInputDevice, + kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; if (mode == QAudio::AudioOutput) { propertyAddress.mSelector = kAudioHardwarePropertyDefaultOutputDevice; } - - OSStatus getPropertyError = AudioObjectGetPropertyData(kAudioObjectSystemObject, - &propertyAddress, - 0, - NULL, - &propertySize, - &defaultDeviceID); + OSStatus getPropertyError = + AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &propertySize, &defaultDeviceID); if (!getPropertyError && propertySize) { CFStringRef deviceName = NULL; propertySize = sizeof(deviceName); propertyAddress.mSelector = kAudioDevicePropertyDeviceNameCFString; - getPropertyError = AudioObjectGetPropertyData(defaultDeviceID, &propertyAddress, 0, - NULL, &propertySize, &deviceName); + getPropertyError = + AudioObjectGetPropertyData(defaultDeviceID, &propertyAddress, 0, NULL, &propertySize, &deviceName); if (!getPropertyError && propertySize) { // find a device in the list that matches the name we have and return it - foreach(QAudioDeviceInfo audioDevice, getAvailableDevices(mode)) { + foreach (QAudioDeviceInfo audioDevice, getAvailableDevices(mode)) { if (audioDevice.deviceName() == CFStringGetCStringPtr(deviceName, kCFStringEncodingMacRoman)) { return audioDevice; } @@ -531,7 +502,7 @@ QAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { #ifdef WIN32 QString deviceName; //Check for Windows Vista or higher, IMMDeviceEnumerator doesn't work below that. - if (!IsWindowsVistaOrGreater()) { // lower then vista + if (!IsWindowsVistaOrGreater()) { // lower then vista if (mode == QAudio::AudioInput) { WAVEINCAPS wic; // first use WAVE_MAPPER to get the default devices manufacturer ID @@ -553,9 +524,11 @@ QAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { HRESULT hr = S_OK; CoInitialize(NULL); IMMDeviceEnumerator* pMMDeviceEnumerator = NULL; - CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&pMMDeviceEnumerator); + CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), + (void**)&pMMDeviceEnumerator); IMMDevice* pEndpoint; - hr = pMMDeviceEnumerator->GetDefaultAudioEndpoint(mode == QAudio::AudioOutput ? eRender : eCapture, eMultimedia, &pEndpoint); + hr = pMMDeviceEnumerator->GetDefaultAudioEndpoint(mode == QAudio::AudioOutput ? eRender : eCapture, eMultimedia, + &pEndpoint); if (hr == E_NOTFOUND) { printf("Audio Error: device not found\n"); deviceName = QString("NONE"); @@ -569,22 +542,22 @@ QAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { CoUninitialize(); } - qCDebug(audioclient) << "defaultAudioDeviceForMode mode: " << (mode == QAudio::AudioOutput ? "Output" : "Input") - << " [" << deviceName << "] [" << getNamedAudioDeviceForMode(mode, deviceName).deviceName() << "]"; + qCDebug(audioclient) << "defaultAudioDeviceForMode mode: " << (mode == QAudio::AudioOutput ? "Output" : "Input") << " [" + << deviceName << "] [" << getNamedAudioDeviceForMode(mode, deviceName).deviceName() << "]"; return getNamedAudioDeviceForMode(mode, deviceName); #endif -#if defined (Q_OS_ANDROID) +#if defined(Q_OS_ANDROID) if (mode == QAudio::AudioInput) { Setting::Handle enableAEC(SETTING_AEC_KEY, DEFAULT_AEC_ENABLED); bool aecEnabled = enableAEC.get(); auto audioClient = DependencyManager::get(); - bool headsetOn = audioClient? audioClient->isHeadsetPluggedIn() : false; + bool headsetOn = audioClient ? audioClient->isHeadsetPluggedIn() : false; auto inputDevices = QAudioDeviceInfo::availableDevices(QAudio::AudioInput); for (auto inputDevice : inputDevices) { if (((headsetOn || !aecEnabled) && inputDevice.deviceName() == VOICE_RECOGNITION) || - ((!headsetOn && aecEnabled) && inputDevice.deviceName() == VOICE_COMMUNICATION)) { + ((!headsetOn && aecEnabled) && inputDevice.deviceName() == VOICE_COMMUNICATION)) { return inputDevice; } } @@ -598,10 +571,8 @@ bool AudioClient::getNamedAudioDeviceForModeExists(QAudio::Mode mode, const QStr return (getNamedAudioDeviceForMode(mode, deviceName).deviceName() == deviceName); } - // attempt to use the native sample rate and channel count bool nativeFormatForAudioDevice(const QAudioDeviceInfo& audioDevice, QAudioFormat& audioFormat) { - audioFormat = audioDevice.preferredFormat(); // converting to/from this rate must produce an integral number of samples @@ -622,7 +593,6 @@ bool nativeFormatForAudioDevice(const QAudioDeviceInfo& audioDevice, QAudioForma // attempt the native sample rate, with channels forced to 2 audioFormat.setChannelCount(2); if (!audioDevice.isFormatSupported(audioFormat)) { - // attempt the native sample rate, with channels forced to 1 audioFormat.setChannelCount(1); if (!audioDevice.isFormatSupported(audioFormat)) { @@ -636,40 +606,38 @@ bool nativeFormatForAudioDevice(const QAudioDeviceInfo& audioDevice, QAudioForma bool adjustedFormatForAudioDevice(const QAudioDeviceInfo& audioDevice, const QAudioFormat& desiredAudioFormat, QAudioFormat& adjustedAudioFormat) { - qCDebug(audioclient) << "The desired format for audio I/O is" << desiredAudioFormat; #if defined(Q_OS_WIN) if (IsWindows8OrGreater()) { // On Windows using WASAPI shared-mode, returns the internal mix format return nativeFormatForAudioDevice(audioDevice, adjustedAudioFormat); - } // else enumerate formats + } // else enumerate formats #endif - + #if defined(Q_OS_MAC) // Mac OSX returns the preferred CoreAudio format return nativeFormatForAudioDevice(audioDevice, adjustedAudioFormat); #endif - + #if defined(Q_OS_ANDROID) // As of Qt5.6, Android returns the native OpenSLES sample rate when possible, else 48000 if (nativeFormatForAudioDevice(audioDevice, adjustedAudioFormat)) { return true; - } // else enumerate formats + } // else enumerate formats #endif - + adjustedAudioFormat = desiredAudioFormat; // // Attempt the device sample rate and channel count in decreasing order of preference. // const int sampleRates[] = { 48000, 44100, 32000, 24000, 16000, 96000, 192000, 88200, 176400 }; - const int inputChannels[] = { 1, 2, 4, 6, 8 }; // prefer mono - const int outputChannels[] = { 2, 4, 6, 8, 1 }; // prefer stereo, downmix as last resort + const int inputChannels[] = { 1, 2, 4, 6, 8 }; // prefer mono + const int outputChannels[] = { 2, 4, 6, 8, 1 }; // prefer stereo, downmix as last resort for (int channelCount : (desiredAudioFormat.channelCount() == 1 ? inputChannels : outputChannels)) { for (int sampleRate : sampleRates) { - adjustedAudioFormat.setChannelCount(channelCount); adjustedAudioFormat.setSampleRate(sampleRate); @@ -679,11 +647,14 @@ bool adjustedFormatForAudioDevice(const QAudioDeviceInfo& audioDevice, } } - return false; // a supported format could not be found + return false; // a supported format could not be found } -bool sampleChannelConversion(const int16_t* sourceSamples, int16_t* destinationSamples, int numSourceSamples, - const int sourceChannelCount, const int destinationChannelCount) { +bool sampleChannelConversion(const int16_t* sourceSamples, + int16_t* destinationSamples, + int numSourceSamples, + const int sourceChannelCount, + const int destinationChannelCount) { if (sourceChannelCount == 2 && destinationChannelCount == 1) { // loop through the stereo input audio samples and average every two samples for (int i = 0; i < numSourceSamples; i += 2) { @@ -692,7 +663,6 @@ bool sampleChannelConversion(const int16_t* sourceSamples, int16_t* destinationS return true; } else if (sourceChannelCount == 1 && destinationChannelCount == 2) { - // loop through the mono input audio and repeat each sample twice for (int i = 0; i < numSourceSamples; ++i) { destinationSamples[i * 2] = destinationSamples[(i * 2) + 1] = sourceSamples[i]; @@ -705,28 +675,29 @@ bool sampleChannelConversion(const int16_t* sourceSamples, int16_t* destinationS } int possibleResampling(AudioSRC* resampler, - const int16_t* sourceSamples, int16_t* destinationSamples, - int numSourceSamples, int maxDestinationSamples, - const int sourceChannelCount, const int destinationChannelCount) { - + const int16_t* sourceSamples, + int16_t* destinationSamples, + int numSourceSamples, + int maxDestinationSamples, + const int sourceChannelCount, + const int destinationChannelCount) { int numSourceFrames = numSourceSamples / sourceChannelCount; int numDestinationFrames = 0; if (numSourceSamples > 0) { if (!resampler) { - if (!sampleChannelConversion(sourceSamples, destinationSamples, numSourceSamples, - sourceChannelCount, destinationChannelCount)) { + if (!sampleChannelConversion(sourceSamples, destinationSamples, numSourceSamples, sourceChannelCount, + destinationChannelCount)) { // no conversion, we can copy the samples directly across memcpy(destinationSamples, sourceSamples, numSourceSamples * AudioConstants::SAMPLE_SIZE); } numDestinationFrames = numSourceFrames; } else { if (sourceChannelCount != destinationChannelCount) { - int16_t* channelConversionSamples = new int16_t[numSourceFrames * destinationChannelCount]; - sampleChannelConversion(sourceSamples, channelConversionSamples, numSourceSamples, - sourceChannelCount, destinationChannelCount); + sampleChannelConversion(sourceSamples, channelConversionSamples, numSourceSamples, sourceChannelCount, + destinationChannelCount); numDestinationFrames = resampler->render(channelConversionSamples, destinationSamples, numSourceFrames); @@ -746,7 +717,6 @@ int possibleResampling(AudioSRC* resampler, } void AudioClient::start() { - // set up the desired audio format _desiredInputFormat.setSampleRate(AudioConstants::SAMPLE_RATE); _desiredInputFormat.setSampleSize(16); @@ -835,7 +805,6 @@ void AudioClient::handleAudioDataPacket(QSharedPointer message) nodeList->flagTimeForConnectionStep(LimitedNodeList::ConnectionStep::ReceiveFirstAudioPacket); if (_audioOutput) { - if (!_hasReceivedFirstPacket) { _hasReceivedFirstPacket = true; @@ -852,8 +821,8 @@ void AudioClient::handleAudioDataPacket(QSharedPointer message) } } -AudioClient::Gate::Gate(AudioClient* audioClient) : - _audioClient(audioClient) {} +AudioClient::Gate::Gate(AudioClient* audioClient) : _audioClient(audioClient) { +} void AudioClient::Gate::setIsSimulatingJitter(bool enable) { std::lock_guard lock(_mutex); @@ -906,7 +875,6 @@ void AudioClient::Gate::flush() { _index = 0; } - void AudioClient::handleNoisyMutePacket(QSharedPointer message) { if (!_muted) { setMuted(true); @@ -952,7 +920,6 @@ void AudioClient::handleSelectedAudioFormat(QSharedPointer mess } void AudioClient::selectAudioFormat(const QString& selectedCodecName) { - _selectedCodecName = selectedCodecName; qCDebug(audioclient) << "Selected Codec:" << _selectedCodecName << "isStereoInput:" << _isStereoInput; @@ -970,12 +937,12 @@ void AudioClient::selectAudioFormat(const QString& selectedCodecName) { if (_selectedCodecName == plugin->getName()) { _codec = plugin; _receivedAudioStream.setupCodec(plugin, _selectedCodecName, AudioConstants::STEREO); - _encoder = plugin->createEncoder(AudioConstants::SAMPLE_RATE, _isStereoInput ? AudioConstants::STEREO : AudioConstants::MONO); + _encoder = plugin->createEncoder(AudioConstants::SAMPLE_RATE, + _isStereoInput ? AudioConstants::STEREO : AudioConstants::MONO); qCDebug(audioclient) << "Selected Codec Plugin:" << _codec.get(); break; } } - } bool AudioClient::switchAudioDevice(QAudio::Mode mode, const QAudioDeviceInfo& deviceInfo) { @@ -987,7 +954,7 @@ bool AudioClient::switchAudioDevice(QAudio::Mode mode, const QAudioDeviceInfo& d if (mode == QAudio::AudioInput) { return switchInputToAudioDevice(device); - } else { // if (mode == QAudio::AudioOutput) + } else { // if (mode == QAudio::AudioOutput) return switchOutputToAudioDevice(device); } } @@ -1029,8 +996,8 @@ void AudioClient::configureReverb() { p.sampleRate = _outputFormat.sampleRate(); p.wetDryMix = 100.0f; p.preDelay = 0.0f; - p.earlyGain = -96.0f; // disable ER - p.lateGain += _reverbOptions->getWetDryMix() * (24.0f/100.0f) - 24.0f; // -0dB to -24dB, based on wetDryMix + p.earlyGain = -96.0f; // disable ER + p.lateGain += _reverbOptions->getWetDryMix() * (24.0f / 100.0f) - 24.0f; // -0dB to -24dB, based on wetDryMix p.lateMixLeft = 0.0f; p.lateMixRight = 0.0f; @@ -1040,7 +1007,6 @@ void AudioClient::configureReverb() { void AudioClient::updateReverbOptions() { bool reverbChanged = false; if (_receivedAudioStream.hasReverb()) { - if (_zoneReverbOptions.getReverbTime() != _receivedAudioStream.getRevebTime()) { _zoneReverbOptions.setReverbTime(_receivedAudioStream.getRevebTime()); reverbChanged = true; @@ -1110,8 +1076,8 @@ static void deinterleaveToFloat(const int16_t* src, float* const* dst, int numFr for (int i = 0; i < numFrames; i++) { for (int ch = 0; ch < numChannels; ch++) { float f = *src++; - f *= (1/32768.0f); // scale - dst[ch][i] = f; // deinterleave + f *= (1 / 32768.0f); // scale + dst[ch][i] = f; // deinterleave } } } @@ -1120,10 +1086,10 @@ static void interleaveToInt16(const float* const* src, int16_t* dst, int numFram for (int i = 0; i < numFrames; i++) { for (int ch = 0; ch < numChannels; ch++) { float f = src[ch][i]; - f *= 32768.0f; // scale - f += (f < 0.0f) ? -0.5f : 0.5f; // round - f = std::max(std::min(f, 32767.0f), -32768.0f); // saturate - *dst++ = (int16_t)f; // interleave + f *= 32768.0f; // scale + f += (f < 0.0f) ? -0.5f : 0.5f; // round + f = std::max(std::min(f, 32767.0f), -32768.0f); // saturate + *dst++ = (int16_t)f; // interleave } } } @@ -1153,7 +1119,6 @@ void AudioClient::configureWebrtc() { // rebuffer into 10ms chunks void AudioClient::processWebrtcFarEnd(const int16_t* samples, int numFrames, int numChannels, int sampleRate) { - const webrtc::StreamConfig streamConfig = webrtc::StreamConfig(sampleRate, numChannels); const int numChunk = (int)streamConfig.num_frames(); @@ -1167,7 +1132,6 @@ void AudioClient::processWebrtcFarEnd(const int16_t* samples, int numFrames, int } while (numFrames > 0) { - // number of frames to fill int numFill = std::min(numFrames, numChunk - _numFifoFarEnd); @@ -1178,7 +1142,6 @@ void AudioClient::processWebrtcFarEnd(const int16_t* samples, int numFrames, int _numFifoFarEnd += numFill; if (_numFifoFarEnd == numChunk) { - // convert audio format float buffer[WEBRTC_CHANNELS_MAX][WEBRTC_FRAMES_MAX]; float* const buffers[WEBRTC_CHANNELS_MAX] = { buffer[0], buffer[1] }; @@ -1195,7 +1158,6 @@ void AudioClient::processWebrtcFarEnd(const int16_t* samples, int numFrames, int } void AudioClient::processWebrtcNearEnd(int16_t* samples, int numFrames, int numChannels, int sampleRate) { - const webrtc::StreamConfig streamConfig = webrtc::StreamConfig(sampleRate, numChannels); const int numChunk = (int)streamConfig.num_frames(); @@ -1227,7 +1189,7 @@ void AudioClient::processWebrtcNearEnd(int16_t* samples, int numFrames, int numC } } -#endif // WEBRTC_ENABLED +#endif // WEBRTC_ENABLED void AudioClient::handleLocalEchoAndReverb(QByteArray& inputByteArray) { // If there is server echo, reverb will be applied to the recieved audio stream so no need to have it here. @@ -1254,7 +1216,8 @@ void AudioClient::handleLocalEchoAndReverb(QByteArray& inputByteArray) { // if required, create loopback resampler if (_inputFormat.sampleRate() != _outputFormat.sampleRate() && !_loopbackResampler) { - qCDebug(audioclient) << "Resampling from" << _inputFormat.sampleRate() << "to" << _outputFormat.sampleRate() << "for audio loopback."; + qCDebug(audioclient) << "Resampling from" << _inputFormat.sampleRate() << "to" << _outputFormat.sampleRate() + << "for audio loopback."; _loopbackResampler = new AudioSRC(_inputFormat.sampleRate(), _outputFormat.sampleRate(), OUTPUT_CHANNEL_COUNT); } @@ -1270,27 +1233,23 @@ void AudioClient::handleLocalEchoAndReverb(QByteArray& inputByteArray) { int16_t* inputSamples = reinterpret_cast(inputByteArray.data()); int16_t* loopbackSamples = reinterpret_cast(loopBackByteArray.data()); - int numLoopbackSamples = possibleResampling(_loopbackResampler, - inputSamples, loopbackSamples, - numInputSamples, maxLoopbackSamples, - _inputFormat.channelCount(), OUTPUT_CHANNEL_COUNT); + int numLoopbackSamples = possibleResampling(_loopbackResampler, inputSamples, loopbackSamples, numInputSamples, + maxLoopbackSamples, _inputFormat.channelCount(), OUTPUT_CHANNEL_COUNT); loopBackByteArray.resize(numLoopbackSamples * AudioConstants::SAMPLE_SIZE); // apply stereo reverb at the source, to the loopback audio if (!_shouldEchoLocally && hasReverb) { updateReverbOptions(); - _sourceReverb.render(loopbackSamples, loopbackSamples, numLoopbackSamples/2); + _sourceReverb.render(loopbackSamples, loopbackSamples, numLoopbackSamples / 2); } // if required, upmix or downmix to deviceChannelCount int deviceChannelCount = _outputFormat.channelCount(); if (deviceChannelCount == OUTPUT_CHANNEL_COUNT) { - _loopbackOutputDevice->write(loopBackByteArray); } else { - static QByteArray deviceByteArray; int numDeviceSamples = (numLoopbackSamples * deviceChannelCount) / OUTPUT_CHANNEL_COUNT; @@ -1310,7 +1269,6 @@ void AudioClient::handleLocalEchoAndReverb(QByteArray& inputByteArray) { void AudioClient::handleAudioInput(QByteArray& audioBuffer) { if (!_audioPaused) { - bool audioGateOpen = false; if (!_muted) { @@ -1364,8 +1322,7 @@ void AudioClient::handleAudioInput(QByteArray& audioBuffer) { } emitAudioPacket(encodedBuffer.data(), encodedBuffer.size(), _outgoingAvatarAudioSequenceNumber, _isStereoInput, - audioTransform, avatarBoundingBoxCorner, avatarBoundingBoxScale, - packetType, _selectedCodecName); + audioTransform, avatarBoundingBoxCorner, avatarBoundingBoxScale, packetType, _selectedCodecName); _stats.sentPacket(); } } @@ -1380,9 +1337,10 @@ void AudioClient::handleMicAudioInput() { #endif // input samples required to produce exactly NETWORK_FRAME_SAMPLES of output - const int inputSamplesRequired = (_inputToNetworkResampler ? - _inputToNetworkResampler->getMinInput(AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL) : - AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL) * _inputFormat.channelCount(); + const int inputSamplesRequired = + (_inputToNetworkResampler ? _inputToNetworkResampler->getMinInput(AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL) + : AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL) * + _inputFormat.channelCount(); const auto inputAudioSamples = std::unique_ptr(new int16_t[inputSamplesRequired]); QByteArray inputByteArray = _inputDevice->readAll(); @@ -1394,17 +1352,14 @@ void AudioClient::handleMicAudioInput() { float audioInputMsecsRead = inputByteArray.size() / (float)(_inputFormat.bytesForDuration(USECS_PER_MSEC)); _stats.updateInputMsRead(audioInputMsecsRead); - const int numNetworkBytes = _isStereoInput - ? AudioConstants::NETWORK_FRAME_BYTES_STEREO - : AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL; - const int numNetworkSamples = _isStereoInput - ? AudioConstants::NETWORK_FRAME_SAMPLES_STEREO - : AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL; + const int numNetworkBytes = + _isStereoInput ? AudioConstants::NETWORK_FRAME_BYTES_STEREO : AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL; + const int numNetworkSamples = + _isStereoInput ? AudioConstants::NETWORK_FRAME_SAMPLES_STEREO : AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL; static int16_t networkAudioSamples[AudioConstants::NETWORK_FRAME_SAMPLES_STEREO]; while (_inputRingBuffer.samplesAvailable() >= inputSamplesRequired) { - _inputRingBuffer.readSamples(inputAudioSamples.get(), inputSamplesRequired); // detect clipping on the raw input @@ -1414,7 +1369,7 @@ void AudioClient::handleMicAudioInput() { } else if (_timeSinceLastClip >= 0.0f) { _timeSinceLastClip += AudioConstants::NETWORK_FRAME_SECS; } - isClipping = (_timeSinceLastClip >= 0.0f) && (_timeSinceLastClip < 2.0f); // 2 second hold time + isClipping = (_timeSinceLastClip >= 0.0f) && (_timeSinceLastClip < 2.0f); // 2 second hold time #if defined(WEBRTC_ENABLED) if (_isAECEnabled) { @@ -1434,10 +1389,8 @@ void AudioClient::handleMicAudioInput() { emit inputLoudnessChanged(_lastSmoothedRawInputLoudness, isClipping); if (!_muted) { - possibleResampling(_inputToNetworkResampler, - inputAudioSamples.get(), networkAudioSamples, - inputSamplesRequired, numNetworkSamples, - _inputFormat.channelCount(), _desiredInputFormat.channelCount()); + possibleResampling(_inputToNetworkResampler, inputAudioSamples.get(), networkAudioSamples, inputSamplesRequired, + numNetworkSamples, _inputFormat.channelCount(), _desiredInputFormat.channelCount()); } int bytesInInputRingBuffer = _inputRingBuffer.samplesAvailable() * AudioConstants::SAMPLE_SIZE; float msecsInInputRingBuffer = bytesInInputRingBuffer / (float)(_inputFormat.bytesForDuration(USECS_PER_MSEC)); @@ -1449,11 +1402,10 @@ void AudioClient::handleMicAudioInput() { } void AudioClient::handleDummyAudioInput() { - const int numNetworkBytes = _isStereoInput - ? AudioConstants::NETWORK_FRAME_BYTES_STEREO - : AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL; + const int numNetworkBytes = + _isStereoInput ? AudioConstants::NETWORK_FRAME_BYTES_STEREO : AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL; - QByteArray audioBuffer(numNetworkBytes, 0); // silent + QByteArray audioBuffer(numNetworkBytes, 0); // silent handleAudioInput(audioBuffer); } @@ -1484,9 +1436,8 @@ void AudioClient::prepareLocalAudioInjectors(std::unique_ptr localAudioLoc int bufferCapacity = _localInjectorsStream.getSampleCapacity(); int maxOutputSamples = AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * AudioConstants::STEREO; if (_localToOutputResampler) { - maxOutputSamples = - _localToOutputResampler->getMaxOutput(AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL) * - AudioConstants::STEREO; + maxOutputSamples = _localToOutputResampler->getMaxOutput(AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL) * + AudioConstants::STEREO; } samplesNeeded = bufferCapacity - _localSamplesAvailable.load(std::memory_order_relaxed); @@ -1509,7 +1460,7 @@ void AudioClient::prepareLocalAudioInjectors(std::unique_ptr localAudioLoc if (_localToOutputResampler) { // resample to output sample rate int frames = _localToOutputResampler->render(_localMixBuffer, _localOutputMixBuffer, - AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL); + AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL); // write to local injectors' ring buffer samples = frames * AudioConstants::STEREO; @@ -1518,8 +1469,7 @@ void AudioClient::prepareLocalAudioInjectors(std::unique_ptr localAudioLoc } else { // write to local injectors' ring buffer samples = AudioConstants::NETWORK_FRAME_SAMPLES_STEREO; - _localInjectorsStream.writeSamples(_localMixBuffer, - AudioConstants::NETWORK_FRAME_SAMPLES_STEREO); + _localInjectorsStream.writeSamples(_localMixBuffer, AudioConstants::NETWORK_FRAME_SAMPLES_STEREO); } _localSamplesAvailable.fetch_add(samples, std::memory_order_release); @@ -1544,26 +1494,23 @@ bool AudioClient::mixLocalAudioInjectors(float* mixBuffer) { // the lock guarantees that injectorBuffer, if found, is invariant auto injectorBuffer = injector->getLocalBuffer(); if (injectorBuffer) { - auto options = injector->getOptions(); static const int HRTF_DATASET_INDEX = 1; - int numChannels = options.ambisonic ? AudioConstants::AMBISONIC : (options.stereo ? AudioConstants::STEREO : AudioConstants::MONO); + int numChannels = options.ambisonic ? AudioConstants::AMBISONIC + : (options.stereo ? AudioConstants::STEREO : AudioConstants::MONO); size_t bytesToRead = numChannels * AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL; // get one frame from the injector memset(_localScratchBuffer, 0, bytesToRead); if (0 < injectorBuffer->readData((char*)_localScratchBuffer, bytesToRead)) { - bool isSystemSound = !options.positionSet && !options.ambisonic; float gain = options.volume * (isSystemSound ? _systemInjectorGain : _localInjectorGain); if (options.ambisonic) { - if (options.positionSet) { - // distance attenuation glm::vec3 relativePosition = options.position - _positionGetter(); float distance = glm::max(glm::length(relativePosition), EPSILON); @@ -1583,12 +1530,10 @@ bool AudioClient::mixLocalAudioInjectors(float* mixBuffer) { float qz = relativeOrientation.y; // spatialize into mixBuffer - injector->getLocalFOA().render(_localScratchBuffer, mixBuffer, HRTF_DATASET_INDEX, - qw, qx, qy, qz, gain, AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL); + injector->getLocalFOA().render(_localScratchBuffer, mixBuffer, HRTF_DATASET_INDEX, qw, qx, qy, qz, gain, + AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL); } else if (options.stereo) { - if (options.positionSet) { - // distance attenuation glm::vec3 relativePosition = options.position - _positionGetter(); float distance = glm::max(glm::length(relativePosition), EPSILON); @@ -1598,10 +1543,9 @@ bool AudioClient::mixLocalAudioInjectors(float* mixBuffer) { // direct mix into mixBuffer injector->getLocalHRTF().mixStereo(_localScratchBuffer, mixBuffer, gain, AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL); - } else { // injector is mono + } else { // injector is mono if (options.positionSet) { - // distance attenuation glm::vec3 relativePosition = options.position - _positionGetter(); float distance = glm::max(glm::length(relativePosition), EPSILON); @@ -1610,10 +1554,9 @@ bool AudioClient::mixLocalAudioInjectors(float* mixBuffer) { float azimuth = azimuthForSource(relativePosition); // spatialize into mixBuffer - injector->getLocalHRTF().render(_localScratchBuffer, mixBuffer, HRTF_DATASET_INDEX, - azimuth, distance, gain, AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL); + injector->getLocalHRTF().render(_localScratchBuffer, mixBuffer, HRTF_DATASET_INDEX, azimuth, distance, + gain, AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL); } else { - // direct mix into mixBuffer injector->getLocalHRTF().mixMono(_localScratchBuffer, mixBuffer, gain, AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL); @@ -1621,14 +1564,12 @@ bool AudioClient::mixLocalAudioInjectors(float* mixBuffer) { } } else { - //qCDebug(audioclient) << "injector has no more data, marking finished for removal"; injector->finishLocalInjection(); injectorsToRemove.append(injector); } } else { - //qCDebug(audioclient) << "injector has no local buffer, marking as finished for removal"; injector->finishLocalInjection(); injectorsToRemove.append(injector); @@ -1647,7 +1588,6 @@ bool AudioClient::mixLocalAudioInjectors(float* mixBuffer) { } void AudioClient::processReceivedSamples(const QByteArray& decodedBuffer, QByteArray& outputBuffer) { - const int16_t* decodedSamples = reinterpret_cast(decodedBuffer.data()); assert(decodedBuffer.size() == AudioConstants::NETWORK_FRAME_BYTES_STEREO); @@ -1736,7 +1676,7 @@ void AudioClient::setAcousticEchoCancellation(bool enable, bool emitSignal) { bool AudioClient::setIsStereoInput(bool isStereoInput) { bool stereoInputChanged = false; - if (isStereoInput != _isStereoInput && _inputDeviceInfo.supportedChannelCounts().contains(2)) { + if (isStereoInput != _isStereoInput && _inputDeviceInfo.getDevice().supportedChannelCounts().contains(2)) { _isStereoInput = isStereoInput; stereoInputChanged = true; @@ -1751,12 +1691,13 @@ bool AudioClient::setIsStereoInput(bool isStereoInput) { if (_encoder) { _codec->releaseEncoder(_encoder); } - _encoder = _codec->createEncoder(AudioConstants::SAMPLE_RATE, _isStereoInput ? AudioConstants::STEREO : AudioConstants::MONO); + _encoder = _codec->createEncoder(AudioConstants::SAMPLE_RATE, + _isStereoInput ? AudioConstants::STEREO : AudioConstants::MONO); } qCDebug(audioclient) << "Reset Codec:" << _selectedCodecName << "isStereoInput:" << _isStereoInput; // restart the input device - switchInputToAudioDevice(_inputDeviceInfo); + switchInputToAudioDevice(_inputDeviceInfo.getDevice()); emit isStereoInputChanged(_isStereoInput); } @@ -1791,10 +1732,9 @@ int AudioClient::getNumLocalInjectors() { Lock lock(_injectorsMutex); return _activeLocalAudioInjectors.size(); } - void AudioClient::outputFormatChanged() { _outputFrameSize = (AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * OUTPUT_CHANNEL_COUNT * _outputFormat.sampleRate()) / - _desiredOutputFormat.sampleRate(); + _desiredOutputFormat.sampleRate(); _receivedAudioStream.outputFormatChanged(_outputFormat.sampleRate(), OUTPUT_CHANNEL_COUNT); } @@ -1808,7 +1748,7 @@ bool AudioClient::switchInputToAudioDevice(const QAudioDeviceInfo inputDeviceInf Lock lock(_deviceMutex); #if defined(Q_OS_ANDROID) - _shouldRestartInputSetup = false; // avoid a double call to _audioInput->start() from audioInputStateChanged + _shouldRestartInputSetup = false; // avoid a double call to _audioInput->start() from audioInputStateChanged #endif // cleanup any previously initialized device @@ -1823,7 +1763,7 @@ bool AudioClient::switchInputToAudioDevice(const QAudioDeviceInfo inputDeviceInf _audioInput = NULL; _numInputCallbackBytes = 0; - _inputDeviceInfo = QAudioDeviceInfo(); + _inputDeviceInfo = HifiAudioDeviceInfo(); //QAudioDeviceInfo(); } if (_dummyAudioInput) { @@ -1856,23 +1796,24 @@ bool AudioClient::switchInputToAudioDevice(const QAudioDeviceInfo inputDeviceInf if (!inputDeviceInfo.isNull()) { qCDebug(audioclient) << "The audio input device " << inputDeviceInfo.deviceName() << "is available."; - _inputDeviceInfo = inputDeviceInfo; - emit deviceChanged(QAudio::AudioInput, inputDeviceInfo); + _inputDeviceInfo = HifiAudioDeviceInfo(); + _inputDeviceInfo.setDevice(inputDeviceInfo); + emit deviceChanged(QAudio::AudioInput, _inputDeviceInfo); if (adjustedFormatForAudioDevice(inputDeviceInfo, _desiredInputFormat, _inputFormat)) { qCDebug(audioclient) << "The format to be used for audio input is" << _inputFormat; // we've got the best we can get for input // if required, setup a resampler for this input to our desired network format - if (_inputFormat != _desiredInputFormat - && _inputFormat.sampleRate() != _desiredInputFormat.sampleRate()) { + if (_inputFormat != _desiredInputFormat && _inputFormat.sampleRate() != _desiredInputFormat.sampleRate()) { qCDebug(audioclient) << "Attemping to create a resampler for input format to network format."; assert(_inputFormat.sampleSize() == 16); assert(_desiredInputFormat.sampleSize() == 16); int channelCount = (_inputFormat.channelCount() == 2 && _desiredInputFormat.channelCount() == 2) ? 2 : 1; - _inputToNetworkResampler = new AudioSRC(_inputFormat.sampleRate(), _desiredInputFormat.sampleRate(), channelCount); + _inputToNetworkResampler = + new AudioSRC(_inputFormat.sampleRate(), _desiredInputFormat.sampleRate(), channelCount); } else { qCDebug(audioclient) << "No resampling required for audio input to match desired network format."; @@ -1906,7 +1847,7 @@ bool AudioClient::switchInputToAudioDevice(const QAudioDeviceInfo inputDeviceInf connect(_inputDevice, SIGNAL(readyRead()), this, SLOT(handleMicAudioInput())); supportedFormat = true; } else { - qCDebug(audioclient) << "Error starting audio input -" << _audioInput->error(); + qCDebug(audioclient) << "Error starting audio input -" << _audioInput->error(); _audioInput->deleteLater(); _audioInput = NULL; } @@ -1919,7 +1860,7 @@ bool AudioClient::switchInputToAudioDevice(const QAudioDeviceInfo inputDeviceInf // This enables clients without a mic to still receive an audio stream from the mixer. if (!_audioInput) { qCDebug(audioclient) << "Audio input device is not available, using dummy input."; - _inputDeviceInfo = QAudioDeviceInfo(); + _inputDeviceInfo.setDevice(QAudioDeviceInfo()); emit deviceChanged(QAudio::AudioInput, _inputDeviceInfo); _inputFormat = _desiredInputFormat; @@ -1976,7 +1917,7 @@ void AudioClient::checkInputTimeout() { void AudioClient::setHeadsetPluggedIn(bool pluggedIn) { #if defined(Q_OS_ANDROID) if (pluggedIn == !_isHeadsetPluggedIn && !_inputDeviceInfo.isNull()) { - QAndroidJniObject brand = QAndroidJniObject::getStaticObjectField("android/os/Build", "BRAND"); + QAndroidJniObject brand = QAndroidJniObject::getStaticObjectField("android/os/Build", "BRAND"); // some samsung phones needs more time to shutdown the previous input device if (brand.toString().contains("samsung", Qt::CaseInsensitive)) { switchInputToAudioDevice(QAudioDeviceInfo(), true); @@ -2014,8 +1955,8 @@ void AudioClient::outputNotify() { int newOutputBufferSizeFrames = setOutputBufferSize(oldOutputBufferSizeFrames + 1, false); if (newOutputBufferSizeFrames > oldOutputBufferSizeFrames) { - qCDebug(audioclient, - "Starve threshold surpassed (%d starves in %d ms)", _outputStarveDetectionCount, dt); + qCDebug(audioclient, "Starve threshold surpassed (%d starves in %d ms)", _outputStarveDetectionCount, + dt); } _outputStarveDetectionStartTimeMsec = now; @@ -2029,7 +1970,8 @@ void AudioClient::outputNotify() { bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo outputDeviceInfo, bool isShutdownRequest) { Q_ASSERT_X(QThread::currentThread() == thread(), Q_FUNC_INFO, "Function invoked on wrong thread"); - qCDebug(audioclient) << "AudioClient::switchOutputToAudioDevice() outputDeviceInfo: [" << outputDeviceInfo.deviceName() << "]"; + qCDebug(audioclient) << "AudioClient::switchOutputToAudioDevice() outputDeviceInfo: [" << outputDeviceInfo.deviceName() + << "]"; bool supportedFormat = false; // NOTE: device start() uses the Qt internal device list @@ -2062,7 +2004,9 @@ bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo outputDeviceI delete[] _localOutputMixBuffer; _localOutputMixBuffer = NULL; - _outputDeviceInfo = QAudioDeviceInfo(); + //ctor call needed? + _outputDeviceInfo = HifiAudioDeviceInfo(); + _outputDeviceInfo.setDevice(QAudioDeviceInfo()); } // cleanup any resamplers @@ -2088,23 +2032,24 @@ bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo outputDeviceI if (!outputDeviceInfo.isNull()) { qCDebug(audioclient) << "The audio output device " << outputDeviceInfo.deviceName() << "is available."; - _outputDeviceInfo = outputDeviceInfo; - emit deviceChanged(QAudio::AudioOutput, outputDeviceInfo); + _outputDeviceInfo.setDevice(outputDeviceInfo); + emit deviceChanged(QAudio::AudioOutput, _outputDeviceInfo); if (adjustedFormatForAudioDevice(outputDeviceInfo, _desiredOutputFormat, _outputFormat)) { qCDebug(audioclient) << "The format to be used for audio output is" << _outputFormat; // we've got the best we can get for input // if required, setup a resampler for this input to our desired network format - if (_desiredOutputFormat != _outputFormat - && _desiredOutputFormat.sampleRate() != _outputFormat.sampleRate()) { + if (_desiredOutputFormat != _outputFormat && _desiredOutputFormat.sampleRate() != _outputFormat.sampleRate()) { qCDebug(audioclient) << "Attemping to create a resampler for network format to output format."; assert(_desiredOutputFormat.sampleSize() == 16); assert(_outputFormat.sampleSize() == 16); - _networkToOutputResampler = new AudioSRC(_desiredOutputFormat.sampleRate(), _outputFormat.sampleRate(), OUTPUT_CHANNEL_COUNT); - _localToOutputResampler = new AudioSRC(_desiredOutputFormat.sampleRate(), _outputFormat.sampleRate(), OUTPUT_CHANNEL_COUNT); + _networkToOutputResampler = + new AudioSRC(_desiredOutputFormat.sampleRate(), _outputFormat.sampleRate(), OUTPUT_CHANNEL_COUNT); + _localToOutputResampler = + new AudioSRC(_desiredOutputFormat.sampleRate(), _outputFormat.sampleRate(), OUTPUT_CHANNEL_COUNT); } else { qCDebug(audioclient) << "No resampling required for network output to match actual output format."; @@ -2116,7 +2061,9 @@ bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo outputDeviceI _audioOutput = new QAudioOutput(outputDeviceInfo, _outputFormat, this); int deviceChannelCount = _outputFormat.channelCount(); - int frameSize = (AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * deviceChannelCount * _outputFormat.sampleRate()) / _desiredOutputFormat.sampleRate(); + int frameSize = + (AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * deviceChannelCount * _outputFormat.sampleRate()) / + _desiredOutputFormat.sampleRate(); int requestedSize = _sessionOutputBufferSizeFrames * frameSize * AudioConstants::SAMPLE_SIZE; _audioOutput->setBufferSize(requestedSize); @@ -2137,7 +2084,9 @@ bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo outputDeviceI _outputScratchBuffer = new int16_t[_outputPeriod]; // size local output mix buffer based on resampled network frame size - int networkPeriod = _localToOutputResampler ? _localToOutputResampler->getMaxOutput(AudioConstants::NETWORK_FRAME_SAMPLES_STEREO) : AudioConstants::NETWORK_FRAME_SAMPLES_STEREO; + int networkPeriod = _localToOutputResampler + ? _localToOutputResampler->getMaxOutput(AudioConstants::NETWORK_FRAME_SAMPLES_STEREO) + : AudioConstants::NETWORK_FRAME_SAMPLES_STEREO; _localOutputMixBuffer = new float[networkPeriod]; // local period should be at least twice the output period, @@ -2180,7 +2129,8 @@ int AudioClient::setOutputBufferSize(int numFrames, bool persist) { qCDebug(audioclient) << __FUNCTION__ << "numFrames:" << numFrames << "persist:" << persist; numFrames = std::min(std::max(numFrames, MIN_BUFFER_FRAMES), MAX_BUFFER_FRAMES); - qCDebug(audioclient) << __FUNCTION__ << "clamped numFrames:" << numFrames << "_sessionOutputBufferSizeFrames:" << _sessionOutputBufferSizeFrames; + qCDebug(audioclient) << __FUNCTION__ << "clamped numFrames:" << numFrames + << "_sessionOutputBufferSizeFrames:" << _sessionOutputBufferSizeFrames; if (numFrames != _sessionOutputBufferSizeFrames) { qCInfo(audioclient, "Audio output buffer set to %d frames", numFrames); @@ -2211,10 +2161,10 @@ const float AudioClient::CALLBACK_ACCELERATOR_RATIO = 2.0f; #endif int AudioClient::calculateNumberOfInputCallbackBytes(const QAudioFormat& format) const { - int numInputCallbackBytes = (int)(((AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL - * format.channelCount() - * ((float) format.sampleRate() / AudioConstants::SAMPLE_RATE)) - / CALLBACK_ACCELERATOR_RATIO) + 0.5f); + int numInputCallbackBytes = (int)(((AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL * format.channelCount() * + ((float)format.sampleRate() / AudioConstants::SAMPLE_RATE)) / + CALLBACK_ACCELERATOR_RATIO) + + 0.5f); return numInputCallbackBytes; } @@ -2236,10 +2186,9 @@ float AudioClient::azimuthForSource(const glm::vec3& relativePosition) { float rotatedSourcePositionLength2 = glm::length2(rotatedSourcePosition); if (rotatedSourcePositionLength2 > SOURCE_DISTANCE_THRESHOLD) { - // produce an oriented angle about the y-axis glm::vec3 direction = rotatedSourcePosition * (1.0f / fastSqrtf(rotatedSourcePositionLength2)); - float angle = fastAcosf(glm::clamp(-direction.z, -1.0f, 1.0f)); // UNIT_NEG_Z is "forward" + float angle = fastAcosf(glm::clamp(-direction.z, -1.0f, 1.0f)); // UNIT_NEG_Z is "forward" return (direction.x < 0.0f) ? -angle : angle; } else { @@ -2249,7 +2198,6 @@ float AudioClient::azimuthForSource(const glm::vec3& relativePosition) { } float AudioClient::gainForSource(float distance, float volume) { - // attenuation = -6dB * log2(distance) // reference attenuation of 0dB at distance = ATTN_DISTANCE_REF float d = (1.0f / ATTN_DISTANCE_REF) * std::max(distance, HRTF_NEARFIELD_MIN); @@ -2259,8 +2207,7 @@ float AudioClient::gainForSource(float distance, float volume) { return gain; } -qint64 AudioClient::AudioOutputIODevice::readData(char * data, qint64 maxSize) { - +qint64 AudioClient::AudioOutputIODevice::readData(char* data, qint64 maxSize) { // lock-free wait for initialization to avoid races if (!_audio->_audioOutputInitialized.load(std::memory_order_acquire)) { memset(data, 0, maxSize); @@ -2279,7 +2226,8 @@ qint64 AudioClient::AudioOutputIODevice::readData(char * data, qint64 maxSize) { int samplesRequested = maxSamplesRequested; int networkSamplesPopped; if ((networkSamplesPopped = _receivedAudioStream.popSamples(samplesRequested, false)) > 0) { - qCDebug(audiostream, "Read %d samples from buffer (%d available, %d requested)", networkSamplesPopped, _receivedAudioStream.getSamplesAvailable(), samplesRequested); + qCDebug(audiostream, "Read %d samples from buffer (%d available, %d requested)", networkSamplesPopped, + _receivedAudioStream.getSamplesAvailable(), samplesRequested); AudioRingBuffer::ConstIterator lastPopOutput = _receivedAudioStream.getLastPopOutput(); lastPopOutput.readSamples(scratchBuffer, networkSamplesPopped); for (int i = 0; i < networkSamplesPopped; i++) { @@ -2311,14 +2259,13 @@ qint64 AudioClient::AudioOutputIODevice::readData(char * data, qint64 maxSize) { samplesRequested = std::min(samplesRequested, samplesAvailable); if ((injectorSamplesPopped = _localInjectorsStream.appendSamples(mixBuffer, samplesRequested, append)) > 0) { _audio->_localSamplesAvailable.fetch_sub(injectorSamplesPopped, std::memory_order_release); - qCDebug(audiostream, "Read %d samples from injectors (%d available, %d requested)", injectorSamplesPopped, _localInjectorsStream.samplesAvailable(), samplesRequested); + qCDebug(audiostream, "Read %d samples from injectors (%d available, %d requested)", injectorSamplesPopped, + _localInjectorsStream.samplesAvailable(), samplesRequested); } } // prepare injectors for the next callback - QtConcurrent::run(QThreadPool::globalInstance(), [this] { - _audio->prepareLocalAudioInjectors(); - }); + QtConcurrent::run(QThreadPool::globalInstance(), [this] { _audio->prepareLocalAudioInjectors(); }); int samplesPopped = std::max(networkSamplesPopped, injectorSamplesPopped); if (samplesPopped == 0) { @@ -2398,7 +2345,6 @@ void AudioClient::loadSettings() { for (auto& plugin : codecPlugins) { qCDebug(audioclient) << "Codec available:" << plugin->getName(); } - } void AudioClient::saveSettings() { @@ -2411,9 +2357,9 @@ void AudioClient::setAvatarBoundingBoxParameters(glm::vec3 corner, glm::vec3 sca avatarBoundingBoxScale = scale; } - void AudioClient::startThread() { - moveToNewNamedThread(this, "Audio Thread", [this] { start(); }, QThread::TimeCriticalPriority); + moveToNewNamedThread( + this, "Audio Thread", [this] { start(); }, QThread::TimeCriticalPriority); } void AudioClient::setInputVolume(float volume, bool emitSignal) { diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index ab12393ebf..fcea31a21b 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -53,18 +53,19 @@ #include "AudioIOStats.h" #include "AudioFileWav.h" +#include "HifiAudioDeviceInfo.h" #ifdef _WIN32 -#pragma warning( push ) -#pragma warning( disable : 4273 ) -#pragma warning( disable : 4305 ) +#pragma warning(push) +#pragma warning(disable : 4273) +#pragma warning(disable : 4305) #endif #ifdef _WIN32 -#pragma warning( pop ) +#pragma warning(pop) #endif -#if defined (Q_OS_ANDROID) +#if defined(Q_OS_ANDROID) #define VOICE_RECOGNITION "voicerecognition" #define VOICE_COMMUNICATION "voicecommunication" @@ -79,11 +80,14 @@ class QIODevice; class Transform; class NLPacket; + + class AudioClient : public AbstractAudioInterface, public Dependency { Q_OBJECT SINGLETON_DEPENDENCY using LocalInjectorsStream = AudioMixRingBuffer; + public: static const int MIN_BUFFER_FRAMES; static const int MAX_BUFFER_FRAMES; @@ -96,15 +100,21 @@ public: class AudioOutputIODevice : public QIODevice { public: - AudioOutputIODevice(LocalInjectorsStream& localInjectorsStream, MixedProcessedAudioStream& receivedAudioStream, - AudioClient* audio) : - _localInjectorsStream(localInjectorsStream), _receivedAudioStream(receivedAudioStream), - _audio(audio), _unfulfilledReads(0) {} + AudioOutputIODevice(LocalInjectorsStream& localInjectorsStream, + MixedProcessedAudioStream& receivedAudioStream, + AudioClient* audio) : + _localInjectorsStream(localInjectorsStream), + _receivedAudioStream(receivedAudioStream), _audio(audio), _unfulfilledReads(0) {} void start() { open(QIODevice::ReadOnly | QIODevice::Unbuffered); } - qint64 readData(char * data, qint64 maxSize) override; - qint64 writeData(const char * data, qint64 maxSize) override { return 0; } - int getRecentUnfulfilledReads() { int unfulfilledReads = _unfulfilledReads; _unfulfilledReads = 0; return unfulfilledReads; } + qint64 readData(char* data, qint64 maxSize) override; + qint64 writeData(const char* data, qint64 maxSize) override { return 0; } + int getRecentUnfulfilledReads() { + int unfulfilledReads = _unfulfilledReads; + _unfulfilledReads = 0; + return unfulfilledReads; + } + private: LocalInjectorsStream& _localInjectorsStream; MixedProcessedAudioStream& _receivedAudioStream; @@ -152,11 +162,11 @@ public: void setIsPlayingBackRecording(bool isPlayingBackRecording) { _isPlayingBackRecording = isPlayingBackRecording; } Q_INVOKABLE void setAvatarBoundingBoxParameters(glm::vec3 corner, glm::vec3 scale); - + bool outputLocalInjector(const AudioInjectorPointer& injector) override; - QAudioDeviceInfo getActiveAudioDevice(QAudio::Mode mode) const; - QList getAudioDevices(QAudio::Mode mode) const; + HifiAudioDeviceInfo getActiveAudioDevice(QAudio::Mode mode) const; + QList getAudioDevices(QAudio::Mode mode) const; void enablePeakValues(bool enable) { _enablePeakValues = enable; } bool peakValuesAvailable() const; @@ -269,10 +279,10 @@ signals: void noiseGateOpened(); void noiseGateClosed(); - void changeDevice(const QAudioDeviceInfo& outputDeviceInfo); + void changeDevice(const HifiAudioDeviceInfo& outputDeviceInfo); - void deviceChanged(QAudio::Mode mode, const QAudioDeviceInfo& device); - void devicesChanged(QAudio::Mode mode, const QList& devices); + void deviceChanged(QAudio::Mode mode, const HifiAudioDeviceInfo& device); + void devicesChanged(QAudio::Mode mode, const QList& devices); void peakValueListChanged(const QList peakValueList); void receivedFirstPacket(); @@ -345,7 +355,7 @@ private: QIODevice* _inputDevice; int _numInputCallbackBytes; QAudioOutput* _audioOutput; - std::atomic _audioOutputInitialized { false }; + std::atomic _audioOutputInitialized{ false }; QAudioFormat _desiredOutputFormat; QAudioFormat _outputFormat; int _outputFrameSize; @@ -356,11 +366,11 @@ private: LocalInjectorsStream _localInjectorsStream; // In order to use _localInjectorsStream as a lock-free pipe, // use it with a single producer/consumer, and track available samples and injectors - std::atomic _localSamplesAvailable { 0 }; - std::atomic _localInjectorsAvailable { false }; + std::atomic _localSamplesAvailable{ 0 }; + std::atomic _localInjectorsAvailable{ false }; MixedProcessedAudioStream _receivedAudioStream; bool _isStereoInput; - std::atomic _enablePeakValues { false }; + std::atomic _enablePeakValues{ false }; quint64 _outputStarveDetectionStartTimeMsec; int _outputStarveDetectionCount; @@ -371,9 +381,9 @@ private: StDev _stdev; QElapsedTimer _timeSinceLastReceived; - float _lastRawInputLoudness; // before mute/gate + float _lastRawInputLoudness; // before mute/gate float _lastSmoothedRawInputLoudness; - float _lastInputLoudness; // after mute/gate + float _lastInputLoudness; // after mute/gate float _timeSinceLastClip; int _totalInputAudioSamples; @@ -388,9 +398,9 @@ private: AudioEffectOptions _scriptReverbOptions; AudioEffectOptions _zoneReverbOptions; AudioEffectOptions* _reverbOptions; - AudioReverb _sourceReverb { AudioConstants::SAMPLE_RATE }; - AudioReverb _listenerReverb { AudioConstants::SAMPLE_RATE }; - AudioReverb _localReverb { AudioConstants::SAMPLE_RATE }; + AudioReverb _sourceReverb{ AudioConstants::SAMPLE_RATE }; + AudioReverb _listenerReverb{ AudioConstants::SAMPLE_RATE }; + AudioReverb _localReverb{ AudioConstants::SAMPLE_RATE }; // possible streams needed for resample AudioSRC* _inputToNetworkResampler; @@ -402,21 +412,21 @@ private: int16_t _networkScratchBuffer[AudioConstants::NETWORK_FRAME_SAMPLES_AMBISONIC]; // for output audio (used by this thread) - int _outputPeriod { 0 }; - float* _outputMixBuffer { NULL }; - int16_t* _outputScratchBuffer { NULL }; - std::atomic _outputGain { 1.0f }; - float _lastOutputGain { 1.0f }; + int _outputPeriod{ 0 }; + float* _outputMixBuffer{ NULL }; + int16_t* _outputScratchBuffer{ NULL }; + std::atomic _outputGain{ 1.0f }; + float _lastOutputGain{ 1.0f }; // for local audio (used by audio injectors thread) - std::atomic _localInjectorGain { 1.0f }; - std::atomic _systemInjectorGain { 1.0f }; + std::atomic _localInjectorGain{ 1.0f }; + std::atomic _systemInjectorGain{ 1.0f }; float _localMixBuffer[AudioConstants::NETWORK_FRAME_SAMPLES_STEREO]; int16_t _localScratchBuffer[AudioConstants::NETWORK_FRAME_SAMPLES_AMBISONIC]; - float* _localOutputMixBuffer { NULL }; + float* _localOutputMixBuffer{ NULL }; Mutex _localAudioMutex; AudioLimiter _audioLimiter; - + // Adds Reverb void configureReverb(); void updateReverbOptions(); @@ -427,10 +437,10 @@ private: static const int WEBRTC_CHANNELS_MAX = 2; static const int WEBRTC_FRAMES_MAX = webrtc::AudioProcessing::kChunkSizeMs * WEBRTC_SAMPLE_RATE_MAX / 1000; - webrtc::AudioProcessing* _apm { nullptr }; + webrtc::AudioProcessing* _apm{ nullptr }; - int16_t _fifoFarEnd[WEBRTC_CHANNELS_MAX * WEBRTC_FRAMES_MAX] {}; - int _numFifoFarEnd = 0; // numFrames saved in fifo + int16_t _fifoFarEnd[WEBRTC_CHANNELS_MAX * WEBRTC_FRAMES_MAX]{}; + int _numFifoFarEnd = 0; // numFrames saved in fifo void configureWebrtc(); void processWebrtcFarEnd(const int16_t* samples, int numFrames, int numChannels, int sampleRate); @@ -450,8 +460,8 @@ private: AudioIOStats _stats; - AudioGate* _audioGate { nullptr }; - bool _audioGateOpen { true }; + AudioGate* _audioGate{ nullptr }; + bool _audioGateOpen{ true }; AudioPositionGetter _positionGetter; AudioOrientationGetter _orientationGetter; @@ -459,24 +469,30 @@ private: glm::vec3 avatarBoundingBoxCorner; glm::vec3 avatarBoundingBoxScale; - QAudioDeviceInfo _inputDeviceInfo; - QAudioDeviceInfo _outputDeviceInfo; + HifiAudioDeviceInfo _inputDeviceInfo; + HifiAudioDeviceInfo _outputDeviceInfo; - QList _inputDevices; - QList _outputDevices; + QList _inputDevices; + QList _outputDevices; + + //QAudioDeviceInfo _inputDeviceInfo; + // QAudioDeviceInfo _outputDeviceInfo; + + // QList _inputDevices; + /// QList _outputDevices; AudioFileWav _audioFileWav; - bool _hasReceivedFirstPacket { false }; + bool _hasReceivedFirstPacket{ false }; QVector _activeLocalAudioInjectors; - bool _isPlayingBackRecording { false }; - bool _audioPaused { false }; + bool _isPlayingBackRecording{ false }; + bool _audioPaused{ false }; CodecPluginPointer _codec; QString _selectedCodecName; - Encoder* _encoder { nullptr }; // for outbound mic stream + Encoder* _encoder{ nullptr }; // for outbound mic stream RateCounter<> _silentOutbound; RateCounter<> _audioOutbound; @@ -484,18 +500,17 @@ private: RateCounter<> _audioInbound; #if defined(Q_OS_ANDROID) - bool _shouldRestartInputSetup { true }; // Should we restart the input device because of an unintended stop? + bool _shouldRestartInputSetup{ true }; // Should we restart the input device because of an unintended stop? #endif AudioSolo _solo; - - Mutex _checkDevicesMutex; - QTimer* _checkDevicesTimer { nullptr }; - Mutex _checkPeakValuesMutex; - QTimer* _checkPeakValuesTimer { nullptr }; - bool _isRecording { false }; + Mutex _checkDevicesMutex; + QTimer* _checkDevicesTimer{ nullptr }; + Mutex _checkPeakValuesMutex; + QTimer* _checkPeakValuesTimer{ nullptr }; + + bool _isRecording{ false }; }; - -#endif // hifi_AudioClient_h +#endif // hifi_AudioClient_h diff --git a/libraries/ui/src/ui/OffscreenQmlSurface.cpp b/libraries/ui/src/ui/OffscreenQmlSurface.cpp index 8beca598a2..5dfdce0c63 100644 --- a/libraries/ui/src/ui/OffscreenQmlSurface.cpp +++ b/libraries/ui/src/ui/OffscreenQmlSurface.cpp @@ -356,7 +356,7 @@ void OffscreenQmlSurface::onRootCreated() { getSurfaceContext()->setContextProperty("offscreenWindow", QVariant::fromValue(getWindow())); // Connect with the audio client and listen for audio device changes - connect(DependencyManager::get().data(), &AudioClient::deviceChanged, this, [this](QAudio::Mode mode, const QAudioDeviceInfo& device) { + connect(DependencyManager::get().data(), &AudioClient::deviceChanged, this, [this](QAudio::Mode mode, const HifiAudioDeviceInfo& device) { if (mode == QAudio::Mode::AudioOutput) { QMetaObject::invokeMethod(this, "changeAudioOutputDevice", Qt::QueuedConnection, Q_ARG(QString, device.deviceName())); } From 4fb31ad4792f90092f3b1f29f3f4fa9f2a9bd010 Mon Sep 17 00:00:00 2001 From: amerhifi Date: Fri, 13 Sep 2019 12:29:46 -0700 Subject: [PATCH 03/27] rebuilding the lost file :(. also undoing the postbuild script changes that were part on my last test --- .../audio-client/src/HifiAudioDeviceInfo.h | 47 +++++++++++++++++++ .../audio-client/src/HifiAudioDeviceinfo.cpp | 16 +++++++ tools/ci-scripts/postbuild.py | 3 +- 3 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 libraries/audio-client/src/HifiAudioDeviceInfo.h create mode 100644 libraries/audio-client/src/HifiAudioDeviceinfo.cpp diff --git a/libraries/audio-client/src/HifiAudioDeviceInfo.h b/libraries/audio-client/src/HifiAudioDeviceInfo.h new file mode 100644 index 0000000000..5155807b51 --- /dev/null +++ b/libraries/audio-client/src/HifiAudioDeviceInfo.h @@ -0,0 +1,47 @@ +#ifndef hifi_audiodeviceinfo_h +#define hifi_audiodeviceinfo_h + +#include +#include +#include +#include + +class HifiAudioDeviceInfo : public QObject { + QObject + +public: + HifiAudioDeviceInfo() {} + HifiAudioDeviceInfo(const HifiAudioDeviceInfo &deviceInfo){ + _audioDeviceInfo = deviceInfo.getDevice(); + _mode = deviceInfo.getMode(); + _deviceName = deviceInfo.deviceName(); + _isDefault = deviceInfo.isDefault(); + } + + HifiAudioDeviceInfo(QAudioDeviceInfo deviceInfo, bool isDefault, QAudio::Mode mode) : + _audioDeviceInfo(deviceInfo), + _isDefault(isDefault), + _mode(mode) { + setDeviceName(); + } + + void setMode(QAudio::Mode mode); + void setIsDefault(bool isDefault = false); + void setDeviceName(QString name); + + QAudioDeviceInfo getDevice() const { return _audioDeviceInfo; } + QString deviceName() const { return _deviceName; } + bool isDefault() const { return isDefault; } + QAudio::Mode getMode() const { return _mode; } + +private: + void setDeviceName(); + +private: + QAudioDeviceInfo _audioDeviceInfo; + QString _deviceName; + bool _isDefault; + QAudio::Mode _mode; +}; + +#endif \ No newline at end of file diff --git a/libraries/audio-client/src/HifiAudioDeviceinfo.cpp b/libraries/audio-client/src/HifiAudioDeviceinfo.cpp new file mode 100644 index 0000000000..066e8e6962 --- /dev/null +++ b/libraries/audio-client/src/HifiAudioDeviceinfo.cpp @@ -0,0 +1,16 @@ +#include "HifiAudioDeviceInfo.h" + +void HifiAudioDeviceInfo::setMode(QAudio::Mode mode) { +} + +void HifiAudioDeviceInfo::setIsDefault(bool isDefault) { +} + +void HifiAudioDeviceInfo::setDeviceName(QString name) { + +} + + void HifiAudioDeviceInfo::setDeviceName() { + + + } \ No newline at end of file diff --git a/tools/ci-scripts/postbuild.py b/tools/ci-scripts/postbuild.py index 8e165f05b7..b93ed5a664 100644 --- a/tools/ci-scripts/postbuild.py +++ b/tools/ci-scripts/postbuild.py @@ -220,8 +220,7 @@ cpackCommand = [ 'cpack', '-G', 'ZIP', '-D', "CPACK_PACKAGE_FILE_NAME={}".format(archiveName), - '-D', "CPACK_INCLUDE_TOPLEVEL_DIRECTORY=OFF", - '-D', "CPACK_RPM_COMPRESSION_TYPE=lzma" + '-D', "CPACK_INCLUDE_TOPLEVEL_DIRECTORY=OFF" ] print("Create ZIP version of installer archive") From bdfb82c072d487a939ff9f3fae801a176f4cef7d Mon Sep 17 00:00:00 2001 From: amerhifi Date: Fri, 13 Sep 2019 13:13:54 -0700 Subject: [PATCH 04/27] finishing up the wrapper code implementation. --- libraries/audio-client/src/AudioClient.cpp | 2 +- .../audio-client/src/HifiAudioDeviceInfo.h | 26 +++++++++++++++++-- .../audio-client/src/HifiAudioDeviceinfo.cpp | 21 ++++++++++----- 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 195afc619c..e40c91e541 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -1763,7 +1763,7 @@ bool AudioClient::switchInputToAudioDevice(const QAudioDeviceInfo inputDeviceInf _audioInput = NULL; _numInputCallbackBytes = 0; - _inputDeviceInfo = HifiAudioDeviceInfo(); //QAudioDeviceInfo(); + _inputDeviceInfo = HifiAudioDeviceInfo(); } if (_dummyAudioInput) { diff --git a/libraries/audio-client/src/HifiAudioDeviceInfo.h b/libraries/audio-client/src/HifiAudioDeviceInfo.h index 5155807b51..6a6ca602f8 100644 --- a/libraries/audio-client/src/HifiAudioDeviceInfo.h +++ b/libraries/audio-client/src/HifiAudioDeviceInfo.h @@ -7,7 +7,7 @@ #include class HifiAudioDeviceInfo : public QObject { - QObject + Q_OBJECT public: HifiAudioDeviceInfo() {} @@ -28,12 +28,34 @@ public: void setMode(QAudio::Mode mode); void setIsDefault(bool isDefault = false); void setDeviceName(QString name); + void setDevice(QAudioDeviceInfo devInfo) { + _audioDeviceInfo = devInfo; + setDeviceName(); + } QAudioDeviceInfo getDevice() const { return _audioDeviceInfo; } QString deviceName() const { return _deviceName; } - bool isDefault() const { return isDefault; } + bool isDefault() const { return _isDefault; } QAudio::Mode getMode() const { return _mode; } + + HifiAudioDeviceInfo& operator=(const HifiAudioDeviceInfo& other) { + _audioDeviceInfo = other.getDevice(); + _deviceName = other.deviceName(); + _mode = other.getMode(); + _isDefault = other.isDefault(); + return *this; + } + + bool operator==(const HifiAudioDeviceInfo& rhs) const { + return _audioDeviceInfo == rhs.getDevice(); + } + + bool operator!=(const HifiAudioDeviceInfo& rhs) const { + return _audioDeviceInfo != rhs.getDevice(); + } + + private: void setDeviceName(); diff --git a/libraries/audio-client/src/HifiAudioDeviceinfo.cpp b/libraries/audio-client/src/HifiAudioDeviceinfo.cpp index 066e8e6962..3052f950d8 100644 --- a/libraries/audio-client/src/HifiAudioDeviceinfo.cpp +++ b/libraries/audio-client/src/HifiAudioDeviceinfo.cpp @@ -1,16 +1,25 @@ #include "HifiAudioDeviceInfo.h" void HifiAudioDeviceInfo::setMode(QAudio::Mode mode) { + _mode = mode; + setDeviceName(); } void HifiAudioDeviceInfo::setIsDefault(bool isDefault) { -} - -void HifiAudioDeviceInfo::setDeviceName(QString name) { - + isDefault = isDefault; + setDeviceName(); } void HifiAudioDeviceInfo::setDeviceName() { + if (isDefault) { + if (_mode == QAudio::Mode::AudioInput) { + _deviceName = "Default microphone (recommended)"; + } else { + _deviceName = "Default audio (recommended)"; + } + } else { + _deviceName = _audioDeviceInfo.deviceName(); + } + } - - } \ No newline at end of file + \ No newline at end of file From 0de7628d48c27a7395c87ad93ea3032482f06bc0 Mon Sep 17 00:00:00 2001 From: amerhifi Date: Fri, 13 Sep 2019 13:19:32 -0700 Subject: [PATCH 05/27] fix typo --- libraries/audio-client/src/HifiAudioDeviceinfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/audio-client/src/HifiAudioDeviceinfo.cpp b/libraries/audio-client/src/HifiAudioDeviceinfo.cpp index 3052f950d8..8802064423 100644 --- a/libraries/audio-client/src/HifiAudioDeviceinfo.cpp +++ b/libraries/audio-client/src/HifiAudioDeviceinfo.cpp @@ -11,7 +11,7 @@ void HifiAudioDeviceInfo::setIsDefault(bool isDefault) { } void HifiAudioDeviceInfo::setDeviceName() { - if (isDefault) { + if (_isDefault) { if (_mode == QAudio::Mode::AudioInput) { _deviceName = "Default microphone (recommended)"; } else { From 68cd8cc8a61beb762889add1fd9a17317ba88a23 Mon Sep 17 00:00:00 2001 From: amerhifi Date: Mon, 16 Sep 2019 10:32:22 -0700 Subject: [PATCH 06/27] getting wrapper to correctly detect default and fixed clang formatting changes by vs19 --- libraries/audio-client/src/AudioClient.cpp | 28 +++++--- libraries/audio-client/src/AudioClient.h | 68 ++++++++++--------- .../audio-client/src/HifiAudioDeviceinfo.cpp | 2 +- 3 files changed, 56 insertions(+), 42 deletions(-) diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index e40c91e541..cc5c9524e4 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -89,6 +89,7 @@ using Mutex = std::mutex; using Lock = std::unique_lock; Mutex _deviceMutex; Mutex _recordMutex; +QAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode); // thread-safe QList getAvailableDevices(QAudio::Mode mode) { @@ -97,16 +98,9 @@ QList getAvailableDevices(QAudio::Mode mode) { auto devices = QAudioDeviceInfo::availableDevices(mode); QList newDevices; - QAudioDeviceInfo::defaultOutputDevice(); for (auto& device : devices) { - bool isDefault = false; - if (mode == QAudio::Mode::AudioInput) { - isDefault = device == QAudioDeviceInfo::defaultInputDevice(); - } else { - isDefault = device == QAudioDeviceInfo::defaultOutputDevice(); - } - newDevices.push_back(HifiAudioDeviceInfo(device, isDefault, mode)); + newDevices.push_back(HifiAudioDeviceInfo(device, false, mode)); } return newDevices; @@ -124,6 +118,9 @@ void AudioClient::checkDevices() { auto inputDevices = getAvailableDevices(QAudio::AudioInput); auto outputDevices = getAvailableDevices(QAudio::AudioOutput); + QMetaObject::invokeMethod(this, "setDefaultDevice", Qt::BlockingQueuedConnection, Q_ARG(QList&, inputDevices), Q_ARG(QAudio::Mode, QAudio::AudioInput)); + QMetaObject::invokeMethod(this, "setDefaultDevice", Qt::BlockingQueuedConnection, Q_ARG(QList&, outputDevices), Q_ARG(QAudio::Mode, QAudio::AudioOutput)); + Lock lock(_deviceMutex); if (inputDevices != _inputDevices) { _inputDevices.swap(inputDevices); @@ -409,6 +406,21 @@ void AudioClient::setAudioPaused(bool pause) { } } +void AudioClient::setDefaultDevice(QList& devices ,QAudio::Mode mode) { + QAudioDeviceInfo defDevice = defaultAudioDeviceForMode(mode); + for (auto& device : devices) { + if (device.getDevice() == defDevice) { + if (!device.isDefault()) { + device.setIsDefault(true); + } + } else { + if (device.isDefault()) { + device.setIsDefault(false); + } + } + } +} + QAudioDeviceInfo getNamedAudioDeviceForMode(QAudio::Mode mode, const QString& deviceName) { QAudioDeviceInfo result; foreach (HifiAudioDeviceInfo audioDevice, getAvailableDevices(mode)) { diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index fcea31a21b..eb6ebb9339 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -56,13 +56,13 @@ #include "HifiAudioDeviceInfo.h" #ifdef _WIN32 -#pragma warning(push) -#pragma warning(disable : 4273) -#pragma warning(disable : 4305) +#pragma warning( push ) +#pragma warning( disable : 4273 ) +#pragma warning( disable : 4305 ) #endif #ifdef _WIN32 -#pragma warning(pop) +#pragma warning( pop ) #endif #if defined(Q_OS_ANDROID) @@ -121,7 +121,7 @@ public: AudioClient* _audio; int _unfulfilledReads; }; - + void startThread(); void negotiateAudioFormat(); void selectAudioFormat(const QString& selectedCodecName); @@ -132,6 +132,7 @@ public: Q_INVOKABLE float getAudioInboundPPS() const { return _audioInbound.rate(); } Q_INVOKABLE float getSilentOutboundPPS() const { return _silentOutbound.rate(); } Q_INVOKABLE float getAudioOutboundPPS() const { return _audioOutbound.rate(); } + Q_INVOKABLE void setDefaultDevice(QList& devices, QAudio::Mode mode); const MixedProcessedAudioStream& getReceivedAudioStream() const { return _receivedAudioStream; } MixedProcessedAudioStream& getReceivedAudioStream() { return _receivedAudioStream; } @@ -167,7 +168,7 @@ public: HifiAudioDeviceInfo getActiveAudioDevice(QAudio::Mode mode) const; QList getAudioDevices(QAudio::Mode mode) const; - + void enablePeakValues(bool enable) { _enablePeakValues = enable; } bool peakValuesAvailable() const; @@ -181,6 +182,7 @@ public: bool startRecording(const QString& filename); void stopRecording(); void setAudioPaused(bool pause); + AudioSolo& getAudioSolo() override { return _solo; } @@ -355,7 +357,7 @@ private: QIODevice* _inputDevice; int _numInputCallbackBytes; QAudioOutput* _audioOutput; - std::atomic _audioOutputInitialized{ false }; + std::atomic _audioOutputInitialized { false }; QAudioFormat _desiredOutputFormat; QAudioFormat _outputFormat; int _outputFrameSize; @@ -366,11 +368,11 @@ private: LocalInjectorsStream _localInjectorsStream; // In order to use _localInjectorsStream as a lock-free pipe, // use it with a single producer/consumer, and track available samples and injectors - std::atomic _localSamplesAvailable{ 0 }; - std::atomic _localInjectorsAvailable{ false }; + std::atomic _localSamplesAvailable { 0 }; + std::atomic _localInjectorsAvailable { false }; MixedProcessedAudioStream _receivedAudioStream; bool _isStereoInput; - std::atomic _enablePeakValues{ false }; + std::atomic _enablePeakValues { false }; quint64 _outputStarveDetectionStartTimeMsec; int _outputStarveDetectionCount; @@ -398,9 +400,9 @@ private: AudioEffectOptions _scriptReverbOptions; AudioEffectOptions _zoneReverbOptions; AudioEffectOptions* _reverbOptions; - AudioReverb _sourceReverb{ AudioConstants::SAMPLE_RATE }; - AudioReverb _listenerReverb{ AudioConstants::SAMPLE_RATE }; - AudioReverb _localReverb{ AudioConstants::SAMPLE_RATE }; + AudioReverb _sourceReverb { AudioConstants::SAMPLE_RATE }; + AudioReverb _listenerReverb { AudioConstants::SAMPLE_RATE }; + AudioReverb _localReverb { AudioConstants::SAMPLE_RATE }; // possible streams needed for resample AudioSRC* _inputToNetworkResampler; @@ -412,18 +414,18 @@ private: int16_t _networkScratchBuffer[AudioConstants::NETWORK_FRAME_SAMPLES_AMBISONIC]; // for output audio (used by this thread) - int _outputPeriod{ 0 }; - float* _outputMixBuffer{ NULL }; - int16_t* _outputScratchBuffer{ NULL }; - std::atomic _outputGain{ 1.0f }; - float _lastOutputGain{ 1.0f }; + int _outputPeriod { 0 }; + float* _outputMixBuffer { NULL }; + int16_t* _outputScratchBuffer { NULL }; + std::atomic _outputGain { 1.0f }; + float _lastOutputGain { 1.0f }; // for local audio (used by audio injectors thread) - std::atomic _localInjectorGain{ 1.0f }; - std::atomic _systemInjectorGain{ 1.0f }; + std::atomic _localInjectorGain { 1.0f }; + std::atomic _systemInjectorGain { 1.0f }; float _localMixBuffer[AudioConstants::NETWORK_FRAME_SAMPLES_STEREO]; int16_t _localScratchBuffer[AudioConstants::NETWORK_FRAME_SAMPLES_AMBISONIC]; - float* _localOutputMixBuffer{ NULL }; + float* _localOutputMixBuffer { NULL }; Mutex _localAudioMutex; AudioLimiter _audioLimiter; @@ -437,9 +439,9 @@ private: static const int WEBRTC_CHANNELS_MAX = 2; static const int WEBRTC_FRAMES_MAX = webrtc::AudioProcessing::kChunkSizeMs * WEBRTC_SAMPLE_RATE_MAX / 1000; - webrtc::AudioProcessing* _apm{ nullptr }; + webrtc::AudioProcessing* _apm { nullptr }; - int16_t _fifoFarEnd[WEBRTC_CHANNELS_MAX * WEBRTC_FRAMES_MAX]{}; + int16_t _fifoFarEnd[WEBRTC_CHANNELS_MAX * WEBRTC_FRAMES_MAX] {}; int _numFifoFarEnd = 0; // numFrames saved in fifo void configureWebrtc(); @@ -460,8 +462,8 @@ private: AudioIOStats _stats; - AudioGate* _audioGate{ nullptr }; - bool _audioGateOpen{ true }; + AudioGate* _audioGate { nullptr }; + bool _audioGateOpen { true }; AudioPositionGetter _positionGetter; AudioOrientationGetter _orientationGetter; @@ -483,16 +485,16 @@ private: AudioFileWav _audioFileWav; - bool _hasReceivedFirstPacket{ false }; + bool _hasReceivedFirstPacket { false }; QVector _activeLocalAudioInjectors; - bool _isPlayingBackRecording{ false }; - bool _audioPaused{ false }; + bool _isPlayingBackRecording { false }; + bool _audioPaused { false }; CodecPluginPointer _codec; QString _selectedCodecName; - Encoder* _encoder{ nullptr }; // for outbound mic stream + Encoder* _encoder { nullptr }; // for outbound mic stream RateCounter<> _silentOutbound; RateCounter<> _audioOutbound; @@ -500,17 +502,17 @@ private: RateCounter<> _audioInbound; #if defined(Q_OS_ANDROID) - bool _shouldRestartInputSetup{ true }; // Should we restart the input device because of an unintended stop? + bool _shouldRestartInputSetup { true }; // Should we restart the input device because of an unintended stop? #endif AudioSolo _solo; Mutex _checkDevicesMutex; - QTimer* _checkDevicesTimer{ nullptr }; + QTimer* _checkDevicesTimer { nullptr }; Mutex _checkPeakValuesMutex; - QTimer* _checkPeakValuesTimer{ nullptr }; + QTimer* _checkPeakValuesTimer { nullptr }; - bool _isRecording{ false }; + bool _isRecording { false }; }; #endif // hifi_AudioClient_h diff --git a/libraries/audio-client/src/HifiAudioDeviceinfo.cpp b/libraries/audio-client/src/HifiAudioDeviceinfo.cpp index 8802064423..3d40d418fc 100644 --- a/libraries/audio-client/src/HifiAudioDeviceinfo.cpp +++ b/libraries/audio-client/src/HifiAudioDeviceinfo.cpp @@ -6,7 +6,7 @@ void HifiAudioDeviceInfo::setMode(QAudio::Mode mode) { } void HifiAudioDeviceInfo::setIsDefault(bool isDefault) { - isDefault = isDefault; + _isDefault = isDefault; setDeviceName(); } From aa6cf466d97340570f67ca36619cb29cce729466 Mon Sep 17 00:00:00 2001 From: amerhifi Date: Mon, 16 Sep 2019 11:52:04 -0700 Subject: [PATCH 07/27] fixing jenkins warning. Added pseudo device and fixed issues with names --- libraries/audio-client/src/AudioClient.cpp | 20 ++++++- libraries/audio-client/src/AudioClient.h | 4 +- .../audio-client/src/HifiAudioDeviceInfo.h | 52 +++++++------------ .../audio-client/src/HifiAudioDeviceinfo.cpp | 33 ++++++------ 4 files changed, 54 insertions(+), 55 deletions(-) diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index cc5c9524e4..0f356c70a8 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -118,8 +118,9 @@ void AudioClient::checkDevices() { auto inputDevices = getAvailableDevices(QAudio::AudioInput); auto outputDevices = getAvailableDevices(QAudio::AudioOutput); - QMetaObject::invokeMethod(this, "setDefaultDevice", Qt::BlockingQueuedConnection, Q_ARG(QList&, inputDevices), Q_ARG(QAudio::Mode, QAudio::AudioInput)); - QMetaObject::invokeMethod(this, "setDefaultDevice", Qt::BlockingQueuedConnection, Q_ARG(QList&, outputDevices), Q_ARG(QAudio::Mode, QAudio::AudioOutput)); + //add the pseudo device to the list of devices + inputDevices.push_front(_defaultInputDevice); + outputDevices.push_front(_defaultOutputDevice); Lock lock(_deviceMutex); if (inputDevices != _inputDevices) { @@ -308,6 +309,21 @@ AudioClient::AudioClient() : connect(&_receivedAudioStream, &InboundAudioStream::mismatchedAudioCodec, this, &AudioClient::handleMismatchAudioFormat); + + _defaultOutputDevice = HifiAudioDeviceInfo(); + _defaultOutputDevice.setDevice(defaultAudioDeviceForMode(QAudio::AudioOutput)); + _defaultOutputDevice.setDeviceName("Default audio (recommended)"); + _defaultOutputDevice.setIsDefault(true); + _defaultOutputDevice.setMode(QAudio::AudioOutput); + + + _defaultInputDevice = HifiAudioDeviceInfo(); + _defaultInputDevice.setDevice(defaultAudioDeviceForMode(QAudio::AudioInput)); + _defaultInputDevice.setDeviceName("Default microphone (recommended)"); + _defaultInputDevice.setIsDefault(true); + _defaultInputDevice.setMode(QAudio::AudioOutput); + + // initialize wasapi; if getAvailableDevices is called from the CheckDevicesThread before this, it will crash getAvailableDevices(QAudio::AudioInput); getAvailableDevices(QAudio::AudioOutput); diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index eb6ebb9339..15f0772dc3 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -182,7 +182,6 @@ public: bool startRecording(const QString& filename); void stopRecording(); void setAudioPaused(bool pause); - AudioSolo& getAudioSolo() override { return _solo; } @@ -474,6 +473,9 @@ private: HifiAudioDeviceInfo _inputDeviceInfo; HifiAudioDeviceInfo _outputDeviceInfo; + HifiAudioDeviceInfo _defaultInputDevice; + HifiAudioDeviceInfo _defaultOutputDevice; + QList _inputDevices; QList _outputDevices; diff --git a/libraries/audio-client/src/HifiAudioDeviceInfo.h b/libraries/audio-client/src/HifiAudioDeviceInfo.h index 6a6ca602f8..d2a349ed8c 100644 --- a/libraries/audio-client/src/HifiAudioDeviceInfo.h +++ b/libraries/audio-client/src/HifiAudioDeviceInfo.h @@ -10,7 +10,7 @@ class HifiAudioDeviceInfo : public QObject { Q_OBJECT public: - HifiAudioDeviceInfo() {} + HifiAudioDeviceInfo() : QObject() {} HifiAudioDeviceInfo(const HifiAudioDeviceInfo &deviceInfo){ _audioDeviceInfo = deviceInfo.getDevice(); _mode = deviceInfo.getMode(); @@ -19,51 +19,35 @@ public: } HifiAudioDeviceInfo(QAudioDeviceInfo deviceInfo, bool isDefault, QAudio::Mode mode) : - _audioDeviceInfo(deviceInfo), - _isDefault(isDefault), - _mode(mode) { - setDeviceName(); + _isDefault(isDefault), + _mode(mode), + _audioDeviceInfo(deviceInfo), + _deviceName(deviceInfo.deviceName()){ } - void setMode(QAudio::Mode mode); - void setIsDefault(bool isDefault = false); - void setDeviceName(QString name); - void setDevice(QAudioDeviceInfo devInfo) { - _audioDeviceInfo = devInfo; - setDeviceName(); + void setMode(QAudio::Mode mode) { _mode = mode; } + void setIsDefault(bool isDefault = false) { _isDefault = isDefault; } + + void setDeviceName(QString name) { + _deviceName = name; } + void setDevice(QAudioDeviceInfo devInfo); + QAudioDeviceInfo getDevice() const { return _audioDeviceInfo; } QString deviceName() const { return _deviceName; } bool isDefault() const { return _isDefault; } QAudio::Mode getMode() const { return _mode; } - - HifiAudioDeviceInfo& operator=(const HifiAudioDeviceInfo& other) { - _audioDeviceInfo = other.getDevice(); - _deviceName = other.deviceName(); - _mode = other.getMode(); - _isDefault = other.isDefault(); - return *this; - } - - bool operator==(const HifiAudioDeviceInfo& rhs) const { - return _audioDeviceInfo == rhs.getDevice(); - } - - bool operator!=(const HifiAudioDeviceInfo& rhs) const { - return _audioDeviceInfo != rhs.getDevice(); - } - - -private: - void setDeviceName(); + HifiAudioDeviceInfo& operator=(const HifiAudioDeviceInfo& other); + bool operator==(const HifiAudioDeviceInfo& rhs) const; + bool operator!=(const HifiAudioDeviceInfo& rhs) const; private: QAudioDeviceInfo _audioDeviceInfo; - QString _deviceName; - bool _isDefault; - QAudio::Mode _mode; + QString _deviceName{ "" }; + bool _isDefault { false }; + QAudio::Mode _mode { QAudio::AudioInput }; }; #endif \ No newline at end of file diff --git a/libraries/audio-client/src/HifiAudioDeviceinfo.cpp b/libraries/audio-client/src/HifiAudioDeviceinfo.cpp index 3d40d418fc..91a6324c26 100644 --- a/libraries/audio-client/src/HifiAudioDeviceinfo.cpp +++ b/libraries/audio-client/src/HifiAudioDeviceinfo.cpp @@ -1,25 +1,22 @@ #include "HifiAudioDeviceInfo.h" -void HifiAudioDeviceInfo::setMode(QAudio::Mode mode) { - _mode = mode; - setDeviceName(); +void HifiAudioDeviceInfo::setDevice(QAudioDeviceInfo devInfo) { + _audioDeviceInfo = devInfo; } -void HifiAudioDeviceInfo::setIsDefault(bool isDefault) { - _isDefault = isDefault; - setDeviceName(); +HifiAudioDeviceInfo& HifiAudioDeviceInfo::operator=(const HifiAudioDeviceInfo& other) { + _audioDeviceInfo = other.getDevice(); + _deviceName = other.deviceName(); + _mode = other.getMode(); + _isDefault = other.isDefault(); + return *this; } - void HifiAudioDeviceInfo::setDeviceName() { - if (_isDefault) { - if (_mode == QAudio::Mode::AudioInput) { - _deviceName = "Default microphone (recommended)"; - } else { - _deviceName = "Default audio (recommended)"; - } - } else { - _deviceName = _audioDeviceInfo.deviceName(); - } - } +bool HifiAudioDeviceInfo::operator==(const HifiAudioDeviceInfo& rhs) const { + return _audioDeviceInfo == rhs.getDevice(); +} + +bool HifiAudioDeviceInfo::operator!=(const HifiAudioDeviceInfo& rhs) const { + return _audioDeviceInfo != rhs.getDevice(); +} - \ No newline at end of file From 92d1f7bdcba91a4926decf9786ccef52b4191287 Mon Sep 17 00:00:00 2001 From: amerhifi Date: Mon, 16 Sep 2019 13:09:14 -0700 Subject: [PATCH 08/27] removed clang formatting issues :" --- libraries/audio-client/src/AudioClient.cpp | 324 +++++++++++++-------- libraries/audio-client/src/AudioClient.h | 27 +- 2 files changed, 204 insertions(+), 147 deletions(-) diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 0f356c70a8..8609b9585a 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -67,7 +67,7 @@ static const int CHECK_INPUT_READS_MSECS = 2000; static const int MIN_READS_TO_CONSIDER_INPUT_ALIVE = 10; #endif -static const auto DEFAULT_POSITION_GETTER = [] { return Vectors::ZERO; }; +static const auto DEFAULT_POSITION_GETTER = []{ return Vectors::ZERO; }; static const auto DEFAULT_ORIENTATION_GETTER = [] { return Quaternions::IDENTITY; }; static const int DEFAULT_BUFFER_FRAMES = 1; @@ -78,11 +78,12 @@ static const int OUTPUT_CHANNEL_COUNT = 2; static const bool DEFAULT_STARVE_DETECTION_ENABLED = true; static const int STARVE_DETECTION_THRESHOLD = 3; -static const int STARVE_DETECTION_PERIOD = 10 * 1000; // 10 Seconds +static const int STARVE_DETECTION_PERIOD = 10 * 1000; // 10 Seconds Setting::Handle dynamicJitterBufferEnabled("dynamicJitterBuffersEnabled", InboundAudioStream::DEFAULT_DYNAMIC_JITTER_BUFFER_ENABLED); -Setting::Handle staticJitterBufferFrames("staticJitterBufferFrames", InboundAudioStream::DEFAULT_STATIC_JITTER_FRAMES); +Setting::Handle staticJitterBufferFrames("staticJitterBufferFrames", + InboundAudioStream::DEFAULT_STATIC_JITTER_FRAMES); // protect the Qt internal device list using Mutex = std::mutex; @@ -155,7 +156,8 @@ QList AudioClient::getAudioDevices(QAudio::Mode mode) const } static void channelUpmix(int16_t* source, int16_t* dest, int numSamples, int numExtraChannels) { - for (int i = 0; i < numSamples / 2; i++) { + for (int i = 0; i < numSamples/2; i++) { + // read 2 samples int16_t left = *source++; int16_t right = *source++; @@ -171,6 +173,7 @@ static void channelUpmix(int16_t* source, int16_t* dest, int numSamples, int num static void channelDownmix(int16_t* source, int16_t* dest, int numSamples) { for (int i = 0; i < numSamples / 2; i++) { + // read 2 samples int16_t left = *source++; int16_t right = *source++; @@ -181,6 +184,7 @@ static void channelDownmix(int16_t* source, int16_t* dest, int numSamples) { } static bool detectClipping(int16_t* samples, int numSamples, int numChannels) { + const int32_t CLIPPING_THRESHOLD = 32392; // -0.1 dBFS const int CLIPPING_DETECTION = 3; // consecutive samples over threshold @@ -190,9 +194,9 @@ static bool detectClipping(int16_t* samples, int numSamples, int numChannels) { int oversLeft = 0; int oversRight = 0; - for (int i = 0; i < numSamples / 2; i++) { - int32_t left = std::abs((int32_t)samples[2 * i + 0]); - int32_t right = std::abs((int32_t)samples[2 * i + 1]); + for (int i = 0; i < numSamples/2; i++) { + int32_t left = std::abs((int32_t)samples[2*i+0]); + int32_t right = std::abs((int32_t)samples[2*i+1]); if (left > CLIPPING_THRESHOLD) { isClipping |= (++oversLeft >= CLIPPING_DETECTION); @@ -223,6 +227,7 @@ static bool detectClipping(int16_t* samples, int numSamples, int numChannels) { } static float computeLoudness(int16_t* samples, int numSamples) { + float scale = numSamples ? 1.0f / numSamples : 0.0f; int32_t loudness = 0; @@ -234,6 +239,7 @@ static float computeLoudness(int16_t* samples, int numSamples) { template static void applyGainSmoothing(float* buffer, int numFrames, float gain0, float gain1) { + // fast path for unity gain if (gain0 == 1.0f && gain1 == 1.0f) { return; @@ -248,13 +254,14 @@ static void applyGainSmoothing(float* buffer, int numFrames, float gain0, float float tStep = 1.0f / numFrames; for (int i = 0; i < numFrames; i++) { + // evaluate poly over t=[0,1) float gain = (c3 * t + c2) * t * t + c0; t += tStep; // apply gain to all channels for (int ch = 0; ch < NUM_CHANNELS; ch++) { - buffer[NUM_CHANNELS * i + ch] *= gain; + buffer[NUM_CHANNELS*i + ch] *= gain; } } } @@ -264,22 +271,52 @@ static inline float convertToFloat(int16_t sample) { } AudioClient::AudioClient() : - AbstractAudioInterface(), _gate(this), _audioInput(NULL), _dummyAudioInput(NULL), _desiredInputFormat(), _inputFormat(), - _numInputCallbackBytes(0), _audioOutput(NULL), _desiredOutputFormat(), _outputFormat(), _outputFrameSize(0), - _numOutputCallbackBytes(0), _loopbackAudioOutput(NULL), _loopbackOutputDevice(NULL), _inputRingBuffer(0), - _localInjectorsStream(0, 1), _receivedAudioStream(RECEIVED_AUDIO_STREAM_CAPACITY_FRAMES), _isStereoInput(false), - _outputStarveDetectionStartTimeMsec(0), _outputStarveDetectionCount(0), + AbstractAudioInterface(), + _gate(this), + _audioInput(NULL), + _dummyAudioInput(NULL), + _desiredInputFormat(), + _inputFormat(), + _numInputCallbackBytes(0), + _audioOutput(NULL), + _desiredOutputFormat(), + _outputFormat(), + _outputFrameSize(0), + _numOutputCallbackBytes(0), + _loopbackAudioOutput(NULL), + _loopbackOutputDevice(NULL), + _inputRingBuffer(0), + _localInjectorsStream(0, 1), + _receivedAudioStream(RECEIVED_AUDIO_STREAM_CAPACITY_FRAMES), + _isStereoInput(false), + _outputStarveDetectionStartTimeMsec(0), + _outputStarveDetectionCount(0), _outputBufferSizeFrames("audioOutputBufferFrames", DEFAULT_BUFFER_FRAMES), _sessionOutputBufferSizeFrames(_outputBufferSizeFrames.get()), _outputStarveDetectionEnabled("audioOutputStarveDetectionEnabled", DEFAULT_STARVE_DETECTION_ENABLED), - _lastRawInputLoudness(0.0f), _lastSmoothedRawInputLoudness(0.0f), _lastInputLoudness(0.0f), _timeSinceLastClip(-1.0f), - _muted(false), _shouldEchoLocally(false), _shouldEchoToServer(false), _isNoiseGateEnabled(true), _isAECEnabled(true), - _reverb(false), _reverbOptions(&_scriptReverbOptions), _inputToNetworkResampler(NULL), _networkToOutputResampler(NULL), - _localToOutputResampler(NULL), _loopbackResampler(NULL), _audioLimiter(AudioConstants::SAMPLE_RATE, OUTPUT_CHANNEL_COUNT), - _outgoingAvatarAudioSequenceNumber(0), _audioOutputIODevice(_localInjectorsStream, _receivedAudioStream, this), - _stats(&_receivedAudioStream), _positionGetter(DEFAULT_POSITION_GETTER), + _lastRawInputLoudness(0.0f), + _lastSmoothedRawInputLoudness(0.0f), + _lastInputLoudness(0.0f), + _timeSinceLastClip(-1.0f), + _muted(false), + _shouldEchoLocally(false), + _shouldEchoToServer(false), + _isNoiseGateEnabled(true), + _isAECEnabled(true), + _reverb(false), + _reverbOptions(&_scriptReverbOptions), + _inputToNetworkResampler(NULL), + _networkToOutputResampler(NULL), + _localToOutputResampler(NULL), + _loopbackResampler(NULL), + _audioLimiter(AudioConstants::SAMPLE_RATE, OUTPUT_CHANNEL_COUNT), + _outgoingAvatarAudioSequenceNumber(0), + _audioOutputIODevice(_localInjectorsStream, _receivedAudioStream, this), + _stats(&_receivedAudioStream), + _positionGetter(DEFAULT_POSITION_GETTER), #if defined(Q_OS_ANDROID) - _checkInputTimer(this), _isHeadsetPluggedIn(false), + _checkInputTimer(this), + _isHeadsetPluggedIn(false), #endif _orientationGetter(DEFAULT_ORIENTATION_GETTER) { @@ -290,20 +327,16 @@ AudioClient::AudioClient() : { Setting::Handle::Deprecated("maxFramesOverDesired", InboundAudioStream::MAX_FRAMES_OVER_DESIRED); Setting::Handle::Deprecated("windowStarveThreshold", InboundAudioStream::WINDOW_STARVE_THRESHOLD); - Setting::Handle::Deprecated("windowSecondsForDesiredCalcOnTooManyStarves", - InboundAudioStream::WINDOW_SECONDS_FOR_DESIRED_CALC_ON_TOO_MANY_STARVES); - Setting::Handle::Deprecated("windowSecondsForDesiredReduction", - InboundAudioStream::WINDOW_SECONDS_FOR_DESIRED_REDUCTION); + Setting::Handle::Deprecated("windowSecondsForDesiredCalcOnTooManyStarves", InboundAudioStream::WINDOW_SECONDS_FOR_DESIRED_CALC_ON_TOO_MANY_STARVES); + Setting::Handle::Deprecated("windowSecondsForDesiredReduction", InboundAudioStream::WINDOW_SECONDS_FOR_DESIRED_REDUCTION); Setting::Handle::Deprecated("useStDevForJitterCalc", InboundAudioStream::USE_STDEV_FOR_JITTER); Setting::Handle::Deprecated("repetitionWithFade", InboundAudioStream::REPETITION_WITH_FADE); } - connect(&_receivedAudioStream, &MixedProcessedAudioStream::processSamples, this, &AudioClient::processReceivedSamples, - Qt::DirectConnection); + connect(&_receivedAudioStream, &MixedProcessedAudioStream::processSamples, + this, &AudioClient::processReceivedSamples, Qt::DirectConnection); connect(this, &AudioClient::changeDevice, this, [=](const HifiAudioDeviceInfo& outputDeviceInfo) { - qCDebug(audioclient) - << "got AudioClient::changeDevice signal, about to call switchOutputToAudioDevice() outputDeviceInfo: [" - << outputDeviceInfo.deviceName() << "]"; + qCDebug(audioclient)<< "got AudioClient::changeDevice signal, about to call switchOutputToAudioDevice() outputDeviceInfo: ["<< outputDeviceInfo.deviceName() << "]"; switchOutputToAudioDevice(outputDeviceInfo.getDevice()); }); @@ -345,8 +378,9 @@ AudioClient::AudioClient() : // start a thread to detect peak value changes _checkPeakValuesTimer = new QTimer(this); - connect(_checkPeakValuesTimer, &QTimer::timeout, this, - [this] { QtConcurrent::run(QThreadPool::globalInstance(), [this] { checkPeakValues(); }); }); + connect(_checkPeakValuesTimer, &QTimer::timeout, this, [this] { + QtConcurrent::run(QThreadPool::globalInstance(), [this] { checkPeakValues(); }); + }); const unsigned long PEAK_VALUES_CHECK_INTERVAL_MSECS = 50; _checkPeakValuesTimer->start(PEAK_VALUES_CHECK_INTERVAL_MSECS); @@ -367,7 +401,9 @@ AudioClient::AudioClient() : packetReceiver.registerListener(PacketType::SelectedAudioFormat, this, "handleSelectedAudioFormat"); auto& domainHandler = nodeList->getDomainHandler(); - connect(&domainHandler, &DomainHandler::disconnectedFromDomain, this, [this] { _solo.reset(); }); + connect(&domainHandler, &DomainHandler::disconnectedFromDomain, this, [this] { + _solo.reset(); + }); connect(nodeList.data(), &NodeList::nodeActivated, this, [this](SharedNodePointer node) { if (node->getType() == NodeType::AudioMixer) { _solo.resend(); @@ -376,6 +412,7 @@ AudioClient::AudioClient() : } AudioClient::~AudioClient() { + stop(); if (_codec && _encoder) { @@ -392,11 +429,11 @@ void AudioClient::customDeleter() { } void AudioClient::handleMismatchAudioFormat(SharedNodePointer node, const QString& currentCodec, const QString& recievedCodec) { - qCDebug(audioclient) << __FUNCTION__ << "sendingNode:" << *node << "currentCodec:" << currentCodec - << "recievedCodec:" << recievedCodec; + qCDebug(audioclient) << __FUNCTION__ << "sendingNode:" << *node << "currentCodec:" << currentCodec << "recievedCodec:" << recievedCodec; selectAudioFormat(recievedCodec); } + void AudioClient::reset() { _receivedAudioStream.reset(); _stats.reset(); @@ -474,8 +511,7 @@ QString AudioClient::getWinDeviceName(wchar_t* guid) { HRESULT hr = S_OK; CoInitialize(nullptr); IMMDeviceEnumerator* pMMDeviceEnumerator = nullptr; - CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), - (void**)&pMMDeviceEnumerator); + CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&pMMDeviceEnumerator); IMMDevice* pEndpoint; hr = pMMDeviceEnumerator->GetDevice(guid, &pEndpoint); if (hr == E_NOTFOUND) { @@ -499,22 +535,30 @@ QAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { if (getAvailableDevices(mode).size() > 1) { AudioDeviceID defaultDeviceID = 0; uint32_t propertySize = sizeof(AudioDeviceID); - AudioObjectPropertyAddress propertyAddress = { kAudioHardwarePropertyDefaultInputDevice, - kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; + AudioObjectPropertyAddress propertyAddress = { + kAudioHardwarePropertyDefaultInputDevice, + kAudioObjectPropertyScopeGlobal, + kAudioObjectPropertyElementMaster + }; if (mode == QAudio::AudioOutput) { propertyAddress.mSelector = kAudioHardwarePropertyDefaultOutputDevice; } - OSStatus getPropertyError = - AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &propertySize, &defaultDeviceID); + + OSStatus getPropertyError = AudioObjectGetPropertyData(kAudioObjectSystemObject, + &propertyAddress, + 0, + NULL, + &propertySize, + &defaultDeviceID); if (!getPropertyError && propertySize) { CFStringRef deviceName = NULL; propertySize = sizeof(deviceName); propertyAddress.mSelector = kAudioDevicePropertyDeviceNameCFString; - getPropertyError = - AudioObjectGetPropertyData(defaultDeviceID, &propertyAddress, 0, NULL, &propertySize, &deviceName); + getPropertyError = AudioObjectGetPropertyData(defaultDeviceID, &propertyAddress, 0, + NULL, &propertySize, &deviceName); if (!getPropertyError && propertySize) { // find a device in the list that matches the name we have and return it @@ -552,11 +596,9 @@ QAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { HRESULT hr = S_OK; CoInitialize(NULL); IMMDeviceEnumerator* pMMDeviceEnumerator = NULL; - CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), - (void**)&pMMDeviceEnumerator); + CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&pMMDeviceEnumerator); IMMDevice* pEndpoint; - hr = pMMDeviceEnumerator->GetDefaultAudioEndpoint(mode == QAudio::AudioOutput ? eRender : eCapture, eMultimedia, - &pEndpoint); + hr = pMMDeviceEnumerator->GetDefaultAudioEndpoint(mode == QAudio::AudioOutput ? eRender : eCapture, eMultimedia, &pEndpoint); if (hr == E_NOTFOUND) { printf("Audio Error: device not found\n"); deviceName = QString("NONE"); @@ -570,8 +612,8 @@ QAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { CoUninitialize(); } - qCDebug(audioclient) << "defaultAudioDeviceForMode mode: " << (mode == QAudio::AudioOutput ? "Output" : "Input") << " [" - << deviceName << "] [" << getNamedAudioDeviceForMode(mode, deviceName).deviceName() << "]"; + qCDebug(audioclient) << "defaultAudioDeviceForMode mode: " << (mode == QAudio::AudioOutput ? "Output" : "Input") + << " [" << deviceName << "] [" << getNamedAudioDeviceForMode(mode, deviceName).deviceName() << "]"; return getNamedAudioDeviceForMode(mode, deviceName); #endif @@ -599,8 +641,10 @@ bool AudioClient::getNamedAudioDeviceForModeExists(QAudio::Mode mode, const QStr return (getNamedAudioDeviceForMode(mode, deviceName).deviceName() == deviceName); } + // attempt to use the native sample rate and channel count bool nativeFormatForAudioDevice(const QAudioDeviceInfo& audioDevice, QAudioFormat& audioFormat) { + audioFormat = audioDevice.preferredFormat(); // converting to/from this rate must produce an integral number of samples @@ -621,6 +665,7 @@ bool nativeFormatForAudioDevice(const QAudioDeviceInfo& audioDevice, QAudioForma // attempt the native sample rate, with channels forced to 2 audioFormat.setChannelCount(2); if (!audioDevice.isFormatSupported(audioFormat)) { + // attempt the native sample rate, with channels forced to 1 audioFormat.setChannelCount(1); if (!audioDevice.isFormatSupported(audioFormat)) { @@ -634,6 +679,7 @@ bool nativeFormatForAudioDevice(const QAudioDeviceInfo& audioDevice, QAudioForma bool adjustedFormatForAudioDevice(const QAudioDeviceInfo& audioDevice, const QAudioFormat& desiredAudioFormat, QAudioFormat& adjustedAudioFormat) { + qCDebug(audioclient) << "The desired format for audio I/O is" << desiredAudioFormat; #if defined(Q_OS_WIN) @@ -666,6 +712,7 @@ bool adjustedFormatForAudioDevice(const QAudioDeviceInfo& audioDevice, for (int channelCount : (desiredAudioFormat.channelCount() == 1 ? inputChannels : outputChannels)) { for (int sampleRate : sampleRates) { + adjustedAudioFormat.setChannelCount(channelCount); adjustedAudioFormat.setSampleRate(sampleRate); @@ -678,11 +725,8 @@ bool adjustedFormatForAudioDevice(const QAudioDeviceInfo& audioDevice, return false; // a supported format could not be found } -bool sampleChannelConversion(const int16_t* sourceSamples, - int16_t* destinationSamples, - int numSourceSamples, - const int sourceChannelCount, - const int destinationChannelCount) { +bool sampleChannelConversion(const int16_t* sourceSamples, int16_t* destinationSamples, int numSourceSamples, + const int sourceChannelCount, const int destinationChannelCount) { if (sourceChannelCount == 2 && destinationChannelCount == 1) { // loop through the stereo input audio samples and average every two samples for (int i = 0; i < numSourceSamples; i += 2) { @@ -691,6 +735,7 @@ bool sampleChannelConversion(const int16_t* sourceSamples, return true; } else if (sourceChannelCount == 1 && destinationChannelCount == 2) { + // loop through the mono input audio and repeat each sample twice for (int i = 0; i < numSourceSamples; ++i) { destinationSamples[i * 2] = destinationSamples[(i * 2) + 1] = sourceSamples[i]; @@ -703,29 +748,28 @@ bool sampleChannelConversion(const int16_t* sourceSamples, } int possibleResampling(AudioSRC* resampler, - const int16_t* sourceSamples, - int16_t* destinationSamples, - int numSourceSamples, - int maxDestinationSamples, - const int sourceChannelCount, - const int destinationChannelCount) { + const int16_t* sourceSamples, int16_t* destinationSamples, + int numSourceSamples, int maxDestinationSamples, + const int sourceChannelCount, const int destinationChannelCount) { + int numSourceFrames = numSourceSamples / sourceChannelCount; int numDestinationFrames = 0; if (numSourceSamples > 0) { if (!resampler) { - if (!sampleChannelConversion(sourceSamples, destinationSamples, numSourceSamples, sourceChannelCount, - destinationChannelCount)) { + if (!sampleChannelConversion(sourceSamples, destinationSamples, numSourceSamples, + sourceChannelCount, destinationChannelCount)) { // no conversion, we can copy the samples directly across memcpy(destinationSamples, sourceSamples, numSourceSamples * AudioConstants::SAMPLE_SIZE); } numDestinationFrames = numSourceFrames; } else { if (sourceChannelCount != destinationChannelCount) { + int16_t* channelConversionSamples = new int16_t[numSourceFrames * destinationChannelCount]; - sampleChannelConversion(sourceSamples, channelConversionSamples, numSourceSamples, sourceChannelCount, - destinationChannelCount); + sampleChannelConversion(sourceSamples, channelConversionSamples, numSourceSamples, + sourceChannelCount, destinationChannelCount); numDestinationFrames = resampler->render(channelConversionSamples, destinationSamples, numSourceFrames); @@ -745,6 +789,7 @@ int possibleResampling(AudioSRC* resampler, } void AudioClient::start() { + // set up the desired audio format _desiredInputFormat.setSampleRate(AudioConstants::SAMPLE_RATE); _desiredInputFormat.setSampleSize(16); @@ -833,6 +878,7 @@ void AudioClient::handleAudioDataPacket(QSharedPointer message) nodeList->flagTimeForConnectionStep(LimitedNodeList::ConnectionStep::ReceiveFirstAudioPacket); if (_audioOutput) { + if (!_hasReceivedFirstPacket) { _hasReceivedFirstPacket = true; @@ -849,8 +895,8 @@ void AudioClient::handleAudioDataPacket(QSharedPointer message) } } -AudioClient::Gate::Gate(AudioClient* audioClient) : _audioClient(audioClient) { -} +AudioClient::Gate::Gate(AudioClient* audioClient) : + _audioClient(audioClient) {} void AudioClient::Gate::setIsSimulatingJitter(bool enable) { std::lock_guard lock(_mutex); @@ -903,6 +949,7 @@ void AudioClient::Gate::flush() { _index = 0; } + void AudioClient::handleNoisyMutePacket(QSharedPointer message) { if (!_muted) { setMuted(true); @@ -948,6 +995,7 @@ void AudioClient::handleSelectedAudioFormat(QSharedPointer mess } void AudioClient::selectAudioFormat(const QString& selectedCodecName) { + _selectedCodecName = selectedCodecName; qCDebug(audioclient) << "Selected Codec:" << _selectedCodecName << "isStereoInput:" << _isStereoInput; @@ -965,12 +1013,12 @@ void AudioClient::selectAudioFormat(const QString& selectedCodecName) { if (_selectedCodecName == plugin->getName()) { _codec = plugin; _receivedAudioStream.setupCodec(plugin, _selectedCodecName, AudioConstants::STEREO); - _encoder = plugin->createEncoder(AudioConstants::SAMPLE_RATE, - _isStereoInput ? AudioConstants::STEREO : AudioConstants::MONO); + _encoder = plugin->createEncoder(AudioConstants::SAMPLE_RATE, _isStereoInput ? AudioConstants::STEREO : AudioConstants::MONO); qCDebug(audioclient) << "Selected Codec Plugin:" << _codec.get(); break; } } + } bool AudioClient::switchAudioDevice(QAudio::Mode mode, const QAudioDeviceInfo& deviceInfo) { @@ -1035,6 +1083,7 @@ void AudioClient::configureReverb() { void AudioClient::updateReverbOptions() { bool reverbChanged = false; if (_receivedAudioStream.hasReverb()) { + if (_zoneReverbOptions.getReverbTime() != _receivedAudioStream.getRevebTime()) { _zoneReverbOptions.setReverbTime(_receivedAudioStream.getRevebTime()); reverbChanged = true; @@ -1147,6 +1196,7 @@ void AudioClient::configureWebrtc() { // rebuffer into 10ms chunks void AudioClient::processWebrtcFarEnd(const int16_t* samples, int numFrames, int numChannels, int sampleRate) { + const webrtc::StreamConfig streamConfig = webrtc::StreamConfig(sampleRate, numChannels); const int numChunk = (int)streamConfig.num_frames(); @@ -1160,6 +1210,7 @@ void AudioClient::processWebrtcFarEnd(const int16_t* samples, int numFrames, int } while (numFrames > 0) { + // number of frames to fill int numFill = std::min(numFrames, numChunk - _numFifoFarEnd); @@ -1170,6 +1221,7 @@ void AudioClient::processWebrtcFarEnd(const int16_t* samples, int numFrames, int _numFifoFarEnd += numFill; if (_numFifoFarEnd == numChunk) { + // convert audio format float buffer[WEBRTC_CHANNELS_MAX][WEBRTC_FRAMES_MAX]; float* const buffers[WEBRTC_CHANNELS_MAX] = { buffer[0], buffer[1] }; @@ -1186,6 +1238,7 @@ void AudioClient::processWebrtcFarEnd(const int16_t* samples, int numFrames, int } void AudioClient::processWebrtcNearEnd(int16_t* samples, int numFrames, int numChannels, int sampleRate) { + const webrtc::StreamConfig streamConfig = webrtc::StreamConfig(sampleRate, numChannels); const int numChunk = (int)streamConfig.num_frames(); @@ -1244,8 +1297,7 @@ void AudioClient::handleLocalEchoAndReverb(QByteArray& inputByteArray) { // if required, create loopback resampler if (_inputFormat.sampleRate() != _outputFormat.sampleRate() && !_loopbackResampler) { - qCDebug(audioclient) << "Resampling from" << _inputFormat.sampleRate() << "to" << _outputFormat.sampleRate() - << "for audio loopback."; + qCDebug(audioclient) << "Resampling from" << _inputFormat.sampleRate() << "to" << _outputFormat.sampleRate() << "for audio loopback."; _loopbackResampler = new AudioSRC(_inputFormat.sampleRate(), _outputFormat.sampleRate(), OUTPUT_CHANNEL_COUNT); } @@ -1261,8 +1313,10 @@ void AudioClient::handleLocalEchoAndReverb(QByteArray& inputByteArray) { int16_t* inputSamples = reinterpret_cast(inputByteArray.data()); int16_t* loopbackSamples = reinterpret_cast(loopBackByteArray.data()); - int numLoopbackSamples = possibleResampling(_loopbackResampler, inputSamples, loopbackSamples, numInputSamples, - maxLoopbackSamples, _inputFormat.channelCount(), OUTPUT_CHANNEL_COUNT); + int numLoopbackSamples = possibleResampling(_loopbackResampler, + inputSamples, loopbackSamples, + numInputSamples, maxLoopbackSamples, + _inputFormat.channelCount(), OUTPUT_CHANNEL_COUNT); loopBackByteArray.resize(numLoopbackSamples * AudioConstants::SAMPLE_SIZE); @@ -1275,9 +1329,11 @@ void AudioClient::handleLocalEchoAndReverb(QByteArray& inputByteArray) { // if required, upmix or downmix to deviceChannelCount int deviceChannelCount = _outputFormat.channelCount(); if (deviceChannelCount == OUTPUT_CHANNEL_COUNT) { + _loopbackOutputDevice->write(loopBackByteArray); } else { + static QByteArray deviceByteArray; int numDeviceSamples = (numLoopbackSamples * deviceChannelCount) / OUTPUT_CHANNEL_COUNT; @@ -1297,6 +1353,7 @@ void AudioClient::handleLocalEchoAndReverb(QByteArray& inputByteArray) { void AudioClient::handleAudioInput(QByteArray& audioBuffer) { if (!_audioPaused) { + bool audioGateOpen = false; if (!_muted) { @@ -1350,7 +1407,8 @@ void AudioClient::handleAudioInput(QByteArray& audioBuffer) { } emitAudioPacket(encodedBuffer.data(), encodedBuffer.size(), _outgoingAvatarAudioSequenceNumber, _isStereoInput, - audioTransform, avatarBoundingBoxCorner, avatarBoundingBoxScale, packetType, _selectedCodecName); + audioTransform, avatarBoundingBoxCorner, avatarBoundingBoxScale, + packetType, _selectedCodecName); _stats.sentPacket(); } } @@ -1365,10 +1423,9 @@ void AudioClient::handleMicAudioInput() { #endif // input samples required to produce exactly NETWORK_FRAME_SAMPLES of output - const int inputSamplesRequired = - (_inputToNetworkResampler ? _inputToNetworkResampler->getMinInput(AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL) - : AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL) * - _inputFormat.channelCount(); + const int inputSamplesRequired = (_inputToNetworkResampler ? + _inputToNetworkResampler->getMinInput(AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL) : + AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL) * _inputFormat.channelCount(); const auto inputAudioSamples = std::unique_ptr(new int16_t[inputSamplesRequired]); QByteArray inputByteArray = _inputDevice->readAll(); @@ -1380,14 +1437,17 @@ void AudioClient::handleMicAudioInput() { float audioInputMsecsRead = inputByteArray.size() / (float)(_inputFormat.bytesForDuration(USECS_PER_MSEC)); _stats.updateInputMsRead(audioInputMsecsRead); - const int numNetworkBytes = - _isStereoInput ? AudioConstants::NETWORK_FRAME_BYTES_STEREO : AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL; - const int numNetworkSamples = - _isStereoInput ? AudioConstants::NETWORK_FRAME_SAMPLES_STEREO : AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL; + const int numNetworkBytes = _isStereoInput + ? AudioConstants::NETWORK_FRAME_BYTES_STEREO + : AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL; + const int numNetworkSamples = _isStereoInput + ? AudioConstants::NETWORK_FRAME_SAMPLES_STEREO + : AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL; static int16_t networkAudioSamples[AudioConstants::NETWORK_FRAME_SAMPLES_STEREO]; while (_inputRingBuffer.samplesAvailable() >= inputSamplesRequired) { + _inputRingBuffer.readSamples(inputAudioSamples.get(), inputSamplesRequired); // detect clipping on the raw input @@ -1417,8 +1477,10 @@ void AudioClient::handleMicAudioInput() { emit inputLoudnessChanged(_lastSmoothedRawInputLoudness, isClipping); if (!_muted) { - possibleResampling(_inputToNetworkResampler, inputAudioSamples.get(), networkAudioSamples, inputSamplesRequired, - numNetworkSamples, _inputFormat.channelCount(), _desiredInputFormat.channelCount()); + possibleResampling(_inputToNetworkResampler, + inputAudioSamples.get(), networkAudioSamples, + inputSamplesRequired, numNetworkSamples, + _inputFormat.channelCount(), _desiredInputFormat.channelCount()); } int bytesInInputRingBuffer = _inputRingBuffer.samplesAvailable() * AudioConstants::SAMPLE_SIZE; float msecsInInputRingBuffer = bytesInInputRingBuffer / (float)(_inputFormat.bytesForDuration(USECS_PER_MSEC)); @@ -1430,8 +1492,9 @@ void AudioClient::handleMicAudioInput() { } void AudioClient::handleDummyAudioInput() { - const int numNetworkBytes = - _isStereoInput ? AudioConstants::NETWORK_FRAME_BYTES_STEREO : AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL; + const int numNetworkBytes = _isStereoInput + ? AudioConstants::NETWORK_FRAME_BYTES_STEREO + : AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL; QByteArray audioBuffer(numNetworkBytes, 0); // silent handleAudioInput(audioBuffer); @@ -1464,7 +1527,8 @@ void AudioClient::prepareLocalAudioInjectors(std::unique_ptr localAudioLoc int bufferCapacity = _localInjectorsStream.getSampleCapacity(); int maxOutputSamples = AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * AudioConstants::STEREO; if (_localToOutputResampler) { - maxOutputSamples = _localToOutputResampler->getMaxOutput(AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL) * + maxOutputSamples = + _localToOutputResampler->getMaxOutput(AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL) * AudioConstants::STEREO; } @@ -1497,7 +1561,8 @@ void AudioClient::prepareLocalAudioInjectors(std::unique_ptr localAudioLoc } else { // write to local injectors' ring buffer samples = AudioConstants::NETWORK_FRAME_SAMPLES_STEREO; - _localInjectorsStream.writeSamples(_localMixBuffer, AudioConstants::NETWORK_FRAME_SAMPLES_STEREO); + _localInjectorsStream.writeSamples(_localMixBuffer, + AudioConstants::NETWORK_FRAME_SAMPLES_STEREO); } _localSamplesAvailable.fetch_add(samples, std::memory_order_release); @@ -1522,23 +1587,26 @@ bool AudioClient::mixLocalAudioInjectors(float* mixBuffer) { // the lock guarantees that injectorBuffer, if found, is invariant auto injectorBuffer = injector->getLocalBuffer(); if (injectorBuffer) { + auto options = injector->getOptions(); static const int HRTF_DATASET_INDEX = 1; - int numChannels = options.ambisonic ? AudioConstants::AMBISONIC - : (options.stereo ? AudioConstants::STEREO : AudioConstants::MONO); + int numChannels = options.ambisonic ? AudioConstants::AMBISONIC : (options.stereo ? AudioConstants::STEREO : AudioConstants::MONO); size_t bytesToRead = numChannels * AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL; // get one frame from the injector memset(_localScratchBuffer, 0, bytesToRead); if (0 < injectorBuffer->readData((char*)_localScratchBuffer, bytesToRead)) { + bool isSystemSound = !options.positionSet && !options.ambisonic; float gain = options.volume * (isSystemSound ? _systemInjectorGain : _localInjectorGain); if (options.ambisonic) { + if (options.positionSet) { + // distance attenuation glm::vec3 relativePosition = options.position - _positionGetter(); float distance = glm::max(glm::length(relativePosition), EPSILON); @@ -1558,10 +1626,12 @@ bool AudioClient::mixLocalAudioInjectors(float* mixBuffer) { float qz = relativeOrientation.y; // spatialize into mixBuffer - injector->getLocalFOA().render(_localScratchBuffer, mixBuffer, HRTF_DATASET_INDEX, qw, qx, qy, qz, gain, - AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL); + injector->getLocalFOA().render(_localScratchBuffer, mixBuffer, HRTF_DATASET_INDEX, + qw, qx, qy, qz, gain, AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL); } else if (options.stereo) { + if (options.positionSet) { + // distance attenuation glm::vec3 relativePosition = options.position - _positionGetter(); float distance = glm::max(glm::length(relativePosition), EPSILON); @@ -1574,6 +1644,7 @@ bool AudioClient::mixLocalAudioInjectors(float* mixBuffer) { } else { // injector is mono if (options.positionSet) { + // distance attenuation glm::vec3 relativePosition = options.position - _positionGetter(); float distance = glm::max(glm::length(relativePosition), EPSILON); @@ -1582,9 +1653,10 @@ bool AudioClient::mixLocalAudioInjectors(float* mixBuffer) { float azimuth = azimuthForSource(relativePosition); // spatialize into mixBuffer - injector->getLocalHRTF().render(_localScratchBuffer, mixBuffer, HRTF_DATASET_INDEX, azimuth, distance, - gain, AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL); + injector->getLocalHRTF().render(_localScratchBuffer, mixBuffer, HRTF_DATASET_INDEX, + azimuth, distance, gain, AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL); } else { + // direct mix into mixBuffer injector->getLocalHRTF().mixMono(_localScratchBuffer, mixBuffer, gain, AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL); @@ -1592,12 +1664,14 @@ bool AudioClient::mixLocalAudioInjectors(float* mixBuffer) { } } else { + //qCDebug(audioclient) << "injector has no more data, marking finished for removal"; injector->finishLocalInjection(); injectorsToRemove.append(injector); } } else { + //qCDebug(audioclient) << "injector has no local buffer, marking as finished for removal"; injector->finishLocalInjection(); injectorsToRemove.append(injector); @@ -1616,6 +1690,7 @@ bool AudioClient::mixLocalAudioInjectors(float* mixBuffer) { } void AudioClient::processReceivedSamples(const QByteArray& decodedBuffer, QByteArray& outputBuffer) { + const int16_t* decodedSamples = reinterpret_cast(decodedBuffer.data()); assert(decodedBuffer.size() == AudioConstants::NETWORK_FRAME_BYTES_STEREO); @@ -1719,8 +1794,7 @@ bool AudioClient::setIsStereoInput(bool isStereoInput) { if (_encoder) { _codec->releaseEncoder(_encoder); } - _encoder = _codec->createEncoder(AudioConstants::SAMPLE_RATE, - _isStereoInput ? AudioConstants::STEREO : AudioConstants::MONO); + _encoder = _codec->createEncoder(AudioConstants::SAMPLE_RATE, _isStereoInput ? AudioConstants::STEREO : AudioConstants::MONO); } qCDebug(audioclient) << "Reset Codec:" << _selectedCodecName << "isStereoInput:" << _isStereoInput; @@ -1760,6 +1834,7 @@ int AudioClient::getNumLocalInjectors() { Lock lock(_injectorsMutex); return _activeLocalAudioInjectors.size(); } + void AudioClient::outputFormatChanged() { _outputFrameSize = (AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * OUTPUT_CHANNEL_COUNT * _outputFormat.sampleRate()) / _desiredOutputFormat.sampleRate(); @@ -1833,15 +1908,15 @@ bool AudioClient::switchInputToAudioDevice(const QAudioDeviceInfo inputDeviceInf // we've got the best we can get for input // if required, setup a resampler for this input to our desired network format - if (_inputFormat != _desiredInputFormat && _inputFormat.sampleRate() != _desiredInputFormat.sampleRate()) { + if (_inputFormat != _desiredInputFormat + && _inputFormat.sampleRate() != _desiredInputFormat.sampleRate()) { qCDebug(audioclient) << "Attemping to create a resampler for input format to network format."; assert(_inputFormat.sampleSize() == 16); assert(_desiredInputFormat.sampleSize() == 16); int channelCount = (_inputFormat.channelCount() == 2 && _desiredInputFormat.channelCount() == 2) ? 2 : 1; - _inputToNetworkResampler = - new AudioSRC(_inputFormat.sampleRate(), _desiredInputFormat.sampleRate(), channelCount); + _inputToNetworkResampler = new AudioSRC(_inputFormat.sampleRate(), _desiredInputFormat.sampleRate(), channelCount); } else { qCDebug(audioclient) << "No resampling required for audio input to match desired network format."; @@ -1983,8 +2058,8 @@ void AudioClient::outputNotify() { int newOutputBufferSizeFrames = setOutputBufferSize(oldOutputBufferSizeFrames + 1, false); if (newOutputBufferSizeFrames > oldOutputBufferSizeFrames) { - qCDebug(audioclient, "Starve threshold surpassed (%d starves in %d ms)", _outputStarveDetectionCount, - dt); + qCDebug(audioclient, + "Starve threshold surpassed (%d starves in %d ms)", _outputStarveDetectionCount, dt); } _outputStarveDetectionStartTimeMsec = now; @@ -1998,8 +2073,7 @@ void AudioClient::outputNotify() { bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo outputDeviceInfo, bool isShutdownRequest) { Q_ASSERT_X(QThread::currentThread() == thread(), Q_FUNC_INFO, "Function invoked on wrong thread"); - qCDebug(audioclient) << "AudioClient::switchOutputToAudioDevice() outputDeviceInfo: [" << outputDeviceInfo.deviceName() - << "]"; + qCDebug(audioclient) << "AudioClient::switchOutputToAudioDevice() outputDeviceInfo: [" << outputDeviceInfo.deviceName() << "]"; bool supportedFormat = false; // NOTE: device start() uses the Qt internal device list @@ -2068,16 +2142,15 @@ bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo outputDeviceI // we've got the best we can get for input // if required, setup a resampler for this input to our desired network format - if (_desiredOutputFormat != _outputFormat && _desiredOutputFormat.sampleRate() != _outputFormat.sampleRate()) { + if (_desiredOutputFormat != _outputFormat + && _desiredOutputFormat.sampleRate() != _outputFormat.sampleRate()) { qCDebug(audioclient) << "Attemping to create a resampler for network format to output format."; assert(_desiredOutputFormat.sampleSize() == 16); assert(_outputFormat.sampleSize() == 16); - _networkToOutputResampler = - new AudioSRC(_desiredOutputFormat.sampleRate(), _outputFormat.sampleRate(), OUTPUT_CHANNEL_COUNT); - _localToOutputResampler = - new AudioSRC(_desiredOutputFormat.sampleRate(), _outputFormat.sampleRate(), OUTPUT_CHANNEL_COUNT); + _networkToOutputResampler = new AudioSRC(_desiredOutputFormat.sampleRate(), _outputFormat.sampleRate(), OUTPUT_CHANNEL_COUNT); + _localToOutputResampler = new AudioSRC(_desiredOutputFormat.sampleRate(), _outputFormat.sampleRate(), OUTPUT_CHANNEL_COUNT); } else { qCDebug(audioclient) << "No resampling required for network output to match actual output format."; @@ -2089,9 +2162,7 @@ bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo outputDeviceI _audioOutput = new QAudioOutput(outputDeviceInfo, _outputFormat, this); int deviceChannelCount = _outputFormat.channelCount(); - int frameSize = - (AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * deviceChannelCount * _outputFormat.sampleRate()) / - _desiredOutputFormat.sampleRate(); + int frameSize = (AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * deviceChannelCount * _outputFormat.sampleRate()) / _desiredOutputFormat.sampleRate(); int requestedSize = _sessionOutputBufferSizeFrames * frameSize * AudioConstants::SAMPLE_SIZE; _audioOutput->setBufferSize(requestedSize); @@ -2112,9 +2183,7 @@ bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo outputDeviceI _outputScratchBuffer = new int16_t[_outputPeriod]; // size local output mix buffer based on resampled network frame size - int networkPeriod = _localToOutputResampler - ? _localToOutputResampler->getMaxOutput(AudioConstants::NETWORK_FRAME_SAMPLES_STEREO) - : AudioConstants::NETWORK_FRAME_SAMPLES_STEREO; + int networkPeriod = _localToOutputResampler ? _localToOutputResampler->getMaxOutput(AudioConstants::NETWORK_FRAME_SAMPLES_STEREO) : AudioConstants::NETWORK_FRAME_SAMPLES_STEREO; _localOutputMixBuffer = new float[networkPeriod]; // local period should be at least twice the output period, @@ -2157,8 +2226,7 @@ int AudioClient::setOutputBufferSize(int numFrames, bool persist) { qCDebug(audioclient) << __FUNCTION__ << "numFrames:" << numFrames << "persist:" << persist; numFrames = std::min(std::max(numFrames, MIN_BUFFER_FRAMES), MAX_BUFFER_FRAMES); - qCDebug(audioclient) << __FUNCTION__ << "clamped numFrames:" << numFrames - << "_sessionOutputBufferSizeFrames:" << _sessionOutputBufferSizeFrames; + qCDebug(audioclient) << __FUNCTION__ << "clamped numFrames:" << numFrames << "_sessionOutputBufferSizeFrames:" << _sessionOutputBufferSizeFrames; if (numFrames != _sessionOutputBufferSizeFrames) { qCInfo(audioclient, "Audio output buffer set to %d frames", numFrames); @@ -2189,10 +2257,10 @@ const float AudioClient::CALLBACK_ACCELERATOR_RATIO = 2.0f; #endif int AudioClient::calculateNumberOfInputCallbackBytes(const QAudioFormat& format) const { - int numInputCallbackBytes = (int)(((AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL * format.channelCount() * - ((float)format.sampleRate() / AudioConstants::SAMPLE_RATE)) / - CALLBACK_ACCELERATOR_RATIO) + - 0.5f); + int numInputCallbackBytes = (int)(((AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL + * format.channelCount() + * ((float) format.sampleRate() / AudioConstants::SAMPLE_RATE)) + / CALLBACK_ACCELERATOR_RATIO) + 0.5f); return numInputCallbackBytes; } @@ -2214,6 +2282,7 @@ float AudioClient::azimuthForSource(const glm::vec3& relativePosition) { float rotatedSourcePositionLength2 = glm::length2(rotatedSourcePosition); if (rotatedSourcePositionLength2 > SOURCE_DISTANCE_THRESHOLD) { + // produce an oriented angle about the y-axis glm::vec3 direction = rotatedSourcePosition * (1.0f / fastSqrtf(rotatedSourcePositionLength2)); float angle = fastAcosf(glm::clamp(-direction.z, -1.0f, 1.0f)); // UNIT_NEG_Z is "forward" @@ -2226,6 +2295,7 @@ float AudioClient::azimuthForSource(const glm::vec3& relativePosition) { } float AudioClient::gainForSource(float distance, float volume) { + // attenuation = -6dB * log2(distance) // reference attenuation of 0dB at distance = ATTN_DISTANCE_REF float d = (1.0f / ATTN_DISTANCE_REF) * std::max(distance, HRTF_NEARFIELD_MIN); @@ -2236,6 +2306,7 @@ float AudioClient::gainForSource(float distance, float volume) { } qint64 AudioClient::AudioOutputIODevice::readData(char* data, qint64 maxSize) { + // lock-free wait for initialization to avoid races if (!_audio->_audioOutputInitialized.load(std::memory_order_acquire)) { memset(data, 0, maxSize); @@ -2254,8 +2325,7 @@ qint64 AudioClient::AudioOutputIODevice::readData(char* data, qint64 maxSize) { int samplesRequested = maxSamplesRequested; int networkSamplesPopped; if ((networkSamplesPopped = _receivedAudioStream.popSamples(samplesRequested, false)) > 0) { - qCDebug(audiostream, "Read %d samples from buffer (%d available, %d requested)", networkSamplesPopped, - _receivedAudioStream.getSamplesAvailable(), samplesRequested); + qCDebug(audiostream, "Read %d samples from buffer (%d available, %d requested)", networkSamplesPopped, _receivedAudioStream.getSamplesAvailable(), samplesRequested); AudioRingBuffer::ConstIterator lastPopOutput = _receivedAudioStream.getLastPopOutput(); lastPopOutput.readSamples(scratchBuffer, networkSamplesPopped); for (int i = 0; i < networkSamplesPopped; i++) { @@ -2287,13 +2357,14 @@ qint64 AudioClient::AudioOutputIODevice::readData(char* data, qint64 maxSize) { samplesRequested = std::min(samplesRequested, samplesAvailable); if ((injectorSamplesPopped = _localInjectorsStream.appendSamples(mixBuffer, samplesRequested, append)) > 0) { _audio->_localSamplesAvailable.fetch_sub(injectorSamplesPopped, std::memory_order_release); - qCDebug(audiostream, "Read %d samples from injectors (%d available, %d requested)", injectorSamplesPopped, - _localInjectorsStream.samplesAvailable(), samplesRequested); + qCDebug(audiostream, "Read %d samples from injectors (%d available, %d requested)", injectorSamplesPopped, _localInjectorsStream.samplesAvailable(), samplesRequested); } } // prepare injectors for the next callback - QtConcurrent::run(QThreadPool::globalInstance(), [this] { _audio->prepareLocalAudioInjectors(); }); + QtConcurrent::run(QThreadPool::globalInstance(), [this] { + _audio->prepareLocalAudioInjectors(); + }); int samplesPopped = std::max(networkSamplesPopped, injectorSamplesPopped); if (samplesPopped == 0) { @@ -2373,6 +2444,7 @@ void AudioClient::loadSettings() { for (auto& plugin : codecPlugins) { qCDebug(audioclient) << "Codec available:" << plugin->getName(); } + } void AudioClient::saveSettings() { @@ -2385,9 +2457,9 @@ void AudioClient::setAvatarBoundingBoxParameters(glm::vec3 corner, glm::vec3 sca avatarBoundingBoxScale = scale; } + void AudioClient::startThread() { - moveToNewNamedThread( - this, "Audio Thread", [this] { start(); }, QThread::TimeCriticalPriority); + moveToNewNamedThread(this, "Audio Thread", [this] { start(); }, QThread::TimeCriticalPriority); } void AudioClient::setInputVolume(float volume, bool emitSignal) { @@ -2397,4 +2469,4 @@ void AudioClient::setInputVolume(float volume, bool emitSignal) { emit inputVolumeChanged(_audioInput->volume()); } } -} +} \ No newline at end of file diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index 15f0772dc3..fabf83c53f 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -80,14 +80,11 @@ class QIODevice; class Transform; class NLPacket; - - class AudioClient : public AbstractAudioInterface, public Dependency { Q_OBJECT SINGLETON_DEPENDENCY using LocalInjectorsStream = AudioMixRingBuffer; - public: static const int MIN_BUFFER_FRAMES; static const int MAX_BUFFER_FRAMES; @@ -100,21 +97,15 @@ public: class AudioOutputIODevice : public QIODevice { public: - AudioOutputIODevice(LocalInjectorsStream& localInjectorsStream, - MixedProcessedAudioStream& receivedAudioStream, + AudioOutputIODevice(LocalInjectorsStream& localInjectorsStream, MixedProcessedAudioStream& receivedAudioStream, AudioClient* audio) : - _localInjectorsStream(localInjectorsStream), - _receivedAudioStream(receivedAudioStream), _audio(audio), _unfulfilledReads(0) {} + _localInjectorsStream(localInjectorsStream), _receivedAudioStream(receivedAudioStream), + _audio(audio), _unfulfilledReads(0) {} void start() { open(QIODevice::ReadOnly | QIODevice::Unbuffered); } qint64 readData(char* data, qint64 maxSize) override; qint64 writeData(const char* data, qint64 maxSize) override { return 0; } - int getRecentUnfulfilledReads() { - int unfulfilledReads = _unfulfilledReads; - _unfulfilledReads = 0; - return unfulfilledReads; - } - + int getRecentUnfulfilledReads() { int unfulfilledReads = _unfulfilledReads; _unfulfilledReads = 0; return unfulfilledReads; } private: LocalInjectorsStream& _localInjectorsStream; MixedProcessedAudioStream& _receivedAudioStream; @@ -132,7 +123,6 @@ public: Q_INVOKABLE float getAudioInboundPPS() const { return _audioInbound.rate(); } Q_INVOKABLE float getSilentOutboundPPS() const { return _silentOutbound.rate(); } Q_INVOKABLE float getAudioOutboundPPS() const { return _audioOutbound.rate(); } - Q_INVOKABLE void setDefaultDevice(QList& devices, QAudio::Mode mode); const MixedProcessedAudioStream& getReceivedAudioStream() const { return _receivedAudioStream; } MixedProcessedAudioStream& getReceivedAudioStream() { return _receivedAudioStream; } @@ -479,12 +469,6 @@ private: QList _inputDevices; QList _outputDevices; - //QAudioDeviceInfo _inputDeviceInfo; - // QAudioDeviceInfo _outputDeviceInfo; - - // QList _inputDevices; - /// QList _outputDevices; - AudioFileWav _audioFileWav; bool _hasReceivedFirstPacket { false }; @@ -517,4 +501,5 @@ private: bool _isRecording { false }; }; -#endif // hifi_AudioClient_h + +#endif // hifi_AudioClient_h \ No newline at end of file From e68953141016336cd8e571aa60034b422b92073f Mon Sep 17 00:00:00 2001 From: amerhifi Date: Mon, 16 Sep 2019 15:31:44 -0700 Subject: [PATCH 09/27] added unique identifier to device for comparison. Because a default device had a different name, but same underlying device. So comparing with device name is not necessarily the same device. Possibly fixed select issue with multiple devices same name --- interface/src/scripting/AudioDevices.cpp | 13 +-- libraries/audio-client/src/AudioClient.cpp | 87 ++++++++----------- libraries/audio-client/src/AudioClient.h | 6 +- .../audio-client/src/HifiAudioDeviceInfo.h | 17 ++-- .../audio-client/src/HifiAudioDeviceinfo.cpp | 9 +- 5 files changed, 62 insertions(+), 70 deletions(-) diff --git a/interface/src/scripting/AudioDevices.cpp b/interface/src/scripting/AudioDevices.cpp index dbdd0c4852..7e31d36f7d 100644 --- a/interface/src/scripting/AudioDevices.cpp +++ b/interface/src/scripting/AudioDevices.cpp @@ -200,9 +200,10 @@ void AudioDeviceList::onDeviceChanged(const HifiAudioDeviceInfo& device, bool is for (auto i = 0; i < _devices.size(); ++i) { std::shared_ptr device = _devices[i]; bool& isSelected = isHMD ? device->selectedHMD : device->selectedDesktop; - if (isSelected && device->info != selectedDevice) { - isSelected = false; - } else if (device->info == selectedDevice) { + HifiAudioDeviceInfo devInfo = device->info; + isSelected = false; + + if (devInfo == selectedDevice) { isSelected = true; } } @@ -401,7 +402,7 @@ void AudioDevices::onContextChanged(const QString& context) { void AudioDevices::onDeviceSelected(QAudio::Mode mode, const HifiAudioDeviceInfo& device, const HifiAudioDeviceInfo& previousDevice, bool isHMD) { - QString deviceName = device.getDevice().isNull() ? QString() : device.deviceName(); + QString deviceName = device.deviceName(); auto& setting = getSetting(isHMD, mode); @@ -512,7 +513,7 @@ void AudioDevices::chooseInputDevice(const HifiAudioDeviceInfo& device, bool isH _requestedInputDevice = device; QMetaObject::invokeMethod(client, "switchAudioDevice", Q_ARG(QAudio::Mode, QAudio::AudioInput), - Q_ARG(const QAudioDeviceInfo&, device.getDevice())); + Q_ARG(const HifiAudioDeviceInfo&, device)); } else { //context is different. just save device in settings onDeviceSelected(QAudio::AudioInput, device, @@ -529,7 +530,7 @@ void AudioDevices::chooseOutputDevice(const HifiAudioDeviceInfo& device, bool is _requestedOutputDevice = device; QMetaObject::invokeMethod(client, "switchAudioDevice", Q_ARG(QAudio::Mode, QAudio::AudioOutput), - Q_ARG(const QAudioDeviceInfo&, device.getDevice())); + Q_ARG(const HifiAudioDeviceInfo&, device)); } else { //context is different. just save device in settings onDeviceSelected(QAudio::AudioOutput, device, diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 8609b9585a..4f5edef1b8 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -90,7 +90,7 @@ using Mutex = std::mutex; using Lock = std::unique_lock; Mutex _deviceMutex; Mutex _recordMutex; -QAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode); +HifiAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode); // thread-safe QList getAvailableDevices(QAudio::Mode mode) { @@ -337,24 +337,22 @@ AudioClient::AudioClient() : this, &AudioClient::processReceivedSamples, Qt::DirectConnection); connect(this, &AudioClient::changeDevice, this, [=](const HifiAudioDeviceInfo& outputDeviceInfo) { qCDebug(audioclient)<< "got AudioClient::changeDevice signal, about to call switchOutputToAudioDevice() outputDeviceInfo: ["<< outputDeviceInfo.deviceName() << "]"; - switchOutputToAudioDevice(outputDeviceInfo.getDevice()); + switchOutputToAudioDevice(outputDeviceInfo); }); connect(&_receivedAudioStream, &InboundAudioStream::mismatchedAudioCodec, this, &AudioClient::handleMismatchAudioFormat); - _defaultOutputDevice = HifiAudioDeviceInfo(); - _defaultOutputDevice.setDevice(defaultAudioDeviceForMode(QAudio::AudioOutput)); + _defaultOutputDevice = defaultAudioDeviceForMode(QAudio::AudioOutput); _defaultOutputDevice.setDeviceName("Default audio (recommended)"); _defaultOutputDevice.setIsDefault(true); _defaultOutputDevice.setMode(QAudio::AudioOutput); - _defaultInputDevice = HifiAudioDeviceInfo(); - _defaultInputDevice.setDevice(defaultAudioDeviceForMode(QAudio::AudioInput)); + _defaultInputDevice = defaultAudioDeviceForMode(QAudio::AudioInput); _defaultInputDevice.setDeviceName("Default microphone (recommended)"); _defaultInputDevice.setIsDefault(true); - _defaultInputDevice.setMode(QAudio::AudioOutput); + _defaultInputDevice.setMode(QAudio::AudioInput); // initialize wasapi; if getAvailableDevices is called from the CheckDevicesThread before this, it will crash @@ -459,30 +457,14 @@ void AudioClient::setAudioPaused(bool pause) { } } -void AudioClient::setDefaultDevice(QList& devices ,QAudio::Mode mode) { - QAudioDeviceInfo defDevice = defaultAudioDeviceForMode(mode); - for (auto& device : devices) { - if (device.getDevice() == defDevice) { - if (!device.isDefault()) { - device.setIsDefault(true); - } - } else { - if (device.isDefault()) { - device.setIsDefault(false); - } - } - } -} - -QAudioDeviceInfo getNamedAudioDeviceForMode(QAudio::Mode mode, const QString& deviceName) { - QAudioDeviceInfo result; +HifiAudioDeviceInfo getNamedAudioDeviceForMode(QAudio::Mode mode, const QString& deviceName) { + HifiAudioDeviceInfo result; foreach (HifiAudioDeviceInfo audioDevice, getAvailableDevices(mode)) { if (audioDevice.deviceName().trimmed() == deviceName.trimmed()) { - result = audioDevice.getDevice(); + result = audioDevice; break; } } - return result; } @@ -530,7 +512,7 @@ QString AudioClient::getWinDeviceName(wchar_t* guid) { #endif -QAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { +HifiAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { #ifdef __APPLE__ if (getAvailableDevices(mode).size() > 1) { AudioDeviceID defaultDeviceID = 0; @@ -562,7 +544,7 @@ QAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { if (!getPropertyError && propertySize) { // find a device in the list that matches the name we have and return it - foreach (QAudioDeviceInfo audioDevice, getAvailableDevices(mode)) { + foreach (AudioDeviceInfo audioDevice, getAvailableDevices(mode)) { if (audioDevice.deviceName() == CFStringGetCStringPtr(deviceName, kCFStringEncodingMacRoman)) { return audioDevice; } @@ -634,7 +616,8 @@ QAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { } #endif // fallback for failed lookup is the default device - return (mode == QAudio::AudioInput) ? QAudioDeviceInfo::defaultInputDevice() : QAudioDeviceInfo::defaultOutputDevice(); + return (mode == QAudio::AudioInput) ? HifiAudioDeviceInfo(QAudioDeviceInfo::defaultInputDevice(), false, QAudio::AudioInput) : + HifiAudioDeviceInfo(QAudioDeviceInfo::defaultOutputDevice(), false, QAudio::AudioOutput); } bool AudioClient::getNamedAudioDeviceForModeExists(QAudio::Mode mode, const QString& deviceName) { @@ -801,22 +784,22 @@ void AudioClient::start() { _desiredOutputFormat = _desiredInputFormat; _desiredOutputFormat.setChannelCount(OUTPUT_CHANNEL_COUNT); - QAudioDeviceInfo inputDeviceInfo = defaultAudioDeviceForMode(QAudio::AudioInput); + HifiAudioDeviceInfo inputDeviceInfo = defaultAudioDeviceForMode(QAudio::AudioInput); qCDebug(audioclient) << "The default audio input device is" << inputDeviceInfo.deviceName(); bool inputFormatSupported = switchInputToAudioDevice(inputDeviceInfo); - QAudioDeviceInfo outputDeviceInfo = defaultAudioDeviceForMode(QAudio::AudioOutput); + HifiAudioDeviceInfo outputDeviceInfo = defaultAudioDeviceForMode(QAudio::AudioOutput); qCDebug(audioclient) << "The default audio output device is" << outputDeviceInfo.deviceName(); bool outputFormatSupported = switchOutputToAudioDevice(outputDeviceInfo); if (!inputFormatSupported) { qCDebug(audioclient) << "Unable to set up audio input because of a problem with input format."; - qCDebug(audioclient) << "The closest format available is" << inputDeviceInfo.nearestFormat(_desiredInputFormat); + qCDebug(audioclient) << "The closest format available is" << inputDeviceInfo.getDevice().nearestFormat(_desiredInputFormat); } if (!outputFormatSupported) { qCDebug(audioclient) << "Unable to set up audio output because of a problem with output format."; - qCDebug(audioclient) << "The closest format available is" << outputDeviceInfo.nearestFormat(_desiredOutputFormat); + qCDebug(audioclient) << "The closest format available is" << outputDeviceInfo.getDevice().nearestFormat(_desiredOutputFormat); } #if defined(Q_OS_ANDROID) connect(&_checkInputTimer, &QTimer::timeout, this, &AudioClient::checkInputTimeout); @@ -826,10 +809,10 @@ void AudioClient::start() { void AudioClient::stop() { qCDebug(audioclient) << "AudioClient::stop(), requesting switchInputToAudioDevice() to shut down"; - switchInputToAudioDevice(QAudioDeviceInfo(), true); + switchInputToAudioDevice(HifiAudioDeviceInfo(), true); qCDebug(audioclient) << "AudioClient::stop(), requesting switchOutputToAudioDevice() to shut down"; - switchOutputToAudioDevice(QAudioDeviceInfo(), true); + switchOutputToAudioDevice(HifiAudioDeviceInfo(), true); // Stop triggering the checks QObject::disconnect(_checkPeakValuesTimer, &QTimer::timeout, nullptr, nullptr); @@ -1021,11 +1004,11 @@ void AudioClient::selectAudioFormat(const QString& selectedCodecName) { } -bool AudioClient::switchAudioDevice(QAudio::Mode mode, const QAudioDeviceInfo& deviceInfo) { +bool AudioClient::switchAudioDevice(QAudio::Mode mode, const HifiAudioDeviceInfo& deviceInfo) { auto device = deviceInfo; - if (device.isNull()) { - device = defaultAudioDeviceForMode(mode); + if (device.getDevice().isNull()) { + device=defaultAudioDeviceForMode(mode); } if (mode == QAudio::AudioInput) { @@ -1799,7 +1782,7 @@ bool AudioClient::setIsStereoInput(bool isStereoInput) { qCDebug(audioclient) << "Reset Codec:" << _selectedCodecName << "isStereoInput:" << _isStereoInput; // restart the input device - switchInputToAudioDevice(_inputDeviceInfo.getDevice()); + switchInputToAudioDevice(_inputDeviceInfo); emit isStereoInputChanged(_isStereoInput); } @@ -1841,10 +1824,10 @@ void AudioClient::outputFormatChanged() { _receivedAudioStream.outputFormatChanged(_outputFormat.sampleRate(), OUTPUT_CHANNEL_COUNT); } -bool AudioClient::switchInputToAudioDevice(const QAudioDeviceInfo inputDeviceInfo, bool isShutdownRequest) { +bool AudioClient::switchInputToAudioDevice(const HifiAudioDeviceInfo inputDeviceInfo, bool isShutdownRequest) { Q_ASSERT_X(QThread::currentThread() == thread(), Q_FUNC_INFO, "Function invoked on wrong thread"); - qCDebug(audioclient) << __FUNCTION__ << "inputDeviceInfo: [" << inputDeviceInfo.deviceName() << "]"; + qCDebug(audioclient) << __FUNCTION__ << "inputDeviceInfo: [" << inputDeviceInfo.getDevice().deviceName() << "]"; bool supportedFormat = false; // NOTE: device start() uses the Qt internal device list @@ -1897,13 +1880,12 @@ bool AudioClient::switchInputToAudioDevice(const QAudioDeviceInfo inputDeviceInf return true; } - if (!inputDeviceInfo.isNull()) { + if (!inputDeviceInfo.getDevice().isNull()) { qCDebug(audioclient) << "The audio input device " << inputDeviceInfo.deviceName() << "is available."; - _inputDeviceInfo = HifiAudioDeviceInfo(); - _inputDeviceInfo.setDevice(inputDeviceInfo); + _inputDeviceInfo = inputDeviceInfo; emit deviceChanged(QAudio::AudioInput, _inputDeviceInfo); - if (adjustedFormatForAudioDevice(inputDeviceInfo, _desiredInputFormat, _inputFormat)) { + if (adjustedFormatForAudioDevice(inputDeviceInfo.getDevice(), _desiredInputFormat, _inputFormat)) { qCDebug(audioclient) << "The format to be used for audio input is" << _inputFormat; // we've got the best we can get for input @@ -1928,7 +1910,7 @@ bool AudioClient::switchInputToAudioDevice(const QAudioDeviceInfo inputDeviceInf // if the user wants stereo but this device can't provide then bail if (!_isStereoInput || _inputFormat.channelCount() == 2) { - _audioInput = new QAudioInput(inputDeviceInfo, _inputFormat, this); + _audioInput = new QAudioInput(inputDeviceInfo.getDevice(), _inputFormat, this); _numInputCallbackBytes = calculateNumberOfInputCallbackBytes(_inputFormat); _audioInput->setBufferSize(_numInputCallbackBytes); // different audio input devices may have different volumes @@ -2070,7 +2052,7 @@ void AudioClient::outputNotify() { } } -bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo outputDeviceInfo, bool isShutdownRequest) { +bool AudioClient::switchOutputToAudioDevice(const HifiAudioDeviceInfo outputDeviceInfo, bool isShutdownRequest) { Q_ASSERT_X(QThread::currentThread() == thread(), Q_FUNC_INFO, "Function invoked on wrong thread"); qCDebug(audioclient) << "AudioClient::switchOutputToAudioDevice() outputDeviceInfo: [" << outputDeviceInfo.deviceName() << "]"; @@ -2106,7 +2088,6 @@ bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo outputDeviceI delete[] _localOutputMixBuffer; _localOutputMixBuffer = NULL; - //ctor call needed? _outputDeviceInfo = HifiAudioDeviceInfo(); _outputDeviceInfo.setDevice(QAudioDeviceInfo()); } @@ -2132,12 +2113,12 @@ bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo outputDeviceI return true; } - if (!outputDeviceInfo.isNull()) { + if (!outputDeviceInfo.getDevice().isNull()) { qCDebug(audioclient) << "The audio output device " << outputDeviceInfo.deviceName() << "is available."; - _outputDeviceInfo.setDevice(outputDeviceInfo); + _outputDeviceInfo = outputDeviceInfo; emit deviceChanged(QAudio::AudioOutput, _outputDeviceInfo); - if (adjustedFormatForAudioDevice(outputDeviceInfo, _desiredOutputFormat, _outputFormat)) { + if (adjustedFormatForAudioDevice(outputDeviceInfo.getDevice(), _desiredOutputFormat, _outputFormat)) { qCDebug(audioclient) << "The format to be used for audio output is" << _outputFormat; // we've got the best we can get for input @@ -2159,7 +2140,7 @@ bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo outputDeviceI outputFormatChanged(); // setup our general output device for audio-mixer audio - _audioOutput = new QAudioOutput(outputDeviceInfo, _outputFormat, this); + _audioOutput = new QAudioOutput(outputDeviceInfo.getDevice(), _outputFormat, this); int deviceChannelCount = _outputFormat.channelCount(); int frameSize = (AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * deviceChannelCount * _outputFormat.sampleRate()) / _desiredOutputFormat.sampleRate(); @@ -2211,7 +2192,7 @@ bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo outputDeviceI localAudioLock.unlock(); // setup a loopback audio output device - _loopbackAudioOutput = new QAudioOutput(outputDeviceInfo, _outputFormat, this); + _loopbackAudioOutput = new QAudioOutput(outputDeviceInfo.getDevice(), _outputFormat, this); _timeSinceLastReceived.start(); diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index fabf83c53f..bbc22ba93d 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -236,7 +236,7 @@ public slots: bool shouldLoopbackInjectors() override { return _shouldEchoToServer; } // calling with a null QAudioDevice will use the system default - bool switchAudioDevice(QAudio::Mode mode, const QAudioDeviceInfo& deviceInfo = QAudioDeviceInfo()); + bool switchAudioDevice(QAudio::Mode mode, const HifiAudioDeviceInfo& deviceInfo = HifiAudioDeviceInfo()); bool switchAudioDevice(QAudio::Mode mode, const QString& deviceName); // Qt opensles plugin is not able to detect when the headset is plugged in @@ -438,8 +438,8 @@ private: void processWebrtcNearEnd(int16_t* samples, int numFrames, int numChannels, int sampleRate); #endif - bool switchInputToAudioDevice(const QAudioDeviceInfo inputDeviceInfo, bool isShutdownRequest = false); - bool switchOutputToAudioDevice(const QAudioDeviceInfo outputDeviceInfo, bool isShutdownRequest = false); + bool switchInputToAudioDevice(const HifiAudioDeviceInfo inputDeviceInfo, bool isShutdownRequest = false); + bool switchOutputToAudioDevice(const HifiAudioDeviceInfo outputDeviceInfo, bool isShutdownRequest = false); // Callback acceleration dependent calculations int calculateNumberOfInputCallbackBytes(const QAudioFormat& format) const; diff --git a/libraries/audio-client/src/HifiAudioDeviceInfo.h b/libraries/audio-client/src/HifiAudioDeviceInfo.h index d2a349ed8c..e044562a35 100644 --- a/libraries/audio-client/src/HifiAudioDeviceInfo.h +++ b/libraries/audio-client/src/HifiAudioDeviceInfo.h @@ -1,5 +1,6 @@ #ifndef hifi_audiodeviceinfo_h #define hifi_audiodeviceinfo_h +#pragma once #include #include @@ -14,26 +15,29 @@ public: HifiAudioDeviceInfo(const HifiAudioDeviceInfo &deviceInfo){ _audioDeviceInfo = deviceInfo.getDevice(); _mode = deviceInfo.getMode(); - _deviceName = deviceInfo.deviceName(); _isDefault = deviceInfo.isDefault(); + + setDeviceName(deviceInfo.deviceName()); } HifiAudioDeviceInfo(QAudioDeviceInfo deviceInfo, bool isDefault, QAudio::Mode mode) : _isDefault(isDefault), _mode(mode), - _audioDeviceInfo(deviceInfo), - _deviceName(deviceInfo.deviceName()){ + _audioDeviceInfo(deviceInfo){ + + setDeviceName(deviceInfo.deviceName()); } void setMode(QAudio::Mode mode) { _mode = mode; } void setIsDefault(bool isDefault = false) { _isDefault = isDefault; } - void setDeviceName(QString name) { _deviceName = name; + setId(name); } - void setDevice(QAudioDeviceInfo devInfo); - + void setId(QString name); + + QString getId() const { return _uniqueId; } QAudioDeviceInfo getDevice() const { return _audioDeviceInfo; } QString deviceName() const { return _deviceName; } bool isDefault() const { return _isDefault; } @@ -48,6 +52,7 @@ private: QString _deviceName{ "" }; bool _isDefault { false }; QAudio::Mode _mode { QAudio::AudioInput }; + QString _uniqueId; }; #endif \ No newline at end of file diff --git a/libraries/audio-client/src/HifiAudioDeviceinfo.cpp b/libraries/audio-client/src/HifiAudioDeviceinfo.cpp index 91a6324c26..0c677a2027 100644 --- a/libraries/audio-client/src/HifiAudioDeviceinfo.cpp +++ b/libraries/audio-client/src/HifiAudioDeviceinfo.cpp @@ -1,4 +1,5 @@ #include "HifiAudioDeviceInfo.h" +#include void HifiAudioDeviceInfo::setDevice(QAudioDeviceInfo devInfo) { _audioDeviceInfo = devInfo; @@ -9,14 +10,18 @@ HifiAudioDeviceInfo& HifiAudioDeviceInfo::operator=(const HifiAudioDeviceInfo& o _deviceName = other.deviceName(); _mode = other.getMode(); _isDefault = other.isDefault(); + _uniqueId = other.getId(); return *this; } bool HifiAudioDeviceInfo::operator==(const HifiAudioDeviceInfo& rhs) const { - return _audioDeviceInfo == rhs.getDevice(); + return _audioDeviceInfo == rhs.getDevice() && getId() == rhs.getId(); } bool HifiAudioDeviceInfo::operator!=(const HifiAudioDeviceInfo& rhs) const { - return _audioDeviceInfo != rhs.getDevice(); + return _audioDeviceInfo != rhs.getDevice() && getId() != rhs.getId(); } +void HifiAudioDeviceInfo::setId(QString name) { + _uniqueId=QString(QCryptographicHash::hash(name.toUtf8().constData(), QCryptographicHash::Md5).toHex()); +} From 66725f5f1b48d7247cb246c590095603d0909bed Mon Sep 17 00:00:00 2001 From: amerhifi Date: Tue, 17 Sep 2019 07:50:22 -0700 Subject: [PATCH 10/27] working on swapping default devices on system change --- interface/src/scripting/AudioDevices.cpp | 2 ++ libraries/audio-client/src/AudioClient.cpp | 28 +++++++++++++++++-- .../audio-client/src/HifiAudioDeviceInfo.h | 2 +- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/interface/src/scripting/AudioDevices.cpp b/interface/src/scripting/AudioDevices.cpp index 7e31d36f7d..b7c2d1e973 100644 --- a/interface/src/scripting/AudioDevices.cpp +++ b/interface/src/scripting/AudioDevices.cpp @@ -121,6 +121,8 @@ AudioDeviceList::~AudioDeviceList() { // store the selected device foreach(std::shared_ptr adevice, _devices) { if (adevice->selectedDesktop) { + qDebug() << "AMER ----> " << adevice->info.getId(); + qDebug() << " AMER-------------> " << adevice->info.deviceName(); settingDesktop.set(adevice->info.deviceName()); } if (adevice->selectedHMD) { diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 4f5edef1b8..a926865025 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -119,6 +119,31 @@ void AudioClient::checkDevices() { auto inputDevices = getAvailableDevices(QAudio::AudioInput); auto outputDevices = getAvailableDevices(QAudio::AudioOutput); + { + Lock lock(_deviceMutex); + //is the current device the default selected device? + if (_inputDeviceInfo.isDefault() && _inputDeviceInfo == _defaultInputDevice) { + auto defInput = defaultAudioDeviceForMode(QAudio::AudioInput); + + //Has the default device changed + if (_defaultInputDevice.getDevice() != defInput.getDevice()) { + qDebug() << "Changing Current Default device " << _defaultInputDevice.getAudioDeviceName(); + _defaultInputDevice.setDevice(defInput.getDevice()); + qDebug() << "NEW Default device " << _defaultInputDevice.getAudioDeviceName(); + QMetaObject::invokeMethod(this, "switchInputToAudioDevice", Qt::QueuedConnection, Q_ARG(HifiAudioDeviceInfo, _defaultInputDevice)); + } + } + + if (_outputDeviceInfo.isDefault() && _inputDeviceInfo == _defaultInputDevice) { + auto defOutput = defaultAudioDeviceForMode(QAudio::AudioOutput); + + if (_defaultOutputDevice.getDevice() != defOutput.getDevice()) { + _defaultOutputDevice.setDevice(defOutput.getDevice()); + QMetaObject::invokeMethod(this, "switchOutputToAudioDevice", Qt::QueuedConnection, Q_ARG(HifiAudioDeviceInfo, _defaultOutputDevice)); + } + } + } + //add the pseudo device to the list of devices inputDevices.push_front(_defaultInputDevice); outputDevices.push_front(_defaultOutputDevice); @@ -342,19 +367,16 @@ AudioClient::AudioClient() : connect(&_receivedAudioStream, &InboundAudioStream::mismatchedAudioCodec, this, &AudioClient::handleMismatchAudioFormat); - _defaultOutputDevice = defaultAudioDeviceForMode(QAudio::AudioOutput); _defaultOutputDevice.setDeviceName("Default audio (recommended)"); _defaultOutputDevice.setIsDefault(true); _defaultOutputDevice.setMode(QAudio::AudioOutput); - _defaultInputDevice = defaultAudioDeviceForMode(QAudio::AudioInput); _defaultInputDevice.setDeviceName("Default microphone (recommended)"); _defaultInputDevice.setIsDefault(true); _defaultInputDevice.setMode(QAudio::AudioInput); - // initialize wasapi; if getAvailableDevices is called from the CheckDevicesThread before this, it will crash getAvailableDevices(QAudio::AudioInput); getAvailableDevices(QAudio::AudioOutput); diff --git a/libraries/audio-client/src/HifiAudioDeviceInfo.h b/libraries/audio-client/src/HifiAudioDeviceInfo.h index e044562a35..2647235e15 100644 --- a/libraries/audio-client/src/HifiAudioDeviceInfo.h +++ b/libraries/audio-client/src/HifiAudioDeviceInfo.h @@ -36,7 +36,7 @@ public: } void setDevice(QAudioDeviceInfo devInfo); void setId(QString name); - + QString getAudioDeviceName() { return _audioDeviceInfo.deviceName(); } QString getId() const { return _uniqueId; } QAudioDeviceInfo getDevice() const { return _audioDeviceInfo; } QString deviceName() const { return _deviceName; } From 065df442f356fd1eebcf5edf033790260a0b72a0 Mon Sep 17 00:00:00 2001 From: amerhifi Date: Tue, 17 Sep 2019 08:01:05 -0700 Subject: [PATCH 11/27] changing work location --- libraries/audio-client/src/AudioClient.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index a926865025..1b5633d5d8 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -120,7 +120,7 @@ void AudioClient::checkDevices() { auto outputDevices = getAvailableDevices(QAudio::AudioOutput); { - Lock lock(_deviceMutex); + //is the current device the default selected device? if (_inputDeviceInfo.isDefault() && _inputDeviceInfo == _defaultInputDevice) { auto defInput = defaultAudioDeviceForMode(QAudio::AudioInput); @@ -130,7 +130,7 @@ void AudioClient::checkDevices() { qDebug() << "Changing Current Default device " << _defaultInputDevice.getAudioDeviceName(); _defaultInputDevice.setDevice(defInput.getDevice()); qDebug() << "NEW Default device " << _defaultInputDevice.getAudioDeviceName(); - QMetaObject::invokeMethod(this, "switchInputToAudioDevice", Qt::QueuedConnection, Q_ARG(HifiAudioDeviceInfo, _defaultInputDevice)); + QMetaObject::invokeMethod(this, "switchAudioDevice", Q_ARG(QAudio::Mode, QAudio::AudioInput), Q_ARG(const HifiAudioDeviceInfo&, _defaultInputDevice)); } } @@ -138,8 +138,10 @@ void AudioClient::checkDevices() { auto defOutput = defaultAudioDeviceForMode(QAudio::AudioOutput); if (_defaultOutputDevice.getDevice() != defOutput.getDevice()) { + qDebug() << "Changing Current Default device " << _defaultOutputDevice.getAudioDeviceName(); _defaultOutputDevice.setDevice(defOutput.getDevice()); - QMetaObject::invokeMethod(this, "switchOutputToAudioDevice", Qt::QueuedConnection, Q_ARG(HifiAudioDeviceInfo, _defaultOutputDevice)); + qDebug() << "NEW Default device " << _defaultOutputDevice.getAudioDeviceName(); + QMetaObject::invokeMethod(this, "switchAudioDevice", Q_ARG(QAudio::Mode, QAudio::AudioOutput), Q_ARG(const HifiAudioDeviceInfo&, _defaultOutputDevice)); } } } From 46f654114af2bb9a13a36ac207e6c22fed521e89 Mon Sep 17 00:00:00 2001 From: amerhifi Date: Tue, 17 Sep 2019 08:03:51 -0700 Subject: [PATCH 12/27] for real, changing location --- libraries/audio-client/src/AudioClient.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 1b5633d5d8..b25f1ff3d5 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -130,7 +130,7 @@ void AudioClient::checkDevices() { qDebug() << "Changing Current Default device " << _defaultInputDevice.getAudioDeviceName(); _defaultInputDevice.setDevice(defInput.getDevice()); qDebug() << "NEW Default device " << _defaultInputDevice.getAudioDeviceName(); - QMetaObject::invokeMethod(this, "switchAudioDevice", Q_ARG(QAudio::Mode, QAudio::AudioInput), Q_ARG(const HifiAudioDeviceInfo&, _defaultInputDevice)); + QMetaObject::invokeMethod(this, "switchAudioDevice", Qt::DirectConnection, Q_ARG(QAudio::Mode, QAudio::AudioInput), Q_ARG(const HifiAudioDeviceInfo&, _defaultInputDevice)); } } @@ -141,7 +141,7 @@ void AudioClient::checkDevices() { qDebug() << "Changing Current Default device " << _defaultOutputDevice.getAudioDeviceName(); _defaultOutputDevice.setDevice(defOutput.getDevice()); qDebug() << "NEW Default device " << _defaultOutputDevice.getAudioDeviceName(); - QMetaObject::invokeMethod(this, "switchAudioDevice", Q_ARG(QAudio::Mode, QAudio::AudioOutput), Q_ARG(const HifiAudioDeviceInfo&, _defaultOutputDevice)); + QMetaObject::invokeMethod(this, "switchAudioDevice",Qt::DirectConnection, Q_ARG(QAudio::Mode, QAudio::AudioOutput), Q_ARG(const HifiAudioDeviceInfo&, _defaultOutputDevice)); } } } From 05a8c7853c8cc8b7065acca31377103c3801fd91 Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Tue, 17 Sep 2019 10:03:54 -0700 Subject: [PATCH 13/27] added file info. moved pragma --- libraries/audio-client/src/HifiAudioDeviceInfo.h | 14 +++++++++++++- libraries/audio-client/src/HifiAudioDeviceinfo.cpp | 12 ++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/libraries/audio-client/src/HifiAudioDeviceInfo.h b/libraries/audio-client/src/HifiAudioDeviceInfo.h index 2647235e15..afce47690c 100644 --- a/libraries/audio-client/src/HifiAudioDeviceInfo.h +++ b/libraries/audio-client/src/HifiAudioDeviceInfo.h @@ -1,6 +1,18 @@ +// +// HifiAudioDeviceInfo.h +// libraries/audio-client/src +// +// Created by Amer Cerkic on 9/14/19. +// Copyright 2019 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#pragma once #ifndef hifi_audiodeviceinfo_h #define hifi_audiodeviceinfo_h -#pragma once + #include #include diff --git a/libraries/audio-client/src/HifiAudioDeviceinfo.cpp b/libraries/audio-client/src/HifiAudioDeviceinfo.cpp index 0c677a2027..9accb7b88b 100644 --- a/libraries/audio-client/src/HifiAudioDeviceinfo.cpp +++ b/libraries/audio-client/src/HifiAudioDeviceinfo.cpp @@ -1,3 +1,15 @@ +// +// HifiAudioDeviceInfo.cpp +// libraries/audio-client/src +// +// Created by Amer Cerkic on 9/14/19. +// Copyright 2019 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + + #include "HifiAudioDeviceInfo.h" #include From a777757c48afaa76bf0da4eedf227f29eac95765 Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Tue, 17 Sep 2019 12:46:38 -0700 Subject: [PATCH 14/27] fixed android build --- interface/src/scripting/Audio.h | 2 +- interface/src/scripting/AudioDevices.h | 2 +- libraries/audio-client/src/AudioClient.cpp | 6 +++--- libraries/audio-client/src/HifiAudioDeviceInfo.h | 5 ++--- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/interface/src/scripting/Audio.h b/interface/src/scripting/Audio.h index ab4fe89ce9..74d85f0107 100644 --- a/interface/src/scripting/Audio.h +++ b/interface/src/scripting/Audio.h @@ -19,7 +19,7 @@ #include "SettingHandle.h" #include "AudioFileWav.h" #include -#include "HifiAudioDeviceInfo.h" +#include using MutedGetter = std::function; using MutedSetter = std::function; diff --git a/interface/src/scripting/AudioDevices.h b/interface/src/scripting/AudioDevices.h index 21cd875f7b..13d97d53dd 100644 --- a/interface/src/scripting/AudioDevices.h +++ b/interface/src/scripting/AudioDevices.h @@ -19,7 +19,7 @@ #include #include -#include "HifiAudioDeviceInfo.h" +#include namespace scripting { diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index b25f1ff3d5..808d264304 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -634,7 +634,7 @@ HifiAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { for (auto inputDevice : inputDevices) { if (((headsetOn || !aecEnabled) && inputDevice.deviceName() == VOICE_RECOGNITION) || ((!headsetOn && aecEnabled) && inputDevice.deviceName() == VOICE_COMMUNICATION)) { - return inputDevice; + return HifiAudioDeviceInfo(inputDevice,false,QAudio::AudioInput); } } } @@ -2025,11 +2025,11 @@ void AudioClient::checkInputTimeout() { void AudioClient::setHeadsetPluggedIn(bool pluggedIn) { #if defined(Q_OS_ANDROID) - if (pluggedIn == !_isHeadsetPluggedIn && !_inputDeviceInfo.isNull()) { + if (pluggedIn == !_isHeadsetPluggedIn && !_inputDeviceInfo.getDevice().isNull()) { QAndroidJniObject brand = QAndroidJniObject::getStaticObjectField("android/os/Build", "BRAND"); // some samsung phones needs more time to shutdown the previous input device if (brand.toString().contains("samsung", Qt::CaseInsensitive)) { - switchInputToAudioDevice(QAudioDeviceInfo(), true); + switchInputToAudioDevice(HifiAudioDeviceInfo(), true); QThread::msleep(200); } diff --git a/libraries/audio-client/src/HifiAudioDeviceInfo.h b/libraries/audio-client/src/HifiAudioDeviceInfo.h index afce47690c..030bee8cfa 100644 --- a/libraries/audio-client/src/HifiAudioDeviceInfo.h +++ b/libraries/audio-client/src/HifiAudioDeviceInfo.h @@ -33,10 +33,9 @@ public: } HifiAudioDeviceInfo(QAudioDeviceInfo deviceInfo, bool isDefault, QAudio::Mode mode) : + _audioDeviceInfo(deviceInfo), _isDefault(isDefault), - _mode(mode), - _audioDeviceInfo(deviceInfo){ - + _mode(mode){ setDeviceName(deviceInfo.deviceName()); } From 7a9020a429968b46ff8ee149e32d10f4dc789973 Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Tue, 17 Sep 2019 14:16:25 -0700 Subject: [PATCH 15/27] renamed file to match class --- .../src/{HifiAudioDeviceinfo.cpp => HifiAudioDeviceInfo.cpp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename libraries/audio-client/src/{HifiAudioDeviceinfo.cpp => HifiAudioDeviceInfo.cpp} (100%) diff --git a/libraries/audio-client/src/HifiAudioDeviceinfo.cpp b/libraries/audio-client/src/HifiAudioDeviceInfo.cpp similarity index 100% rename from libraries/audio-client/src/HifiAudioDeviceinfo.cpp rename to libraries/audio-client/src/HifiAudioDeviceInfo.cpp From c1854d34388d57ec8de56d92fe70801b94a1117c Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Tue, 17 Sep 2019 14:42:35 -0700 Subject: [PATCH 16/27] fixing gnu warnings and removing debug output --- interface/src/scripting/AudioDevices.cpp | 2 -- libraries/audio-client/src/HifiAudioDeviceInfo.h | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/interface/src/scripting/AudioDevices.cpp b/interface/src/scripting/AudioDevices.cpp index b7c2d1e973..7e31d36f7d 100644 --- a/interface/src/scripting/AudioDevices.cpp +++ b/interface/src/scripting/AudioDevices.cpp @@ -121,8 +121,6 @@ AudioDeviceList::~AudioDeviceList() { // store the selected device foreach(std::shared_ptr adevice, _devices) { if (adevice->selectedDesktop) { - qDebug() << "AMER ----> " << adevice->info.getId(); - qDebug() << " AMER-------------> " << adevice->info.deviceName(); settingDesktop.set(adevice->info.deviceName()); } if (adevice->selectedHMD) { diff --git a/libraries/audio-client/src/HifiAudioDeviceInfo.h b/libraries/audio-client/src/HifiAudioDeviceInfo.h index 030bee8cfa..3f6fc7fc36 100644 --- a/libraries/audio-client/src/HifiAudioDeviceInfo.h +++ b/libraries/audio-client/src/HifiAudioDeviceInfo.h @@ -24,11 +24,10 @@ class HifiAudioDeviceInfo : public QObject { public: HifiAudioDeviceInfo() : QObject() {} - HifiAudioDeviceInfo(const HifiAudioDeviceInfo &deviceInfo){ + HifiAudioDeviceInfo(const HifiAudioDeviceInfo &deviceInfo) : QObject(){ _audioDeviceInfo = deviceInfo.getDevice(); _mode = deviceInfo.getMode(); _isDefault = deviceInfo.isDefault(); - setDeviceName(deviceInfo.deviceName()); } From 46b9496965b64f685a07dd6aeba007626a76a794 Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Tue, 17 Sep 2019 16:02:20 -0700 Subject: [PATCH 17/27] fixing mac build error --- libraries/audio-client/src/AudioClient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 808d264304..4ebd21f349 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -568,7 +568,7 @@ HifiAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { if (!getPropertyError && propertySize) { // find a device in the list that matches the name we have and return it - foreach (AudioDeviceInfo audioDevice, getAvailableDevices(mode)) { + foreach (HifiAudioDeviceInfo audioDevice, getAvailableDevices(mode)) { if (audioDevice.deviceName() == CFStringGetCStringPtr(deviceName, kCFStringEncodingMacRoman)) { return audioDevice; } From d4dc06d2e7e12960a6c57fe81d792b2693282f9b Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Wed, 18 Sep 2019 12:44:03 -0700 Subject: [PATCH 18/27] fixed issue with null device on load. --- libraries/audio-client/src/AudioClient.cpp | 15 ++++++++++++++- libraries/audio-client/src/AudioClient.h | 2 ++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 4ebd21f349..48eaf9fa5d 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -481,6 +481,19 @@ void AudioClient::setAudioPaused(bool pause) { } } + +HifiAudioDeviceInfo AudioClient::getNamedAudioDevice(QAudio::Mode mode, const QString& deviceName) { + HifiAudioDeviceInfo result; + + foreach(HifiAudioDeviceInfo audioDevice, getAudioDevices(mode)) { + if (audioDevice.deviceName().trimmed() == deviceName.trimmed()) { + result = audioDevice; + break; + } + } + return result; +} + HifiAudioDeviceInfo getNamedAudioDeviceForMode(QAudio::Mode mode, const QString& deviceName) { HifiAudioDeviceInfo result; foreach (HifiAudioDeviceInfo audioDevice, getAvailableDevices(mode)) { @@ -1043,7 +1056,7 @@ bool AudioClient::switchAudioDevice(QAudio::Mode mode, const HifiAudioDeviceInfo } bool AudioClient::switchAudioDevice(QAudio::Mode mode, const QString& deviceName) { - return switchAudioDevice(mode, getNamedAudioDeviceForMode(mode, deviceName)); + return switchAudioDevice(mode, getNamedAudioDevice(mode, deviceName)); } void AudioClient::configureReverb() { diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index bbc22ba93d..4faa9f1117 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -126,6 +126,8 @@ public: const MixedProcessedAudioStream& getReceivedAudioStream() const { return _receivedAudioStream; } MixedProcessedAudioStream& getReceivedAudioStream() { return _receivedAudioStream; } + + HifiAudioDeviceInfo getNamedAudioDevice(QAudio::Mode mode, const QString& deviceName); const QAudioFormat& getOutputFormat() const { return _outputFormat; } From ecca898db87bbc00b96b1f088c9a0c9b6cb3d7d3 Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Wed, 18 Sep 2019 14:39:55 -0700 Subject: [PATCH 19/27] fixed some more vs clang reformatting --- libraries/audio-client/src/AudioClient.cpp | 109 +++++++++++---------- libraries/audio-client/src/AudioClient.h | 12 +-- 2 files changed, 61 insertions(+), 60 deletions(-) diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 48eaf9fa5d..14f9a3a5bc 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -81,7 +81,7 @@ static const int STARVE_DETECTION_THRESHOLD = 3; static const int STARVE_DETECTION_PERIOD = 10 * 1000; // 10 Seconds Setting::Handle dynamicJitterBufferEnabled("dynamicJitterBuffersEnabled", - InboundAudioStream::DEFAULT_DYNAMIC_JITTER_BUFFER_ENABLED); + InboundAudioStream::DEFAULT_DYNAMIC_JITTER_BUFFER_ENABLED); Setting::Handle staticJitterBufferFrames("staticJitterBufferFrames", InboundAudioStream::DEFAULT_STATIC_JITTER_FRAMES); @@ -90,6 +90,7 @@ using Mutex = std::mutex; using Lock = std::unique_lock; Mutex _deviceMutex; Mutex _recordMutex; + HifiAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode); // thread-safe @@ -199,7 +200,7 @@ static void channelUpmix(int16_t* source, int16_t* dest, int numSamples, int num } static void channelDownmix(int16_t* source, int16_t* dest, int numSamples) { - for (int i = 0; i < numSamples / 2; i++) { + for (int i = 0; i < numSamples/2; i++) { // read 2 samples int16_t left = *source++; @@ -212,8 +213,8 @@ static void channelDownmix(int16_t* source, int16_t* dest, int numSamples) { static bool detectClipping(int16_t* samples, int numSamples, int numChannels) { - const int32_t CLIPPING_THRESHOLD = 32392; // -0.1 dBFS - const int CLIPPING_DETECTION = 3; // consecutive samples over threshold + const int32_t CLIPPING_THRESHOLD = 32392; // -0.1 dBFS + const int CLIPPING_DETECTION = 3; // consecutive samples over threshold bool isClipping = false; @@ -298,46 +299,46 @@ static inline float convertToFloat(int16_t sample) { } AudioClient::AudioClient() : - AbstractAudioInterface(), - _gate(this), - _audioInput(NULL), - _dummyAudioInput(NULL), - _desiredInputFormat(), + AbstractAudioInterface(), + _gate(this), + _audioInput(NULL), + _dummyAudioInput(NULL), + _desiredInputFormat(), _inputFormat(), - _numInputCallbackBytes(0), - _audioOutput(NULL), - _desiredOutputFormat(), - _outputFormat(), + _numInputCallbackBytes(0), + _audioOutput(NULL), + _desiredOutputFormat(), + _outputFormat(), _outputFrameSize(0), - _numOutputCallbackBytes(0), - _loopbackAudioOutput(NULL), - _loopbackOutputDevice(NULL), + _numOutputCallbackBytes(0), + _loopbackAudioOutput(NULL), + _loopbackOutputDevice(NULL), _inputRingBuffer(0), - _localInjectorsStream(0, 1), - _receivedAudioStream(RECEIVED_AUDIO_STREAM_CAPACITY_FRAMES), + _localInjectorsStream(0, 1), + _receivedAudioStream(RECEIVED_AUDIO_STREAM_CAPACITY_FRAMES), _isStereoInput(false), - _outputStarveDetectionStartTimeMsec(0), + _outputStarveDetectionStartTimeMsec(0), _outputStarveDetectionCount(0), _outputBufferSizeFrames("audioOutputBufferFrames", DEFAULT_BUFFER_FRAMES), _sessionOutputBufferSizeFrames(_outputBufferSizeFrames.get()), _outputStarveDetectionEnabled("audioOutputStarveDetectionEnabled", DEFAULT_STARVE_DETECTION_ENABLED), - _lastRawInputLoudness(0.0f), + _lastRawInputLoudness(0.0f), _lastSmoothedRawInputLoudness(0.0f), _lastInputLoudness(0.0f), _timeSinceLastClip(-1.0f), - _muted(false), - _shouldEchoLocally(false), - _shouldEchoToServer(false), - _isNoiseGateEnabled(true), + _muted(false), + _shouldEchoLocally(false), + _shouldEchoToServer(false), + _isNoiseGateEnabled(true), _isAECEnabled(true), - _reverb(false), + _reverb(false), _reverbOptions(&_scriptReverbOptions), _inputToNetworkResampler(NULL), _networkToOutputResampler(NULL), - _localToOutputResampler(NULL), - _loopbackResampler(NULL), + _localToOutputResampler(NULL), + _loopbackResampler(NULL), _audioLimiter(AudioConstants::SAMPLE_RATE, OUTPUT_CHANNEL_COUNT), - _outgoingAvatarAudioSequenceNumber(0), + _outgoingAvatarAudioSequenceNumber(0), _audioOutputIODevice(_localInjectorsStream, _receivedAudioStream, this), _stats(&_receivedAudioStream), _positionGetter(DEFAULT_POSITION_GETTER), @@ -360,8 +361,8 @@ AudioClient::AudioClient() : Setting::Handle::Deprecated("repetitionWithFade", InboundAudioStream::REPETITION_WITH_FADE); } - connect(&_receivedAudioStream, &MixedProcessedAudioStream::processSamples, - this, &AudioClient::processReceivedSamples, Qt::DirectConnection); + connect(&_receivedAudioStream, &MixedProcessedAudioStream::processSamples, + this, &AudioClient::processReceivedSamples, Qt::DirectConnection); connect(this, &AudioClient::changeDevice, this, [=](const HifiAudioDeviceInfo& outputDeviceInfo) { qCDebug(audioclient)<< "got AudioClient::changeDevice signal, about to call switchOutputToAudioDevice() outputDeviceInfo: ["<< outputDeviceInfo.deviceName() << "]"; switchOutputToAudioDevice(outputDeviceInfo); @@ -400,7 +401,7 @@ AudioClient::AudioClient() : // start a thread to detect peak value changes _checkPeakValuesTimer = new QTimer(this); - connect(_checkPeakValuesTimer, &QTimer::timeout, this, [this] { + connect(_checkPeakValuesTimer, &QTimer::timeout, this, [this] { QtConcurrent::run(QThreadPool::globalInstance(), [this] { checkPeakValues(); }); }); const unsigned long PEAK_VALUES_CHECK_INTERVAL_MSECS = 50; @@ -424,8 +425,8 @@ AudioClient::AudioClient() : auto& domainHandler = nodeList->getDomainHandler(); connect(&domainHandler, &DomainHandler::disconnectedFromDomain, this, [this] { - _solo.reset(); - }); + _solo.reset(); + }); connect(nodeList.data(), &NodeList::nodeActivated, this, [this](SharedNodePointer node) { if (node->getType() == NodeType::AudioMixer) { _solo.resend(); @@ -581,7 +582,7 @@ HifiAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { if (!getPropertyError && propertySize) { // find a device in the list that matches the name we have and return it - foreach (HifiAudioDeviceInfo audioDevice, getAvailableDevices(mode)) { + foreach(HifiAudioDeviceInfo audioDevice, getAvailableDevices(mode)) { if (audioDevice.deviceName() == CFStringGetCStringPtr(deviceName, kCFStringEncodingMacRoman)) { return audioDevice; } @@ -593,7 +594,7 @@ HifiAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { #ifdef WIN32 QString deviceName; //Check for Windows Vista or higher, IMMDeviceEnumerator doesn't work below that. - if (!IsWindowsVistaOrGreater()) { // lower then vista + if (!IsWindowsVistaOrGreater()) { // lower then vista if (mode == QAudio::AudioInput) { WAVEINCAPS wic; // first use WAVE_MAPPER to get the default devices manufacturer ID @@ -632,12 +633,12 @@ HifiAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { } qCDebug(audioclient) << "defaultAudioDeviceForMode mode: " << (mode == QAudio::AudioOutput ? "Output" : "Input") - << " [" << deviceName << "] [" << getNamedAudioDeviceForMode(mode, deviceName).deviceName() << "]"; + << " [" << deviceName << "] [" << getNamedAudioDeviceForMode(mode, deviceName).deviceName() << "]"; return getNamedAudioDeviceForMode(mode, deviceName); #endif -#if defined(Q_OS_ANDROID) +#if defined (Q_OS_ANDROID) if (mode == QAudio::AudioInput) { Setting::Handle enableAEC(SETTING_AEC_KEY, DEFAULT_AEC_ENABLED); bool aecEnabled = enableAEC.get(); @@ -646,7 +647,7 @@ HifiAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { auto inputDevices = QAudioDeviceInfo::availableDevices(QAudio::AudioInput); for (auto inputDevice : inputDevices) { if (((headsetOn || !aecEnabled) && inputDevice.deviceName() == VOICE_RECOGNITION) || - ((!headsetOn && aecEnabled) && inputDevice.deviceName() == VOICE_COMMUNICATION)) { + ((!headsetOn && aecEnabled) && inputDevice.deviceName() == VOICE_COMMUNICATION)) { return HifiAudioDeviceInfo(inputDevice,false,QAudio::AudioInput); } } @@ -742,7 +743,7 @@ bool adjustedFormatForAudioDevice(const QAudioDeviceInfo& audioDevice, } } - return false; // a supported format could not be found + return false; // a supported format could not be found } bool sampleChannelConversion(const int16_t* sourceSamples, int16_t* destinationSamples, int numSourceSamples, @@ -1045,12 +1046,12 @@ bool AudioClient::switchAudioDevice(QAudio::Mode mode, const HifiAudioDeviceInfo auto device = deviceInfo; if (device.getDevice().isNull()) { - device=defaultAudioDeviceForMode(mode); + device = defaultAudioDeviceForMode(mode); } if (mode == QAudio::AudioInput) { return switchInputToAudioDevice(device); - } else { // if (mode == QAudio::AudioOutput) + } else { return switchOutputToAudioDevice(device); } } @@ -1092,7 +1093,7 @@ void AudioClient::configureReverb() { p.sampleRate = _outputFormat.sampleRate(); p.wetDryMix = 100.0f; p.preDelay = 0.0f; - p.earlyGain = -96.0f; // disable ER + p.earlyGain = -96.0f; // disable ER p.lateGain += _reverbOptions->getWetDryMix() * (24.0f / 100.0f) - 24.0f; // -0dB to -24dB, based on wetDryMix p.lateMixLeft = 0.0f; p.lateMixRight = 0.0f; @@ -1173,8 +1174,8 @@ static void deinterleaveToFloat(const int16_t* src, float* const* dst, int numFr for (int i = 0; i < numFrames; i++) { for (int ch = 0; ch < numChannels; ch++) { float f = *src++; - f *= (1 / 32768.0f); // scale - dst[ch][i] = f; // deinterleave + f *= (1/32768.0f); // scale + dst[ch][i] = f; // deinterleave } } } @@ -1183,10 +1184,10 @@ static void interleaveToInt16(const float* const* src, int16_t* dst, int numFram for (int i = 0; i < numFrames; i++) { for (int ch = 0; ch < numChannels; ch++) { float f = src[ch][i]; - f *= 32768.0f; // scale - f += (f < 0.0f) ? -0.5f : 0.5f; // round - f = std::max(std::min(f, 32767.0f), -32768.0f); // saturate - *dst++ = (int16_t)f; // interleave + f *= 32768.0f; // scale + f += (f < 0.0f) ? -0.5f : 0.5f; // round + f = std::max(std::min(f, 32767.0f), -32768.0f); // saturate + *dst++ = (int16_t)f; // interleave } } } @@ -1290,7 +1291,7 @@ void AudioClient::processWebrtcNearEnd(int16_t* samples, int numFrames, int numC } } -#endif // WEBRTC_ENABLED +#endif // WEBRTC_ENABLED void AudioClient::handleLocalEchoAndReverb(QByteArray& inputByteArray) { // If there is server echo, reverb will be applied to the recieved audio stream so no need to have it here. @@ -1343,7 +1344,7 @@ void AudioClient::handleLocalEchoAndReverb(QByteArray& inputByteArray) { // apply stereo reverb at the source, to the loopback audio if (!_shouldEchoLocally && hasReverb) { updateReverbOptions(); - _sourceReverb.render(loopbackSamples, loopbackSamples, numLoopbackSamples / 2); + _sourceReverb.render(loopbackSamples, loopbackSamples, numLoopbackSamples/2); } // if required, upmix or downmix to deviceChannelCount @@ -1549,7 +1550,7 @@ void AudioClient::prepareLocalAudioInjectors(std::unique_ptr localAudioLoc if (_localToOutputResampler) { maxOutputSamples = _localToOutputResampler->getMaxOutput(AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL) * - AudioConstants::STEREO; + AudioConstants::STEREO; } samplesNeeded = bufferCapacity - _localSamplesAvailable.load(std::memory_order_relaxed); @@ -1572,7 +1573,7 @@ void AudioClient::prepareLocalAudioInjectors(std::unique_ptr localAudioLoc if (_localToOutputResampler) { // resample to output sample rate int frames = _localToOutputResampler->render(_localMixBuffer, _localOutputMixBuffer, - AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL); + AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL); // write to local injectors' ring buffer samples = frames * AudioConstants::STEREO; @@ -1857,7 +1858,7 @@ int AudioClient::getNumLocalInjectors() { void AudioClient::outputFormatChanged() { _outputFrameSize = (AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * OUTPUT_CHANNEL_COUNT * _outputFormat.sampleRate()) / - _desiredOutputFormat.sampleRate(); + _desiredOutputFormat.sampleRate(); _receivedAudioStream.outputFormatChanged(_outputFormat.sampleRate(), OUTPUT_CHANNEL_COUNT); } @@ -2323,7 +2324,7 @@ float AudioClient::gainForSource(float distance, float volume) { return gain; } -qint64 AudioClient::AudioOutputIODevice::readData(char* data, qint64 maxSize) { +qint64 AudioClient::AudioOutputIODevice::readData(char * data, qint64 maxSize) { // lock-free wait for initialization to avoid races if (!_audio->_audioOutputInitialized.load(std::memory_order_acquire)) { diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index 4faa9f1117..038914d639 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -65,7 +65,7 @@ #pragma warning( pop ) #endif -#if defined(Q_OS_ANDROID) +#if defined (Q_OS_ANDROID) #define VOICE_RECOGNITION "voicerecognition" #define VOICE_COMMUNICATION "voicecommunication" @@ -98,7 +98,7 @@ public: class AudioOutputIODevice : public QIODevice { public: AudioOutputIODevice(LocalInjectorsStream& localInjectorsStream, MixedProcessedAudioStream& receivedAudioStream, - AudioClient* audio) : + AudioClient* audio) : _localInjectorsStream(localInjectorsStream), _receivedAudioStream(receivedAudioStream), _audio(audio), _unfulfilledReads(0) {} @@ -374,9 +374,9 @@ private: StDev _stdev; QElapsedTimer _timeSinceLastReceived; - float _lastRawInputLoudness; // before mute/gate + float _lastRawInputLoudness; // before mute/gate float _lastSmoothedRawInputLoudness; - float _lastInputLoudness; // after mute/gate + float _lastInputLoudness; // after mute/gate float _timeSinceLastClip; int _totalInputAudioSamples; @@ -433,7 +433,7 @@ private: webrtc::AudioProcessing* _apm { nullptr }; int16_t _fifoFarEnd[WEBRTC_CHANNELS_MAX * WEBRTC_FRAMES_MAX] {}; - int _numFifoFarEnd = 0; // numFrames saved in fifo + int _numFifoFarEnd = 0; // numFrames saved in fifo void configureWebrtc(); void processWebrtcFarEnd(const int16_t* samples, int numFrames, int numChannels, int sampleRate); @@ -504,4 +504,4 @@ private: }; -#endif // hifi_AudioClient_h \ No newline at end of file +#endif // hifi_AudioClient_h \ No newline at end of file From be2fff13d254ec937fceabbdc25903430e076678 Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Wed, 18 Sep 2019 17:10:12 -0700 Subject: [PATCH 20/27] fixed wrong device in if block --- libraries/audio-client/src/AudioClient.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 14f9a3a5bc..54ca2d3f31 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -122,7 +122,7 @@ void AudioClient::checkDevices() { { - //is the current device the default selected device? + //is the current device the default?, if so has the underlying QAudioDeviceInfo changed from the os call if (_inputDeviceInfo.isDefault() && _inputDeviceInfo == _defaultInputDevice) { auto defInput = defaultAudioDeviceForMode(QAudio::AudioInput); @@ -134,8 +134,9 @@ void AudioClient::checkDevices() { QMetaObject::invokeMethod(this, "switchAudioDevice", Qt::DirectConnection, Q_ARG(QAudio::Mode, QAudio::AudioInput), Q_ARG(const HifiAudioDeviceInfo&, _defaultInputDevice)); } } - - if (_outputDeviceInfo.isDefault() && _inputDeviceInfo == _defaultInputDevice) { + + //is the current device the default?, if so has the underlying QAudioDeviceInfo changed from the os call + if (_outputDeviceInfo.isDefault() && _outputDeviceInfo == _defaultOutputDevice) { auto defOutput = defaultAudioDeviceForMode(QAudio::AudioOutput); if (_defaultOutputDevice.getDevice() != defOutput.getDevice()) { From 9cc3b7a5c78cd86b582108bcc32a76505fc86478 Mon Sep 17 00:00:00 2001 From: amerhifi Date: Thu, 19 Sep 2019 10:08:30 -0700 Subject: [PATCH 21/27] addressing pr comments --- interface/src/scripting/AudioDevices.cpp | 17 +++++++++++++---- libraries/audio-client/src/AudioClient.cpp | 16 +++++++--------- .../audio-client/src/HifiAudioDeviceInfo.cpp | 12 +++--------- .../audio-client/src/HifiAudioDeviceInfo.h | 14 ++------------ 4 files changed, 25 insertions(+), 34 deletions(-) diff --git a/interface/src/scripting/AudioDevices.cpp b/interface/src/scripting/AudioDevices.cpp index 7e31d36f7d..0f8a9ee0c5 100644 --- a/interface/src/scripting/AudioDevices.cpp +++ b/interface/src/scripting/AudioDevices.cpp @@ -283,10 +283,19 @@ void AudioDeviceList::onDevicesChanged(const QList& devices foreach(const HifiAudioDeviceInfo& deviceInfo, devices) { AudioDevice device; device.info = deviceInfo; - device.display = device.info.deviceName() - .replace("High Definition", "HD") - .remove("Device") - .replace(" )", ")"); + + if (deviceInfo.isDefault()) { + if (deviceInfo.getMode() == QAudio::AudioInput) { + device.display = "Default microphone (recommended)"; + } else { + device.display = "Default audio (recommended)"; + } + } else { + device.display = device.info.deviceName() + .replace("High Definition", "HD") + .remove("Device") + .replace(" )", ")"); + } for (bool isHMD : {false, true}) { HifiAudioDeviceInfo& selectedDevice = isHMD ? _selectedHMDDevice : _selectedDesktopDevice; diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 54ca2d3f31..570a7c6c92 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -123,14 +123,14 @@ void AudioClient::checkDevices() { { //is the current device the default?, if so has the underlying QAudioDeviceInfo changed from the os call - if (_inputDeviceInfo.isDefault() && _inputDeviceInfo == _defaultInputDevice) { + if (_inputDeviceInfo.isDefault()) { auto defInput = defaultAudioDeviceForMode(QAudio::AudioInput); //Has the default device changed if (_defaultInputDevice.getDevice() != defInput.getDevice()) { - qDebug() << "Changing Current Default device " << _defaultInputDevice.getAudioDeviceName(); + qDebug() << "Changing Current Default device " << _defaultInputDevice.deviceName(); _defaultInputDevice.setDevice(defInput.getDevice()); - qDebug() << "NEW Default device " << _defaultInputDevice.getAudioDeviceName(); + qDebug() << "NEW Default device " << _defaultInputDevice.deviceName(); QMetaObject::invokeMethod(this, "switchAudioDevice", Qt::DirectConnection, Q_ARG(QAudio::Mode, QAudio::AudioInput), Q_ARG(const HifiAudioDeviceInfo&, _defaultInputDevice)); } } @@ -140,9 +140,9 @@ void AudioClient::checkDevices() { auto defOutput = defaultAudioDeviceForMode(QAudio::AudioOutput); if (_defaultOutputDevice.getDevice() != defOutput.getDevice()) { - qDebug() << "Changing Current Default device " << _defaultOutputDevice.getAudioDeviceName(); + qDebug() << "Changing Current Default device " << _defaultOutputDevice.deviceName(); _defaultOutputDevice.setDevice(defOutput.getDevice()); - qDebug() << "NEW Default device " << _defaultOutputDevice.getAudioDeviceName(); + qDebug() << "NEW Default device " << _defaultOutputDevice.deviceName(); QMetaObject::invokeMethod(this, "switchAudioDevice",Qt::DirectConnection, Q_ARG(QAudio::Mode, QAudio::AudioOutput), Q_ARG(const HifiAudioDeviceInfo&, _defaultOutputDevice)); } } @@ -372,12 +372,10 @@ AudioClient::AudioClient() : connect(&_receivedAudioStream, &InboundAudioStream::mismatchedAudioCodec, this, &AudioClient::handleMismatchAudioFormat); _defaultOutputDevice = defaultAudioDeviceForMode(QAudio::AudioOutput); - _defaultOutputDevice.setDeviceName("Default audio (recommended)"); _defaultOutputDevice.setIsDefault(true); _defaultOutputDevice.setMode(QAudio::AudioOutput); _defaultInputDevice = defaultAudioDeviceForMode(QAudio::AudioInput); - _defaultInputDevice.setDeviceName("Default microphone (recommended)"); _defaultInputDevice.setIsDefault(true); _defaultInputDevice.setMode(QAudio::AudioInput); @@ -649,7 +647,7 @@ HifiAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { for (auto inputDevice : inputDevices) { if (((headsetOn || !aecEnabled) && inputDevice.deviceName() == VOICE_RECOGNITION) || ((!headsetOn && aecEnabled) && inputDevice.deviceName() == VOICE_COMMUNICATION)) { - return HifiAudioDeviceInfo(inputDevice,false,QAudio::AudioInput); + return HifiAudioDeviceInfo(inputDevice, false, QAudio::AudioInput); } } } @@ -1866,7 +1864,7 @@ void AudioClient::outputFormatChanged() { bool AudioClient::switchInputToAudioDevice(const HifiAudioDeviceInfo inputDeviceInfo, bool isShutdownRequest) { Q_ASSERT_X(QThread::currentThread() == thread(), Q_FUNC_INFO, "Function invoked on wrong thread"); - qCDebug(audioclient) << __FUNCTION__ << "inputDeviceInfo: [" << inputDeviceInfo.getDevice().deviceName() << "]"; + qCDebug(audioclient) << __FUNCTION__ << "inputDeviceInfo: [" << inputDeviceInfo.deviceName() <<"----"< void HifiAudioDeviceInfo::setDevice(QAudioDeviceInfo devInfo) { _audioDeviceInfo = devInfo; @@ -19,21 +18,16 @@ void HifiAudioDeviceInfo::setDevice(QAudioDeviceInfo devInfo) { HifiAudioDeviceInfo& HifiAudioDeviceInfo::operator=(const HifiAudioDeviceInfo& other) { _audioDeviceInfo = other.getDevice(); - _deviceName = other.deviceName(); _mode = other.getMode(); _isDefault = other.isDefault(); - _uniqueId = other.getId(); return *this; } + bool HifiAudioDeviceInfo::operator==(const HifiAudioDeviceInfo& rhs) const { - return _audioDeviceInfo == rhs.getDevice() && getId() == rhs.getId(); + return getDevice() == rhs.getDevice() && isDefault() == rhs.isDefault(); } - bool HifiAudioDeviceInfo::operator!=(const HifiAudioDeviceInfo& rhs) const { - return _audioDeviceInfo != rhs.getDevice() && getId() != rhs.getId(); + return getDevice() != rhs.getDevice() && isDefault() != rhs.isDefault(); } -void HifiAudioDeviceInfo::setId(QString name) { - _uniqueId=QString(QCryptographicHash::hash(name.toUtf8().constData(), QCryptographicHash::Md5).toHex()); -} diff --git a/libraries/audio-client/src/HifiAudioDeviceInfo.h b/libraries/audio-client/src/HifiAudioDeviceInfo.h index 3f6fc7fc36..74fe2b37d0 100644 --- a/libraries/audio-client/src/HifiAudioDeviceInfo.h +++ b/libraries/audio-client/src/HifiAudioDeviceInfo.h @@ -28,28 +28,20 @@ public: _audioDeviceInfo = deviceInfo.getDevice(); _mode = deviceInfo.getMode(); _isDefault = deviceInfo.isDefault(); - setDeviceName(deviceInfo.deviceName()); } HifiAudioDeviceInfo(QAudioDeviceInfo deviceInfo, bool isDefault, QAudio::Mode mode) : _audioDeviceInfo(deviceInfo), _isDefault(isDefault), _mode(mode){ - setDeviceName(deviceInfo.deviceName()); } void setMode(QAudio::Mode mode) { _mode = mode; } void setIsDefault(bool isDefault = false) { _isDefault = isDefault; } - void setDeviceName(QString name) { - _deviceName = name; - setId(name); - } + void setDevice(QAudioDeviceInfo devInfo); - void setId(QString name); - QString getAudioDeviceName() { return _audioDeviceInfo.deviceName(); } - QString getId() const { return _uniqueId; } + QString deviceName() const { return _audioDeviceInfo.deviceName(); } QAudioDeviceInfo getDevice() const { return _audioDeviceInfo; } - QString deviceName() const { return _deviceName; } bool isDefault() const { return _isDefault; } QAudio::Mode getMode() const { return _mode; } @@ -59,10 +51,8 @@ public: private: QAudioDeviceInfo _audioDeviceInfo; - QString _deviceName{ "" }; bool _isDefault { false }; QAudio::Mode _mode { QAudio::AudioInput }; - QString _uniqueId; }; #endif \ No newline at end of file From 8d7c28fe8339fc28b38f62d3d4fba6512a8e7dd4 Mon Sep 17 00:00:00 2001 From: amerhifi Date: Thu, 19 Sep 2019 14:19:43 -0700 Subject: [PATCH 22/27] fixed audio switching issues. removed risky access to properties. adressing comments --- libraries/audio-client/src/AudioClient.cpp | 104 ++++++------------ libraries/audio-client/src/AudioClient.h | 7 +- .../audio-client/src/HifiAudioDeviceInfo.h | 10 +- 3 files changed, 41 insertions(+), 80 deletions(-) diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 570a7c6c92..a8a627ffab 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -119,38 +119,19 @@ void AudioClient::checkDevices() { auto inputDevices = getAvailableDevices(QAudio::AudioInput); auto outputDevices = getAvailableDevices(QAudio::AudioOutput); + + auto defInput = defaultAudioDeviceForMode(QAudio::AudioInput); + defInput.setIsDefault(true); - { - - //is the current device the default?, if so has the underlying QAudioDeviceInfo changed from the os call - if (_inputDeviceInfo.isDefault()) { - auto defInput = defaultAudioDeviceForMode(QAudio::AudioInput); - - //Has the default device changed - if (_defaultInputDevice.getDevice() != defInput.getDevice()) { - qDebug() << "Changing Current Default device " << _defaultInputDevice.deviceName(); - _defaultInputDevice.setDevice(defInput.getDevice()); - qDebug() << "NEW Default device " << _defaultInputDevice.deviceName(); - QMetaObject::invokeMethod(this, "switchAudioDevice", Qt::DirectConnection, Q_ARG(QAudio::Mode, QAudio::AudioInput), Q_ARG(const HifiAudioDeviceInfo&, _defaultInputDevice)); - } - } - - //is the current device the default?, if so has the underlying QAudioDeviceInfo changed from the os call - if (_outputDeviceInfo.isDefault() && _outputDeviceInfo == _defaultOutputDevice) { - auto defOutput = defaultAudioDeviceForMode(QAudio::AudioOutput); - - if (_defaultOutputDevice.getDevice() != defOutput.getDevice()) { - qDebug() << "Changing Current Default device " << _defaultOutputDevice.deviceName(); - _defaultOutputDevice.setDevice(defOutput.getDevice()); - qDebug() << "NEW Default device " << _defaultOutputDevice.deviceName(); - QMetaObject::invokeMethod(this, "switchAudioDevice",Qt::DirectConnection, Q_ARG(QAudio::Mode, QAudio::AudioOutput), Q_ARG(const HifiAudioDeviceInfo&, _defaultOutputDevice)); - } - } - } - + auto defOutput = defaultAudioDeviceForMode(QAudio::AudioOutput); + defOutput.setIsDefault(true); + //add the pseudo device to the list of devices - inputDevices.push_front(_defaultInputDevice); - outputDevices.push_front(_defaultOutputDevice); + inputDevices.push_front(defInput); + outputDevices.push_front(defOutput); + + QMetaObject::invokeMethod(this, "changeDefault", Q_ARG(HifiAudioDeviceInfo, defInput), Q_ARG(QAudio::Mode, QAudio::AudioInput)); + QMetaObject::invokeMethod(this, "changeDefault", Q_ARG(HifiAudioDeviceInfo, defOutput), Q_ARG(QAudio::Mode, QAudio::AudioOutput)); Lock lock(_deviceMutex); if (inputDevices != _inputDevices) { @@ -371,14 +352,6 @@ AudioClient::AudioClient() : connect(&_receivedAudioStream, &InboundAudioStream::mismatchedAudioCodec, this, &AudioClient::handleMismatchAudioFormat); - _defaultOutputDevice = defaultAudioDeviceForMode(QAudio::AudioOutput); - _defaultOutputDevice.setIsDefault(true); - _defaultOutputDevice.setMode(QAudio::AudioOutput); - - _defaultInputDevice = defaultAudioDeviceForMode(QAudio::AudioInput); - _defaultInputDevice.setIsDefault(true); - _defaultInputDevice.setMode(QAudio::AudioInput); - // initialize wasapi; if getAvailableDevices is called from the CheckDevicesThread before this, it will crash getAvailableDevices(QAudio::AudioInput); getAvailableDevices(QAudio::AudioOutput); @@ -481,19 +454,6 @@ void AudioClient::setAudioPaused(bool pause) { } } - -HifiAudioDeviceInfo AudioClient::getNamedAudioDevice(QAudio::Mode mode, const QString& deviceName) { - HifiAudioDeviceInfo result; - - foreach(HifiAudioDeviceInfo audioDevice, getAudioDevices(mode)) { - if (audioDevice.deviceName().trimmed() == deviceName.trimmed()) { - result = audioDevice; - break; - } - } - return result; -} - HifiAudioDeviceInfo getNamedAudioDeviceForMode(QAudio::Mode mode, const QString& deviceName) { HifiAudioDeviceInfo result; foreach (HifiAudioDeviceInfo audioDevice, getAvailableDevices(mode)) { @@ -1041,13 +1001,15 @@ void AudioClient::selectAudioFormat(const QString& selectedCodecName) { } +void AudioClient::changeDefault(HifiAudioDeviceInfo newDefault, QAudio::Mode mode) { + HifiAudioDeviceInfo currentDevice = mode == QAudio::AudioInput ? _inputDeviceInfo : _outputDeviceInfo; + if (currentDevice.isDefault() && currentDevice.getDevice() != newDefault.getDevice()) { + switchAudioDevice(mode, newDefault); + } +} + bool AudioClient::switchAudioDevice(QAudio::Mode mode, const HifiAudioDeviceInfo& deviceInfo) { auto device = deviceInfo; - - if (device.getDevice().isNull()) { - device = defaultAudioDeviceForMode(mode); - } - if (mode == QAudio::AudioInput) { return switchInputToAudioDevice(device); } else { @@ -1055,10 +1017,6 @@ bool AudioClient::switchAudioDevice(QAudio::Mode mode, const HifiAudioDeviceInfo } } -bool AudioClient::switchAudioDevice(QAudio::Mode mode, const QString& deviceName) { - return switchAudioDevice(mode, getNamedAudioDevice(mode, deviceName)); -} - void AudioClient::configureReverb() { ReverbParameters p; @@ -1864,7 +1822,7 @@ void AudioClient::outputFormatChanged() { bool AudioClient::switchInputToAudioDevice(const HifiAudioDeviceInfo inputDeviceInfo, bool isShutdownRequest) { Q_ASSERT_X(QThread::currentThread() == thread(), Q_FUNC_INFO, "Function invoked on wrong thread"); - qCDebug(audioclient) << __FUNCTION__ << "inputDeviceInfo: [" << inputDeviceInfo.deviceName() <<"----"<deleteLater(); _audioInput = NULL; _numInputCallbackBytes = 0; - - _inputDeviceInfo = HifiAudioDeviceInfo(); } if (_dummyAudioInput) { @@ -1919,10 +1875,14 @@ bool AudioClient::switchInputToAudioDevice(const HifiAudioDeviceInfo inputDevice if (!inputDeviceInfo.getDevice().isNull()) { qCDebug(audioclient) << "The audio input device " << inputDeviceInfo.deviceName() << "is available."; + + bool doEmit = _inputDeviceInfo.deviceName() != inputDeviceInfo.deviceName(); _inputDeviceInfo = inputDeviceInfo; - emit deviceChanged(QAudio::AudioInput, _inputDeviceInfo); + if (doEmit) { + emit deviceChanged(QAudio::AudioInput, _inputDeviceInfo); + } - if (adjustedFormatForAudioDevice(inputDeviceInfo.getDevice(), _desiredInputFormat, _inputFormat)) { + if (adjustedFormatForAudioDevice(_inputDeviceInfo.getDevice(), _desiredInputFormat, _inputFormat)) { qCDebug(audioclient) << "The format to be used for audio input is" << _inputFormat; // we've got the best we can get for input @@ -1947,7 +1907,7 @@ bool AudioClient::switchInputToAudioDevice(const HifiAudioDeviceInfo inputDevice // if the user wants stereo but this device can't provide then bail if (!_isStereoInput || _inputFormat.channelCount() == 2) { - _audioInput = new QAudioInput(inputDeviceInfo.getDevice(), _inputFormat, this); + _audioInput = new QAudioInput(_inputDeviceInfo.getDevice(), _inputFormat, this); _numInputCallbackBytes = calculateNumberOfInputCallbackBytes(_inputFormat); _audioInput->setBufferSize(_numInputCallbackBytes); // different audio input devices may have different volumes @@ -2124,9 +2084,6 @@ bool AudioClient::switchOutputToAudioDevice(const HifiAudioDeviceInfo outputDevi delete[] _localOutputMixBuffer; _localOutputMixBuffer = NULL; - - _outputDeviceInfo = HifiAudioDeviceInfo(); - _outputDeviceInfo.setDevice(QAudioDeviceInfo()); } // cleanup any resamplers @@ -2152,10 +2109,13 @@ bool AudioClient::switchOutputToAudioDevice(const HifiAudioDeviceInfo outputDevi if (!outputDeviceInfo.getDevice().isNull()) { qCDebug(audioclient) << "The audio output device " << outputDeviceInfo.deviceName() << "is available."; + bool doEmit = _outputDeviceInfo.deviceName() != outputDeviceInfo.deviceName(); _outputDeviceInfo = outputDeviceInfo; - emit deviceChanged(QAudio::AudioOutput, _outputDeviceInfo); + if (doEmit) { + emit deviceChanged(QAudio::AudioOutput, _outputDeviceInfo); + } - if (adjustedFormatForAudioDevice(outputDeviceInfo.getDevice(), _desiredOutputFormat, _outputFormat)) { + if (adjustedFormatForAudioDevice(_outputDeviceInfo.getDevice(), _desiredOutputFormat, _outputFormat)) { qCDebug(audioclient) << "The format to be used for audio output is" << _outputFormat; // we've got the best we can get for input @@ -2177,7 +2137,7 @@ bool AudioClient::switchOutputToAudioDevice(const HifiAudioDeviceInfo outputDevi outputFormatChanged(); // setup our general output device for audio-mixer audio - _audioOutput = new QAudioOutput(outputDeviceInfo.getDevice(), _outputFormat, this); + _audioOutput = new QAudioOutput(_outputDeviceInfo.getDevice(), _outputFormat, this); int deviceChannelCount = _outputFormat.channelCount(); int frameSize = (AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * deviceChannelCount * _outputFormat.sampleRate()) / _desiredOutputFormat.sampleRate(); diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index 038914d639..de3e98420d 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -126,8 +126,6 @@ public: const MixedProcessedAudioStream& getReceivedAudioStream() const { return _receivedAudioStream; } MixedProcessedAudioStream& getReceivedAudioStream() { return _receivedAudioStream; } - - HifiAudioDeviceInfo getNamedAudioDevice(QAudio::Mode mode, const QString& deviceName); const QAudioFormat& getOutputFormat() const { return _outputFormat; } @@ -236,10 +234,10 @@ public slots: int setOutputBufferSize(int numFrames, bool persist = true); bool shouldLoopbackInjectors() override { return _shouldEchoToServer; } + Q_INVOKABLE void changeDefault(HifiAudioDeviceInfo newDefault, QAudio::Mode mode); // calling with a null QAudioDevice will use the system default bool switchAudioDevice(QAudio::Mode mode, const HifiAudioDeviceInfo& deviceInfo = HifiAudioDeviceInfo()); - bool switchAudioDevice(QAudio::Mode mode, const QString& deviceName); // Qt opensles plugin is not able to detect when the headset is plugged in void setHeadsetPluggedIn(bool pluggedIn); @@ -465,9 +463,6 @@ private: HifiAudioDeviceInfo _inputDeviceInfo; HifiAudioDeviceInfo _outputDeviceInfo; - HifiAudioDeviceInfo _defaultInputDevice; - HifiAudioDeviceInfo _defaultOutputDevice; - QList _inputDevices; QList _outputDevices; diff --git a/libraries/audio-client/src/HifiAudioDeviceInfo.h b/libraries/audio-client/src/HifiAudioDeviceInfo.h index 74fe2b37d0..d923b4231c 100644 --- a/libraries/audio-client/src/HifiAudioDeviceInfo.h +++ b/libraries/audio-client/src/HifiAudioDeviceInfo.h @@ -38,9 +38,15 @@ public: void setMode(QAudio::Mode mode) { _mode = mode; } void setIsDefault(bool isDefault = false) { _isDefault = isDefault; } - void setDevice(QAudioDeviceInfo devInfo); - QString deviceName() const { return _audioDeviceInfo.deviceName(); } + QString deviceName() const { + if (_isDefault) { + return "default"; + } + else { + return _audioDeviceInfo.deviceName(); + } + } QAudioDeviceInfo getDevice() const { return _audioDeviceInfo; } bool isDefault() const { return _isDefault; } QAudio::Mode getMode() const { return _mode; } From 7fbce46e3010e8d2d039f0bfa06cc1a50d776942 Mon Sep 17 00:00:00 2001 From: amerhifi Date: Thu, 19 Sep 2019 15:57:38 -0700 Subject: [PATCH 23/27] fixing android build, I removed a function thinking it was unused. also added android ifdef guards for name since default does to exist on that device. Simplified getting a default device --- libraries/audio-client/src/AudioClient.cpp | 11 ++++++----- libraries/audio-client/src/AudioClient.h | 2 +- libraries/audio-client/src/HifiAudioDeviceInfo.h | 6 ++++-- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index a8a627ffab..425216db99 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -121,10 +121,7 @@ void AudioClient::checkDevices() { auto outputDevices = getAvailableDevices(QAudio::AudioOutput); auto defInput = defaultAudioDeviceForMode(QAudio::AudioInput); - defInput.setIsDefault(true); - auto defOutput = defaultAudioDeviceForMode(QAudio::AudioOutput); - defOutput.setIsDefault(true); //add the pseudo device to the list of devices inputDevices.push_front(defInput); @@ -613,8 +610,8 @@ HifiAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { } #endif // fallback for failed lookup is the default device - return (mode == QAudio::AudioInput) ? HifiAudioDeviceInfo(QAudioDeviceInfo::defaultInputDevice(), false, QAudio::AudioInput) : - HifiAudioDeviceInfo(QAudioDeviceInfo::defaultOutputDevice(), false, QAudio::AudioOutput); + return (mode == QAudio::AudioInput) ? HifiAudioDeviceInfo(QAudioDeviceInfo::defaultInputDevice(), true, QAudio::AudioInput) : + HifiAudioDeviceInfo(QAudioDeviceInfo::defaultOutputDevice(), true, QAudio::AudioOutput); } bool AudioClient::getNamedAudioDeviceForModeExists(QAudio::Mode mode, const QString& deviceName) { @@ -1017,6 +1014,10 @@ bool AudioClient::switchAudioDevice(QAudio::Mode mode, const HifiAudioDeviceInfo } } +bool AudioClient::switchAudioDevice(QAudio::Mode mode, const QString& deviceName) { + return switchAudioDevice(mode, getNamedAudioDeviceForMode(mode, deviceName)); +} + void AudioClient::configureReverb() { ReverbParameters p; diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index de3e98420d..a13943f22e 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -238,7 +238,7 @@ public slots: // calling with a null QAudioDevice will use the system default bool switchAudioDevice(QAudio::Mode mode, const HifiAudioDeviceInfo& deviceInfo = HifiAudioDeviceInfo()); - + bool switchAudioDevice(QAudio::Mode mode, const QString& deviceName); // Qt opensles plugin is not able to detect when the headset is plugged in void setHeadsetPluggedIn(bool pluggedIn); diff --git a/libraries/audio-client/src/HifiAudioDeviceInfo.h b/libraries/audio-client/src/HifiAudioDeviceInfo.h index d923b4231c..85da862d05 100644 --- a/libraries/audio-client/src/HifiAudioDeviceInfo.h +++ b/libraries/audio-client/src/HifiAudioDeviceInfo.h @@ -40,10 +40,12 @@ public: void setIsDefault(bool isDefault = false) { _isDefault = isDefault; } void setDevice(QAudioDeviceInfo devInfo); QString deviceName() const { +#if defined(Q_OS_ANDROID) + return _audioDeviceInfo.deviceName(); +#endif if (_isDefault) { return "default"; - } - else { + } else { return _audioDeviceInfo.deviceName(); } } From 64f14dd6baa5b81db7fc78fefdd8d9161dc3f2a3 Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Fri, 20 Sep 2019 11:32:57 -0700 Subject: [PATCH 24/27] fixing selection issues --- libraries/audio-client/src/AudioClient.cpp | 44 ++++++++++++---------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 425216db99..badc39ca56 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -104,6 +104,8 @@ QList getAvailableDevices(QAudio::Mode mode) { for (auto& device : devices) { newDevices.push_back(HifiAudioDeviceInfo(device, false, mode)); } + + newDevices.push_front(defaultAudioDeviceForMode(mode)); return newDevices; } @@ -120,15 +122,8 @@ void AudioClient::checkDevices() { auto inputDevices = getAvailableDevices(QAudio::AudioInput); auto outputDevices = getAvailableDevices(QAudio::AudioOutput); - auto defInput = defaultAudioDeviceForMode(QAudio::AudioInput); - auto defOutput = defaultAudioDeviceForMode(QAudio::AudioOutput); - - //add the pseudo device to the list of devices - inputDevices.push_front(defInput); - outputDevices.push_front(defOutput); - - QMetaObject::invokeMethod(this, "changeDefault", Q_ARG(HifiAudioDeviceInfo, defInput), Q_ARG(QAudio::Mode, QAudio::AudioInput)); - QMetaObject::invokeMethod(this, "changeDefault", Q_ARG(HifiAudioDeviceInfo, defOutput), Q_ARG(QAudio::Mode, QAudio::AudioOutput)); + QMetaObject::invokeMethod(this, "changeDefault", Q_ARG(HifiAudioDeviceInfo, inputDevices.first()), Q_ARG(QAudio::Mode, QAudio::AudioInput)); + QMetaObject::invokeMethod(this, "changeDefault", Q_ARG(HifiAudioDeviceInfo, outputDevices.first()), Q_ARG(QAudio::Mode, QAudio::AudioOutput)); Lock lock(_deviceMutex); if (inputDevices != _inputDevices) { @@ -157,7 +152,7 @@ QList AudioClient::getAudioDevices(QAudio::Mode mode) const if (mode == QAudio::AudioInput) { return _inputDevices; - } else { // if (mode == QAudio::AudioOutput) + } else { return _outputDevices; } } @@ -507,8 +502,10 @@ QString AudioClient::getWinDeviceName(wchar_t* guid) { #endif HifiAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { + QList devices = QAudioDeviceInfo::availableDevices(mode); + #ifdef __APPLE__ - if (getAvailableDevices(mode).size() > 1) { + if (devices.size() > 1) { AudioDeviceID defaultDeviceID = 0; uint32_t propertySize = sizeof(AudioDeviceID); AudioObjectPropertyAddress propertyAddress = { @@ -538,9 +535,9 @@ HifiAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { if (!getPropertyError && propertySize) { // find a device in the list that matches the name we have and return it - foreach(HifiAudioDeviceInfo audioDevice, getAvailableDevices(mode)) { + foreach(QAudioDeviceInfo audioDevice, devices){ if (audioDevice.deviceName() == CFStringGetCStringPtr(deviceName, kCFStringEncodingMacRoman)) { - return audioDevice; + return HifiAudioDeviceInfo(audioDevice, true, mode); } } } @@ -588,10 +585,18 @@ HifiAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { CoUninitialize(); } + HifiAudioDeviceInfo foundDevice; + foreach(QAudioDeviceInfo audioDevice, devices) { + if (audioDevice.deviceName().trimmed() == deviceName.trimmed()) { + foundDevice=HifiAudioDeviceInfo(audioDevice,true,mode); + break; + } + } + qCDebug(audioclient) << "defaultAudioDeviceForMode mode: " << (mode == QAudio::AudioOutput ? "Output" : "Input") - << " [" << deviceName << "] [" << getNamedAudioDeviceForMode(mode, deviceName).deviceName() << "]"; + << " [" << deviceName << "] [" << foundDevice.deviceName() << "]"; - return getNamedAudioDeviceForMode(mode, deviceName); + return foundDevice; #endif #if defined (Q_OS_ANDROID) @@ -600,18 +605,17 @@ HifiAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { bool aecEnabled = enableAEC.get(); auto audioClient = DependencyManager::get(); bool headsetOn = audioClient ? audioClient->isHeadsetPluggedIn() : false; - auto inputDevices = QAudioDeviceInfo::availableDevices(QAudio::AudioInput); - for (auto inputDevice : inputDevices) { + for (QAudioDeviceInfo inputDevice : devices) { if (((headsetOn || !aecEnabled) && inputDevice.deviceName() == VOICE_RECOGNITION) || ((!headsetOn && aecEnabled) && inputDevice.deviceName() == VOICE_COMMUNICATION)) { - return HifiAudioDeviceInfo(inputDevice, false, QAudio::AudioInput); + return HifiAudioDeviceInfo(inputDevice, false, QAudio::AudioInput); } } } #endif // fallback for failed lookup is the default device - return (mode == QAudio::AudioInput) ? HifiAudioDeviceInfo(QAudioDeviceInfo::defaultInputDevice(), true, QAudio::AudioInput) : - HifiAudioDeviceInfo(QAudioDeviceInfo::defaultOutputDevice(), true, QAudio::AudioOutput); + return (mode == QAudio::AudioInput) ? HifiAudioDeviceInfo(QAudioDeviceInfo::defaultInputDevice(), true,mode) : + HifiAudioDeviceInfo(QAudioDeviceInfo::defaultOutputDevice(), true, mode); } bool AudioClient::getNamedAudioDeviceForModeExists(QAudio::Mode mode, const QString& deviceName) { From e3db7a43a6488d3d38ca21ab20371a03df5f69ef Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Mon, 23 Sep 2019 11:00:51 -0700 Subject: [PATCH 25/27] set default value for non set devices, typically only for first time runs --- interface/src/scripting/AudioDevices.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/interface/src/scripting/AudioDevices.cpp b/interface/src/scripting/AudioDevices.cpp index 0f8a9ee0c5..d98c8af92b 100644 --- a/interface/src/scripting/AudioDevices.cpp +++ b/interface/src/scripting/AudioDevices.cpp @@ -66,6 +66,8 @@ static QString getTargetDevice(bool hmd, QAudio::Mode mode) { } else { // if (_mode == QAudio::AudioOutput) deviceName = qApp->getActiveDisplayPlugin()->getPreferredAudioOutDevice(); } + } else if (!setting.isSet()) { + deviceName = "default"; } return deviceName; } @@ -99,6 +101,7 @@ AudioDeviceList::AudioDeviceList(QAudio::Mode mode) : _mode(mode) { qDebug() << "Device name in settings for Desktop, Input" << setting3.get(); _backupSelectedDesktopDeviceName = setting3.get(); } else { + _backupSelectedDesktopDeviceName = "default"; qDebug() << "Device name in settings for Desktop, Input not set"; } } From fbc68e7f69ad29ef303c322cd0d40c1897c566dd Mon Sep 17 00:00:00 2001 From: amerhifi Date: Mon, 23 Sep 2019 15:07:04 -0700 Subject: [PATCH 26/27] removed clang format issue, removed old attempt at getting defaults to startup correctly --- interface/src/scripting/AudioDevices.cpp | 1 - libraries/audio-client/src/AudioClient.cpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/interface/src/scripting/AudioDevices.cpp b/interface/src/scripting/AudioDevices.cpp index d98c8af92b..85e7faef4d 100644 --- a/interface/src/scripting/AudioDevices.cpp +++ b/interface/src/scripting/AudioDevices.cpp @@ -101,7 +101,6 @@ AudioDeviceList::AudioDeviceList(QAudio::Mode mode) : _mode(mode) { qDebug() << "Device name in settings for Desktop, Input" << setting3.get(); _backupSelectedDesktopDeviceName = setting3.get(); } else { - _backupSelectedDesktopDeviceName = "default"; qDebug() << "Device name in settings for Desktop, Input not set"; } } diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index badc39ca56..5e7a49c015 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -1535,7 +1535,7 @@ void AudioClient::prepareLocalAudioInjectors(std::unique_ptr localAudioLoc if (_localToOutputResampler) { // resample to output sample rate int frames = _localToOutputResampler->render(_localMixBuffer, _localOutputMixBuffer, - AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL); + AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL); // write to local injectors' ring buffer samples = frames * AudioConstants::STEREO; From 73f14d812f4a2cb93899400b8f3fdc855c7b3e77 Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Wed, 25 Sep 2019 13:22:50 -0700 Subject: [PATCH 27/27] addressing cr comments --- interface/src/scripting/AudioDevices.cpp | 12 +++--------- libraries/audio-client/src/HifiAudioDeviceInfo.cpp | 5 ++++- libraries/audio-client/src/HifiAudioDeviceInfo.h | 7 +++++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/interface/src/scripting/AudioDevices.cpp b/interface/src/scripting/AudioDevices.cpp index 85e7faef4d..eae4a61552 100644 --- a/interface/src/scripting/AudioDevices.cpp +++ b/interface/src/scripting/AudioDevices.cpp @@ -66,8 +66,8 @@ static QString getTargetDevice(bool hmd, QAudio::Mode mode) { } else { // if (_mode == QAudio::AudioOutput) deviceName = qApp->getActiveDisplayPlugin()->getPreferredAudioOutDevice(); } - } else if (!setting.isSet()) { - deviceName = "default"; + } else { + deviceName = HifiAudioDeviceInfo::DEFAULT_DEVICE_NAME; } return deviceName; } @@ -198,16 +198,10 @@ void AudioDeviceList::resetDevice(bool contextIsHMD) { void AudioDeviceList::onDeviceChanged(const HifiAudioDeviceInfo& device, bool isHMD) { HifiAudioDeviceInfo& selectedDevice = isHMD ? _selectedHMDDevice : _selectedDesktopDevice; selectedDevice = device; - for (auto i = 0; i < _devices.size(); ++i) { std::shared_ptr device = _devices[i]; bool& isSelected = isHMD ? device->selectedHMD : device->selectedDesktop; - HifiAudioDeviceInfo devInfo = device->info; - isSelected = false; - - if (devInfo == selectedDevice) { - isSelected = true; - } + isSelected = device->info == selectedDevice; } emit deviceChanged(selectedDevice); diff --git a/libraries/audio-client/src/HifiAudioDeviceInfo.cpp b/libraries/audio-client/src/HifiAudioDeviceInfo.cpp index d6a288e7d1..6e2d5fbe92 100644 --- a/libraries/audio-client/src/HifiAudioDeviceInfo.cpp +++ b/libraries/audio-client/src/HifiAudioDeviceInfo.cpp @@ -12,6 +12,8 @@ #include "HifiAudioDeviceInfo.h" +const QString HifiAudioDeviceInfo::DEFAULT_DEVICE_NAME = "default "; + void HifiAudioDeviceInfo::setDevice(QAudioDeviceInfo devInfo) { _audioDeviceInfo = devInfo; } @@ -25,9 +27,10 @@ HifiAudioDeviceInfo& HifiAudioDeviceInfo::operator=(const HifiAudioDeviceInfo& o bool HifiAudioDeviceInfo::operator==(const HifiAudioDeviceInfo& rhs) const { + //Does the QAudioDeviceinfo match as well as is this the default device or return getDevice() == rhs.getDevice() && isDefault() == rhs.isDefault(); } bool HifiAudioDeviceInfo::operator!=(const HifiAudioDeviceInfo& rhs) const { - return getDevice() != rhs.getDevice() && isDefault() != rhs.isDefault(); + return getDevice() != rhs.getDevice() || isDefault() != rhs.isDefault(); } diff --git a/libraries/audio-client/src/HifiAudioDeviceInfo.h b/libraries/audio-client/src/HifiAudioDeviceInfo.h index 85da862d05..99520f1643 100644 --- a/libraries/audio-client/src/HifiAudioDeviceInfo.h +++ b/libraries/audio-client/src/HifiAudioDeviceInfo.h @@ -37,14 +37,14 @@ public: } void setMode(QAudio::Mode mode) { _mode = mode; } - void setIsDefault(bool isDefault = false) { _isDefault = isDefault; } + void setIsDefault() { _isDefault = true; } void setDevice(QAudioDeviceInfo devInfo); QString deviceName() const { #if defined(Q_OS_ANDROID) return _audioDeviceInfo.deviceName(); #endif if (_isDefault) { - return "default"; + return DEFAULT_DEVICE_NAME; } else { return _audioDeviceInfo.deviceName(); } @@ -61,6 +61,9 @@ private: QAudioDeviceInfo _audioDeviceInfo; bool _isDefault { false }; QAudio::Mode _mode { QAudio::AudioInput }; + +public: + static const QString DEFAULT_DEVICE_NAME; }; #endif \ No newline at end of file