• Advertisement
Sign in to follow this  

SDL_Mixer playback problem (C++)

This topic is 3558 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

Got a problem with sample playback in SDL_Mixer. If I want to restart the sample (Mix_Chunk) I'm currently playing, first I have to stop it in a DIFFERENT cycle. If I stop it right before playing it, the program will crash... (OS: OSX 1.5.2; SDL_Mixer version is 1.2.8) code:
const int PAN_LEFT(0);
const int PAN_RIGHT(254);
const int PAN_CENTER(127);

struct SampleState
  Mix_Chunk *pChunk_;
  int channel_;
  int volume_;
  int panning_;

  explicit SampleState(Mix_Chunk *p): pChunk_(p), channel_(-1), volume_(MIX_MAX_VOLUME), panning_(PAN_CENTER) {}
  ~SampleState() {};

  bool SetSample(Mix_Chunk *pC) {
    Stop(); // SampleState doesn't own the chunk, it is only responsible for the channel
    if(pC == 0) { return false; }
    pChunk_ = pC;
    return true;

  void SetVolume(int vol) {
    volume_ = vol;
    if(channel_ < 0) { return; }
    volume_ = ::Mix_Volume(channel_, volume_);

  void SetPanning(int panning) {
    panning_ = panning;
    if(channel_ < 0) { return; }
    ::Mix_SetPanning(channel_, PAN_RIGHT - panning_, panning);

  void Play(int loops = 0, int ticks = -1, int channelPref = -1) {
    if(channel_ < 0) {
      channel_ = ::Mix_PlayChannelTimed(channelPref, pChunk_, loops, ticks);

  void Stop() {
    if(channel_ < 0) { return; }
    channel_ = -1;

// initial setup, skipped

Mix_Chunk *pMyChunk(::Mix_LoadWAV("test.wav"));
SampleState myState(pMyChunk);

SDL_Event e;
bool done(false);
bool toProcess;

while(!done) {
  toProcess = ::SDL_PollEvent(&e);
  Uint8 *kStates(::SDL_GetKeyState(0));

  if(toProcess) {
    switch(e.type) {
    case SDL_QUIT:
      done = true;
  if(kStates[SDLK_SPACE] == 1) {
      /* crash code (if placed here):
  // non-crash code:
  else {

So: - when I place something that calls ::Mix_HaltChannel() in front of ::Mix_PlayChannel(), it will crash the program. - if I place it so as the two doesn't get executed in the same cycle, they're OK (I guess it's sort of a timing issue, but not being multithread(head)ed, I can't afford waiting in the performance-intensive part of the program for a comfortability feature (I used to call Stop() from within Play()). - and I can't Play() the sample again if I don't Stop(), as the channel won't be reset. I know I could do this by using a call-back function (with ::Mix_ChannelFinished), but I have no way to correspond the call-back function's signature (void (*cbfunc)(int /*channelID*/)) to my SampleStates. (attempts included storing channels in my Mixer class (basically an initializer for the SDL_Mixer) and giving SampleState a static member std::vector <SampleState*> for each channel) - if I remove the channel check in Play() I lose track of the channel and soon run out of channels -> crash. do I have a completely wrong grasp on SDL_Mixer with this SampleState model? does it make sense at all to write a C++ 'wrapper' around SDL_Mixer? [Edited by - trajectorymodifier on June 23, 2008 8:00:40 AM]

Share this post

Link to post
Share on other sites
You must check the result of SDL_PollEvent and only handle the event if it actually exists! Fix that and see if it makes a difference. It probably won't, but it's worth eliminating.

(And PAN_RIGHT should probably be 255, no?)

Share this post

Link to post
Share on other sites
thanks Kylotan, fixed it. I guess I should've put the SDL_GetKeyState() version the first place, as it's not only truer to what's in the original code, but clearer too... (in the original I only used e (after polling) to check against an SDL_QUIT)

unfortunately, it wasn't the problem.

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement