Edit wav files using Python's Wave module

Hello everybody

It seems that Python comes with a wave module as standard, and it seems that you can read and write wav files by using this module. This time, let's play with a program that uses it to create a short wav file with the latter half cut out from a long wav file.

Environmental preparation

I'm PHPer, so I don't know how to prepare a python environment, but I have a docker image with keras that I often use, so I use this one. (Although it is quite heavy) https://hub.docker.com/r/gw000/keras-full/

Also, of course, I don't have the guts to create a file and run it repeatedly on the console, so I start jupyter quickly and run it via a browser.

$ docker run --rm -v `pwd`/src:/srv -v `pwd`/data:/data -p 8888:8888 -p 6006:6006 -m 2g gw000/keras-full

I was worried about the memory, so I have reserved 2GB just in case. later, http://127.0.0.1:8888 If you access with a browser, jupyter is running, so enter the password [keras] and start.

loading wav

Now that the preparation is complete, let's read the wave file and get the information. Enter the following on jupyter.

import wave
import struct
from scipy import fromstring, int16

#Read file
wavf = '/data/input/test.wav'
wr = wave.open(wavf, 'r')

#Get the properties of wave files
ch = wr.getnchannels()
width = wr.getsampwidth()
fr = wr.getframerate()
fn = wr.getnframes()

print("Channel: ", ch)
print("Sample width: ", width)
print("Frame Rate: ", fr)
print("Frame num: ", fn)
print("Params: ", wr.getparams())
print("Total time: ", 1.0 * fn / fr)

#Get the actual data of the wave and quantify it
data = wr.readframes(wr.getnframes())
wr.close()
X = fromstring(data, dtype=int16)

I will try to execute it so far.

Channel:  2
Sample width:  2
Frame Rate:  44100
Frame num:  15884224
Params:  _wave_params(nchannels=2, sampwidth=2, framerate=44100, nframes=15884224, comptype='NONE', compname='not compressed')
Total time:  360.18648526077095

The following result is output. Since Channel is 2, you can see that this file is in stereo. Also, you can see that the total time is 360 seconds = 6 minutes, which is a relatively long file.

Export to wave

Next, let's write out the read contents for 90 seconds from the beginning as another file.

#Calculate the number of frames equivalent to 90 seconds
time = 90
frames = int(ch * fr * time)

#Generate output data
outf = '/data/output/test.wav'
Y = X[:frames]
outd = struct.pack("h" * len(Y), *Y)

#Export
ww = wave.open(outf, 'w')
ww.setnchannels(ch)
ww.setsampwidth(width)
ww.setframerate(fr)
ww.writeframes(outd)
ww.close()

It is like this. If there are multiple channels, the number of frames required will increase accordingly, so that is taken into consideration. So, after converting the output data to the character string format again, it feels like writing out by specifying the same parameters as when reading. So, if you look at whether the file was actually created,

スクリーンショット 2017-06-06 13.53.56.png

It looks like it's done.

Summary

This time, I investigated how to edit a wav file directly using wave, which is a standard module of Python. That's why I'm talking about it. .. ..

This time it is like this.

reference

http://yukara-13.hatenablog.com/entry/2013/11/09/103848 http://denshi.blog.jp/signal_processing/python/save_sine_wave

Recommended Posts

Edit wav files using Python's Wave module
Learn about logging using Python's logging module ①
I tried to synthesize WAV files using Pydub.
Save an array of numpy to a wav file using the wave module
Getting Started with Python's ast Module (Using NodeVisitor)
Try using Python's feedparser.
Try using Python's Tkinter