Search code examples
pythonaudioraspberry-piraspberry-pi3raspbian

How to toggle audio playback using GPIO push button?


I want to play and pause an audio file using the same push button. What will be the solution of this problem? Please help me. I am using 'aplay', which player has such feature of toggling? here is the python code:

import RPi.GPIO as GPIO
import time
import os
import subprocess
GPIO.setmode(GPIO.BCM)

GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_UP) 
while True:
    input_state1=GPIO.input(17)
    if input_state1==False:
        subprocess.call(["aplay", "temp.wav"])

Solution

  • It looks like you are configuring an input pin, and this is what you are doing so far:

    • when pin is pressed, input_state1 will be True, and you do not do anything.
    • when pin is not pressed, input_state1 will be False and you are playing the temp.wav file using aplay (command-line sound recorder and player for ALSA).

    Correct me if I'm mistaken, but I understand your intention is to play and pause using the GPIO pin as a toggle (ie. when pressed, it should play if it is paused, or pause if it is playing).

    After a little searching, it looks like aplay cannot pause and resume like you would want to. If you still want to use this, you can use this aplay wrapper for Node.js called Node-aplay which supports this. Easier way is to use mpc, you'd have to first install it and and set it up. After that, you can try this code to do the toggling:

    import RPi.GPIO as GPIO
    import time
    import os
    import subprocess
    GPIO.setmode(GPIO.BCM)
    
    GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    
    # this method is invoked when the event occurs
    def toggle_state(channel):
        subprocess.call(["mpc", "toggle"]) # toggles between play and pause
    
    # detects GPIO pin press event
    GPIO.add_event_detect(17, GPIO.BOTH, toggle_state, 600)
    
    try:
        subprocess.call(["mpc", "add", "temp.wav"]) # adds file to the playlist
        subprocess.call(["mpc", "play"]) # starts playing (may need to mention position)
    except KeyboardInterrupt:
        GPIO.cleanup() # clean up GPIO settings before exiting
    

    As you can see, I have added GPIO.add_event_detect to detect the GPIO being pressed (read more about this API here). I have put some comments against what the code does too. Hope this helps!