mirror of
https://github.com/lubosz/overte.git
synced 2025-04-23 13:33:38 +02:00
Merge branch 'atp' of https://github.com/birarda/hifi into protocol
This commit is contained in:
commit
9889dcdd64
7 changed files with 126 additions and 163 deletions
|
@ -94,7 +94,7 @@ void OctreeInboundPacketProcessor::processPacket(const SharedNodePointer& sendin
|
|||
if (_myServer->getOctree()->handlesEditPacketType(packetType)) {
|
||||
PerformanceWarning warn(debugProcessPacket, "processPacket KNOWN TYPE",debugProcessPacket);
|
||||
_receivedPacketCount++;
|
||||
|
||||
|
||||
const unsigned char* packetData = reinterpret_cast<const unsigned char*>(packet.data());
|
||||
|
||||
unsigned short int sequence = (*((unsigned short int*)(packetData + numBytesPacketHeader)));
|
||||
|
@ -120,16 +120,16 @@ void OctreeInboundPacketProcessor::processPacket(const SharedNodePointer& sendin
|
|||
qDebug() << " arrivedAt=" << arrivedAt << " usecs";
|
||||
qDebug() << " transitTime=" << transitTime << " usecs";
|
||||
qDebug() << " sendingNode->getClockSkewUsec()=" << sendingNode->getClockSkewUsec() << " usecs";
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (debugProcessPacket) {
|
||||
qDebug() << " numBytesPacketHeader=" << numBytesPacketHeader;
|
||||
qDebug() << " sizeof(sequence)=" << sizeof(sequence);
|
||||
qDebug() << " sizeof(sentAt)=" << sizeof(sentAt);
|
||||
}
|
||||
|
||||
|
||||
int atByte = numBytesPacketHeader + sizeof(sequence) + sizeof(sentAt);
|
||||
|
||||
if (debugProcessPacket) {
|
||||
|
@ -139,11 +139,11 @@ void OctreeInboundPacketProcessor::processPacket(const SharedNodePointer& sendin
|
|||
qDebug() << " ----- UNEXPECTED ---- got a packet without any edit details!!!! --------";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned char* editData = (unsigned char*)&packetData[atByte];
|
||||
while (atByte < packet.size()) {
|
||||
|
||||
|
||||
int maxSize = packet.size() - atByte;
|
||||
|
||||
if (debugProcessPacket) {
|
||||
|
@ -242,8 +242,8 @@ int OctreeInboundPacketProcessor::sendNackPackets() {
|
|||
return packetsSent;
|
||||
}
|
||||
|
||||
char packet[MAX_PACKET_SIZE];
|
||||
|
||||
auto nackPacket { NLPacket::create(_myServer->getMyEditNackType(); }
|
||||
|
||||
NodeToSenderStatsMapIterator i = _singleSenderStats.begin();
|
||||
while (i != _singleSenderStats.end()) {
|
||||
|
||||
|
@ -268,44 +268,36 @@ int OctreeInboundPacketProcessor::sendNackPackets() {
|
|||
// retrieve sequence number stats of node, prune its missing set
|
||||
SequenceNumberStats& sequenceNumberStats = nodeStats.getIncomingEditSequenceNumberStats();
|
||||
sequenceNumberStats.pruneMissingSet();
|
||||
|
||||
|
||||
// construct nack packet(s) for this node
|
||||
const QSet<unsigned short int>& missingSequenceNumbers = sequenceNumberStats.getMissingSet();
|
||||
int numSequenceNumbersAvailable = missingSequenceNumbers.size();
|
||||
QSet<unsigned short int>::const_iterator missingSequenceNumberIterator = missingSequenceNumbers.constBegin();
|
||||
while (numSequenceNumbersAvailable > 0) {
|
||||
|
||||
char* dataAt = packet;
|
||||
int bytesRemaining = MAX_PACKET_SIZE;
|
||||
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
|
||||
// pack header
|
||||
int numBytesPacketHeader = nodeList->populatePacketHeader(packet, _myServer->getMyEditNackType());
|
||||
dataAt += numBytesPacketHeader;
|
||||
bytesRemaining -= numBytesPacketHeader;
|
||||
nackPacket->reset();
|
||||
|
||||
// calculate and pack the number of sequence numbers to nack
|
||||
int numSequenceNumbersRoomFor = (bytesRemaining - sizeof(uint16_t)) / sizeof(unsigned short int);
|
||||
int numSequenceNumbersRoomFor = (nackPacket->getCapacity() - sizeof(uint16_t)) / sizeof(unsigned short int);
|
||||
uint16_t numSequenceNumbers = std::min(numSequenceNumbersAvailable, numSequenceNumbersRoomFor);
|
||||
uint16_t* numSequenceNumbersAt = (uint16_t*)dataAt;
|
||||
*numSequenceNumbersAt = numSequenceNumbers;
|
||||
dataAt += sizeof(uint16_t);
|
||||
|
||||
nackPacket->write(&numSequenceNumbers, sizeof(numSequenceNumbers));
|
||||
|
||||
// pack sequence numbers to nack
|
||||
for (uint16_t i = 0; i < numSequenceNumbers; i++) {
|
||||
unsigned short int* sequenceNumberAt = (unsigned short int*)dataAt;
|
||||
*sequenceNumberAt = *missingSequenceNumberIterator;
|
||||
dataAt += sizeof(unsigned short int);
|
||||
unsigned short int sequenceNumber = *missingSequenceNumberIterator;
|
||||
nackPacket->write(&sequenceNumber, sizeof(sequenceNumber));
|
||||
|
||||
missingSequenceNumberIterator++;
|
||||
}
|
||||
numSequenceNumbersAvailable -= numSequenceNumbers;
|
||||
|
||||
// send it
|
||||
nodeList->writeUnverifiedDatagram(packet, dataAt - packet, destinationNode);
|
||||
nodeList->sendUnreliablePacket(nackPacket, destinationNode);
|
||||
packetsSent++;
|
||||
|
||||
|
||||
qDebug() << "NACK Sent back to editor/client... destinationNode=" << nodeUUID;
|
||||
}
|
||||
i++;
|
||||
|
|
|
@ -127,18 +127,13 @@ SharedNetworkPeer IceServer::addOrUpdateHeartbeatingPeer(const QByteArray& incom
|
|||
}
|
||||
|
||||
void IceServer::sendPeerInformationPacket(const NetworkPeer& peer, const HifiSockAddr* destinationSockAddr) {
|
||||
QByteArray outgoingPacket(MAX_PACKET_SIZE, 0);
|
||||
int currentPacketSize = populatePacketHeaderWithUUID(outgoingPacket, PacketTypeIceServerPeerInformation, _id);
|
||||
int numHeaderBytes = currentPacketSize;
|
||||
auto peerPacket { NLPacket::create(PacketType::IceServerPeerInformation); }
|
||||
|
||||
// get the byte array for this peer
|
||||
QByteArray peerBytes = peer.toByteArray();
|
||||
outgoingPacket.replace(numHeaderBytes, peerBytes.size(), peerBytes);
|
||||
|
||||
currentPacketSize += peerBytes.size();
|
||||
peerPacket->write(peer.toByteArray());
|
||||
|
||||
// write the current packet
|
||||
_serverSocket.writeDatagram(outgoingPacket.data(), outgoingPacket.size(),
|
||||
_serverSocket.writeDatagram(peerPacket.constData(), peerPacket.sizeUsed(),
|
||||
destinationSockAddr->getAddress(), destinationSockAddr->getPort());
|
||||
}
|
||||
|
||||
|
|
|
@ -378,7 +378,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
|||
_runningScriptsWidget = new RunningScriptsWidget(_window);
|
||||
_renderEngine->addTask(render::TaskPointer(new RenderDeferredTask()));
|
||||
_renderEngine->registerScene(_main3DScene);
|
||||
|
||||
|
||||
// start the nodeThread so its event loop is running
|
||||
QThread* nodeThread = new QThread(this);
|
||||
nodeThread->setObjectName("Datagram Processor Thread");
|
||||
|
@ -537,7 +537,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
|||
// the GL surface
|
||||
_glWidget->setCursor(Qt::BlankCursor);
|
||||
#endif
|
||||
|
||||
|
||||
// enable mouse tracking; otherwise, we only get drag events
|
||||
_glWidget->setMouseTracking(true);
|
||||
|
||||
|
@ -606,7 +606,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
|||
_settingsTimer.setSingleShot(false);
|
||||
_settingsTimer.setInterval(SAVE_SETTINGS_INTERVAL);
|
||||
_settingsThread.start();
|
||||
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::IndependentMode)) {
|
||||
Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, true);
|
||||
cameraMenuChanged();
|
||||
|
@ -637,7 +637,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
|||
ddeTracker->init();
|
||||
connect(ddeTracker.data(), &FaceTracker::muteToggled, this, &Application::faceTrackerMuteToggled);
|
||||
#endif
|
||||
|
||||
|
||||
auto applicationUpdater = DependencyManager::get<AutoUpdater>();
|
||||
connect(applicationUpdater.data(), &AutoUpdater::newVersionIsAvailable, dialogsManager.data(), &DialogsManager::showUpdateDialog);
|
||||
applicationUpdater->checkForUpdate();
|
||||
|
@ -879,7 +879,7 @@ void Application::paintGL() {
|
|||
OculusManager::beginFrameTiming();
|
||||
}
|
||||
|
||||
|
||||
|
||||
PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings));
|
||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||
PerformanceWarning warn(showWarnings, "Application::paintGL()");
|
||||
|
@ -897,7 +897,7 @@ void Application::paintGL() {
|
|||
}
|
||||
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
|
||||
|
||||
if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON || _myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
|
||||
Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, _myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN);
|
||||
Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, !(_myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN));
|
||||
|
@ -982,7 +982,7 @@ void Application::paintGL() {
|
|||
|
||||
renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE;
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) {
|
||||
renderRearViewMirror(&renderArgs, _mirrorViewRect);
|
||||
renderRearViewMirror(&renderArgs, _mirrorViewRect);
|
||||
}
|
||||
|
||||
renderArgs._renderMode = RenderArgs::NORMAL_RENDER_MODE;
|
||||
|
@ -1756,9 +1756,9 @@ bool Application::acceptSnapshot(const QString& urlString) {
|
|||
}
|
||||
|
||||
void Application::sendPingPackets() {
|
||||
|
||||
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
|
||||
|
||||
nodeList->eachMatchingNode([](const SharedNodePointer& node)->bool {
|
||||
switch (node->getType()) {
|
||||
case NodeType::AvatarMixer:
|
||||
|
@ -1855,7 +1855,7 @@ void Application::idle() {
|
|||
// After finishing all of the above work, ensure the idle timer is set to the proper interval,
|
||||
// depending on whether we're throttling or not
|
||||
idleTimer->start(_glWidget->isThrottleRendering() ? THROTTLED_IDLE_TIMER_DELAY : 0);
|
||||
}
|
||||
}
|
||||
|
||||
// check for any requested background downloads.
|
||||
emit checkBackgroundDownloads();
|
||||
|
@ -2661,7 +2661,8 @@ int Application::sendNackPackets() {
|
|||
}
|
||||
|
||||
int packetsSent = 0;
|
||||
char packet[MAX_PACKET_SIZE];
|
||||
|
||||
auto nackPacket { NLPacket::create(PacketType::OctreeDataNack); }
|
||||
|
||||
// iterates thru all nodes in NodeList
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
|
@ -2698,33 +2699,26 @@ int Application::sendNackPackets() {
|
|||
QSet<OCTREE_PACKET_SEQUENCE>::const_iterator missingSequenceNumbersIterator = missingSequenceNumbers.constBegin();
|
||||
while (numSequenceNumbersAvailable > 0) {
|
||||
|
||||
char* dataAt = packet;
|
||||
int bytesRemaining = MAX_PACKET_SIZE;
|
||||
|
||||
// pack header
|
||||
int numBytesPacketHeader = nodeList->populatePacketHeader(packet, PacketTypeOctreeDataNack);
|
||||
dataAt += numBytesPacketHeader;
|
||||
bytesRemaining -= numBytesPacketHeader;
|
||||
// reset the position we are writing at and the size we have used
|
||||
nackPacket->seek(0);
|
||||
nackPacket->setSizeUsed(0);
|
||||
|
||||
// calculate and pack the number of sequence numbers
|
||||
int numSequenceNumbersRoomFor = (bytesRemaining - sizeof(uint16_t)) / sizeof(OCTREE_PACKET_SEQUENCE);
|
||||
int numSequenceNumbersRoomFor = (nackPacket->size() - sizeof(uint16_t)) / sizeof(OCTREE_PACKET_SEQUENCE);
|
||||
uint16_t numSequenceNumbers = min(numSequenceNumbersAvailable, numSequenceNumbersRoomFor);
|
||||
uint16_t* numSequenceNumbersAt = (uint16_t*)dataAt;
|
||||
*numSequenceNumbersAt = numSequenceNumbers;
|
||||
dataAt += sizeof(uint16_t);
|
||||
|
||||
nackPacket->write(&numSequenceNumbers, sizeof(numSequenceNumbers));
|
||||
|
||||
// pack sequence numbers
|
||||
for (int i = 0; i < numSequenceNumbers; i++) {
|
||||
OCTREE_PACKET_SEQUENCE* sequenceNumberAt = (OCTREE_PACKET_SEQUENCE*)dataAt;
|
||||
*sequenceNumberAt = *missingSequenceNumbersIterator;
|
||||
dataAt += sizeof(OCTREE_PACKET_SEQUENCE);
|
||||
|
||||
OCTREE_PACKET_SEQUENCE missingNumber = *missingSequenceNumbersIterator;
|
||||
nackPacket->write(&missingNumber, sizeof(OCTREE_PACKET_SEQUENCE));
|
||||
missingSequenceNumbersIterator++;
|
||||
}
|
||||
numSequenceNumbersAvailable -= numSequenceNumbers;
|
||||
|
||||
// send it
|
||||
nodeList->writeUnverifiedDatagram(packet, dataAt - packet, node);
|
||||
// send the packet
|
||||
nodeList->sendUnreliablePacket(packet, node);
|
||||
packetsSent++;
|
||||
}
|
||||
}
|
||||
|
@ -2756,9 +2750,7 @@ void Application::queryOctree(NodeType_t serverType, PacketType::Value packetTyp
|
|||
_octreeQuery.setOctreeSizeScale(lodManager->getOctreeSizeScale());
|
||||
_octreeQuery.setBoundaryLevelAdjust(lodManager->getBoundaryLevelAdjust());
|
||||
|
||||
unsigned char queryPacket[MAX_PACKET_SIZE];
|
||||
|
||||
// Iterate all of the nodes, and get a count of how many voxel servers we have...
|
||||
// Iterate all of the nodes, and get a count of how many octree servers we have...
|
||||
int totalServers = 0;
|
||||
int inViewServers = 0;
|
||||
int unknownJurisdictionServers = 0;
|
||||
|
@ -2825,6 +2817,8 @@ void Application::queryOctree(NodeType_t serverType, PacketType::Value packetTyp
|
|||
qCDebug(interfaceapp, "perServerPPS: %d perUnknownServer: %d", perServerPPS, perUnknownServer);
|
||||
}
|
||||
|
||||
auto queryPacket { NLPacket::create(packetType); }
|
||||
|
||||
nodeList->eachNode([&](const SharedNodePointer& node){
|
||||
// only send to the NodeTypes that are serverType
|
||||
if (node->getActiveSocket() && node->getType() == serverType) {
|
||||
|
@ -2899,19 +2893,13 @@ void Application::queryOctree(NodeType_t serverType, PacketType::Value packetTyp
|
|||
} else {
|
||||
_octreeQuery.setMaxQueryPacketsPerSecond(0);
|
||||
}
|
||||
// set up the packet for sending...
|
||||
unsigned char* endOfQueryPacket = queryPacket;
|
||||
|
||||
// insert packet type/version and node UUID
|
||||
endOfQueryPacket += nodeList->populatePacketHeader(reinterpret_cast<char*>(endOfQueryPacket), packetType);
|
||||
|
||||
// encode the query data...
|
||||
endOfQueryPacket += _octreeQuery.getBroadcastData(endOfQueryPacket);
|
||||
|
||||
int packetLength = endOfQueryPacket - queryPacket;
|
||||
// encode the query data
|
||||
int packetSize = _octreeQuery.getBroadcastData(queryPacket.payload());
|
||||
queryPacket.setSizeUsed(packetSize);
|
||||
|
||||
// make sure we still have an active socket
|
||||
nodeList->writeUnverifiedDatagram(reinterpret_cast<const char*>(queryPacket), packetLength, node);
|
||||
nodeList->sendUnreliablePacket(queryPacket, node);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -3310,7 +3298,7 @@ namespace render {
|
|||
const float APPROXIMATE_DISTANCE_FROM_HORIZON = 0.1f;
|
||||
const float DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON = 0.2f;
|
||||
|
||||
glm::vec3 sunDirection = (args->_viewFrustum->getPosition()/*getAvatarPosition()*/ - closestData.getSunLocation())
|
||||
glm::vec3 sunDirection = (args->_viewFrustum->getPosition()/*getAvatarPosition()*/ - closestData.getSunLocation())
|
||||
/ closestData.getAtmosphereOuterRadius();
|
||||
float height = glm::distance(args->_viewFrustum->getPosition()/*theCamera.getPosition()*/, closestData.getAtmosphereCenter());
|
||||
if (height < closestData.getAtmosphereInnerRadius()) {
|
||||
|
@ -3318,20 +3306,20 @@ namespace render {
|
|||
alpha = 0.0f;
|
||||
|
||||
if (sunDirection.y > -APPROXIMATE_DISTANCE_FROM_HORIZON) {
|
||||
float directionY = glm::clamp(sunDirection.y,
|
||||
-APPROXIMATE_DISTANCE_FROM_HORIZON, APPROXIMATE_DISTANCE_FROM_HORIZON)
|
||||
float directionY = glm::clamp(sunDirection.y,
|
||||
-APPROXIMATE_DISTANCE_FROM_HORIZON, APPROXIMATE_DISTANCE_FROM_HORIZON)
|
||||
+ APPROXIMATE_DISTANCE_FROM_HORIZON;
|
||||
alpha = (directionY / DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON);
|
||||
}
|
||||
|
||||
|
||||
|
||||
} else if (height < closestData.getAtmosphereOuterRadius()) {
|
||||
alpha = (height - closestData.getAtmosphereInnerRadius()) /
|
||||
(closestData.getAtmosphereOuterRadius() - closestData.getAtmosphereInnerRadius());
|
||||
|
||||
if (sunDirection.y > -APPROXIMATE_DISTANCE_FROM_HORIZON) {
|
||||
float directionY = glm::clamp(sunDirection.y,
|
||||
-APPROXIMATE_DISTANCE_FROM_HORIZON, APPROXIMATE_DISTANCE_FROM_HORIZON)
|
||||
float directionY = glm::clamp(sunDirection.y,
|
||||
-APPROXIMATE_DISTANCE_FROM_HORIZON, APPROXIMATE_DISTANCE_FROM_HORIZON)
|
||||
+ APPROXIMATE_DISTANCE_FROM_HORIZON;
|
||||
alpha = (directionY / DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON);
|
||||
}
|
||||
|
@ -3358,7 +3346,7 @@ namespace render {
|
|||
}
|
||||
} else if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_BOX) {
|
||||
PerformanceTimer perfTimer("skybox");
|
||||
|
||||
|
||||
skybox = skyStage->getSkybox();
|
||||
if (skybox) {
|
||||
model::Skybox::render(batch, *(Application::getInstance()->getDisplayViewFrustum()), *skybox);
|
||||
|
@ -3465,7 +3453,7 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
|||
|
||||
glEnable(GL_LIGHTING);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
|
||||
// Assuming nothing get's rendered through that
|
||||
|
||||
if (!selfAvatarOnly) {
|
||||
|
@ -3508,8 +3496,8 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
|||
pendingChanges.resetItem(WorldBoxRenderData::_item, worldBoxRenderPayload);
|
||||
} else {
|
||||
|
||||
pendingChanges.updateItem<WorldBoxRenderData>(WorldBoxRenderData::_item,
|
||||
[](WorldBoxRenderData& payload) {
|
||||
pendingChanges.updateItem<WorldBoxRenderData>(WorldBoxRenderData::_item,
|
||||
[](WorldBoxRenderData& payload) {
|
||||
payload._val++;
|
||||
});
|
||||
}
|
||||
|
@ -3528,7 +3516,7 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
|||
}
|
||||
|
||||
{
|
||||
PerformanceTimer perfTimer("SceneProcessPendingChanges");
|
||||
PerformanceTimer perfTimer("SceneProcessPendingChanges");
|
||||
_main3DScene->enqueuePendingChanges(pendingChanges);
|
||||
|
||||
_main3DScene->processPendingChangesQueue();
|
||||
|
@ -3560,7 +3548,7 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
|||
|
||||
// Before the deferred pass, let's try to use the render engine
|
||||
_renderEngine->run();
|
||||
|
||||
|
||||
auto engineRC = _renderEngine->getRenderContext();
|
||||
sceneInterface->setEngineFeedOpaqueItems(engineRC->_numFeedOpaqueItems);
|
||||
sceneInterface->setEngineDrawnOpaqueItems(engineRC->_numDrawnOpaqueItems);
|
||||
|
@ -4835,8 +4823,8 @@ qreal Application::getDevicePixelRatio() {
|
|||
mat4 Application::getEyeProjection(int eye) const {
|
||||
if (isHMDMode()) {
|
||||
return OculusManager::getEyeProjection(eye);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return _viewFrustum.getProjection();
|
||||
}
|
||||
|
||||
|
|
|
@ -724,20 +724,18 @@ void AudioClient::handleLocalEchoAndReverb(QByteArray& inputByteArray) {
|
|||
}
|
||||
|
||||
void AudioClient::handleAudioInput() {
|
||||
static char audioDataPacket[MAX_PACKET_SIZE];
|
||||
|
||||
static int numBytesPacketHeader = numBytesForPacketHeaderGivenPacketType(PacketTypeMicrophoneAudioNoEcho);
|
||||
|
||||
// NOTE: we assume PacketTypeMicrophoneAudioWithEcho has same size headers as
|
||||
// PacketTypeMicrophoneAudioNoEcho. If not, then networkAudioSamples will be pointing to the wrong place for writing
|
||||
// audio samples with echo.
|
||||
static int leadingBytes = numBytesPacketHeader + sizeof(quint16) + sizeof(glm::vec3) + sizeof(glm::quat) + sizeof(quint8);
|
||||
static int16_t* networkAudioSamples = (int16_t*)(audioDataPacket + leadingBytes);
|
||||
if (!_audioPacket) {
|
||||
// we don't have an audioPacket yet - set that up now
|
||||
_audioPacket = NLPacket::create(PacketType::MicrophoneAudioNoEcho);
|
||||
}
|
||||
|
||||
float inputToNetworkInputRatio = calculateDeviceToNetworkInputRatio();
|
||||
|
||||
int inputSamplesRequired = (int)((float)AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * inputToNetworkInputRatio);
|
||||
|
||||
static int leadingBytes = sizeof(quint16) + sizeof(glm::vec3) + sizeof(glm::quat) + sizeof(quint8);
|
||||
int16_t* networkAudioSamples = (int16_t*)(_audioPacket->payload() + leadingBytes);
|
||||
|
||||
QByteArray inputByteArray = _inputDevice->readAll();
|
||||
|
||||
// Add audio source injection if enabled
|
||||
|
@ -769,7 +767,7 @@ void AudioClient::handleAudioInput() {
|
|||
while (_inputRingBuffer.samplesAvailable() >= inputSamplesRequired) {
|
||||
|
||||
const int numNetworkBytes = _isStereoInput
|
||||
? AudioConstants::NETWORK_FRAME_BYTES_STEREO
|
||||
? AudioConstants::NETWORK_FRAME_BYTES_STEREO`
|
||||
: AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL;
|
||||
const int numNetworkSamples = _isStereoInput
|
||||
? AudioConstants::NETWORK_FRAME_SAMPLES_STEREO
|
||||
|
@ -846,57 +844,49 @@ void AudioClient::handleAudioInput() {
|
|||
|
||||
PacketType::Value packetType;
|
||||
if (_lastInputLoudness == 0) {
|
||||
packetType = PacketTypeSilentAudioFrame;
|
||||
_audioPacket->setType(PacketType::SilentAudioFrame);
|
||||
} else {
|
||||
if (_shouldEchoToServer) {
|
||||
packetType = PacketTypeMicrophoneAudioWithEcho;
|
||||
_audioPacket->setType(PacketType::MicrophoneAudioWithEcho);
|
||||
} else {
|
||||
packetType = PacketTypeMicrophoneAudioNoEcho;
|
||||
_audioPacket->setType(PacketType::MicrophoneAudioNoEcho);
|
||||
}
|
||||
}
|
||||
|
||||
char* currentPacketPtr = audioDataPacket + nodeList->populatePacketHeader(audioDataPacket, packetType);
|
||||
// seek to the beginning of the audio packet payload
|
||||
_audioPacket->seek(0);
|
||||
|
||||
// pack sequence number
|
||||
memcpy(currentPacketPtr, &_outgoingAvatarAudioSequenceNumber, sizeof(quint16));
|
||||
currentPacketPtr += sizeof(quint16);
|
||||
// reset the size used in this packet so it will be correct once we are done writing
|
||||
_audioPacket->setSizeUsed(0);
|
||||
|
||||
if (packetType == PacketTypeSilentAudioFrame) {
|
||||
// write sequence number
|
||||
_audioPacket->write(&_outgoingAvatarAudioSequenceNumber, sizeof(quint16));
|
||||
|
||||
if (packetType == PacketType::SilentAudioFrame) {
|
||||
// pack num silent samples
|
||||
quint16 numSilentSamples = numNetworkSamples;
|
||||
memcpy(currentPacketPtr, &numSilentSamples, sizeof(quint16));
|
||||
currentPacketPtr += sizeof(quint16);
|
||||
|
||||
// memcpy the three float positions
|
||||
memcpy(currentPacketPtr, &headPosition, sizeof(headPosition));
|
||||
currentPacketPtr += (sizeof(headPosition));
|
||||
|
||||
// memcpy our orientation
|
||||
memcpy(currentPacketPtr, &headOrientation, sizeof(headOrientation));
|
||||
currentPacketPtr += sizeof(headOrientation);
|
||||
|
||||
_audioPacket->write(&numSilentSamples, sizeof(quint16));
|
||||
} else {
|
||||
// set the mono/stereo byte
|
||||
*currentPacketPtr++ = isStereo;
|
||||
_audioPacket->write(&isStereo, sizeof(isStereo));
|
||||
}
|
||||
|
||||
// memcpy the three float positions
|
||||
memcpy(currentPacketPtr, &headPosition, sizeof(headPosition));
|
||||
currentPacketPtr += (sizeof(headPosition));
|
||||
// pack the three float positions
|
||||
_audioPacket->write(&headPosition, sizeof(headPosition));
|
||||
|
||||
// memcpy our orientation
|
||||
memcpy(currentPacketPtr, &headOrientation, sizeof(headOrientation));
|
||||
currentPacketPtr += sizeof(headOrientation);
|
||||
// pack the orientation
|
||||
_audioPacket->write(&headOrientation, sizeof(headOrientation));
|
||||
|
||||
if (packetType != PacketType::SilentAudioFrame) {
|
||||
// audio samples have already been packed (written to networkAudioSamples)
|
||||
currentPacketPtr += numNetworkBytes;
|
||||
_audioPacket->setSizeUsed(_audioPacket->getSizeUsed() + numNetworkBytes);
|
||||
}
|
||||
|
||||
_stats.sentPacket();
|
||||
|
||||
nodeList->flagTimeForConnectionStep(LimitedNodeList::ConnectionStep::SendAudioPacket);
|
||||
|
||||
int packetBytes = currentPacketPtr - audioDataPacket;
|
||||
nodeList->writeDatagram(audioDataPacket, packetBytes, audioMixer);
|
||||
nodeList->sendUnreliablePacket(_audioPacket, audioMixer);
|
||||
|
||||
_outgoingAvatarAudioSequenceNumber++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -308,6 +308,8 @@ private:
|
|||
void checkDevices();
|
||||
|
||||
bool _hasReceivedFirstPacket = false;
|
||||
|
||||
std::unique_ptr<NLPacket> _audioPacket;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ AudioIOStats::AudioIOStats(MixedProcessedAudioStream* receivedAudioStream) :
|
|||
_lastSentAudioPacket(0),
|
||||
_packetSentTimeGaps(1, APPROXIMATELY_30_SECONDS_OF_AUDIO_PACKETS)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
AudioStreamStats AudioIOStats::getMixerDownstreamStats() const {
|
||||
|
@ -40,13 +40,13 @@ AudioStreamStats AudioIOStats::getMixerDownstreamStats() const {
|
|||
|
||||
void AudioIOStats::reset() {
|
||||
_receivedAudioStream->resetStats();
|
||||
|
||||
|
||||
_mixerAvatarStreamStats = AudioStreamStats();
|
||||
_mixerInjectedStreamStatsMap.clear();
|
||||
|
||||
|
||||
_audioInputMsecsReadStats.reset();
|
||||
_inputRingBufferMsecsAvailableStats.reset();
|
||||
|
||||
|
||||
_audioOutputMsecsUnplayedStats.reset();
|
||||
_packetSentTimeGaps.reset();
|
||||
}
|
||||
|
@ -59,32 +59,32 @@ void AudioIOStats::sentPacket() {
|
|||
quint64 now = usecTimestampNow();
|
||||
quint64 gap = now - _lastSentAudioPacket;
|
||||
_packetSentTimeGaps.update(gap);
|
||||
|
||||
|
||||
_lastSentAudioPacket = now;
|
||||
}
|
||||
}
|
||||
void AudioIOStats::parseAudioStreamStatsPacket(const QByteArray& packet) {
|
||||
|
||||
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(packet);
|
||||
const char* dataAt = packet.constData() + numBytesPacketHeader;
|
||||
|
||||
|
||||
// parse the appendFlag, clear injected audio stream stats if 0
|
||||
quint8 appendFlag = *(reinterpret_cast<const quint16*>(dataAt));
|
||||
dataAt += sizeof(quint8);
|
||||
if (!appendFlag) {
|
||||
_mixerInjectedStreamStatsMap.clear();
|
||||
}
|
||||
|
||||
|
||||
// parse the number of stream stats structs to follow
|
||||
quint16 numStreamStats = *(reinterpret_cast<const quint16*>(dataAt));
|
||||
dataAt += sizeof(quint16);
|
||||
|
||||
|
||||
// parse the stream stats
|
||||
AudioStreamStats streamStats;
|
||||
for (quint16 i = 0; i < numStreamStats; i++) {
|
||||
memcpy(&streamStats, dataAt, sizeof(AudioStreamStats));
|
||||
dataAt += sizeof(AudioStreamStats);
|
||||
|
||||
|
||||
if (streamStats._streamType == PositionalAudioStream::Microphone) {
|
||||
_mixerAvatarStreamStats = streamStats;
|
||||
} else {
|
||||
|
@ -94,40 +94,35 @@ void AudioIOStats::parseAudioStreamStatsPacket(const QByteArray& packet) {
|
|||
}
|
||||
|
||||
void AudioIOStats::sendDownstreamAudioStatsPacket() {
|
||||
|
||||
|
||||
auto audioIO = DependencyManager::get<AudioClient>();
|
||||
|
||||
|
||||
// since this function is called every second, we'll sample for some of our stats here
|
||||
_inputRingBufferMsecsAvailableStats.update(audioIO->getInputRingBufferMsecsAvailable());
|
||||
_audioOutputMsecsUnplayedStats.update(audioIO->getAudioOutputMsecsUnplayed());
|
||||
|
||||
|
||||
// also, call _receivedAudioStream's per-second callback
|
||||
_receivedAudioStream->perSecondCallbackForUpdatingStats();
|
||||
|
||||
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
|
||||
char packet[MAX_PACKET_SIZE];
|
||||
|
||||
// pack header
|
||||
int numBytesPacketHeader = nodeList->populatePacketHeader(packet, PacketTypeAudioStreamStats);
|
||||
char* dataAt = packet + numBytesPacketHeader;
|
||||
|
||||
// pack append flag
|
||||
|
||||
quint8 appendFlag = 0;
|
||||
memcpy(dataAt, &appendFlag, sizeof(quint8));
|
||||
dataAt += sizeof(quint8);
|
||||
|
||||
// pack number of stats packed
|
||||
quint16 numStreamStatsToPack = 1;
|
||||
memcpy(dataAt, &numStreamStatsToPack, sizeof(quint16));
|
||||
dataAt += sizeof(quint16);
|
||||
|
||||
// pack downstream audio stream stats
|
||||
AudioStreamStats stats = _receivedAudioStream->getAudioStreamStats();
|
||||
memcpy(dataAt, &stats, sizeof(AudioStreamStats));
|
||||
dataAt += sizeof(AudioStreamStats);
|
||||
|
||||
|
||||
int statsPacketSize = sizeof(appendFlag) + sizeof(numStreamStatsToPack) + sizeof(stats);
|
||||
auto statsPacket { NLPacket::create(PacketType::AudioStreamStats, statsPacketSize); }
|
||||
|
||||
// pack append flag
|
||||
statsPacket->write(&appendFlag, sizeof(appendFlag));
|
||||
|
||||
// pack number of stats packed
|
||||
statsPacket->write(&numStreamStatsToPack, sizeof(numStreamStatsToPack));
|
||||
|
||||
// pack downstream audio stream stats
|
||||
statsPacket->write(&stats, sizeof(stats));
|
||||
|
||||
// send packet
|
||||
SharedNodePointer audioMixer = nodeList->soloNodeOfType(NodeType::AudioMixer);
|
||||
nodeList->writeDatagram(packet, dataAt - packet, audioMixer);
|
||||
nodeList->sendPacket(packet, audioMixer);
|
||||
}
|
||||
|
|
|
@ -552,6 +552,7 @@ int NodeList::processDomainServerList(const QByteArray& packet) {
|
|||
packetStream >> newUUID;
|
||||
setSessionUUID(newUUID);
|
||||
|
||||
// TODO: when fixing this read these are actually chars now, not bools
|
||||
bool thisNodeCanAdjustLocks;
|
||||
packetStream >> thisNodeCanAdjustLocks;
|
||||
setThisNodeCanAdjustLocks(thisNodeCanAdjustLocks);
|
||||
|
|
Loading…
Reference in a new issue