created new AudioWrapper

This commit is contained in:
amerhifi 2019-09-13 11:24:41 -07:00
parent a3fa82d72e
commit cc11bd9552
7 changed files with 324 additions and 358 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([&] { withWriteLock([&] {
_devices.chooseInputDevice(device, isHMD); _devices.chooseInputDevice(device, isHMD);
}); });
} }
void Audio::setOutputDevice(const QAudioDeviceInfo& device, bool isHMD) { void Audio::setOutputDevice(const HifiAudioDeviceInfo& device, bool isHMD) {
withWriteLock([&] { withWriteLock([&] {
_devices.chooseOutputDevice(device, isHMD); _devices.chooseOutputDevice(device, isHMD);
}); });

View file

@ -19,6 +19,7 @@
#include "SettingHandle.h" #include "SettingHandle.h"
#include "AudioFileWav.h" #include "AudioFileWav.h"
#include <shared/ReadWriteLockable.h> #include <shared/ReadWriteLockable.h>
#include "HifiAudioDeviceInfo.h"
using MutedGetter = std::function<bool()>; using MutedGetter = std::function<bool()>;
using MutedSetter = std::function<void(bool)>; using MutedSetter = std::function<void(bool)>;
@ -158,7 +159,7 @@ public:
* @param {boolean} isHMD - Is HMD. * @param {boolean} isHMD - Is HMD.
* @deprecated This function is deprecated and will be removed. * @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 /**jsdoc
* @function Audio.setOutputDevice * @function Audio.setOutputDevice
@ -166,7 +167,7 @@ public:
* @param {boolean} isHMD - Is HMD. * @param {boolean} isHMD - Is HMD.
* @deprecated This function is deprecated and will be removed. * @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 /**jsdoc
* Enables or disables reverberation. Reverberation is done by the client on the post-mix audio. The reverberation options * 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> hmdInputDeviceSetting { QStringList { Audio::AUDIO, Audio::HMD, "INPUT" }};
static Setting::Handle<QString> hmdOutputDeviceSetting { QStringList { Audio::AUDIO, Audio::HMD, "OUTPUT" }}; static Setting::Handle<QString> hmdOutputDeviceSetting { QStringList { Audio::AUDIO, Audio::HMD, "OUTPUT" }};
Q_DECLARE_METATYPE(HifiAudioDeviceInfo);
Setting::Handle<QString>& getSetting(bool contextIsHMD, QAudio::Mode mode) { Setting::Handle<QString>& getSetting(bool contextIsHMD, QAudio::Mode mode) {
if (mode == QAudio::AudioInput) { if (mode == QAudio::AudioInput) {
return contextIsHMD ? hmdInputDeviceSetting : desktopInputDeviceSetting; return contextIsHMD ? hmdInputDeviceSetting : desktopInputDeviceSetting;
@ -139,7 +141,7 @@ QVariant AudioDeviceList::data(const QModelIndex& index, int role) const {
} else if (role == SelectedHMDRole) { } else if (role == SelectedHMDRole) {
return _devices.at(index.row())->selectedHMD; return _devices.at(index.row())->selectedHMD;
} else if (role == InfoRole) { } else if (role == InfoRole) {
return QVariant::fromValue<QAudioDeviceInfo>(_devices.at(index.row())->info); return QVariant::fromValue<HifiAudioDeviceInfo>(_devices.at(index.row())->info);
} else { } else {
return QVariant(); return QVariant();
} }
@ -191,8 +193,8 @@ void AudioDeviceList::resetDevice(bool contextIsHMD) {
#endif #endif
} }
void AudioDeviceList::onDeviceChanged(const QAudioDeviceInfo& device, bool isHMD) { void AudioDeviceList::onDeviceChanged(const HifiAudioDeviceInfo& device, bool isHMD) {
QAudioDeviceInfo& selectedDevice = isHMD ? _selectedHMDDevice : _selectedDesktopDevice; HifiAudioDeviceInfo& selectedDevice = isHMD ? _selectedHMDDevice : _selectedDesktopDevice;
selectedDevice = device; selectedDevice = device;
for (auto i = 0; i < _devices.size(); ++i) { for (auto i = 0; i < _devices.size(); ++i) {
@ -259,25 +261,25 @@ std::shared_ptr<scripting::AudioDevice> getSimilarDevice(const QString& deviceNa
return devices[minDistanceIndex]; return devices[minDistanceIndex];
} }
void AudioDeviceList::onDevicesChanged(const QList<QAudioDeviceInfo>& devices) { void AudioDeviceList::onDevicesChanged(const QList<HifiAudioDeviceInfo>& devices) {
beginResetModel(); beginResetModel();
QList<std::shared_ptr<AudioDevice>> newDevices; QList<std::shared_ptr<AudioDevice>> newDevices;
bool hmdIsSelected = false; bool hmdIsSelected = false;
bool desktopIsSelected = false; bool desktopIsSelected = false;
foreach(const QAudioDeviceInfo& deviceInfo, devices) { foreach(const HifiAudioDeviceInfo& deviceInfo, devices) {
for (bool isHMD : {false, true}) { for (bool isHMD : {false, true}) {
auto& backupSelectedDeviceName = isHMD ? _backupSelectedHMDDeviceName : _backupSelectedDesktopDeviceName; auto& backupSelectedDeviceName = isHMD ? _backupSelectedHMDDeviceName : _backupSelectedDesktopDeviceName;
if (deviceInfo.deviceName() == backupSelectedDeviceName) { if (deviceInfo.deviceName() == backupSelectedDeviceName) {
QAudioDeviceInfo& selectedDevice = isHMD ? _selectedHMDDevice : _selectedDesktopDevice; HifiAudioDeviceInfo& selectedDevice = isHMD ? _selectedHMDDevice : _selectedDesktopDevice;
selectedDevice = deviceInfo; selectedDevice = deviceInfo;
backupSelectedDeviceName.clear(); backupSelectedDeviceName.clear();
} }
} }
} }
foreach(const QAudioDeviceInfo& deviceInfo, devices) { foreach(const HifiAudioDeviceInfo& deviceInfo, devices) {
AudioDevice device; AudioDevice device;
device.info = deviceInfo; device.info = deviceInfo;
device.display = device.info.deviceName() device.display = device.info.deviceName()
@ -286,10 +288,10 @@ void AudioDeviceList::onDevicesChanged(const QList<QAudioDeviceInfo>& devices) {
.replace(" )", ")"); .replace(" )", ")");
for (bool isHMD : {false, true}) { for (bool isHMD : {false, true}) {
QAudioDeviceInfo& selectedDevice = isHMD ? _selectedHMDDevice : _selectedDesktopDevice; HifiAudioDeviceInfo& selectedDevice = isHMD ? _selectedHMDDevice : _selectedDesktopDevice;
bool& isSelected = isHMD ? device.selectedHMD : device.selectedDesktop; bool& isSelected = isHMD ? device.selectedHMD : device.selectedDesktop;
if (!selectedDevice.isNull()) { if (!selectedDevice.getDevice().isNull()) {
isSelected = (device.info == selectedDevice); isSelected = (device.info == selectedDevice);
} }
else { else {
@ -325,13 +327,13 @@ void AudioDeviceList::onDevicesChanged(const QList<QAudioDeviceInfo>& devices) {
if (!newDevices.isEmpty()) { if (!newDevices.isEmpty()) {
if (!hmdIsSelected) { if (!hmdIsSelected) {
_backupSelectedHMDDeviceName = !_selectedHMDDevice.isNull() ? _selectedHMDDevice.deviceName() : _hmdSavedDeviceName; _backupSelectedHMDDeviceName = !_selectedHMDDevice.getDevice().isNull() ? _selectedHMDDevice.deviceName() : _hmdSavedDeviceName;
auto device = getSimilarDevice(_backupSelectedHMDDeviceName, newDevices); auto device = getSimilarDevice(_backupSelectedHMDDeviceName, newDevices);
device->selectedHMD = true; device->selectedHMD = true;
emit selectedDevicePlugged(device->info, true); emit selectedDevicePlugged(device->info, true);
} }
if (!desktopIsSelected) { if (!desktopIsSelected) {
_backupSelectedDesktopDeviceName = !_selectedDesktopDevice.isNull() ? _selectedDesktopDevice.deviceName() : _desktopSavedDeviceName; _backupSelectedDesktopDeviceName = !_selectedDesktopDevice.getDevice().isNull() ? _selectedDesktopDevice.deviceName() : _desktopSavedDeviceName;
auto device = getSimilarDevice(_backupSelectedDesktopDeviceName, newDevices); auto device = getSimilarDevice(_backupSelectedDesktopDeviceName, newDevices);
device->selectedDesktop = true; device->selectedDesktop = true;
emit selectedDevicePlugged(device->info, false); emit selectedDevicePlugged(device->info, false);
@ -382,8 +384,8 @@ AudioDevices::AudioDevices(bool& contextIsHMD) : _contextIsHMD(contextIsHMD) {
_outputs.onDeviceChanged(client->getActiveAudioDevice(QAudio::AudioOutput), contextIsHMD); _outputs.onDeviceChanged(client->getActiveAudioDevice(QAudio::AudioOutput), contextIsHMD);
// connections are made after client is initialized, so we must also fetch the devices // connections are made after client is initialized, so we must also fetch the devices
const QList<QAudioDeviceInfo>& devicesInput = client->getAudioDevices(QAudio::AudioInput); const QList<HifiAudioDeviceInfo>& devicesInput = client->getAudioDevices(QAudio::AudioInput);
const QList<QAudioDeviceInfo>& devicesOutput = client->getAudioDevices(QAudio::AudioOutput); const QList<HifiAudioDeviceInfo>& devicesOutput = client->getAudioDevices(QAudio::AudioOutput);
//setup devices //setup devices
_inputs.onDevicesChanged(devicesInput); _inputs.onDevicesChanged(devicesInput);
@ -397,9 +399,9 @@ void AudioDevices::onContextChanged(const QString& context) {
_outputs.resetDevice(_contextIsHMD); _outputs.resetDevice(_contextIsHMD);
} }
void AudioDevices::onDeviceSelected(QAudio::Mode mode, const QAudioDeviceInfo& device, void AudioDevices::onDeviceSelected(QAudio::Mode mode, const HifiAudioDeviceInfo& device,
const QAudioDeviceInfo& previousDevice, bool isHMD) { const HifiAudioDeviceInfo& previousDevice, bool isHMD) {
QString deviceName = device.isNull() ? QString() : device.deviceName(); QString deviceName = device.getDevice().isNull() ? QString() : device.deviceName();
auto& setting = getSetting(isHMD, mode); auto& setting = getSetting(isHMD, mode);
@ -410,7 +412,7 @@ void AudioDevices::onDeviceSelected(QAudio::Mode mode, const QAudioDeviceInfo& d
setting.set(deviceName); setting.set(deviceName);
// log the selected device // log the selected device
if (!device.isNull()) { if (!device.getDevice().isNull()) {
QJsonObject data; QJsonObject data;
const QString MODE = "audio_mode"; const QString MODE = "audio_mode";
@ -434,13 +436,13 @@ void AudioDevices::onDeviceSelected(QAudio::Mode mode, const QAudioDeviceInfo& d
} }
} }
void AudioDevices::onDeviceChanged(QAudio::Mode mode, const QAudioDeviceInfo& device) { void AudioDevices::onDeviceChanged(QAudio::Mode mode, const HifiAudioDeviceInfo& device) {
if (mode == QAudio::AudioInput) { if (mode == QAudio::AudioInput) {
if (_requestedInputDevice == device) { if (_requestedInputDevice == device) {
onDeviceSelected(QAudio::AudioInput, device, onDeviceSelected(QAudio::AudioInput, device,
_contextIsHMD ? _inputs._selectedHMDDevice : _inputs._selectedDesktopDevice, _contextIsHMD ? _inputs._selectedHMDDevice : _inputs._selectedDesktopDevice,
_contextIsHMD); _contextIsHMD);
_requestedInputDevice = QAudioDeviceInfo(); _requestedInputDevice = HifiAudioDeviceInfo();
} }
_inputs.onDeviceChanged(device, _contextIsHMD); _inputs.onDeviceChanged(device, _contextIsHMD);
} else { // if (mode == QAudio::AudioOutput) } else { // if (mode == QAudio::AudioOutput)
@ -448,13 +450,13 @@ void AudioDevices::onDeviceChanged(QAudio::Mode mode, const QAudioDeviceInfo& de
onDeviceSelected(QAudio::AudioOutput, device, onDeviceSelected(QAudio::AudioOutput, device,
_contextIsHMD ? _outputs._selectedHMDDevice : _outputs._selectedDesktopDevice, _contextIsHMD ? _outputs._selectedHMDDevice : _outputs._selectedDesktopDevice,
_contextIsHMD); _contextIsHMD);
_requestedOutputDevice = QAudioDeviceInfo(); _requestedOutputDevice = HifiAudioDeviceInfo();
} }
_outputs.onDeviceChanged(device, _contextIsHMD); _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; static std::once_flag once;
std::call_once(once, [&] { std::call_once(once, [&] {
//readout settings //readout settings
@ -503,14 +505,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 //check if current context equals device to change
if (_contextIsHMD == isHMD) { if (_contextIsHMD == isHMD) {
auto client = DependencyManager::get<AudioClient>().data(); auto client = DependencyManager::get<AudioClient>().data();
_requestedInputDevice = device; _requestedInputDevice = device;
QMetaObject::invokeMethod(client, "switchAudioDevice", QMetaObject::invokeMethod(client, "switchAudioDevice",
Q_ARG(QAudio::Mode, QAudio::AudioInput), Q_ARG(QAudio::Mode, QAudio::AudioInput),
Q_ARG(const QAudioDeviceInfo&, device)); Q_ARG(const QAudioDeviceInfo&, device.getDevice()));
} else { } else {
//context is different. just save device in settings //context is different. just save device in settings
onDeviceSelected(QAudio::AudioInput, device, onDeviceSelected(QAudio::AudioInput, device,
@ -520,14 +522,14 @@ void AudioDevices::chooseInputDevice(const QAudioDeviceInfo& device, bool isHMD)
} }
} }
void AudioDevices::chooseOutputDevice(const QAudioDeviceInfo& device, bool isHMD) { void AudioDevices::chooseOutputDevice(const HifiAudioDeviceInfo& device, bool isHMD) {
//check if current context equals device to change //check if current context equals device to change
if (_contextIsHMD == isHMD) { if (_contextIsHMD == isHMD) {
auto client = DependencyManager::get<AudioClient>().data(); auto client = DependencyManager::get<AudioClient>().data();
_requestedOutputDevice = device; _requestedOutputDevice = device;
QMetaObject::invokeMethod(client, "switchAudioDevice", QMetaObject::invokeMethod(client, "switchAudioDevice",
Q_ARG(QAudio::Mode, QAudio::AudioOutput), Q_ARG(QAudio::Mode, QAudio::AudioOutput),
Q_ARG(const QAudioDeviceInfo&, device)); Q_ARG(const QAudioDeviceInfo&, device.getDevice()));
} else { } else {
//context is different. just save device in settings //context is different. just save device in settings
onDeviceSelected(QAudio::AudioOutput, device, onDeviceSelected(QAudio::AudioOutput, device,

View file

@ -19,11 +19,13 @@
#include <QAbstractListModel> #include <QAbstractListModel>
#include <QAudioDeviceInfo> #include <QAudioDeviceInfo>
#include "HifiAudioDeviceInfo.h"
namespace scripting { namespace scripting {
class AudioDevice { class AudioDevice {
public: public:
QAudioDeviceInfo info; HifiAudioDeviceInfo info;
QString display; QString display;
bool selectedDesktop { false }; bool selectedDesktop { false };
bool selectedHMD { false }; bool selectedHMD { false };
@ -50,12 +52,12 @@ public:
void resetDevice(bool contextIsHMD); void resetDevice(bool contextIsHMD);
signals: signals:
void deviceChanged(const QAudioDeviceInfo& device); void deviceChanged(const HifiAudioDeviceInfo& device);
void selectedDevicePlugged(const QAudioDeviceInfo& device, bool isHMD); void selectedDevicePlugged(const HifiAudioDeviceInfo& device, bool isHMD);
protected slots: protected slots:
void onDeviceChanged(const QAudioDeviceInfo& device, bool isHMD); void onDeviceChanged(const HifiAudioDeviceInfo& device, bool isHMD);
void onDevicesChanged(const QList<QAudioDeviceInfo>& devices); void onDevicesChanged(const QList<HifiAudioDeviceInfo>& devices);
protected: protected:
friend class AudioDevices; friend class AudioDevices;
@ -63,8 +65,8 @@ protected:
static QHash<int, QByteArray> _roles; static QHash<int, QByteArray> _roles;
static Qt::ItemFlags _flags; static Qt::ItemFlags _flags;
const QAudio::Mode _mode; const QAudio::Mode _mode;
QAudioDeviceInfo _selectedDesktopDevice; HifiAudioDeviceInfo _selectedDesktopDevice;
QAudioDeviceInfo _selectedHMDDevice; HifiAudioDeviceInfo _selectedHMDDevice;
QString _backupSelectedDesktopDeviceName; QString _backupSelectedDesktopDeviceName;
QString _backupSelectedHMDDeviceName; QString _backupSelectedHMDDeviceName;
QList<std::shared_ptr<AudioDevice>> _devices; QList<std::shared_ptr<AudioDevice>> _devices;
@ -124,14 +126,14 @@ signals:
void nop(); void nop();
private slots: private slots:
void chooseInputDevice(const QAudioDeviceInfo& device, bool isHMD); void chooseInputDevice(const HifiAudioDeviceInfo& device, bool isHMD);
void chooseOutputDevice(const QAudioDeviceInfo& device, bool isHMD); void chooseOutputDevice(const HifiAudioDeviceInfo& device, bool isHMD);
void onContextChanged(const QString& context); void onContextChanged(const QString& context);
void onDeviceSelected(QAudio::Mode mode, const QAudioDeviceInfo& device, void onDeviceSelected(QAudio::Mode mode, const HifiAudioDeviceInfo& device,
const QAudioDeviceInfo& previousDevice, bool isHMD); const HifiAudioDeviceInfo& previousDevice, bool isHMD);
void onDeviceChanged(QAudio::Mode mode, const QAudioDeviceInfo& device); void onDeviceChanged(QAudio::Mode mode, const HifiAudioDeviceInfo& device);
void onDevicesChanged(QAudio::Mode mode, const QList<QAudioDeviceInfo>& devices); void onDevicesChanged(QAudio::Mode mode, const QList<HifiAudioDeviceInfo>& devices);
private: private:
friend class Audio; friend class Audio;
@ -141,8 +143,8 @@ private:
AudioInputDeviceList _inputs; AudioInputDeviceList _inputs;
AudioDeviceList _outputs { QAudio::AudioOutput }; AudioDeviceList _outputs { QAudio::AudioOutput };
QAudioDeviceInfo _requestedOutputDevice; HifiAudioDeviceInfo _requestedOutputDevice;
QAudioDeviceInfo _requestedInputDevice; HifiAudioDeviceInfo _requestedInputDevice;
const bool& _contextIsHMD; const bool& _contextIsHMD;
}; };

File diff suppressed because it is too large Load diff

View file

@ -53,18 +53,19 @@
#include "AudioIOStats.h" #include "AudioIOStats.h"
#include "AudioFileWav.h" #include "AudioFileWav.h"
#include "HifiAudioDeviceInfo.h"
#ifdef _WIN32 #ifdef _WIN32
#pragma warning( push ) #pragma warning(push)
#pragma warning( disable : 4273 ) #pragma warning(disable : 4273)
#pragma warning( disable : 4305 ) #pragma warning(disable : 4305)
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
#pragma warning( pop ) #pragma warning(pop)
#endif #endif
#if defined (Q_OS_ANDROID) #if defined(Q_OS_ANDROID)
#define VOICE_RECOGNITION "voicerecognition" #define VOICE_RECOGNITION "voicerecognition"
#define VOICE_COMMUNICATION "voicecommunication" #define VOICE_COMMUNICATION "voicecommunication"
@ -79,11 +80,14 @@ class QIODevice;
class Transform; class Transform;
class NLPacket; class NLPacket;
class AudioClient : public AbstractAudioInterface, public Dependency { class AudioClient : public AbstractAudioInterface, public Dependency {
Q_OBJECT Q_OBJECT
SINGLETON_DEPENDENCY SINGLETON_DEPENDENCY
using LocalInjectorsStream = AudioMixRingBuffer; using LocalInjectorsStream = AudioMixRingBuffer;
public: public:
static const int MIN_BUFFER_FRAMES; static const int MIN_BUFFER_FRAMES;
static const int MAX_BUFFER_FRAMES; static const int MAX_BUFFER_FRAMES;
@ -96,15 +100,21 @@ public:
class AudioOutputIODevice : public QIODevice { class AudioOutputIODevice : public QIODevice {
public: public:
AudioOutputIODevice(LocalInjectorsStream& localInjectorsStream, MixedProcessedAudioStream& receivedAudioStream, AudioOutputIODevice(LocalInjectorsStream& localInjectorsStream,
AudioClient* audio) : MixedProcessedAudioStream& receivedAudioStream,
_localInjectorsStream(localInjectorsStream), _receivedAudioStream(receivedAudioStream), AudioClient* audio) :
_audio(audio), _unfulfilledReads(0) {} _localInjectorsStream(localInjectorsStream),
_receivedAudioStream(receivedAudioStream), _audio(audio), _unfulfilledReads(0) {}
void start() { open(QIODevice::ReadOnly | QIODevice::Unbuffered); } void start() { open(QIODevice::ReadOnly | QIODevice::Unbuffered); }
qint64 readData(char * data, qint64 maxSize) override; qint64 readData(char* data, qint64 maxSize) override;
qint64 writeData(const char * data, qint64 maxSize) override { return 0; } qint64 writeData(const char* data, qint64 maxSize) override { return 0; }
int getRecentUnfulfilledReads() { int unfulfilledReads = _unfulfilledReads; _unfulfilledReads = 0; return unfulfilledReads; } int getRecentUnfulfilledReads() {
int unfulfilledReads = _unfulfilledReads;
_unfulfilledReads = 0;
return unfulfilledReads;
}
private: private:
LocalInjectorsStream& _localInjectorsStream; LocalInjectorsStream& _localInjectorsStream;
MixedProcessedAudioStream& _receivedAudioStream; MixedProcessedAudioStream& _receivedAudioStream;
@ -152,11 +162,11 @@ public:
void setIsPlayingBackRecording(bool isPlayingBackRecording) { _isPlayingBackRecording = isPlayingBackRecording; } void setIsPlayingBackRecording(bool isPlayingBackRecording) { _isPlayingBackRecording = isPlayingBackRecording; }
Q_INVOKABLE void setAvatarBoundingBoxParameters(glm::vec3 corner, glm::vec3 scale); Q_INVOKABLE void setAvatarBoundingBoxParameters(glm::vec3 corner, glm::vec3 scale);
bool outputLocalInjector(const AudioInjectorPointer& injector) override; bool outputLocalInjector(const AudioInjectorPointer& injector) override;
QAudioDeviceInfo getActiveAudioDevice(QAudio::Mode mode) const; HifiAudioDeviceInfo getActiveAudioDevice(QAudio::Mode mode) const;
QList<QAudioDeviceInfo> getAudioDevices(QAudio::Mode mode) const; QList<HifiAudioDeviceInfo> getAudioDevices(QAudio::Mode mode) const;
void enablePeakValues(bool enable) { _enablePeakValues = enable; } void enablePeakValues(bool enable) { _enablePeakValues = enable; }
bool peakValuesAvailable() const; bool peakValuesAvailable() const;
@ -269,10 +279,10 @@ signals:
void noiseGateOpened(); void noiseGateOpened();
void noiseGateClosed(); void noiseGateClosed();
void changeDevice(const QAudioDeviceInfo& outputDeviceInfo); void changeDevice(const HifiAudioDeviceInfo& outputDeviceInfo);
void deviceChanged(QAudio::Mode mode, const QAudioDeviceInfo& device); void deviceChanged(QAudio::Mode mode, const HifiAudioDeviceInfo& device);
void devicesChanged(QAudio::Mode mode, const QList<QAudioDeviceInfo>& devices); void devicesChanged(QAudio::Mode mode, const QList<HifiAudioDeviceInfo>& devices);
void peakValueListChanged(const QList<float> peakValueList); void peakValueListChanged(const QList<float> peakValueList);
void receivedFirstPacket(); void receivedFirstPacket();
@ -345,7 +355,7 @@ private:
QIODevice* _inputDevice; QIODevice* _inputDevice;
int _numInputCallbackBytes; int _numInputCallbackBytes;
QAudioOutput* _audioOutput; QAudioOutput* _audioOutput;
std::atomic<bool> _audioOutputInitialized { false }; std::atomic<bool> _audioOutputInitialized{ false };
QAudioFormat _desiredOutputFormat; QAudioFormat _desiredOutputFormat;
QAudioFormat _outputFormat; QAudioFormat _outputFormat;
int _outputFrameSize; int _outputFrameSize;
@ -356,11 +366,11 @@ private:
LocalInjectorsStream _localInjectorsStream; LocalInjectorsStream _localInjectorsStream;
// In order to use _localInjectorsStream as a lock-free pipe, // In order to use _localInjectorsStream as a lock-free pipe,
// use it with a single producer/consumer, and track available samples and injectors // use it with a single producer/consumer, and track available samples and injectors
std::atomic<int> _localSamplesAvailable { 0 }; std::atomic<int> _localSamplesAvailable{ 0 };
std::atomic<bool> _localInjectorsAvailable { false }; std::atomic<bool> _localInjectorsAvailable{ false };
MixedProcessedAudioStream _receivedAudioStream; MixedProcessedAudioStream _receivedAudioStream;
bool _isStereoInput; bool _isStereoInput;
std::atomic<bool> _enablePeakValues { false }; std::atomic<bool> _enablePeakValues{ false };
quint64 _outputStarveDetectionStartTimeMsec; quint64 _outputStarveDetectionStartTimeMsec;
int _outputStarveDetectionCount; int _outputStarveDetectionCount;
@ -371,9 +381,9 @@ private:
StDev _stdev; StDev _stdev;
QElapsedTimer _timeSinceLastReceived; QElapsedTimer _timeSinceLastReceived;
float _lastRawInputLoudness; // before mute/gate float _lastRawInputLoudness; // before mute/gate
float _lastSmoothedRawInputLoudness; float _lastSmoothedRawInputLoudness;
float _lastInputLoudness; // after mute/gate float _lastInputLoudness; // after mute/gate
float _timeSinceLastClip; float _timeSinceLastClip;
int _totalInputAudioSamples; int _totalInputAudioSamples;
@ -388,9 +398,9 @@ private:
AudioEffectOptions _scriptReverbOptions; AudioEffectOptions _scriptReverbOptions;
AudioEffectOptions _zoneReverbOptions; AudioEffectOptions _zoneReverbOptions;
AudioEffectOptions* _reverbOptions; AudioEffectOptions* _reverbOptions;
AudioReverb _sourceReverb { AudioConstants::SAMPLE_RATE }; AudioReverb _sourceReverb{ AudioConstants::SAMPLE_RATE };
AudioReverb _listenerReverb { AudioConstants::SAMPLE_RATE }; AudioReverb _listenerReverb{ AudioConstants::SAMPLE_RATE };
AudioReverb _localReverb { AudioConstants::SAMPLE_RATE }; AudioReverb _localReverb{ AudioConstants::SAMPLE_RATE };
// possible streams needed for resample // possible streams needed for resample
AudioSRC* _inputToNetworkResampler; AudioSRC* _inputToNetworkResampler;
@ -402,21 +412,21 @@ private:
int16_t _networkScratchBuffer[AudioConstants::NETWORK_FRAME_SAMPLES_AMBISONIC]; int16_t _networkScratchBuffer[AudioConstants::NETWORK_FRAME_SAMPLES_AMBISONIC];
// for output audio (used by this thread) // for output audio (used by this thread)
int _outputPeriod { 0 }; int _outputPeriod{ 0 };
float* _outputMixBuffer { NULL }; float* _outputMixBuffer{ NULL };
int16_t* _outputScratchBuffer { NULL }; int16_t* _outputScratchBuffer{ NULL };
std::atomic<float> _outputGain { 1.0f }; std::atomic<float> _outputGain{ 1.0f };
float _lastOutputGain { 1.0f }; float _lastOutputGain{ 1.0f };
// for local audio (used by audio injectors thread) // for local audio (used by audio injectors thread)
std::atomic<float> _localInjectorGain { 1.0f }; std::atomic<float> _localInjectorGain{ 1.0f };
std::atomic<float> _systemInjectorGain { 1.0f }; std::atomic<float> _systemInjectorGain{ 1.0f };
float _localMixBuffer[AudioConstants::NETWORK_FRAME_SAMPLES_STEREO]; float _localMixBuffer[AudioConstants::NETWORK_FRAME_SAMPLES_STEREO];
int16_t _localScratchBuffer[AudioConstants::NETWORK_FRAME_SAMPLES_AMBISONIC]; int16_t _localScratchBuffer[AudioConstants::NETWORK_FRAME_SAMPLES_AMBISONIC];
float* _localOutputMixBuffer { NULL }; float* _localOutputMixBuffer{ NULL };
Mutex _localAudioMutex; Mutex _localAudioMutex;
AudioLimiter _audioLimiter; AudioLimiter _audioLimiter;
// Adds Reverb // Adds Reverb
void configureReverb(); void configureReverb();
void updateReverbOptions(); void updateReverbOptions();
@ -427,10 +437,10 @@ private:
static const int WEBRTC_CHANNELS_MAX = 2; static const int WEBRTC_CHANNELS_MAX = 2;
static const int WEBRTC_FRAMES_MAX = webrtc::AudioProcessing::kChunkSizeMs * WEBRTC_SAMPLE_RATE_MAX / 1000; static const int WEBRTC_FRAMES_MAX = webrtc::AudioProcessing::kChunkSizeMs * WEBRTC_SAMPLE_RATE_MAX / 1000;
webrtc::AudioProcessing* _apm { nullptr }; webrtc::AudioProcessing* _apm{ nullptr };
int16_t _fifoFarEnd[WEBRTC_CHANNELS_MAX * WEBRTC_FRAMES_MAX] {}; int16_t _fifoFarEnd[WEBRTC_CHANNELS_MAX * WEBRTC_FRAMES_MAX]{};
int _numFifoFarEnd = 0; // numFrames saved in fifo int _numFifoFarEnd = 0; // numFrames saved in fifo
void configureWebrtc(); void configureWebrtc();
void processWebrtcFarEnd(const int16_t* samples, int numFrames, int numChannels, int sampleRate); void processWebrtcFarEnd(const int16_t* samples, int numFrames, int numChannels, int sampleRate);
@ -450,8 +460,8 @@ private:
AudioIOStats _stats; AudioIOStats _stats;
AudioGate* _audioGate { nullptr }; AudioGate* _audioGate{ nullptr };
bool _audioGateOpen { true }; bool _audioGateOpen{ true };
AudioPositionGetter _positionGetter; AudioPositionGetter _positionGetter;
AudioOrientationGetter _orientationGetter; AudioOrientationGetter _orientationGetter;
@ -459,24 +469,30 @@ private:
glm::vec3 avatarBoundingBoxCorner; glm::vec3 avatarBoundingBoxCorner;
glm::vec3 avatarBoundingBoxScale; glm::vec3 avatarBoundingBoxScale;
QAudioDeviceInfo _inputDeviceInfo; HifiAudioDeviceInfo _inputDeviceInfo;
QAudioDeviceInfo _outputDeviceInfo; HifiAudioDeviceInfo _outputDeviceInfo;
QList<QAudioDeviceInfo> _inputDevices; QList<HifiAudioDeviceInfo> _inputDevices;
QList<QAudioDeviceInfo> _outputDevices; QList<HifiAudioDeviceInfo> _outputDevices;
//QAudioDeviceInfo _inputDeviceInfo;
// QAudioDeviceInfo _outputDeviceInfo;
// QList<QAudioDeviceInfo> _inputDevices;
/// QList<QAudioDeviceInfo> _outputDevices;
AudioFileWav _audioFileWav; AudioFileWav _audioFileWav;
bool _hasReceivedFirstPacket { false }; bool _hasReceivedFirstPacket{ false };
QVector<AudioInjectorPointer> _activeLocalAudioInjectors; QVector<AudioInjectorPointer> _activeLocalAudioInjectors;
bool _isPlayingBackRecording { false }; bool _isPlayingBackRecording{ false };
bool _audioPaused { false }; bool _audioPaused{ false };
CodecPluginPointer _codec; CodecPluginPointer _codec;
QString _selectedCodecName; QString _selectedCodecName;
Encoder* _encoder { nullptr }; // for outbound mic stream Encoder* _encoder{ nullptr }; // for outbound mic stream
RateCounter<> _silentOutbound; RateCounter<> _silentOutbound;
RateCounter<> _audioOutbound; RateCounter<> _audioOutbound;
@ -484,18 +500,17 @@ private:
RateCounter<> _audioInbound; RateCounter<> _audioInbound;
#if defined(Q_OS_ANDROID) #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 #endif
AudioSolo _solo; AudioSolo _solo;
Mutex _checkDevicesMutex;
QTimer* _checkDevicesTimer { nullptr };
Mutex _checkPeakValuesMutex;
QTimer* _checkPeakValuesTimer { nullptr };
bool _isRecording { false }; Mutex _checkDevicesMutex;
QTimer* _checkDevicesTimer{ nullptr };
Mutex _checkPeakValuesMutex;
QTimer* _checkPeakValuesTimer{ nullptr };
bool _isRecording{ false };
}; };
#endif // hifi_AudioClient_h
#endif // hifi_AudioClient_h

View file

@ -356,7 +356,7 @@ void OffscreenQmlSurface::onRootCreated() {
getSurfaceContext()->setContextProperty("offscreenWindow", QVariant::fromValue(getWindow())); getSurfaceContext()->setContextProperty("offscreenWindow", QVariant::fromValue(getWindow()));
// Connect with the audio client and listen for audio device changes // 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) { if (mode == QAudio::Mode::AudioOutput) {
QMetaObject::invokeMethod(this, "changeAudioOutputDevice", Qt::QueuedConnection, Q_ARG(QString, device.deviceName())); QMetaObject::invokeMethod(this, "changeAudioOutputDevice", Qt::QueuedConnection, Q_ARG(QString, device.deviceName()));
} }