mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 14:18:24 +02:00
send 256 samples per callback so mixer can reply with two channels
This commit is contained in:
parent
5978b50912
commit
29df6e6a3e
7 changed files with 76 additions and 73 deletions
|
@ -18,8 +18,16 @@
|
||||||
|
|
||||||
Oscilloscope * scope;
|
Oscilloscope * scope;
|
||||||
|
|
||||||
const short PACKET_LENGTH_BYTES = 1024;
|
const int PACKET_LENGTH_BYTES = 1024;
|
||||||
const short PACKET_LENGTH_SAMPLES = PACKET_LENGTH_BYTES / sizeof(int16_t);
|
const int PACKET_LENGTH_BYTES_PER_CHANNEL = PACKET_LENGTH_BYTES / 2;
|
||||||
|
const int PACKET_LENGTH_SAMPLES = PACKET_LENGTH_BYTES / sizeof(int16_t);
|
||||||
|
const int PACKET_LENGTH_SAMPLES_PER_CHANNEL = PACKET_LENGTH_SAMPLES / 2;
|
||||||
|
|
||||||
|
const int BUFFER_LENGTH_BYTES = 512;
|
||||||
|
const int BUFFER_LENGTH_SAMPLES = BUFFER_LENGTH_BYTES / sizeof(int16_t);
|
||||||
|
|
||||||
|
const int RING_BUFFER_FRAMES = 10;
|
||||||
|
const int RING_BUFFER_SAMPLES = RING_BUFFER_FRAMES * BUFFER_LENGTH_SAMPLES;
|
||||||
|
|
||||||
const int PHASE_DELAY_AT_90 = 20;
|
const int PHASE_DELAY_AT_90 = 20;
|
||||||
const float AMPLITUDE_RATIO_AT_90 = 0.5;
|
const float AMPLITUDE_RATIO_AT_90 = 0.5;
|
||||||
|
@ -97,7 +105,7 @@ int audioCallback (const void *inputBuffer,
|
||||||
memcpy(dataPacket + 1 + (p * sizeof(float)), &data->sourcePosition[p], sizeof(float));
|
memcpy(dataPacket + 1 + (p * sizeof(float)), &data->sourcePosition[p], sizeof(float));
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy the audio data to the last 1024 bytes of the data packet
|
// copy the audio data to the last BUFFER_LENGTH_BYTES bytes of the data packet
|
||||||
memcpy(dataPacket + leadingBytes, inputLeft, BUFFER_LENGTH_BYTES);
|
memcpy(dataPacket + leadingBytes, inputLeft, BUFFER_LENGTH_BYTES);
|
||||||
|
|
||||||
data->audioSocket->send((sockaddr *)&audioMixerSocket, dataPacket, BUFFER_LENGTH_BYTES + leadingBytes);
|
data->audioSocket->send((sockaddr *)&audioMixerSocket, dataPacket, BUFFER_LENGTH_BYTES + leadingBytes);
|
||||||
|
@ -126,21 +134,11 @@ int audioCallback (const void *inputBuffer,
|
||||||
int16_t *outputLeft = ((int16_t **) outputBuffer)[0];
|
int16_t *outputLeft = ((int16_t **) outputBuffer)[0];
|
||||||
int16_t *outputRight = ((int16_t **) outputBuffer)[1];
|
int16_t *outputRight = ((int16_t **) outputBuffer)[1];
|
||||||
|
|
||||||
memset(outputLeft, 0, BUFFER_LENGTH_BYTES);
|
memset(outputLeft, 0, PACKET_LENGTH_BYTES_PER_CHANNEL);
|
||||||
memset(outputRight, 0, BUFFER_LENGTH_BYTES);
|
memset(outputRight, 0, PACKET_LENGTH_BYTES_PER_CHANNEL);
|
||||||
|
|
||||||
// Copy output data to oscilloscope
|
|
||||||
if (scope->getState()) {
|
|
||||||
for (int i = 0; i < BUFFER_LENGTH_SAMPLES; i++) {
|
|
||||||
scope->addData((float)outputRight[i]/32767.0, 2, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioRingBuffer *ringBuffer = data->ringBuffer;
|
AudioRingBuffer *ringBuffer = data->ringBuffer;
|
||||||
|
|
||||||
int16_t *queueBuffer = data->samplesToQueue;
|
|
||||||
memset(queueBuffer, 0, BUFFER_LENGTH_BYTES);
|
|
||||||
|
|
||||||
// if we've been reset, and there isn't any new packets yet
|
// if we've been reset, and there isn't any new packets yet
|
||||||
// just play some silence
|
// just play some silence
|
||||||
|
|
||||||
|
@ -158,10 +156,10 @@ int audioCallback (const void *inputBuffer,
|
||||||
ringBuffer->setStarted(true);
|
ringBuffer->setStarted(true);
|
||||||
// play whatever we have in the audio buffer
|
// play whatever we have in the audio buffer
|
||||||
|
|
||||||
// no sample overlap, either a direct copy of the audio data, or a copy with some appended silence
|
memcpy(outputLeft, ringBuffer->getNextOutput(), PACKET_LENGTH_BYTES_PER_CHANNEL);
|
||||||
memcpy(queueBuffer, ringBuffer->getNextOutput(), BUFFER_LENGTH_BYTES);
|
memcpy(outputRight, ringBuffer->getNextOutput() + PACKET_LENGTH_SAMPLES_PER_CHANNEL, PACKET_LENGTH_BYTES_PER_CHANNEL);
|
||||||
|
|
||||||
ringBuffer->setNextOutput(ringBuffer->getNextOutput() + BUFFER_LENGTH_SAMPLES);
|
ringBuffer->setNextOutput(ringBuffer->getNextOutput() + PACKET_LENGTH_SAMPLES);
|
||||||
|
|
||||||
if (ringBuffer->getNextOutput() == ringBuffer->getBuffer() + RING_BUFFER_SAMPLES) {
|
if (ringBuffer->getNextOutput() == ringBuffer->getBuffer() + RING_BUFFER_SAMPLES) {
|
||||||
ringBuffer->setNextOutput(ringBuffer->getBuffer());
|
ringBuffer->setNextOutput(ringBuffer->getBuffer());
|
||||||
|
@ -169,10 +167,6 @@ int audioCallback (const void *inputBuffer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy whatever is in the queueBuffer to the outputLeft and outputRight buffers
|
|
||||||
memcpy(outputLeft, queueBuffer, BUFFER_LENGTH_BYTES);
|
|
||||||
memcpy(outputRight, queueBuffer, BUFFER_LENGTH_BYTES);
|
|
||||||
|
|
||||||
gettimeofday(&data->lastCallback, NULL);
|
gettimeofday(&data->lastCallback, NULL);
|
||||||
return paContinue;
|
return paContinue;
|
||||||
}
|
}
|
||||||
|
@ -190,7 +184,7 @@ void *receiveAudioViaUDP(void *args) {
|
||||||
AudioRecThreadStruct *threadArgs = (AudioRecThreadStruct *) args;
|
AudioRecThreadStruct *threadArgs = (AudioRecThreadStruct *) args;
|
||||||
AudioData *sharedAudioData = threadArgs->sharedAudioData;
|
AudioData *sharedAudioData = threadArgs->sharedAudioData;
|
||||||
|
|
||||||
int16_t *receivedData = new int16_t[BUFFER_LENGTH_SAMPLES];
|
int16_t *receivedData = new int16_t[PACKET_LENGTH_SAMPLES];
|
||||||
ssize_t receivedBytes;
|
ssize_t receivedBytes;
|
||||||
|
|
||||||
timeval previousReceiveTime, currentReceiveTime = {};
|
timeval previousReceiveTime, currentReceiveTime = {};
|
||||||
|
@ -270,11 +264,11 @@ Audio::Audio(Oscilloscope * s)
|
||||||
|
|
||||||
scope = s;
|
scope = s;
|
||||||
|
|
||||||
audioData = new AudioData(BUFFER_LENGTH_BYTES);
|
audioData = new AudioData();
|
||||||
|
|
||||||
// setup a UDPSocket
|
// setup a UDPSocket
|
||||||
audioData->audioSocket = new UDPSocket(AUDIO_UDP_LISTEN_PORT);
|
audioData->audioSocket = new UDPSocket(AUDIO_UDP_LISTEN_PORT);
|
||||||
audioData->ringBuffer = new AudioRingBuffer();
|
audioData->ringBuffer = new AudioRingBuffer(RING_BUFFER_SAMPLES, PACKET_LENGTH_SAMPLES);
|
||||||
|
|
||||||
AudioRecThreadStruct threadArgs;
|
AudioRecThreadStruct threadArgs;
|
||||||
threadArgs.sharedAudioData = audioData;
|
threadArgs.sharedAudioData = audioData;
|
||||||
|
@ -285,8 +279,8 @@ Audio::Audio(Oscilloscope * s)
|
||||||
2, // input channels
|
2, // input channels
|
||||||
2, // output channels
|
2, // output channels
|
||||||
(paInt16 | paNonInterleaved), // sample format
|
(paInt16 | paNonInterleaved), // sample format
|
||||||
22050, // sample rate (hz)
|
SAMPLE_RATE, // sample rate (hz)
|
||||||
512, // frames per buffer
|
BUFFER_LENGTH_SAMPLES, // frames per buffer
|
||||||
audioCallback, // callback function
|
audioCallback, // callback function
|
||||||
(void *) audioData); // user data to be passed to callback
|
(void *) audioData); // user data to be passed to callback
|
||||||
if (paError != paNoError) goto error;
|
if (paError != paNoError) goto error;
|
||||||
|
@ -297,7 +291,7 @@ Audio::Audio(Oscilloscope * s)
|
||||||
Pa_StartStream(stream);
|
Pa_StartStream(stream);
|
||||||
if (paError != paNoError) goto error;
|
if (paError != paNoError) goto error;
|
||||||
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -347,10 +341,10 @@ void Audio::render(int screenWidth, int screenHeight)
|
||||||
timeval currentTime;
|
timeval currentTime;
|
||||||
gettimeofday(¤tTime, NULL);
|
gettimeofday(¤tTime, NULL);
|
||||||
float timeLeftInCurrentBuffer = 0;
|
float timeLeftInCurrentBuffer = 0;
|
||||||
if (audioData->lastCallback.tv_usec > 0) timeLeftInCurrentBuffer = diffclock(&audioData->lastCallback, ¤tTime)/(1000.0*(float)BUFFER_LENGTH_SAMPLES/(float)SAMPLE_RATE) * frameWidth;
|
if (audioData->lastCallback.tv_usec > 0) timeLeftInCurrentBuffer = diffclock(&audioData->lastCallback, ¤tTime)/(1000.0*(float)PACKET_LENGTH_SAMPLES/(float)SAMPLE_RATE) * frameWidth;
|
||||||
|
|
||||||
if (audioData->ringBuffer->getEndOfLastWrite() != NULL)
|
if (audioData->ringBuffer->getEndOfLastWrite() != NULL)
|
||||||
remainingBuffer = audioData->ringBuffer->diffLastWriteNextOutput() / BUFFER_LENGTH_SAMPLES * frameWidth;
|
remainingBuffer = audioData->ringBuffer->diffLastWriteNextOutput() / PACKET_LENGTH_SAMPLES * frameWidth;
|
||||||
|
|
||||||
if (audioData->wasStarved == 0) glColor3f(0, 1, 0);
|
if (audioData->wasStarved == 0) glColor3f(0, 1, 0);
|
||||||
else {
|
else {
|
||||||
|
@ -378,12 +372,12 @@ void Audio::render(int screenWidth, int screenHeight)
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
char out[20];
|
char out[20];
|
||||||
sprintf(out, "%3.0f\n", audioData->averagedLatency/(float)frameWidth*(1000.0*(float)BUFFER_LENGTH_SAMPLES/(float)SAMPLE_RATE));
|
sprintf(out, "%3.0f\n", audioData->averagedLatency/(float)frameWidth*(1000.0*(float)PACKET_LENGTH_SAMPLES/(float)SAMPLE_RATE));
|
||||||
drawtext(startX + audioData->averagedLatency - 10, topY-10, 0.08, 0, 1, 0, out, 1,1,0);
|
drawtext(startX + audioData->averagedLatency - 10, topY-10, 0.08, 0, 1, 0, out, 1,1,0);
|
||||||
|
|
||||||
// Show a Cyan bar with the most recently measured jitter stdev
|
// Show a Cyan bar with the most recently measured jitter stdev
|
||||||
|
|
||||||
int jitterPels = (float) audioData->measuredJitter/ ((1000.0*(float)BUFFER_LENGTH_SAMPLES/(float)SAMPLE_RATE)) * (float)frameWidth;
|
int jitterPels = (float) audioData->measuredJitter/ ((1000.0*(float)PACKET_LENGTH_SAMPLES/(float)SAMPLE_RATE)) * (float)frameWidth;
|
||||||
|
|
||||||
glColor3f(0,1,1);
|
glColor3f(0,1,1);
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
|
|
|
@ -8,11 +8,10 @@
|
||||||
|
|
||||||
#include "AudioData.h"
|
#include "AudioData.h"
|
||||||
|
|
||||||
AudioData::AudioData(int bufferLength) {
|
AudioData::AudioData() {
|
||||||
mixerAddress = 0;
|
mixerAddress = 0;
|
||||||
mixerPort = 0;
|
mixerPort = 0;
|
||||||
|
|
||||||
samplesToQueue = new int16_t[bufferLength / sizeof(int16_t)];
|
|
||||||
averagedLatency = 0.0;
|
averagedLatency = 0.0;
|
||||||
lastCallback.tv_usec = 0;
|
lastCallback.tv_usec = 0;
|
||||||
wasStarved = 0;
|
wasStarved = 0;
|
||||||
|
@ -22,6 +21,5 @@ AudioData::AudioData(int bufferLength) {
|
||||||
|
|
||||||
|
|
||||||
AudioData::~AudioData() {
|
AudioData::~AudioData() {
|
||||||
delete[] samplesToQueue;
|
|
||||||
delete audioSocket;
|
delete audioSocket;
|
||||||
}
|
}
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
class AudioData {
|
class AudioData {
|
||||||
public:
|
public:
|
||||||
AudioData(int bufferLength);
|
AudioData();
|
||||||
~AudioData();
|
~AudioData();
|
||||||
AudioRingBuffer *ringBuffer;
|
AudioRingBuffer *ringBuffer;
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,7 @@ int fullscreen = 0;
|
||||||
|
|
||||||
in_addr_t localAddress;
|
in_addr_t localAddress;
|
||||||
|
|
||||||
Oscilloscope audioScope(512,200,true);
|
Oscilloscope audioScope(256,200,true);
|
||||||
|
|
||||||
#define HAND_RADIUS 0.25 // Radius of in-world 'hand' of you
|
#define HAND_RADIUS 0.25 // Radius of in-world 'hand' of you
|
||||||
Head myHead; // The rendered head of oneself
|
Head myHead; // The rendered head of oneself
|
||||||
|
|
|
@ -19,11 +19,18 @@
|
||||||
const unsigned short MIXER_LISTEN_PORT = 55443;
|
const unsigned short MIXER_LISTEN_PORT = 55443;
|
||||||
|
|
||||||
const float SAMPLE_RATE = 22050.0;
|
const float SAMPLE_RATE = 22050.0;
|
||||||
const float BUFFER_SEND_INTERVAL_USECS = (BUFFER_LENGTH_SAMPLES/SAMPLE_RATE) * 1000000;
|
|
||||||
|
|
||||||
const short JITTER_BUFFER_MSECS = 20;
|
const short JITTER_BUFFER_MSECS = 20;
|
||||||
const short JITTER_BUFFER_SAMPLES = JITTER_BUFFER_MSECS * (SAMPLE_RATE / 1000.0);
|
const short JITTER_BUFFER_SAMPLES = JITTER_BUFFER_MSECS * (SAMPLE_RATE / 1000.0);
|
||||||
|
|
||||||
|
const int BUFFER_LENGTH_BYTES = 1024;
|
||||||
|
const int BUFFER_LENGTH_SAMPLES_PER_CHANNEL = (BUFFER_LENGTH_BYTES / 2) / sizeof(int16_t);
|
||||||
|
|
||||||
|
const short RING_BUFFER_FRAMES = 10;
|
||||||
|
const short RING_BUFFER_SAMPLES = RING_BUFFER_FRAMES * BUFFER_LENGTH_SAMPLES_PER_CHANNEL;
|
||||||
|
|
||||||
|
const float BUFFER_SEND_INTERVAL_USECS = (BUFFER_LENGTH_SAMPLES_PER_CHANNEL / SAMPLE_RATE) * 1000000;
|
||||||
|
|
||||||
const long MAX_SAMPLE_VALUE = std::numeric_limits<int16_t>::max();
|
const long MAX_SAMPLE_VALUE = std::numeric_limits<int16_t>::max();
|
||||||
const long MIN_SAMPLE_VALUE = std::numeric_limits<int16_t>::min();
|
const long MIN_SAMPLE_VALUE = std::numeric_limits<int16_t>::min();
|
||||||
|
|
||||||
|
@ -51,9 +58,10 @@ void *sendBuffer(void *args)
|
||||||
|
|
||||||
if (agentBuffer != NULL && agentBuffer->getEndOfLastWrite() != NULL) {
|
if (agentBuffer != NULL && agentBuffer->getEndOfLastWrite() != NULL) {
|
||||||
|
|
||||||
if (!agentBuffer->isStarted() && agentBuffer->diffLastWriteNextOutput() <= BUFFER_LENGTH_SAMPLES + JITTER_BUFFER_SAMPLES) {
|
if (!agentBuffer->isStarted()
|
||||||
|
&& agentBuffer->diffLastWriteNextOutput() <= BUFFER_LENGTH_SAMPLES_PER_CHANNEL + JITTER_BUFFER_SAMPLES) {
|
||||||
printf("Held back buffer %d.\n", i);
|
printf("Held back buffer %d.\n", i);
|
||||||
} else if (agentBuffer->diffLastWriteNextOutput() < BUFFER_LENGTH_SAMPLES) {
|
} else if (agentBuffer->diffLastWriteNextOutput() < BUFFER_LENGTH_SAMPLES_PER_CHANNEL) {
|
||||||
printf("Buffer %d starved.\n", i);
|
printf("Buffer %d starved.\n", i);
|
||||||
agentBuffer->setStarted(false);
|
agentBuffer->setStarted(false);
|
||||||
} else {
|
} else {
|
||||||
|
@ -68,24 +76,26 @@ void *sendBuffer(void *args)
|
||||||
for (int i = 0; i < agentList.getAgents().size(); i++) {
|
for (int i = 0; i < agentList.getAgents().size(); i++) {
|
||||||
Agent *agent = &agentList.getAgents()[i];
|
Agent *agent = &agentList.getAgents()[i];
|
||||||
|
|
||||||
int16_t clientMix[BUFFER_LENGTH_SAMPLES] = {};
|
int16_t clientMix[BUFFER_LENGTH_SAMPLES_PER_CHANNEL * 2] = {};
|
||||||
|
|
||||||
for (int j = 0; j < agentList.getAgents().size(); j++) {
|
for (int j = 0; j < agentList.getAgents().size(); j++) {
|
||||||
if (i != j) {
|
if (i == j) {
|
||||||
AudioRingBuffer *otherAgentBuffer = (AudioRingBuffer *)agentList.getAgents()[j].getLinkedData();
|
AudioRingBuffer *otherAgentBuffer = (AudioRingBuffer *)agentList.getAgents()[j].getLinkedData();
|
||||||
|
|
||||||
float *agentPosition = ((AudioRingBuffer *)agent->getLinkedData())->getPosition();
|
// float *agentPosition = ((AudioRingBuffer *)agent->getLinkedData())->getPosition();
|
||||||
float *otherAgentPosition = otherAgentBuffer->getPosition();
|
// float *otherAgentPosition = otherAgentBuffer->getPosition();
|
||||||
|
//
|
||||||
|
// float distanceToAgent = sqrtf(powf(agentPosition[0] - otherAgentPosition[0], 2) +
|
||||||
|
// powf(agentPosition[1] - otherAgentPosition[1], 2) +
|
||||||
|
// powf(agentPosition[2] - otherAgentPosition[2], 2));
|
||||||
|
//
|
||||||
|
// float distanceCoeff = powf((logf(DISTANCE_RATIO * distanceToAgent) / logf(3)), 2);
|
||||||
|
float distanceCoeff = 1;
|
||||||
|
|
||||||
float distanceToAgent = sqrtf(powf(agentPosition[0] - otherAgentPosition[0], 2) +
|
for (int s = 0; s < BUFFER_LENGTH_SAMPLES_PER_CHANNEL; s++) {
|
||||||
powf(agentPosition[1] - otherAgentPosition[1], 2) +
|
|
||||||
powf(agentPosition[2] - otherAgentPosition[2], 2));
|
|
||||||
|
|
||||||
float distanceCoeff = powf((logf(DISTANCE_RATIO * distanceToAgent) / logf(3)), 2);
|
|
||||||
|
|
||||||
for (int s = 0; s < BUFFER_LENGTH_SAMPLES; s++) {
|
|
||||||
int16_t sample = (otherAgentBuffer->getNextOutput()[s] / distanceCoeff);
|
int16_t sample = (otherAgentBuffer->getNextOutput()[s] / distanceCoeff);
|
||||||
clientMix[s] += sample;
|
clientMix[s] += sample;
|
||||||
|
clientMix[s + BUFFER_LENGTH_SAMPLES_PER_CHANNEL] += sample;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,7 +106,7 @@ void *sendBuffer(void *args)
|
||||||
for (int i = 0; i < agentList.getAgents().size(); i++) {
|
for (int i = 0; i < agentList.getAgents().size(); i++) {
|
||||||
AudioRingBuffer *agentBuffer = (AudioRingBuffer *)agentList.getAgents()[i].getLinkedData();
|
AudioRingBuffer *agentBuffer = (AudioRingBuffer *)agentList.getAgents()[i].getLinkedData();
|
||||||
if (agentBuffer->wasAddedToMix()) {
|
if (agentBuffer->wasAddedToMix()) {
|
||||||
agentBuffer->setNextOutput(agentBuffer->getNextOutput() + BUFFER_LENGTH_SAMPLES);
|
agentBuffer->setNextOutput(agentBuffer->getNextOutput() + BUFFER_LENGTH_SAMPLES_PER_CHANNEL);
|
||||||
|
|
||||||
if (agentBuffer->getNextOutput() >= agentBuffer->getBuffer() + RING_BUFFER_SAMPLES) {
|
if (agentBuffer->getNextOutput() >= agentBuffer->getBuffer() + RING_BUFFER_SAMPLES) {
|
||||||
agentBuffer->setNextOutput(agentBuffer->getBuffer());
|
agentBuffer->setNextOutput(agentBuffer->getBuffer());
|
||||||
|
@ -127,8 +137,8 @@ void *reportAliveToDS(void *args) {
|
||||||
gettimeofday(&lastSend, NULL);
|
gettimeofday(&lastSend, NULL);
|
||||||
|
|
||||||
*output = 'M';
|
*output = 'M';
|
||||||
packSocket(output + 1, 895283510, htons(MIXER_LISTEN_PORT));
|
// packSocket(output + 1, 895283510, htons(MIXER_LISTEN_PORT));
|
||||||
// packSocket(output + 1, 788637888, htons(MIXER_LISTEN_PORT));
|
packSocket(output + 1, 788637888, htons(MIXER_LISTEN_PORT));
|
||||||
agentList.getAgentSocket().send(DOMAIN_IP, DOMAINSERVER_PORT, output, 7);
|
agentList.getAgentSocket().send(DOMAIN_IP, DOMAINSERVER_PORT, output, 7);
|
||||||
|
|
||||||
double usecToSleep = 1000000 - (usecTimestampNow() - usecTimestamp(&lastSend));
|
double usecToSleep = 1000000 - (usecTimestampNow() - usecTimestamp(&lastSend));
|
||||||
|
@ -143,7 +153,7 @@ void *reportAliveToDS(void *args) {
|
||||||
|
|
||||||
void attachNewBufferToAgent(Agent *newAgent) {
|
void attachNewBufferToAgent(Agent *newAgent) {
|
||||||
if (newAgent->getLinkedData() == NULL) {
|
if (newAgent->getLinkedData() == NULL) {
|
||||||
newAgent->setLinkedData(new AudioRingBuffer());
|
newAgent->setLinkedData(new AudioRingBuffer(RING_BUFFER_SAMPLES, BUFFER_LENGTH_SAMPLES_PER_CHANNEL));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,7 +194,7 @@ int main(int argc, const char * argv[])
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if(agentList.getAgentSocket().receive(agentAddress, packetData, &receivedBytes)) {
|
if(agentList.getAgentSocket().receive(agentAddress, packetData, &receivedBytes)) {
|
||||||
if (receivedBytes >= BUFFER_LENGTH_BYTES) {
|
if (packetData[0] == 'I') {
|
||||||
// add or update the existing interface agent
|
// add or update the existing interface agent
|
||||||
agentList.addOrUpdateAgent(agentAddress, agentAddress, packetData[0]);
|
agentList.addOrUpdateAgent(agentAddress, agentAddress, packetData[0]);
|
||||||
agentList.updateAgentWithData(agentAddress, (void *)packetData, receivedBytes);
|
agentList.updateAgentWithData(agentAddress, (void *)packetData, receivedBytes);
|
||||||
|
|
|
@ -9,22 +9,27 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include "AudioRingBuffer.h"
|
#include "AudioRingBuffer.h"
|
||||||
|
|
||||||
AudioRingBuffer::AudioRingBuffer() {
|
AudioRingBuffer::AudioRingBuffer(int ringSamples, int bufferSamples) {
|
||||||
|
ringBufferLengthSamples = ringSamples;
|
||||||
|
bufferLengthSamples = bufferSamples;
|
||||||
|
|
||||||
started = false;
|
started = false;
|
||||||
addedToMix = false;
|
addedToMix = false;
|
||||||
|
|
||||||
endOfLastWrite = NULL;
|
endOfLastWrite = NULL;
|
||||||
|
|
||||||
buffer = new int16_t[RING_BUFFER_SAMPLES];
|
buffer = new int16_t[ringBufferLengthSamples];
|
||||||
nextOutput = buffer;
|
nextOutput = buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
AudioRingBuffer::AudioRingBuffer(const AudioRingBuffer &otherRingBuffer) {
|
AudioRingBuffer::AudioRingBuffer(const AudioRingBuffer &otherRingBuffer) {
|
||||||
|
ringBufferLengthSamples = otherRingBuffer.ringBufferLengthSamples;
|
||||||
|
bufferLengthSamples = otherRingBuffer.bufferLengthSamples;
|
||||||
started = otherRingBuffer.started;
|
started = otherRingBuffer.started;
|
||||||
addedToMix = otherRingBuffer.addedToMix;
|
addedToMix = otherRingBuffer.addedToMix;
|
||||||
|
|
||||||
buffer = new int16_t[RING_BUFFER_SAMPLES];
|
buffer = new int16_t[ringBufferLengthSamples];
|
||||||
memcpy(buffer, otherRingBuffer.buffer, sizeof(int16_t) * RING_BUFFER_SAMPLES);
|
memcpy(buffer, otherRingBuffer.buffer, sizeof(int16_t) * ringBufferLengthSamples);
|
||||||
|
|
||||||
nextOutput = buffer + (otherRingBuffer.nextOutput - otherRingBuffer.buffer);
|
nextOutput = buffer + (otherRingBuffer.nextOutput - otherRingBuffer.buffer);
|
||||||
endOfLastWrite = buffer + (otherRingBuffer.endOfLastWrite - otherRingBuffer.buffer);
|
endOfLastWrite = buffer + (otherRingBuffer.endOfLastWrite - otherRingBuffer.buffer);
|
||||||
|
@ -87,7 +92,7 @@ void AudioRingBuffer::setPosition(float *newPosition) {
|
||||||
void AudioRingBuffer::parseData(void *data, int size) {
|
void AudioRingBuffer::parseData(void *data, int size) {
|
||||||
unsigned char *audioDataStart = (unsigned char *) data;
|
unsigned char *audioDataStart = (unsigned char *) data;
|
||||||
|
|
||||||
if (size > BUFFER_LENGTH_BYTES) {
|
if (size > (bufferLengthSamples * sizeof(int16_t))) {
|
||||||
|
|
||||||
for (int p = 0; p < 3; p ++) {
|
for (int p = 0; p < 3; p ++) {
|
||||||
memcpy(&position[p], audioDataStart + 1 + (sizeof(float) * p), sizeof(float));
|
memcpy(&position[p], audioDataStart + 1 + (sizeof(float) * p), sizeof(float));
|
||||||
|
@ -98,19 +103,19 @@ void AudioRingBuffer::parseData(void *data, int size) {
|
||||||
|
|
||||||
if (endOfLastWrite == NULL) {
|
if (endOfLastWrite == NULL) {
|
||||||
endOfLastWrite = buffer;
|
endOfLastWrite = buffer;
|
||||||
} else if (diffLastWriteNextOutput() > RING_BUFFER_SAMPLES - BUFFER_LENGTH_SAMPLES) {
|
} else if (diffLastWriteNextOutput() > ringBufferLengthSamples - bufferLengthSamples) {
|
||||||
endOfLastWrite = buffer;
|
endOfLastWrite = buffer;
|
||||||
nextOutput = buffer;
|
nextOutput = buffer;
|
||||||
started = false;
|
started = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(endOfLastWrite, audioDataStart, BUFFER_LENGTH_BYTES);
|
memcpy(endOfLastWrite, audioDataStart, bufferLengthSamples * sizeof(int16_t));
|
||||||
|
|
||||||
endOfLastWrite += BUFFER_LENGTH_SAMPLES;
|
endOfLastWrite += bufferLengthSamples;
|
||||||
|
|
||||||
addedToMix = false;
|
addedToMix = false;
|
||||||
|
|
||||||
if (endOfLastWrite >= buffer + RING_BUFFER_SAMPLES) {
|
if (endOfLastWrite >= buffer + ringBufferLengthSamples) {
|
||||||
endOfLastWrite = buffer;
|
endOfLastWrite = buffer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,7 +128,7 @@ short AudioRingBuffer::diffLastWriteNextOutput()
|
||||||
short sampleDifference = endOfLastWrite - nextOutput;
|
short sampleDifference = endOfLastWrite - nextOutput;
|
||||||
|
|
||||||
if (sampleDifference < 0) {
|
if (sampleDifference < 0) {
|
||||||
sampleDifference += RING_BUFFER_SAMPLES;
|
sampleDifference += ringBufferLengthSamples;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sampleDifference;
|
return sampleDifference;
|
||||||
|
|
|
@ -13,15 +13,9 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "AgentData.h"
|
#include "AgentData.h"
|
||||||
|
|
||||||
const int BUFFER_LENGTH_BYTES = 1024;
|
|
||||||
const int BUFFER_LENGTH_SAMPLES = BUFFER_LENGTH_BYTES / sizeof(int16_t);
|
|
||||||
|
|
||||||
const short RING_BUFFER_FRAMES = 10;
|
|
||||||
const short RING_BUFFER_SAMPLES = RING_BUFFER_FRAMES * BUFFER_LENGTH_SAMPLES;
|
|
||||||
|
|
||||||
class AudioRingBuffer : public AgentData {
|
class AudioRingBuffer : public AgentData {
|
||||||
public:
|
public:
|
||||||
AudioRingBuffer();
|
AudioRingBuffer(int ringSamples, int bufferSamples);
|
||||||
~AudioRingBuffer();
|
~AudioRingBuffer();
|
||||||
AudioRingBuffer(const AudioRingBuffer &otherRingBuffer);
|
AudioRingBuffer(const AudioRingBuffer &otherRingBuffer);
|
||||||
|
|
||||||
|
@ -42,6 +36,8 @@ class AudioRingBuffer : public AgentData {
|
||||||
|
|
||||||
short diffLastWriteNextOutput();
|
short diffLastWriteNextOutput();
|
||||||
private:
|
private:
|
||||||
|
int ringBufferLengthSamples;
|
||||||
|
int bufferLengthSamples;
|
||||||
float position[3];
|
float position[3];
|
||||||
int16_t *nextOutput;
|
int16_t *nextOutput;
|
||||||
int16_t *endOfLastWrite;
|
int16_t *endOfLastWrite;
|
||||||
|
|
Loading…
Reference in a new issue