0

the topic name might seem a bit chaotic, but I'm struggling to describe in one line what I mean. I want to create a python script that plays different sounds when certain button is pressed. So far I came to this point:

import RPi.GPIO as GPIO
import time
import pygame

GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_UP)

pygame.mixer.init()
bang = pygame.mixer.Sound('aa.wav')

while True:
    input_state = GPIO.input(18)
    input_state2 = GPIO.input(17)
    if input_state == False:
        print('Button pressed')
        bang.play()
        time.sleep(1.5)
    if input_state2 == False:
        print('Button2 pressed')
        time.sleep(0.3)

GPIO.cleanup()

I used time.sleep(1.5), because this is how long the sound is. If I don't do that, when I press the button I hear the sound multiple times (and I understand that this is how it's supposed to be). All this implies that on a button press I want to hear the sound ONCE only, and then it can play again after the previous execution is finished.

Technically the sleep solves the problem... But only when there is one sound I want to use. Is there a chance I can in some way get a polyphonic output? Like... When I press both buttons in the same time, I get two different sounds (but each of them still plays only once)? I believe the sleep function doesn't have use in this case, but as I'm new to python, I don't know an alternative and I don't know how to look for it...

Thanks for any help, S.

  • While not explicitly off-topic here, as you are attempting to program Python on the Raspberry Pi, this question might fit better on Stack Overflow. That's a programming-specific site, whereas this site is Raspberry Pi-specific. We would love to help you, but I believe you will get better answers on Stack Overflow. – RPiAwesomeness Oct 27 '14 at 13:02
0

you should look for a state change in your program:

while True :
    current_state = GPIO.input(..)

    if previous_state != current_state :
        if current_state == False :
            # whatever

    previous_state = current_state
0

From the pygame documentation it seems that the pygame.mixer mixes sound in background threads. That's why when you use bang.play() it starts playing the sound in another thread and immediately returns to your if block and executes the next statement which is sleep(1.5). Essentially you are simply blocking your main program thread from executing while the sound plays because you simply timed the sleep statement to match the sound's play time! So if you want to play two sounds simultaneously, all you need to do is create another object like 'bang'( for example bang2) associated with the other sound file you wish to play and do something like

bang.play()

bang2.play()

time.sleep(x)

Where x should be the equal to the higher of the two play times of the tracks you wish to play. Do remember the number of "bangs" you can create and play simultaneously depends on the number of audio channels available.

  • I think that Lenik understood me a bit better. I know that this sleep is blocking another activities and I understand why it's acting this way. The thing is I don't really know if I can find a workaround. Imagine I wanted to create an interactive piano (technically this is what I'd want to achieve... kind of). Even when I look for a state change, it still won't work as expected, cause the sound that lasts 1.5 in this case will still start playing more than once. Mhhhhhh, I wish I could just make it sleep for a certain if case instead of entire program, but I doubt this can be done after all. – squid Oct 19 '14 at 19:16
  • Okay!! Lets consider you are going to make a piano. So essentially you want all buttons to be ready and play once if pressed. You could do this using event based programming then, with each button press an event having a callback function to play sound. Turns out that the Raspberry pi GPIO library is exavtly what you need! Check this out sourceforge.net/p/raspberry-gpio-python/wiki/Inputs Also, the switch debouncing should remove the multiple play on button press problem. – taz Oct 19 '14 at 19:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.