Without knowing it, you might have broadcasted arrays. In a nutshell, NumPy tries to perform an operation even though the operands do not have the same shape. In this recipe, we will multiply an array and a scalar. The scalar is "extended" to the shape of the array operand and then the multiplication is performed. We will download an audio file and make a new version that is quieter.
Let's start by reading a WAV file:
We will use a standard Python code to download an audio file of Austin Powers called "Smashing, baby". SciPy has a wavfile
module, which allows you to load sound data or generate WAV files. If SciPy is installed, then we should have this module already. The read
function returns a data array and sample rate. In this example, we only care about the data:
sample_rate, data = scipy.io.wavfile.read(WAV_FILE)
Plot the original WAV data with Matplotlib. Give the subplot the title Original
.
matplotlib.pyplot.subplot(2, 1, 1) matplotlib.pyplot.title("Original") matplotlib.pyplot.plot(data)
Now we will use NumPy to make a quieter audio sample. It's just a matter of creating a new array with smaller values by multiplying with a constant. This is where the magic of broadcasting occurs. At the end, we need to make sure that we have the same data type as in the original array, because of the WAV format:
newdata = data * 0.2 newdata = newdata.astype(numpy.uint8)
This new array can be written into a new WAV file as follows:
scipy.io.wavfile.write("quiet.wav", sample_rate, newdata)
Plot the new data array with Matplotlib:
matplotlib.pyplot.subplot(2, 1, 2) matplotlib.pyplot.title("Quiet") matplotlib.pyplot.plot(newdata) matplotlib.pyplot.show()
The result is a plot of the original WAV file data and a new array with smaller values, as shown in the following screenshot:
The following is the complete code for this recipe:
import scipy.io.wavfile import matplotlib.pyplot import urllib2 import numpy response = urllib2.urlopen('http://www.thesoundarchive.com/austinpowers/smashingbaby.wav') print response.info() WAV_FILE = 'smashingbaby.wav' filehandle = open(WAV_FILE, 'w') filehandle.write(response.read()) filehandle.close() sample_rate, data = scipy.io.wavfile.read(WAV_FILE) print "Data type", data.dtype, "Shape", data.shape matplotlib.pyplot.subplot(2, 1, 1) matplotlib.pyplot.title("Original") matplotlib.pyplot.plot(data) newdata = data * 0.2 newdata = newdata.astype(numpy.uint8) print "Data type", newdata.dtype, "Shape", newdata.shape scipy.io.wavfile.write("quiet.wav", sample_rate, newdata) matplotlib.pyplot.subplot(2, 1, 2) matplotlib.pyplot.title("Quiet") matplotlib.pyplot.plot(newdata) matplotlib.pyplot.show()