From 421d850b76e7e70f804cf6b22322483a163508fd Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Wed, 6 Feb 2013 18:11:56 -0800 Subject: [PATCH 1/3] Renamed 'spaceserver' references to 'domainserver' --- Source/Agent.cpp | 5 +++-- Source/Audio.cpp | 8 ++++---- Source/AudioData.cpp | 4 +++- Source/AudioData.h | 3 ++- Source/Network.cpp | 14 +++++++------- Source/Network.h | 8 ++++---- Source/main.cpp | 6 +++--- interface.xcodeproj/project.pbxproj | 8 ++++---- .../xcschemes/automata7.xcscheme | 1 + 9 files changed, 31 insertions(+), 26 deletions(-) diff --git a/Source/Agent.cpp b/Source/Agent.cpp index 0580ad68d1..a91d4ef6ad 100644 --- a/Source/Agent.cpp +++ b/Source/Agent.cpp @@ -17,14 +17,15 @@ struct AgentList { in_addr sin_addr; Head head; } agents[MAX_AGENTS]; + int num_agents = 0; // -// Process an incoming spaceserver packet telling you about other nearby agents +// Process an incoming domainserver packet telling you about other nearby agents // void update_agents(char * data, int length) { std::string packet(data, length); - std::cout << " Update Agents, string: " << packet << "\n"; + //std::cout << " Update Agents, string: " << packet << "\n"; size_t spot; size_t start_spot = 0; spot = packet.find_first_of (",", 0); diff --git a/Source/Audio.cpp b/Source/Audio.cpp index 2ca055a6fa..d0fe685894 100644 --- a/Source/Audio.cpp +++ b/Source/Audio.cpp @@ -247,8 +247,8 @@ void *receiveAudioViaUDP(void *args) { //printf(\n"; stdev.addValue(tDiff); if (stdev.getSamples() > 500) { - sharedAudioData->jitter = stdev.getStDev(); - printf("Avg: %4.2f, Stdev: %4.2f\n", stdev.getAverage(), sharedAudioData->jitter); + sharedAudioData->measuredJitter = stdev.getStDev(); + printf("Avg: %4.2f, Stdev: %4.2f\n", stdev.getAverage(), sharedAudioData->measuredJitter); stdev.reset(); } } @@ -465,7 +465,7 @@ void Audio::render(int screenWidth, int screenHeight) // Show a Cyan bar with the most recently measured jitter stdev - int jitterPels = (float) data->jitter/ ((1000.0*(float)BUFFER_LENGTH_SAMPLES/(float)SAMPLE_RATE)) * (float)frameWidth; + int jitterPels = (float) data->measuredJitter/ ((1000.0*(float)BUFFER_LENGTH_SAMPLES/(float)SAMPLE_RATE)) * (float)frameWidth; glColor3f(0,1,1); glBegin(GL_QUADS); @@ -475,7 +475,7 @@ void Audio::render(int screenWidth, int screenHeight) glVertex2f(startX + jitterPels - 2, bottomY + 2); glEnd(); - sprintf(out,"%3.1f\n", data->jitter); + sprintf(out,"%3.1f\n", data->measuredJitter); drawtext(startX + jitterPels - 5, topY-10, 0.08, 0, 1, 0, out, 0,1,1); sprintf(out, "%3.1fms\n", JITTER_BUFFER_LENGTH_MSECS); diff --git a/Source/AudioData.cpp b/Source/AudioData.cpp index 7497f31d96..863142faf4 100644 --- a/Source/AudioData.cpp +++ b/Source/AudioData.cpp @@ -27,7 +27,9 @@ AudioData::AudioData(int numberOfSources, int bufferLength) { averagedLatency = 0.0; lastCallback.tv_usec = 0; wasStarved = 0; - jitter = 0; + measuredJitter = 0; + jitterBuffer = 0; + } AudioData::~AudioData() { diff --git a/Source/AudioData.h b/Source/AudioData.h index 2b026b2fda..cf4329c834 100644 --- a/Source/AudioData.h +++ b/Source/AudioData.h @@ -28,7 +28,8 @@ class AudioData { timeval lastCallback; float averagedLatency; - float jitter; + float measuredJitter; + float jitterBuffer; int wasStarved; AudioData(int bufferLength); diff --git a/Source/Network.cpp b/Source/Network.cpp index 4b1af06a3e..561e786375 100644 --- a/Source/Network.cpp +++ b/Source/Network.cpp @@ -19,7 +19,7 @@ int delay_size_received[MAX_DELAY_PACKETS]; int next_to_receive = 0; int next_to_send = 0; -sockaddr_in address, dest_address, spaceserver_address, from; +sockaddr_in address, dest_address, domainserver_address, from; socklen_t fromLength = sizeof( from ); int network_init() @@ -65,9 +65,9 @@ int network_init() dest_address.sin_addr.s_addr = inet_addr(DESTINATION_IP); dest_address.sin_port = htons( (unsigned short) UDP_PORT ); - spaceserver_address.sin_family = AF_INET; - spaceserver_address.sin_addr.s_addr = inet_addr(SPACESERVER_IP); - spaceserver_address.sin_port = htons( (unsigned short) SPACESERVER_PORT ); + domainserver_address.sin_family = AF_INET; + domainserver_address.sin_addr.s_addr = inet_addr(DOMAINSERVER_IP); + domainserver_address.sin_port = htons( (unsigned short) DOMAINSERVER_PORT ); from.sin_family = AF_INET; //from.sin_addr.s_addr = htonl(ip_address); @@ -86,16 +86,16 @@ timeval network_send_ping(int handle) { return check; } -int notify_spaceserver(int handle, float x, float y, float z) { +int notify_domainserver(int handle, float x, float y, float z) { char data[100]; sprintf(data, "%f,%f,%f", x, y, z); //std::cout << "sending: " << data << "\n"; int packet_size = strlen(data); int sent_bytes = sendto( handle, (const char*)data, packet_size, - 0, (sockaddr*)&spaceserver_address, sizeof(sockaddr_in) ); + 0, (sockaddr*)&domainserver_address, sizeof(sockaddr_in) ); if ( sent_bytes != packet_size ) { - printf( "failed to send to spaceserver: return value = %d\n", sent_bytes ); + printf( "failed to send to domainserver: return value = %d\n", sent_bytes ); return false; } return sent_bytes; diff --git a/Source/Network.h b/Source/Network.h index 3b52666263..189f32c168 100644 --- a/Source/Network.h +++ b/Source/Network.h @@ -21,9 +21,9 @@ const int MAX_PACKET_SIZE = 1500; const int UDP_PORT = 30001; const char DESTINATION_IP[] = "127.0.0.1"; -// Address and port of spaceserver process to advertise other agents -const char SPACESERVER_IP[] = "127.0.0.1"; -const int SPACESERVER_PORT = 40000; +// Address and port of domainserver process to advertise other agents +const char DOMAINSERVER_IP[] = "127.0.0.1"; +const int DOMAINSERVER_PORT = 40000; // Randomly send a ping packet every N packets sent const int PING_PACKET_COUNT = 20; @@ -32,6 +32,6 @@ int network_init(); int network_send(int handle, char * packet_data, int packet_size); int network_receive(int handle, in_addr * from_addr, char * packet_data, int delay /*msecs*/); timeval network_send_ping(int handle); -int notify_spaceserver(int handle, float x, float y, float z); +int notify_domainserver(int handle, float x, float y, float z); #endif diff --git a/Source/main.cpp b/Source/main.cpp index 5380a5fdd8..ce4cebc25d 100644 --- a/Source/main.cpp +++ b/Source/main.cpp @@ -230,8 +230,8 @@ void Timer(int extra) glutTimerFunc(1000,Timer,0); gettimeofday(&timer_start, NULL); - // Send a message to the spaceserver telling it we are ALIVE - notify_spaceserver(UDP_socket, location[0], location[1], location[2]); + // Send a message to the domainserver telling it we are ALIVE + notify_domainserver(UDP_socket, location[0], location[1], location[2]); } @@ -783,7 +783,7 @@ void read_network() ping_msecs = (float)diffclock(&ping_start, &check); } else if (incoming_packet[0] == 'S') { // - // Message from Spaceserver + // Message from domainserver // update_agents(&incoming_packet[1], bytes_recvd - 1); } else if (incoming_packet[0] == 'H') { diff --git a/interface.xcodeproj/project.pbxproj b/interface.xcodeproj/project.pbxproj index 4e3c60e1db..df34a02107 100644 --- a/interface.xcodeproj/project.pbxproj +++ b/interface.xcodeproj/project.pbxproj @@ -916,7 +916,7 @@ "$(OTHER_CFLAGS)", ); PRODUCT_NAME = interface; - SDKROOT = macosx10.7; + SDKROOT = macosx; USER_HEADER_SEARCH_PATHS = ""; }; name = Debug; @@ -950,7 +950,7 @@ "$(OTHER_CFLAGS)", ); PRODUCT_NAME = interface; - SDKROOT = macosx10.7; + SDKROOT = macosx; USER_HEADER_SEARCH_PATHS = ""; }; name = Release; @@ -965,7 +965,7 @@ GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.7; ONLY_ACTIVE_ARCH = YES; - SDKROOT = macosx10.7; + SDKROOT = macosx; }; name = Debug; }; @@ -977,7 +977,7 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.7; - SDKROOT = macosx10.7; + SDKROOT = macosx; }; name = Release; }; diff --git a/interface.xcodeproj/xcuserdata/philip.xcuserdatad/xcschemes/automata7.xcscheme b/interface.xcodeproj/xcuserdata/philip.xcuserdatad/xcschemes/automata7.xcscheme index 64763d12c9..3d8c9e6c14 100644 --- a/interface.xcodeproj/xcuserdata/philip.xcuserdatad/xcschemes/automata7.xcscheme +++ b/interface.xcodeproj/xcuserdata/philip.xcuserdatad/xcschemes/automata7.xcscheme @@ -1,5 +1,6 @@ Date: Thu, 7 Feb 2013 15:04:49 -0800 Subject: [PATCH 2/3] change ring buffer to wait for full frames --- Source/Audio.cpp | 94 ++++++++++++++---------------------------------- 1 file changed, 27 insertions(+), 67 deletions(-) diff --git a/Source/Audio.cpp b/Source/Audio.cpp index d0fe685894..034e8da34c 100644 --- a/Source/Audio.cpp +++ b/Source/Audio.cpp @@ -29,7 +29,7 @@ const short RING_BUFFER_FRAMES = 10; const short RING_BUFFER_SIZE_SAMPLES = RING_BUFFER_FRAMES * BUFFER_LENGTH_SAMPLES; const int SAMPLE_RATE = 22050; -const float JITTER_BUFFER_LENGTH_MSECS = 26.0; +const float JITTER_BUFFER_LENGTH_MSECS = 10.0; const short JITTER_BUFFER_SAMPLES = JITTER_BUFFER_LENGTH_MSECS * (SAMPLE_RATE / 1000.0); const short NUM_AUDIO_SOURCES = 2; @@ -105,31 +105,21 @@ int audioCallback (const void *inputBuffer, if (ringBuffer->endOfLastWrite != NULL) { - // play whatever we have in the audio buffer - short silentTail = 0; - - // if the end of the last write to the ring is in front of the current output pointer - // AND the difference between the two is less than a full output buffer - // we need to add some silence after the audio data, to avoid replaying old data - if ((ringBuffer->endOfLastWrite - ringBuffer->buffer) > (ringBuffer->nextOutput - ringBuffer->buffer) - && (ringBuffer->endOfLastWrite - ringBuffer->nextOutput) < BUFFER_LENGTH_SAMPLES) { - silentTail = BUFFER_LENGTH_SAMPLES - (ringBuffer->endOfLastWrite - ringBuffer->nextOutput); - } - - // no sample overlap, either a direct copy of the audio data, or a copy with some appended silence - memcpy(queueBuffer, ringBuffer->nextOutput, (BUFFER_LENGTH_SAMPLES - silentTail) * sizeof(int16_t)); - - ringBuffer->nextOutput += BUFFER_LENGTH_SAMPLES; - - if (ringBuffer->nextOutput == ringBuffer->buffer + RING_BUFFER_SIZE_SAMPLES) { - ringBuffer->nextOutput = ringBuffer->buffer; - } - - if (ringBuffer->diffLastWriteNextOutput() < BUFFER_LENGTH_SAMPLES) { + if (ringBuffer->diffLastWriteNextOutput() < PACKET_LENGTH_SAMPLES + JITTER_BUFFER_SAMPLES) { starve_counter++; printf("Starved #%d\n", starve_counter); - data->wasStarved = 10; // Frames to render the indication that the system was starved. - ringBuffer->endOfLastWrite = NULL; + data->wasStarved = 10; // Frames to render the indication that the system was starved. + } else { + // 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(queueBuffer, ringBuffer->nextOutput, BUFFER_LENGTH_BYTES); + + ringBuffer->nextOutput += BUFFER_LENGTH_SAMPLES; + + if (ringBuffer->nextOutput == ringBuffer->buffer + RING_BUFFER_SIZE_SAMPLES) { + ringBuffer->nextOutput = ringBuffer->buffer; + } } } @@ -255,54 +245,24 @@ void *receiveAudioViaUDP(void *args) { AudioRingBuffer *ringBuffer = sharedAudioData->ringBuffer; - int16_t *copyToPointer; - bool needsJitterBuffer = ringBuffer->endOfLastWrite == NULL; - short bufferSampleOverlap = 0; - - if (!needsJitterBuffer && ringBuffer->diffLastWriteNextOutput() > RING_BUFFER_SIZE_SAMPLES - PACKET_LENGTH_SAMPLES) { + bool ringBufferReset = ringBuffer->endOfLastWrite == NULL; + + if (!ringBufferReset && ringBuffer->diffLastWriteNextOutput() > RING_BUFFER_SIZE_SAMPLES - PACKET_LENGTH_SAMPLES) { + std::cout << "D: " << ringBuffer->diffLastWriteNextOutput() << "\n"; std::cout << "Full\n"; - needsJitterBuffer = true; + ringBufferReset = true; } - if (needsJitterBuffer) { - // we'll need a jitter buffer - // reset the ring buffer and write - copyToPointer = ringBuffer->buffer; - //std::cout << "Writing jitter buffer\n"; - } else { - copyToPointer = ringBuffer->endOfLastWrite; - - // check for possibility of overlap - bufferSampleOverlap = ringBuffer->bufferOverlap(copyToPointer, PACKET_LENGTH_SAMPLES); - + if (ringBufferReset || ringBuffer->endOfLastWrite == ringBuffer->buffer + RING_BUFFER_SIZE_SAMPLES) { + // reset the ring buffer and write from beginning + ringBuffer->endOfLastWrite = ringBuffer->buffer; } - if (!bufferSampleOverlap) { - if (needsJitterBuffer) { - // we need to inject a jitter buffer - - // add silence for jitter buffer and then the received packet - memset(copyToPointer, 0, JITTER_BUFFER_SAMPLES * sizeof(int16_t)); - memcpy(copyToPointer + JITTER_BUFFER_SAMPLES, receivedData, PACKET_LENGTH_BYTES); - - // the end of the write is the pointer to the buffer + packet + jitter buffer - ringBuffer->endOfLastWrite = ringBuffer->buffer + PACKET_LENGTH_SAMPLES + JITTER_BUFFER_SAMPLES; - ringBuffer->nextOutput = ringBuffer->buffer; - } else { - // no jitter buffer, no overlap - // just copy the recieved data to the right spot and then add packet length to previous pointer - memcpy(copyToPointer, receivedData, PACKET_LENGTH_BYTES); - ringBuffer->endOfLastWrite += PACKET_LENGTH_SAMPLES; - } - } else { - // no jitter buffer, but overlap - // copy to the end, and then from the begining to the overlap - memcpy(copyToPointer, receivedData, (PACKET_LENGTH_SAMPLES - bufferSampleOverlap) * sizeof(int16_t)); - memcpy(ringBuffer->buffer, receivedData + (PACKET_LENGTH_SAMPLES - bufferSampleOverlap), bufferSampleOverlap * sizeof(int16_t)); - - // the end of the write is the amount of overlap - ringBuffer->endOfLastWrite = ringBuffer->buffer + bufferSampleOverlap; - } + int16_t *copyToPointer = ringBuffer->endOfLastWrite; + + // just copy the recieved data to the right spot and then add packet length to previous pointer + memcpy(copyToPointer, receivedData, PACKET_LENGTH_BYTES); + ringBuffer->endOfLastWrite += PACKET_LENGTH_SAMPLES; if (LOG_SAMPLE_DELAY) { gettimeofday(&previousReceiveTime, NULL); From 08d090856cf6223375e2c64505411e212eb7c83a Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 7 Feb 2013 15:29:02 -0800 Subject: [PATCH 3/3] fix ring buffer to only hold back on stream start --- Source/Audio.cpp | 28 +++++++++++++++++++--------- Source/AudioRingBuffer.cpp | 1 + Source/AudioRingBuffer.h | 1 + 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/Source/Audio.cpp b/Source/Audio.cpp index 034e8da34c..c71a993d0d 100644 --- a/Source/Audio.cpp +++ b/Source/Audio.cpp @@ -105,11 +105,16 @@ int audioCallback (const void *inputBuffer, if (ringBuffer->endOfLastWrite != NULL) { - if (ringBuffer->diffLastWriteNextOutput() < PACKET_LENGTH_SAMPLES + JITTER_BUFFER_SAMPLES) { + if (!ringBuffer->started && ringBuffer->diffLastWriteNextOutput() <= PACKET_LENGTH_SAMPLES + JITTER_BUFFER_SAMPLES) { + printf("Held back\n"); + } else if (ringBuffer->diffLastWriteNextOutput() < PACKET_LENGTH_SAMPLES) { + ringBuffer->started = false; + starve_counter++; printf("Starved #%d\n", starve_counter); data->wasStarved = 10; // Frames to render the indication that the system was starved. } else { + ringBuffer->started = true; // 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 @@ -245,17 +250,18 @@ void *receiveAudioViaUDP(void *args) { AudioRingBuffer *ringBuffer = sharedAudioData->ringBuffer; - bool ringBufferReset = ringBuffer->endOfLastWrite == NULL; - - if (!ringBufferReset && ringBuffer->diffLastWriteNextOutput() > RING_BUFFER_SIZE_SAMPLES - PACKET_LENGTH_SAMPLES) { + if (ringBuffer->endOfLastWrite == NULL) { + ringBuffer->endOfLastWrite = ringBuffer->buffer; + } else if (ringBuffer->diffLastWriteNextOutput() > RING_BUFFER_SIZE_SAMPLES - PACKET_LENGTH_SAMPLES) { + std::cout << "NAB: " << ringBuffer->nextOutput - ringBuffer->buffer << "\n"; + std::cout << "LAW: " << ringBuffer->endOfLastWrite - ringBuffer->buffer << "\n"; std::cout << "D: " << ringBuffer->diffLastWriteNextOutput() << "\n"; std::cout << "Full\n"; - ringBufferReset = true; - } - - if (ringBufferReset || ringBuffer->endOfLastWrite == ringBuffer->buffer + RING_BUFFER_SIZE_SAMPLES) { - // reset the ring buffer and write from beginning + + // reset us to started state ringBuffer->endOfLastWrite = ringBuffer->buffer; + ringBuffer->nextOutput = ringBuffer->buffer; + ringBuffer->started = false; } int16_t *copyToPointer = ringBuffer->endOfLastWrite; @@ -263,6 +269,10 @@ void *receiveAudioViaUDP(void *args) { // just copy the recieved data to the right spot and then add packet length to previous pointer memcpy(copyToPointer, receivedData, PACKET_LENGTH_BYTES); ringBuffer->endOfLastWrite += PACKET_LENGTH_SAMPLES; + + if (ringBuffer->endOfLastWrite == ringBuffer->buffer + RING_BUFFER_SIZE_SAMPLES) { + ringBuffer->endOfLastWrite = ringBuffer->buffer; + } if (LOG_SAMPLE_DELAY) { gettimeofday(&previousReceiveTime, NULL); diff --git a/Source/AudioRingBuffer.cpp b/Source/AudioRingBuffer.cpp index 3a34ef7454..f79df7945d 100644 --- a/Source/AudioRingBuffer.cpp +++ b/Source/AudioRingBuffer.cpp @@ -10,6 +10,7 @@ AudioRingBuffer::AudioRingBuffer(short ringBufferSamples) { ringBufferLengthSamples = ringBufferSamples; + started = false; endOfLastWrite = NULL; diff --git a/Source/AudioRingBuffer.h b/Source/AudioRingBuffer.h index c78038afb3..9d6b0d7dd8 100644 --- a/Source/AudioRingBuffer.h +++ b/Source/AudioRingBuffer.h @@ -17,6 +17,7 @@ class AudioRingBuffer { int16_t *endOfLastWrite; int16_t *buffer; short ringBufferLengthSamples; + bool started; short diffLastWriteNextOutput(); short bufferOverlap(int16_t *pointer, short addedDistance);