Merge pull request #16196 from amerhifi/dev469

DEV-469: Default Audio device
This commit is contained in:
Amer 2019-09-25 16:28:00 -07:00 committed by GitHub
commit 1e94a82ee6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 301 additions and 155 deletions

View file

@ -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);
});

View file

@ -19,6 +19,7 @@
#include "SettingHandle.h"
#include "AudioFileWav.h"
#include <shared/ReadWriteLockable.h>
#include <HifiAudioDeviceInfo.h>
using MutedGetter = std::function<bool()>;
using MutedSetter = std::function<void(bool)>;
@ -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

View file

@ -29,6 +29,8 @@ static Setting::Handle<QString> desktopOutputDeviceSetting { QStringList { Audio
static Setting::Handle<QString> hmdInputDeviceSetting { QStringList { Audio::AUDIO, Audio::HMD, "INPUT" }};
static Setting::Handle<QString> hmdOutputDeviceSetting { QStringList { Audio::AUDIO, Audio::HMD, "OUTPUT" }};
Q_DECLARE_METATYPE(HifiAudioDeviceInfo);
Setting::Handle<QString>& 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<QAudioDeviceInfo>(_devices.at(index.row())->info);
return QVariant::fromValue<HifiAudioDeviceInfo>(_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<AudioDevice> 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<scripting::AudioDevice> getSimilarDevice(const QString& deviceNa
return devices[minDistanceIndex];
}
void AudioDeviceList::onDevicesChanged(const QList<QAudioDeviceInfo>& devices) {
void AudioDeviceList::onDevicesChanged(const QList<HifiAudioDeviceInfo>& devices) {
beginResetModel();
QList<std::shared_ptr<AudioDevice>> 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<QAudioDeviceInfo>& 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<QAudioDeviceInfo>& devicesInput = client->getAudioDevices(QAudio::AudioInput);
const QList<QAudioDeviceInfo>& devicesOutput = client->getAudioDevices(QAudio::AudioOutput);
const QList<HifiAudioDeviceInfo>& devicesInput = client->getAudioDevices(QAudio::AudioInput);
const QList<HifiAudioDeviceInfo>& 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<QAudioDeviceInfo>& devices) {
void AudioDevices::onDevicesChanged(QAudio::Mode mode, const QList<HifiAudioDeviceInfo>& devices) {
static std::once_flag once;
std::call_once(once, [&] {
//readout settings
@ -503,14 +511,14 @@ void AudioDevices::onDevicesChanged(QAudio::Mode mode, const QList<QAudioDeviceI
}
void AudioDevices::chooseInputDevice(const QAudioDeviceInfo& device, bool isHMD) {
void AudioDevices::chooseInputDevice(const HifiAudioDeviceInfo& device, bool isHMD) {
//check if current context equals device to change
if (_contextIsHMD == isHMD) {
auto client = DependencyManager::get<AudioClient>().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<AudioClient>().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,

View file

@ -19,11 +19,13 @@
#include <QAbstractListModel>
#include <QAudioDeviceInfo>
#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<QAudioDeviceInfo>& devices);
void onDeviceChanged(const HifiAudioDeviceInfo& device, bool isHMD);
void onDevicesChanged(const QList<HifiAudioDeviceInfo>& devices);
protected:
friend class AudioDevices;
@ -63,8 +65,8 @@ protected:
static QHash<int, QByteArray> _roles;
static Qt::ItemFlags _flags;
const QAudio::Mode _mode;
QAudioDeviceInfo _selectedDesktopDevice;
QAudioDeviceInfo _selectedHMDDevice;
HifiAudioDeviceInfo _selectedDesktopDevice;
HifiAudioDeviceInfo _selectedHMDDevice;
QString _backupSelectedDesktopDeviceName;
QString _backupSelectedHMDDeviceName;
QList<std::shared_ptr<AudioDevice>> _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<QAudioDeviceInfo>& 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<HifiAudioDeviceInfo>& 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;
};

View file

@ -91,11 +91,23 @@ using Lock = std::unique_lock<Mutex>;
Mutex _deviceMutex;
Mutex _recordMutex;
HifiAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode);
// thread-safe
QList<QAudioDeviceInfo> getAvailableDevices(QAudio::Mode mode) {
QList<HifiAudioDeviceInfo> 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<HifiAudioDeviceInfo> 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<QAudioDeviceInfo> AudioClient::getAudioDevices(QAudio::Mode mode) const {
QList<HifiAudioDeviceInfo> 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 <int NUM_CHANNELS>
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<QAudioDeviceInfo> 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<bool> enableAEC(SETTING_AEC_KEY, DEFAULT_AEC_ENABLED);
bool aecEnabled = enableAEC.get();
auto audioClient = DependencyManager::get<AudioClient>();
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() <<"----"<<inputDeviceInfo.getDevice().deviceName() << "]";
bool supportedFormat = false;
// NOTE: device start() uses the Qt internal device list
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
@ -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<jstring>("android/os/Build", "BRAND");
if (pluggedIn == !_isHeadsetPluggedIn && !_inputDeviceInfo.getDevice().isNull()) {
QAndroidJniObject brand = QAndroidJniObject::getStaticObjectField<jstring>("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());
}
}
}
}

View file

@ -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<QAudioDeviceInfo> getAudioDevices(QAudio::Mode mode) const;
HifiAudioDeviceInfo getActiveAudioDevice(QAudio::Mode mode) const;
QList<HifiAudioDeviceInfo> 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<QAudioDeviceInfo>& devices);
void deviceChanged(QAudio::Mode mode, const HifiAudioDeviceInfo& device);
void devicesChanged(QAudio::Mode mode, const QList<HifiAudioDeviceInfo>& devices);
void peakValueListChanged(const QList<float> 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<QAudioDeviceInfo> _inputDevices;
QList<QAudioDeviceInfo> _outputDevices;
QList<HifiAudioDeviceInfo> _inputDevices;
QList<HifiAudioDeviceInfo> _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

View file

@ -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();
}

View file

@ -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 <QObject>
#include <QAudioDeviceInfo>
#include <QAudio>
#include <QString>
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

View file

@ -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<AudioClient>().data(), &AudioClient::deviceChanged, this, [this](QAudio::Mode mode, const QAudioDeviceInfo& device) {
connect(DependencyManager::get<AudioClient>().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()));
}