Changing volume in pygame.mixer (almost) no effect - python-2.7

I'm trying to make an application in tkinter that has a number of buttons you can assign sound on and play it later. The click of the button itself only calls play() method, so loading of the sound is done beforehand.
I tried making some kind of volume control with sliders (tk.Scale) and I noticed there is no noticeable difference between most volume values until I get very close to zero (take into consideration that slider resolution is 0.01 from 0.0 to 0.1).
At around 0.02 I think I notice the sound volume is significantly lower and if I get to zero, the sound is muted. Please note that this happens if I move the slider while no sounds are playing.
The interesting thing is, if I try playing a sound that is long enough to let me move the slider while it's playing, I can notice the difference right away, but if the sound stops playing and I try playing it again, it goes to the "default" volume again.
Since I divided my application into multiple scripts according to what they do (recording sound, playing sound, GUI) I thought it could be the problem that I haven't directly initialized pygame mixer, but rather from the imported module, so I made a new python script and typed this code in:
import pygame
import time
pygame.mixer.pre_init(frequency=44100, size=-16, channels=1, buffer=512)
pygame.mixer.init()
sound1=pygame.mixer.Sound("sound.wav")
sound1.set_volume(1.0)
print sound1.get_volume()
sound1.play()
time.sleep(sound1.get_length())
sound1.set_volume(0.5)
print sound1.get_volume()
sound1.play()
time.sleep(sound1.get_length())
sound1.set_volume(0.08)
print sound1.get_volume()
sound1.play()
time.sleep(sound1.get_length())
The output is the following: 1.0,0.5,0.078125 (one below the other) confirming that the volume has indeed been set (I hope properly).
The only time I can notice the difference is the third case, which is not that noticeable really, I want the volume increase to be linear, this is far from it.
I tried the same thing with a channel:
sound1=pygame.mixer.Sound("sound.wav")
channel=pygame.mixer.find_channel(True)
channel.set_volume(1.0)
channel.play(sound1)
time.sleep(sound1.get_length()/2)
channel.set_volume(0.5)
print "Volume set"
time.sleep(sound1.get_length()/2)
No luck, the same thing happens here too.
I spent all day googling "pygame mixer volume problem" "pygame mixer volume set problem" and similar phrases, but no luck. Hopefully someone here can be of help, considering my diploma depends on a python method. :)
Thanks in advance.

I found the answer (thank you Gummbum from PyGame IRC).
The problem is not in Python or Pygame itself, but rather in Windows. It seems sound enhancements are somehow fiddling with the way the sound my script is playing (or any other Pygame script for that matter).
I'm on Windows 10 and this is how I did it:
Right click on the speaker icon in the taskbar
Select Playback Devices
Select Speakers and Properties
Go to Enhancements tab and uncheck Equalizer and Loudness Equalization
That's it.

Music on Raspberry Pi:
using Pygame to program playing music on my Raspberry Pi, I found the volume way too low at settings 0.0 to 1.0. Then I tried setting the value higher up to 10.0(pygame.mixer.music.set_volume(vol)) and it works Great!

Maybe you need to change the file format to mp3 for running the music because when i copied this code got an alarm music in mp3 extension and ran it in Spyder(anaconda) python 3.8 , it works , There might be 2 solutions :
Change your python version to 3.8
Convert the .wav extension into mp3
I am not sure it would work or not but with these situations , it might work at your end.

Related

Changin mp3 speed in Qt and C++ [QMediaPlayer]

I'm trying to develop a little application in which you can load a mp3 file and play it in variable speeds! (I know it already exists :-) )
I'm using Qt and C++. I already have the basic player but I'm stuck with the rate thing, because I want to change the rate smoothly (like in Mixxx) without stopping the playback! The QMediaPlayer always stops if I change the value and creates a gap in the sound. Also I don't want the pitch to change!
I already found something called "SoundTouch" but now I'm completely clueless what to do with it, how to process my mp3 data and how to get it to the player! The "SoundTouch" Library is capable of doing what I want, i got that from the samples on the homepage.
How do I have to import the mp3 file, so I can process it with the SoundTouch functions
How can I play the output from the SoundTouch function? (Perhaps QMediaPlayer can do the job?)
How is that stuff done live? I have to do some kind of stream I guess? So I can change the speed during play and keep on playing without gaps. Graphicaly in my head it has to be something that sits between the data and the player, where all data has to go through live, with a small buffer (20-50 ms or so) behind to avoid gaps during processing future data.
Any help appreciated! I'm also open to any another solution then "SoundTouch" as long as I can stay with Qt/C++!
(Second thing: I want to view a waveform overview aswell as moving part of it (around actual position of the song), so I could also use hints on how to get the waveform data)
Thanks in advance!
As of now (Qt 5.5) this is impossible to do with QMediaPlayer only. You need to do the following:
Decode the audio using GStreamer, FFMpeg or (new) QAudioDecoder: http://doc.qt.io/qt-5/qaudiodecoder.html - this will give you raw PCM stream;
Apply SoundTouch or some other library to this raw data to change the pitch. If GPL is ok, take a look at http://nsound.sourceforge.net/examples/index.html, if you develop proprietary stuff, STK might be a better choice: https://ccrma.stanford.edu/software/stk/
Output the modified data into audio device by using QAudioOutput.
This strategy uses Qt as much as possible, and brings you the best platform coverage (you still lose Android though as it does not support QAudioOutput)

