mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 04:44:11 +02:00
Merge branch 'master' of https://github.com/worklist/hifi
This commit is contained in:
commit
b4d4cfd994
9 changed files with 191 additions and 8 deletions
|
@ -18,4 +18,10 @@ include_glm(${TARGET_NAME} ${ROOT_DIR})
|
|||
# link the shared hifi library
|
||||
include(${MACRO_DIR}/LinkHifiLibrary.cmake)
|
||||
link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR})
|
||||
link_hifi_library(audio ${TARGET_NAME} ${ROOT_DIR})
|
||||
link_hifi_library(audio ${TARGET_NAME} ${ROOT_DIR})
|
||||
|
||||
# link the stk library
|
||||
set(STK_ROOT_DIR ${ROOT_DIR}/externals/stk)
|
||||
find_package(STK REQUIRED)
|
||||
target_link_libraries(${TARGET_NAME} ${STK_LIBRARIES})
|
||||
include_directories(${STK_INCLUDE_DIRS})
|
|
@ -11,10 +11,18 @@
|
|||
#include "AvatarAudioRingBuffer.h"
|
||||
|
||||
AvatarAudioRingBuffer::AvatarAudioRingBuffer() :
|
||||
_twoPoles(),
|
||||
_shouldLoopbackForAgent(false) {
|
||||
|
||||
}
|
||||
|
||||
AvatarAudioRingBuffer::~AvatarAudioRingBuffer() {
|
||||
// enumerate the freeVerbs map and delete the FreeVerb objects
|
||||
for (TwoPoleAgentMap::iterator poleIterator = _twoPoles.begin(); poleIterator != _twoPoles.end(); poleIterator++) {
|
||||
delete poleIterator->second;
|
||||
}
|
||||
}
|
||||
|
||||
int AvatarAudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) {
|
||||
_shouldLoopbackForAgent = (sourceBuffer[0] == PACKET_HEADER_MICROPHONE_AUDIO_WITH_ECHO);
|
||||
return PositionalAudioRingBuffer::parseData(sourceBuffer, numBytes);
|
||||
|
|
|
@ -9,20 +9,29 @@
|
|||
#ifndef __hifi__AvatarAudioRingBuffer__
|
||||
#define __hifi__AvatarAudioRingBuffer__
|
||||
|
||||
#include <Stk.h>
|
||||
#include <TwoPole.h>
|
||||
|
||||
#include "PositionalAudioRingBuffer.h"
|
||||
|
||||
typedef std::map<uint16_t, stk::TwoPole*> TwoPoleAgentMap;
|
||||
|
||||
class AvatarAudioRingBuffer : public PositionalAudioRingBuffer {
|
||||
public:
|
||||
AvatarAudioRingBuffer();
|
||||
~AvatarAudioRingBuffer();
|
||||
|
||||
int parseData(unsigned char* sourceBuffer, int numBytes);
|
||||
|
||||
TwoPoleAgentMap& getTwoPoles() { return _twoPoles; }
|
||||
|
||||
bool shouldLoopbackForAgent() const { return _shouldLoopbackForAgent; }
|
||||
private:
|
||||
// disallow copying of AvatarAudioRingBuffer objects
|
||||
AvatarAudioRingBuffer(const AvatarAudioRingBuffer&);
|
||||
AvatarAudioRingBuffer& operator= (const AvatarAudioRingBuffer&);
|
||||
|
||||
TwoPoleAgentMap _twoPoles;
|
||||
bool _shouldLoopbackForAgent;
|
||||
};
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <AgentTypes.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <StdDev.h>
|
||||
#include <Logstash.h>
|
||||
|
||||
#include "InjectedAudioRingBuffer.h"
|
||||
#include "AvatarAudioRingBuffer.h"
|
||||
|
@ -46,7 +47,7 @@ const unsigned short MIXER_LISTEN_PORT = 55443;
|
|||
const short JITTER_BUFFER_MSECS = 12;
|
||||
const short JITTER_BUFFER_SAMPLES = JITTER_BUFFER_MSECS * (SAMPLE_RATE / 1000.0);
|
||||
|
||||
const float BUFFER_SEND_INTERVAL_USECS = (BUFFER_LENGTH_SAMPLES_PER_CHANNEL / SAMPLE_RATE) * 1000000;
|
||||
const long long BUFFER_SEND_INTERVAL_USECS = floorf((BUFFER_LENGTH_SAMPLES_PER_CHANNEL / SAMPLE_RATE) * 1000000);
|
||||
|
||||
const long MAX_SAMPLE_VALUE = std::numeric_limits<int16_t>::max();
|
||||
const long MIN_SAMPLE_VALUE = std::numeric_limits<int16_t>::min();
|
||||
|
@ -57,7 +58,7 @@ void plateauAdditionOfSamples(int16_t &mixSample, int16_t sampleToAdd) {
|
|||
long normalizedSample = std::min(MAX_SAMPLE_VALUE, sumSample);
|
||||
normalizedSample = std::max(MIN_SAMPLE_VALUE, sumSample);
|
||||
|
||||
mixSample = normalizedSample;
|
||||
mixSample = normalizedSample;
|
||||
}
|
||||
|
||||
void attachNewBufferToAgent(Agent *newAgent) {
|
||||
|
@ -70,9 +71,20 @@ void attachNewBufferToAgent(Agent *newAgent) {
|
|||
}
|
||||
}
|
||||
|
||||
bool wantLocalDomain = false;
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||
|
||||
// Handle Local Domain testing with the --local command line
|
||||
const char* local = "--local";
|
||||
::wantLocalDomain = cmdOptionExists(argc, argv,local);
|
||||
if (::wantLocalDomain) {
|
||||
printf("Local Domain MODE!\n");
|
||||
int ip = getLocalAddress();
|
||||
sprintf(DOMAIN_IP,"%d.%d.%d.%d", (ip & 0xFF), ((ip >> 8) & 0xFF),((ip >> 16) & 0xFF), ((ip >> 24) & 0xFF));
|
||||
}
|
||||
|
||||
AgentList* agentList = AgentList::createInstance(AGENT_TYPE_AUDIO_MIXER, MIXER_LISTEN_PORT);
|
||||
|
||||
ssize_t receivedBytes = 0;
|
||||
|
@ -100,12 +112,42 @@ int main(int argc, const char* argv[]) {
|
|||
|
||||
timeval lastDomainServerCheckIn = {};
|
||||
|
||||
timeval beginSendTime, endSendTime;
|
||||
float sumFrameTimePercentages = 0.0f;
|
||||
int numStatCollections = 0;
|
||||
|
||||
// if we'll be sending stats, call the Logstash::socket() method to make it load the logstash IP outside the loop
|
||||
if (Logstash::shouldSendStats()) {
|
||||
Logstash::socket();
|
||||
}
|
||||
|
||||
while (true) {
|
||||
if (Logstash::shouldSendStats()) {
|
||||
gettimeofday(&beginSendTime, NULL);
|
||||
}
|
||||
|
||||
// send a check in packet to the domain server if DOMAIN_SERVER_CHECK_IN_USECS has elapsed
|
||||
if (usecTimestampNow() - usecTimestamp(&lastDomainServerCheckIn) >= DOMAIN_SERVER_CHECK_IN_USECS) {
|
||||
gettimeofday(&lastDomainServerCheckIn, NULL);
|
||||
AgentList::getInstance()->sendDomainServerCheckIn();
|
||||
|
||||
if (Logstash::shouldSendStats() && numStatCollections > 0) {
|
||||
// if we should be sending stats to Logstash send the appropriate average now
|
||||
const char MIXER_LOGSTASH_METRIC_NAME[] = "audio-mixer-frame-time-usage";
|
||||
|
||||
// we're sending a floating point percentage with two mandatory numbers after decimal point
|
||||
// that could be up to 6 bytes
|
||||
const int MIXER_LOGSTASH_PACKET_BYTES = strlen(MIXER_LOGSTASH_METRIC_NAME) + 7;
|
||||
char logstashPacket[MIXER_LOGSTASH_PACKET_BYTES];
|
||||
|
||||
float averageFrameTimePercentage = sumFrameTimePercentages / numStatCollections;
|
||||
int packetBytes = sprintf(logstashPacket, "%s %.2f", MIXER_LOGSTASH_METRIC_NAME, averageFrameTimePercentage);
|
||||
|
||||
agentList->getAgentSocket()->send(Logstash::socket(), logstashPacket, packetBytes);
|
||||
|
||||
sumFrameTimePercentages = 0.0f;
|
||||
numStatCollections = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) {
|
||||
|
@ -136,6 +178,8 @@ int main(int argc, const char* argv[]) {
|
|||
int numSamplesDelay = 0;
|
||||
float weakChannelAmplitudeRatio = 1.0f;
|
||||
|
||||
stk::TwoPole* otherAgentTwoPole = NULL;
|
||||
|
||||
if (otherAgent != agent) {
|
||||
|
||||
glm::vec3 listenerPosition = agentRingBuffer->getPosition();
|
||||
|
@ -212,6 +256,26 @@ int main(int argc, const char* argv[]) {
|
|||
float sinRatio = fabsf(sinf(glm::radians(bearingRelativeAngleToSource)));
|
||||
numSamplesDelay = PHASE_DELAY_AT_90 * sinRatio;
|
||||
weakChannelAmplitudeRatio = 1 - (PHASE_AMPLITUDE_RATIO_AT_90 * sinRatio);
|
||||
|
||||
// grab the TwoPole object for this source, add it if it doesn't exist
|
||||
TwoPoleAgentMap& agentTwoPoles = agentRingBuffer->getTwoPoles();
|
||||
TwoPoleAgentMap::iterator twoPoleIterator = agentTwoPoles.find(otherAgent->getAgentID());
|
||||
|
||||
if (twoPoleIterator == agentTwoPoles.end()) {
|
||||
// setup the freeVerb effect for this source for this client
|
||||
otherAgentTwoPole = agentTwoPoles[otherAgent->getAgentID()] = new stk::TwoPole;
|
||||
} else {
|
||||
otherAgentTwoPole = twoPoleIterator->second;
|
||||
}
|
||||
|
||||
// calculate the reasonance for this TwoPole based on angle to source
|
||||
float TWO_POLE_CUT_OFF_FREQUENCY = 800.0f;
|
||||
float TWO_POLE_MAX_FILTER_STRENGTH = 0.4f;
|
||||
|
||||
otherAgentTwoPole->setResonance(TWO_POLE_CUT_OFF_FREQUENCY,
|
||||
TWO_POLE_MAX_FILTER_STRENGTH
|
||||
* fabsf(bearingRelativeAngleToSource) / 180.0f,
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -237,6 +301,10 @@ int main(int argc, const char* argv[]) {
|
|||
plateauAdditionOfSamples(delayedChannel[s], earlierSample);
|
||||
}
|
||||
|
||||
if (otherAgentTwoPole) {
|
||||
otherAgentBuffer->getNextOutput()[s] = otherAgentTwoPole->tick(otherAgentBuffer->getNextOutput()[s]);
|
||||
}
|
||||
|
||||
int16_t currentSample = otherAgentBuffer->getNextOutput()[s] * attenuationCoefficient;
|
||||
|
||||
plateauAdditionOfSamples(goodChannel[s], currentSample);
|
||||
|
@ -318,6 +386,22 @@ int main(int argc, const char* argv[]) {
|
|||
}
|
||||
}
|
||||
|
||||
if (Logstash::shouldSendStats()) {
|
||||
// send a packet to our logstash instance
|
||||
|
||||
// calculate the percentage value for time elapsed for this send (of the max allowable time)
|
||||
gettimeofday(&endSendTime, NULL);
|
||||
|
||||
float percentageOfMaxElapsed = ((float) (usecTimestamp(&endSendTime) - usecTimestamp(&beginSendTime))
|
||||
/ BUFFER_SEND_INTERVAL_USECS) * 100.0f;
|
||||
|
||||
if (percentageOfMaxElapsed > 0) {
|
||||
sumFrameTimePercentages += percentageOfMaxElapsed;
|
||||
}
|
||||
|
||||
numStatCollections++;
|
||||
}
|
||||
|
||||
long long usecToSleep = usecTimestamp(&startTime) + (++nextFrame * BUFFER_SEND_INTERVAL_USECS) - usecTimestampNow();
|
||||
|
||||
if (usecToSleep > 0) {
|
||||
|
|
|
@ -15,8 +15,4 @@ include(${MACRO_DIR}/IncludeGLM.cmake)
|
|||
include_glm(${TARGET_NAME} ${ROOT_DIR})
|
||||
|
||||
include(${MACRO_DIR}/LinkHifiLibrary.cmake)
|
||||
link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR})
|
||||
|
||||
# link the threads library
|
||||
find_package(Threads REQUIRED)
|
||||
target_link_libraries(${TARGET_NAME} ${CMAKE_THREAD_LIBS_INIT})
|
||||
link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR})
|
45
libraries/shared/src/Logstash.cpp
Normal file
45
libraries/shared/src/Logstash.cpp
Normal file
|
@ -0,0 +1,45 @@
|
|||
//
|
||||
// Logstash.cpp
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen Birarda on 6/11/13.
|
||||
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <netdb.h>
|
||||
|
||||
#include "SharedUtil.h"
|
||||
|
||||
#include "Logstash.h"
|
||||
|
||||
sockaddr_in Logstash::logstashSocket = {};
|
||||
|
||||
sockaddr* Logstash::socket() {
|
||||
|
||||
if (logstashSocket.sin_addr.s_addr == 0) {
|
||||
// we need to construct the socket object
|
||||
|
||||
// assume IPv4
|
||||
logstashSocket.sin_family = AF_INET;
|
||||
|
||||
// use the constant port
|
||||
logstashSocket.sin_port = htons(LOGSTASH_UDP_PORT);
|
||||
|
||||
// lookup the IP address for the constant hostname
|
||||
struct hostent* logstashHostInfo;
|
||||
if ((logstashHostInfo = gethostbyname(LOGSTASH_HOSTNAME))) {
|
||||
memcpy(&logstashSocket.sin_addr, logstashHostInfo->h_addr_list[0], logstashHostInfo->h_length);
|
||||
} else {
|
||||
printf("Failed to lookup logstash IP - will try again on next log attempt.\n");
|
||||
}
|
||||
}
|
||||
|
||||
return (sockaddr*) &logstashSocket;
|
||||
}
|
||||
|
||||
bool Logstash::shouldSendStats() {
|
||||
static bool shouldSendStats = isInEnvironment("production");
|
||||
return shouldSendStats;
|
||||
}
|
25
libraries/shared/src/Logstash.h
Normal file
25
libraries/shared/src/Logstash.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
//
|
||||
// Logstash.h
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen Birarda on 6/11/13.
|
||||
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef __hifi__Logstash__
|
||||
#define __hifi__Logstash__
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
const int LOGSTASH_UDP_PORT = 9500;
|
||||
const char LOGSTASH_HOSTNAME[] = "graphite.highfidelity.io";
|
||||
|
||||
class Logstash {
|
||||
public:
|
||||
static sockaddr* socket();
|
||||
static bool shouldSendStats();
|
||||
private:
|
||||
static sockaddr_in logstashSocket;
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__Logstash__) */
|
|
@ -110,6 +110,15 @@ void setSemiNibbleAt(unsigned char& byte, int bitIndex, int value) {
|
|||
byte += ((value & 3) << (6 - bitIndex)); // semi-nibbles store 00, 01, 10, or 11
|
||||
}
|
||||
|
||||
bool isInEnvironment(const char* environment) {
|
||||
char* environmentString = getenv("HIFI_ENVIRONMENT");
|
||||
|
||||
if (environmentString && strcmp(environmentString, environment) == 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void switchToResourcesParentIfRequired() {
|
||||
#ifdef __APPLE__
|
||||
|
|
|
@ -57,6 +57,7 @@ void setAtBit(unsigned char& byte, int bitIndex);
|
|||
int getSemiNibbleAt(unsigned char& byte, int bitIndex);
|
||||
void setSemiNibbleAt(unsigned char& byte, int bitIndex, int value);
|
||||
|
||||
bool isInEnvironment(const char* environment);
|
||||
|
||||
void switchToResourcesParentIfRequired();
|
||||
|
||||
|
|
Loading…
Reference in a new issue