Howdy folks,
EDIT: Solved, I just needed to Mix_AllocateChannels(some_high_number);. Apparently “channels” in Mix_OpenAudio corresponds directly to mono/stereo/surround/etc. Stereo provides 8 “channels” which are seemingly software-defined, not hardware defined. But you can also allocate these “software channels” in greater number. I feel like this naming schema is pretty confusing. Anyway, it works now.
I’m trying to use SDL2_mixer for my game, and maybe I’m doing something wrong here, but seems like I can’t play very many samples at once. I’ve tried tweaking my MixOpenAudio parameters, but it doesn’t seem to help. I’ve boiled down my example to a short and simple C file.
#include <SDL2/SDL.h>
#include <SDL2/SDL_mixer.h>
int main(int argc, char** argv) {
// Initialize SDL2 mixer
int flags = MIX_INIT_OGG;
int initted = Mix_Init(flags);
if ((initted & flags) != flags) {
printf("Failed to initialize SDL2 mixer: %s\n", Mix_GetError());
return 1;
}
// Open the audio device
int channels = 2;
int chunksize = 1024;
if (Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, channels, chunksize) < 0) {
printf("Failed to open audio device: %s\n", Mix_GetError());
return 1;
}
// Load the OGG files
Mix_Chunk* effects[14];
effects[0] = Mix_LoadWAV("sfx_shotgun_shoot.ogg");
effects[1] = Mix_LoadWAV("sfx_enemy_gib.ogg");
effects[2] = Mix_LoadWAV("sfx_enemy_hit.ogg");
effects[3] = Mix_LoadWAV("sfx_enemy_hound_attack.ogg");
effects[4] = Mix_LoadWAV("sfx_grenade_bounce.ogg");
effects[5] = Mix_LoadWAV("sfx_grenade_explode.ogg");
effects[6] = Mix_LoadWAV("sfx_grenade_shoot.ogg");
effects[7] = Mix_LoadWAV("sfx_hurt.ogg");
effects[8] = Mix_LoadWAV("sfx_nailgun_hit.ogg");
effects[9] = Mix_LoadWAV("sfx_nailgun_shoot.ogg");
effects[10] = Mix_LoadWAV("sfx_no_ammo.ogg");
effects[11] = Mix_LoadWAV("sfx_pickup.ogg");
effects[12] = Mix_LoadWAV("sfx_plasma_shoot.ogg");
effects[13] = Mix_LoadWAV("sfx_shotgun_reload.ogg");
// Play the sound effects
for (int i = 0; i < 14; i++) {
int channel = Mix_PlayChannel(-1, effects[i], 0);
if (channel == -1) {
printf("Failed to play effect: %s\n", Mix_GetError());
}
}
// Wait for the sound effects to finish
SDL_Delay(5000); // wait for 5 seconds
// Free the loaded files
for (int i = 0; i < 10; i++) {
Mix_FreeChunk(effects[i]);
}
// Close the audio device
Mix_CloseAudio();
// Quit SDL2 mixer
Mix_Quit();
return 0;
}
This will play my sound effects, but a few of them fail to play:
$ gcc main.c -lSDL2 -lSDL2_mixer && ./a.out
Failed to play effect: No free channels available
Failed to play effect: No free channels available
Failed to play effect: No free channels available
Failed to play effect: No free channels available
Failed to play effect: No free channels available
Failed to play effect: No free channels available
Now, I don’t really know a ton about how digital audio works, but I’ve been going off of this from the docs:
The audio device channels are generally 1 for mono output, or 2 for stereo, but the brave can try surround sound configs with 4 (quad), 6 (5.1), 7 (6.1) or 8 (7.1).
The audio device's chunk size is the number of sample frames (one sample per frame for mono output, two samples per frame in a stereo setup, etc) that are fed to the device at once. The lower the number, the lower the latency, but you risk dropouts if it gets too low. 2048 is often a reasonable default
Ok, so channels is gonna be a static 2 for me here, and the higher I set the chunk size, the more sounds I should be able to play at once? But 512, 1024, 2048, 4096, they all produce the same amount of errors.
Could anyone shed some light on how this works? The files are all pretty small and short. I also tried reducing the frequency and bitrates by half (to 24KHz, and 64Kbps), but it always seems to error out after exactly 8 requests to play chunks.
files:
14K sfx_enemy_gib.ogg
6.2K sfx_enemy_hit.ogg
12K sfx_enemy_hound_attack.ogg
9.5K sfx_grenade_bounce.ogg
21K sfx_grenade_explode.ogg
12K sfx_grenade_shoot.ogg
11K sfx_hurt.ogg
6.5K sfx_nailgun_hit.ogg
9.4K sfx_nailgun_shoot.ogg
4.6K sfx_no_ammo.ogg
9.0K sfx_pickup.ogg
13K sfx_plasma_shoot.ogg
6.8K sfx_shotgun_reload.ogg
14K sfx_shotgun_shoot.ogg
sfx_enemy_gib.ogg: Ogg data, Vorbis audio, stereo, 48000 Hz, ~112000 bps
sfx_enemy_hit.ogg: Ogg data, Vorbis audio, stereo, 48000 Hz, ~112000 bps
sfx_enemy_hound_attack.ogg: Ogg data, Vorbis audio, stereo, 48000 Hz, ~112000 bps
sfx_grenade_bounce.ogg: Ogg data, Vorbis audio, stereo, 48000 Hz, ~112000 bps
sfx_grenade_explode.ogg: Ogg data, Vorbis audio, stereo, 48000 Hz, ~112000 bps
sfx_grenade_shoot.ogg: Ogg data, Vorbis audio, stereo, 48000 Hz, ~112000 bps
sfx_hurt.ogg: Ogg data, Vorbis audio, stereo, 48000 Hz, ~112000 bps
sfx_nailgun_hit.ogg: Ogg data, Vorbis audio, stereo, 48000 Hz, ~112000 bps
sfx_nailgun_shoot.ogg: Ogg data, Vorbis audio, stereo, 48000 Hz, ~112000 bps
sfx_no_ammo.ogg: Ogg data, Vorbis audio, stereo, 48000 Hz, ~112000 bps
sfx_pickup.ogg: Ogg data, Vorbis audio, stereo, 48000 Hz, ~112000 bps
sfx_plasma_shoot.ogg: Ogg data, Vorbis audio, stereo, 48000 Hz, ~112000 bps
sfx_shotgun_reload.ogg: Ogg data, Vorbis audio, stereo, 48000 Hz, ~112000 bps
sfx_shotgun_shoot.ogg: Ogg data, Vorbis audio, stereo, 48000 Hz, ~112000 bps
Thanks,
– Ben