From 387100605ca1f07568d28f9e634361ca77cfa933 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 4 Feb 2013 16:00:37 -0800 Subject: [PATCH 1/2] properly reset nextOutput pointer to beginning on starve / full --- Source/Audio.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Source/Audio.cpp b/Source/Audio.cpp index f2d2edee35..0eccdad0fb 100644 --- a/Source/Audio.cpp +++ b/Source/Audio.cpp @@ -25,7 +25,7 @@ const short PACKET_LENGTH_SAMPLES = PACKET_LENGTH_BYTES / sizeof(int16_t); const int PHASE_DELAY_AT_90 = 20; const float AMPLITUDE_RATIO_AT_90 = 0.5; -const short RING_BUFFER_FRAMES = 5; +const short RING_BUFFER_FRAMES = 10; const short RING_BUFFER_SIZE_SAMPLES = RING_BUFFER_FRAMES * BUFFER_LENGTH_SAMPLES; const short JITTER_BUFFER_LENGTH_MSECS = 1; @@ -123,6 +123,7 @@ int audioCallback (const void *inputBuffer, if (ringBuffer->diffLastWriteNextOutput() < BUFFER_LENGTH_SAMPLES) { std::cout << "Starved\n"; + ringBuffer->nextOutput = ringBuffer->buffer; ringBuffer->endOfLastWrite = NULL; } } @@ -239,6 +240,7 @@ void *receiveAudioViaUDP(void *args) { short bufferSampleOverlap = 0; if (!needsJitterBuffer && ringBuffer->diffLastWriteNextOutput() > RING_BUFFER_SIZE_SAMPLES - PACKET_LENGTH_SAMPLES) { + std::cout << "Full\n"; needsJitterBuffer = true; } @@ -257,14 +259,15 @@ void *receiveAudioViaUDP(void *args) { if (!bufferSampleOverlap) { if (needsJitterBuffer) { // we need to inject a jitter buffer - short jitterBufferSamples = JITTER_BUFFER_LENGTH_MSECS * (SAMPLE_RATE / 1000); - + short jitterBufferSamples = JITTER_BUFFER_LENGTH_MSECS * (SAMPLE_RATE / 1000.0); + // add silence for jitter buffer and then the received packet memset(copyToPointer, 0, jitterBufferSamples * sizeof(int16_t)); memcpy(copyToPointer + jitterBufferSamples, 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 + jitterBufferSamples; + 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 From c6f206d541bc5eb589e81f0603f6069de767bca9 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 4 Feb 2013 17:34:40 -0800 Subject: [PATCH 2/2] add a really dumb graph for ring buffer stats --- Source/Audio.cpp | 54 ++++++++++++++++++++++++++++++++++++++++++++++-- Source/Audio.h | 1 + Source/main.cpp | 1 + 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/Source/Audio.cpp b/Source/Audio.cpp index d88e887194..501a5ccc47 100644 --- a/Source/Audio.cpp +++ b/Source/Audio.cpp @@ -84,7 +84,7 @@ int audioCallback (const void *inputBuffer, // int16_t *inputRight = ((int16_t **) inputBuffer)[1]; if (inputLeft != NULL) { - data->audioSocket->send((char *) WORKCLUB_AUDIO_SERVER, 55443, (void *)inputLeft, BUFFER_LENGTH_BYTES); + data->audioSocket->send((char *) EC2_WEST_AUDIO_SERVER, 55443, (void *)inputLeft, BUFFER_LENGTH_BYTES); } int16_t *outputLeft = ((int16_t **) outputBuffer)[0]; @@ -376,7 +376,6 @@ error: void Audio::render() { if (initialized && !ECHO_SERVER_TEST) { - for (int s = 0; s < NUM_AUDIO_SOURCES; s++) { // render gl objects on screen for our sources glPushMatrix(); @@ -390,6 +389,57 @@ void Audio::render() } } +void Audio::render(int screenWidth, int screenHeight) +{ + if (initialized && ECHO_SERVER_TEST) { + glBegin(GL_LINES); + glColor3f(1,1,1); + + int startX = 50.0; + int currentX = startX; + int topY = screenHeight - 90; + int bottomY = screenHeight - 50; + float frameWidth = 50.0; + float halfY = topY + ((bottomY - topY) / 2.0); + + // draw the lines for the base of the ring buffer + + glVertex2f(currentX, topY); + glVertex2f(currentX, bottomY); + + for (int i = 0; i < RING_BUFFER_FRAMES; i++) { + glVertex2f(currentX, halfY); + glVertex2f(currentX + frameWidth, halfY); + currentX += frameWidth; + + glVertex2f(currentX, topY); + glVertex2f(currentX, bottomY); + } + + // show the next audio buffer and end of last write position + int scaleLength = currentX - startX; + + float nextOutputSampleOffset = data->ringBuffer->nextOutput - data->ringBuffer->buffer; + float nextOutputX = startX + (nextOutputSampleOffset / RING_BUFFER_SIZE_SAMPLES) * scaleLength; + glColor3f(1, 0, 0); + glVertex2f(nextOutputX, topY); + glVertex2f(nextOutputX, bottomY); + + float endLastWriteSampleOffset = data->ringBuffer->endOfLastWrite - data->ringBuffer->buffer; + + if (data->ringBuffer->endOfLastWrite == NULL) { + endLastWriteSampleOffset = 0; + } + + float endLastWriteX = startX + (endLastWriteSampleOffset / RING_BUFFER_SIZE_SAMPLES) * scaleLength; + glColor3f(0, 1, 0); + glVertex2f(endLastWriteX, topY); + glVertex2f(endLastWriteX, bottomY); + + glEnd(); + } +} + /** * Close the running audio stream, and deinitialize portaudio. * Should be called at the end of program execution. diff --git a/Source/Audio.h b/Source/Audio.h index 9889a0d783..f1c8ac1d8a 100644 --- a/Source/Audio.h +++ b/Source/Audio.h @@ -21,6 +21,7 @@ public: static bool init(Head* mainHead); static void render(); + static void render(int screenWidth, int screenHeight); // terminates audio I/O static bool terminate(); diff --git a/Source/main.cpp b/Source/main.cpp index 1dc89ffeee..60203ffd13 100644 --- a/Source/main.cpp +++ b/Source/main.cpp @@ -584,6 +584,7 @@ void display(void) glDisable(GL_LIGHTING); //lattice.render(WIDTH, HEIGHT); + Audio::render(WIDTH, HEIGHT); //drawvec3(100, 100, 0.15, 0, 1.0, 0, myHead.getPos(), 0, 1, 0); glPointParameterfvARB( GL_POINT_DISTANCE_ATTENUATION_ARB, pointer_attenuation_quadratic );