How to play Wav sound samples from memory - python

For my final year project in college I am working with Wav Files and Python and messing around with them. I would love to be able to play the sound samples from memory rather than write the sound samples out in to a WAV file before I can hear them.
I have been looking for weeks online and have found PyMedia, PySound, PyGame etc and none of them seem to work for me. Every single package gives me errors.
Are there other libraries I am missing that would help me do this ? Or am I just being stupid and can't get the other packages to work.
Exactly what I want to do is along the lines of this:
#open file and get parameters
wavfile = Wave.open("file.wav", "r")
params = wfile.getparams()
nframes = params[3]
#get sound samples in a list
samples = []
for i in range(nframes):
samples.append(wfile.readframes(1))
playsound(samples)
changedSamples = makeChangeTo(samples)
playsound(changedSamples)
And I would like to be able to have this in a loop so I can edit and hear the edits while the program is still runnning without having to write the samples to a wav file before being able to hear it as that takes too long.
Any suggestions ? Cheers !

You should clearly separate those two concerns:
Reading/writing WAV files (or other audio files)
Playing/recording sounds
There are several questions and answers to both topics here on SO.
This is my personal (and of course biased) recommendation:
You should use NumPy to manipulate sounds, it's much easier than handling plain Python buffers.
If for some reason you cannot use NumPy, you can still do all this, but it will be a bit more work.
For reading/writing sound files, I recommend the soundfile module (full disclosure: I'm a co-author).
For playing/recording sounds, I recommend the sounddevice module (full disclosure: I'm its main author).
When using those modules, your example would probably become something like this:
import soundfile as sf
import sounddevice as sd
samples, samplerate = sf.read('file.wav')
sd.play(samples, samplerate)
sd.wait()
changed_samples = make_change_to(samples)
sd.play(changed_samples, samplerate)
sd.wait()
If you work in an interactive Python prompt, you probably don't need the sd.wait() calls, you can just wait until the playback has finished. Or, if you get bored of listening to it, you can use:
sd.stop()
If you know that you will use the same sampling rate for some time, you can set it as default:
sd.default.samplerate = 48000
After that, you can drop the samplerate argument when using play():
sd.play(samples)
If you want to store the changed sound to a file, you can use something like this:
sf.write('changed_file.wav', changed_samples, samplerate)
Further reading:
different options for reading/writing audio files
different options for playback/recording
a very basic tutorial about handling audio signals

Related

Export (but not save to) an audio file in PyDub?

The PyDub library, for me, is pretty much ideal for converting audio formats. I recently used it to write a command line audio converter to convert about 200 audio files, and it saved me having to buy or look for an audio converter that would allow me to queue up songs and other audio files for conversion. But I quickly noticed that it replaced my audio files. Now, for me, this was ideal. This was great. But what if I didn't want PyDub to replace the audio files, but rather duplicate it but in a different format? I could just copy the files into the directory and convert them, but is there no way to do this from within PyDub? I looked into it and I couldn't find a way to do this, nor could I find a question on this, so maybe this isn't a very common thing to do.
Thanks!
When you export an audio segment, you can always specify a new name for the file (or use the same name but in a different folder)
from pydub import AudioSegment
song = AudioSegment.from_file("/path/to/file.mp3", format="mp3")
song.export("/path/to/new/filename.mp4", format="mp4")
Hope this helps:
myaudio = AudioSegment.from_mp3("XXXXX/y.mp3")
chunk_length_ms = 1000000 # pydub calculates in millisec
chunks = make_chunks(myaudio, chunk_length_ms) # Make chunks of one sec
chunks.export('path where file needs to be exported' + chunks, format='mp3')

Python Creating raw audio

I use Windows 7. All I want to do is create raw audio and stream it to a speaker. After that, I want to create classes that can generate sine progressions (basically, a tone that slowly gets more and more shrill). After that, I want to put my raw audio into audio codecs and containers like .WAV and .MP3 without going insane. How might I be able to achieve this in Python without using dependencies that don't come with a standard install?
I looked up a great deal of files, descriptions, and related questions from here and all over the internet. I read about PCM and ADPCM, as well as A/D Converters. Where I get lost is somewhere between the ratio of byte input --> Kbps output, and all that stuff.
Really, all I want is for somebody to please be able to point me in the right direction to learn the audio formats precisely, and how to use them in Python (but first I want to start with raw audio).
This questions really has 2 parts:
How do I generate audio signals
How do I play audio signals through the speakers.
I wrote a simple wrapper around the python std lib's wave module, called pydub, which you can look at (on github) as a point of reference for how to manipulate raw audio data.
I generally just export the audio data to a file and then play it using VLC player. IMHO there's no reason to write a bunch of code to playback audio unless you're making a synthesizer or a game or some other realtime app.
Anyway, I hope that helps you get started :)

How do I mix audio files using python?

I would like to do basic audio mixing in python.
To give an example: I would like to take two mp3 files and add them together and return one mp3 file. Another example: I would like to take the first ten seconds of one mp3 file and add it to the beginning of another mp3 file.
What is the best way to accomplish these tasks? I would like to use built in python functions like audioop but can not find any good tutorials or sample code out there for using the built in functions.
I am going through the docs but I am pretty confused and cannot figure out how to do things like this. I am not even sure that the python libraries like mp3's. Most of the stuff I have looked at seem to refer to WAV files. So, if this is the case, I guess a follow up question would be is there an easy way to convert an mp3 to a WAV for manipulation and back again?
You can do this pretty easily using pydub:
from pydub import AudioSegment
sound1 = AudioSegment.from_mp3("/path/to/file1.mp3")
sound2 = AudioSegment.from_mp3("/path/to/file1.mp3")
# mix sound2 with sound1, starting at 5000ms into sound1)
output = sound1.overlay(sound2, position=5000)
# save the result
output.export("mixed_sounds.mp3", format="mp3")
You could check out some of the code in the python audiotools project. It is a collection of command-line utilities which make use of a common python package. There is a utility included with audiotools (trackcat) which can con*cat*enate two or more audio tracks; another (tracksplit) can split an audio track (using a .cue file). These, as well as the numerous other included utilities, can work with audio files of various encodings, including mp3.
The way I've done this in the past is just use subprocess. and call sox.
E.g. subprocess.call(["sox", "in.1.mp3", "in.2.mp3", "out.mp3"])

Get binary data from audio impulses

I have IR sensor which have TRS connector and I can record my remotes signals into audio.
Now I want to control my computer with TV remote, but I don't have any clue how to compare audio input with pre-recorded audio. But after I realized that these audio waves contains only some kind data (binary) I can turn these into binary or hex, so it is much easier to compare.
Waves look just like this:
And this:
These are records of "OK" button, sometimes there are some impulses on right channel too and I don't know why, it seems like connections in sensor are damaged maybe.
Ok thats not matter, anyway
I need help with python program which read these impulses and turn these into binary, in realtime from audio input(mic).
I know it's sounds like "Do it for me, while I enjoy my life", but I don't have experiences with sound transforming/reading... I've looking for python examples for recording and reading audio, but unsuccessfully.
The this is quite easy if you can forgo the real time requirement: just save the data as a .wav file, and then read it in using Python's wave module.
Here's an example of how to read a wav file in Python,
import wave
w = wave.open("myfile.wav", "rb")
binary_data = w.readframes(w.getnframes())
w.close()
It's possible to do this in real time, but it's harder, though still not super difficult. For real time, I use PyAudio, and a good start would be to follow the examples in the demos. In these you basically open a stream and read small chunks at a time, and if you want any interactivity, you need to do this in a thread.
(Also, note, that the sound card will filter your audio inputs, so what you see isn't going to be the true input signal. In particular, I think remote controls often have a carrier frequency around 40KHz, which is higher than human hearing, so I doubt that sound cards work well in this range, though they may be sufficient depending on what you want to do.)

High level audio crossfading library for python

I am looking for a high level audio library that supports crossfading for python (and that works in linux). In fact crossfading a song and saving it is about the only thing I need.
I tried pyechonest but I find it really slow. Working with multiple songs at the same time is hard on memory too (I tried to crossfade about 10 songs in one, but I got out of memory errors and my script was using 1.4Gb of memory). So now I'm looking for something else that works with python.
I have no idea if there exists anything like that, if not, are there good command line tools for this, I could write a wrapper for the tool.
A list of Python sound libraries.
Play a Sound with Python
PyGame or Snack would work, but for this, I'd use something like audioop.
— basic first steps here : merge background audio file
A scriptable solution using external tools AviSynth and avs2wav or WAVI:
Create an AviSynth script file:
test.avs
v=ColorBars()
a1=WAVSource("audio1.wav").FadeOut(50)
a2=WAVSource("audio2.wav").Reverse.FadeOut(50).Reverse
AudioDub(v,a1+a2)
Script fades out on audio1 stores that in a1 then fades in on audio2 and stores that in a2.
a1 & a2 are concatenated and then dubbed with a Colorbar screen pattern to make a video.
You can't just work with audio alone - a valid video must be generated.
I kept the script as simple as possible for demonstration purposes. Google for more details on audio processing via AviSynth.
Now using avs2wav (or WAVI) you can render the audio:
avs2wav.exe test.avs combined.wav
or
wavi.exe test.avs combined.wav
Good luck!
Some references:
How to edit with Avisynth
AviSynth filters reference

Categories