How do you reserve a pygame.mixer Channel in pygame?

Viewed 155

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

1 Answers

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.

Related