Archived

This topic is now archived and is closed to further replies.

Sound programming - audio latency / unresponsiveness (in SDL)

This topic is 4948 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I''m using SDL, the SDL_OpenAudio( ) & callback thing and am unhappy with the latency. I hit a key and get a 1/4 second delay in key->sound-response. I seem to be in the familiar situation of: short sound buffer --> low (good) latency but risk gaps in sound if buffer not filled fast enough long sound buffer --> high (bad) latency but no gaps in sound. I can''t help thinking thinking there must be a better way of doing this that I don''t know about. I had always been under the impression that sound effects were pretty much instant in games. I am toying with the idea of remembering the time when the callback was activated and using the playback frequency and ''now'' to calculate where to throw the sample ''straight-in'' to the remaining sound-buffer, though it seems messy/dangerous. is the low sound-card latency idea the only way to address this problem?

Share this post


Link to post
Share on other sites

I know this isn''t exactly the answer you''re looking for, but I had similar latency/buffer size problems with SDL''s audio. After messing with it for a bit, I tried OpenAL, which gave me great results and isn''t nearly as complicated as you might think. You might want to consider giving OpenAL a try.

Share this post


Link to post
Share on other sites
There was a thread about this on the SDL mailinglist. I can''t find it now, but you can try yourself at http://twomix.devolution.com/pipermail/sdl/.

The solution there was something like this:

if (desired.freq <= 11025)
desired.samples = 512;
else if (desired.freq <= 22050)
desired.samples = 1024;
else if (desired.freq <= 44100)
desired.samples = 2048;
else
desired.samples = 4096;

Share this post


Link to post
Share on other sites
right... I have been trying to get it to do small sample ranges, even as low as 16 but it chooses 11005 or something which is about every 1/4 second. I''ll look into openAL and have a look for that article, thanks



Share this post


Link to post
Share on other sites

Hey Timberl,

I don''t know if this helps you or not, but here is a simple OpenAL program that loads a sound in from a WAV file and mixes it against itself. Although my example doesn''t stream data into the sound buffer, OpenAL provides this capability through alSourceQueueBuffers You need to have the OpenAL SDK in order to compile this example.


/*
OpenAL Test
Written by Steve Northamer
December 2, 2003
*/


#include <stdio.h>

#include "al.h"
#include "alut.h"

#define ASSERT(x) Assert(x, __FILE__, __LINE__)

void Assert(bool xCondition, char* xFileName, int xLineNumber)
{
if (xCondition)
return;

printf("Assertion failed on line %d\n", xLineNumber);
}

const int NUM_SOURCES = 16;

void main()
{
// Initialize OpenAL

alutInit(0, NULL);
ASSERT(alGetError() == AL_NO_ERROR);

// Create sound buffer

ALuint BufferID;
alGenBuffers(1, &BufferID);
ASSERT(alGetError() == AL_NO_ERROR);

// Load WAV file into memory

ALenum WAVFormat;
ALvoid* WAVData;
ALsizei WAVSize;
ALsizei WAVFreq;
ALboolean WAVLoop;
alutLoadWAVFile("Sound.wav", &WAVFormat, &WAVData, &WAVSize, &WAVFreq, &WAVLoop);

// Copy WAV data into buffer

alBufferData(BufferID, WAVFormat, WAVData, WAVSize, WAVFreq);
ASSERT(alGetError() == AL_NO_ERROR);

// Unload WAV file from memory

alutUnloadWAV(WAVFormat, WAVData, WAVSize, WAVFreq);

// Create sound sources

ALuint pSourceIDs[NUM_SOURCES];
alGenSources(NUM_SOURCES, pSourceIDs);
ASSERT(alGetError() == AL_NO_ERROR);

// Attach buffer to sources

int i;
for (i = 0; i < NUM_SOURCES; i++)
{
alSourcei(pSourceIDs[i], AL_BUFFER, BufferID);
ASSERT(alGetError() == AL_NO_ERROR);
}

// Get user input

char pBuffer[256];
puts("Type q to quit, press enter to play sound effect...\n");

while (true)
{
gets(pBuffer);

if (pBuffer[0] == ''q'' || pBuffer[0] == ''Q'')
break;

// Find source which isn''t playing

ALint SourceState;
for (i = 0; i < NUM_SOURCES; i++)
{
alGetSourcei(pSourceIDs[i], AL_SOURCE_STATE, &SourceState);
if (SourceState != AL_PLAYING)
break;
}

// Trigger sound source

alSourcePlay(pSourceIDs[i]);
ASSERT(alGetError() == AL_NO_ERROR);
}

// Delete sound sources

alDeleteSources(NUM_SOURCES, pSourceIDs);
ASSERT(alGetError() == AL_NO_ERROR);

// Delete sound buffer

alDeleteBuffers(1, &BufferID);
ASSERT(alGetError() == AL_NO_ERROR);

// Deinitialize OpenAL

alutExit();
}

Share this post


Link to post
Share on other sites