Trying to play music while opening a door - python

EDIT : replaced GPIO.PUD_UP to GPIO.PUD_DOWN and while loop looks like this now :
playing = False
while True:
if GPIO.input(26)==False:
if not playing:
pygame.mixer.music.play()
playing = True
else:
if playing:
pygame.mixer.music.stop()
playing = False
I'm trying to play music while opening a door, doing it with a raspberry pi Zero WH and an Hall effect sensor. I'm rather new to python, but its fairly simple. But im stuck because i can't find how to do exactly what I want.
So I want to play music when the door is opened (GPIO is LOW), but i also want it to stop when it is closed (when GPIO is UP then). It seems that I can't find how to do it. Here's my code :
import RPi.GPIO as GPIO
import time
import pygame
import pygame.mixer
pygame.mixer.init()
pygame.init()
scary = pygame.mixer.Sound("scary.wav")
pygame.mixer.music.set_volume(0.1)
GPIO.setmode(GPIO.BCM)
GPIO.setup(26, GPIO.IN, pull_up_down=GPIO.PUD_UP)
while True:
if GPIO.input(26)==False:
pygame.mixer.music.play()
while GPIO.input(26)==False:
pass
else:
pygame.mixer.music.stop()
while GPIO.input(26)==True:
pass
I want music to play as soon as the door open, only once (its about a minute long), but can stop whenever the door close. How should I do it ? (time.sleep(x) just delays the whole loop, or maybe idk how to use it?) Thanks !

Addd a variable to keep track if the music is currently playing:
playing = False
while True:
if gpio is high:
if not playing:
play()
playing = True
else:
if playing:
stop()
playing = False
You can't rid of the indentation by using if/else with and/or statements.

Related

Trying to record audio whilst a gpio input is high in scipy

I am trying to make wedding guest answer phone for my sister. The basic idea of these things is you pick up the handset, hear a message from the host, leave you own, replace the handset, and the recording stops and saves. I have set all of the hardware up fine, it works, but as I have essentially no experience with coding getting all of the individual aspects to work is my issue.
For the recording aspect scipy seems to work the best, I have been using this for 5 second test recordings.
import sounddevice as sd
from scipy.io.wavfile import write
import wavio as wv
import uuid
freq = 44100
duration = 5
recording = sd.rec(int(duration * freq),
samplerate=freq, channels=2)
sd.wait()
write("recording0_"+str(uuid.uuid4())+".wav", freq, recording)
The main issue is these messages are only 5 seconds, I don't know how to make them start recording after the host message and stop when the handset is replaced.
The following is the code that I have been using to play a test for the host message when the handset is picked up.
import RPi.GPIO as gpio
import pygame
gpio.setmode(gpio.BCM)
gpio.setup(23, gpio.IN, pull_up_down=gpio.PUD_UP)
gpio.setwarnings(False)
def rising(channel):
gpio.remove_event_detect(23)
print ('Button up')
pygame.mixer.init()
sound = pygame.mixer.Sound('/home/pi/Documents/E and R/test1.wav')
playing = sound.play()
while playing.get_busy():
pygame.time.delay(100)
gpio.add_event_detect(23, gpio.FALLING, callback=falling, bouncetime=10)
def falling(channel):
gpio.remove_event_detect(23)
print ('Button down')
gpio.add_event_detect(23, gpio.RISING, callback=rising, bouncetime=10)
gpio.add_event_detect(23, gpio.FALLING, callback=falling, bouncetime=10)
try:
raw_input()
except KeyboardInterrupt:
gpio.cleanup()
gpio.cleanup()
There are a few problems with this, I have tried changing the order of various aspects and either when you lift the handset and the audio is played it doesn't read if the handset is replaced while the audio is playing. Or in another version if you tap the handset switch a bunch of times it layers copies of the audio on top of each other.
Also I know that raw_input() is not used in python 3 but if I just use input() the code doesn't work and if I omit the whole section it doesn't work.
Basically, I'm illiterate and any help smashing this all together and showing me how to get audio recordings for an in-determinant length of time would be greatly appreciated.
Also if this helps I'm using a Raspberry pi 4 and Python 3.9.2.

