I want to write a program in Python which plays random music. Is there any library that can directly play a sound of the given pitch or frequency, during the given time? For example, play(440, 4) should play the note A during 4 seconds.
I've found some libraries that can do what I said, but they don't play the music directly: you have to create a .wav file and, then, play this file. If I don't find any library that does what I want, I'll create a file, play it, and remove it for each note, but I think it would be more easy to do it directly.
I've finally found an answer to my question.
There's a module called winsound (https://docs.python.org/3/library/winsound.html) which can play a sound of a given frequency and duration: winsound.Beep(frequency, duration). But the problem is that it isn't cross-platform, only works for Windows operating systems.
So I've found another module called pyaudiere (https://pypi.org/project/pyaudiere/) which is cross-platform. It works a bit different than winsound. First you create a device: d = audiere.open_device(). Then, you can create a tone doing t = d.create_tone(440). To play the tone you do t.play() and to stop it t.stop(). If you want to play it during some seconds you can use the time module. I'm still investigating but I think it only works for Python2. This is the stackoverflow post where I found the answer: Python library for playing fixed-frequency sound.
Related
I'm working on a python3 project (in PyCharm, using Windows 10) and I'm trying to play a series of tones and save them all to a mp3 file.
I can get it to play a series of notes with winsound:
import winsound
while True:
winsound.Beep(1000, 1000)
But I can't save it.
All help appreciated!
If you want to save output to a file, rather than just play it, probably the most ideal way of doing this is to generate midi files. There are a few packages that can help you create midi files in a similar way.
This example uses the package called mido
from mido import Message, MidiFile, MidiTrack
mid = MidiFile()
track = MidiTrack()
mid.tracks.append(track)
track.append(Message('note_on', note=64, velocity=64, time=32))
mid.save('new_song.mid')
You can convert midi files to MP3s easily if needed (many programs or even online tools can do this) although, midi files are generally well-supported in most applications.
See also
Although perhaps dated, you can also check the PythonInMusic wiki for references to more MIDI and other audio libraries.
Alternatively, you can use a separate program to record your audio output when running your python script using winsound.
What I need
I am working on a music player with a sample analyzer. My issue is that I am currently using pydub to get the samples from the song, but as the song gets longer, the more out of sync the two become. I have made the two literally in sync, pydub just so happens to read out of it [I even started them at the same time, the two actually progressively de-synced with audio alone and more so as the song continues playing].
Basically, is there a python-vlc equivalent to pydub.AudioSegment.get_array_of_samples()?
You can look at the python-vlc docs here: https://www.olivieraubert.net/vlc/python-ctypes/doc/
What I've tried
python-vlc has sound.get_time() which returns the last updated time in milliseconds. The issue with this command is not that it only updates every half a second or so [I've found a way around that] but that it doesn't return the accurate time. I can start a timer from when it starts playing using time.monotonic(). As time progresses, the get_time() wildly varies from the timer. I've gotten a difference of 195ms, 294ms and 217ms.
I tried using an external timer using the threading module. It appears that pydub.AudioSegment[index] is not in sync whatsoever.
Scaling from sound.get_time() in py-vlc to len(sound) in pydub. This doesn't work as expected. I cannot tell you why but it is still desynced.
Using sound.get_time() with an average offset that increases over time. It appears that pydub.AudioSegment[index] doesn't line up properly.
Using aubio. It only reads WAV files, and for a live analyzer, converting to a WAV first would take too long.
Things I found out
I've looked at how long each song is in milliseconds, len(sound) for pydub and sound.get_length() for python-vlc is different usually by 10 or so seconds.
Things that won't work
Using pydub's play() command. I don't like it because it's very limiting.
Using something else than py-vlc to play the audio, VLC has many features that just cannot be replicated.
Previous suggestions
Use How can I extract audio from video with ffmpeg?
This won't work because I am not looking to extract audio from an existing video file, I'm trying to get samples like pydub.AudioSegment.get_array_of_samples()
I'm curious
Is there a python module for Audacity? I've been looking and couldn't find it. I can also use some other command line tool that can interact with Audacity if possible [I know the built in command line utility doesn't do much at all]
You probably want to use ffmpeg directly for this.
I am learning python. I thought of a fun and do-able(for me as a noob) exercise to test myself with.
I want to write a script that asks the user for a string.. and then it translates the string into morse code and plays it. I just dont know how to access/play a sound file in Python... Doesnt really matter what type.. .wav .mp3 or whatever, just whatever works best with Python. It obviously will just be a short beep that will be played for a certain(very short) time length. I saw that people suggest using pygame.. is that the only option? For educational purposes I'd like to know how to do this with the standard library(if possible). If not a module is fine.
Or better yet, is there a way to create a beep sound with only python code? In other words no sound file needed at all. A function that says "make a sound at x frequency for x time"?
You could try the winsound library (built in).
By using winsound.PlaySound(filename,winsound.SND_FILENAME) you are able to play WAV audio files.
By using winsound.Beep(frequency(in Hz),duration(in miliseconds)) you should be able to produce a beeping sound.
There is a slight chance the Beep() function won't work, as is in my case, and i am currently looking into it.
Take a look at the docs here: https://docs.python.org/3.7/library/winsound.html
I am using Python 2.7, win 7, 64bit and I need to play a sound data stored in a variable. Of course, there is a possibility to make a WAV file and play it, but is there any option to play that directly? Could you recommend a library, etc. etc.?
Apparently, audiere is outdated by now (as presented in Playing a sound from a wave form stored in an array).
What you might be looking for is pyAudio :
http://people.csail.mit.edu/hubert/pyaudio/docs/
See in the example how they are storing a wav file in a variable and then playing it.
I'm trying to write something that catches the audio being played to the speakers/headphones/soundcard and see whether it is playing and what the longest silence is. This is to test an application that is being executed and to see if it stops playing audio after a certain point, as such i don't actually need to really know what the audio itself is, just whether or not there is audio playing.
I need this to be fully programmatic (so not requiring the use of GUI tools or the like, to set up an environment). I know applications like projectM do this, I just can't for the life of me find anything anywhere that denotes how.
An audio level meter would also work for this, as would ossiliscope data or the like, really would take any recommendation.
Here is a very similar question: record output sound in python
You could try to route your output to a new device with jack and record this with portaudio. There are Python Bindings for portaudio called pyaudio and for jack called PyJack. I have never used the latter one but pyaudio works great.