GStreamer issue with time

I use GStreamer to play audio and regularly require a timestamp of where I am in the file.
If I adjust the rate of play, be it using a seek command specifying a new play rate or if I use a plugin like “pitch” to adjust the “tempo” component. All timings go out of the window as GStreamer adjusts the length of the audio and its current position to factor in the speed that it is playing at. So what was at say 18 seconds is now at 14 seconds, for example.
I have also tried stopping the audio and starting afresh passing the new settings and also issuing the seek with a rate of 1.00 and also the tempo rate neither has worked. I have run out of ideas for the moment, thus this plea to SO.
Example code
#Slow down rate of file play
def OnSlow(self, evt):
media_state = self.media_get_state()
self.rate = Gpitch.get_property("tempo")
if self.rate > 0.2:
self.rate = self.rate - 0.10
Gpitch.set_property("tempo", self.rate)
r = "%.2f" % (self.rate)
self.ma3.SetLabel("Speed: "+r)
if media_state == Gst.State.PLAYING or media_state == Gst.State.PAUSED:
self.timer.Stop() #momentarily stop updating the screen
seek_event = Gst.Event.new_seek(self.rate, Gst.Format.TIME,
(Gst.SeekFlags.FLUSH),#NONE),
Gst.SeekType.NONE, 0, Gst.SeekType.NONE, -1)
Gplayer.send_event(seek_event)
time.sleep(0.1)
self.timer.Start() #Restart updating the screen
I have tried multiplying the duration and the current position by the adjustment in an attempt to pull or push the timestamps back to their positions, as if it were being played at normal speed but to no avail.
I have been pulling my hair out over this and the real kick in the teeth, is that, if I perform the same task using Vlc as my audio engine it works but I have to alter the pitch separately. The whole reason for moving over to GStreamer was that the pitch plugin tracks the “tempo” component and yet if I cannot get accurate and consistent timestamps, the project is dead in the water.
My question, has anybody a) come across this issue and b) mastered it
The answer, for anyone who finds themselves in a similar predicament, seems to lie with a fundamental tussle between the soundtouch pitch plugin and GStreamer's rate of play.
Audacity even makes a note of it in their User Manual.
The only way I eventually found a way round the problem, was to ditch the pitch plugin entirely from the pipeline, as just having it in there was enough to mess things up.
Instead, I used the ladspa-am-pitchshift-1433-so-ampitchshift plugin to adjust the pitch of the audio and left GStreamer to vary the rate using normal seek commands whilst altering the rate, to give slower and faster rates of play.
In this way the timestamps remain consistent but the pitch has to be manually adjusted. Although it can be semi-automated by picking from a list of predefined pitch values for given rates of play.
I trust that this saves someone else 2 days of head scratching.
Additional Note:
Even though GStreamer works in nanoseconds and one could be forgiven for thinking that not using the flag Gst.SeekFlags.ACCURATE, when performing a seek, wouldn't make that much difference, one would be very much mistaken.
I have noticed that not using the ACCURATE flag can make a difference of up to 10 seconds when GStreamer is asked to report its current position, if the seek didn't use the ACCURATE flag.
So forewarned is forearmed.
(note that using this flag will make the seek take longer but at least if gives consistent results)

Python audio library for simultaneous audio creation and playback

I'm working on an audio creation framework. It'll be generating large audio files, say 3 minute long audio files that take about 1 minute to generate. So what I want is a system much like streaming audio from the internet, where I play the sound as I generate it.
Pygame's mixer allows me to edit the sound as it's playing. But I cannot figure out how to change the sample rate, sample size, or number of channels.
Snack allows me to edit sounds, as well as their sample rate, sample size, length, and number of channels. But I cannot figure out how to edit sounds as they are playing.
Could anybody point me to a library that allows me to edit a sound as it is playing, as well as configure the number of channels, sample rate, and length (all known ahead of time)? If not, perhaps somebody knows of a tutorial to do this in C++?
[EDIT] Pymedia.audio would work fine for me. However, I can't get it to work under Python 2.6. Any ideas?
pymedia.audio does work with Python 2.6. Take a look at this SO post: Pymedia installation on Windows with Python 2.6
You can append audio to Output objects, as they are playing. So as each sample is generated, it can also be appended to the stream. The example in their documentation shows just how to do this: http://pymedia.org/docs/pymedia.audio.sound.html

Off screen rendering when laptop shuts screen down?

