Manipulate the volume of a constantly repeating audio in Pyglet - python

How can I manipulate the volume of the audio loaded via pyglet.media.load?
The reason is that I have to repeat a sound repeatedly (eg bullets), but if I use the Player, the sound is queued to be able to play it and plays it only once using .play() (eg bullet = pyglet.media.load("bullet.wav", streaming=False) audioPlayer = pyglet.media.Player() audioPlayer.queue(bullet) if the audioPlayer.play() command is used several times, for example from a key, it is executed only once and that's it)
If I don't use the Player, I can use the sound constantly, but at that point I can no longer manipulate the volume of the audio. (eg bullet = pyglet.media.load("bullet.wav", streaming=False) bullet.play())
So how can I go about solving the problem? I don't have much experience using Pyglet audio, so I'm probably ignoring something I'm not aware of.

The audio player is the correct approach as you can set volume on the player.
audioPlayer.volume = 0.5
Under the hood all the media.play() command does is create a Player instance, queue and play it. If you want to replay something, simply queue the source and play the player again. If you need audio overlaps, then you would create separate Player instances every time, like media.play() would.

Related

How can I tell the progress of a VLC MediaListPlayer?

I have a Raspberry Pi 3b that I'm using to play music. When a button (GPIO) is pressed, I want to play a list of songs. I'm doing this using the vlc media list player. I build a media list by grabbing N random mp3 files from a directory.
eg:
i=vlc.Instance()
l=i.media_list_new()
l.insert_media(i.media_new(...)) # this loops and grabs random mp3s
p=i.media_list_player_new()
p.set_media_list(l)
p.play()
Another GPIO signal will call p.stop(). What I want to know at that point is which songs in the media list have been played. This way I can track them and not play them again the next time the Play button is pressed, but the unplayed tracks in the list should still be eligible to play.
So far I don't see any way to get any info from the media list player on what item in the list it's on or another way to tell what has been played from the list.
I tried an alternative of manually looping through a list of songs and using a regular player (not list player), but when I do this I have to do a while True loop to make the player wait for one song to finish before playing the next one. This loop also seems to block my GPIO event handler for some reason and pressing the STOP button goes undetected (have to cancel the script to stop).
My advice would be: Don't use the MediaListPlayer.
Use a MediaList along with a MediaPlayer and listen for libvlc_MediaListEndReached https://www.videolan.org/developers/vlc/doc/doxygen/html/group__libvlc.html
loop to make the player wait for one song to finish before playing the next one
Use libvlc events.
Actually got this working using the MediaListPlayer and events. I added an event handler for MediaListPlayerNextItemSet that calls a function that increments a counter, so I know how many songs in the list were played now.

How to stop sound in pygame?

Ok so basically I'm working on this pygame game and I'm using the mixer sub module for sounds. However, in pygame if you want to stop a sound, the sound must finish its cycle until it can be stopped. For all my sounds this is ok as they can be a looped 1 second sound. However, I use a falling sound which needs to constantly play in a cycle, but cycling a falling sound that is only 1 second long doesn't sound very effective. So, ultimately I want to know if there is a way to stop a 7 second sound loop instantly without it finishing a cycle.
According to the pygame documentation for pygame.mixer
pygame.mixer.pause()
will temporarily stop playback of all sound channels. You can start them all playing again with;
pygame.mixer.unpause()
For an individual sound, whilst it will stop after a full cycle, you can immediately affect it's volume with;
pygame.mixer.Sound.set_volume(0)
So what I'd try first is stopping the sound at the same time as setting it's volume to zero and seeing if that solves your problem. Alternatively, you can split your mixer into Channels for better controlling sound playback, which will give you the ability to use
pygame.mixer.Channel.pause()
pygame.mixer.Channel.unpause()
On specific groups of sounds rather than all sound. You create a mixer channel with;
pygame.mixer.Channel(id)
You can then play specific sounds on that channel with;
pygame.mixer.Channel.play(Sound, loops=0, maxtime=0, fade_ms=0)
This would also allow you to more dynamically adjust the levels of various types of sounds in your game - for example, environment, music, weather, voices and how they overlap each other, just keep in mind a channel can only play one sound at a time. Because of this, it may by prudent to use;
free_channel = pygame.mixer.find_channel()
free_channel.play(Sound)
or more simply;
pygame.mixer.find_channel().play(Sound)
For everything except your 'falling' channel.

How do I handle Amazon AudioPlayer events?

I'm writing a simple Alexa Skill that utilizes AudioPlayer to play a long audio file. This StackOverflow answer nicely demonstrates the use of directives to play (and stop) audio, but I'm not quite sure how to intercept AudioPlayer events like PlayBackStopped and PlayBackPaused. Basically I'm trying to let the user pause an audio stream and then resume playing where they last left off. Any examples in Python would be very welcome!
I'm not quite sure how to intercept AudioPlayer events like
PlayBackStopped and PlayBackPaused
Events such as PlaybackPaused are Audio requests notifying the player about the state. So whenever a user pauses in an active session, you will get two events one is STOP and other is PlayBackPaused.
I'm trying to let the user pause an audio stream and then resume
playing where they last left off
So whenever you get PlayBackStopped you also get offset in milliseconds. You can take that offset and store in DynamoDB or any persistent storage. When the user returns just check is he has any offset and start from there.
Amazon Documentation
Example of python ask-SDK multistream audio player.

python pygame how to fade in the volume?

song = "choy_san_dou.ogg"
pygame.init()
pygame.display.set_mode((200,100))
pygame.mixer.init()
pygame.mixer.music.load(song)
pygame.mixer.music.set_volume(0.1)
pygame.mixer.music.play(0)
I am unable to find a way to fade in the volume when the song is loaded, means to have the volume of the song slowly increase until a max volume instead of blasting it off full volume from the very beginning. How to do it?
Another problem is this, I must declare
pygame.display.set_mode((200,100))
or the sound won't play. The program is actually running because after time of the sound has elapsed, the subsequent steps in the program continues. Why is it this way? I am testing it on windows pc, with the intention of transferring it to a raspberry pi later.
The pygame.mixer module has a Sound class (doc: http://www.pygame.org/docs/ref/mixer.html) that takes a file name as input and converts the file contents to a Sound object. Sound objects have a method play() where you can specify an amount of time where the Sound is faded in (you likely want to make it much shorter than the actual length of the Sound). I suggest you read the documentation to get the gist of how pygame.mixer works. If you want to alter the Sound object, such as adding fade-in or fade-out, there's the pygame.sndarray module that can convert a Sound object to a numpy array and vice versa, though you'll need to use numpy or scipy to do stuff with that array (I recommend the free Anaconda package).
The difference between the music and the mixer module is that the music module STREAMS data to playback, while the mixer module handles data saved to main memory.

Playback of at least 3 music files at one in python

I am searching for a way/framework to play at least 3 music files at one in a python application. It should run at least under ubuntu and mac as well as on the raspberry pi.
I need per channel/music file/"deck" that is played:
Control of the Volume of the Playback
Control of the start position of the playback
Play and Pause/Resume functionality
Should support mp3 (Not a must but would be great!)
Great would be built in repeat functionality really great would be a fade to the next iteration when the song is over.
If I can also play at least two video files with audio over the same framework, this would be great, but is not a must.
Has anyone an Idea? I already tried pygame but their player can play just one music file at once or has no control over the playback position.
I need that for a theatre where a background sound should be played (and started simultaneosly with the light) and when it is over, a next file fades over. while that is happening there are some effects (e.g. a bell) at a third audio layer.
I finally got an answer/workaround.
I am using pythons multiprocessing class/functionality to run multiple pygame instances.
So i can play more than one music file at a time with fully control over playmode and playback position.

Categories