Raspberry Pi loop within a loop triggerd by button

I've written a short piece of code for my Raspberry Pi. The idea is to place the device in a room and when a group of people enter the room (it's a guided tour), the Pi is triggerd by the motion sensor and starts playing a video projected on the wall. So far this works.
When the movie is done playing, I set it to sleep for 10 minutes until the next group enters the room.
I've noticed that sometimes it takes less then 10 minutes before a new group enters the room but the Pi is still sleeping.
I want to solve this by adding a button to my device to manually trigger the loop again. I've wired it to my Pi and it works.
The idea is to manually start the loop when I press the button so the group can see the video. Afterwords the script should go back to normal so the motionsensor picks up the next group.
I can't figure out how to do this. A loop within the first loop? Cut out the 10 minutes sleep in the loop and place it somewhere else?
Hoping someone has some advice.
Thanks in advance.
Below my code:
from gpiozero import MotionSensor, LED, Button
from time import sleep
import vlc
playing = set([1,2,3,4])
# creating Instance class object
vlc_instance = vlc.Instance()
player = vlc_instance.media_player_new()
player.set_fullscreen(True)
#Motion Sensor
pir = MotionSensor(4)
#Led
led = LED(26)
#Button
button= Button(18)
led.off()
print("Sensor wordt geladen.")
pir.wait_for_no_motion()
sleep(5)
while True:
print("Ready")
pir.wait_for_motion()
sleep(1)
print("Motion detected")
led.on()
sleep(1)
led.off()
player.set_mrl("/media/pi/GROT/MOSA25.mp4")
player.play()
sleep(120)
while player.get_state() in playing:
sleep(1)
continue
print("Finished")
sleep(600)
continue

Pygame: No such audio device [duplicate]

