Just wondering how I could make a hit on the drum hat kill the hit that is playing, it presently just plays over top, for example if I have a longer sample and I want to start it again? thanks for any insight
It looks like Pygame’s Sound object supports stop
to stop it playing: https://www.pygame.org/docs/ref/mixer.html#pygame.mixer.Sound
I can’t see any way to determine if it’s currently playing, though. It seems a sensible approach would be to:
- Keep a value for each drum pad that you toggle on hit
- If that value is true then
.play()
the corresponding sound - If that value is false then
.stop()
the corresponding sound - Additionally you could light an LED to show which state a pad is in
This doesn’t seem to bode well for re-trigger though, since if you can’t tell if a sound is playing or stopped then if you do let the sound finish the next drum pad hit will try to stop it.
Apparently, though, you could have a channel for each drum pad and play the sound into that, allowing you to use the get_busy()
method:
https://www.pygame.org/docs/ref/mixer.html#pygame.mixer.Channel.get_busy
So I think your use-case is possible!
You can also combine this with loops=-1
for longer sounds, so they play in a continuous loop.
If you wanted to sync multiple sounds together (say percussion, rhythm and melody layers for a performance), you would have to play them all simultaneously and mute/unmute each channel on tap.
This is quite a useful setup, and would make for a good example!
Here’s a quick demo showing my last thought in action: https://gist.github.com/Gadgetoid/a0b2dd2d62b6e64298387fc54bf1ff9d
import time
import math
import pygame
NUM_CHANNELS = 3
pygame.mixer.init(44100, -16, 1, 512)
pygame.mixer.set_num_channels(NUM_CHANNELS)
channels = [pygame.mixer.Channel(n) for n in range(NUM_CHANNELS)]
melody = pygame.mixer.Sound("./fn-melody.wav")
bass = pygame.mixer.Sound("./fn-bass.wav")
percussion = pygame.mixer.Sound("./fn-percussion.wav")
channels[0].play(melody, loops=-1)
channels[1].play(bass, loops=-1)
channels[2].play(percussion, loops=-1)
channels[1].set_volume(0.5)
while True:
vol = (math.sin(time.time()) + 1) / 2
channels[0].set_volume(vol)
time.sleep(0.01)
This uses 3 loops played simultaneously and simply adjusts the volume of one with a sine wave to simulate how you might start/stop it.
A full example would need some differentiation between loops that play continuously from start-up and stay in sync, and single trigger sounds, but that’s not too tricky.
wow that’s great, i’ll get on this, my students are having a blast with the drum pad so i will try some of your ideas out and see where we go, thx so much!