mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 18:44:00 +02:00
Merge branch 'tablet-ui' of github.com:highfidelity/hifi into tablet-imporove-dialogs
This commit is contained in:
commit
78da936344
23 changed files with 99 additions and 1304 deletions
|
@ -241,6 +241,7 @@ void AudioMixer::sendStatsPacket() {
|
|||
|
||||
statsObject["avg_streams_per_frame"] = (float)_stats.sumStreams / (float)_numStatFrames;
|
||||
statsObject["avg_listeners_per_frame"] = (float)_stats.sumListeners / (float)_numStatFrames;
|
||||
statsObject["avg_listeners_(silent)_per_frame"] = (float)_stats.sumListenersSilent / (float)_numStatFrames;
|
||||
|
||||
statsObject["silent_packets_per_frame"] = (float)_numSilentPackets / (float)_numStatFrames;
|
||||
|
||||
|
|
|
@ -106,6 +106,7 @@ void AudioMixerSlave::mix(const SharedNodePointer& node) {
|
|||
|
||||
sendMixPacket(node, *data, encodedBuffer);
|
||||
} else {
|
||||
++stats.sumListenersSilent;
|
||||
sendSilentPacket(node, *data);
|
||||
}
|
||||
|
||||
|
@ -221,17 +222,19 @@ bool AudioMixerSlave::prepareMix(const SharedNodePointer& listener) {
|
|||
stats.mixTime += mixTime.count();
|
||||
#endif
|
||||
|
||||
// use the per listener AudioLimiter to render the mixed data...
|
||||
listenerData->audioLimiter.render(_mixSamples, _bufferSamples, AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL);
|
||||
|
||||
// check for silent audio after the peak limiter has converted the samples
|
||||
// check for silent audio before limiting
|
||||
// limiting uses a dither and can only guarantee abs(sample) <= 1
|
||||
bool hasAudio = false;
|
||||
for (int i = 0; i < AudioConstants::NETWORK_FRAME_SAMPLES_STEREO; ++i) {
|
||||
if (_bufferSamples[i] != 0) {
|
||||
if (_mixSamples[i] != 0.0f) {
|
||||
hasAudio = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// use the per listener AudioLimiter to render the mixed data
|
||||
listenerData->audioLimiter.render(_mixSamples, _bufferSamples, AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL);
|
||||
|
||||
return hasAudio;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
void AudioMixerStats::reset() {
|
||||
sumStreams = 0;
|
||||
sumListeners = 0;
|
||||
sumListenersSilent = 0;
|
||||
totalMixes = 0;
|
||||
hrtfRenders = 0;
|
||||
hrtfSilentRenders = 0;
|
||||
|
@ -28,6 +29,7 @@ void AudioMixerStats::reset() {
|
|||
void AudioMixerStats::accumulate(const AudioMixerStats& otherStats) {
|
||||
sumStreams += otherStats.sumStreams;
|
||||
sumListeners += otherStats.sumListeners;
|
||||
sumListenersSilent += otherStats.sumListenersSilent;
|
||||
totalMixes += otherStats.totalMixes;
|
||||
hrtfRenders += otherStats.hrtfRenders;
|
||||
hrtfSilentRenders += otherStats.hrtfSilentRenders;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
struct AudioMixerStats {
|
||||
int sumStreams { 0 };
|
||||
int sumListeners { 0 };
|
||||
int sumListenersSilent { 0 };
|
||||
|
||||
int totalMixes { 0 };
|
||||
|
||||
|
|
|
@ -66,8 +66,6 @@ TabletModalWindow {
|
|||
signal canceled();
|
||||
|
||||
Component.onCompleted: {
|
||||
console.log("Helper " + helper + " drives " + drives);
|
||||
|
||||
fileDialogItem.keyboardEnabled = HMD.active;
|
||||
|
||||
// HACK: The following lines force the model to initialize properly such that the go-up button
|
||||
|
@ -459,6 +457,7 @@ TabletModalWindow {
|
|||
bottomMargin: hifi.dimensions.contentSpacing.y + currentSelection.controlHeight - currentSelection.height
|
||||
}
|
||||
headerVisible: !selectDirectory
|
||||
onClicked: navigateToRow(row);
|
||||
onDoubleClicked: navigateToRow(row);
|
||||
focus: true
|
||||
Keys.onReturnPressed: navigateToCurrentRow();
|
||||
|
|
|
@ -81,6 +81,10 @@ void HMDScriptingInterface::closeTablet() {
|
|||
_showTablet = false;
|
||||
}
|
||||
|
||||
void HMDScriptingInterface::openTablet() {
|
||||
_showTablet = true;
|
||||
}
|
||||
|
||||
QScriptValue HMDScriptingInterface::getHUDLookAtPosition2D(QScriptContext* context, QScriptEngine* engine) {
|
||||
glm::vec3 hudIntersection;
|
||||
auto instance = DependencyManager::get<HMDScriptingInterface>();
|
||||
|
|
|
@ -76,6 +76,8 @@ public:
|
|||
|
||||
Q_INVOKABLE void closeTablet();
|
||||
|
||||
Q_INVOKABLE void openTablet();
|
||||
|
||||
signals:
|
||||
bool shouldShowHandControllersChanged();
|
||||
|
||||
|
|
|
@ -1052,7 +1052,12 @@ void AudioClient::handleAudioInput() {
|
|||
auto packetType = _shouldEchoToServer ?
|
||||
PacketType::MicrophoneAudioWithEcho : PacketType::MicrophoneAudioNoEcho;
|
||||
|
||||
if (_lastInputLoudness == 0) {
|
||||
// if the _inputGate closed in this last frame, then we don't actually want
|
||||
// to send a silent packet, instead, we want to go ahead and encode and send
|
||||
// the output from the input gate (eventually, this could be crossfaded)
|
||||
// and allow the codec to properly encode down to silent/zero. If we still
|
||||
// have _lastInputLoudness of 0 in our NEXT frame, we will send a silent packet
|
||||
if (_lastInputLoudness == 0 && !_inputGate.closedInLastFrame()) {
|
||||
packetType = PacketType::SilentAudioFrame;
|
||||
}
|
||||
Transform audioTransform;
|
||||
|
|
|
@ -58,7 +58,6 @@ void AudioNoiseGate::removeDCOffset(int16_t* samples, int numSamples) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void AudioNoiseGate::gateSamples(int16_t* samples, int numSamples) {
|
||||
//
|
||||
// Impose Noise Gate
|
||||
|
@ -77,8 +76,7 @@ void AudioNoiseGate::gateSamples(int16_t* samples, int numSamples) {
|
|||
// NOISE_GATE_FRAMES_TO_AVERAGE: How many audio frames should we average together to compute noise floor.
|
||||
// More means better rejection but also can reject continuous things like singing.
|
||||
// NUMBER_OF_NOISE_SAMPLE_FRAMES: How often should we re-evaluate the noise floor?
|
||||
|
||||
|
||||
|
||||
float loudness = 0;
|
||||
int thisSample = 0;
|
||||
int samplesOverNoiseGate = 0;
|
||||
|
@ -142,11 +140,13 @@ void AudioNoiseGate::gateSamples(int16_t* samples, int numSamples) {
|
|||
_sampleCounter = 0;
|
||||
|
||||
}
|
||||
|
||||
if (samplesOverNoiseGate > NOISE_GATE_WIDTH) {
|
||||
_isOpen = true;
|
||||
_framesToClose = NOISE_GATE_CLOSE_FRAME_DELAY;
|
||||
} else {
|
||||
if (--_framesToClose == 0) {
|
||||
_closedInLastFrame = !_isOpen;
|
||||
_isOpen = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ public:
|
|||
void removeDCOffset(int16_t* samples, int numSamples);
|
||||
|
||||
bool clippedInLastFrame() const { return _didClipInLastFrame; }
|
||||
bool closedInLastFrame() const { return _closedInLastFrame; }
|
||||
float getMeasuredFloor() const { return _measuredFloor; }
|
||||
float getLastLoudness() const { return _lastLoudness; }
|
||||
|
||||
|
@ -40,6 +41,7 @@ private:
|
|||
float _sampleFrames[NUMBER_OF_NOISE_SAMPLE_FRAMES];
|
||||
int _sampleCounter;
|
||||
bool _isOpen;
|
||||
bool _closedInLastFrame { false };
|
||||
int _framesToClose;
|
||||
};
|
||||
|
||||
|
|
|
@ -136,9 +136,10 @@ int InboundAudioStream::parseData(ReceivedMessage& message) {
|
|||
break;
|
||||
}
|
||||
case SequenceNumberStats::Early: {
|
||||
// Packet is early; write droppable silent samples for each of the skipped packets.
|
||||
// NOTE: we assume that each dropped packet contains the same number of samples
|
||||
// as the packet we just received.
|
||||
// Packet is early. Treat the packets as if all the packets between the last
|
||||
// OnTime packet and this packet were lost. If we're using a codec this will
|
||||
// also result in allowing the codec to interpolate lost data. Then
|
||||
// fall through to the "on time" logic to actually handle this packet
|
||||
int packetsDropped = arrivalInfo._seqDiffFromExpected;
|
||||
lostAudioData(packetsDropped);
|
||||
|
||||
|
@ -147,7 +148,8 @@ int InboundAudioStream::parseData(ReceivedMessage& message) {
|
|||
case SequenceNumberStats::OnTime: {
|
||||
// Packet is on time; parse its data to the ringbuffer
|
||||
if (message.getType() == PacketType::SilentAudioFrame) {
|
||||
// FIXME - Some codecs need to know about these silent frames... and can produce better output
|
||||
// If we recieved a SilentAudioFrame from our sender, we might want to drop
|
||||
// some of the samples in order to catch up to our desired jitter buffer size.
|
||||
writeDroppableSilentFrames(networkFrames);
|
||||
} else {
|
||||
// note: PCM and no codec are identical
|
||||
|
@ -158,7 +160,12 @@ int InboundAudioStream::parseData(ReceivedMessage& message) {
|
|||
parseAudioData(message.getType(), afterProperties);
|
||||
} else {
|
||||
qDebug(audio) << "Codec mismatch: expected" << _selectedCodecName << "got" << codecInPacket << "writing silence";
|
||||
writeDroppableSilentFrames(networkFrames);
|
||||
|
||||
// Since the data in the stream is using a codec that we aren't prepared for,
|
||||
// we need to let the codec know that we don't have data for it, this will
|
||||
// allow the codec to interpolate missing data and produce a fade to silence.
|
||||
lostAudioData(1);
|
||||
|
||||
// inform others of the mismatch
|
||||
auto sendingNode = DependencyManager::get<NodeList>()->nodeWithUUID(message.getSourceID());
|
||||
emit mismatchedAudioCodec(sendingNode, _selectedCodecName, codecInPacket);
|
||||
|
@ -240,6 +247,25 @@ int InboundAudioStream::parseAudioData(PacketType type, const QByteArray& packet
|
|||
|
||||
int InboundAudioStream::writeDroppableSilentFrames(int silentFrames) {
|
||||
|
||||
// We can't guarentee that all clients have faded the stream down
|
||||
// to silence and encoded that silence before sending us a
|
||||
// SilentAudioFrame. If the encoder has truncated the stream it will
|
||||
// leave the decoder holding some unknown loud state. To handle this
|
||||
// case we will call the decoder's lostFrame() method, which indicates
|
||||
// that it should interpolate from its last known state down toward
|
||||
// silence.
|
||||
if (_decoder) {
|
||||
// FIXME - We could potentially use the output from the codec, in which
|
||||
// case we might get a cleaner fade toward silence. NOTE: The below logic
|
||||
// attempts to catch up in the event that the jitter buffers have grown.
|
||||
// The better long term fix is to use the output from the decode, detect
|
||||
// when it actually reaches silence, and then delete the silent portions
|
||||
// of the jitter buffers. Or petentially do a cross fade from the decode
|
||||
// output to silence.
|
||||
QByteArray decodedBuffer;
|
||||
_decoder->lostFrame(decodedBuffer);
|
||||
}
|
||||
|
||||
// calculate how many silent frames we should drop.
|
||||
int silentSamples = silentFrames * _numChannels;
|
||||
int samplesPerFrame = _ringBuffer.getNumFrameSamples();
|
||||
|
|
|
@ -434,6 +434,7 @@ void OffscreenQmlSurface::create(QOpenGLContext* shareContext) {
|
|||
auto rootContext = getRootContext();
|
||||
rootContext->setContextProperty("urlHandler", new UrlHandler());
|
||||
rootContext->setContextProperty("resourceDirectoryUrl", QUrl::fromLocalFile(PathUtils::resourcesPath()));
|
||||
rootContext->setContextProperty("pathToFonts", "../../");
|
||||
}
|
||||
|
||||
static uvec2 clampSize(const uvec2& size, uint32_t maxDimension) {
|
||||
|
|
|
@ -287,7 +287,8 @@ void TabletProxy::setQmlTabletRoot(QQuickItem* qmlTabletRoot, QObject* qmlOffscr
|
|||
QMetaObject::invokeMethod(_qmlTabletRoot, "loadSource", Q_ARG(const QVariant&, QVariant(TABLET_SOURCE_URL)));
|
||||
}
|
||||
|
||||
gotoHomeScreen();
|
||||
// force to the tablet to go to the homescreen
|
||||
loadHomeScreen(true);
|
||||
|
||||
QMetaObject::invokeMethod(_qmlTabletRoot, "setUsername", Q_ARG(const QVariant&, QVariant(getUsername())));
|
||||
|
||||
|
@ -305,6 +306,9 @@ void TabletProxy::setQmlTabletRoot(QQuickItem* qmlTabletRoot, QObject* qmlOffscr
|
|||
}
|
||||
}
|
||||
|
||||
void TabletProxy::gotoHomeScreen() {
|
||||
loadHomeScreen(false);
|
||||
}
|
||||
void TabletProxy::gotoMenuScreen(const QString& submenu) {
|
||||
|
||||
QObject* root = nullptr;
|
||||
|
@ -388,8 +392,8 @@ void TabletProxy::popFromStack() {
|
|||
}
|
||||
}
|
||||
|
||||
void TabletProxy::gotoHomeScreen() {
|
||||
if (_state != State::Home) {
|
||||
void TabletProxy::loadHomeScreen(bool forceOntoHomeScreen) {
|
||||
if (_state != State::Home && ( _state != State::Uninitialized || forceOntoHomeScreen)) {
|
||||
if (!_toolbarMode && _qmlTabletRoot) {
|
||||
auto loader = _qmlTabletRoot->findChild<QQuickItem*>("loader");
|
||||
QObject::connect(loader, SIGNAL(loaded()), this, SLOT(addButtonsToHomeScreen()), Qt::DirectConnection);
|
||||
|
|
|
@ -202,6 +202,7 @@ protected slots:
|
|||
void desktopWindowClosed();
|
||||
protected:
|
||||
void removeButtonsFromHomeScreen();
|
||||
void loadHomeScreen(bool forceOntoHomeScreen);
|
||||
void addButtonsToToolbar();
|
||||
void removeButtonsFromToolbar();
|
||||
|
||||
|
|
|
@ -72,6 +72,9 @@ tablet.screenChanged.connect(onScreenChanged);
|
|||
AudioDevice.muteToggled.connect(onMuteToggled);
|
||||
|
||||
Script.scriptEnding.connect(function () {
|
||||
if (onAudioScreen) {
|
||||
tablet.gotoHomeScreen();
|
||||
}
|
||||
button.clicked.disconnect(onClicked);
|
||||
tablet.screenChanged.disconnect(onScreenChanged);
|
||||
AudioDevice.muteToggled.disconnect(onMuteToggled);
|
||||
|
|
|
@ -18,13 +18,14 @@ var button;
|
|||
var buttonName = "GOTO";
|
||||
var toolBar = null;
|
||||
var tablet = null;
|
||||
|
||||
var onGotoScreen = false;
|
||||
function onAddressBarShown(visible) {
|
||||
button.editProperties({isActive: visible});
|
||||
}
|
||||
|
||||
function onClicked(){
|
||||
DialogsManager.toggleAddressBar();
|
||||
onGotoScreen = !onGotoScreen;
|
||||
}
|
||||
|
||||
if (Settings.getValue("HUDUIEnabled")) {
|
||||
|
@ -49,6 +50,9 @@ button.clicked.connect(onClicked);
|
|||
DialogsManager.addressBarShown.connect(onAddressBarShown);
|
||||
|
||||
Script.scriptEnding.connect(function () {
|
||||
if (onGotoScreen) {
|
||||
DialogsManager.toggleAddressBar();
|
||||
}
|
||||
button.clicked.disconnect(onClicked);
|
||||
if (tablet) {
|
||||
tablet.removeButton(button);
|
||||
|
|
|
@ -48,6 +48,9 @@
|
|||
}, POLL_RATE);
|
||||
|
||||
Script.scriptEnding.connect(function () {
|
||||
if (enabled) {
|
||||
Menu.closeInfoView('InfoView_html/help.html');
|
||||
}
|
||||
button.clicked.disconnect(onClicked);
|
||||
Script.clearInterval(interval);
|
||||
if (tablet) {
|
||||
|
|
|
@ -121,6 +121,7 @@ function onClick() {
|
|||
if (onMarketplaceScreen) {
|
||||
// for toolbar-mode: go back to home screen, this will close the window.
|
||||
tablet.gotoHomeScreen();
|
||||
onMarketplaceScreen = false;
|
||||
} else {
|
||||
var entity = HMD.tabletID;
|
||||
Entities.editEntity(entity, {textures: JSON.stringify({"tex.close": HOME_BUTTON_TEXTURE})});
|
||||
|
@ -140,6 +141,9 @@ tablet.screenChanged.connect(onScreenChanged);
|
|||
Entities.canWriteAssetsChanged.connect(onCanWriteAssetsChanged);
|
||||
|
||||
Script.scriptEnding.connect(function () {
|
||||
if (onMarketplaceScreen) {
|
||||
tablet.gotoHomeScreen();
|
||||
}
|
||||
tablet.removeButton(marketplaceButton);
|
||||
tablet.screenChanged.disconnect(onScreenChanged);
|
||||
Entities.canWriteAssetsChanged.disconnect(onCanWriteAssetsChanged);
|
||||
|
|
|
@ -48,6 +48,9 @@ var HOME_BUTTON_TEXTURE = "http://hifi-content.s3.amazonaws.com/alan/dev/tablet-
|
|||
tablet.screenChanged.connect(onScreenChanged);
|
||||
|
||||
Script.scriptEnding.connect(function () {
|
||||
if (onMenuScreen) {
|
||||
tablet.gotoHomeScreen();
|
||||
}
|
||||
button.clicked.disconnect(onClicked);
|
||||
tablet.removeButton(button);
|
||||
tablet.screenChanged.disconnect(onScreenChanged);
|
||||
|
|
|
@ -696,6 +696,9 @@ function clearLocalQMLDataAndClosePAL() {
|
|||
}
|
||||
|
||||
function shutdown() {
|
||||
if (onPalScreen) {
|
||||
tablet.gotoHomeScreen();
|
||||
}
|
||||
button.clicked.disconnect(onTabletButtonClicked);
|
||||
tablet.removeButton(button);
|
||||
tablet.screenChanged.disconnect(onTabletScreenChanged);
|
||||
|
|
|
@ -191,12 +191,12 @@ function resetButtons(pathStillSnapshot, pathAnimatedSnapshot, notify) {
|
|||
if (clearOverlayWhenMoving) {
|
||||
MyAvatar.setClearOverlayWhenMoving(true); // not until after the share dialog
|
||||
}
|
||||
HMD.openTablet();
|
||||
}
|
||||
|
||||
function processingGif() {
|
||||
// show hud
|
||||
Reticle.visible = reticleVisible;
|
||||
|
||||
button.clicked.disconnect(onClicked);
|
||||
buttonConnected = false;
|
||||
// show overlays if they were on
|
||||
|
@ -211,8 +211,10 @@ Window.snapshotShared.connect(snapshotShared);
|
|||
Window.processingGif.connect(processingGif);
|
||||
|
||||
Script.scriptEnding.connect(function () {
|
||||
button.clicked.disconnect(onClicked);
|
||||
buttonConnected = false;
|
||||
if (buttonConnected) {
|
||||
button.clicked.disconnect(onClicked);
|
||||
buttonConnected = false;
|
||||
}
|
||||
if (tablet) {
|
||||
tablet.removeButton(button);
|
||||
}
|
||||
|
|
|
@ -114,6 +114,9 @@
|
|||
tablet.screenChanged.connect(onScreenChanged);
|
||||
|
||||
function cleanup() {
|
||||
if (onUsersScreen) {
|
||||
tablet.gotoHomeScreen();
|
||||
}
|
||||
button.clicked.disconnect(onClicked);
|
||||
tablet.removeButton(button);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue