3

How does reserving channels work? Can I reserve specific channels or are they picked randomly? There is no clear documentation on how it works and I seem to do it wrong because mixer.findChannel() still picks reserved channels.

Here's my code:

        self.music1 = pygame.mixer.Channel(0)
        self.music2 = pygame.mixer.Channel(1)
        self.sound1 = pygame.mixer.Channel(2)
        self.sound2 = pygame.mixer.Channel(3)
        self.sound3 = pygame.mixer.Channel(4)
        self.sound4 = pygame.mixer.Channel(5)
        self.sound5 = pygame.mixer.Channel(6)
        self.sound6 = pygame.mixer.Channel(7)
        
        pygame.mixer.set_reserved(2)

I'd like to reserve music1 and music2.

The documentation states that the argument of mixer.set_reserved() defines the number of channels that will be reserved.

If I can't pick which channels will be reserved, is there a way around it?

Thanks in advance

  • Indeed, there doesn't seem to be a way to determine which channels are reserved. So is it *even possible* to use a reserved channel? – Kingsley Feb 17 '21 at 04:10
  • Printing out `str( self.music )`, gives some address output, e.g.: ``. Printing out the result of `pygame.mixer.find_channel()` it gives an address *not already* assigned to a variable. So just assigning it seems to (possibly) reserve it somehow. Personally, I would just write your code without channel-reservation, and then worry about it when it's a problem. Currently I see no way around this limitation in the API. – Kingsley Feb 17 '21 at 04:14
  • I created some issues on pygame's bugtracker, so the documentation will be corrected in the future. – sloth Feb 17 '21 at 12:28

1 Answers1

1

Sometimes, pygame's documentation is lacking, and lot of stuff makes more sense if you look which SDL functions pygame actually calls and what those functions do.

So mixer.set_reserved() actually calls Mix_ReserveChannels, but does not return the number of reserved channels:

Mix_ReserveChannels

int Mix_ReserveChannels(int num)

Reserve num channels from being used when playing samples when passing in -1 as a channel number to playback functions. The channels are reserved starting from channel 0 to num-1. Passing in zero will unreserve all channels. Normally SDL_mixer starts without any channels reserved.

The following functions are affected by this setting:
4.3.3 Mix_PlayChannel
4.3.4 Mix_PlayChannelTimed
4.3.5 Mix_FadeInChannel
4.3.6 Mix_FadeInChannelTimed

mixer.findChannel() calls Mix_GroupAvailable:

Mix_GroupAvailable

int Mix_GroupAvailable(int tag)

Find the first available (not playing) channel in group tag.

As you can see, findChannel ignores reserved channels. Reserving a channel only prevents it from being automatically picked when using one of the functions above. Pygame uses Mix_PlayChannelTimed and Mix_FadeInChannelTimed, for example here.


To sum up, if you want to make sure a sound is played, reserve one or more channels with mixer.set_reserved.

Then, to play that important sound, use mixer.findChannel to either get a reserved channel or to get an unreserved, free channel. You could also create a new Channel instance with a channel number of 0 (or more if you reserved more than one channel) if you want to have full control over with channel to play the sound.

Play all other sounds without specifying a channel, and they will play only on non-reserved channels.

So the code in your question already does what you want: reserving channel 0 and 1.

sloth
  • 99,095
  • 21
  • 171
  • 219