Hi,
Sometimes SDL_mixer hangs when plays a sound chunk continuously in the same
channel during playing music because of a dead lock.
When the function Mix_PlayChannel() is called, it locks mixer_lock.
Then, if that channel is playing, _Mix_channel_done_playing() is called.
It calls SDL_LockAudio() to block audio callback.
On the other hand, mix_channels() is called from SDL as a callback funciton.
mix_channels() tries to lock mixer_lock.
So that, when mix_channels is trying to lock mixer_lock, and _Mix_channel_done_playing
is trying to call SDL_LockAudio at the same time, they causes a dead lock.
I hacked Mix_PlayChannelTimed(); changed the second arg of _Mix_channel_done_playing()
from 1 to 0. I have no idea this hack is valid or invalid, but it works well.
-----Test code is following-----
#include <stdio.h>
#include <stdlib.h>
#include <SDL/SDL.h>
#include <SDL/SDL_mixer.h>
#include <unistd.h>
static int audio_rate;
static Uint16 audio_format;
static int audio_channels;
static int audio_buffers;
static char *musicNormal = “music.mp3”;
static char soundFiles = “sound.wav”; / modify these file name */
static Mix_Music *currentMusic;
static Mix_Chunk *soundEffect;
int main()
{
SDL_Event event;
audio_rate = 22050;
audio_format = AUDIO_S16;
audio_channels = 2;
audio_buffers = 512;
SDL_Init(SDL_INIT_AUDIO|SDL_INIT_TIMER);
atexit(SDL_Quit);
if (Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers) < 0) {
printf("Couldn't open audio: %s\n", SDL_GetError());
exit(1);
}
Mix_QuerySpec(&audio_rate, &audio_format, &audio_channels);
printf("Opened audio at %d Hz %d bit %s, %d bytes audio buffer\n", audio_rate,
(audio_format&0xFF),
(audio_channels > 1) ? "stereo" : "mono",
audio_buffers );
Mix_ReserveChannels(audio_channels);
Mix_SetMusicCMD(getenv("MUSIC_CMD"));
soundEffect = Mix_LoadWAV(soundFiles);
if(soundEffect == NULL) {
printf("Failed to load sound file %s.\n", soundFiles);
exit(1);
}
currentMusic = Mix_LoadMUS(musicNormal);
Mix_PlayMusic(currentMusic, 0);
while(Mix_PlayingMusic()) {
Mix_PlayChannel(2, soundEffect, 0);
usleep(10000);
while(SDL_PollEvent(&event)) {
if(event.type == SDL_QUIT) exit(1);
}
}
return 0;
}