From b7b39c2a6ef54a275cfdb752042c4ce2ccd05fe2 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 17 May 2013 14:03:15 -0700 Subject: [PATCH 1/3] have addOrUpdateAgent return a pointer to the agent instead of a bool --- audio-mixer/src/main.cpp | 15 ++++++++++----- avatar-mixer/src/main.cpp | 5 +++-- domain-server/src/main.cpp | 10 ++++++---- libraries/audio/src/AudioInjector.cpp | 8 ++++++++ libraries/audio/src/AudioInjector.h | 5 +++-- libraries/avatars/src/AvatarData.cpp | 1 - libraries/shared/src/AgentList.cpp | 12 ++++-------- libraries/shared/src/AgentList.h | 2 +- libraries/shared/src/SharedUtil.cpp | 9 +++++++++ libraries/shared/src/SharedUtil.h | 2 ++ voxel-server/src/main.cpp | 7 +++++-- 11 files changed, 51 insertions(+), 25 deletions(-) diff --git a/audio-mixer/src/main.cpp b/audio-mixer/src/main.cpp index 5bb33a9198..d987c807f7 100644 --- a/audio-mixer/src/main.cpp +++ b/audio-mixer/src/main.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -272,16 +273,20 @@ int main(int argc, const char* argv[]) { // pull any new audio data from agents off of the network stack while (agentList->getAgentSocket()->receive(agentAddress, packetData, &receivedBytes)) { - if (packetData[0] == PACKET_HEADER_INJECT_AUDIO || packetData[0] == PACKET_HEADER_MICROPHONE_AUDIO) { - char agentType = (packetData[0] == PACKET_HEADER_MICROPHONE_AUDIO) - ? AGENT_TYPE_AVATAR - : AGENT_TYPE_AUDIO_INJECTOR; + if (packetData[0] == PACKET_HEADER_MICROPHONE_AUDIO) { + Agent* avatarAgent = agentList->addOrUpdateAgent(agentAddress, + agentAddress, + AGENT_TYPE_AVATAR, + agentList->getLastAgentID()); - if (agentList->addOrUpdateAgent(agentAddress, agentAddress, agentType, agentList->getLastAgentID())) { + if (avatarAgent->getAgentID() == agentList->getLastAgentID()) { agentList->increaseAgentID(); } agentList->updateAgentWithData(agentAddress, packetData, receivedBytes); + } else if (packetData[0] == PACKET_HEADER_INJECT_AUDIO) { + + // this is an injector stream - check our map to see if we have it already } } diff --git a/avatar-mixer/src/main.cpp b/avatar-mixer/src/main.cpp index d51e48b055..da2b41b1bd 100644 --- a/avatar-mixer/src/main.cpp +++ b/avatar-mixer/src/main.cpp @@ -70,6 +70,7 @@ int main(int argc, const char* argv[]) { unsigned char* currentBufferPosition = NULL; uint16_t agentID = 0; + Agent* avatarAgent = NULL; while (true) { if (agentList->getAgentSocket()->receive(agentAddress, packetData, &receivedBytes)) { @@ -79,10 +80,10 @@ int main(int argc, const char* argv[]) { unpackAgentId(packetData + 1, &agentID); // add or update the agent in our list - agentList->addOrUpdateAgent(agentAddress, agentAddress, AGENT_TYPE_AVATAR, agentID); + avatarAgent = agentList->addOrUpdateAgent(agentAddress, agentAddress, AGENT_TYPE_AVATAR, agentID); // parse positional data from an agent - agentList->updateAgentWithData(agentAddress, packetData, receivedBytes); + agentList->updateAgentWithData(avatarAgent, packetData, receivedBytes); currentBufferPosition = broadcastPacket + 1; diff --git a/domain-server/src/main.cpp b/domain-server/src/main.cpp index 959456bd03..968057623f 100644 --- a/domain-server/src/main.cpp +++ b/domain-server/src/main.cpp @@ -115,10 +115,12 @@ int main(int argc, const char * argv[]) } } - if (agentList->addOrUpdateAgent((sockaddr*) &agentPublicAddress, - (sockaddr*) &agentLocalAddress, - agentType, - agentList->getLastAgentID())) { + Agent* newAgent = agentList->addOrUpdateAgent((sockaddr*) &agentPublicAddress, + (sockaddr*) &agentLocalAddress, + agentType, + agentList->getLastAgentID()); + + if (newAgent->getAgentID() == agentList->getLastAgentID()) { agentList->increaseAgentID(); } diff --git a/libraries/audio/src/AudioInjector.cpp b/libraries/audio/src/AudioInjector.cpp index 689b4c6cd9..7a1747a355 100644 --- a/libraries/audio/src/AudioInjector.cpp +++ b/libraries/audio/src/AudioInjector.cpp @@ -24,6 +24,8 @@ AudioInjector::AudioInjector(const char* filename) : _indexOfNextSlot(0), _isInjectingAudio(false) { + loadRandomIdentifier(_identifier, INJECTOR_IDENTIFIER_NUM_BYTES); + std::fstream sourceFile; sourceFile.open(filename, std::ios::in | std::ios::binary); @@ -51,6 +53,8 @@ AudioInjector::AudioInjector(int maxNumSamples) : _indexOfNextSlot(0), _isInjectingAudio(false) { + loadRandomIdentifier(_identifier, INJECTOR_IDENTIFIER_NUM_BYTES); + _audioSampleArray = new int16_t[maxNumSamples]; memset(_audioSampleArray, 0, _numTotalSamples * sizeof(int16_t)); } @@ -81,6 +85,10 @@ void AudioInjector::injectAudio(UDPSocket* injectorSocket, sockaddr* destination memcpy(currentPacketPtr, &_bearing, sizeof(_bearing)); currentPacketPtr += sizeof(_bearing); + // copy the identifier for this injector + memcpy(currentPacketPtr, &_identifier, sizeof(_identifier)); + currentPacketPtr += sizeof(_identifier); + for (int i = 0; i < _numTotalSamples; i += BUFFER_LENGTH_SAMPLES) { gettimeofday(&startTime, NULL); diff --git a/libraries/audio/src/AudioInjector.h b/libraries/audio/src/AudioInjector.h index eb22df1177..fa907438bf 100644 --- a/libraries/audio/src/AudioInjector.h +++ b/libraries/audio/src/AudioInjector.h @@ -18,9 +18,9 @@ const int BUFFER_LENGTH_SAMPLES = BUFFER_LENGTH_BYTES / sizeof(int16_t); const float SAMPLE_RATE = 22050.0f; const float BUFFER_SEND_INTERVAL_USECS = (BUFFER_LENGTH_SAMPLES / SAMPLE_RATE) * 1000000; +const int INJECTOR_IDENTIFIER_NUM_BYTES = 8; + class AudioInjector { - friend class AudioInjectionManager; - public: AudioInjector(const char* filename); AudioInjector(int maxNumSamples); @@ -43,6 +43,7 @@ public: void addSample(const int16_t sample); void addSamples(int16_t* sampleBuffer, int numSamples); private: + unsigned char _identifier[INJECTOR_IDENTIFIER_NUM_BYTES]; int16_t* _audioSampleArray; int _numTotalSamples; glm::vec3 _position; diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index f63947a580..2e11e8aa84 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -19,7 +19,6 @@ using namespace std; using avatars_lib::printLog; - int packFloatAngleToTwoByte(unsigned char* buffer, float angle) { const float ANGLE_CONVERSION_RATIO = (std::numeric_limits::max() / 360.0); diff --git a/libraries/shared/src/AgentList.cpp b/libraries/shared/src/AgentList.cpp index fef0446056..c667f733a4 100644 --- a/libraries/shared/src/AgentList.cpp +++ b/libraries/shared/src/AgentList.cpp @@ -126,11 +126,7 @@ void AgentList::processBulkAgentData(sockaddr *senderAddress, unsigned char *pac if (!matchingAgent) { // we're missing this agent, we need to add it to the list - addOrUpdateAgent(NULL, NULL, AGENT_TYPE_AVATAR, agentID); - - // TODO: this is a really stupid way to do this - // Add a reverse iterator and go from the end of the list - matchingAgent = agentWithID(agentID); + matchingAgent = addOrUpdateAgent(NULL, NULL, AGENT_TYPE_AVATAR, agentID); } currentPosition += updateAgentWithData(matchingAgent, @@ -218,7 +214,7 @@ int AgentList::processDomainServerList(unsigned char *packetData, size_t dataByt return readAgents; } -bool AgentList::addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket, char agentType, uint16_t agentId) { +Agent* AgentList::addOrUpdateAgent(sockaddr* publicSocket, sockaddr* localSocket, char agentType, uint16_t agentId) { AgentList::iterator agent = end(); if (publicSocket != NULL) { @@ -250,7 +246,7 @@ bool AgentList::addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket, addAgentToList(newAgent); - return true; + return newAgent; } else { if (agent->getType() == AGENT_TYPE_AUDIO_MIXER || agent->getType() == AGENT_TYPE_VOXEL) { @@ -260,7 +256,7 @@ bool AgentList::addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket, } // we had this agent already, do nothing for now - return false; + return &*agent; } } diff --git a/libraries/shared/src/AgentList.h b/libraries/shared/src/AgentList.h index 280927929f..3ac7cf1f8d 100644 --- a/libraries/shared/src/AgentList.h +++ b/libraries/shared/src/AgentList.h @@ -59,7 +59,7 @@ public: Agent* agentWithAddress(sockaddr *senderAddress); Agent* agentWithID(uint16_t agentID); - bool addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket, char agentType, uint16_t agentId); + Agent* addOrUpdateAgent(sockaddr* publicSocket, sockaddr* localSocket, char agentType, uint16_t agentId); void processAgentData(sockaddr *senderAddress, unsigned char *packetData, size_t dataBytes); void processBulkAgentData(sockaddr *senderAddress, unsigned char *packetData, int numTotalBytes); diff --git a/libraries/shared/src/SharedUtil.cpp b/libraries/shared/src/SharedUtil.cpp index d6820897b8..51794813a9 100644 --- a/libraries/shared/src/SharedUtil.cpp +++ b/libraries/shared/src/SharedUtil.cpp @@ -114,6 +114,15 @@ void switchToResourcesParentIfRequired() { #endif } +void loadRandomIdentifier(unsigned char* identifierBuffer, int numBytes) { + // seed the the random number generator + srand(time(NULL)); + + for (int i = 0; i < numBytes; i++) { + identifierBuffer[i] = rand() % 255; + } +} + ////////////////////////////////////////////////////////////////////////////////////////// // Function: getCmdOption() // Description: Handy little function to tell you if a command line flag and option was diff --git a/libraries/shared/src/SharedUtil.h b/libraries/shared/src/SharedUtil.h index 98baa5488a..d0e71ec71e 100644 --- a/libraries/shared/src/SharedUtil.h +++ b/libraries/shared/src/SharedUtil.h @@ -53,6 +53,8 @@ void setAtBit(unsigned char& byte, int bitIndex); void switchToResourcesParentIfRequired(); +void loadRandomIdentifier(unsigned char* identifierBuffer, int numBytes); + const char* getCmdOption(int argc, const char * argv[],const char* option); bool cmdOptionExists(int argc, const char * argv[],const char* option); diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 25e86f1f8a..84d9834477 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -587,9 +587,12 @@ int main(int argc, const char * argv[]) if (packetData[0] == PACKET_HEADER_HEAD_DATA) { uint16_t agentID = 0; unpackAgentId(packetData + sizeof(PACKET_HEADER_HEAD_DATA), &agentID); - agentList->addOrUpdateAgent(&agentPublicAddress, &agentPublicAddress, AGENT_TYPE_AVATAR, agentID); + Agent* agent = agentList->addOrUpdateAgent(&agentPublicAddress, + &agentPublicAddress, + AGENT_TYPE_AVATAR, + agentID); - agentList->updateAgentWithData(&agentPublicAddress, packetData, receivedBytes); + agentList->updateAgentWithData(agent, packetData, receivedBytes); } } } From d72b931ebe3a8a716ef4dba9d263823545983e14 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 17 May 2013 14:57:10 -0700 Subject: [PATCH 2/3] attach stream identifier to AudioRingBuffer to match incoming data in audio mixer --- audio-mixer/CMakeLists.txt | 7 + audio-mixer/src/main.cpp | 228 +++++++++++++----------- libraries/audio/src/AudioInjector.cpp | 12 +- libraries/audio/src/AudioInjector.h | 6 +- libraries/audio/src/AudioRingBuffer.cpp | 11 +- libraries/audio/src/AudioRingBuffer.h | 15 +- 6 files changed, 159 insertions(+), 120 deletions(-) diff --git a/audio-mixer/CMakeLists.txt b/audio-mixer/CMakeLists.txt index 3e2d9939b0..eac2792883 100644 --- a/audio-mixer/CMakeLists.txt +++ b/audio-mixer/CMakeLists.txt @@ -3,11 +3,18 @@ cmake_minimum_required(VERSION 2.8) set(ROOT_DIR ..) set(MACRO_DIR ${ROOT_DIR}/cmake/macros) +# setup for find modules +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/modules/") + set(TARGET_NAME audio-mixer) include(${MACRO_DIR}/SetupHifiProject.cmake) setup_hifi_project(${TARGET_NAME}) +# set up the external glm library +include(${MACRO_DIR}/IncludeGLM.cmake) +include_glm(${TARGET_NAME} ${ROOT_DIR}) + # link the shared hifi library include(${MACRO_DIR}/LinkHifiLibrary.cmake) link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR}) diff --git a/audio-mixer/src/main.cpp b/audio-mixer/src/main.cpp index d987c807f7..e2028911ef 100644 --- a/audio-mixer/src/main.cpp +++ b/audio-mixer/src/main.cpp @@ -133,128 +133,130 @@ int main(int argc, const char* argv[]) { memset(distanceCoefficients, 0, sizeof(distanceCoefficients)); for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { - AudioRingBuffer* agentRingBuffer = (AudioRingBuffer*) agent->getLinkedData(); - - // zero out the client mix for this agent - memset(clientSamples, 0, sizeof(clientSamples)); - - for (AgentList::iterator otherAgent = agentList->begin(); otherAgent != agentList->end(); otherAgent++) { - if (otherAgent != agent || (otherAgent == agent && agentRingBuffer->shouldLoopbackForAgent())) { - AudioRingBuffer* otherAgentBuffer = (AudioRingBuffer*) otherAgent->getLinkedData(); - - if (otherAgentBuffer->shouldBeAddedToMix()) { + if (agent->getType() == AGENT_TYPE_AVATAR) { + AudioRingBuffer* agentRingBuffer = (AudioRingBuffer*) agent->getLinkedData(); + + // zero out the client mix for this agent + memset(clientSamples, 0, sizeof(clientSamples)); + + for (AgentList::iterator otherAgent = agentList->begin(); otherAgent != agentList->end(); otherAgent++) { + if (otherAgent != agent || (otherAgent == agent && agentRingBuffer->shouldLoopbackForAgent())) { + AudioRingBuffer* otherAgentBuffer = (AudioRingBuffer*) otherAgent->getLinkedData(); - float bearingRelativeAngleToSource = 0.f; - float attenuationCoefficient = 1.f; - int numSamplesDelay = 0; - float weakChannelAmplitudeRatio = 1.f; - - if (otherAgent != agent) { - Position agentPosition = agentRingBuffer->getPosition(); - Position otherAgentPosition = otherAgentBuffer->getPosition(); + if (otherAgentBuffer->shouldBeAddedToMix()) { - // calculate the distance to the other agent + float bearingRelativeAngleToSource = 0.f; + float attenuationCoefficient = 1.f; + int numSamplesDelay = 0; + float weakChannelAmplitudeRatio = 1.f; - // use the distance to the other agent to calculate the change in volume for this frame - int lowAgentIndex = std::min(agent.getAgentIndex(), otherAgent.getAgentIndex()); - int highAgentIndex = std::max(agent.getAgentIndex(), otherAgent.getAgentIndex()); - - if (distanceCoefficients[lowAgentIndex][highAgentIndex] == 0) { - float distanceToAgent = sqrtf(powf(agentPosition.x - otherAgentPosition.x, 2) + - powf(agentPosition.y - otherAgentPosition.y, 2) + - powf(agentPosition.z - otherAgentPosition.z, 2)); + if (otherAgent != agent) { + glm::vec3 agentPosition = agentRingBuffer->getPosition(); + glm::vec3 otherAgentPosition = otherAgentBuffer->getPosition(); - float minCoefficient = std::min(1.0f, - powf(0.5, - (logf(DISTANCE_RATIO * distanceToAgent) / logf(3)) - 1)); - distanceCoefficients[lowAgentIndex][highAgentIndex] = minCoefficient; - } - - - // get the angle from the right-angle triangle - float triangleAngle = atan2f(fabsf(agentPosition.z - otherAgentPosition.z), - fabsf(agentPosition.x - otherAgentPosition.x)) * (180 / M_PI); - float absoluteAngleToSource = 0; - bearingRelativeAngleToSource = 0; - - // find the angle we need for calculation based on the orientation of the triangle - if (otherAgentPosition.x > agentPosition.x) { - if (otherAgentPosition.z > agentPosition.z) { - absoluteAngleToSource = -90 + triangleAngle; - } else { - absoluteAngleToSource = -90 - triangleAngle; + // calculate the distance to the other agent + + // use the distance to the other agent to calculate the change in volume for this frame + int lowAgentIndex = std::min(agent.getAgentIndex(), otherAgent.getAgentIndex()); + int highAgentIndex = std::max(agent.getAgentIndex(), otherAgent.getAgentIndex()); + + if (distanceCoefficients[lowAgentIndex][highAgentIndex] == 0) { + float distanceToAgent = sqrtf(powf(agentPosition.x - otherAgentPosition.x, 2) + + powf(agentPosition.y - otherAgentPosition.y, 2) + + powf(agentPosition.z - otherAgentPosition.z, 2)); + + float minCoefficient = std::min(1.0f, + powf(0.5, + (logf(DISTANCE_RATIO * distanceToAgent) / logf(3)) - 1)); + distanceCoefficients[lowAgentIndex][highAgentIndex] = minCoefficient; } - } else { - if (otherAgentPosition.z > agentPosition.z) { - absoluteAngleToSource = 90 - triangleAngle; + + + // get the angle from the right-angle triangle + float triangleAngle = atan2f(fabsf(agentPosition.z - otherAgentPosition.z), + fabsf(agentPosition.x - otherAgentPosition.x)) * (180 / M_PI); + float absoluteAngleToSource = 0; + bearingRelativeAngleToSource = 0; + + // find the angle we need for calculation based on the orientation of the triangle + if (otherAgentPosition.x > agentPosition.x) { + if (otherAgentPosition.z > agentPosition.z) { + absoluteAngleToSource = -90 + triangleAngle; + } else { + absoluteAngleToSource = -90 - triangleAngle; + } } else { - absoluteAngleToSource = 90 + triangleAngle; + if (otherAgentPosition.z > agentPosition.z) { + absoluteAngleToSource = 90 - triangleAngle; + } else { + absoluteAngleToSource = 90 + triangleAngle; + } } + + bearingRelativeAngleToSource = absoluteAngleToSource - agentRingBuffer->getBearing(); + + if (bearingRelativeAngleToSource > 180) { + bearingRelativeAngleToSource -= 360; + } else if (bearingRelativeAngleToSource < -180) { + bearingRelativeAngleToSource += 360; + } + + float angleOfDelivery = absoluteAngleToSource - otherAgentBuffer->getBearing(); + + if (angleOfDelivery > 180) { + angleOfDelivery -= 360; + } else if (angleOfDelivery < -180) { + angleOfDelivery += 360; + } + + float offAxisCoefficient = MAX_OFF_AXIS_ATTENUATION + + (OFF_AXIS_ATTENUATION_FORMULA_STEP * (fabsf(angleOfDelivery) / 90.0f)); + + attenuationCoefficient = distanceCoefficients[lowAgentIndex][highAgentIndex] + * otherAgentBuffer->getAttenuationRatio() + * offAxisCoefficient; + + bearingRelativeAngleToSource *= (M_PI / 180); + + float sinRatio = fabsf(sinf(bearingRelativeAngleToSource)); + numSamplesDelay = PHASE_DELAY_AT_90 * sinRatio; + weakChannelAmplitudeRatio = 1 - (PHASE_AMPLITUDE_RATIO_AT_90 * sinRatio); } - bearingRelativeAngleToSource = absoluteAngleToSource - agentRingBuffer->getBearing(); - - if (bearingRelativeAngleToSource > 180) { - bearingRelativeAngleToSource -= 360; - } else if (bearingRelativeAngleToSource < -180) { - bearingRelativeAngleToSource += 360; - } - - float angleOfDelivery = absoluteAngleToSource - otherAgentBuffer->getBearing(); - - if (angleOfDelivery > 180) { - angleOfDelivery -= 360; - } else if (angleOfDelivery < -180) { - angleOfDelivery += 360; - } - - float offAxisCoefficient = MAX_OFF_AXIS_ATTENUATION + - (OFF_AXIS_ATTENUATION_FORMULA_STEP * (fabsf(angleOfDelivery) / 90.0f)); - - attenuationCoefficient = distanceCoefficients[lowAgentIndex][highAgentIndex] - * otherAgentBuffer->getAttenuationRatio() - * offAxisCoefficient; - - bearingRelativeAngleToSource *= (M_PI / 180); - - float sinRatio = fabsf(sinf(bearingRelativeAngleToSource)); - numSamplesDelay = PHASE_DELAY_AT_90 * sinRatio; - weakChannelAmplitudeRatio = 1 - (PHASE_AMPLITUDE_RATIO_AT_90 * sinRatio); - } - - int16_t* goodChannel = bearingRelativeAngleToSource > 0.0f + int16_t* goodChannel = bearingRelativeAngleToSource > 0.0f ? clientSamples + BUFFER_LENGTH_SAMPLES_PER_CHANNEL : clientSamples; - int16_t* delayedChannel = bearingRelativeAngleToSource > 0.0f + int16_t* delayedChannel = bearingRelativeAngleToSource > 0.0f ? clientSamples : clientSamples + BUFFER_LENGTH_SAMPLES_PER_CHANNEL; - - int16_t* delaySamplePointer = otherAgentBuffer->getNextOutput() == otherAgentBuffer->getBuffer() + + int16_t* delaySamplePointer = otherAgentBuffer->getNextOutput() == otherAgentBuffer->getBuffer() ? otherAgentBuffer->getBuffer() + RING_BUFFER_SAMPLES - numSamplesDelay : otherAgentBuffer->getNextOutput() - numSamplesDelay; - - for (int s = 0; s < BUFFER_LENGTH_SAMPLES_PER_CHANNEL; s++) { - if (s < numSamplesDelay) { - // pull the earlier sample for the delayed channel - int earlierSample = delaySamplePointer[s] * attenuationCoefficient; - plateauAdditionOfSamples(delayedChannel[s], earlierSample * weakChannelAmplitudeRatio); - } - - int16_t currentSample = (otherAgentBuffer->getNextOutput()[s] * attenuationCoefficient); - plateauAdditionOfSamples(goodChannel[s], currentSample); - - if (s + numSamplesDelay < BUFFER_LENGTH_SAMPLES_PER_CHANNEL) { - plateauAdditionOfSamples(delayedChannel[s + numSamplesDelay], - currentSample * weakChannelAmplitudeRatio); + for (int s = 0; s < BUFFER_LENGTH_SAMPLES_PER_CHANNEL; s++) { + + if (s < numSamplesDelay) { + // pull the earlier sample for the delayed channel + int earlierSample = delaySamplePointer[s] * attenuationCoefficient; + plateauAdditionOfSamples(delayedChannel[s], earlierSample * weakChannelAmplitudeRatio); + } + + int16_t currentSample = (otherAgentBuffer->getNextOutput()[s] * attenuationCoefficient); + plateauAdditionOfSamples(goodChannel[s], currentSample); + + if (s + numSamplesDelay < BUFFER_LENGTH_SAMPLES_PER_CHANNEL) { + plateauAdditionOfSamples(delayedChannel[s + numSamplesDelay], + currentSample * weakChannelAmplitudeRatio); + } } } } } + + memcpy(clientPacket + 1, clientSamples, sizeof(clientSamples)); + agentList->getAgentSocket()->send(agent->getPublicSocket(), clientPacket, BUFFER_LENGTH_BYTES + 1); } - - memcpy(clientPacket + 1, clientSamples, sizeof(clientSamples)); - agentList->getAgentSocket()->send(agent->getPublicSocket(), clientPacket, BUFFER_LENGTH_BYTES + 1); } // push forward the next output pointers for any audio buffers we used @@ -285,8 +287,30 @@ int main(int argc, const char* argv[]) { agentList->updateAgentWithData(agentAddress, packetData, receivedBytes); } else if (packetData[0] == PACKET_HEADER_INJECT_AUDIO) { + Agent* matchingInjector = NULL; - // this is an injector stream - check our map to see if we have it already + for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { + if (agent->getLinkedData()) { + AudioRingBuffer* ringBuffer = (AudioRingBuffer*) agent->getLinkedData(); + if (memcmp(ringBuffer->getStreamIdentifier(), packetData + 1, sizeof(STREAM_IDENTIFIER_NUM_BYTES))) { + // this is the matching stream, assign to matchingInjector and stop looking + matchingInjector = &*agent; + break; + } + } + } + + if (!matchingInjector) { + matchingInjector = agentList->addOrUpdateAgent(NULL, + NULL, + AGENT_TYPE_AUDIO_INJECTOR, + agentList->getLastAgentID()); + agentList->increaseAgentID(); + + } + + // give the new audio data to the matching injector agent + agentList->updateAgentWithData(matchingInjector, packetData, receivedBytes); } } diff --git a/libraries/audio/src/AudioInjector.cpp b/libraries/audio/src/AudioInjector.cpp index 7a1747a355..6cc7ccd792 100644 --- a/libraries/audio/src/AudioInjector.cpp +++ b/libraries/audio/src/AudioInjector.cpp @@ -24,7 +24,7 @@ AudioInjector::AudioInjector(const char* filename) : _indexOfNextSlot(0), _isInjectingAudio(false) { - loadRandomIdentifier(_identifier, INJECTOR_IDENTIFIER_NUM_BYTES); + loadRandomIdentifier(_streamIdentifier, STREAM_IDENTIFIER_NUM_BYTES); std::fstream sourceFile; @@ -53,7 +53,7 @@ AudioInjector::AudioInjector(int maxNumSamples) : _indexOfNextSlot(0), _isInjectingAudio(false) { - loadRandomIdentifier(_identifier, INJECTOR_IDENTIFIER_NUM_BYTES); + loadRandomIdentifier(_streamIdentifier, STREAM_IDENTIFIER_NUM_BYTES); _audioSampleArray = new int16_t[maxNumSamples]; memset(_audioSampleArray, 0, _numTotalSamples * sizeof(int16_t)); @@ -76,6 +76,10 @@ void AudioInjector::injectAudio(UDPSocket* injectorSocket, sockaddr* destination dataPacket[0] = PACKET_HEADER_INJECT_AUDIO; unsigned char *currentPacketPtr = dataPacket + 1; + // copy the identifier for this injector + memcpy(currentPacketPtr, &_streamIdentifier, sizeof(_streamIdentifier)); + currentPacketPtr += sizeof(_streamIdentifier); + memcpy(currentPacketPtr, &_position, sizeof(_position)); currentPacketPtr += sizeof(_position); @@ -85,10 +89,6 @@ void AudioInjector::injectAudio(UDPSocket* injectorSocket, sockaddr* destination memcpy(currentPacketPtr, &_bearing, sizeof(_bearing)); currentPacketPtr += sizeof(_bearing); - // copy the identifier for this injector - memcpy(currentPacketPtr, &_identifier, sizeof(_identifier)); - currentPacketPtr += sizeof(_identifier); - for (int i = 0; i < _numTotalSamples; i += BUFFER_LENGTH_SAMPLES) { gettimeofday(&startTime, NULL); diff --git a/libraries/audio/src/AudioInjector.h b/libraries/audio/src/AudioInjector.h index fa907438bf..2571947e99 100644 --- a/libraries/audio/src/AudioInjector.h +++ b/libraries/audio/src/AudioInjector.h @@ -13,13 +13,13 @@ #include +#include "AudioRingBuffer.h" + const int BUFFER_LENGTH_BYTES = 512; const int BUFFER_LENGTH_SAMPLES = BUFFER_LENGTH_BYTES / sizeof(int16_t); const float SAMPLE_RATE = 22050.0f; const float BUFFER_SEND_INTERVAL_USECS = (BUFFER_LENGTH_SAMPLES / SAMPLE_RATE) * 1000000; -const int INJECTOR_IDENTIFIER_NUM_BYTES = 8; - class AudioInjector { public: AudioInjector(const char* filename); @@ -43,7 +43,7 @@ public: void addSample(const int16_t sample); void addSamples(int16_t* sampleBuffer, int numSamples); private: - unsigned char _identifier[INJECTOR_IDENTIFIER_NUM_BYTES]; + unsigned char _streamIdentifier[STREAM_IDENTIFIER_NUM_BYTES]; int16_t* _audioSampleArray; int _numTotalSamples; glm::vec3 _position; diff --git a/libraries/audio/src/AudioRingBuffer.cpp b/libraries/audio/src/AudioRingBuffer.cpp index 19fea1593a..59b35b18a3 100644 --- a/libraries/audio/src/AudioRingBuffer.cpp +++ b/libraries/audio/src/AudioRingBuffer.cpp @@ -18,8 +18,9 @@ AudioRingBuffer::AudioRingBuffer(int ringSamples, int bufferSamples) : _endOfLastWrite(NULL), _started(false), _shouldBeAddedToMix(false), - _shouldLoopbackForAgent(false) { - + _shouldLoopbackForAgent(false), + _streamIdentifier() +{ _buffer = new int16_t[_ringBufferLengthSamples]; _nextOutput = _buffer; }; @@ -39,6 +40,12 @@ int AudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) { // if this came from an injector or interface client // there's data required for spatialization to pull out + if (sourceBuffer[0] == PACKET_HEADER_INJECT_AUDIO) { + // we've got a stream identifier to pull from the packet + memcpy(&_streamIdentifier, dataBuffer, sizeof(_streamIdentifier)); + dataBuffer += sizeof(_streamIdentifier); + } + memcpy(&_position, dataBuffer, sizeof(_position)); dataBuffer += (sizeof(_position)); diff --git a/libraries/audio/src/AudioRingBuffer.h b/libraries/audio/src/AudioRingBuffer.h index 68c35937a7..b448f93cee 100644 --- a/libraries/audio/src/AudioRingBuffer.h +++ b/libraries/audio/src/AudioRingBuffer.h @@ -10,13 +10,12 @@ #define __interface__AudioRingBuffer__ #include + +#include + #include "AgentData.h" -struct Position { - float x; - float y; - float z; -}; +const int STREAM_IDENTIFIER_NUM_BYTES = 8; class AudioRingBuffer : public AgentData { public: @@ -39,10 +38,11 @@ public: bool shouldBeAddedToMix() const { return _shouldBeAddedToMix; } void setShouldBeAddedToMix(bool shouldBeAddedToMix) { _shouldBeAddedToMix = shouldBeAddedToMix; } - const Position& getPosition() const { return _position; } + const glm::vec3& getPosition() const { return _position; } float getAttenuationRatio() const { return _attenuationRatio; } float getBearing() const { return _bearing; } bool shouldLoopbackForAgent() const { return _shouldLoopbackForAgent; } + const unsigned char* getStreamIdentifier() const { return _streamIdentifier; } short diffLastWriteNextOutput(); private: @@ -52,7 +52,7 @@ private: int _ringBufferLengthSamples; int _bufferLengthSamples; - Position _position; + glm::vec3 _position; float _attenuationRatio; float _bearing; int16_t* _nextOutput; @@ -61,6 +61,7 @@ private: bool _started; bool _shouldBeAddedToMix; bool _shouldLoopbackForAgent; + unsigned char _streamIdentifier[STREAM_IDENTIFIER_NUM_BYTES]; }; #endif /* defined(__interface__AudioRingBuffer__) */ From 85c0c1fa986d385c80a4f59e9b56c74585947ba3 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 17 May 2013 15:07:12 -0700 Subject: [PATCH 3/3] fix the mod so we get values up to 255 --- libraries/shared/src/SharedUtil.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/shared/src/SharedUtil.cpp b/libraries/shared/src/SharedUtil.cpp index 51794813a9..c73b696fc4 100644 --- a/libraries/shared/src/SharedUtil.cpp +++ b/libraries/shared/src/SharedUtil.cpp @@ -119,7 +119,7 @@ void loadRandomIdentifier(unsigned char* identifierBuffer, int numBytes) { srand(time(NULL)); for (int i = 0; i < numBytes; i++) { - identifierBuffer[i] = rand() % 255; + identifierBuffer[i] = rand() % 256; } }