• 对哼唱的语音或者播放的音乐进行乐谱的识别,并将哼唱转换为其他乐器的声音回放


    读取信号为数组

    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
    View Code

    音量计算

    # 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
    View Code

    分帧信号

    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
    View Code

    #端点检测,通道(阈值)计算方法 

    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
    View Code

    #基频(音高)计算

    # 自相关函数计算基频率
    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
    View Code
  • 相关阅读:
    链表 | 递归删除不带头结点链表所有x元素
    A1016 | 磨人的大模拟
    Ubuntu 下安装 Qt Designer
    shell札记
    A1102 | 反转二叉树
    顺序表 | 二分查找:两个数组合并后的中位数
    A1113 | Integer Set Partition (25)
    A1128 | 逻辑想象能力、简洁高效美观的代码、memset的使用情景
    05.字符串
    04.序列的应用
  • 原文地址:https://www.cnblogs.com/oucxlw/p/9224857.html
Copyright © 2020-2023  润新知