mirror of
https://github.com/Armored-Dragon/overte.git
synced 2025-03-11 16:13:16 +01:00
expose Audio.devices.input/output
This commit is contained in:
parent
4a3f2e1d09
commit
954e4979f8
8 changed files with 322 additions and 79 deletions
|
@ -13,6 +13,7 @@
|
|||
#define hifi_scripting_Audio_h
|
||||
|
||||
#include "AudioScriptingInterface.h"
|
||||
#include "AudioDevices.h"
|
||||
|
||||
namespace scripting {
|
||||
|
||||
|
@ -22,14 +23,21 @@ class Audio : public AudioScriptingInterface {
|
|||
|
||||
// TODO: Q_PROPERTY(bool mute)
|
||||
// TODO: Q_PROPERTY(bool noiseReduction)
|
||||
// TODO: Q_PROPERTY(bool reverb)
|
||||
// TODO: Q_PROPERTY(float inputVolume)
|
||||
// TODO: Q_PROPERTY(bool showMicLevel)
|
||||
// TODO: Q_PROPERTY(? devices)
|
||||
// TODO: Q_PROPERTY(QString context)
|
||||
Q_PROPERTY(AudioDevices* devices READ getDevices)
|
||||
|
||||
public:
|
||||
virtual ~Audio() {}
|
||||
|
||||
protected:
|
||||
Audio() {}
|
||||
|
||||
private:
|
||||
AudioDevices* getDevices() { return &_devices; }
|
||||
AudioDevices _devices;
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
//
|
||||
|
||||
#include "AudioClient.h"
|
||||
/*
|
||||
#include "AudioDeviceScriptingInterface.h"
|
||||
#include "SettingsScriptingInterface.h"
|
||||
|
||||
|
@ -269,3 +270,4 @@ void AudioDeviceScriptingInterface::currentDeviceUpdate(const QString& name, QAu
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#ifndef hifi_AudioDeviceScriptingInterface_h
|
||||
#define hifi_AudioDeviceScriptingInterface_h
|
||||
|
||||
/*
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
|
@ -103,5 +104,6 @@ private:
|
|||
QString _currentInputDevice;
|
||||
QString _currentOutputDevice;
|
||||
};
|
||||
*/
|
||||
|
||||
#endif // hifi_AudioDeviceScriptingInterface_h
|
||||
|
|
146
interface/src/scripting/AudioDevices.cpp
Normal file
146
interface/src/scripting/AudioDevices.cpp
Normal file
|
@ -0,0 +1,146 @@
|
|||
//
|
||||
// AudioDevices.cpp
|
||||
// interface/src/scripting
|
||||
//
|
||||
// Created by Zach Pomerantz on 28/5/2017.
|
||||
// Copyright 2017 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 "AudioDevices.h"
|
||||
#include "AudioClient.h"
|
||||
|
||||
using namespace scripting;
|
||||
|
||||
QHash<int, QByteArray> AudioDeviceList::_roles {
|
||||
{ Qt::DisplayRole, "display" },
|
||||
{ Qt::CheckStateRole, "selected" }
|
||||
};
|
||||
Qt::ItemFlags AudioDeviceList::_flags { Qt::ItemIsSelectable | Qt::ItemIsEnabled };
|
||||
|
||||
AudioDeviceList::AudioDeviceList(QAudio::Mode mode) : _mode(mode) {
|
||||
}
|
||||
|
||||
int AudioDeviceList::rowCount(const QModelIndex& parent) const {
|
||||
Q_UNUSED(parent);
|
||||
return _devices.size();
|
||||
}
|
||||
|
||||
QVariant AudioDeviceList::data(const QModelIndex& index, int role) const {
|
||||
if (!index.isValid() || index.row() >= _devices.size()) {
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
if (role == Qt::DisplayRole) {
|
||||
return _devices.at(index.row()).name;
|
||||
} else if (role == Qt::CheckStateRole) {
|
||||
return _devices.at(index.row()).selected;
|
||||
} else {
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> AudioDeviceList::roleNames() const {
|
||||
return _roles;
|
||||
}
|
||||
|
||||
Qt::ItemFlags AudioDeviceList::flags(const QModelIndex& index) const {
|
||||
return _flags;
|
||||
}
|
||||
|
||||
bool AudioDeviceList::setData(const QModelIndex& index, const QVariant &value, int role) {
|
||||
if (!index.isValid() || index.row() >= _devices.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
|
||||
if (role == Qt::CheckStateRole) {
|
||||
auto selected = value.toBool();
|
||||
auto& device = _devices[index.row()];
|
||||
|
||||
// only allow switching to a new device, not deactivating an in-use device
|
||||
if (selected
|
||||
// skip if already selected
|
||||
&& selected != device.selected) {
|
||||
|
||||
auto client = DependencyManager::get<AudioClient>();
|
||||
bool success;
|
||||
QMetaObject::invokeMethod(client.data(), "switchAudioDevice", Qt::BlockingQueuedConnection,
|
||||
Q_RETURN_ARG(bool, success),
|
||||
Q_ARG(QAudio::Mode, _mode),
|
||||
Q_ARG(const QAudioDeviceInfo&, device.info));
|
||||
|
||||
if (success) {
|
||||
device.selected = true;
|
||||
emit dataChanged(index, index, { Qt::CheckStateRole });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
void AudioDeviceList::setDevice(const QAudioDeviceInfo& device) {
|
||||
_selectedDevice = device;
|
||||
|
||||
for (auto i = 0; i < _devices.size(); ++i) {
|
||||
AudioDevice& device = _devices[i];
|
||||
|
||||
if (device.selected && device.info != _selectedDevice) {
|
||||
device.selected = false;
|
||||
auto index = createIndex(i , 0);
|
||||
emit dataChanged(index, index, { Qt::CheckStateRole });
|
||||
} else if (!device.selected && device.info == _selectedDevice) {
|
||||
device.selected = true;
|
||||
auto index = createIndex(i , 0);
|
||||
emit dataChanged(index, index, { Qt::CheckStateRole });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AudioDeviceList::populate(const QList<QAudioDeviceInfo>& devices) {
|
||||
beginResetModel();
|
||||
|
||||
_devices.clear();
|
||||
foreach(const QAudioDeviceInfo& deviceInfo, devices) {
|
||||
AudioDevice device;
|
||||
device.info = deviceInfo;
|
||||
device.name = device.info.deviceName();
|
||||
device.selected = (device.info == _selectedDevice);
|
||||
_devices.push_back(device);
|
||||
}
|
||||
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
AudioDevices::AudioDevices() {
|
||||
auto client = DependencyManager::get<AudioClient>();
|
||||
// connections are made after client is initialized, so we must also fetch the devices
|
||||
|
||||
connect(client.data(), &AudioClient::deviceChanged, this, &AudioDevices::onDeviceChanged, Qt::QueuedConnection);
|
||||
_inputs.setDevice(client->getActiveAudioDevice(QAudio::AudioInput));
|
||||
_outputs.setDevice(client->getActiveAudioDevice(QAudio::AudioOutput));
|
||||
|
||||
connect(client.data(), &AudioClient::devicesChanged, this, &AudioDevices::onDevicesChanged, Qt::QueuedConnection);
|
||||
_inputs.populate(client->getAudioDevices(QAudio::AudioInput));
|
||||
_outputs.populate(client->getAudioDevices(QAudio::AudioOutput));
|
||||
}
|
||||
|
||||
void AudioDevices::onDeviceChanged(QAudio::Mode mode, const QAudioDeviceInfo& device) {
|
||||
if (mode == QAudio::AudioInput) {
|
||||
_inputs.setDevice(device);
|
||||
} else { // if (mode == QAudio::AudioOutput)
|
||||
_outputs.setDevice(device);
|
||||
}
|
||||
}
|
||||
|
||||
void AudioDevices::onDevicesChanged(QAudio::Mode mode, const QList<QAudioDeviceInfo>& devices) {
|
||||
if (mode == QAudio::AudioInput) {
|
||||
_inputs.populate(devices);
|
||||
} else { // if (mode == QAudio::AudioOutput)
|
||||
_outputs.populate(devices);
|
||||
}
|
||||
}
|
76
interface/src/scripting/AudioDevices.h
Normal file
76
interface/src/scripting/AudioDevices.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
//
|
||||
// AudioDeviceScriptingInterface.h
|
||||
// interface/src/scripting
|
||||
//
|
||||
// Created by Zach Pomerantz on 28/5/2017.
|
||||
// Copyright 2017 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
|
||||
//
|
||||
|
||||
#ifndef hifi_scripting_AudioDevices_h
|
||||
#define hifi_scripting_AudioDevices_h
|
||||
|
||||
#include <QObject>
|
||||
#include <QAbstractListModel>
|
||||
#include <QAudioDeviceInfo>
|
||||
|
||||
namespace scripting {
|
||||
|
||||
class AudioDevice {
|
||||
public:
|
||||
QAudioDeviceInfo info;
|
||||
QString name;
|
||||
bool selected { false };
|
||||
};
|
||||
|
||||
class AudioDeviceList : public QAbstractListModel {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AudioDeviceList(QAudio::Mode mode);
|
||||
|
||||
int rowCount(const QModelIndex& parent) const override;
|
||||
QVariant data(const QModelIndex& index, int role) const override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
Qt::ItemFlags flags(const QModelIndex& index) const override;
|
||||
bool setData(const QModelIndex& index, const QVariant &value, int role) override;
|
||||
|
||||
void setDevice(const QAudioDeviceInfo& device);
|
||||
void populate(const QList<QAudioDeviceInfo>& devices);
|
||||
|
||||
private:
|
||||
static QHash<int, QByteArray> _roles;
|
||||
static Qt::ItemFlags _flags;
|
||||
|
||||
QAudio::Mode _mode;
|
||||
QAudioDeviceInfo _selectedDevice;
|
||||
QList<AudioDevice> _devices;
|
||||
};
|
||||
|
||||
class AudioDevices : public QObject {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(AudioDeviceList* input READ getInputList)
|
||||
Q_PROPERTY(AudioDeviceList* output READ getOutputList)
|
||||
|
||||
public:
|
||||
AudioDevices();
|
||||
|
||||
private slots:
|
||||
void onDeviceChanged(QAudio::Mode mode, const QAudioDeviceInfo& device);
|
||||
void onDevicesChanged(QAudio::Mode mode, const QList<QAudioDeviceInfo>& devices);
|
||||
|
||||
private:
|
||||
AudioDeviceList* getInputList() { return &_inputs; }
|
||||
AudioDeviceList* getOutputList() { return &_outputs; }
|
||||
|
||||
AudioDeviceList _inputs { QAudio::AudioInput };
|
||||
AudioDeviceList _outputs { QAudio::AudioOutput };
|
||||
|
||||
bool tester;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif // hifi_scripting_AudioDevices_h
|
|
@ -76,6 +76,13 @@ using Mutex = std::mutex;
|
|||
using Lock = std::unique_lock<Mutex>;
|
||||
static Mutex _deviceMutex;
|
||||
|
||||
// thread-safe
|
||||
QList<QAudioDeviceInfo> getAvailableDevices(QAudio::Mode mode) {
|
||||
// NOTE: availableDevices() clobbers the Qt internal device list
|
||||
Lock lock(_deviceMutex);
|
||||
return QAudioDeviceInfo::availableDevices(mode);
|
||||
}
|
||||
|
||||
class BackgroundThread : public QThread {
|
||||
public:
|
||||
BackgroundThread(AudioClient* client) : QThread((QObject*)client), _client(client) {}
|
||||
|
@ -115,6 +122,45 @@ private:
|
|||
std::condition_variable _joinCondition;
|
||||
};
|
||||
|
||||
// now called from a background thread, to keep blocking operations off the audio thread
|
||||
void AudioClient::checkDevices() {
|
||||
auto inputDevices = getAvailableDevices(QAudio::AudioInput);
|
||||
auto outputDevices = getAvailableDevices(QAudio::AudioOutput);
|
||||
|
||||
Lock lock(_deviceMutex);
|
||||
|
||||
if (inputDevices != _inputDevices) {
|
||||
_inputDevices.swap(inputDevices);
|
||||
emit devicesChanged(QAudio::AudioInput, _inputDevices);
|
||||
}
|
||||
|
||||
if (outputDevices != _outputDevices) {
|
||||
_outputDevices.swap(outputDevices);
|
||||
emit devicesChanged(QAudio::AudioOutput, _outputDevices);
|
||||
}
|
||||
}
|
||||
|
||||
QAudioDeviceInfo AudioClient::getActiveAudioDevice(QAudio::Mode mode) const {
|
||||
Lock lock(_deviceMutex);
|
||||
|
||||
if (mode == QAudio::AudioInput) {
|
||||
return _inputDeviceInfo;
|
||||
} else { // if (mode == QAudio::AudioOutput)
|
||||
return _outputDeviceInfo;
|
||||
}
|
||||
}
|
||||
|
||||
QList<QAudioDeviceInfo> AudioClient::getAudioDevices(QAudio::Mode mode) const {
|
||||
Lock lock(_deviceMutex);
|
||||
|
||||
if (mode == QAudio::AudioInput) {
|
||||
return _inputDevices;
|
||||
} else { // if (mode == QAudio::AudioOutput)
|
||||
return _outputDevices;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// background thread buffering local injectors
|
||||
class LocalInjectorsThread : public BackgroundThread {
|
||||
Q_OBJECT
|
||||
|
@ -220,8 +266,9 @@ AudioClient::AudioClient() :
|
|||
|
||||
connect(&_receivedAudioStream, &InboundAudioStream::mismatchedAudioCodec, this, &AudioClient::handleMismatchAudioFormat);
|
||||
|
||||
_inputDevices = getDeviceNames(QAudio::AudioInput);
|
||||
_outputDevices = getDeviceNames(QAudio::AudioOutput);
|
||||
// initialize wasapi; if getAvailableDevices is called from the CheckDevicesThread before this, it will crash
|
||||
getAvailableDevices(QAudio::AudioInput);
|
||||
getAvailableDevices(QAudio::AudioOutput);
|
||||
|
||||
// start a thread to detect any device changes
|
||||
_checkDevicesThread = new CheckDevicesThread(this);
|
||||
|
@ -295,13 +342,6 @@ void AudioClient::audioMixerKilled() {
|
|||
emit disconnected();
|
||||
}
|
||||
|
||||
// thread-safe
|
||||
QList<QAudioDeviceInfo> getAvailableDevices(QAudio::Mode mode) {
|
||||
// NOTE: availableDevices() clobbers the Qt internal device list
|
||||
Lock lock(_deviceMutex);
|
||||
return QAudioDeviceInfo::availableDevices(mode);
|
||||
}
|
||||
|
||||
QAudioDeviceInfo getNamedAudioDeviceForMode(QAudio::Mode mode, const QString& deviceName) {
|
||||
QAudioDeviceInfo result;
|
||||
foreach(QAudioDeviceInfo audioDevice, getAvailableDevices(mode)) {
|
||||
|
@ -315,7 +355,7 @@ QAudioDeviceInfo getNamedAudioDeviceForMode(QAudio::Mode mode, const QString& de
|
|||
}
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
QString friendlyNameForAudioDevice(IMMDevice* pEndpoint) {
|
||||
QString getWinDeviceName(IMMDevice* pEndpoint) {
|
||||
QString deviceName;
|
||||
IPropertyStore* pPropertyStore;
|
||||
pEndpoint->OpenPropertyStore(STGM_READ, &pPropertyStore);
|
||||
|
@ -336,7 +376,7 @@ QString friendlyNameForAudioDevice(IMMDevice* pEndpoint) {
|
|||
return deviceName;
|
||||
}
|
||||
|
||||
QString AudioClient::friendlyNameForAudioDevice(wchar_t* guid) {
|
||||
QString AudioClient::getWinDeviceName(wchar_t* guid) {
|
||||
QString deviceName;
|
||||
HRESULT hr = S_OK;
|
||||
CoInitialize(nullptr);
|
||||
|
@ -348,7 +388,7 @@ QString AudioClient::friendlyNameForAudioDevice(wchar_t* guid) {
|
|||
printf("Audio Error: device not found\n");
|
||||
deviceName = QString("NONE");
|
||||
} else {
|
||||
deviceName = ::friendlyNameForAudioDevice(pEndpoint);
|
||||
deviceName = ::getWinDeviceName(pEndpoint);
|
||||
}
|
||||
pMMDeviceEnumerator->Release();
|
||||
pMMDeviceEnumerator = nullptr;
|
||||
|
@ -431,7 +471,7 @@ QAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) {
|
|||
printf("Audio Error: device not found\n");
|
||||
deviceName = QString("NONE");
|
||||
} else {
|
||||
deviceName = friendlyNameForAudioDevice(pEndpoint);
|
||||
deviceName = getWinDeviceName(pEndpoint);
|
||||
}
|
||||
pMMDeviceEnumerator->Release();
|
||||
pMMDeviceEnumerator = NULL;
|
||||
|
@ -791,29 +831,12 @@ void AudioClient::selectAudioFormat(const QString& selectedCodecName) {
|
|||
|
||||
}
|
||||
|
||||
|
||||
QString AudioClient::getDefaultDeviceName(QAudio::Mode mode) {
|
||||
QAudioDeviceInfo deviceInfo = defaultAudioDeviceForMode(mode);
|
||||
return deviceInfo.deviceName();
|
||||
}
|
||||
|
||||
QVector<QString> AudioClient::getDeviceNames(QAudio::Mode mode) {
|
||||
QVector<QString> deviceNames;
|
||||
const QList<QAudioDeviceInfo> &availableDevice = getAvailableDevices(mode);
|
||||
foreach(const QAudioDeviceInfo &audioDevice, availableDevice) {
|
||||
deviceNames << audioDevice.deviceName().trimmed();
|
||||
bool AudioClient::switchAudioDevice(QAudio::Mode mode, const QAudioDeviceInfo& deviceInfo) {
|
||||
if (mode == QAudio::AudioInput) {
|
||||
return switchInputToAudioDevice(deviceInfo);
|
||||
} else { // if (mode == QAudio::AudioOutput)
|
||||
return switchOutputToAudioDevice(deviceInfo);
|
||||
}
|
||||
return deviceNames;
|
||||
}
|
||||
|
||||
bool AudioClient::switchInputToAudioDevice(const QString& inputDeviceName) {
|
||||
qCDebug(audioclient) << "[" << inputDeviceName << "] [" << getNamedAudioDeviceForMode(QAudio::AudioInput, inputDeviceName).deviceName() << "]";
|
||||
return switchInputToAudioDevice(getNamedAudioDeviceForMode(QAudio::AudioInput, inputDeviceName));
|
||||
}
|
||||
|
||||
bool AudioClient::switchOutputToAudioDevice(const QString& outputDeviceName) {
|
||||
qCDebug(audioclient) << "[" << outputDeviceName << "] [" << getNamedAudioDeviceForMode(QAudio::AudioOutput, outputDeviceName).deviceName() << "]";
|
||||
return switchOutputToAudioDevice(getNamedAudioDeviceForMode(QAudio::AudioOutput, outputDeviceName));
|
||||
}
|
||||
|
||||
void AudioClient::configureReverb() {
|
||||
|
@ -1357,7 +1380,7 @@ void AudioClient::setIsStereoInput(bool isStereoInput) {
|
|||
}
|
||||
|
||||
// change in channel count for desired input format, restart the input device
|
||||
switchInputToAudioDevice(_inputAudioDeviceName);
|
||||
switchInputToAudioDevice(_inputDeviceInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1397,6 +1420,9 @@ void AudioClient::outputFormatChanged() {
|
|||
bool AudioClient::switchInputToAudioDevice(const QAudioDeviceInfo& inputDeviceInfo) {
|
||||
bool supportedFormat = false;
|
||||
|
||||
// NOTE: device start() uses the Qt internal device list
|
||||
Lock lock(_deviceMutex);
|
||||
|
||||
// cleanup any previously initialized device
|
||||
if (_audioInput) {
|
||||
// The call to stop() causes _inputDevice to be destructed.
|
||||
|
@ -1409,7 +1435,7 @@ bool AudioClient::switchInputToAudioDevice(const QAudioDeviceInfo& inputDeviceIn
|
|||
_audioInput = NULL;
|
||||
_numInputCallbackBytes = 0;
|
||||
|
||||
_inputAudioDeviceName = "";
|
||||
_inputDeviceInfo = QAudioDeviceInfo();
|
||||
}
|
||||
|
||||
if (_inputToNetworkResampler) {
|
||||
|
@ -1424,8 +1450,8 @@ bool AudioClient::switchInputToAudioDevice(const QAudioDeviceInfo& inputDeviceIn
|
|||
|
||||
if (!inputDeviceInfo.isNull()) {
|
||||
qCDebug(audioclient) << "The audio input device " << inputDeviceInfo.deviceName() << "is available.";
|
||||
_inputAudioDeviceName = inputDeviceInfo.deviceName().trimmed();
|
||||
emit currentInputDeviceChanged(_inputAudioDeviceName);
|
||||
_inputDeviceInfo = inputDeviceInfo;
|
||||
emit deviceChanged(QAudio::AudioInput, inputDeviceInfo);
|
||||
|
||||
if (adjustedFormatForAudioDevice(inputDeviceInfo, _desiredInputFormat, _inputFormat)) {
|
||||
qCDebug(audioclient) << "The format to be used for audio input is" << _inputFormat;
|
||||
|
@ -1460,10 +1486,7 @@ bool AudioClient::switchInputToAudioDevice(const QAudioDeviceInfo& inputDeviceIn
|
|||
int numFrameSamples = calculateNumberOfFrameSamples(_numInputCallbackBytes);
|
||||
_inputRingBuffer.resizeForFrameSize(numFrameSamples);
|
||||
|
||||
// NOTE: device start() uses the Qt internal device list
|
||||
Lock lock(_deviceMutex);
|
||||
_inputDevice = _audioInput->start();
|
||||
lock.unlock();
|
||||
|
||||
if (_inputDevice) {
|
||||
connect(_inputDevice, SIGNAL(readyRead()), this, SLOT(handleMicAudioInput()));
|
||||
|
@ -1511,6 +1534,9 @@ void AudioClient::outputNotify() {
|
|||
bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo& outputDeviceInfo) {
|
||||
bool supportedFormat = false;
|
||||
|
||||
// NOTE: device start() uses the Qt internal device list
|
||||
Lock lock(_deviceMutex);
|
||||
|
||||
Lock localAudioLock(_localAudioMutex);
|
||||
_localSamplesAvailable.exchange(0, std::memory_order_release);
|
||||
|
||||
|
@ -1536,6 +1562,8 @@ bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo& outputDevice
|
|||
|
||||
delete[] _localOutputMixBuffer;
|
||||
_localOutputMixBuffer = NULL;
|
||||
|
||||
_outputDeviceInfo = QAudioDeviceInfo();
|
||||
}
|
||||
|
||||
if (_networkToOutputResampler) {
|
||||
|
@ -1549,8 +1577,8 @@ bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo& outputDevice
|
|||
|
||||
if (!outputDeviceInfo.isNull()) {
|
||||
qCDebug(audioclient) << "The audio output device " << outputDeviceInfo.deviceName() << "is available.";
|
||||
_outputAudioDeviceName = outputDeviceInfo.deviceName().trimmed();
|
||||
emit currentOutputDeviceChanged(_outputAudioDeviceName);
|
||||
_outputDeviceInfo = outputDeviceInfo;
|
||||
emit deviceChanged(QAudio::AudioOutput, outputDeviceInfo);
|
||||
|
||||
if (adjustedFormatForAudioDevice(outputDeviceInfo, _desiredOutputFormat, _outputFormat)) {
|
||||
qCDebug(audioclient) << "The format to be used for audio output is" << _outputFormat;
|
||||
|
@ -1625,10 +1653,7 @@ bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo& outputDevice
|
|||
|
||||
_audioOutputIODevice.start();
|
||||
|
||||
// NOTE: device start() uses the Qt internal device list
|
||||
Lock lock(_deviceMutex);
|
||||
_audioOutput->start(&_audioOutputIODevice);
|
||||
lock.unlock();
|
||||
|
||||
// setup a loopback audio output device
|
||||
_loopbackAudioOutput = new QAudioOutput(outputDeviceInfo, _outputFormat, this);
|
||||
|
@ -1821,19 +1846,6 @@ qint64 AudioClient::AudioOutputIODevice::readData(char * data, qint64 maxSize) {
|
|||
return bytesWritten;
|
||||
}
|
||||
|
||||
// now called from a background thread, to keep blocking operations off the audio thread
|
||||
void AudioClient::checkDevices() {
|
||||
QVector<QString> inputDevices = getDeviceNames(QAudio::AudioInput);
|
||||
QVector<QString> outputDevices = getDeviceNames(QAudio::AudioOutput);
|
||||
|
||||
if (inputDevices != _inputDevices || outputDevices != _outputDevices) {
|
||||
_inputDevices = inputDevices;
|
||||
_outputDevices = outputDevices;
|
||||
|
||||
emit deviceChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void AudioClient::loadSettings() {
|
||||
_receivedAudioStream.setDynamicJitterBufferEnabled(dynamicJitterBufferEnabled.get());
|
||||
_receivedAudioStream.setStaticJitterBufferFrames(staticJitterBufferFrames.get());
|
||||
|
|
|
@ -146,10 +146,13 @@ public:
|
|||
|
||||
bool outputLocalInjector(AudioInjector* injector) override;
|
||||
|
||||
QAudioDeviceInfo getActiveAudioDevice(QAudio::Mode mode) const;
|
||||
QList<QAudioDeviceInfo> getAudioDevices(QAudio::Mode mode) const;
|
||||
|
||||
static const float CALLBACK_ACCELERATOR_RATIO;
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
static QString friendlyNameForAudioDevice(wchar_t* guid);
|
||||
static QString getWinDeviceName(wchar_t* guid);
|
||||
#endif
|
||||
|
||||
public slots:
|
||||
|
@ -185,12 +188,7 @@ public slots:
|
|||
|
||||
bool shouldLoopbackInjectors() override { return _shouldEchoToServer; }
|
||||
|
||||
bool switchInputToAudioDevice(const QString& inputDeviceName);
|
||||
bool switchOutputToAudioDevice(const QString& outputDeviceName);
|
||||
QString getDeviceName(QAudio::Mode mode) const { return (mode == QAudio::AudioInput) ?
|
||||
_inputAudioDeviceName : _outputAudioDeviceName; }
|
||||
QString getDefaultDeviceName(QAudio::Mode mode);
|
||||
QVector<QString> getDeviceNames(QAudio::Mode mode);
|
||||
bool switchAudioDevice(QAudio::Mode mode, const QAudioDeviceInfo& deviceInfo);
|
||||
|
||||
float getInputVolume() const { return (_audioInput) ? (float)_audioInput->volume() : 0.0f; }
|
||||
void setInputVolume(float volume) { if (_audioInput) _audioInput->setVolume(volume); }
|
||||
|
@ -212,7 +210,9 @@ signals:
|
|||
void noiseGateClosed();
|
||||
|
||||
void changeDevice(const QAudioDeviceInfo& outputDeviceInfo);
|
||||
void deviceChanged();
|
||||
|
||||
void deviceChanged(QAudio::Mode mode, const QAudioDeviceInfo& device);
|
||||
void devicesChanged(QAudio::Mode mode, const QList<QAudioDeviceInfo>& devices);
|
||||
|
||||
void receivedFirstPacket();
|
||||
void disconnected();
|
||||
|
@ -221,9 +221,6 @@ signals:
|
|||
|
||||
void muteEnvironmentRequested(glm::vec3 position, float radius);
|
||||
|
||||
void currentOutputDeviceChanged(const QString& name);
|
||||
void currentInputDeviceChanged(const QString& name);
|
||||
|
||||
protected:
|
||||
AudioClient();
|
||||
~AudioClient();
|
||||
|
@ -290,9 +287,6 @@ private:
|
|||
MixedProcessedAudioStream _receivedAudioStream;
|
||||
bool _isStereoInput;
|
||||
|
||||
QString _inputAudioDeviceName;
|
||||
QString _outputAudioDeviceName;
|
||||
|
||||
quint64 _outputStarveDetectionStartTimeMsec;
|
||||
int _outputStarveDetectionCount;
|
||||
|
||||
|
@ -368,8 +362,11 @@ private:
|
|||
glm::vec3 avatarBoundingBoxCorner;
|
||||
glm::vec3 avatarBoundingBoxScale;
|
||||
|
||||
QVector<QString> _inputDevices;
|
||||
QVector<QString> _outputDevices;
|
||||
QAudioDeviceInfo _inputDeviceInfo;
|
||||
QAudioDeviceInfo _outputDeviceInfo;
|
||||
|
||||
QList<QAudioDeviceInfo> _inputDevices;
|
||||
QList<QAudioDeviceInfo> _outputDevices;
|
||||
|
||||
bool _hasReceivedFirstPacket { false };
|
||||
|
||||
|
|
|
@ -244,7 +244,7 @@ QString OculusDisplayPlugin::getPreferredAudioInDevice() const {
|
|||
if (!OVR_SUCCESS(ovr_GetAudioDeviceInGuidStr(buffer))) {
|
||||
return QString();
|
||||
}
|
||||
return AudioClient::friendlyNameForAudioDevice(buffer);
|
||||
return AudioClient::getWinDeviceName(buffer);
|
||||
}
|
||||
|
||||
QString OculusDisplayPlugin::getPreferredAudioOutDevice() const {
|
||||
|
@ -252,7 +252,7 @@ QString OculusDisplayPlugin::getPreferredAudioOutDevice() const {
|
|||
if (!OVR_SUCCESS(ovr_GetAudioDeviceOutGuidStr(buffer))) {
|
||||
return QString();
|
||||
}
|
||||
return AudioClient::friendlyNameForAudioDevice(buffer);
|
||||
return AudioClient::getWinDeviceName(buffer);
|
||||
}
|
||||
|
||||
OculusDisplayPlugin::~OculusDisplayPlugin() {
|
||||
|
|
Loading…
Reference in a new issue