如何在python中读取.wav字节流

时间:2017-05-10 18:13:31

标签: python wav pyaudio wave

有没有办法读取.wav格式二进制数据的帧?我正在将.wav二进制文件流式传输到一个python服务器,我希望能够通过pyaudio进行读取和使用,它会抱怨帧大小。

由于我无法使用wave.open('filename.wav'),因为我已经有了二进制数据流,有没有办法读取二进制数据,以便我可以使用readframes方法wave蟒蛇库?

编辑: 我尝试从客户端传输readframes,但是pyaudio给出了一个错误,即字节不是.wav格式。如果我能在服务器上完成这项工作,那将是理想的。

3 个答案:

答案 0 :(得分:3)

from scipy.io import wavfile
fs, data = wavfile.read('your file path')

答案 1 :(得分:2)

@Vishesh Mangla指出,使用librosa一个很好的音频信号库

import librosa

sr = librosa.get_samplerate('/path/to/file.wav')

# Set the frame parameters to be equivalent to the librosa defaults
# in the file's native sampling rate
frame_length = (2048 * sr) // 22050
hop_length = (512 * sr) // 22050

# Stream the data, working on 128 frames at a time
stream = librosa.stream('path/to/file.wav',
                        block_length=128,
                        frame_length=frame_length,
                        hop_length=hop_length)

chromas = []
for y in stream:
   chroma_block = librosa.feature.chroma_stft(y=y, sr=sr,
                                              n_fft=frame_length,
                                              hop_length=hop_length,
                                              center=False)
   chromas.append(chromas)

在此示例中,每个音频片段y将包含128个帧的样本值,或更具体地说,len(y)== frame_length +(block_length-1)* hop_length。每个片段y都将通过frame_length-hop_length样本与后续片段重叠,从而确保流处理将提供与如果一步一步处理整个序列(假定填充/居中禁用)相同的结果。

有关流接口的更多详细信息,请参阅librosa.core.stream

答案 2 :(得分:0)

在我自己的赏金里,我borrow from this more general context relating to getting a virtual file object有一个优雅的解决方案。

import io
audio = wave.open(io.BytesIO(bytes))

这将为python字节对象启用wave的所有API,至少我用于与原始问题相同的场景的子集。例如,使用上方的audio变量,您现在可以:

format=self.audio.get_format_from_width(
   audio.getsampwidth()),
   channels=audio.getnchannels(),
   rate=audio.getframerate(),
   frames_per_buffer=self.chunk_size,
   output=True)

由于wave库似乎不直接支持磁盘文件对象,因此这是一个不错的解决方法,至少它依赖于标准python库(io),该库提供了我们所需的桥梁。 API。