up to reverb (needs cherry-picking)

This commit is contained in:
Zach Pomerantz 2017-06-12 18:00:52 -04:00
parent 858b980c16
commit b37a0239b0
24 changed files with 386 additions and 392 deletions

View file

@ -18,6 +18,7 @@ Original.CheckBox {
id: checkBox
property int colorScheme: hifi.colorSchemes.light
property string color: hifi.colors.lightGray
readonly property bool isLightColorScheme: colorScheme == hifi.colorSchemes.light
property bool isRedCheck: false
property int boxSize: 14
@ -89,7 +90,7 @@ Original.CheckBox {
label: Label {
text: control.text
colorScheme: checkBox.colorScheme
color: control.color
x: 2
wrapMode: Text.Wrap
enabled: checkBox.enabled

View file

@ -25,7 +25,6 @@ ScrollingWindow {
height: 577
property var sections: []
property var showCategories: []
property bool showFooter: true
minSize: Qt.vector2d(400, 500)
HifiConstants { id: hifi }
@ -95,8 +94,6 @@ ScrollingWindow {
}
footer: Row {
visible: root.showFooter
anchors {
top: parent.top
right: parent.right

View file

@ -1,279 +0,0 @@
//
// Audio.qml
// qml/hifi
//
// Audio setup
//
// Created by Vlad Stelmahovsky on 03/22/2017
// Copyright 2017 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
import QtQuick 2.5
import QtQuick.Controls 1.4
import QtGraphicalEffects 1.0
import "../styles-uit"
import "../controls-uit" as HifiControls
import "../windows"
import "components"
Rectangle {
id: audio;
HifiConstants { id: hifi; }
property var eventBridge;
property string title: "Audio Settings"
signal sendToScript(var message);
color: "#404040";
Text {
text: "ZZMP"
}
ListView {
model: Audio.devices.input
}
}
/*
Rectangle {
id: audio;
//put info text here
property alias infoText: infoArea.text
color: "#404040";
HifiConstants { id: hifi; }
objectName: "AudioWindow"
property var eventBridge;
property string title: "Audio Options"
signal sendToScript(var message);
Component {
id: separator
LinearGradient {
start: Qt.point(0, 0)
end: Qt.point(0, 4)
gradient: Gradient {
GradientStop { position: 0.0; color: "#303030" }
GradientStop { position: 0.33; color: "#252525" } // Equivalent of darkGray0 over baseGray background.
GradientStop { position: 0.5; color: "#303030" }
GradientStop { position: 0.6; color: "#454a49" }
GradientStop { position: 1.0; color: "#454a49" }
}
cached: true
}
}
Column {
anchors { left: parent.left; right: parent.right }
spacing: 8
RalewayRegular {
anchors { left: parent.left; right: parent.right; leftMargin: 30 }
height: 45
size: 20
color: "white"
text: audio.title
}
Loader {
width: parent.width
height: 5
sourceComponent: separator
}
//connections required to syncronize with Menu
Connections {
target: AudioDevice
onMuteToggled: {
audioMute.checkbox.checked = AudioDevice.getMuted()
}
}
Connections {
target: AvatarInputs !== undefined ? AvatarInputs : null
onShowAudioToolsChanged: {
audioTools.checkbox.checked = showAudioTools
}
}
AudioCheckbox {
id: audioMute
width: parent.width
anchors { left: parent.left; right: parent.right; leftMargin: 30 }
checkbox.checked: AudioDevice.muted
text.text: qsTr("Mute microphone")
onCheckBoxClicked: {
AudioDevice.muted = checked
}
}
AudioCheckbox {
id: audioTools
width: parent.width
anchors { left: parent.left; right: parent.right; leftMargin: 30 }
checkbox.checked: AvatarInputs !== undefined ? AvatarInputs.showAudioTools : false
text.text: qsTr("Show audio level meter")
onCheckBoxClicked: {
if (AvatarInputs !== undefined) {
AvatarInputs.showAudioTools = checked
}
}
}
Loader {
width: parent.width
height: 5
sourceComponent: separator
}
Row {
anchors { left: parent.left; right: parent.right; leftMargin: 30 }
height: 40
spacing: 8
HiFiGlyphs {
text: hifi.glyphs.mic
color: hifi.colors.primaryHighlight
anchors.verticalCenter: parent.verticalCenter
size: 32
}
RalewayRegular {
anchors.verticalCenter: parent.verticalCenter
size: 16
color: "#AFAFAF"
text: qsTr("CHOOSE INPUT DEVICE")
}
}
ListView {
id: inputAudioListView
anchors { left: parent.left; right: parent.right; leftMargin: 70 }
height: 125
spacing: 0
clip: true
snapMode: ListView.SnapToItem
model: AudioDevice
delegate: Item {
width: parent.width
visible: devicemode === 0
height: visible ? 36 : 0
AudioCheckbox {
id: cbin
anchors.verticalCenter: parent.verticalCenter
Binding {
target: cbin.checkbox
property: 'checked'
value: devicechecked
}
width: parent.width
cbchecked: devicechecked
text.text: devicename
onCheckBoxClicked: {
if (checked) {
AudioDevice.setInputDeviceAsync(devicename)
}
}
}
}
}
Loader {
width: parent.width
height: 5
sourceComponent: separator
}
Row {
anchors { left: parent.left; right: parent.right; leftMargin: 30 }
height: 40
spacing: 8
HiFiGlyphs {
text: hifi.glyphs.unmuted
color: hifi.colors.primaryHighlight
anchors.verticalCenter: parent.verticalCenter
size: 32
}
RalewayRegular {
anchors.verticalCenter: parent.verticalCenter
size: 16
color: "#AFAFAF"
text: qsTr("CHOOSE OUTPUT DEVICE")
}
}
ListView {
id: outputAudioListView
anchors { left: parent.left; right: parent.right; leftMargin: 70 }
height: 250
spacing: 0
clip: true
snapMode: ListView.SnapToItem
model: AudioDevice
delegate: Item {
width: parent.width
visible: devicemode === 1
height: visible ? 36 : 0
AudioCheckbox {
id: cbout
width: parent.width
anchors.verticalCenter: parent.verticalCenter
Binding {
target: cbout.checkbox
property: 'checked'
value: devicechecked
}
text.text: devicename
onCheckBoxClicked: {
if (checked) {
AudioDevice.setOutputDeviceAsync(devicename)
}
}
}
}
}
Loader {
id: lastSeparator
width: parent.width
height: 6
sourceComponent: separator
}
Row {
anchors { left: parent.left; right: parent.right; leftMargin: 30 }
height: 40
spacing: 8
HiFiGlyphs {
id: infoSign
text: hifi.glyphs.info
color: "#AFAFAF"
anchors.verticalCenter: parent.verticalCenter
size: 60
}
RalewayRegular {
id: infoArea
width: parent.width - infoSign.implicitWidth - parent.spacing - 10
wrapMode: Text.WordWrap
anchors.verticalCenter: parent.verticalCenter
size: 12
color: hifi.colors.baseGrayHighlight
}
}
}
}
*/

View file

@ -0,0 +1,146 @@
//
// Audio.qml
// qml/hifi/audio
//
// Audio setup
//
// Created by Vlad Stelmahovsky on 03/22/2017
// Copyright 2017 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.3
import "../../styles-uit"
import "../../controls-uit" as HifiControls
import "../../windows"
import "./" as Audio
Rectangle {
id: audio;
HifiConstants { id: hifi; }
property var eventBridge;
property string title: "Audio Settings - " + Audio.context
signal sendToScript(var message);
color: hifi.colors.baseGray;
Column {
y: 16 // padding does not work
spacing: 16
width: parent.width
Grid {
columns: 2
x: 16 // padding does not work
spacing: 16
Audio.CheckBox {
text: qsTr("Mute microphone");
checked: Audio.muted
onClicked: {
Audio.muted = checked;
checked = Qt.binding(function() { return Audio.muted; }); // restore binding
}
}
Audio.CheckBox {
text: qsTr("Enable noise reduction");
checked: Audio.noiseReduction
onClicked: {
Audio.noiseReduction = checked;
checked = Qt.binding(function() { return Audio.noiseReduction; }); // restore binding
}
}
Audio.CheckBox {
text: qsTr("Show audio level meter");
checked: Audio.showMicMeter
onClicked: {
Audio.showMicMeter = checked;
checked = Qt.binding(function() { return Audio.showMicMeter; }); // restore binding
}
}
}
Separator {}
RowLayout {
HiFiGlyphs {
text: hifi.glyphs.mic
color: hifi.colors.primaryHighlight
anchors.verticalCenter: parent.verticalCenter
size: 28
}
RalewayRegular {
anchors.verticalCenter: parent.verticalCenter
size: 16
color: "#AFAFAF"
text: qsTr("CHOOSE INPUT DEVICE")
}
}
ListView {
anchors { left: parent.left; right: parent.right; leftMargin: 70 }
height: 125
spacing: 0
snapMode: ListView.SnapToItem
clip: true
model: Audio.devices.input
delegate: Item {
width: parent.width
height: 36
Audio.CheckBox {
text: display;
checked: selected
onClicked: {
selected = checked;
checked = Qt.binding(function() { return selected; }); // restore binding
}
}
}
}
Separator {}
RowLayout {
HiFiGlyphs {
text: hifi.glyphs.unmuted
color: hifi.colors.primaryHighlight
anchors.verticalCenter: parent.verticalCenter
size: 36
}
RalewayRegular {
anchors.verticalCenter: parent.verticalCenter
size: 16
color: "#AFAFAF"
text: qsTr("CHOOSE OUTPUT DEVICE")
}
}
ListView {
anchors { left: parent.left; right: parent.right; leftMargin: 70 }
height: 125
spacing: 0
snapMode: ListView.SnapToItem
clip: true
model: Audio.devices.output
delegate: Item {
width: parent.width
height: 36
Audio.CheckBox {
text: display;
checked: selected
onClicked: {
selected = checked;
checked = Qt.binding(function() { return selected; }); // restore binding
}
}
}
}
}
}

View file

@ -0,0 +1,18 @@
//
// CheckBox.qml
// qml/hifi/audio
//
// Created by Zach Pomerantz on 6/12/2017
// Copyright 2017 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
import QtQuick 2.5
import "../../controls-uit" as HifiControls
HifiControls.CheckBox {
color: "white"
}

View file

@ -1,30 +0,0 @@
import QtQuick 2.5
import QtQuick.Controls 1.4
import "../../styles-uit"
import "../../controls-uit" as HifiControls
Row {
id: row
spacing: 16
property alias checkbox: cb
property alias cbchecked: cb.checked
property alias text: txt
signal checkBoxClicked(bool checked)
HifiControls.CheckBox {
id: cb
boxSize: 20
colorScheme: hifi.colorSchemes.dark
anchors.verticalCenter: parent.verticalCenter
onClicked: checkBoxClicked(cb.checked)
}
RalewayBold {
id: txt
wrapMode: Text.WordWrap
width: parent.width - cb.boxSize - 30
anchors.verticalCenter: parent.verticalCenter
size: 16
color: "white"
}
}

View file

@ -1,21 +1,26 @@
import QtQuick 2.5
import Qt.labs.settings 1.0
//
// Audio.qml
//
// Created by Zach Pomerantz on 6/12/2017
// Copyright 2017 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
import "../../dialogs"
import "../"
import "../../windows"
import "../audio"
PreferencesDialog {
id: root
ScrollingWindow {
resizable: true
destroyOnHidden: true
width: 400
height: 577
minSize: Qt.vector2d(400, 500)
id: audio
objectName: "AudioDialog"
title: "Audio Settings"
showFooter: false
property var settings: Settings {
category: root.objectName
property alias x: root.x
property alias y: root.y
property alias width: root.width
property alias height: root.height
}
title: "Audio Settings - " + Audio.context
Audio {}
Audio { width: audio.width }
}

View file

@ -151,7 +151,7 @@ Item {
}
function toggleMicEnabled() {
ApplicationInterface.toggleMuteAudio();
Audio.mute = !Audio.mute;
}
function setUsername(newUsername) {

View file

@ -73,7 +73,7 @@ Windows.ScrollingWindow {
}
function toggleMicEnabled() {
ApplicationInterface.toggleMuteAudio();
Audio.mute = !Audio.mute;
}
function setUsername(newUsername) {

View file

@ -1,5 +1,5 @@
#!/bin/bash
while sleep 5; do
cp ~/hifi/interface/resources/qml/hifi/Audio.qml ~/hifi/build/interface/Release/resources/qml/hifi/Audio.qml
cp ~/hifi/interface/resources/qml/hifi/audio/* ~/hifi/build/interface/Release/resources/qml/hifi/audio/
done

View file

@ -14,6 +14,8 @@ import "../styles-uit"
Item {
// Size
height: 2;
width: parent.width;
Rectangle {
// Size
width: parent.width;
@ -25,6 +27,7 @@ Item {
// Style
color: hifi.colors.baseGrayShadow;
}
Rectangle {
// Size
width: parent.width;

View file

@ -725,7 +725,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
connect(audioThread, &QThread::started, audioIO.data(), &AudioClient::start);
connect(audioIO.data(), &AudioClient::destroyed, audioThread, &QThread::quit);
connect(audioThread, &QThread::finished, audioThread, &QThread::deleteLater);
connect(audioIO.data(), &AudioClient::muteToggled, this, &Application::audioMuteToggled);
connect(audioIO.data(), &AudioClient::mutedByMixer, audioScriptingInterface.data(), &AudioScriptingInterface::mutedByMixer);
connect(audioIO.data(), &AudioClient::receivedFirstPacket, audioScriptingInterface.data(), &AudioScriptingInterface::receivedFirstPacket);
connect(audioIO.data(), &AudioClient::disconnected, audioScriptingInterface.data(), &AudioScriptingInterface::disconnected);
@ -741,6 +740,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
audioScriptingInterface->environmentMuted();
}
});
connect(this, &Application::activeDisplayPluginChanged,
reinterpret_cast<scripting::Audio*>(audioScriptingInterface.data()), &scripting::Audio::onChangedContext);
audioThread->start();
@ -824,6 +825,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
connect(this, &Application::activeDisplayPluginChanged, this, &Application::updateThreadPoolCount);
connect(this, &Application::activeDisplayPluginChanged, this, [](){
bool isHMD = qApp->isHMDMode();
qApp->setProperty(hifi::properties::HMD, qApp->isHMDMode());
});
connect(this, &Application::activeDisplayPluginChanged, this, &Application::updateSystemTabletMode);
@ -1922,7 +1924,15 @@ void Application::initializeUi() {
rootContext->setContextProperty("ApplicationCompositor", &getApplicationCompositor());
rootContext->setContextProperty("AvatarInputs", AvatarInputs::getInstance());
{
auto ai = AvatarInputs::getInstance();
rootContext->setContextProperty("AvatarInputs", ai);
// hook up audio
auto audio = reinterpret_cast<scripting::Audio*>(DependencyManager::get<AudioScriptingInterface>().data());
connect(ai, &AvatarInputs::showAudioToolsChanged, audio, &scripting::Audio::onChangedMicMeter);
connect(audio, &scripting::Audio::changedMicMeter, ai, &AvatarInputs::setShowAudioTools);
}
if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) {
rootContext->setContextProperty("Steam", new SteamScriptingInterface(engine, steamClient.get()));
@ -2221,12 +2231,6 @@ void Application::runTests() {
runUnitTests();
}
void Application::audioMuteToggled() const {
QAction* muteAction = Menu::getInstance()->getActionForOption(MenuOption::MuteAudio);
Q_CHECK_PTR(muteAction);
muteAction->setChecked(DependencyManager::get<AudioClient>()->isMuted());
}
void Application::faceTrackerMuteToggled() {
QAction* muteAction = Menu::getInstance()->getActionForOption(MenuOption::MuteFaceTracking);
@ -2765,6 +2769,12 @@ void Application::keyPressEvent(QKeyEvent* event) {
Menu::getInstance()->triggerOption(MenuOption::DefaultSkybox);
break;
case Qt::Key_M:
if (isMeta) {
DependencyManager::get<AudioClient>()->toggleMute();
}
break;
case Qt::Key_N:
if (!isOption && !isShifted && isMeta) {
DependencyManager::get<NodeList>()->toggleIgnoreRadius();
@ -4336,10 +4346,11 @@ void Application::update(float deltaTime) {
} else {
const quint64 MUTE_MICROPHONE_AFTER_USECS = 5000000; //5 secs
Menu* menu = Menu::getInstance();
if (menu->isOptionChecked(MenuOption::AutoMuteAudio) && !menu->isOptionChecked(MenuOption::MuteAudio)) {
auto audioClient = DependencyManager::get<AudioClient>();
if (menu->isOptionChecked(MenuOption::AutoMuteAudio) && !audioClient->isMuted()) {
if (_lastFaceTrackerUpdate > 0
&& ((usecTimestampNow() - _lastFaceTrackerUpdate) > MUTE_MICROPHONE_AFTER_USECS)) {
menu->triggerOption(MenuOption::MuteAudio);
audioClient->toggleMute();
_lastFaceTrackerUpdate = 0;
}
} else {
@ -6985,11 +6996,6 @@ void Application::updateSystemTabletMode() {
}
}
void Application::toggleMuteAudio() {
auto menu = Menu::getInstance();
menu->setIsOptionChecked(MenuOption::MuteAudio, !menu->isOptionChecked(MenuOption::MuteAudio));
}
OverlayID Application::getTabletScreenID() const {
auto HMD = DependencyManager::get<HMDScriptingInterface>();
return HMD->getCurrentTabletScreenID();

View file

@ -390,7 +390,6 @@ public slots:
void addAssetToWorldMessageClose();
Q_INVOKABLE void toggleMuteAudio();
void loadLODToolsDialog();
void loadEntityStatisticsDialog();
void loadDomainConnectionDialog();
@ -404,7 +403,6 @@ private slots:
void resettingDomain();
void audioMuteToggled() const;
void faceTrackerMuteToggled();
void activeChanged(Qt::ApplicationState state);

View file

@ -290,7 +290,7 @@ Menu::Menu() {
action = addActionToQMenuAndActionHash(settingsMenu, "Audio...", Qt::CTRL | Qt::Key_Z);
connect(action, &QAction::triggered, [] {
static const QUrl widgetUrl("hifi/dialogs/Audio.qml");
static const QUrl tabletUrl("../../hifi/Audio.qml");
static const QUrl tabletUrl("../../hifi/audio/Audio.qml");
static const QString name("AudioDialog");
qApp->showDialog(widgetUrl, tabletUrl, name);
});

View file

@ -36,7 +36,6 @@ namespace MenuOption {
const QString AssetMigration = "ATP Asset Migration";
const QString AssetServer = "Asset Browser";
const QString Attachments = "Attachments...";
const QString AudioNoiseReduction = "Noise Reduction";
const QString AudioScope = "Show Scope";
const QString AudioScopeFiftyFrames = "Fifty";
const QString AudioScopeFiveFrames = "Five";
@ -44,7 +43,6 @@ namespace MenuOption {
const QString AudioScopePause = "Pause Scope";
const QString AudioScopeTwentyFrames = "Twenty";
const QString AudioStatsShowInjectedStreams = "Audio Stats Show Injected Streams";
const QString AudioTools = "Show Level Meter";
const QString AutoMuteAudio = "Auto Mute Microphone";
const QString AvatarReceiveStats = "Show Receive Stats";
const QString AvatarBookmarks = "Avatar Bookmarks";
@ -124,7 +122,6 @@ namespace MenuOption {
const QString LogExtraTimings = "Log Extra Timing Details";
const QString LowVelocityFilter = "Low Velocity Filter";
const QString MeshVisible = "Draw Mesh";
const QString MuteAudio = "Mute Microphone";
const QString MuteEnvironment = "Mute Environment";
const QString MuteFaceTracking = "Mute Face Tracking";
const QString NamesAboveHeads = "Names Above Heads";

View file

@ -11,11 +11,98 @@
#include "Audio.h"
#include "Application.h"
#include "AudioClient.h"
#include "ui/AvatarInputs.h"
using namespace scripting;
static const QString DESKTOP_CONTEXT { "Desktop" };
static const QString HMD_CONTEXT { "VR" };
QString Audio::getContext() {
return _contextIsHMD ? HMD_CONTEXT : DESKTOP_CONTEXT;
Audio::Audio() {
auto client = DependencyManager::get<AudioClient>();
connect(client.data(), &AudioClient::muteToggled, this, &Audio::onChangedMuted);
connect(&_devices._inputs, &AudioDeviceList::deviceChanged, this, &Audio::onInputChanged);
// TODO: make noise reduction sticky
// TODO: make mic meter sticky (need to reinitialize in AvatarInputs)
}
void Audio::onChangedContext() {
bool isHMD = qApp->isHMDMode();
if (_contextIsHMD != isHMD) {
_contextIsHMD = isHMD;
_devices.restoreDevices(_contextIsHMD);
emit changedContext(getContext());
}
}
QString Audio::getContext() const {
return _contextIsHMD ? HMD_CONTEXT : DESKTOP_CONTEXT;
}
void Audio::onChangedMuted() {
auto client = DependencyManager::get<AudioClient>().data();
bool isMuted;
QMetaObject::invokeMethod(client, "isMuted", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, isMuted));
if (_isMuted != isMuted) {
_isMuted = isMuted;
emit changedMuted(_isMuted);
}
}
void Audio::setMuted(bool isMuted) {
if (_isMuted != isMuted) {
auto client = DependencyManager::get<AudioClient>().data();
QMetaObject::invokeMethod(client, "toggleMute", Qt::BlockingQueuedConnection);
_isMuted = isMuted;
emit changedMuted(_isMuted);
}
}
void Audio::enableNoiseReduction(bool enable) {
auto client = DependencyManager::get<AudioClient>().data();
QMetaObject::invokeMethod(client, "setNoiseReduction", Qt::BlockingQueuedConnection, Q_ARG(bool, enable));
_enableNoiseReduction = enable;
emit changedNoiseReduction(enable);
}
void Audio::onChangedMicMeter(bool show) {
showMicMeter(show);
}
void Audio::showMicMeter(bool show) {
if (_showMicMeter != show) {
_showMicMeter = show;
emit changedMicMeter(show);
}
}
void Audio::setInputVolume(float volume) {
// getInputVolume will not reflect changes synchronously, so clamp beforehand
volume = glm::clamp(volume, 0.0f, 1.0f);
if (_inputVolume != volume) {
auto client = DependencyManager::get<AudioClient>().data();
QMetaObject::invokeMethod(client, "setInputVolume", Qt::BlockingQueuedConnection, Q_ARG(float, volume));
_inputVolume = volume;
emit changedInputVolume(_inputVolume);
}
}
void Audio::onInputChanged() {
auto client = DependencyManager::get<AudioClient>().data();
float volume;
QMetaObject::invokeMethod(client, "getInputVolume", Qt::BlockingQueuedConnection, Q_RETURN_ARG(float, volume));
if (_inputVolume != volume) {
_inputVolume = volume;
emit changedInputVolume(_inputVolume);
}
}

View file

@ -21,11 +21,11 @@ class Audio : public AudioScriptingInterface {
Q_OBJECT
SINGLETON_DEPENDENCY
// TODO: Q_PROPERTY(bool mute)
// TODO: Q_PROPERTY(bool noiseReduction)
// TODO: Q_PROPERTY(bool reverb)
// TODO: Q_PROPERTY(float inputVolume)
// TODO: Q_PROPERTY(bool showMicLevel)
Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY changedMuted)
Q_PROPERTY(bool noiseReduction READ noiseReductionEnabled WRITE enableNoiseReduction NOTIFY changedNoiseReduction)
Q_PROPERTY(bool showMicMeter READ micMeterShown WRITE showMicMeter NOTIFY changedMicMeter)
// TODO: Q_PROPERTY(bool reverb READ getReverb WRITE setReverb NOTIFY changedReverb)
Q_PROPERTY(float inputVolume READ getInputVolume WRITE setInputVolume NOTIFY changedInputVolume)
Q_PROPERTY(QString context READ getContext NOTIFY changedContext)
Q_PROPERTY(AudioDevices* devices READ getDevices NOTIFY nop)
@ -34,18 +34,41 @@ public:
signals:
void nop();
void changedMuted(bool);
void changedNoiseReduction(bool);
void changedMicMeter(bool);
void changedInputVolume(float);
void changedContext(QString);
protected:
Audio() {}
public slots:
void onChangedMuted();
void onChangedMicMeter(bool);
void onChangedContext();
void onInputChanged();
QString getContext();
protected:
Audio();
private:
bool isMuted() const { return _isMuted; }
bool noiseReductionEnabled() const { return _enableNoiseReduction; }
bool micMeterShown() const { return _showMicMeter; }
float getInputVolume() const { return _inputVolume; }
QString getContext() const;
void setMuted(bool muted);
void enableNoiseReduction(bool enable);
void showMicMeter(bool show);
void setInputVolume(float volume);
float _inputVolume { 1.0f };
bool _isMuted { false };
bool _enableNoiseReduction { true };
bool _showMicMeter { false };
bool _contextIsHMD { false };
AudioDevices* getDevices() { return &_devices; }
AudioDevices _devices;
bool _contextIsHMD { false };
};
};

View file

@ -10,6 +10,8 @@
//
#include "AudioDevices.h"
#include "Application.h"
#include "AudioClient.h"
using namespace scripting;
@ -75,40 +77,46 @@ bool AudioDeviceList::setData(const QModelIndex& index, const QVariant &value, i
if (success) {
device.selected = true;
emit dataChanged(index, index, { Qt::CheckStateRole });
emit deviceChanged();
}
}
}
emit dataChanged(createIndex(0, 0), createIndex(rowCount() - 1, 0));
return success;
}
void AudioDeviceList::setDevice(const QAudioDeviceInfo& device) {
_selectedDevice = device;
QModelIndex index;
for (auto i = 0; i < _devices.size(); ++i) {
AudioDevice& device = _devices[i];
if (device.selected && device.info != _selectedDevice) {
device.selected = false;
auto index = createIndex(i , 0);
emit dataChanged(index, index, { Qt::CheckStateRole });
} else if (!device.selected && device.info == _selectedDevice) {
} else if (device.info == _selectedDevice) {
device.selected = true;
auto index = createIndex(i , 0);
emit dataChanged(index, index, { Qt::CheckStateRole });
index = createIndex(i, 0);
}
}
emit deviceChanged();
emit dataChanged(createIndex(0, 0), createIndex(rowCount() - 1, 0));
}
void AudioDeviceList::populate(const QList<QAudioDeviceInfo>& devices) {
beginResetModel();
_devices.clear();
_selectedDeviceIndex = QModelIndex();
foreach(const QAudioDeviceInfo& deviceInfo, devices) {
AudioDevice device;
device.info = deviceInfo;
device.name = device.info.deviceName();
device.name = device.info.deviceName()
.replace("High Definition", "HD")
.remove("Device");
device.selected = (device.info == _selectedDevice);
_devices.push_back(device);
}
@ -129,6 +137,10 @@ AudioDevices::AudioDevices() {
_outputs.populate(client->getAudioDevices(QAudio::AudioOutput));
}
void AudioDevices::restoreDevices(bool isHMD) {
// TODO
}
void AudioDevices::onDeviceChanged(QAudio::Mode mode, const QAudioDeviceInfo& device) {
if (mode == QAudio::AudioInput) {
_inputs.setDevice(device);
@ -138,9 +150,22 @@ void AudioDevices::onDeviceChanged(QAudio::Mode mode, const QAudioDeviceInfo& de
}
void AudioDevices::onDevicesChanged(QAudio::Mode mode, const QList<QAudioDeviceInfo>& devices) {
static bool initialized { false };
auto initialize = [&]{
if (initialized) {
restoreDevices(qApp->isHMDMode());
} else {
initialized = true;
}
};
if (mode == QAudio::AudioInput) {
_inputs.populate(devices);
static std::once_flag inputFlag;
std::call_once(inputFlag, initialize);
} else { // if (mode == QAudio::AudioOutput)
_outputs.populate(devices);
static std::once_flag outputFlag;
std::call_once(outputFlag, initialize);
}
}

View file

@ -31,7 +31,7 @@ class AudioDeviceList : public QAbstractListModel {
public:
AudioDeviceList(QAudio::Mode mode);
int rowCount(const QModelIndex& parent) const override;
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
QVariant data(const QModelIndex& index, int role) const override;
QHash<int, QByteArray> roleNames() const override;
Qt::ItemFlags flags(const QModelIndex& index) const override;
@ -40,12 +40,16 @@ public:
void setDevice(const QAudioDeviceInfo& device);
void populate(const QList<QAudioDeviceInfo>& devices);
signals:
void deviceChanged();
private:
static QHash<int, QByteArray> _roles;
static Qt::ItemFlags _flags;
QAudio::Mode _mode;
QAudioDeviceInfo _selectedDevice;
QModelIndex _selectedDeviceIndex;
QList<AudioDevice> _devices;
};
@ -56,6 +60,7 @@ class AudioDevices : public QObject {
public:
AudioDevices();
void restoreDevices(bool isHMD);
signals:
void nop();
@ -65,6 +70,8 @@ private slots:
void onDevicesChanged(QAudio::Mode mode, const QList<QAudioDeviceInfo>& devices);
private:
friend class Audio;
AudioDeviceList* getInputList() { return &_inputs; }
AudioDeviceList* getOutputList() { return &_outputs; }

View file

@ -43,16 +43,6 @@ AvatarInputs::AvatarInputs(QQuickItem* parent) : QQuickItem(parent) {
} \
}
#define AI_UPDATE_WRITABLE(name, src) \
{ \
auto val = src; \
if (_##name != val) { \
_##name = val; \
qDebug() << "AvatarInputs" << val; \
emit name##Changed(val); \
} \
}
#define AI_UPDATE_FLOAT(name, src, epsilon) \
{ \
float val = src; \
@ -94,8 +84,6 @@ void AvatarInputs::update() {
AI_UPDATE(cameraMuted, Menu::getInstance()->isOptionChecked(MenuOption::MuteFaceTracking));
AI_UPDATE(isHMD, qApp->isHMDMode());
AI_UPDATE_WRITABLE(showAudioTools, Menu::getInstance()->isOptionChecked(MenuOption::AudioTools));
auto audioIO = DependencyManager::get<AudioClient>();
const float audioLevel = loudnessToAudioLevel(DependencyManager::get<AudioClient>()->getLastInputLoudness());
@ -122,8 +110,8 @@ void AvatarInputs::setShowAudioTools(bool showAudioTools) {
if (_showAudioTools == showAudioTools)
return;
Menu::getInstance()->setIsOptionChecked(MenuOption::AudioTools, showAudioTools);
update();
_showAudioTools = showAudioTools;
emit showAudioToolsChanged(_showAudioTools);
}
void AvatarInputs::toggleCameraMute() {

View file

@ -49,7 +49,7 @@ signals:
void audioClippingChanged();
void audioLevelChanged();
void isHMDChanged();
void showAudioToolsChanged(bool showAudioTools);
void showAudioToolsChanged(bool);
protected:
Q_INVOKABLE void resetSensors();

View file

@ -122,8 +122,6 @@ public:
float getTimeSinceLastClip() const { return _timeSinceLastClip; }
float getAudioAverageInputLoudness() const { return _lastInputLoudness; }
bool isMuted() { return _muted; }
const AudioIOStats& getStats() const { return _stats; }
int getOutputBufferSize() { return _outputBufferSizeFrames.get(); }
@ -172,11 +170,14 @@ public slots:
void handleRecordedAudioInput(const QByteArray& audio);
void reset();
void audioMixerKilled();
void toggleMute();
bool isMuted() { return _muted; }
virtual void setIsStereoInput(bool stereo) override;
void toggleAudioNoiseReduction() { _isNoiseGateEnabled = !_isNoiseGateEnabled; }
void setNoiseReduction(bool isNoiseGateEnabled) { _isNoiseGateEnabled = isNoiseGateEnabled; }
void toggleLocalEcho() { _shouldEchoLocally = !_shouldEchoLocally; }
void toggleServerEcho() { _shouldEchoToServer = !_shouldEchoToServer; }

View file

@ -527,6 +527,7 @@ QObject* OffscreenQmlSurface::load(const QUrl& qmlSource, std::function<void(QQm
// Synchronous loading may take a while; restart the deadlock timer
QMetaObject::invokeMethod(qApp, "updateHeartbeat", Qt::DirectConnection);
qDebug() << qmlSource;
_qmlComponent->loadUrl(qmlSource, QQmlComponent::PreferSynchronous);
if (_qmlComponent->isLoading()) {

View file

@ -46,7 +46,7 @@ function onClicked() {
Entities.editEntity(entity, { textures: JSON.stringify({ "tex.close": HOME_BUTTON_TEXTURE }) });
shouldActivateButton = true;
shouldActivateButton = true;
tablet.loadQMLSource("../Audio.qml");
tablet.loadQMLSource("../audio/Audio.qml");
onAudioScreen = true;
}
}