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..74d85f0107 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 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..eae4a61552 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; @@ -64,6 +66,8 @@ static QString getTargetDevice(bool hmd, QAudio::Mode mode) { } else { // if (_mode == QAudio::AudioOutput) deviceName = qApp->getActiveDisplayPlugin()->getPreferredAudioOutDevice(); } + } else { + deviceName = HifiAudioDeviceInfo::DEFAULT_DEVICE_NAME; } return deviceName; } @@ -139,7 +143,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,18 +195,13 @@ 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) { 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) { - isSelected = true; - } + isSelected = device->info == selectedDevice; } emit deviceChanged(selectedDevice); @@ -259,37 +258,46 @@ 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() - .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}) { - 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 +333,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 +390,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 +405,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.deviceName(); auto& setting = getSetting(isHMD, mode); @@ -410,7 +418,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 +442,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 +456,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 +511,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 HifiAudioDeviceInfo&, device)); } else { //context is different. just save device in settings onDeviceSelected(QAudio::AudioInput, device, @@ -520,14 +528,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 HifiAudioDeviceInfo&, device)); } 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..13d97d53dd 100644 --- a/interface/src/scripting/AudioDevices.h +++ b/interface/src/scripting/AudioDevices.h @@ -19,11 +19,13 @@ #include #include +#include + 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..5e7a49c015 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -91,11 +91,23 @@ using Lock = std::unique_lock; Mutex _deviceMutex; Mutex _recordMutex; +HifiAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode); + // 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; + + for (auto& device : devices) { + newDevices.push_back(HifiAudioDeviceInfo(device, false, mode)); + } + + newDevices.push_front(defaultAudioDeviceForMode(mode)); + + return newDevices; } // now called from a background thread, to keep blocking operations off the audio thread @@ -109,6 +121,9 @@ void AudioClient::checkDevices() { auto inputDevices = getAvailableDevices(QAudio::AudioInput); auto outputDevices = getAvailableDevices(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) { @@ -122,22 +137,22 @@ 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 { return _outputDevices; } } @@ -226,7 +241,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; @@ -241,7 +256,7 @@ 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; @@ -321,9 +336,9 @@ AudioClient::AudioClient() : } 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() << "]"; + 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); }); @@ -373,7 +388,7 @@ AudioClient::AudioClient() : packetReceiver.registerListener(PacketType::SelectedAudioFormat, this, "handleSelectedAudioFormat"); auto& domainHandler = nodeList->getDomainHandler(); - connect(&domainHandler, &DomainHandler::disconnectedFromDomain, this, [this] { + connect(&domainHandler, &DomainHandler::disconnectedFromDomain, this, [this] { _solo.reset(); }); connect(nodeList.data(), &NodeList::nodeActivated, this, [this](SharedNodePointer node) { @@ -431,15 +446,14 @@ void AudioClient::setAudioPaused(bool pause) { } } -QAudioDeviceInfo getNamedAudioDeviceForMode(QAudio::Mode mode, const QString& deviceName) { - QAudioDeviceInfo result; - foreach(QAudioDeviceInfo audioDevice, getAvailableDevices(mode)) { +HifiAudioDeviceInfo getNamedAudioDeviceForMode(QAudio::Mode mode, const QString& deviceName) { + HifiAudioDeviceInfo result; + foreach (HifiAudioDeviceInfo audioDevice, getAvailableDevices(mode)) { if (audioDevice.deviceName().trimmed() == deviceName.trimmed()) { result = audioDevice; break; } } - return result; } @@ -487,9 +501,11 @@ QString AudioClient::getWinDeviceName(wchar_t* guid) { #endif -QAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { +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 = { @@ -519,9 +535,9 @@ 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(QAudioDeviceInfo audioDevice, devices){ if (audioDevice.deviceName() == CFStringGetCStringPtr(deviceName, kCFStringEncodingMacRoman)) { - return audioDevice; + return HifiAudioDeviceInfo(audioDevice, true, mode); } } } @@ -569,10 +585,18 @@ QAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { CoUninitialize(); } - qCDebug(audioclient) << "defaultAudioDeviceForMode mode: " << (mode == QAudio::AudioOutput ? "Output" : "Input") - << " [" << deviceName << "] [" << getNamedAudioDeviceForMode(mode, deviceName).deviceName() << "]"; + 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 << "] [" << foundDevice.deviceName() << "]"; - return getNamedAudioDeviceForMode(mode, deviceName); + return foundDevice; #endif #if defined (Q_OS_ANDROID) @@ -580,18 +604,18 @@ QAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { Setting::Handle enableAEC(SETTING_AEC_KEY, DEFAULT_AEC_ENABLED); bool aecEnabled = enableAEC.get(); auto audioClient = DependencyManager::get(); - bool headsetOn = audioClient? audioClient->isHeadsetPluggedIn() : false; - auto inputDevices = QAudioDeviceInfo::availableDevices(QAudio::AudioInput); - for (auto inputDevice : inputDevices) { + bool headsetOn = audioClient ? audioClient->isHeadsetPluggedIn() : false; + for (QAudioDeviceInfo inputDevice : devices) { if (((headsetOn || !aecEnabled) && inputDevice.deviceName() == VOICE_RECOGNITION) || - ((!headsetOn && aecEnabled) && inputDevice.deviceName() == VOICE_COMMUNICATION)) { - return inputDevice; + ((!headsetOn && aecEnabled) && inputDevice.deviceName() == VOICE_COMMUNICATION)) { + return HifiAudioDeviceInfo(inputDevice, false, QAudio::AudioInput); } } } #endif // fallback for failed lookup is the default device - return (mode == QAudio::AudioInput) ? QAudioDeviceInfo::defaultInputDevice() : QAudioDeviceInfo::defaultOutputDevice(); + return (mode == QAudio::AudioInput) ? HifiAudioDeviceInfo(QAudioDeviceInfo::defaultInputDevice(), true,mode) : + HifiAudioDeviceInfo(QAudioDeviceInfo::defaultOutputDevice(), true, mode); } bool AudioClient::getNamedAudioDeviceForModeExists(QAudio::Mode mode, const QString& deviceName) { @@ -643,29 +667,29 @@ bool adjustedFormatForAudioDevice(const QAudioDeviceInfo& audioDevice, 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) { @@ -758,22 +782,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); @@ -783,10 +807,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); @@ -978,16 +1002,18 @@ void AudioClient::selectAudioFormat(const QString& selectedCodecName) { } -bool AudioClient::switchAudioDevice(QAudio::Mode mode, const QAudioDeviceInfo& deviceInfo) { - auto device = deviceInfo; - - if (device.isNull()) { - device = defaultAudioDeviceForMode(mode); +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 (mode == QAudio::AudioInput) { return switchInputToAudioDevice(device); - } else { // if (mode == QAudio::AudioOutput) + } else { return switchOutputToAudioDevice(device); } } @@ -1030,7 +1056,7 @@ void AudioClient::configureReverb() { 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.lateGain += _reverbOptions->getWetDryMix() * (24.0f / 100.0f) - 24.0f; // -0dB to -24dB, based on wetDryMix p.lateMixLeft = 0.0f; p.lateMixRight = 0.0f; @@ -1414,7 +1440,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) { @@ -1453,7 +1479,7 @@ void AudioClient::handleDummyAudioInput() { ? AudioConstants::NETWORK_FRAME_BYTES_STEREO : AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL; - QByteArray audioBuffer(numNetworkBytes, 0); // silent + QByteArray audioBuffer(numNetworkBytes, 0); // silent handleAudioInput(audioBuffer); } @@ -1598,7 +1624,7 @@ 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) { @@ -1736,7 +1762,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; @@ -1798,17 +1824,17 @@ 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.deviceName() <<"----"<start() from audioInputStateChanged + _shouldRestartInputSetup = false; // avoid a double call to _audioInput->start() from audioInputStateChanged #endif // cleanup any previously initialized device @@ -1822,8 +1848,6 @@ bool AudioClient::switchInputToAudioDevice(const QAudioDeviceInfo inputDeviceInf _audioInput->deleteLater(); _audioInput = NULL; _numInputCallbackBytes = 0; - - _inputDeviceInfo = QAudioDeviceInfo(); } if (_dummyAudioInput) { @@ -1854,12 +1878,16 @@ 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."; + + bool doEmit = _inputDeviceInfo.deviceName() != inputDeviceInfo.deviceName(); _inputDeviceInfo = inputDeviceInfo; - emit deviceChanged(QAudio::AudioInput, inputDeviceInfo); + if (doEmit) { + 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 @@ -1884,7 +1912,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 @@ -1906,7 +1934,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 +1947,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; @@ -1975,11 +2003,11 @@ 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"); + 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); } @@ -2026,7 +2054,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() << "]"; @@ -2061,8 +2089,6 @@ bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo outputDeviceI delete[] _localOutputMixBuffer; _localOutputMixBuffer = NULL; - - _outputDeviceInfo = QAudioDeviceInfo(); } // cleanup any resamplers @@ -2086,12 +2112,15 @@ 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."; + bool doEmit = _outputDeviceInfo.deviceName() != outputDeviceInfo.deviceName(); _outputDeviceInfo = outputDeviceInfo; - emit deviceChanged(QAudio::AudioOutput, outputDeviceInfo); + if (doEmit) { + 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 @@ -2113,7 +2142,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(); @@ -2165,7 +2194,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(); @@ -2239,7 +2268,7 @@ float AudioClient::azimuthForSource(const glm::vec3& relativePosition) { // 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 { @@ -2423,4 +2452,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 ab12393ebf..a13943f22e 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -53,6 +53,7 @@ #include "AudioIOStats.h" #include "AudioFileWav.h" +#include "HifiAudioDeviceInfo.h" #ifdef _WIN32 #pragma warning( push ) @@ -102,8 +103,8 @@ public: _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; } + 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; @@ -111,7 +112,7 @@ public: AudioClient* _audio; int _unfulfilledReads; }; - + void startThread(); void negotiateAudioFormat(); void selectAudioFormat(const QString& selectedCodecName); @@ -152,12 +153,12 @@ 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; @@ -233,11 +234,11 @@ 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 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 void setHeadsetPluggedIn(bool pluggedIn); @@ -269,10 +270,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(); @@ -416,7 +417,7 @@ private: float* _localOutputMixBuffer { NULL }; Mutex _localAudioMutex; AudioLimiter _audioLimiter; - + // Adds Reverb void configureReverb(); void updateReverbOptions(); @@ -437,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; @@ -459,11 +460,11 @@ private: glm::vec3 avatarBoundingBoxCorner; glm::vec3 avatarBoundingBoxScale; - QAudioDeviceInfo _inputDeviceInfo; - QAudioDeviceInfo _outputDeviceInfo; + HifiAudioDeviceInfo _inputDeviceInfo; + HifiAudioDeviceInfo _outputDeviceInfo; - QList _inputDevices; - QList _outputDevices; + QList _inputDevices; + QList _outputDevices; AudioFileWav _audioFileWav; @@ -476,7 +477,7 @@ private: CodecPluginPointer _codec; QString _selectedCodecName; - Encoder* _encoder { nullptr }; // for outbound mic stream + Encoder* _encoder { nullptr }; // for outbound mic stream RateCounter<> _silentOutbound; RateCounter<> _audioOutbound; @@ -484,11 +485,11 @@ 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; @@ -498,4 +499,4 @@ private: }; -#endif // hifi_AudioClient_h +#endif // hifi_AudioClient_h \ 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..6e2d5fbe92 --- /dev/null +++ b/libraries/audio-client/src/HifiAudioDeviceInfo.cpp @@ -0,0 +1,36 @@ +// +// 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" + +const QString HifiAudioDeviceInfo::DEFAULT_DEVICE_NAME = "default "; + +void HifiAudioDeviceInfo::setDevice(QAudioDeviceInfo devInfo) { + _audioDeviceInfo = devInfo; +} + +HifiAudioDeviceInfo& HifiAudioDeviceInfo::operator=(const HifiAudioDeviceInfo& other) { + _audioDeviceInfo = other.getDevice(); + _mode = other.getMode(); + _isDefault = other.isDefault(); + return *this; +} + + +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(); +} + diff --git a/libraries/audio-client/src/HifiAudioDeviceInfo.h b/libraries/audio-client/src/HifiAudioDeviceInfo.h new file mode 100644 index 0000000000..99520f1643 --- /dev/null +++ b/libraries/audio-client/src/HifiAudioDeviceInfo.h @@ -0,0 +1,69 @@ +// +// 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 + + +#include +#include +#include +#include + +class HifiAudioDeviceInfo : public QObject { + Q_OBJECT + +public: + HifiAudioDeviceInfo() : QObject() {} + HifiAudioDeviceInfo(const HifiAudioDeviceInfo &deviceInfo) : QObject(){ + _audioDeviceInfo = deviceInfo.getDevice(); + _mode = deviceInfo.getMode(); + _isDefault = deviceInfo.isDefault(); + } + + HifiAudioDeviceInfo(QAudioDeviceInfo deviceInfo, bool isDefault, QAudio::Mode mode) : + _audioDeviceInfo(deviceInfo), + _isDefault(isDefault), + _mode(mode){ + } + + void setMode(QAudio::Mode mode) { _mode = mode; } + void setIsDefault() { _isDefault = true; } + void setDevice(QAudioDeviceInfo devInfo); + QString deviceName() const { +#if defined(Q_OS_ANDROID) + return _audioDeviceInfo.deviceName(); +#endif + if (_isDefault) { + return DEFAULT_DEVICE_NAME; + } else { + return _audioDeviceInfo.deviceName(); + } + } + QAudioDeviceInfo getDevice() const { return _audioDeviceInfo; } + bool isDefault() const { return _isDefault; } + QAudio::Mode getMode() const { return _mode; } + + HifiAudioDeviceInfo& operator=(const HifiAudioDeviceInfo& other); + bool operator==(const HifiAudioDeviceInfo& rhs) const; + bool operator!=(const HifiAudioDeviceInfo& rhs) const; + +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 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())); }