diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0d7b416fe0..e669a2a527 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -152,8 +152,8 @@ Application::Application(int& argc, char** argv) : _packetCount(0), _packetsPerSecond(0), _bytesPerSecond(0), - _bytesCount(0) { - + _bytesCount(0) +{ gettimeofday(&_applicationStartupTime, NULL); printLog("Interface Startup:\n"); @@ -169,7 +169,9 @@ Application::Application(int& argc, char** argv) : if (portStr) { listenPort = atoi(portStr); } + AgentList::createInstance(AGENT_TYPE_AVATAR, listenPort); + _enableNetworkThread = !cmdOptionExists(argc, constArgv, "--nonblocking"); if (!_enableNetworkThread) { AgentList::getInstance()->getAgentSocket()->setBlocking(false); @@ -934,11 +936,13 @@ void Application::idle() { } // Update from Mouse - QPoint mouse = QCursor::pos(); - _myAvatar.updateFromMouse(_glWidget->mapFromGlobal(mouse).x(), - _glWidget->mapFromGlobal(mouse).y(), - _glWidget->width(), - _glWidget->height()); + if (_mouseLook->isChecked()) { + QPoint mouse = QCursor::pos(); + _myAvatar.updateFromMouse(_glWidget->mapFromGlobal(mouse).x(), + _glWidget->mapFromGlobal(mouse).y(), + _glWidget->width(), + _glWidget->height()); + } // Read serial port interface devices if (_serialPort.active) { @@ -1195,6 +1199,8 @@ void Application::initMenu() { optionsMenu->addAction("Noise", this, SLOT(setNoise(bool)), Qt::Key_N)->setCheckable(true); (_gyroLook = optionsMenu->addAction("Gyro Look"))->setCheckable(true); _gyroLook->setChecked(true); + (_mouseLook = optionsMenu->addAction("Mouse Look"))->setCheckable(true); + _mouseLook->setChecked(false); optionsMenu->addAction("Fullscreen", this, SLOT(setFullscreen(bool)), Qt::Key_F)->setCheckable(true); QMenu* renderMenu = menuBar->addMenu("Render"); diff --git a/interface/src/Application.h b/interface/src/Application.h index d072eefe24..3e3dbb97b8 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -134,6 +134,7 @@ private: QAction* _lookingInMirror; // Are we currently rendering one's own head as if in mirror? QAction* _gyroLook; // Whether to allow the gyro data from head to move your view + QAction* _mouseLook; // Whether the have the mouse near edge of screen move your view QAction* _renderVoxels; // Whether to render voxels QAction* _renderStarsOn; // Whether to display the stars QAction* _renderAtmosphereOn; // Whether to display the atmosphere diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 5bca301552..c64701d67e 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -99,12 +99,21 @@ int audioCallback (const void* inputBuffer, parentAudio->_scope->addSamples(2, outputRight, PACKET_LENGTH_SAMPLES_PER_CHANNEL); // if needed, add input/output data to echo analysis buffers - if (parentAudio->_isGatheringEchoFrames) { - memcpy(parentAudio->_echoInputSamples, inputLeft, + if (parentAudio->_echoInputFrameCountdown > 0) { + if (--parentAudio->_echoInputFrameCountdown == 0) { + memcpy(parentAudio->_echoInputSamples, inputLeft, PACKET_LENGTH_SAMPLES_PER_CHANNEL * sizeof(int16_t)); + parentAudio->_echoInputFrameCountdown = 0; + printLog("got input\n"); + } + } + + if (parentAudio->_isGatheringEchoOutputFrames) { memcpy(parentAudio->_echoOutputSamples, outputLeft, PACKET_LENGTH_SAMPLES_PER_CHANNEL * sizeof(int16_t)); - parentAudio->addedPingFrame(); + parentAudio->_isGatheringEchoOutputFrames = false; + parentAudio->_echoInputFrameCountdown = 2; + printLog("got output\n"); } if (inputLeft != NULL) { @@ -273,7 +282,10 @@ int audioCallback (const void* inputBuffer, for (int s = 0; s < PACKET_LENGTH_SAMPLES_PER_CHANNEL; s++) { outputLeft[s] = outputRight[s] = (int16_t)(sinf((float) s / PING_PITCH) * PING_VOLUME); } - parentAudio->_isGatheringEchoFrames = true; + printLog("Send echo ping\n"); + parentAudio->_isSendingEchoPing = false; + parentAudio->_isGatheringEchoOutputFrames = true; + } gettimeofday(&parentAudio->_lastCallbackTime, NULL); return paContinue; @@ -293,6 +305,9 @@ Audio::Audio(Oscilloscope* scope) : _scope(scope), _averagedLatency(0.0), _measuredJitter(0), + _jitterBufferLengthMsecs(12.0), + _jitterBufferSamples(_jitterBufferLengthMsecs * + NUM_AUDIO_CHANNELS * (SAMPLE_RATE / 1000.0)), _wasStarved(0), _lastInputLoudness(0), _mixerLoopbackFlag(false), @@ -303,8 +318,8 @@ Audio::Audio(Oscilloscope* scope) : _packetsReceivedThisPlayback(0), _shouldStartEcho(false), _isSendingEchoPing(false), - _echoPingFrameCount(0), - _isGatheringEchoFrames(false) + _echoInputFrameCountdown(0), + _isGatheringEchoOutputFrames(false) { outputPortAudioError(Pa_Initialize()); outputPortAudioError(Pa_OpenDefaultStream(&_stream, @@ -376,20 +391,11 @@ void Audio::addProceduralSounds(int16_t* inputBuffer, int numSamples) { void Audio::startEchoTest() { _shouldStartEcho = true; - _echoPingFrameCount = 0; _isSendingEchoPing = true; - _isGatheringEchoFrames = false; + _isGatheringEchoOutputFrames = false; + } -void Audio::addedPingFrame() { - const int ECHO_PING_FRAMES = 1; - _echoPingFrameCount++; - if (_echoPingFrameCount == ECHO_PING_FRAMES) { - _isGatheringEchoFrames = false; - _isSendingEchoPing = false; - //startEchoTest(); - } -} void Audio::analyzeEcho(int16_t* inputBuffer, int16_t* outputBuffer, int numSamples) { // Compare output and input streams, looking for evidence of correlation needing echo cancellation // diff --git a/interface/src/Audio.h b/interface/src/Audio.h index 2eae70bb34..34a342a1d4 100644 --- a/interface/src/Audio.h +++ b/interface/src/Audio.h @@ -38,7 +38,6 @@ public: void addReceivedAudioToBuffer(unsigned char* receivedData, int receivedBytes); void startEchoTest(); - void addedPingFrame(); void renderEchoCompare(); private: @@ -49,6 +48,8 @@ private: timeval _lastReceiveTime; float _averagedLatency; float _measuredJitter; + float _jitterBufferLengthMsecs; + short _jitterBufferSamples; int _wasStarved; float _lastInputLoudness; bool _mixerLoopbackFlag; @@ -57,12 +58,15 @@ private: int _totalPacketsReceived; timeval _firstPlaybackTime; int _packetsReceivedThisPlayback; + // Echo Analysis bool _shouldStartEcho; bool _isSendingEchoPing; - int _echoPingFrameCount; int16_t* _echoInputSamples; int16_t* _echoOutputSamples; - bool _isGatheringEchoFrames; + int _echoInputFrameCountdown; + bool _isGatheringEchoOutputFrames; + + // give access to AudioData class from audioCallback friend int audioCallback (const void*, void*, unsigned long, const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags, void*); diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 9b351a7684..78977e4572 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -188,9 +188,9 @@ bool Avatar::getIsNearInteractingOther() { void Avatar::updateFromMouse(int mouseX, int mouseY, int screenWidth, int screenHeight) { // Update yaw based on mouse behavior - const float MOUSE_MOVE_RADIUS = 0.25f; - const float MOUSE_ROTATE_SPEED = 5.0f; - const float MOUSE_PITCH_SPEED = 3.0f; + const float MOUSE_MOVE_RADIUS = 0.15f; + const float MOUSE_ROTATE_SPEED = 3.0f; + const float MOUSE_PITCH_SPEED = 1.5f; const float MAX_YAW_TO_ADD = 180.f; const int TITLE_BAR_HEIGHT = 46; float mouseLocationX = (float)mouseX / (float)screenWidth - 0.5f; @@ -1377,4 +1377,4 @@ void Avatar::readAvatarDataFromFile() { } fclose(avatarFile); } -} \ No newline at end of file +} diff --git a/interface/src/Oscilloscope.cpp b/interface/src/Oscilloscope.cpp index 088ef6ac14..baa173e512 100644 --- a/interface/src/Oscilloscope.cpp +++ b/interface/src/Oscilloscope.cpp @@ -32,11 +32,15 @@ namespace { // everything in here only exists while compiling this .cpp file } -Oscilloscope::Oscilloscope(int w, int h, bool isEnabled) : - _valWidth(w), _valHeight(h), - _arrSamples(0l), _arrVertices(0l), - _valLowpass(0.4f), _valDownsample(3), - enabled(isEnabled), inputPaused(false) { +Oscilloscope::Oscilloscope(int w, int h, bool isEnabled) : + enabled(isEnabled), + inputPaused(false), + _valWidth(w), + _valHeight(h), + _arrSamples(0l), + _arrVertices(0l), + _valLowpass(0.4f), + _valDownsample(3) { // allocate enough space for the sample data and to turn it into // vertices and since they're all 'short', do so in one shot diff --git a/libraries/audio/src/AudioInjectionManager.cpp b/libraries/audio/src/AudioInjectionManager.cpp index ce252afd23..275161730e 100644 --- a/libraries/audio/src/AudioInjectionManager.cpp +++ b/libraries/audio/src/AudioInjectionManager.cpp @@ -9,12 +9,16 @@ #include #include "SharedUtil.h" +#include "AgentList.h" +#include "AgentTypes.h" +#include "Agent.h" #include "PacketHeaders.h" #include "AudioInjectionManager.h" UDPSocket* AudioInjectionManager::_injectorSocket = NULL; sockaddr AudioInjectionManager::_destinationSocket; +bool AudioInjectionManager::_isDestinationSocketExplicit = false; AudioInjector* AudioInjectionManager::_injectors[50] = {}; AudioInjector* AudioInjectionManager::injectorWithSamplesFromFile(const char* filename) { @@ -39,9 +43,24 @@ AudioInjector* AudioInjectionManager::injectorWithCapacity(int capacity) { return NULL; } +void AudioInjectionManager::setDestinationSocket(sockaddr& destinationSocket) { + _destinationSocket = destinationSocket; + _isDestinationSocketExplicit = true; +} + void* AudioInjectionManager::injectAudioViaThread(void* args) { AudioInjector* injector = (AudioInjector*) args; + // if we don't have an injectorSocket then grab the one from the agent list + if (!_injectorSocket) { + _injectorSocket = AgentList::getInstance()->getAgentSocket(); + } + + // if we don't have an explicit destination socket then pull active socket for current audio mixer from agent list + if (!_isDestinationSocketExplicit) { + _destinationSocket = *AgentList::getInstance()->soloAgentOfType(AGENT_TYPE_AUDIO_MIXER)->getActiveSocket(); + } + injector->injectAudio(_injectorSocket, &_destinationSocket); // if this an injector inside the injection manager's array we're responsible for deletion diff --git a/libraries/audio/src/AudioInjectionManager.h b/libraries/audio/src/AudioInjectionManager.h index 3297305475..8cb9614811 100644 --- a/libraries/audio/src/AudioInjectionManager.h +++ b/libraries/audio/src/AudioInjectionManager.h @@ -24,12 +24,13 @@ public: static void threadInjector(AudioInjector* injector); static void setInjectorSocket(UDPSocket* injectorSocket) { _injectorSocket = injectorSocket;} - static void setDestinationSocket(sockaddr& destinationSocket) { _destinationSocket = destinationSocket; } + static void setDestinationSocket(sockaddr& destinationSocket); private: static void* injectAudioViaThread(void* args); static UDPSocket* _injectorSocket; static sockaddr _destinationSocket; + static bool _isDestinationSocketExplicit; static AudioInjector* _injectors[MAX_CONCURRENT_INJECTORS]; }; diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 43259298fb..658551e726 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -61,7 +61,6 @@ AvatarData::AvatarData() : { }; - int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { unsigned char* bufferStart = destinationBuffer; diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 57edf3c452..68411fa3ee 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -33,8 +33,7 @@ public: const glm::vec3& getPosition() const { return _position; } void setPosition(const glm::vec3 position) { _position = position; } - - void setHandPosition(const glm::vec3 handPosition) { _handPosition = handPosition; } + void setHandPosition(const glm::vec3 handPosition) { _handPosition = handPosition; } int getBroadcastData(unsigned char* destinationBuffer); int parseData(unsigned char* sourceBuffer, int numBytes); @@ -42,10 +41,8 @@ public: // Body Rotation float getBodyYaw() const { return _bodyYaw; } void setBodyYaw(float bodyYaw) { _bodyYaw = bodyYaw; } - float getBodyPitch() const { return _bodyPitch; } void setBodyPitch(float bodyPitch) { _bodyPitch = bodyPitch; } - float getBodyRoll() const {return _bodyRoll; } void setBodyRoll(float bodyRoll) { _bodyRoll = bodyRoll; } @@ -116,7 +113,7 @@ protected: // privatize the copy constructor and assignment operator so they cannot be called AvatarData(const AvatarData&); AvatarData& operator= (const AvatarData&); - + glm::vec3 _position; glm::vec3 _handPosition; diff --git a/libraries/shared/src/AgentList.cpp b/libraries/shared/src/AgentList.cpp index c667f733a4..3da956a04a 100644 --- a/libraries/shared/src/AgentList.cpp +++ b/libraries/shared/src/AgentList.cpp @@ -10,6 +10,7 @@ #include #include #include + #include "AgentList.h" #include "AgentTypes.h" #include "PacketHeaders.h"