I'm trying to read a wav file, then manipulate its contents, sample by sample
Here's what I have so far:
import scipy.io.wavfile
import math
rate, data = scipy.io.wavfile.read('xenencounter_23.wav')
for i in range(len(data)):
data[i][0] = math.sin(data[i][0])
print data[i][0]
The result I get is:
0
0
0
0
0
0
etc
It is reading properly, because if I write print data[i]
instead I get usually non-zero arrays of size 2.
The wave module in Python's standard library is an easy interface to the audio WAV format. The functions in this module can write audio data in raw format to a file like object and read the attributes of a WAV file. The file is opened in 'write' or read mode just as with built-in open () function, but with open () function in wave module.
So let’s see how to work with audio files using Python. Python provides a module called pydub to work with audio files. pydub is a Python library to work with only .wav files. By using this library we can play, split, merge, edit our . wav audio files. This module does not come built-in with Python.
The file is opened in 'write' or read mode just as with built-in open () function, but with open () function in wave module This function opens a file to read/write audio data. The function needs two parameters - first the file name and second the mode. The mode can be 'wb' for writing audio data or 'rb' for reading.
1) Playing Audio File: This is done using play () method. Use Up/Down Arrow keys to increase or decrease volume. 2) Knowing about .wav file: for this we will use attributes of audio file object. 3) Increasing/Decreasing volume of the file: By using ‘ +’ and ‘ -‘ operator. Use Up/Down Arrow keys to increase or decrease volume.
The array data
returned by wavfile.read
is a numpy array with an integer data type. The data type of a numpy array can not be changed in place, so this line:
data[i][0] = math.sin(data[i][0])
casts the result of math.sin
to an integer, which will always be 0.
Instead of that line, create a new floating point array to store your computed result.
Or use numpy.sin
to compute the sine of all the elements in the array at once:
import numpy as np
import scipy.io.wavfile
rate, data = scipy.io.wavfile.read('xenencounter_23.wav')
sin_data = np.sin(data)
print sin_data
From your additional comments, it appears that you want to take the sine of each value and write out the result as a new wav file.
Here is an example that (I think) does what you want. I'll use the file 'M1F1-int16-AFsp.wav' from here: http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Samples.html. The function show_info
is just a convenient way to illustrate the results of each step. If you are using an interactive shell, you can use it to inspect the variables and their attributes.
import numpy as np
from scipy.io import wavfile
def show_info(aname, a):
print "Array", aname
print "shape:", a.shape
print "dtype:", a.dtype
print "min, max:", a.min(), a.max()
print
rate, data = wavfile.read('M1F1-int16-AFsp.wav')
show_info("data", data)
# Take the sine of each element in `data`.
# The np.sin function is "vectorized", so there is no need
# for a Python loop here.
sindata = np.sin(data)
show_info("sindata", sindata)
# Scale up the values to 16 bit integer range and round
# the value.
scaled = np.round(32767*sindata)
show_info("scaled", scaled)
# Cast `scaled` to an array with a 16 bit signed integer data type.
newdata = scaled.astype(np.int16)
show_info("newdata", newdata)
# Write the data to 'newname.wav'
wavfile.write('newname.wav', rate, newdata)
Here's the output. (The initial warning means there is perhaps some metadata in the file that is not understood by scipy.io.wavfile.read
.)
<snip>/scipy/io/wavfile.py:147: WavFileWarning: Chunk (non-data) not understood, skipping it.
WavFileWarning)
Array 'data'
shape: (23493, 2)
dtype: int16
min, max: -7125 14325
Array 'sindata'
shape: (23493, 2)
dtype: float32
min, max: -0.999992 0.999991
Array 'scaled'
shape: (23493, 2)
dtype: float32
min, max: -32767.0 32767.0
Array 'newdata'
shape: (23493, 2)
dtype: int16
min, max: -32767 32767
The new file 'newname.wav' contains two channels of signed 16 bit values.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With