在Python中读取* .wav文件

我需要分析用.wav文件写的声音。 为此,我需要将此文件转换为一组数字(例如数组)。 我想我需要使用波包。 但是,我不知道它是如何工作的。 例如,我做了以下几点:

import wave w = wave.open('/usr/share/sounds/ekiga/voicemail.wav', 'r') for i in range(w.getnframes()): frame = w.readframes(i) print frame 

作为这个代码的结果,我期望看到作为时间函数的声压。 相反,我看到很多奇怪的,神秘的符号(不是hex数字)。 有人可以请求帮助我吗?

根据来源 , scipy.io.wavfile.read(somefile)返回一个包含两个项目的元组:第一个是每秒样本的采样率,第二个是从文件中读取所有数据的numpy数组。 看起来很容易使用!

我今天晚上做了一些研究,发现:

 import wave, struct waveFile = wave.open('sine.wav', 'r') length = waveFile.getnframes() for i in range(0,length): waveData = waveFile.readframes(1) data = struct.unpack("<h", waveData) print(int(data[0])) 

希望这个片段可以帮助别人。 详细信息:使用结构模块 ,可以取波形帧(在-32768; 0x8000和32767; 0x7FFF之间为2s补码)读取MONO,16位,WAVE文件。 我发现这个网页在制定这个相当有用。

恕我直言,从声音文件中获取audio数据到NumPy数组最简单的方法是PySoundFile :

 import soundfile as sf data, fs = sf.read('/usr/share/sounds/ekiga/voicemail.wav') 

这也支持开箱即用的24位文件。

有很多声音文件库可用,我写了一个概述 ,你可以看到一些优点和缺点。 它还具有一个页面,解释如何使用wave模块读取24位wav文件 。

不同的python模块来读取wav:

至less有以下这些库可以读取waveaudio文件:

  • PySoundFile
  • scipy.io.wavfile (来自scipy )
  • 波 (读取stream,包括在python2和3)
  • scikits.audiolab (似乎没有维护)
  • sounddevice (播放和录制声音,适合stream和实时)
  • pyglet

最简单的例子:

这是一个Pysoundfile的简单例子:

 import soundfile as sf data, samplerate = sf.read('existing_file.wav') 

输出格式:

警告,数据并不总是相同的格式,这取决于图书馆。 例如:

 from scikits import audiolab from scipy.io import wavfile from sys import argv for filetest in argv[1:]: [x, fs, nbBits] = audiolab.wavread(filePath) print '\nReading with scikits.audiolab.wavread: ', x [fs, x] = wavfile.read(filetest) print '\nReading with scipy.io.wavfile.read: ', x 

用scikits.audiolab.wavread阅读:[0。0 …,-0.00097656 -0.00079346 -0.00097656]用scipy.io.wavfile.read读取:[0 0 0 …,-32 -26 -32 ]

PySoundFile和Audiolab在-1和1之间返回float(就像matab那样,这是audio信号的约定)。 Scipy和Wave返回整数,可以根据编码的位数在float中进行转换。

例如:

 from scipy.io.wavfile import read as wavread [samplerate, x] = wavread(audiofilename) # x is a numpy array of integer, representing the samples # scale to -1.0 -- 1.0 if x.dtype == 'int16': nb_bits = 16 # -> 16-bit wav files elif x.dtype == 'int32': nb_bits = 32 # -> 32-bit wav files max_nb_bit = float(2 ** (nb_bits - 1)) samples = x / (max_nb_bit + 1.0) # samples is a numpy array of float representing the samples 

您可以使用scikits.audiolab模块来完成此操作。 它需要NumPy和SciPy以及libsndfile。

请注意,我只能使它在Ubunutu而不是在OSX上工作。

 from scikits.audiolab import wavread filename = "testfile.wav" data, sample_frequency,encoding = wavread(filename) 

现在你有了wav数据

如果你想逐块处理一个audio块,一些给定的解决scheme是相当可怕的,因为它们意味着将整个audio加载到内存中,产生许多caching未命中并放慢你的程序。 python-wavefile提供了一些Pythonic结构来进行NumPy逐块处理,使用高效和透明的块pipe理,通过生成器。 其他pythonic niceties文件的上下文pipe理器,元数据作为属性…如果你想要整个文件接口,因为你正在开发一个快速原型,你不关心效率,整个文件接口仍然存在。

一个简单的例子是:

 import sys from wavefile import WaveReader, WaveWriter with WaveReader(sys.argv[1]) as r : with WaveWriter( 'output.wav', channels=r.channels, samplerate=r.samplerate, ) as w : # Just to set the metadata w.metadata.title = r.metadata.title + " II" w.metadata.artist = r.metadata.artist # This is the prodessing loop for data in r.read_iter(size=512) : data[1] *= .8 # lower volume on the second channel w.write(data) 

该示例重用相同的块来读取整个文件,即使在通常小于所需大小的最后一个块的情况下也是如此。 在这种情况下,你得到一个块的一部分。 因此,请相信返回的块长度,而不是使用硬编码的512大小进行进一步处理。

如果你打算在波形数据上进行传输,那么也许你应该使用SciPy ,特别是scipy.io.wavfile

如果只有两个文件和采样率非常高,则可以交织它们。

 from scipy.io import wavfile rate1,dat1 = wavfile.read(File1) rate2,dat2 = wavfile.read(File2) if len(dat2) > len(dat1):#swap shortest temp = dat2 dat2 = dat1 dat1 = temp output = dat1 for i in range(len(dat2)/2): output[i*2]=dat2[i*2] wavfile.write(OUTPUT,rate,dat) 

我需要读取1个通道的24位WAV文件。 Nak以上的post非常有用。 不过,正如上面提到的那样, 24位的不是简单的。 我终于得到它使用以下代码片段:

 from scipy.io import wavfile TheFile = 'example24bit1channelFile.wav' [fs, x] = wavfile.read(TheFile) # convert the loaded data into a 24bit signal nx = len(x) ny = nx/3*4 # four 3-byte samples are contained in three int32 words y = np.zeros((ny,), dtype=np.int32) # initialise array # build the data left aligned in order to keep the sign bit operational. # result will be factor 256 too high y[0:ny:4] = ((x[0:nx:3] & 0x000000FF) << 8) | \ ((x[0:nx:3] & 0x0000FF00) << 8) | ((x[0:nx:3] & 0x00FF0000) << 8) y[1:ny:4] = ((x[0:nx:3] & 0xFF000000) >> 16) | \ ((x[1:nx:3] & 0x000000FF) << 16) | ((x[1:nx:3] & 0x0000FF00) << 16) y[2:ny:4] = ((x[1:nx:3] & 0x00FF0000) >> 8) | \ ((x[1:nx:3] & 0xFF000000) >> 8) | ((x[2:nx:3] & 0x000000FF) << 24) y[3:ny:4] = (x[2:nx:3] & 0x0000FF00) | \ (x[2:nx:3] & 0x00FF0000) | (x[2:nx:3] & 0xFF000000) y = y/256 # correct for building 24 bit data left aligned in 32bit words 

如果您需要-1和+1之间的结果,则需要一些额外的缩放比例。 也许你们中有些人可能会觉得这很有用