如何在 Python 中操作 wav 文件数据?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18644166/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to manipulate wav file data in Python?
提问by JVE999
I'm trying to read a wav file, then manipulate its contents, sample by sample
我正在尝试读取一个 wav 文件,然后逐个示例地操作其内容
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.
它正在正确读取,因为如果我print data[i]
改为写入,我通常会得到大小为 2 的非零数组。
回答by Warren Weckesser
The array data
returned by wavfile.read
is a numpy array with an integerdata type. The data type of a numpy array can not be changed in place, so this line:
data
返回的数组wavfile.read
是一个整数数据类型的 numpy 数组。numpy 数组的数据类型不能就地改变,所以这一行:
data[i][0] = math.sin(data[i][0])
casts the result of math.sin
to an integer, which will always be 0.
将 的结果强制转换为math.sin
整数,该整数将始终为 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:
或用于一次numpy.sin
计算数组中所有元素的正弦值:
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.
从您的附加评论中,您似乎想要取每个值的正弦并将结果写出作为新的 wav 文件。
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.
这是一个(我认为)做你想做的事的例子。我将使用来自此处的文件“M1F1-int16-AFsp.wav”:http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Samples.html 。该函数show_info
只是一种方便的方式来说明每一步的结果。如果您使用的是交互式 shell,则可以使用它来检查变量及其属性。
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
.)
这是输出。(最初的警告意味着文件中可能有一些 无法理解的元数据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.
新文件“newname.wav”包含两个带符号的 16 位值通道。