读取信号为数组
def wavread(filename): f = wave.open(filename,'rb') params = f.getparams() nchannels, sampwidth, framerate, nframes = params[:4] strData = f.readframes(nframes)#读取音频,字符串格式 waveData = np.fromstring(strData,dtype=np.int16)#将字符串转化为int f.close() waveData = waveData*1.0/(max(abs(waveData)))#wave幅值归一化 waveData = np.reshape(waveData,[nframes,nchannels]) return waveData
音量计算
# method 1: absSum def calVolume(waveData, frameSize, overLap): wlen = len(waveData) step = frameSize - overLap frameNum = int(math.ceil(wlen*1.0/step)) volume = np.zeros((frameNum,1)) for i in range(frameNum): curFrame = waveData[np.arange(i*step,min(i*step+frameSize,wlen))] curFrame = curFrame - np.median(curFrame) # zero-justified volume[i] = np.sum(np.abs(curFrame)) return volume
分帧信号
def enframe(signal, nw, inc): '''将音频信号转化为帧。 参数含义: signal:原始音频型号 nw:每一帧的长度(这里指采样点的长度,即采样频率乘以时间间隔) inc:相邻帧的间隔(同上定义) ''' signal_length=len(signal) #信号总长度 if signal_length<=nw: #若信号长度小于一个帧的长度,则帧数定义为1 nf=1 else: #否则,计算帧的总长度 nf=int(np.ceil((1.0*signal_length-nw+inc)/inc)) pad_length=int((nf-1)*inc+nw) #所有帧加起来总的铺平后的长度 zeros=np.zeros((pad_length-signal_length,)) #不够的长度使用0填补,类似于FFT中的扩充数组操作 pad_signal=np.concatenate((signal,zeros)) #填补后的信号记为pad_signal indices=np.tile(np.arange(0,nw),(nf,1))+np.tile(np.arange(0,nf*inc,inc),(nw,1)).T #相当于对所有帧的时间点进行抽取,得到nf*nw长度的矩阵 indices=np.array(indices,dtype=np.int32) #将indices转化为矩阵 frames=pad_signal[indices] #得到帧信号 # win=np.tile(winfunc(nw),(nf,1)) #window窗函数,这里默认取1 # return frames*win #返回帧信号矩阵 return frames
#端点检测,通道(阈值)计算方法
def findIndex(vol,thres): l = len(vol) ii = 0 index = np.zeros(500,dtype=np.int16) for i in range(l-1): if((vol[i]-thres)*(vol[i+1]-thres)<0): index[ii]=i ii = ii+1 #return index[[0,-1]] return index
#基频(音高)计算
# 自相关函数计算基频率 def ACF(frame): flen = len(frame) acf = np.zeros(flen) for i in range(flen): acf[i] = np.sum(frame[i:flen]*frame[0:flen-i]) return acf