Hello fellow SDL developers,
Currently I’m experiencing a problem with SDL’s soundcode
and most importantly with Audio samplebuffer (IE samples).
For my programm (GBA emu I should use a desired sample
buffer of 735 or 1470 if possible. This isn’t a problem
when I use SDL on WIN32 and/or BeOS systems. But for FreeBSD
and Linux this is a problem. It’s my understanding that
Linux needs a sample buffer size powered by two. After much
testing I’ve finally had the soundcode working using a powered
by two sample size (2048), only problem is that the sound
becomes inaccurate at a later stadium or that the sound
quality becomes worse, worser and worser, even with the
desired 60 Frames per second (which is GBA speed).
The problem is simple, the GBA emu needs the value of 735 or
1470, because of it’s internal GBA sound emulation timing but
unfortunately this can’t be archieved by me using SDL on Linux.
Now my question (it took some time, I know). How can I use
a powered by two sample buffersize while the value should
be 735 or 1470? I know it needs a kind of conversion but atm I
haven’t find a way to do that. I hope somebody can provide
me some help with this because I’m a bit fedup with the
inacurate sound and worse sound quality. Or should I use
SDL_Mixer for the audio code?
Extra information :
The source (RAW) soundbuffer is a Uint8 buffer which can be
mixed directly to the destination stream. The value’s of the
source below is as followed :
BUFFER_SIZE = 2048 (this should be 1470 or better, 735)
SAMPLE_RATE = 44100
BUFFER_TOTAL = 5880
Here’s my source of the soundcode I know use :
int BoycaMain::SdlSoundInit()
{
int i;
SDL_AudioSpec wanted;
if(EmuOptions.Sound==FALSE) return 0;
wanted.format = AUDIO_S16SYS;
wanted.channels = 2;
wanted.freq = SAMPLE_RATE;
#ifdef TARGET_BEOS
wanted.samples = BUFFER_TOTAL; // BeOS seems to have better
quality set with this on.
#else
wanted.samples = BUFFER_SIZE;
#endif
wanted.callback = BufferProc;
wanted.userdata = 0;
if( SDL_InitSubSystem( SDL_INIT_AUDIO ) < 0 ) {
printf("Couldn't open SDL audio system\n");
exit(1);
}
if(SDL_OpenAudio( &wanted, NULL) < 0) {
fprintf(stderr, "Couldn't open audio : %s\n", SDL_GetError());
EmuOptions.Sound = FALSE;
return 1;
}
SDL_PauseAudio(0);
return 0;
}
void BoycaMain::BufferProc(void *user, Uint8 *stream, int len)
{
SoundUpdate(0, BUFFER_SIZE); // Update the entire in-emu
soundbuffer.
SDL_MixAudio( stream, (Uint8 *)GB_Data.buf, len, SDL_MIX_MAXVOLUME);
// Similar to SDL_MixAudio but then with memcpy :
// memcpy(stream, (Uint8 *)GB_Data.buf, len); // for Linux audio.
}
I hope somebody could anwser my question. Don’t hessitate to e-mail me
privately should you need more information : sdlemu at ngemu.com.
Regards,
Niels Wagenaar