Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to manipulate wav file data in Python?

Tags:

python

scipy

wav

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.

like image 919
JVE999 Avatar asked Sep 05 '13 19:09

JVE999


People also ask

How to open a WAV file in Python?

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.

How to work with audio files using Python?

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.

How to read/write audio data from a file using Wave module?

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.

How to increase/decrease volume of audio file in Python?

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.


1 Answers

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.

like image 77
Warren Weckesser Avatar answered Sep 28 '22 04:09

Warren Weckesser