tarff
Posts: 3
Joined: Thu Jul 21, 2016 5:08 am

Sound Loop GPIO Music Box

Thu Jul 21, 2016 5:36 am

Hi, I've been playing around with raspberry pi's for some time so I decided to take on a slightly more advanced project (for me anyway.)

I'm trying to build a soundboard that plays samples on a button press. I have the sounds playing and stopping on the button press, however, I cant for the life of me figure out how to get the sounds to play on a continuous loop until the button is pressed again.

I've search google and the forums and figure it has something to do with the hold_repeat function on gpiozero but I don't have much coding experience and cant work out where to fit it in the code.

The code I'm using is:

Code: Select all

import pygame.mixer
from pygame.mixer import Sound
from gpiozero import Button
from signal import pause

pygame.mixer.init()

sound_pins = {
    2: Sound("samples/sound1.wav"),
    3: Sound("samples/sound2.wav"),
}

print "pedal ready"

buttons = [Button(pin) for pin in sound_pins]
for button in buttons:
    sound = sound_pins[button.pin.number]
    button.when_pressed = sound.play
    button.when_released = sound.stop
    
pause()
Taken from here https://gpiozero.readthedocs.io/en/v1.2 ... -music-box

Any help would be greatly appreciated.

YCN-
Posts: 246
Joined: Fri Jun 10, 2016 3:18 pm

Re: Sound Loop GPIO Music Box

Thu Jul 21, 2016 10:09 am

Well, I don't really know a lot of python, but I'm working currently in a similar drum machine project. I'm doing it in C, but here's how I do what you want to do, I use an array int pattern [N_STEP][N_PATTERN] , and I fill it when a button is pressed, mean while I have two principal threads, one playing the sound and the other one witch just increasing the current step each n second (n depending on the BPM aka tempo you wanna have).
This is my way and it's working fine, but I have no idea how you can do thread in python ahah.

(Just in case a thread is an independent program that is running in your program if I can say so. It's not exactly that but if you don't what it is it's a good introduction and for what you want to do I think it's enough for you. I can give you sample of code to show you how threads work in C, but it won't be any help for python)

User avatar
elParaguayo
Posts: 1943
Joined: Wed May 16, 2012 12:46 pm
Location: London, UK

Re: Sound Loop GPIO Music Box

Thu Jul 21, 2016 11:29 am

Well, according to the pygame docs you can pass a loops parameter and setting that to -1 loops indefinitely.

So, you could try changing this line:

Code: Select all

button.when_pressed = sound.play
to

Code: Select all

button.when_pressed = lambda snd=sound: snd.play(loops=-1)
RPi Information Screen: plugin based system for displaying weather, travel information, football scores etc.

tarff
Posts: 3
Joined: Thu Jul 21, 2016 5:08 am

Re: Sound Loop GPIO Music Box

Fri Jul 22, 2016 1:46 am

Ah, thank you so much. That did it.

User avatar
elParaguayo
Posts: 1943
Joined: Wed May 16, 2012 12:46 pm
Location: London, UK

Re: Sound Loop GPIO Music Box

Fri Jul 22, 2016 6:08 am

My pleasure. Happy to help.
RPi Information Screen: plugin based system for displaying weather, travel information, football scores etc.

brandonandrsn
Posts: 3
Joined: Mon Jan 28, 2019 10:09 pm

Re: Sound Loop GPIO Music Box

Mon Jan 28, 2019 10:18 pm

im looking to do something similar.

play sound on GPIO button press and continue to play loop until the GPIO is pressed a second time.

so far my code is this.
it loops the sound while button is pressed but stops once released.
looking to build a crude loop sampler box

Code: Select all

import pygame.mixer
from pygame.mixer import Sound
from gpiozero import Button
from signal import pause

pygame .mixer.init()

button_sounds = {
	Button(21): Sound("samples/clap.wav"),
}

for button, sound in button_sounds.items():
	button.when_pressed = lambda snd=sound: snd.play(loops=-1)
	button.when_released = sound.stop

pause()

User avatar
elParaguayo
Posts: 1943
Joined: Wed May 16, 2012 12:46 pm
Location: London, UK

Re: Sound Loop GPIO Music Box

Tue Jan 29, 2019 9:39 am

One way to do this would be to make the sound play on a particular channel. You can then use the "get_busy" method of the channel to check if the sound is playing.

Your on_pressed method would then call a function that checks if a sound is playing. If it isn't, then it starts it. If it is, then it stops it.

If you're only going to be playing one sound then you can just use pygame.mixer.get_busy instead.
RPi Information Screen: plugin based system for displaying weather, travel information, football scores etc.

brandonandrsn
Posts: 3
Joined: Mon Jan 28, 2019 10:09 pm

Re: Sound Loop GPIO Music Box

Tue Jan 29, 2019 11:07 am

elParaguayo wrote:
Tue Jan 29, 2019 9:39 am
One way to do this would be to make the sound play on a particular channel. You can then use the "get_busy" method of the channel to check if the sound is playing.

Your on_pressed method would then call a function that checks if a sound is playing. If it isn't, then it starts it. If it is, then it stops it.

If you're only going to be playing one sound then you can just use pygame.mixer.get_busy instead.
mind showing me how one would do so? how do i set a sound to a particular channel and use the get busy?

User avatar
elParaguayo
Posts: 1943
Joined: Wed May 16, 2012 12:46 pm
Location: London, UK

Re: Sound Loop GPIO Music Box

Tue Jan 29, 2019 1:00 pm

OK. By default I think pygame has 8 channels but I think you can increase this.

As for the code, I was just thinking something along the lines of:

Code: Select all

import pygame.mixer
from pygame.mixer import Sound
from gpiozero import Button
from signal import pause

pygame.mixer.init()

button_sounds = {
	Button(21): {"channel": 0, "sound": Sound("samples/clap.wav")},
}

def start_stop_sound(snd):
    channel = pygame.mixer.Channel(snd["channel"])
    if channel.get_busy():
        # Sound is playing - stop it
        channel.stop()
    else:
        # No sound playing on this channel
        sound = snd["sound"]
        channel.play(sound, loops=-1)

for button, sound in button_sounds.items():
	button.when_pressed = lambda snd=sound: start_stop_sound(snd)

pause()
Code is untested but I hope this gives you and idea of what I was trying to do.
RPi Information Screen: plugin based system for displaying weather, travel information, football scores etc.

brandonandrsn
Posts: 3
Joined: Mon Jan 28, 2019 10:09 pm

Re: Sound Loop GPIO Music Box

Thu Jan 31, 2019 12:58 am

elParaguayo wrote:
Tue Jan 29, 2019 1:00 pm
OK. By default I think pygame has 8 channels but I think you can increase this.

As for the code, I was just thinking something along the lines of:

Code: Select all

import pygame.mixer
from pygame.mixer import Sound
from gpiozero import Button
from signal import pause

pygame.mixer.init()

button_sounds = {
	Button(21): {"channel": 0, "sound": Sound("samples/clap.wav")},
}

def start_stop_sound(snd):
    channel = pygame.mixer.Channel(snd["channel"])
    if channel.get_busy():
        # Sound is playing - stop it
        channel.stop()
    else:
        # No sound playing on this channel
        sound = snd["sound"]
        channel.play(sound, loops=-1)

for button, sound in button_sounds.items():
	button.when_pressed = lambda snd=sound: start_stop_sound(snd)

pause()
Code is untested but I hope this gives you and idea of what I was trying to do.
thank you so mucch

Return to “Graphics, sound and multimedia”