mirror of
https://github.com/lubosz/overte.git
synced 2025-08-07 18:21:16 +02:00
Merge branch 'master' of github.com:highfidelity/hifi into friction
This commit is contained in:
commit
de4e8b9cc4
33 changed files with 475 additions and 240 deletions
|
@ -433,7 +433,7 @@ void Agent::executeScript() {
|
||||||
|
|
||||||
using namespace recording;
|
using namespace recording;
|
||||||
static const FrameType AUDIO_FRAME_TYPE = Frame::registerFrameType(AudioConstants::getAudioFrameName());
|
static const FrameType AUDIO_FRAME_TYPE = Frame::registerFrameType(AudioConstants::getAudioFrameName());
|
||||||
Frame::registerFrameHandler(AUDIO_FRAME_TYPE, [this, &scriptedAvatar](Frame::ConstPointer frame) {
|
Frame::registerFrameHandler(AUDIO_FRAME_TYPE, [this, &player, &scriptedAvatar](Frame::ConstPointer frame) {
|
||||||
if (_shouldMuteRecordingAudio) {
|
if (_shouldMuteRecordingAudio) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -442,9 +442,18 @@ void Agent::executeScript() {
|
||||||
|
|
||||||
QByteArray audio(frame->data);
|
QByteArray audio(frame->data);
|
||||||
|
|
||||||
|
int16_t* samples = reinterpret_cast<int16_t*>(audio.data());
|
||||||
|
int numSamples = AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL;
|
||||||
|
|
||||||
|
auto volume = player->getVolume();
|
||||||
|
if (volume >= 0.0f && volume < 1.0f) {
|
||||||
|
int32_t fract = (int32_t)(volume * (float)(1 << 16)); // Q16
|
||||||
|
for (int i = 0; i < numSamples; i++) {
|
||||||
|
samples[i] = (fract * (int32_t)samples[i]) >> 16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (_isNoiseGateEnabled) {
|
if (_isNoiseGateEnabled) {
|
||||||
int16_t* samples = reinterpret_cast<int16_t*>(audio.data());
|
|
||||||
int numSamples = AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL;
|
|
||||||
_audioGate.render(samples, samples, numSamples);
|
_audioGate.render(samples, samples, numSamples);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ MixerAvatar::MixerAvatar() {
|
||||||
_pendingEvent = false;
|
_pendingEvent = false;
|
||||||
_verifyState = verificationFailed;
|
_verifyState = verificationFailed;
|
||||||
_needsIdentityUpdate = true;
|
_needsIdentityUpdate = true;
|
||||||
qCDebug(avatars) << "Dynamic verification TIMED-OUT for " << getDisplayName() << getSessionUUID();
|
qCDebug(avatars) << "Dynamic verification TIMED-OUT for" << getDisplayName() << getSessionUUID();
|
||||||
} else {
|
} else {
|
||||||
qCDebug(avatars) << "Ignoring timeout of avatar challenge";
|
qCDebug(avatars) << "Ignoring timeout of avatar challenge";
|
||||||
}
|
}
|
||||||
|
@ -287,7 +287,7 @@ void MixerAvatar::processCertifyEvents() {
|
||||||
<< ":" << _dynamicMarketResponse;
|
<< ":" << _dynamicMarketResponse;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
qCDebug(avatars) << "Get owner status failed for " << getDisplayName() << _marketplaceIdFromURL <<
|
qCDebug(avatars) << "Get owner status failed for" << getDisplayName() << _marketplaceIdFromURL <<
|
||||||
"message:" << responseJson["message"].toString();
|
"message:" << responseJson["message"].toString();
|
||||||
_verifyState = error;
|
_verifyState = error;
|
||||||
}
|
}
|
||||||
|
@ -356,7 +356,7 @@ void MixerAvatar::processChallengeResponse(ReceivedMessage& response) {
|
||||||
_verifyState = challengeResult ? verificationSucceeded : verificationFailed;
|
_verifyState = challengeResult ? verificationSucceeded : verificationFailed;
|
||||||
_needsIdentityUpdate = true;
|
_needsIdentityUpdate = true;
|
||||||
if (_verifyState == verificationFailed) {
|
if (_verifyState == verificationFailed) {
|
||||||
qCDebug(avatars) << "Dynamic verification FAILED for " << getDisplayName() << getSessionUUID();
|
qCDebug(avatars) << "Dynamic verification FAILED for" << getDisplayName() << getSessionUUID();
|
||||||
} else {
|
} else {
|
||||||
qCDebug(avatars) << "Dynamic verification SUCCEEDED for" << getDisplayName() << getSessionUUID();
|
qCDebug(avatars) << "Dynamic verification SUCCEEDED for" << getDisplayName() << getSessionUUID();
|
||||||
}
|
}
|
||||||
|
|
|
@ -250,14 +250,14 @@ $(document).ready(function(){
|
||||||
|
|
||||||
// set focus to the first input in the new row
|
// set focus to the first input in the new row
|
||||||
$target.closest('table').find('tr.inputs input:first').focus();
|
$target.closest('table').find('tr.inputs input:first').focus();
|
||||||
}
|
} else {
|
||||||
|
var tableRows = sibling.parent();
|
||||||
|
var tableBody = tableRows.parent();
|
||||||
|
|
||||||
var tableRows = sibling.parent();
|
// if theres no more siblings, we should jump to a new row
|
||||||
var tableBody = tableRows.parent();
|
if (sibling.next().length == 0 && tableRows.nextAll().length == 1) {
|
||||||
|
tableBody.find("." + Settings.ADD_ROW_BUTTON_CLASS).click();
|
||||||
// if theres no more siblings, we should jump to a new row
|
}
|
||||||
if (sibling.next().length == 0 && tableRows.nextAll().length == 1) {
|
|
||||||
tableBody.find("." + Settings.ADD_ROW_BUTTON_CLASS).click();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -257,27 +257,26 @@ endif()
|
||||||
|
|
||||||
def installQt(self):
|
def installQt(self):
|
||||||
qt5InstallPath = self.getQt5InstallPath()
|
qt5InstallPath = self.getQt5InstallPath()
|
||||||
if os.getenv('QT_CMAKE_PREFIX_PATH') == None:
|
if not os.path.isdir(qt5InstallPath):
|
||||||
if not os.path.isdir(qt5InstallPath):
|
print ('Downloading Qt from AWS')
|
||||||
print ('Downloading Qt from AWS')
|
dest, tail = os.path.split(qt5InstallPath)
|
||||||
dest, tail = os.path.split(qt5InstallPath)
|
|
||||||
|
|
||||||
url = 'NOT DEFINED'
|
url = 'NOT DEFINED'
|
||||||
if platform.system() == 'Windows':
|
if platform.system() == 'Windows':
|
||||||
url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-windows3.tar.gz'
|
url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-windows3.tar.gz'
|
||||||
elif platform.system() == 'Darwin':
|
elif platform.system() == 'Darwin':
|
||||||
url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-macos3.tar.gz'
|
url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-macos3.tar.gz'
|
||||||
elif platform.system() == 'Linux':
|
elif platform.system() == 'Linux':
|
||||||
if platform.linux_distribution()[1][:3] == '16.':
|
if platform.linux_distribution()[1][:3] == '16.':
|
||||||
url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-ubuntu-16.04-with-symbols.tar.gz'
|
url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-ubuntu-16.04-with-symbols.tar.gz'
|
||||||
elif platform.linux_distribution()[1][:3] == '18.':
|
elif platform.linux_distribution()[1][:3] == '18.':
|
||||||
url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-ubuntu-18.04.tar.gz'
|
url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-ubuntu-18.04.tar.gz'
|
||||||
else:
|
|
||||||
print('UNKNOWN LINUX VERSION!!!')
|
|
||||||
else:
|
else:
|
||||||
print('UNKNOWN OPERATING SYSTEM!!!')
|
print('UNKNOWN LINUX VERSION!!!')
|
||||||
|
|
||||||
print('Extracting ' + url + ' to ' + dest)
|
|
||||||
hifi_utils.downloadAndExtract(url, dest)
|
|
||||||
else:
|
else:
|
||||||
print ('Qt has already been downloaded')
|
print('UNKNOWN OPERATING SYSTEM!!!')
|
||||||
|
|
||||||
|
print('Extracting ' + url + ' to ' + dest)
|
||||||
|
hifi_utils.downloadAndExtract(url, dest)
|
||||||
|
else:
|
||||||
|
print ('Qt has already been downloaded')
|
||||||
|
|
Binary file not shown.
|
@ -3799,8 +3799,8 @@
|
||||||
{
|
{
|
||||||
"easingType": "easeInOutQuad",
|
"easingType": "easeInOutQuad",
|
||||||
"id": "reactionPoint",
|
"id": "reactionPoint",
|
||||||
"interpDuration": 18,
|
"interpDuration": 10,
|
||||||
"interpTarget": 18,
|
"interpTarget": 10,
|
||||||
"interpType": "evaluateBoth",
|
"interpType": "evaluateBoth",
|
||||||
"transitions": [
|
"transitions": [
|
||||||
{
|
{
|
||||||
|
@ -4610,9 +4610,9 @@
|
||||||
{
|
{
|
||||||
"easingType": "easeInOutQuad",
|
"easingType": "easeInOutQuad",
|
||||||
"id": "idle",
|
"id": "idle",
|
||||||
"interpDuration": 30,
|
"interpDuration": 10,
|
||||||
"interpTarget": 30,
|
"interpTarget": 10,
|
||||||
"interpType": "evaluateBoth",
|
"interpType": "snapshotPrev",
|
||||||
"transitions": [
|
"transitions": [
|
||||||
{
|
{
|
||||||
"state": "WALKFWD",
|
"state": "WALKFWD",
|
||||||
|
@ -4742,14 +4742,34 @@
|
||||||
{
|
{
|
||||||
"easingType": "easeInOutQuad",
|
"easingType": "easeInOutQuad",
|
||||||
"id": "idleSettle",
|
"id": "idleSettle",
|
||||||
"interpDuration": 12,
|
"interpDuration": 15,
|
||||||
"interpTarget": 12,
|
"interpTarget": 15,
|
||||||
"interpType": "evaluateBoth",
|
"interpType": "snapshotPrev",
|
||||||
"transitions": [
|
"transitions": [
|
||||||
{
|
{
|
||||||
"state": "idle",
|
"state": "idle",
|
||||||
"var": "idleSettleOnDone"
|
"var": "idleSettleOnDone"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"state": "idle",
|
||||||
|
"var": "reactionPositiveTrigger"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"state": "idle",
|
||||||
|
"var": "reactionNegativeTrigger"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"state": "idle",
|
||||||
|
"var": "reactionRaiseHandEnabled"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"state": "idle",
|
||||||
|
"var": "reactionApplaudEnabled"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"state": "idle",
|
||||||
|
"var": "reactionPointEnabled"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"state": "WALKFWD",
|
"state": "WALKFWD",
|
||||||
"var": "isMovingForward"
|
"var": "isMovingForward"
|
||||||
|
@ -4810,7 +4830,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "WALKFWD",
|
"id": "WALKFWD",
|
||||||
"interpDuration": 10,
|
"interpDuration": 15,
|
||||||
"interpTarget": 35,
|
"interpTarget": 35,
|
||||||
"interpType": "snapshotPrev",
|
"interpType": "snapshotPrev",
|
||||||
"transitions": [
|
"transitions": [
|
||||||
|
@ -4874,7 +4894,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "WALKBWD",
|
"id": "WALKBWD",
|
||||||
"interpDuration": 10,
|
"interpDuration": 15,
|
||||||
"interpTarget": 35,
|
"interpTarget": 35,
|
||||||
"interpType": "snapshotPrev",
|
"interpType": "snapshotPrev",
|
||||||
"transitions": [
|
"transitions": [
|
||||||
|
@ -4938,7 +4958,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "STRAFERIGHT",
|
"id": "STRAFERIGHT",
|
||||||
"interpDuration": 8,
|
"interpDuration": 15,
|
||||||
"interpTarget": 25,
|
"interpTarget": 25,
|
||||||
"interpType": "snapshotPrev",
|
"interpType": "snapshotPrev",
|
||||||
"transitions": [
|
"transitions": [
|
||||||
|
@ -5002,7 +5022,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "STRAFELEFT",
|
"id": "STRAFELEFT",
|
||||||
"interpDuration": 8,
|
"interpDuration": 15,
|
||||||
"interpTarget": 25,
|
"interpTarget": 25,
|
||||||
"interpType": "snapshotPrev",
|
"interpType": "snapshotPrev",
|
||||||
"transitions": [
|
"transitions": [
|
||||||
|
@ -5873,7 +5893,6 @@
|
||||||
},
|
},
|
||||||
"id": "userAnimStateMachine",
|
"id": "userAnimStateMachine",
|
||||||
"type": "stateMachine"
|
"type": "stateMachine"
|
||||||
|
|
||||||
},
|
},
|
||||||
"version": "1.1"
|
"version": "1.1"
|
||||||
}
|
}
|
||||||
|
|
|
@ -699,8 +699,8 @@ Item {
|
||||||
spacing: controlsTableRoot.rowPadding
|
spacing: controlsTableRoot.rowPadding
|
||||||
|
|
||||||
HifiStylesUit.GraphikRegular {
|
HifiStylesUit.GraphikRegular {
|
||||||
id: mirrorText
|
id: selfieText
|
||||||
text: "Mirror Mode"
|
text: "Selfie"
|
||||||
width: paintedWidth
|
width: paintedWidth
|
||||||
height: parent.height
|
height: parent.height
|
||||||
horizontalAlignment: Text.AlignLeft
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
@ -710,8 +710,8 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
HifiStylesUit.GraphikRegular {
|
HifiStylesUit.GraphikRegular {
|
||||||
text: "See your own avatar"
|
text: "Look at self"
|
||||||
width: parent.width - mirrorText.width - parent.spacing - controlsTableRoot.rowPadding
|
width: parent.width - selfieText.width - parent.spacing - controlsTableRoot.rowPadding
|
||||||
height: parent.height
|
height: parent.height
|
||||||
horizontalAlignment: Text.AlignLeft
|
horizontalAlignment: Text.AlignLeft
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
|
|
@ -234,9 +234,19 @@ Flickable {
|
||||||
SimplifiedControls.RadioButton {
|
SimplifiedControls.RadioButton {
|
||||||
id: thirdPerson
|
id: thirdPerson
|
||||||
text: "Third Person View"
|
text: "Third Person View"
|
||||||
checked: Camera.mode === "third person"
|
checked: Camera.mode === "look at"
|
||||||
onClicked: {
|
onClicked: {
|
||||||
Camera.mode = "third person"
|
Camera.mode = "look at"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SimplifiedControls.RadioButton {
|
||||||
|
id: selfie
|
||||||
|
text: "Selfie"
|
||||||
|
checked: Camera.mode === "selfie"
|
||||||
|
visible: true
|
||||||
|
onClicked: {
|
||||||
|
Camera.mode = "selfie"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,11 +256,21 @@ Flickable {
|
||||||
onModeUpdated: {
|
onModeUpdated: {
|
||||||
if (Camera.mode === "first person") {
|
if (Camera.mode === "first person") {
|
||||||
firstPerson.checked = true
|
firstPerson.checked = true
|
||||||
} else if (Camera.mode === "third person") {
|
} else if (Camera.mode === "look at") {
|
||||||
thirdPerson.checked = true
|
thirdPerson.checked = true
|
||||||
|
} else if (Camera.mode === "selfie" && HMD.active) {
|
||||||
|
selfie.checked = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: HMD
|
||||||
|
|
||||||
|
onDisplayModeChanged: {
|
||||||
|
selfie.visible = isHMDMode ? false : true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -856,9 +856,9 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) {
|
||||||
DependencyManager::set<VirtualPad::Manager>();
|
DependencyManager::set<VirtualPad::Manager>();
|
||||||
DependencyManager::set<DesktopPreviewProvider>();
|
DependencyManager::set<DesktopPreviewProvider>();
|
||||||
#if defined(Q_OS_ANDROID)
|
#if defined(Q_OS_ANDROID)
|
||||||
DependencyManager::set<AccountManager>(); // use the default user agent getter
|
DependencyManager::set<AccountManager>(true); // use the default user agent getter
|
||||||
#else
|
#else
|
||||||
DependencyManager::set<AccountManager>(std::bind(&Application::getUserAgent, qApp));
|
DependencyManager::set<AccountManager>(true, std::bind(&Application::getUserAgent, qApp));
|
||||||
#endif
|
#endif
|
||||||
DependencyManager::set<StatTracker>();
|
DependencyManager::set<StatTracker>();
|
||||||
DependencyManager::set<ScriptEngines>(ScriptEngine::CLIENT_SCRIPT, defaultScriptsOverrideOption);
|
DependencyManager::set<ScriptEngines>(ScriptEngine::CLIENT_SCRIPT, defaultScriptsOverrideOption);
|
||||||
|
|
|
@ -4144,6 +4144,7 @@ void MyAvatar::goToLocation(const glm::vec3& newPosition,
|
||||||
_goToOrientation = quatOrientation;
|
_goToOrientation = quatOrientation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resetLookAtRotation(_goToPosition, _goToOrientation);
|
||||||
emit transformChanged();
|
emit transformChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5996,6 +5997,7 @@ bool MyAvatar::pinJoint(int index, const glm::vec3& position, const glm::quat& o
|
||||||
}
|
}
|
||||||
|
|
||||||
slamPosition(position);
|
slamPosition(position);
|
||||||
|
resetLookAtRotation(position, orientation);
|
||||||
setWorldOrientation(orientation);
|
setWorldOrientation(orientation);
|
||||||
|
|
||||||
auto it = std::find(_pinnedJoints.begin(), _pinnedJoints.end(), index);
|
auto it = std::find(_pinnedJoints.begin(), _pinnedJoints.end(), index);
|
||||||
|
@ -6662,6 +6664,15 @@ void MyAvatar::resetHeadLookAt() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MyAvatar::resetLookAtRotation(const glm::vec3& avatarPosition, const glm::quat& avatarOrientation) {
|
||||||
|
// Align the look at values to the given avatar orientation
|
||||||
|
float yaw = safeEulerAngles(avatarOrientation).y;
|
||||||
|
_lookAtYaw = glm::angleAxis(yaw, avatarOrientation * Vectors::UP);
|
||||||
|
_lookAtPitch = Quaternions::IDENTITY;
|
||||||
|
_lookAtCameraTarget = avatarPosition + avatarOrientation * Vectors::FRONT;
|
||||||
|
resetHeadLookAt();
|
||||||
|
}
|
||||||
|
|
||||||
void MyAvatar::updateHeadLookAt(float deltaTime) {
|
void MyAvatar::updateHeadLookAt(float deltaTime) {
|
||||||
if (_skeletonModelLoaded) {
|
if (_skeletonModelLoaded) {
|
||||||
glm::vec3 lookAtTarget = _scriptControlsHeadLookAt ? _lookAtScriptTarget : _lookAtCameraTarget;
|
glm::vec3 lookAtTarget = _scriptControlsHeadLookAt ? _lookAtScriptTarget : _lookAtCameraTarget;
|
||||||
|
|
|
@ -2654,11 +2654,6 @@ private:
|
||||||
bool _scriptControlsHeadLookAt { false };
|
bool _scriptControlsHeadLookAt { false };
|
||||||
float _scriptHeadControlTimer { 0.0f };
|
float _scriptHeadControlTimer { 0.0f };
|
||||||
|
|
||||||
// LookAt camera data
|
|
||||||
float _selfieTriggerAngle { 55.0f };
|
|
||||||
float _frontLookAtSpeed { 0.15f };
|
|
||||||
float _backLookAtSpeed { 0.25f };
|
|
||||||
|
|
||||||
Setting::Handle<float> _realWorldFieldOfView;
|
Setting::Handle<float> _realWorldFieldOfView;
|
||||||
Setting::Handle<bool> _useAdvancedMovementControls;
|
Setting::Handle<bool> _useAdvancedMovementControls;
|
||||||
Setting::Handle<bool> _showPlayArea;
|
Setting::Handle<bool> _showPlayArea;
|
||||||
|
@ -2685,6 +2680,7 @@ private:
|
||||||
void initFlowFromFST();
|
void initFlowFromFST();
|
||||||
void updateHeadLookAt(float deltaTime);
|
void updateHeadLookAt(float deltaTime);
|
||||||
void resetHeadLookAt();
|
void resetHeadLookAt();
|
||||||
|
void resetLookAtRotation(const glm::vec3& avatarPosition, const glm::quat& avatarOrientation);
|
||||||
|
|
||||||
// Avatar Preferences
|
// Avatar Preferences
|
||||||
QUrl _fullAvatarURLFromPreferences;
|
QUrl _fullAvatarURLFromPreferences;
|
||||||
|
|
|
@ -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);
|
||||||
});
|
});
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -64,6 +66,8 @@ static QString getTargetDevice(bool hmd, QAudio::Mode mode) {
|
||||||
} else { // if (_mode == QAudio::AudioOutput)
|
} else { // if (_mode == QAudio::AudioOutput)
|
||||||
deviceName = qApp->getActiveDisplayPlugin()->getPreferredAudioOutDevice();
|
deviceName = qApp->getActiveDisplayPlugin()->getPreferredAudioOutDevice();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
deviceName = HifiAudioDeviceInfo::DEFAULT_DEVICE_NAME;
|
||||||
}
|
}
|
||||||
return deviceName;
|
return deviceName;
|
||||||
}
|
}
|
||||||
|
@ -139,7 +143,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,18 +195,13 @@ 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) {
|
||||||
std::shared_ptr<AudioDevice> device = _devices[i];
|
std::shared_ptr<AudioDevice> device = _devices[i];
|
||||||
bool& isSelected = isHMD ? device->selectedHMD : device->selectedDesktop;
|
bool& isSelected = isHMD ? device->selectedHMD : device->selectedDesktop;
|
||||||
if (isSelected && device->info != selectedDevice) {
|
isSelected = device->info == selectedDevice;
|
||||||
isSelected = false;
|
|
||||||
} else if (device->info == selectedDevice) {
|
|
||||||
isSelected = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
emit deviceChanged(selectedDevice);
|
emit deviceChanged(selectedDevice);
|
||||||
|
@ -259,37 +258,46 @@ 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()
|
|
||||||
.replace("High Definition", "HD")
|
if (deviceInfo.isDefault()) {
|
||||||
.remove("Device")
|
if (deviceInfo.getMode() == QAudio::AudioInput) {
|
||||||
.replace(" )", ")");
|
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}) {
|
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 +333,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 +390,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 +405,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.deviceName();
|
||||||
|
|
||||||
auto& setting = getSetting(isHMD, mode);
|
auto& setting = getSetting(isHMD, mode);
|
||||||
|
|
||||||
|
@ -410,7 +418,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 +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 (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 +456,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 +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
|
//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 HifiAudioDeviceInfo&, device));
|
||||||
} 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 +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
|
//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 HifiAudioDeviceInfo&, device));
|
||||||
} 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,
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -50,9 +50,6 @@ ContextOverlayInterface::ContextOverlayInterface() {
|
||||||
_entityPropertyFlags += PROP_OWNING_AVATAR_ID;
|
_entityPropertyFlags += PROP_OWNING_AVATAR_ID;
|
||||||
|
|
||||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>().data();
|
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>().data();
|
||||||
/* REMOVING THIS AS AN EMERGENCY FIX. We will be returning to modify the code so that MP inspection is not intrusive in domains with a lot of certified content.
|
|
||||||
Jira bug to remove inspection temporarily: https://highfidelity.atlassian.net/browse/DEV-639
|
|
||||||
Jira bug to modify it and bring it back: https://highfidelity.atlassian.net/browse/DEV-645
|
|
||||||
connect(entityScriptingInterface, &EntityScriptingInterface::mousePressOnEntity, this, &ContextOverlayInterface::clickDownOnEntity);
|
connect(entityScriptingInterface, &EntityScriptingInterface::mousePressOnEntity, this, &ContextOverlayInterface::clickDownOnEntity);
|
||||||
connect(entityScriptingInterface, &EntityScriptingInterface::mouseReleaseOnEntity, this, &ContextOverlayInterface::mouseReleaseOnEntity);
|
connect(entityScriptingInterface, &EntityScriptingInterface::mouseReleaseOnEntity, this, &ContextOverlayInterface::mouseReleaseOnEntity);
|
||||||
connect(entityScriptingInterface, &EntityScriptingInterface::hoverEnterEntity, this, &ContextOverlayInterface::contextOverlays_hoverEnterEntity);
|
connect(entityScriptingInterface, &EntityScriptingInterface::hoverEnterEntity, this, &ContextOverlayInterface::contextOverlays_hoverEnterEntity);
|
||||||
|
@ -60,7 +57,6 @@ ContextOverlayInterface::ContextOverlayInterface() {
|
||||||
|
|
||||||
connect(&qApp->getOverlays(), &Overlays::hoverEnterOverlay, this, &ContextOverlayInterface::contextOverlays_hoverEnterOverlay);
|
connect(&qApp->getOverlays(), &Overlays::hoverEnterOverlay, this, &ContextOverlayInterface::contextOverlays_hoverEnterOverlay);
|
||||||
connect(&qApp->getOverlays(), &Overlays::hoverLeaveOverlay, this, &ContextOverlayInterface::contextOverlays_hoverLeaveOverlay);
|
connect(&qApp->getOverlays(), &Overlays::hoverLeaveOverlay, this, &ContextOverlayInterface::contextOverlays_hoverLeaveOverlay);
|
||||||
*/
|
|
||||||
|
|
||||||
connect(_tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system"), &TabletProxy::tabletShownChanged, this, [&]() {
|
connect(_tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system"), &TabletProxy::tabletShownChanged, this, [&]() {
|
||||||
if (_contextOverlayJustClicked && _hmdScriptingInterface->isMounted()) {
|
if (_contextOverlayJustClicked && _hmdScriptingInterface->isMounted()) {
|
||||||
|
|
|
@ -91,11 +91,23 @@ using Lock = std::unique_lock<Mutex>;
|
||||||
Mutex _deviceMutex;
|
Mutex _deviceMutex;
|
||||||
Mutex _recordMutex;
|
Mutex _recordMutex;
|
||||||
|
|
||||||
|
HifiAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode);
|
||||||
|
|
||||||
// thread-safe
|
// thread-safe
|
||||||
QList<QAudioDeviceInfo> getAvailableDevices(QAudio::Mode mode) {
|
QList<HifiAudioDeviceInfo> getAvailableDevices(QAudio::Mode mode) {
|
||||||
// NOTE: availableDevices() clobbers the Qt internal device list
|
// NOTE: availableDevices() clobbers the Qt internal device list
|
||||||
Lock lock(_deviceMutex);
|
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
|
// 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 inputDevices = getAvailableDevices(QAudio::AudioInput);
|
||||||
auto outputDevices = getAvailableDevices(QAudio::AudioOutput);
|
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);
|
Lock lock(_deviceMutex);
|
||||||
if (inputDevices != _inputDevices) {
|
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);
|
Lock lock(_deviceMutex);
|
||||||
|
|
||||||
if (mode == QAudio::AudioInput) {
|
if (mode == QAudio::AudioInput) {
|
||||||
return _inputDeviceInfo;
|
return _inputDeviceInfo;
|
||||||
} else { // if (mode == QAudio::AudioOutput)
|
} else {
|
||||||
return _outputDeviceInfo;
|
return _outputDeviceInfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QAudioDeviceInfo> AudioClient::getAudioDevices(QAudio::Mode mode) const {
|
QList<HifiAudioDeviceInfo> AudioClient::getAudioDevices(QAudio::Mode mode) const {
|
||||||
Lock lock(_deviceMutex);
|
Lock lock(_deviceMutex);
|
||||||
|
|
||||||
if (mode == QAudio::AudioInput) {
|
if (mode == QAudio::AudioInput) {
|
||||||
return _inputDevices;
|
return _inputDevices;
|
||||||
} else { // if (mode == QAudio::AudioOutput)
|
} else {
|
||||||
return _outputDevices;
|
return _outputDevices;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,7 +241,7 @@ static float computeLoudness(int16_t* samples, int numSamples) {
|
||||||
|
|
||||||
template <int NUM_CHANNELS>
|
template <int NUM_CHANNELS>
|
||||||
static void applyGainSmoothing(float* buffer, int numFrames, float gain0, float gain1) {
|
static void applyGainSmoothing(float* buffer, int numFrames, float gain0, float gain1) {
|
||||||
|
|
||||||
// fast path for unity gain
|
// fast path for unity gain
|
||||||
if (gain0 == 1.0f && gain1 == 1.0f) {
|
if (gain0 == 1.0f && gain1 == 1.0f) {
|
||||||
return;
|
return;
|
||||||
|
@ -241,7 +256,7 @@ static void applyGainSmoothing(float* buffer, int numFrames, float gain0, float
|
||||||
float tStep = 1.0f / numFrames;
|
float tStep = 1.0f / numFrames;
|
||||||
|
|
||||||
for (int i = 0; i < numFrames; i++) {
|
for (int i = 0; i < numFrames; i++) {
|
||||||
|
|
||||||
// evaluate poly over t=[0,1)
|
// evaluate poly over t=[0,1)
|
||||||
float gain = (c3 * t + c2) * t * t + c0;
|
float gain = (c3 * t + c2) * t * t + c0;
|
||||||
t += tStep;
|
t += tStep;
|
||||||
|
@ -321,9 +336,9 @@ AudioClient::AudioClient() :
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(&_receivedAudioStream, &MixedProcessedAudioStream::processSamples,
|
connect(&_receivedAudioStream, &MixedProcessedAudioStream::processSamples,
|
||||||
this, &AudioClient::processReceivedSamples, Qt::DirectConnection);
|
this, &AudioClient::processReceivedSamples, Qt::DirectConnection);
|
||||||
connect(this, &AudioClient::changeDevice, this, [=](const QAudioDeviceInfo& outputDeviceInfo) {
|
connect(this, &AudioClient::changeDevice, this, [=](const HifiAudioDeviceInfo& outputDeviceInfo) {
|
||||||
qCDebug(audioclient) << "got AudioClient::changeDevice signal, about to call switchOutputToAudioDevice() outputDeviceInfo: [" << outputDeviceInfo.deviceName() << "]";
|
qCDebug(audioclient)<< "got AudioClient::changeDevice signal, about to call switchOutputToAudioDevice() outputDeviceInfo: ["<< outputDeviceInfo.deviceName() << "]";
|
||||||
switchOutputToAudioDevice(outputDeviceInfo);
|
switchOutputToAudioDevice(outputDeviceInfo);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -373,7 +388,7 @@ AudioClient::AudioClient() :
|
||||||
packetReceiver.registerListener(PacketType::SelectedAudioFormat, this, "handleSelectedAudioFormat");
|
packetReceiver.registerListener(PacketType::SelectedAudioFormat, this, "handleSelectedAudioFormat");
|
||||||
|
|
||||||
auto& domainHandler = nodeList->getDomainHandler();
|
auto& domainHandler = nodeList->getDomainHandler();
|
||||||
connect(&domainHandler, &DomainHandler::disconnectedFromDomain, this, [this] {
|
connect(&domainHandler, &DomainHandler::disconnectedFromDomain, this, [this] {
|
||||||
_solo.reset();
|
_solo.reset();
|
||||||
});
|
});
|
||||||
connect(nodeList.data(), &NodeList::nodeActivated, this, [this](SharedNodePointer node) {
|
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) {
|
HifiAudioDeviceInfo getNamedAudioDeviceForMode(QAudio::Mode mode, const QString& deviceName) {
|
||||||
QAudioDeviceInfo result;
|
HifiAudioDeviceInfo result;
|
||||||
foreach(QAudioDeviceInfo audioDevice, getAvailableDevices(mode)) {
|
foreach (HifiAudioDeviceInfo audioDevice, getAvailableDevices(mode)) {
|
||||||
if (audioDevice.deviceName().trimmed() == deviceName.trimmed()) {
|
if (audioDevice.deviceName().trimmed() == deviceName.trimmed()) {
|
||||||
result = audioDevice;
|
result = audioDevice;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -487,9 +501,11 @@ QString AudioClient::getWinDeviceName(wchar_t* guid) {
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) {
|
HifiAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) {
|
||||||
|
QList<QAudioDeviceInfo> devices = QAudioDeviceInfo::availableDevices(mode);
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
if (getAvailableDevices(mode).size() > 1) {
|
if (devices.size() > 1) {
|
||||||
AudioDeviceID defaultDeviceID = 0;
|
AudioDeviceID defaultDeviceID = 0;
|
||||||
uint32_t propertySize = sizeof(AudioDeviceID);
|
uint32_t propertySize = sizeof(AudioDeviceID);
|
||||||
AudioObjectPropertyAddress propertyAddress = {
|
AudioObjectPropertyAddress propertyAddress = {
|
||||||
|
@ -519,9 +535,9 @@ QAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) {
|
||||||
|
|
||||||
if (!getPropertyError && propertySize) {
|
if (!getPropertyError && propertySize) {
|
||||||
// find a device in the list that matches the name we have and return it
|
// 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)) {
|
if (audioDevice.deviceName() == CFStringGetCStringPtr(deviceName, kCFStringEncodingMacRoman)) {
|
||||||
return audioDevice;
|
return HifiAudioDeviceInfo(audioDevice, true, mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -569,10 +585,18 @@ QAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) {
|
||||||
CoUninitialize();
|
CoUninitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
qCDebug(audioclient) << "defaultAudioDeviceForMode mode: " << (mode == QAudio::AudioOutput ? "Output" : "Input")
|
HifiAudioDeviceInfo foundDevice;
|
||||||
<< " [" << deviceName << "] [" << getNamedAudioDeviceForMode(mode, deviceName).deviceName() << "]";
|
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
|
#endif
|
||||||
|
|
||||||
#if defined (Q_OS_ANDROID)
|
#if defined (Q_OS_ANDROID)
|
||||||
|
@ -580,18 +604,18 @@ QAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) {
|
||||||
Setting::Handle<bool> enableAEC(SETTING_AEC_KEY, DEFAULT_AEC_ENABLED);
|
Setting::Handle<bool> enableAEC(SETTING_AEC_KEY, DEFAULT_AEC_ENABLED);
|
||||||
bool aecEnabled = enableAEC.get();
|
bool aecEnabled = enableAEC.get();
|
||||||
auto audioClient = DependencyManager::get<AudioClient>();
|
auto audioClient = DependencyManager::get<AudioClient>();
|
||||||
bool headsetOn = audioClient? audioClient->isHeadsetPluggedIn() : false;
|
bool headsetOn = audioClient ? audioClient->isHeadsetPluggedIn() : false;
|
||||||
auto inputDevices = QAudioDeviceInfo::availableDevices(QAudio::AudioInput);
|
for (QAudioDeviceInfo inputDevice : devices) {
|
||||||
for (auto inputDevice : inputDevices) {
|
|
||||||
if (((headsetOn || !aecEnabled) && inputDevice.deviceName() == VOICE_RECOGNITION) ||
|
if (((headsetOn || !aecEnabled) && inputDevice.deviceName() == VOICE_RECOGNITION) ||
|
||||||
((!headsetOn && aecEnabled) && inputDevice.deviceName() == VOICE_COMMUNICATION)) {
|
((!headsetOn && aecEnabled) && inputDevice.deviceName() == VOICE_COMMUNICATION)) {
|
||||||
return inputDevice;
|
return HifiAudioDeviceInfo(inputDevice, false, QAudio::AudioInput);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// fallback for failed lookup is the default device
|
// 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) {
|
bool AudioClient::getNamedAudioDeviceForModeExists(QAudio::Mode mode, const QString& deviceName) {
|
||||||
|
@ -643,29 +667,29 @@ bool adjustedFormatForAudioDevice(const QAudioDeviceInfo& audioDevice,
|
||||||
if (IsWindows8OrGreater()) {
|
if (IsWindows8OrGreater()) {
|
||||||
// On Windows using WASAPI shared-mode, returns the internal mix format
|
// On Windows using WASAPI shared-mode, returns the internal mix format
|
||||||
return nativeFormatForAudioDevice(audioDevice, adjustedAudioFormat);
|
return nativeFormatForAudioDevice(audioDevice, adjustedAudioFormat);
|
||||||
} // else enumerate formats
|
} // else enumerate formats
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(Q_OS_MAC)
|
#if defined(Q_OS_MAC)
|
||||||
// Mac OSX returns the preferred CoreAudio format
|
// Mac OSX returns the preferred CoreAudio format
|
||||||
return nativeFormatForAudioDevice(audioDevice, adjustedAudioFormat);
|
return nativeFormatForAudioDevice(audioDevice, adjustedAudioFormat);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(Q_OS_ANDROID)
|
#if defined(Q_OS_ANDROID)
|
||||||
// As of Qt5.6, Android returns the native OpenSLES sample rate when possible, else 48000
|
// As of Qt5.6, Android returns the native OpenSLES sample rate when possible, else 48000
|
||||||
if (nativeFormatForAudioDevice(audioDevice, adjustedAudioFormat)) {
|
if (nativeFormatForAudioDevice(audioDevice, adjustedAudioFormat)) {
|
||||||
return true;
|
return true;
|
||||||
} // else enumerate formats
|
} // else enumerate formats
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
adjustedAudioFormat = desiredAudioFormat;
|
adjustedAudioFormat = desiredAudioFormat;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Attempt the device sample rate and channel count in decreasing order of preference.
|
// 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 sampleRates[] = { 48000, 44100, 32000, 24000, 16000, 96000, 192000, 88200, 176400 };
|
||||||
const int inputChannels[] = { 1, 2, 4, 6, 8 }; // prefer mono
|
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 outputChannels[] = { 2, 4, 6, 8, 1 }; // prefer stereo, downmix as last resort
|
||||||
|
|
||||||
for (int channelCount : (desiredAudioFormat.channelCount() == 1 ? inputChannels : outputChannels)) {
|
for (int channelCount : (desiredAudioFormat.channelCount() == 1 ? inputChannels : outputChannels)) {
|
||||||
for (int sampleRate : sampleRates) {
|
for (int sampleRate : sampleRates) {
|
||||||
|
@ -758,22 +782,22 @@ void AudioClient::start() {
|
||||||
_desiredOutputFormat = _desiredInputFormat;
|
_desiredOutputFormat = _desiredInputFormat;
|
||||||
_desiredOutputFormat.setChannelCount(OUTPUT_CHANNEL_COUNT);
|
_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();
|
qCDebug(audioclient) << "The default audio input device is" << inputDeviceInfo.deviceName();
|
||||||
bool inputFormatSupported = switchInputToAudioDevice(inputDeviceInfo);
|
bool inputFormatSupported = switchInputToAudioDevice(inputDeviceInfo);
|
||||||
|
|
||||||
QAudioDeviceInfo outputDeviceInfo = defaultAudioDeviceForMode(QAudio::AudioOutput);
|
HifiAudioDeviceInfo outputDeviceInfo = defaultAudioDeviceForMode(QAudio::AudioOutput);
|
||||||
qCDebug(audioclient) << "The default audio output device is" << outputDeviceInfo.deviceName();
|
qCDebug(audioclient) << "The default audio output device is" << outputDeviceInfo.deviceName();
|
||||||
bool outputFormatSupported = switchOutputToAudioDevice(outputDeviceInfo);
|
bool outputFormatSupported = switchOutputToAudioDevice(outputDeviceInfo);
|
||||||
|
|
||||||
if (!inputFormatSupported) {
|
if (!inputFormatSupported) {
|
||||||
qCDebug(audioclient) << "Unable to set up audio input because of a problem with input format.";
|
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) {
|
if (!outputFormatSupported) {
|
||||||
qCDebug(audioclient) << "Unable to set up audio output because of a problem with output format.";
|
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)
|
#if defined(Q_OS_ANDROID)
|
||||||
connect(&_checkInputTimer, &QTimer::timeout, this, &AudioClient::checkInputTimeout);
|
connect(&_checkInputTimer, &QTimer::timeout, this, &AudioClient::checkInputTimeout);
|
||||||
|
@ -783,10 +807,10 @@ void AudioClient::start() {
|
||||||
|
|
||||||
void AudioClient::stop() {
|
void AudioClient::stop() {
|
||||||
qCDebug(audioclient) << "AudioClient::stop(), requesting switchInputToAudioDevice() to shut down";
|
qCDebug(audioclient) << "AudioClient::stop(), requesting switchInputToAudioDevice() to shut down";
|
||||||
switchInputToAudioDevice(QAudioDeviceInfo(), true);
|
switchInputToAudioDevice(HifiAudioDeviceInfo(), true);
|
||||||
|
|
||||||
qCDebug(audioclient) << "AudioClient::stop(), requesting switchOutputToAudioDevice() to shut down";
|
qCDebug(audioclient) << "AudioClient::stop(), requesting switchOutputToAudioDevice() to shut down";
|
||||||
switchOutputToAudioDevice(QAudioDeviceInfo(), true);
|
switchOutputToAudioDevice(HifiAudioDeviceInfo(), true);
|
||||||
|
|
||||||
// Stop triggering the checks
|
// Stop triggering the checks
|
||||||
QObject::disconnect(_checkPeakValuesTimer, &QTimer::timeout, nullptr, nullptr);
|
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) {
|
void AudioClient::changeDefault(HifiAudioDeviceInfo newDefault, QAudio::Mode mode) {
|
||||||
auto device = deviceInfo;
|
HifiAudioDeviceInfo currentDevice = mode == QAudio::AudioInput ? _inputDeviceInfo : _outputDeviceInfo;
|
||||||
|
if (currentDevice.isDefault() && currentDevice.getDevice() != newDefault.getDevice()) {
|
||||||
if (device.isNull()) {
|
switchAudioDevice(mode, newDefault);
|
||||||
device = defaultAudioDeviceForMode(mode);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AudioClient::switchAudioDevice(QAudio::Mode mode, const HifiAudioDeviceInfo& deviceInfo) {
|
||||||
|
auto device = deviceInfo;
|
||||||
if (mode == QAudio::AudioInput) {
|
if (mode == QAudio::AudioInput) {
|
||||||
return switchInputToAudioDevice(device);
|
return switchInputToAudioDevice(device);
|
||||||
} else { // if (mode == QAudio::AudioOutput)
|
} else {
|
||||||
return switchOutputToAudioDevice(device);
|
return switchOutputToAudioDevice(device);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1030,7 +1056,7 @@ void AudioClient::configureReverb() {
|
||||||
p.wetDryMix = 100.0f;
|
p.wetDryMix = 100.0f;
|
||||||
p.preDelay = 0.0f;
|
p.preDelay = 0.0f;
|
||||||
p.earlyGain = -96.0f; // disable ER
|
p.earlyGain = -96.0f; // disable ER
|
||||||
p.lateGain += _reverbOptions->getWetDryMix() * (24.0f/100.0f) - 24.0f; // -0dB to -24dB, based on wetDryMix
|
p.lateGain += _reverbOptions->getWetDryMix() * (24.0f / 100.0f) - 24.0f; // -0dB to -24dB, based on wetDryMix
|
||||||
p.lateMixLeft = 0.0f;
|
p.lateMixLeft = 0.0f;
|
||||||
p.lateMixRight = 0.0f;
|
p.lateMixRight = 0.0f;
|
||||||
|
|
||||||
|
@ -1414,7 +1440,7 @@ void AudioClient::handleMicAudioInput() {
|
||||||
} else if (_timeSinceLastClip >= 0.0f) {
|
} else if (_timeSinceLastClip >= 0.0f) {
|
||||||
_timeSinceLastClip += AudioConstants::NETWORK_FRAME_SECS;
|
_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 defined(WEBRTC_ENABLED)
|
||||||
if (_isAECEnabled) {
|
if (_isAECEnabled) {
|
||||||
|
@ -1453,7 +1479,7 @@ void AudioClient::handleDummyAudioInput() {
|
||||||
? AudioConstants::NETWORK_FRAME_BYTES_STEREO
|
? AudioConstants::NETWORK_FRAME_BYTES_STEREO
|
||||||
: AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL;
|
: AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL;
|
||||||
|
|
||||||
QByteArray audioBuffer(numNetworkBytes, 0); // silent
|
QByteArray audioBuffer(numNetworkBytes, 0); // silent
|
||||||
handleAudioInput(audioBuffer);
|
handleAudioInput(audioBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1598,7 +1624,7 @@ bool AudioClient::mixLocalAudioInjectors(float* mixBuffer) {
|
||||||
// direct mix into mixBuffer
|
// direct mix into mixBuffer
|
||||||
injector->getLocalHRTF().mixStereo(_localScratchBuffer, mixBuffer, gain,
|
injector->getLocalHRTF().mixStereo(_localScratchBuffer, mixBuffer, gain,
|
||||||
AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL);
|
AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL);
|
||||||
} else { // injector is mono
|
} else { // injector is mono
|
||||||
|
|
||||||
if (options.positionSet) {
|
if (options.positionSet) {
|
||||||
|
|
||||||
|
@ -1736,7 +1762,7 @@ void AudioClient::setAcousticEchoCancellation(bool enable, bool emitSignal) {
|
||||||
|
|
||||||
bool AudioClient::setIsStereoInput(bool isStereoInput) {
|
bool AudioClient::setIsStereoInput(bool isStereoInput) {
|
||||||
bool stereoInputChanged = false;
|
bool stereoInputChanged = false;
|
||||||
if (isStereoInput != _isStereoInput && _inputDeviceInfo.supportedChannelCounts().contains(2)) {
|
if (isStereoInput != _isStereoInput && _inputDeviceInfo.getDevice().supportedChannelCounts().contains(2)) {
|
||||||
_isStereoInput = isStereoInput;
|
_isStereoInput = isStereoInput;
|
||||||
stereoInputChanged = true;
|
stereoInputChanged = true;
|
||||||
|
|
||||||
|
@ -1798,17 +1824,17 @@ void AudioClient::outputFormatChanged() {
|
||||||
_receivedAudioStream.outputFormatChanged(_outputFormat.sampleRate(), OUTPUT_CHANNEL_COUNT);
|
_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");
|
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;
|
bool supportedFormat = false;
|
||||||
|
|
||||||
// NOTE: device start() uses the Qt internal device list
|
// NOTE: device start() uses the Qt internal device list
|
||||||
Lock lock(_deviceMutex);
|
Lock lock(_deviceMutex);
|
||||||
|
|
||||||
#if defined(Q_OS_ANDROID)
|
#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
|
#endif
|
||||||
|
|
||||||
// cleanup any previously initialized device
|
// cleanup any previously initialized device
|
||||||
|
@ -1822,8 +1848,6 @@ bool AudioClient::switchInputToAudioDevice(const QAudioDeviceInfo inputDeviceInf
|
||||||
_audioInput->deleteLater();
|
_audioInput->deleteLater();
|
||||||
_audioInput = NULL;
|
_audioInput = NULL;
|
||||||
_numInputCallbackBytes = 0;
|
_numInputCallbackBytes = 0;
|
||||||
|
|
||||||
_inputDeviceInfo = QAudioDeviceInfo();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_dummyAudioInput) {
|
if (_dummyAudioInput) {
|
||||||
|
@ -1854,12 +1878,16 @@ bool AudioClient::switchInputToAudioDevice(const QAudioDeviceInfo inputDeviceInf
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!inputDeviceInfo.isNull()) {
|
if (!inputDeviceInfo.getDevice().isNull()) {
|
||||||
qCDebug(audioclient) << "The audio input device " << inputDeviceInfo.deviceName() << "is available.";
|
qCDebug(audioclient) << "The audio input device " << inputDeviceInfo.deviceName() << "is available.";
|
||||||
|
|
||||||
|
bool doEmit = _inputDeviceInfo.deviceName() != inputDeviceInfo.deviceName();
|
||||||
_inputDeviceInfo = inputDeviceInfo;
|
_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;
|
qCDebug(audioclient) << "The format to be used for audio input is" << _inputFormat;
|
||||||
|
|
||||||
// we've got the best we can get for input
|
// 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 the user wants stereo but this device can't provide then bail
|
||||||
if (!_isStereoInput || _inputFormat.channelCount() == 2) {
|
if (!_isStereoInput || _inputFormat.channelCount() == 2) {
|
||||||
_audioInput = new QAudioInput(inputDeviceInfo, _inputFormat, this);
|
_audioInput = new QAudioInput(_inputDeviceInfo.getDevice(), _inputFormat, this);
|
||||||
_numInputCallbackBytes = calculateNumberOfInputCallbackBytes(_inputFormat);
|
_numInputCallbackBytes = calculateNumberOfInputCallbackBytes(_inputFormat);
|
||||||
_audioInput->setBufferSize(_numInputCallbackBytes);
|
_audioInput->setBufferSize(_numInputCallbackBytes);
|
||||||
// different audio input devices may have different volumes
|
// 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()));
|
connect(_inputDevice, SIGNAL(readyRead()), this, SLOT(handleMicAudioInput()));
|
||||||
supportedFormat = true;
|
supportedFormat = true;
|
||||||
} else {
|
} else {
|
||||||
qCDebug(audioclient) << "Error starting audio input -" << _audioInput->error();
|
qCDebug(audioclient) << "Error starting audio input -" << _audioInput->error();
|
||||||
_audioInput->deleteLater();
|
_audioInput->deleteLater();
|
||||||
_audioInput = NULL;
|
_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.
|
// This enables clients without a mic to still receive an audio stream from the mixer.
|
||||||
if (!_audioInput) {
|
if (!_audioInput) {
|
||||||
qCDebug(audioclient) << "Audio input device is not available, using dummy input.";
|
qCDebug(audioclient) << "Audio input device is not available, using dummy input.";
|
||||||
_inputDeviceInfo = QAudioDeviceInfo();
|
_inputDeviceInfo.setDevice(QAudioDeviceInfo());
|
||||||
emit deviceChanged(QAudio::AudioInput, _inputDeviceInfo);
|
emit deviceChanged(QAudio::AudioInput, _inputDeviceInfo);
|
||||||
|
|
||||||
_inputFormat = _desiredInputFormat;
|
_inputFormat = _desiredInputFormat;
|
||||||
|
@ -1975,11 +2003,11 @@ void AudioClient::checkInputTimeout() {
|
||||||
|
|
||||||
void AudioClient::setHeadsetPluggedIn(bool pluggedIn) {
|
void AudioClient::setHeadsetPluggedIn(bool pluggedIn) {
|
||||||
#if defined(Q_OS_ANDROID)
|
#if defined(Q_OS_ANDROID)
|
||||||
if (pluggedIn == !_isHeadsetPluggedIn && !_inputDeviceInfo.isNull()) {
|
if (pluggedIn == !_isHeadsetPluggedIn && !_inputDeviceInfo.getDevice().isNull()) {
|
||||||
QAndroidJniObject brand = QAndroidJniObject::getStaticObjectField<jstring>("android/os/Build", "BRAND");
|
QAndroidJniObject brand = QAndroidJniObject::getStaticObjectField<jstring>("android/os/Build", "BRAND");
|
||||||
// some samsung phones needs more time to shutdown the previous input device
|
// some samsung phones needs more time to shutdown the previous input device
|
||||||
if (brand.toString().contains("samsung", Qt::CaseInsensitive)) {
|
if (brand.toString().contains("samsung", Qt::CaseInsensitive)) {
|
||||||
switchInputToAudioDevice(QAudioDeviceInfo(), true);
|
switchInputToAudioDevice(HifiAudioDeviceInfo(), true);
|
||||||
QThread::msleep(200);
|
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");
|
Q_ASSERT_X(QThread::currentThread() == thread(), Q_FUNC_INFO, "Function invoked on wrong thread");
|
||||||
|
|
||||||
qCDebug(audioclient) << "AudioClient::switchOutputToAudioDevice() outputDeviceInfo: [" << outputDeviceInfo.deviceName() << "]";
|
qCDebug(audioclient) << "AudioClient::switchOutputToAudioDevice() outputDeviceInfo: [" << outputDeviceInfo.deviceName() << "]";
|
||||||
|
@ -2061,8 +2089,6 @@ bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo outputDeviceI
|
||||||
|
|
||||||
delete[] _localOutputMixBuffer;
|
delete[] _localOutputMixBuffer;
|
||||||
_localOutputMixBuffer = NULL;
|
_localOutputMixBuffer = NULL;
|
||||||
|
|
||||||
_outputDeviceInfo = QAudioDeviceInfo();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// cleanup any resamplers
|
// cleanup any resamplers
|
||||||
|
@ -2086,12 +2112,15 @@ bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo outputDeviceI
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!outputDeviceInfo.isNull()) {
|
if (!outputDeviceInfo.getDevice().isNull()) {
|
||||||
qCDebug(audioclient) << "The audio output device " << outputDeviceInfo.deviceName() << "is available.";
|
qCDebug(audioclient) << "The audio output device " << outputDeviceInfo.deviceName() << "is available.";
|
||||||
|
bool doEmit = _outputDeviceInfo.deviceName() != outputDeviceInfo.deviceName();
|
||||||
_outputDeviceInfo = outputDeviceInfo;
|
_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;
|
qCDebug(audioclient) << "The format to be used for audio output is" << _outputFormat;
|
||||||
|
|
||||||
// we've got the best we can get for input
|
// we've got the best we can get for input
|
||||||
|
@ -2113,7 +2142,7 @@ bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo outputDeviceI
|
||||||
outputFormatChanged();
|
outputFormatChanged();
|
||||||
|
|
||||||
// setup our general output device for audio-mixer audio
|
// 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 deviceChannelCount = _outputFormat.channelCount();
|
||||||
int frameSize = (AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * deviceChannelCount * _outputFormat.sampleRate()) / _desiredOutputFormat.sampleRate();
|
int frameSize = (AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * deviceChannelCount * _outputFormat.sampleRate()) / _desiredOutputFormat.sampleRate();
|
||||||
|
@ -2165,7 +2194,7 @@ bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo outputDeviceI
|
||||||
localAudioLock.unlock();
|
localAudioLock.unlock();
|
||||||
|
|
||||||
// setup a loopback audio output device
|
// setup a loopback audio output device
|
||||||
_loopbackAudioOutput = new QAudioOutput(outputDeviceInfo, _outputFormat, this);
|
_loopbackAudioOutput = new QAudioOutput(outputDeviceInfo.getDevice(), _outputFormat, this);
|
||||||
|
|
||||||
_timeSinceLastReceived.start();
|
_timeSinceLastReceived.start();
|
||||||
|
|
||||||
|
@ -2239,7 +2268,7 @@ float AudioClient::azimuthForSource(const glm::vec3& relativePosition) {
|
||||||
|
|
||||||
// produce an oriented angle about the y-axis
|
// produce an oriented angle about the y-axis
|
||||||
glm::vec3 direction = rotatedSourcePosition * (1.0f / fastSqrtf(rotatedSourcePositionLength2));
|
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;
|
return (direction.x < 0.0f) ? -angle : angle;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -2423,4 +2452,4 @@ void AudioClient::setInputVolume(float volume, bool emitSignal) {
|
||||||
emit inputVolumeChanged(_audioInput->volume());
|
emit inputVolumeChanged(_audioInput->volume());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -53,6 +53,7 @@
|
||||||
|
|
||||||
#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 )
|
||||||
|
@ -102,8 +103,8 @@ public:
|
||||||
_audio(audio), _unfulfilledReads(0) {}
|
_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;
|
||||||
|
@ -111,7 +112,7 @@ public:
|
||||||
AudioClient* _audio;
|
AudioClient* _audio;
|
||||||
int _unfulfilledReads;
|
int _unfulfilledReads;
|
||||||
};
|
};
|
||||||
|
|
||||||
void startThread();
|
void startThread();
|
||||||
void negotiateAudioFormat();
|
void negotiateAudioFormat();
|
||||||
void selectAudioFormat(const QString& selectedCodecName);
|
void selectAudioFormat(const QString& selectedCodecName);
|
||||||
|
@ -152,12 +153,12 @@ 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;
|
||||||
|
|
||||||
|
@ -233,11 +234,11 @@ public slots:
|
||||||
int setOutputBufferSize(int numFrames, bool persist = true);
|
int setOutputBufferSize(int numFrames, bool persist = true);
|
||||||
|
|
||||||
bool shouldLoopbackInjectors() override { return _shouldEchoToServer; }
|
bool shouldLoopbackInjectors() override { return _shouldEchoToServer; }
|
||||||
|
Q_INVOKABLE void changeDefault(HifiAudioDeviceInfo newDefault, QAudio::Mode mode);
|
||||||
|
|
||||||
// calling with a null QAudioDevice will use the system default
|
// 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);
|
bool switchAudioDevice(QAudio::Mode mode, const QString& deviceName);
|
||||||
|
|
||||||
// Qt opensles plugin is not able to detect when the headset is plugged in
|
// Qt opensles plugin is not able to detect when the headset is plugged in
|
||||||
void setHeadsetPluggedIn(bool pluggedIn);
|
void setHeadsetPluggedIn(bool pluggedIn);
|
||||||
|
|
||||||
|
@ -269,10 +270,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();
|
||||||
|
@ -416,7 +417,7 @@ private:
|
||||||
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();
|
||||||
|
@ -437,8 +438,8 @@ private:
|
||||||
void processWebrtcNearEnd(int16_t* samples, int numFrames, int numChannels, int sampleRate);
|
void processWebrtcNearEnd(int16_t* samples, int numFrames, int numChannels, int sampleRate);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool switchInputToAudioDevice(const QAudioDeviceInfo inputDeviceInfo, bool isShutdownRequest = false);
|
bool switchInputToAudioDevice(const HifiAudioDeviceInfo inputDeviceInfo, bool isShutdownRequest = false);
|
||||||
bool switchOutputToAudioDevice(const QAudioDeviceInfo outputDeviceInfo, bool isShutdownRequest = false);
|
bool switchOutputToAudioDevice(const HifiAudioDeviceInfo outputDeviceInfo, bool isShutdownRequest = false);
|
||||||
|
|
||||||
// Callback acceleration dependent calculations
|
// Callback acceleration dependent calculations
|
||||||
int calculateNumberOfInputCallbackBytes(const QAudioFormat& format) const;
|
int calculateNumberOfInputCallbackBytes(const QAudioFormat& format) const;
|
||||||
|
@ -459,11 +460,11 @@ 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;
|
||||||
|
|
||||||
AudioFileWav _audioFileWav;
|
AudioFileWav _audioFileWav;
|
||||||
|
|
||||||
|
@ -476,7 +477,7 @@ private:
|
||||||
|
|
||||||
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,11 +485,11 @@ 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;
|
Mutex _checkDevicesMutex;
|
||||||
QTimer* _checkDevicesTimer { nullptr };
|
QTimer* _checkDevicesTimer { nullptr };
|
||||||
Mutex _checkPeakValuesMutex;
|
Mutex _checkPeakValuesMutex;
|
||||||
|
@ -498,4 +499,4 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // hifi_AudioClient_h
|
#endif // hifi_AudioClient_h
|
36
libraries/audio-client/src/HifiAudioDeviceInfo.cpp
Normal file
36
libraries/audio-client/src/HifiAudioDeviceInfo.cpp
Normal 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();
|
||||||
|
}
|
||||||
|
|
69
libraries/audio-client/src/HifiAudioDeviceInfo.h
Normal file
69
libraries/audio-client/src/HifiAudioDeviceInfo.h
Normal 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
|
|
@ -48,7 +48,8 @@ Q_DECLARE_METATYPE(JSONCallbackParameters)
|
||||||
const QString ACCOUNTS_GROUP = "accounts";
|
const QString ACCOUNTS_GROUP = "accounts";
|
||||||
|
|
||||||
const int POST_SETTINGS_INTERVAL = 10 * MSECS_PER_SECOND;
|
const int POST_SETTINGS_INTERVAL = 10 * MSECS_PER_SECOND;
|
||||||
const int PULL_SETTINGS_RETRY_INTERVAL = 1 * MSECS_PER_SECOND;
|
const int PULL_SETTINGS_RETRY_INTERVAL = 2 * MSECS_PER_SECOND;
|
||||||
|
const int MAX_PULL_RETRIES = 10;
|
||||||
|
|
||||||
JSONCallbackParameters::JSONCallbackParameters(QObject* callbackReceiver,
|
JSONCallbackParameters::JSONCallbackParameters(QObject* callbackReceiver,
|
||||||
const QString& jsonCallbackMethod,
|
const QString& jsonCallbackMethod,
|
||||||
|
@ -73,9 +74,10 @@ QJsonObject AccountManager::dataObjectFromResponse(QNetworkReply* requestReply)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AccountManager::AccountManager(UserAgentGetter userAgentGetter) :
|
AccountManager::AccountManager(bool accountSettingsEnabled, UserAgentGetter userAgentGetter) :
|
||||||
_userAgentGetter(userAgentGetter),
|
_userAgentGetter(userAgentGetter),
|
||||||
_authURL()
|
_authURL(),
|
||||||
|
_accountSettingsEnabled(accountSettingsEnabled)
|
||||||
{
|
{
|
||||||
qRegisterMetaType<OAuthAccessToken>("OAuthAccessToken");
|
qRegisterMetaType<OAuthAccessToken>("OAuthAccessToken");
|
||||||
qRegisterMetaTypeStreamOperators<OAuthAccessToken>("OAuthAccessToken");
|
qRegisterMetaTypeStreamOperators<OAuthAccessToken>("OAuthAccessToken");
|
||||||
|
@ -92,9 +94,14 @@ AccountManager::AccountManager(UserAgentGetter userAgentGetter) :
|
||||||
connect(this, &AccountManager::loginComplete, this, &AccountManager::uploadPublicKey);
|
connect(this, &AccountManager::loginComplete, this, &AccountManager::uploadPublicKey);
|
||||||
connect(this, &AccountManager::loginComplete, this, &AccountManager::requestAccountSettings);
|
connect(this, &AccountManager::loginComplete, this, &AccountManager::requestAccountSettings);
|
||||||
|
|
||||||
|
_pullSettingsRetryTimer = new QTimer(this);
|
||||||
|
_pullSettingsRetryTimer->setSingleShot(true);
|
||||||
|
_pullSettingsRetryTimer->setInterval(PULL_SETTINGS_RETRY_INTERVAL);
|
||||||
|
connect(_pullSettingsRetryTimer, &QTimer::timeout, this, &AccountManager::requestAccountSettings);
|
||||||
|
|
||||||
_postSettingsTimer = new QTimer(this);
|
_postSettingsTimer = new QTimer(this);
|
||||||
_postSettingsTimer->setInterval(POST_SETTINGS_INTERVAL);
|
_postSettingsTimer->setInterval(POST_SETTINGS_INTERVAL);
|
||||||
connect(this, SIGNAL(loginComplete(QUrl)), _postSettingsTimer, SLOT(start()));
|
connect(this, SIGNAL(accountSettingsLoaded()), _postSettingsTimer, SLOT(start()));
|
||||||
connect(this, &AccountManager::logoutComplete, _postSettingsTimer, &QTimer::stop);
|
connect(this, &AccountManager::logoutComplete, _postSettingsTimer, &QTimer::stop);
|
||||||
connect(_postSettingsTimer, &QTimer::timeout, this, &AccountManager::postAccountSettings);
|
connect(_postSettingsTimer, &QTimer::timeout, this, &AccountManager::postAccountSettings);
|
||||||
connect(qApp, &QCoreApplication::aboutToQuit, this, &AccountManager::postAccountSettings);
|
connect(qApp, &QCoreApplication::aboutToQuit, this, &AccountManager::postAccountSettings);
|
||||||
|
@ -104,6 +111,7 @@ const QString ACCOUNT_MANAGER_REQUESTED_SCOPE = "owner";
|
||||||
|
|
||||||
void AccountManager::logout() {
|
void AccountManager::logout() {
|
||||||
postAccountSettings();
|
postAccountSettings();
|
||||||
|
_numPullRetries = 0;
|
||||||
|
|
||||||
// a logout means we want to delete the DataServerAccountInfo we currently have for this URL, in-memory and in file
|
// a logout means we want to delete the DataServerAccountInfo we currently have for this URL, in-memory and in file
|
||||||
_accountInfo = DataServerAccountInfo();
|
_accountInfo = DataServerAccountInfo();
|
||||||
|
@ -796,6 +804,10 @@ void AccountManager::requestProfileError(QNetworkReply::NetworkError error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AccountManager::requestAccountSettings() {
|
void AccountManager::requestAccountSettings() {
|
||||||
|
if (!_accountSettingsEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
||||||
|
|
||||||
QUrl lockerURL = _authURL;
|
QUrl lockerURL = _authURL;
|
||||||
|
@ -826,20 +838,33 @@ void AccountManager::requestAccountSettingsFinished() {
|
||||||
emit accountSettingsLoaded();
|
emit accountSettingsLoaded();
|
||||||
} else {
|
} else {
|
||||||
qCDebug(networking) << "Error in response for account settings: no data object";
|
qCDebug(networking) << "Error in response for account settings: no data object";
|
||||||
QTimer::singleShot(PULL_SETTINGS_RETRY_INTERVAL, this, &AccountManager::requestAccountSettings);
|
if (!_pullSettingsRetryTimer->isActive() && _numPullRetries < MAX_PULL_RETRIES) {
|
||||||
|
++_numPullRetries;
|
||||||
|
_pullSettingsRetryTimer->start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
qCDebug(networking) << "Error in response for account settings" << lockerReply->errorString();
|
qCDebug(networking) << "Error in response for account settings" << lockerReply->errorString();
|
||||||
QTimer::singleShot(PULL_SETTINGS_RETRY_INTERVAL, this, &AccountManager::requestAccountSettings);
|
if (!_pullSettingsRetryTimer->isActive() && _numPullRetries < MAX_PULL_RETRIES) {
|
||||||
|
++_numPullRetries;
|
||||||
|
_pullSettingsRetryTimer->start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AccountManager::requestAccountSettingsError(QNetworkReply::NetworkError error) {
|
void AccountManager::requestAccountSettingsError(QNetworkReply::NetworkError error) {
|
||||||
qCWarning(networking) << "Account settings request encountered an error" << error;
|
qCWarning(networking) << "Account settings request encountered an error" << error;
|
||||||
QTimer::singleShot(PULL_SETTINGS_RETRY_INTERVAL, this, &AccountManager::requestAccountSettings);
|
if (!_pullSettingsRetryTimer->isActive() && _numPullRetries < MAX_PULL_RETRIES) {
|
||||||
|
++_numPullRetries;
|
||||||
|
_pullSettingsRetryTimer->start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AccountManager::postAccountSettings() {
|
void AccountManager::postAccountSettings() {
|
||||||
|
if (!_accountSettingsEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (_settings.lastChangeTimestamp() <= _lastSuccessfulSyncTimestamp && _lastSuccessfulSyncTimestamp != 0) {
|
if (_settings.lastChangeTimestamp() <= _lastSuccessfulSyncTimestamp && _lastSuccessfulSyncTimestamp != 0) {
|
||||||
// Nothing changed, skipping settings post
|
// Nothing changed, skipping settings post
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -60,7 +60,7 @@ const auto DEFAULT_USER_AGENT_GETTER = []() -> QString { return HIGH_FIDELITY_US
|
||||||
class AccountManager : public QObject, public Dependency {
|
class AccountManager : public QObject, public Dependency {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
AccountManager(UserAgentGetter userAgentGetter = DEFAULT_USER_AGENT_GETTER);
|
AccountManager(bool accountSettingsEnabled = false, UserAgentGetter userAgentGetter = DEFAULT_USER_AGENT_GETTER);
|
||||||
|
|
||||||
QNetworkRequest createRequest(QString path, AccountManagerAuth::Type authType);
|
QNetworkRequest createRequest(QString path, AccountManagerAuth::Type authType);
|
||||||
Q_INVOKABLE void sendRequest(const QString& path,
|
Q_INVOKABLE void sendRequest(const QString& path,
|
||||||
|
@ -182,9 +182,12 @@ private:
|
||||||
bool _limitedCommerce { false };
|
bool _limitedCommerce { false };
|
||||||
QString _configFileURL;
|
QString _configFileURL;
|
||||||
|
|
||||||
|
bool _accountSettingsEnabled { false };
|
||||||
AccountSettings _settings;
|
AccountSettings _settings;
|
||||||
quint64 _currentSyncTimestamp { 0 };
|
quint64 _currentSyncTimestamp { 0 };
|
||||||
quint64 _lastSuccessfulSyncTimestamp { 0 };
|
quint64 _lastSuccessfulSyncTimestamp { 0 };
|
||||||
|
int _numPullRetries { 0 };
|
||||||
|
QTimer* _pullSettingsRetryTimer { nullptr };
|
||||||
QTimer* _postSettingsTimer { nullptr };
|
QTimer* _postSettingsTimer { nullptr };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -269,7 +269,7 @@ bool Connection::processReceivedSequenceNumber(SequenceNumber sequenceNumber, in
|
||||||
bool wasDuplicate = false;
|
bool wasDuplicate = false;
|
||||||
|
|
||||||
if (sequenceNumber > _lastReceivedSequenceNumber) {
|
if (sequenceNumber > _lastReceivedSequenceNumber) {
|
||||||
// Update largest recieved sequence number
|
// Update largest received sequence number
|
||||||
_lastReceivedSequenceNumber = sequenceNumber;
|
_lastReceivedSequenceNumber = sequenceNumber;
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, it could be a resend, try and remove it from the loss list
|
// Otherwise, it could be a resend, try and remove it from the loss list
|
||||||
|
@ -312,9 +312,7 @@ void Connection::processControl(ControlPacketPointer controlPacket) {
|
||||||
// We're already in a state where we've received a handshake ack, so we are likely in a state
|
// We're already in a state where we've received a handshake ack, so we are likely in a state
|
||||||
// where the other end expired our connection. Let's reset.
|
// where the other end expired our connection. Let's reset.
|
||||||
|
|
||||||
#ifdef UDT_CONNECTION_DEBUG
|
qCDebug(networking) << "Got HandshakeRequest from" << _destination << "while active, stopping SendQueue";
|
||||||
qCDebug(networking) << "Got HandshakeRequest from" << _destination << ", stopping SendQueue";
|
|
||||||
#endif
|
|
||||||
_hasReceivedHandshakeACK = false;
|
_hasReceivedHandshakeACK = false;
|
||||||
stopSendQueue();
|
stopSendQueue();
|
||||||
}
|
}
|
||||||
|
@ -333,7 +331,7 @@ void Connection::processACK(ControlPacketPointer controlPacket) {
|
||||||
// validate that this isn't a BS ACK
|
// validate that this isn't a BS ACK
|
||||||
if (ack > getSendQueue().getCurrentSequenceNumber()) {
|
if (ack > getSendQueue().getCurrentSequenceNumber()) {
|
||||||
// in UDT they specifically break the connection here - do we want to do anything?
|
// in UDT they specifically break the connection here - do we want to do anything?
|
||||||
Q_ASSERT_X(false, "Connection::processACK", "ACK recieved higher than largest sent sequence number");
|
Q_ASSERT_X(false, "Connection::processACK", "ACK received higher than largest sent sequence number");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,7 @@ public:
|
||||||
void setMaxBandwidth(int maxBandwidth);
|
void setMaxBandwidth(int maxBandwidth);
|
||||||
|
|
||||||
void sendHandshakeRequest();
|
void sendHandshakeRequest();
|
||||||
|
bool hasReceivedHandshake() const { return _hasReceivedHandshake; }
|
||||||
|
|
||||||
void recordSentUnreliablePackets(int wireSize, int payloadSize);
|
void recordSentUnreliablePackets(int wireSize, int payloadSize);
|
||||||
void recordReceivedUnreliablePackets(int wireSize, int payloadSize);
|
void recordReceivedUnreliablePackets(int wireSize, int payloadSize);
|
||||||
|
|
|
@ -548,12 +548,14 @@ void Socket::handleRemoteAddressChange(HifiSockAddr previousAddress, HifiSockAdd
|
||||||
Lock connectionsLock(_connectionsHashMutex);
|
Lock connectionsLock(_connectionsHashMutex);
|
||||||
|
|
||||||
const auto connectionIter = _connectionsHash.find(previousAddress);
|
const auto connectionIter = _connectionsHash.find(previousAddress);
|
||||||
if (connectionIter != _connectionsHash.end()) {
|
// Don't move classes that are unused so far.
|
||||||
|
if (connectionIter != _connectionsHash.end() && connectionIter->second->hasReceivedHandshake()) {
|
||||||
auto connection = move(connectionIter->second);
|
auto connection = move(connectionIter->second);
|
||||||
_connectionsHash.erase(connectionIter);
|
_connectionsHash.erase(connectionIter);
|
||||||
connection->setDestinationAddress(currentAddress);
|
connection->setDestinationAddress(currentAddress);
|
||||||
_connectionsHash[currentAddress] = move(connection);
|
_connectionsHash[currentAddress] = move(connection);
|
||||||
connectionsLock.unlock();
|
connectionsLock.unlock();
|
||||||
|
qCDebug(networking) << "Moved Connection class from" << previousAddress << "to" << currentAddress;
|
||||||
|
|
||||||
Lock sequenceNumbersLock(_unreliableSequenceNumbersMutex);
|
Lock sequenceNumbersLock(_unreliableSequenceNumbersMutex);
|
||||||
const auto sequenceNumbersIter = _unreliableSequenceNumbers.find(previousAddress);
|
const auto sequenceNumbersIter = _unreliableSequenceNumbers.find(previousAddress);
|
||||||
|
|
|
@ -75,7 +75,8 @@ void PhysicalEntitySimulation::removeEntityInternal(EntityItemPointer entity) {
|
||||||
if (motionState) {
|
if (motionState) {
|
||||||
removeOwnershipData(motionState);
|
removeOwnershipData(motionState);
|
||||||
_entitiesToRemoveFromPhysics.insert(entity);
|
_entitiesToRemoveFromPhysics.insert(entity);
|
||||||
} else if (entity->isDead() && entity->getElement()) {
|
}
|
||||||
|
if (entity->isDead() && entity->getElement()) {
|
||||||
_deadEntities.insert(entity);
|
_deadEntities.insert(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,6 +103,10 @@ float Deck::position() const {
|
||||||
return Frame::frameTimeToSeconds(currentPosition);
|
return Frame::frameTimeToSeconds(currentPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Deck::setVolume(float volume) {
|
||||||
|
_volume = std::min(std::max(volume, 0.0f), 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
static const Frame::Time MIN_FRAME_WAIT_INTERVAL = Frame::secondsToFrameTime(0.001f);
|
static const Frame::Time MIN_FRAME_WAIT_INTERVAL = Frame::secondsToFrameTime(0.001f);
|
||||||
static const Frame::Time MAX_FRAME_PROCESSING_TIME = Frame::secondsToFrameTime(0.004f);
|
static const Frame::Time MAX_FRAME_PROCESSING_TIME = Frame::secondsToFrameTime(0.004f);
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,9 @@ public:
|
||||||
float position() const;
|
float position() const;
|
||||||
void seek(float position);
|
void seek(float position);
|
||||||
|
|
||||||
|
float getVolume() const { return _volume; }
|
||||||
|
void setVolume(float volume);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void playbackStateChanged();
|
void playbackStateChanged();
|
||||||
void looped();
|
void looped();
|
||||||
|
@ -76,6 +79,7 @@ private:
|
||||||
bool _pause { true };
|
bool _pause { true };
|
||||||
bool _loop { false };
|
bool _loop { false };
|
||||||
float _length { 0 };
|
float _length { 0 };
|
||||||
|
float _volume { 1.0f };
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,7 +117,7 @@ void RecordingScriptingInterface::startPlaying() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RecordingScriptingInterface::setPlayerVolume(float volume) {
|
void RecordingScriptingInterface::setPlayerVolume(float volume) {
|
||||||
// FIXME
|
_player->setVolume(std::min(std::max(volume, 0.0f), 1.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RecordingScriptingInterface::setPlayerAudioOffset(float audioOffset) {
|
void RecordingScriptingInterface::setPlayerAudioOffset(float audioOffset) {
|
||||||
|
|
|
@ -95,8 +95,9 @@ public slots:
|
||||||
|
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
* Sets the playback audio volume.
|
||||||
* @function Recording.setPlayerVolume
|
* @function Recording.setPlayerVolume
|
||||||
* @param {number} volume
|
* @param {number} volume - The playback audio volume, range <code>0.0</code> – <code>1.0</code>.
|
||||||
*/
|
*/
|
||||||
void setPlayerVolume(float volume);
|
void setPlayerVolume(float volume);
|
||||||
|
|
||||||
|
|
|
@ -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()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,7 +100,7 @@ ACClientApp::ACClientApp(int argc, char* argv[]) :
|
||||||
|
|
||||||
DependencyManager::registerInheritance<LimitedNodeList, NodeList>();
|
DependencyManager::registerInheritance<LimitedNodeList, NodeList>();
|
||||||
|
|
||||||
DependencyManager::set<AccountManager>([&]{ return QString("Mozilla/5.0 (HighFidelityACClient)"); });
|
DependencyManager::set<AccountManager>(false, [&]{ return QString("Mozilla/5.0 (HighFidelityACClient)"); });
|
||||||
DependencyManager::set<AddressManager>();
|
DependencyManager::set<AddressManager>();
|
||||||
DependencyManager::set<NodeList>(NodeType::Agent, listenPort);
|
DependencyManager::set<NodeList>(NodeType::Agent, listenPort);
|
||||||
|
|
||||||
|
|
|
@ -138,7 +138,7 @@ ATPClientApp::ATPClientApp(int argc, char* argv[]) :
|
||||||
DependencyManager::registerInheritance<LimitedNodeList, NodeList>();
|
DependencyManager::registerInheritance<LimitedNodeList, NodeList>();
|
||||||
|
|
||||||
DependencyManager::set<StatTracker>();
|
DependencyManager::set<StatTracker>();
|
||||||
DependencyManager::set<AccountManager>([&]{ return QString(HIGH_FIDELITY_ATP_CLIENT_USER_AGENT); });
|
DependencyManager::set<AccountManager>(false, [&]{ return QString(HIGH_FIDELITY_ATP_CLIENT_USER_AGENT); });
|
||||||
DependencyManager::set<AddressManager>();
|
DependencyManager::set<AddressManager>();
|
||||||
DependencyManager::set<NodeList>(NodeType::Agent, _listenPort);
|
DependencyManager::set<NodeList>(NodeType::Agent, _listenPort);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue