我有一个零和一的numpy数组:
y=[1,1,1,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,1,1]
我想计算一个(或零)组的索引。因此,对于以上示例,一组结果应类似于以下内容:
result=[(0,2), (8,9), (16,19)]
(如何)可以用numpy做到这一点?我没有发现任何类似的分组功能。
我尝试了np.ediff1d,但找不到一个好的解决方案。并不是说该数组可能会或可能不会以一组开头/结尾:
import numpy as np
y = [1,1,1,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,1,1]
mask = np.ediff1d(y)
starts = np.where(mask > 0)
ends = np.where(mask < 0)
Run Code Online (Sandbox Code Playgroud)
我还在这里找到了部分解决方案: 查找索引,其中元素更改值numpy
但这只是给我提供值更改的索引。
情况
我通过使用Python适配器WebRTC-VAD从WebRTC使用VAD(语音活动检测)。GitHub存储库中的示例实现使用Python的wave模块从文件中读取PCM数据。请注意,根据注释,该模块仅适用于单声道音频,采样速率为8000、16000或32000 Hz。
我想做的事
从具有不同采样率的任意音频文件(MP3和WAV文件)中读取音频数据,将它们转换为WebRTC-VAD正在使用的PCM表示形式,应用WebRTC-VAD来检测语音活动,最后通过产生Numpy-Arrays处理结果再次从PCM数据中获取数据,因为使用Librosa时最容易使用它们
我的问题
WebRTC-VAD模块仅在使用该wave
模块时才能正常工作。该模块将PCM数据作为bytes
对象返回。当将其馈入已使用的Numpy数组时,它不起作用librosa.load(...)
。我还没有找到在两种表示形式之间进行转换的方法。
到目前为止我做了什么
我编写了以下函数来从音频文件中读取音频数据并自动将它们转换:
使用Librosa读取/转换任何音频数据的通用函数(->返回Numpy数组):
def read_audio(file_path, sample_rate=None, mono=False):
return librosa.load(file_path, sr=sample_rate, mono=mono)
Run Code Online (Sandbox Code Playgroud)
读取任意数据作为PCM数据的功能(->返回字节):
def read_audio_vad(file_path):
audio, rate = librosa.load(file_path, sr=16000, mono=True)
tmp_file = 'tmp.wav'
sf.write(tmp_file, audio, rate, subtype='PCM_16')
audio, rate = read_pcm16_wave(tmp_file)
remove(tmp_file)
return audio, rate
def read_pcm16_wave(file_path):
with wave.open(file_path, 'rb') as wf:
sample_rate = wf.getframerate()
pcm_data = wf.readframes(wf.getnframes())
return pcm_data, sample_rate
Run Code Online (Sandbox Code Playgroud)
如您所见,我先绕过librosa读取/转换音频数据。这是必需的,因此我可以读取具有任意编码的MP3文件或WAV文件,并使用Librosa自动将其重新采样为16kHz单声道。然后,我正在写一个临时文件。在删除文件之前,我会再次读取内容,但这一次使用wave
模块。这给了我PCM数据。
现在,我有以下代码来提取语音活动并生成Numpy数组:
def webrtc_voice(audio, rate): …
Run Code Online (Sandbox Code Playgroud)