【python】将多脉冲wav文件分割存为单脉冲

待处理的wav文件中包含多个相似的脉冲,要分别保存这些脉冲的完整波形,并使其采样点数量一致。

wav的切割与保存使用wavopen,参考:

(Python) 在Python中对WAV音频文件进行分割与拼接_wav分割-CSDN博客

用循环互相关的方式计算相关性,匹配脉冲信号,参考:

互相关(cross-correlation)及其在Python中的实现 | Dynamics and Python (fanyublog.com)

def correlation(a,v):
    nom = np.linalg.norm(a[:])*np.linalg.norm(v[:])
    return irfft(rfft(a)*rfft(v[::-1]))/nom

 计算互相关需要numpy类型,但发现由于采用waveopen的返回对象为特殊类型,尝试了几个帖子里转换文件类型的方法,发现还是直接使用librosa读取比较方便,且不会影响之后wav文件的保存。参考的帖子:

Python:将wav文件写入numpy浮动数组-腾讯云开发者社区-腾讯云 (tencent.com)

从numpy.frombuffer 报错 ValueError: buffer size must be a multiple of element size 到理解音频信号 - 代码先锋网 (codeleading.com)

定位相关性最好的位置:

scipy使用python寻找时间序列的极大值(局部最大值)或极小值(局部最小值),极值点_argrelextrema scipy-CSDN博客

也可参考:Python常用的峰值查找算法整理(peak detection) - 知乎 (zhihu.com) 

汇总为

import wave
import numpy as np
from scipy import signal
from scipy.fftpack import rfft,irfft
import librosa

def correlation(a,v):
    nom = np.linalg.norm(a[:])*np.linalg.norm(v[:])
    return irfft(rfft(a)*rfft(v[::-1]))/nom
def cutwav(wavpath,wav_std):
    #wavpath是待处理wav的路径,wav_std是用于计算相关性的参考信号,读入为np数组
    wf = wave.open(wavpath, "rb")
 
    # 获取音频文件基本信息
    nchannels = wf.getnchannels()  # 声道数
    sampwidth = wf.getsampwidth()  # 采样位宽
    framerate = wf.getframerate()  # 采样率
    nframes = wf.getnframes()      # 采样点数

    wav,sr=librosa.load(wavpath, sr=None, mono=False)
 
    # 设置分割的长度为10ms
    length =int( 0.01 * framerate)
    
    
    CRR = []
    for n_frames in range(0,nframes-length+1):
     
        data=wav[n_frames:n_frames+length]
        #print(len(data))
        crr=correlation(data,wav_std)
        
        CRR.append(max(crr))
        
    CRR=np.array(CRR)
    n_frames=signal.argrelextrema(CRR, np.greater, order=200)#返回对象<class 'numpy.ndarray'>,包含多个属性(array([  73,  484,  920, 1302], dtype=int64),)。order的大小要根据脉冲的长度调整,不设置order会导致python进入未响应状态

    n_frames=n_frames[0]#第一个属性即np数组,得到各极值点的横坐标

    for i in range(0,len(n_frames)):
        
        
        print(n_frames[i])
        # 截取片段
        wf.setpos(n_frames[i])#将文件指针设置到指定位置。
        data = wf.readframes(length)
        
        # 保存为新文件
        new_wf = wave.open("wav_%03d.wav" % (i), "wb")
        new_wf.setnchannels(nchannels)
        new_wf.setsampwidth(sampwidth)
        new_wf.setframerate(framerate)
        new_wf.writeframes(data)
        new_wf.close()

另外,几种wav读取方法应根据需求选择,可参考:

七种python读取语音文件的方法 - glowwormss - 博客园 (cnblogs.com)

Python 读取wav文件的几种方式及优缺点_wav.read-CSDN博客


 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值