This month I am teaching an intensive boot camp in Python for grad students and postdocs in mathematics and physics. One topic is sound: how to generate it using code, and how to convert what we generate — just an array of numbers — into a
.wav file that can be played on a computer.
There are quite a few resources for this sort of thing on the web, but it took me a while to find a solution that I was really happy with — just six lines of code after the imports. The code, listed below, is an example from the
wavio library. To use it, you will have to run
pip install wavio first.
# Source: https://pypi.org/project/wavio/
# File: gen_sound.py
# $ python gen_sound.py
# to create the file `sine440.py
# Then run (for example on Mac OS)
# $ afplay sine.wav
# to listen to the soundimport numpy as np
import wavio# Parameters
rate = 44100 # samples per second
T = 3 # sample duration (seconds)
f = 440.0 # sound frequency (Hz)# Compute waveform samples
t = np.linspace(0, T, T*rate, endpoint=False)
x = np.sin(2*np.pi * f * t)# Write the samples to a file
wavio.write("sine.wav", x, rate, sampwidth=3)
On my laptop (Macbook Pro, 3.3 GHz Intel Core i7), generating the 3-second sample array
x took about 2.2 milliseconds, while writing the file took about 10 milliseconds.
I tried several other snippets of code that were of similar nature. All used more or less the same method to generate the wave sample (the array
x), but either (a) writing the
.wav file was too slow (using the
wave library), or (b) wrting files was fast, but the data file lacked the header that made it playable.