mirror of
https://github.com/lubosz/overte.git
synced 2025-04-23 07:43:57 +02:00
set jitter buffer on application start to 1/2 of a packet
This commit is contained in:
parent
3304f0eb2e
commit
2c8c34f9bd
4 changed files with 67 additions and 30 deletions
|
@ -72,6 +72,10 @@ const glm::vec3 START_LOCATION(4.f, 0.f, 5.f); // Where one's own agent begin
|
|||
const int IDLE_SIMULATE_MSECS = 16; // How often should call simulate and other stuff
|
||||
// in the idle loop? (60 FPS is default)
|
||||
|
||||
const int STARTUP_JITTER_SAMPLES = PACKET_LENGTH_SAMPLES_PER_CHANNEL / 2;
|
||||
// Startup optimistically with small jitter buffer that
|
||||
// will start playback on the second received audio packet.
|
||||
|
||||
// customized canvas that simply forwards requests/events to the singleton application
|
||||
class GLCanvas : public QGLWidget {
|
||||
protected:
|
||||
|
@ -155,7 +159,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
|
|||
_oculusProgram(0),
|
||||
_oculusDistortionScale(1.25),
|
||||
#ifndef _WIN32
|
||||
_audio(&_audioScope, 0),
|
||||
_audio(&_audioScope, STARTUP_JITTER_SAMPLES),
|
||||
#endif
|
||||
_stopNetworkReceiveThread(false),
|
||||
_packetCount(0),
|
||||
|
|
|
@ -28,12 +28,6 @@
|
|||
// Uncomment the following definition to test audio device latency by copying output to input
|
||||
//#define TEST_AUDIO_LOOPBACK
|
||||
|
||||
const int NUM_AUDIO_CHANNELS = 2;
|
||||
|
||||
const int PACKET_LENGTH_BYTES = 1024;
|
||||
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 PHASE_DELAY_AT_90 = 20;
|
||||
const float AMPLITUDE_RATIO_AT_90 = 0.5;
|
||||
|
@ -172,31 +166,39 @@ int audioCallback (const void* inputBuffer,
|
|||
// just play some silence
|
||||
|
||||
if (ringBuffer->getEndOfLastWrite()) {
|
||||
|
||||
if (!ringBuffer->isStarted() && ringBuffer->diffLastWriteNextOutput() < (PACKET_LENGTH_SAMPLES + parentAudio->_jitterBufferSamples)) {
|
||||
// printLog("Held back, buffer has %d of %d samples required.\n",
|
||||
// ringBuffer->diffLastWriteNextOutput(),
|
||||
// PACKET_LENGTH_SAMPLES + parentAudio->_jitterBufferSamples);
|
||||
//
|
||||
// If not enough audio has arrived to start playback, keep waiting
|
||||
//
|
||||
//printLog("Held back, buffer has %d of %d samples required.\n",
|
||||
// ringBuffer->diffLastWriteNextOutput(),
|
||||
// PACKET_LENGTH_SAMPLES + parentAudio->_jitterBufferSamples);
|
||||
} else if (ringBuffer->diffLastWriteNextOutput() < PACKET_LENGTH_SAMPLES) {
|
||||
//
|
||||
// If we have run out of audio to send to the audio device, we have starved,
|
||||
// so reset the ring buffer and packet counters.
|
||||
//
|
||||
ringBuffer->setStarted(false);
|
||||
::numStarves++;
|
||||
parentAudio->_packetsReceivedThisPlayback = 0;
|
||||
printLog("Starved, remaining buffer msecs = %.0f\n",
|
||||
ringBuffer->diffLastWriteNextOutput() / PACKET_LENGTH_SAMPLES * AUDIO_CALLBACK_MSECS);
|
||||
//printLog("Starved, remaining buffer msecs = %.0f\n",
|
||||
// ringBuffer->diffLastWriteNextOutput() / PACKET_LENGTH_SAMPLES * AUDIO_CALLBACK_MSECS);
|
||||
|
||||
parentAudio->_wasStarved = 10; // Frames to render the indication that the system was starved.
|
||||
parentAudio->_wasStarved = 10; // display frame countdown to show red 'starved' bar.
|
||||
} else {
|
||||
//
|
||||
// We are either already playing back, or we have enough audio to start playing back.
|
||||
//
|
||||
if (!ringBuffer->isStarted()) {
|
||||
ringBuffer->setStarted(true);
|
||||
printLog("starting playback %0.1f msecs delayed, jitter = %d, pkts recvd: %d \n",
|
||||
(usecTimestampNow() - usecTimestamp(&parentAudio->_firstPacketReceivedTime))/1000.0,
|
||||
parentAudio->_jitterBufferSamples,
|
||||
parentAudio->_packetsReceivedThisPlayback);
|
||||
} else {
|
||||
// printLog("pushing buffer\n");
|
||||
//printLog("starting playback %0.1f msecs delayed, jitter = %d, pkts recvd: %d \n",
|
||||
// (usecTimestampNow() - usecTimestamp(&parentAudio->_firstPacketReceivedTime))/1000.0,
|
||||
// parentAudio->_jitterBufferSamples,
|
||||
// parentAudio->_packetsReceivedThisPlayback);
|
||||
}
|
||||
//
|
||||
// play whatever we have in the audio buffer
|
||||
|
||||
//
|
||||
// if we haven't fired off the flange effect, check if we should
|
||||
// TODO: lastMeasuredHeadYaw is now relative to body - check if this still works.
|
||||
|
||||
|
@ -322,14 +324,34 @@ Audio::Audio(Oscilloscope* scope, int16_t initialJitterBufferSamples) :
|
|||
//
|
||||
unsigned long FRAMES_PER_BUFFER = BUFFER_LENGTH_SAMPLES_PER_CHANNEL;
|
||||
|
||||
#define PA_SAMPLE_TYPE paInt16
|
||||
PaStreamParameters inputParameters, outputParameters;
|
||||
|
||||
inputParameters.device = Pa_GetDefaultInputDevice();
|
||||
inputParameters.channelCount = 2; // Stereo input
|
||||
inputParameters.sampleFormat = (paInt16 | paNonInterleaved);
|
||||
//inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
|
||||
inputParameters.suggestedLatency = 0.0116;
|
||||
inputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
outputParameters.device = Pa_GetDefaultOutputDevice();
|
||||
outputParameters.channelCount = 2; // Stereo output
|
||||
outputParameters.sampleFormat = (paInt16 | paNonInterleaved);
|
||||
//outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
|
||||
outputParameters.suggestedLatency = 0.0116;
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
|
||||
outputPortAudioError(Pa_OpenStream(&_stream,
|
||||
&inputParameters,
|
||||
&outputParameters,
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER,
|
||||
paNoFlag,
|
||||
audioCallback,
|
||||
(void*) this));
|
||||
|
||||
/*
|
||||
const PaStreamParameters* inputParameters;
|
||||
const PaStreamParameters* outputParameters;
|
||||
inputParameters->channelCount =
|
||||
|
||||
outputPortAudioError(Pa_OpenStream(&_stream, <#const PaStreamParameters *inputParameters#>, <#const PaStreamParameters *outputParameters#>, SAMPLE_RATE, FRAMES_PER_BUFFER, <#PaStreamFlags streamFlags#>, audioCallback, (void*) this));
|
||||
*/
|
||||
|
||||
outputPortAudioError(Pa_OpenDefaultStream(&_stream,
|
||||
2,
|
||||
2,
|
||||
|
@ -338,9 +360,13 @@ Audio::Audio(Oscilloscope* scope, int16_t initialJitterBufferSamples) :
|
|||
FRAMES_PER_BUFFER,
|
||||
audioCallback,
|
||||
(void*) this));
|
||||
*/
|
||||
|
||||
// start the stream now that sources are good to go
|
||||
outputPortAudioError(Pa_StartStream(_stream));
|
||||
printLog("Default low input, output latency (secs): %0.4f, %0.4f\n",
|
||||
Pa_GetDeviceInfo(Pa_GetDefaultInputDevice())->defaultLowInputLatency,
|
||||
Pa_GetDeviceInfo(Pa_GetDefaultOutputDevice())->defaultLowOutputLatency);
|
||||
|
||||
const PaStreamInfo* streamInfo = Pa_GetStreamInfo(_stream);
|
||||
printLog("Audio started, msecs latency In: %.0f, Out: %.0f\n", streamInfo->inputLatency * 1000.f,
|
||||
|
@ -494,7 +520,7 @@ void Audio::render(int screenWidth, int screenHeight) {
|
|||
glVertex2f(currentX, topY);
|
||||
glVertex2f(currentX, bottomY);
|
||||
|
||||
for (int i = 0; i < RING_BUFFER_LENGTH_FRAMES; i++) {
|
||||
for (int i = 0; i < RING_BUFFER_LENGTH_FRAMES / 2; i++) {
|
||||
glVertex2f(currentX, halfY);
|
||||
glVertex2f(currentX + frameWidth, halfY);
|
||||
currentX += frameWidth;
|
||||
|
|
|
@ -16,6 +16,13 @@
|
|||
#include "Oscilloscope.h"
|
||||
#include "Avatar.h"
|
||||
|
||||
const int NUM_AUDIO_CHANNELS = 2;
|
||||
|
||||
const int PACKET_LENGTH_BYTES = 1024;
|
||||
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;
|
||||
|
||||
class Audio {
|
||||
public:
|
||||
// initializes audio I/O
|
||||
|
|
|
@ -22,7 +22,7 @@ const int BUFFER_LENGTH_BYTES_STEREO = 1024;
|
|||
const int BUFFER_LENGTH_BYTES_PER_CHANNEL = 512;
|
||||
const int BUFFER_LENGTH_SAMPLES_PER_CHANNEL = BUFFER_LENGTH_BYTES_PER_CHANNEL / sizeof(int16_t);
|
||||
|
||||
const short RING_BUFFER_LENGTH_FRAMES = 10;
|
||||
const short RING_BUFFER_LENGTH_FRAMES = 20;
|
||||
const short RING_BUFFER_LENGTH_SAMPLES = RING_BUFFER_LENGTH_FRAMES * BUFFER_LENGTH_SAMPLES_PER_CHANNEL;
|
||||
|
||||
class AudioRingBuffer : public AgentData {
|
||||
|
|
Loading…
Reference in a new issue