I'm trying to play sound files (.wav) with pygame but when I start it I never hear anything.
This is the code:
import pygame
pygame.init()
pygame.mixer.init()
sounda= pygame.mixer.Sound("desert_rustle.wav")
sounda.play()
I also tried using channels but the result is the same
For me (on Windows 7, Python 2.7, PyGame 1.9) I actually have to remove the pygame.init() call to make it work or if the pygame.init() stays to create at least a screen in pygame.
My example:
import time, sys
from pygame import mixer
# pygame.init()
mixer.init()
sound = mixer.Sound(sys.argv[1])
sound.play()
time.sleep(5)
sounda.play() returns an object which is necessary for playing the sound. With it you can also find out if the sound is still playing:
channela = sounda.play()
while channela.get_busy():
pygame.time.delay(100)
I had no sound from playing mixer.Sound, but it started to work after i created the window, this is a minimal example, just change your filename, run and press UP key to play:
WAVFILE = 'tom14.wav'
import pygame
from pygame import *
import sys
mixer.pre_init(frequency=44100, size=-16, channels=2, buffer=4096)
pygame.init()
print pygame.mixer.get_init()
screen=pygame.display.set_mode((400,400),0,32)
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if event.key==K_ESCAPE:
pygame.quit()
sys.exit()
elif event.key==K_UP:
s = pygame.mixer.Sound(WAVFILE)
ch = s.play()
while ch.get_busy():
pygame.time.delay(100)
pygame.display.update()
What you need to do is something like this:
import pygame
import time
pygame.init()
pygame.mixer.init()
sounda= pygame.mixer.Sound("desert_rustle.wav")
sounda.play()
time.sleep (20)
The reason I told the program to sleep is because I wanted a way to keep it running without typing lots of code. I had the same problem and the sound didn't play because the program closed immediately after trying to play the music.
In case you want the program to actually do something just type all the necessary code but make sure it will last long enough for the sound to fully play.
import pygame, time
pygame.mixer.init()
pygame.init()
sounda= pygame.mixer.Sound("beep.wav")
sounda.play()
pygame.init() goes after mixer.init(). It worked for me.
I had the same problem under windows 7. In my case I wasn't running the code as Administrator. Don't ask me why, but opening a command line as administrator fixed it for me.
I think what you need is pygame.mixer.music:
import pygame.mixer
from time import sleep
pygame.mixer.init()
pygame.mixer.music.load(open("\windows\media\chimes.wav","rb"))
pygame.mixer.music.play()
while pygame.mixer.music.get_busy():
sleep(1)
print "done"
You missed to wait for the sound to finish. Your application will start playing the sound but will exit immediately.
If you want to play a single wav file, you have to initialize the module and create a pygame.mixer.Sound() object from the file. Invoke play() to start playing the file. Finally, you have to wait for the file to play.
Use get_length() to get the length of the sound in seconds and wait for the sound to finish:
(The argument to pygame.time.wait() is in milliseconds)
import pygame
pygame.mixer.init()
sounda = pygame.mixer.Sound('desert_rustle.wav')
sounda.play()
pygame.time.wait(int(sounda.get_length() * 1000))
Alternatively you can use pygame.mixer.get_busy to test if a sound is being mixed. Query the status of the mixer continuously in a loop.
In the loop, you need to delay the time by either pygame.time.delay or pygame.time.Clock.tick. In addition, you need to handle the events in the application loop. See pygame.event.get() respectively pygame.event.pump():
For each frame of your game, you will need to make some sort of call to the event queue. This ensures your program can internally interact with the rest of the operating system.
import pygame
pygame.init()
pygame.mixer.init()
sounda = pygame.mixer.Sound('desert_rustle.wav')
sounda.play()
while pygame.mixer.get_busy():
pygame.time.delay(10)
pygame.event.poll()
Your code plays desert_rustle.wav quite fine on my machine (Mac OSX 10.5, Python 2.6.4, pygame 1.9.1). What OS and Python and pygame releases are you using? Can you hear the .wav OK by other means (e.g. open on a Mac's terminal or start on a Windows console followed by the filename/path to the .wav file) to guarante the file is not damaged? It's hard to debug your specific problem (which is not with the code you give) without being able to reproduce it and without having all of these crucial details.
Just try to re-save your wav file to make sure its frequency info. Or you can record a sound to make sure its frequency,bits,size and channels.(I use this method to solve this problem)
I've had something like this happen. Maybe you have the same problem? Try using an absolute path:
import pygame
pygame.init()
pygame.mixer.init()
sounda= pygame.mixer.Sound("/absolute_path/desert_rustle.wav")
sounda.play()
Where abslute_path is obviously replaced with your actual absolute path ;)
good luck.
import pygame
pygame.init()
sound = pygame.mixer.Sound("desert_rustle.wav")
pygame.mixer.Sound.play(sound)
This will work on python 3
5 years late answer but I hope I can help someone.. :-)
Firstly, you dont need the "pygame.init()"-line.
Secondly, make a loop and play the sound inside that, or else pygame.mixer will start, and stop playing again immediately.
I got this code to work fine on my Raspberry pi with Raspbian OS.
Note that I used a while-loop that continues to loop the sound forver.
import pygame.mixer
pygame.mixer.init()
sounda = pygame.mixer.Sound("desert_rustle.wav")
while True:
sounda.play()
Just try:
import pygame.mixer
from time import sleep
pygame.mixer.init()
pygame.mixer.music.load(open("\windows\media\chimes.wav","rb"))
print ""
pygame.mixer.music.play()
while pygame.mixer.music.get_busy():
sleep(1)
print "done"
This should work. You just need to add print ""and the sound will have
had time to load its self.
Many of the posts are running all of this at toplevel, which is why the sound may seem to close. The final method will return while the sound is playing, which closes the program/terminal/process (depending on how called).
What you will eventually want is a probably a class that can call either single time playback or a looping function (both will be called, and will play over each other) for background music and single sound effects.
Here is pattern, that uses a different event loop / run context other than Pygame itself, (I am using tkinter root level object and its init method, you will have to look this up for your own use case) once you have either the Pygame.init() runtime or some other, you can call these methods from your own logic, unless you are exiting the entire runtime, each file playback (either single use or looping)
this code covers the init for ONLY mixer (you need to figure our your root context and where the individual calls should be made for playback, at least 1 level inside root context to be able to rely on the main event loop preventing premature exit of sound files, YOU SHOULD NOT NEED TIME.SLEEP() AT ALL (very anti-pattern here).... ALSO whatever context calls the looping forever bg_music, it will probably be some 'level' or 'scene' or similar in your game/app context, when passing from one 'scene' to the next you will probably want to immediately replace the bg_music with the file for next 'scene', and if you need the fine-grained control stopping the sound_effect objects that are set to play once (or N times)....
from pygame import mixer
bg_music = mixer.Channel(0)
sound_effects = mixer.Channel(1)
call either of these from WITHIN your inner logic loops
effect1 = mixer.Sound('Sound_Effects/'+visid+'.ogg')
sound_effects.play(effect1, 0)
sound1 = mixer.sound('path to ogg or wav file')
bg_music.play(sound1, -1) # play object on this channel, looping forever (-1)
do this:
import pygame
pygame.mixer.init()
pygame.mixer.music.load("desert_rustle.wav")
pygame.mixer.music.play(0)
I think that your problem is that the file is a WAV file.
It worked for me with an MP3. This will probably work on python 3.6.

How to continue a sound in Pygame?

I have a sound that I wish to play.
My code;
[...]
if var_camera_flip == 1:
if var_camera != 4:
pygame.mixer.Channel(2).play(pygame.mixer.Sound(r'audio\camera\camera motor.mp3'), -1)
else:
pygame.mixer.Channel(2).stop()
else:
pygame.mixer.Channel(2).stop()
[...]
This code is in a subroutine that I call. What happens is that it restarts the sound each time it runs. What I want is that is the sound to continue playing until it is told not to.
Do not stop a sound, but pause it with pygame.mixer.Channel.pause:
pygame.mixer.Channel(2).pause()
Once a sound is paused it can be continued with pygame.mixer.unpause:
pygame.mixer.Channel(2).unpause()

pygame is not working

I am trying to play a song with pygame and it is not playing the song.
My code:
import pygame,time
pygame.init()
print "Mixer settings", pygame.mixer.get_init()
print "Mixer channels", pygame.mixer.get_num_channels()
pygame.mixer.music.set_volume(1.0)
pygame.mixer.music.load('C:/1.mp3')
print "Play"
pygame.mixer.music.play(0)
while pygame.mixer.music.get_busy():
print "Playing", pygame.mixer.music.get_pos()
time.sleep(1)
print "Done"
I am getting output as
Mixer settings (22050, -16, 2)
Mixer channels 8
Play
Done
Your code works for me, on Lubuntu 11.10 running Python 2.7.2, with an MP3 I converted from a Youtube clip. Have you checked that the mp3 is not zero length? Have you tried a wav file?
Lacking other explanations, I think it is conceivable that pygame.mixer.music.get_busy() could be returning false if the play(0) call hasn't finished starting its process or thread.
This would cause your code to skip the while loop, print "Done", and terminate, deleting the music player object and terminating playback before you got to hear anything. If this is the problem, you could try something like this after play(0) and before print Done:
pygame.mixer.music.set_endevent(pygame.USEREVENT)
finishedPlaying = False
while not finishedPlaying:
for event in pygame.event.get():
if event.type == pygame.USEREVENT:
finishedPlaying = True
break # only because we don't care about any other events
print "Playing", pygame.mixer.music.get_pos() # will print -1 on the last iteration
in the comments of pygame.mixer.music.play i found this:
November 18, 2010 7:30pm - Anonymous
Work Exmpl:
pygame.mixer.init(frequency=22050, size=-16, channels=2, buffer=4096)
sound = pygame.mixer.Sound('Time_to_coffee.wav').play()
also it seems that your sending 0 as the amount of times you want to repeat it thanks Iskar Jarak , -1 is infinity.
http://www.pygame.org/docs/ref/music.html#pygame.mixer.music.play

Categories

Resources