I have a lengthy number-crunching process which takes advantage of quite abit of OpenGL off-screen rendering. It all works well but when I leave it to work on its own while I go make a sandwich I would usually find that it crashed while I was away.
I was able to determine that the crash occurs very close to the moment The laptop I'm using decides to turn off the screen to conserve energy. The crash itself is well inside the NVIDIA dlls so there is no hope to know what's going on.
The obvious solution is to turn off the power management feature that turns the screen and video card off but I'm looking for something more user friendly.
Is there a way to do this programatically?
I know there's a SETI#home implementation which takes advantage of GPU processing. How does it keep the video card from going to sleep?
I'm not sure what OS you're on, but windows sends a message that it is about to enter a new power state. You can listen for that and then either start processing on the CPU or deny the request to enter a lower-power state.
For the benefit of Linux users encountering a similar issue, I thought I'd add that, you can obtain similar notifications and inhibit power state changes using the DBUS API. An example script in Python, taken from the link, to inhibit power state change:
#!/usr/bin/python
import dbus
import time
bus = dbus.Bus(dbus.Bus.TYPE_SESSION)
devobj = bus.get_object('org.freedesktop.PowerManagement',
'/org/freedesktop/PowerManagement')
dev = dbus.Interface (devobj, "org.freedesktop.PowerManagement.Inhibit")
cookie = dev.Inhibit('Nautilus', 'Copying files from /media/SANVOL')
time.sleep(10)
dev.UnInhibit(cookie)
According to MSDN, there is an API that allows an application to tell Windows that it is still working and that Windows should not go to sleep or turn off the display.
The function is called SetThreadExecutionState (MSDN). It works for me, using the flags ES_SYSTEM_REQUIRED and ES_CONTINUOUS.
Note, however, that using this function does not stop the screen saver from running, which might interfere with your OpenGL app if the screen saver also uses OpenGL (oder Direct3D).

How can I code my own custom splash screen for Linux?

This is NOT a question on plain old boring customization; I actually want to create an program, you know, with source code, etc...
I'm thinking about programming my own media centre interface, and I figured it'd look better if I coded my own splash screen for when the OS is loading.
Note: The media centre interface will be run in X, but this question is regarding what will happen before the X server loads.
Simply, I'd like to make a splash screen application to hide the linux kernel boot messages. Is there a way I can program some animation in to this like some sort of animated progress bar for example? I assume that I won't be able to code any 2D/3D graphics (as that'd require X to be running, right?), so how would I go about generating that?
I'd prefer to do this in C++, but C is also an option.
Note: I'm not looking to use any existing "themes" or anything like that, just interested in the programming side of things.
Update:
Some suggestions have been to use standard images (.bmp, .jpeg, etc), I am not interested in loading images in to an existing application. But obviously I may want to load images in to the boot screen application that I will make.
I'm not tied to a Linux distro, so this can be for anything, although Debian or a Debian-based distro would be nice.
I like the suggestion about loading the X server early and running a loading screen from there, however is there not a more direct approach? Surely you can make a program which hides the boot messages and shows a custom program? Obviously this would be very low level programming, but that's what I'm looking for...
Also, I'm not interested in altering the boot loader (LILO, GRUB, etc).
Update 2:
So far good suggestions have been looking at the source code for applications like splashy and fbsplash. Can anyone better this suggestion?
For the graphical output you can use the Linux framebuffer, for application development you can use gtk which support rendering directly to the framebuffer GtkFB.
For the video and such you can use mplayer which also support rendering to the framebuffer.
For the initialization you have to look around the system used, debian uses a sysv init style initialization http://www.debian-administration.org/articles/212, ubuntu uses upstart.
I'd look into splashy source code. But you will need to code in C.
If you have the skills, you can implement a software based 3D engine (like in the good old days). A simple rotating cube shouldn't be very hard to code and there are tons of tutorials.
The downside is that you will increase the boot time, something not very pleasant in a media center.
Here's the thing: there is a library/kernel patch, fbsplash, that has already been written to do exactly what it sounds like you want to do. It will display an image in place of the normal boot messages, and it can also incorporate a progress bar. When you're trying to do something for which a well-established open-source implementation already exists, there's really no better way to learn how to do it yourself than to look at the source code.
Even if you're looking for something more complicated (say if you want to create some fancier animation than a progress bar), you might be able to start with fbsplash and modify it to suit your needs.
There are several ways you could do this. You could have the X server load very early, and just write a program to display the splash screen. You could also use the framebuffer device. If you are using Intel hardware, or are willing to use the OSS AMD drivers, or Nouveau for Nvidia, you could use kernel mode setting. For this, I would look at Fedora's Plymouth. You could just write a Plymouth plugin to display your splash screen.
The splash screen is simply an image (.bmp, .jpg, etc.) and can be loaded by the boot loader. Since you haven't specified the distribution you're using, look into LILO, grub, or whichever one is appropriate. Check the /boot directory for clues that will direct your search.
If all you want to do is have a nice clean boot sequence with your own splash and absolutely no boot messaging you can do the following:
First, silence grub, boot messaging, and console cursor:
GRUB_CMDLINE_LINUX_DEFAULT = quiet fastboot splash vt.cur_default=1 loglevel=0
GRUB_TIMEOUT = 0
This will very quickly and silently (fade to black) bring you to your login screen, where you can place a splash. Your distro may show it's own splash briefly, which you can change if you like.
This yeilds a professional clean boot sequence, without all the usual linux warts and wrinkles. (Like OSX and Windows).
I personally use Ubunutu with LXDE, and have a clean splashy boot in under 3 seconds, even on older hardware.