Hello all.
This is my first time going into the sound module of SDL, and I was able to get it to play a sound whenever the spaceship shoots a laser, or whenever it gets hit. However, the sound comes out too slow and isn't in sync with the rapid firing laser.
The problem is the audio callback function is called only around once every second, while the space ship can shoot 10 lasers per second. So I added some print statements to show what the buffer size is, and found out that the buffer size is 22056 (close to half of the frequency, 44100). So I tried changing the buffer size through SDL_AudioSpec.samples, but it is still 22056. Then I tried changing SDL_AudioSpec.freq to something lower, and that was able to change the buffer size.
So now I can change the buffer size, but only if also change the frequency. But that makes the sounds sound slow-motion.
Is there a way to customize the buffer size without changing the frequency? Or can it be a hardware limitation?
Here's code showing what I mean
void SoundSystem::init()
{
SDL_AudioSpec want;
Sound::getSpec("sound/checkspec.wav", &want); // use a dummy file to get the spec, this dummy file has same format as other sound files
want.userdata = this;
want.callback = SoundSystem::callback;
//want.freq = 1024; // this changes buffer size to 1024, but makes sounds sound very slow and deep
//want.samples = 512; // this is what I should use to change buffer size to 512, but it doesn't do anything
good = (0 == SDL_OpenAudio(&want, &spec));
if(good)
SDL_PauseAudio(0);
}
void SoundSystem::callback(void *userdata, Uint8 *stream, int len)
{
auto sys = (SoundSystem *) userdata;
SDL_memset(stream, 0, len);
std::cout << len << '\n'; //printing this shows the buffer size
sys->lock(); // sdl spinlock
for(Playback & p : sys->playbacks) // mix all sounds in a list
{
if(p.buf == nullptr)
continue;
unsigned left = p.pos + len > p.len ? p.len - p.pos : len;
SDL_MixAudioFormat(stream, p.buf + p.pos, sys->spec.format, left, SDL_MIX_MAXVOLUME);
p.pos += left;
if(p.pos == p.len)
p = Playback{nullptr, 0, 0};
}
sys->unlock();
}
bool Sound::getSpec(std::string path, SDL_AudioSpec * spec)
{
unsigned len;
Uint8 * buf;
bool good = SDL_LoadWAV(path.c_str(), spec, &buf, &len);
if(good)
SDL_FreeWAV(buf);
return good;
}