语音识别与克隆算法(二)

简介: 语音识别与克隆算法(二)

基于音频指纹的音乐识别


说到音乐识别,相信很多小伙伴都很熟悉,比如酷狗音乐,QQ音乐,网易音乐,他们都有很多的功能,其中就有一个功能就有音乐识别。本届我们就来了解一下基于“音频指纹”的音乐识别系统。


03e2ae16beec758a4d8fc554109fd931_179f2e3b5b8347da84f6d4228826beb4.png


系统架构的核心模块包括信号采集,音频指纹(亦可称之为声纹)生成以及数据存储系统。其中,音频指纹生成苏算法的核心部分会采用傅里叶变换。


音频信号采集与播放

“听歌识曲”首先是“听”,然后才能“识”。“听”的过程,实际上就是一个音频采集(录音与采样)的过程。:识“的过程,是将采集到的音频片段与曲库中的歌曲数据进行比对来获取歌曲信息的过程。曲库中保存着大量的歌曲数据,包括歌曲名称,歌曲存储位置,歌曲声纹等信息。


在写代码之前,我们需要先进行安装模块pyaudio模块。


#音频信号采集与播放
import wave
import pyaudio
class SoundProcessing():
    def Record(self,CHUNK=44100,FORMAT=pyaudio.paInt16,CHANNELS=2,RATE=441100,
               RECORD_SECONDS=200,WAVE_OUTPUT_FILENAME="demoWave.wav"):
        p=pyaudio.PyAudio()
        stream=p.open(format=FORMAT,
                      channels=CHANNELS,
                      rate=RATE,
                      input=True,
                      frames_per_buffer=CHUNK)
        frames=[]
        for i in range(0,int(RATE/CHUNK*RECORD_SECONDS)):
            data=stream.read(CHUNK)
            frames.append(data)
        stream.stop_stream()
        stream.close()
        p.terminate()
        wf=wave.open(WAVE_OUTPUT_FILENAME,'wb')
        wf.setnchannels(CHANNELS)
        wf.setsampwidth(p.get_sample_size(FORMAT))
        wf.setframerate(RATE)
        wf.writeframes(b''.join(frames))
        wf.close()
    def Play(self,FILEPATH):
        chunk=1024
        wf=wave.open(FILEPATH,'rb')
        p=pyaudio.PyAudio()
        #打开声音输出流
        stream=p.open(format=p.get_format_from_width(wf.getsampwidth()),
                      channels=wf.getnchannels(),
                      raate=wf.getframerate(),
                      output=True)
        while True:
            data=wf.readframes(chunk)
            if data=="":
                break
            stream.write(data)
        stream.close()
        p.terminate()
if __name__=='__main__':
    snd=SoundProcessing() #类的实例化
    #录音并将其存储为demoWave.wav文件
    snd.Record(RECORD_SECONDS=30,WAVE_OUTPUT_FILENAME='demoWave.wav')
    snd.Play('demoWave.wav')


音频指纹生成


音频文件有很多格式,注入MP3,WAV,PCM等。其中,WAV格式是Microsoft公司研发的一种音频格式文件,它符合资源交换文件格式(Resource Interchange File Format,RIFF)规范,用于保存Windows操作系统的音频信息资源,beiWindows操作系统及其应用程序广泛支持。标准化的WAV文件采用44100采样率,16bit深度编码。WAV文件分为两个部分,第一个部分是WAV头文件,第二个部分是利用脉冲编码调制(Pulse Code Modulation,PCM)方式进行编码的音频数据。我们将以常见的WAV格式为例,来阐述如何生成音乐的音频指纹(声纹)。


从本质上来看,声音就是一种波。


我们用一个音频文件来描述其波形:


import wave
import matplotlib.pyplot as plt
import numpy as np
import os
waveFile=wave.open('./test.wav','rb')
params=waveFile.getparams()
nchannels,sampwidth,framerate,nframes=params[:4]
strData=waveFile.readframes(nframes)#读取音频文件并转为字符串格式
waveData=np.fromstring(strData,dtype=np.int16) #将字符串格式转化为int类型
waveData=waveData*1.0/(max(abs(waveData))) #wave幅值归一化
#音频波形可视化
time=np.arange(0,nframes)*(1.0/framerate)
waveData=np.arange(453632)
plt.plot(time,waveData)
plt.xlabel("Time(X)")
plt.ylabel("Amplitude(Y)")
plt.title("Single Channel Wave")
plt.grid("on")
plt.show()


8b8483846f9305f7d7474dc8be840e0f_ef4c132baacb46c192e9f74d09c847cf.png


音频波形文件是连续的模拟信号,经过采样可形成数字信号。对于一个单声道音频文件而言,经采样后,实际上就产生一个二维数组,每个元素是对应采样点的数值。对于我们普通人来说,我们该如何去实现听歌识曲?那就是背歌词,只要听到某一句或者多句歌词,就会记起来,但是对于像博主我记忆力不好的人而言,记住很多歌曲是不现实的,所以,我们就要采用其他的方式。那就是利用计算机来记住音频信号序列。声音属于时域信号,我们需要将其转化为频域信号以便后续的信号处理。以下示例代码,通过傅里叶变换将音频时域信号转换为频域信号。


import wave
import matplotlib.pyplot as plt
import numpy as np
import os
waveFile=wave.open('./test.wav','rb')
params=waveFile.getparams()
nchannels,sampwidth,framerate,nframes=params[:4]
strData=waveFile.readframes(nframes)#读取音频文件并转为字符串格式
waveData=np.fromstring(strData,dtype=np.int16) #将字符串格式转化为int类型
waveData=waveData*1.0/(max(abs(waveData))) #wave幅值归一化
#音频波形可视化
time=np.arange(0,nframes)*(1.0/framerate)
#waveData=np.arange(453632)
df=1
freq=[df*n for n in range(0,len(waveData))]
c=np.fft.fft(waveData)
plt.plot(freq,abs(c),color='blue')
plt.xlabel("Frequency(Hz)")
plt.ylabel("Amplitude(Y)")
plt.title("Frequency Domain Signal")
plt.grid(True)
plt.show()


4db5538edb4bc7dbefb2663f87127fe1_6255c67994c148d5a2da1c00cf22ec25.png



音频信号经傅里叶变换之后,原本x,y轴分别为时间和波幅,现在则是频率以及频率幅值,与此同时,也改变了我们对音频构成的理解。


对每一帧音频信号进行傅里叶变换后,就可以开始构造声纹了,这就是整个系统中最核心的部分。构造声纹的最大挑战就是在于如何从众多的频率中选出区分都最大的频率分量。直观上看,选择具有最大幅值的频率(峰值)较为可靠。由于一首音乐的频率分布跨度太大,所以分析的时候会存在难以选择,为了避免分析整个频谱,我们通常将频谱分成多个子带,从每个子带中选择一个频率峰值。低子音带为30Hz~40Hz,40~80Hz和80~120Hz,中音和高音子带分别为120Hz~180Hz和180Hz~300Hz(人声和大部分乐器的基频出现在这俩个子带)。每个子带的最大频率就构成了这一帧信号的签名,这也就是我们最核心的“音频指纹”。


音频文件载入,音频指纹生成功能的实现示例代码:


import numpy as np
import os
import wave
class SoundProcessing():
    SongName=""
    document=[] #存放歌曲指纹列表
    def DataLoad(self,FILEPATH):
        filename_list=os.listdir(FILEPATH)
        for filename in filename_list:
            if filename.endswith('wav'):  #检查文件是否是wav格式
                SoundProcessing.SongName=filename
                f=wave.open(FILEPATH+"\\"+filename,'rb')
                params=f.getparams()
                self.nchannels,self.sampwidth,self.framerate,self.nframes=params[:4]
                str_data=f.readframes(self.nframes)
                self.wave_data=np.fromstring(str_data,dtype=np.short)
                self.wave_data.shape=-1,self.sampwidth
                self.wave_data=self.wave_data.T
                self.GenerateFingerPrint()
                self.name=os.path.basename('./test1.wav')
                return True
        f.close()
    def GenerateFingerPrint(self,frames=40):
        block=[]
        fft_blocks=[]
        self.high_point=[]  #用于保存生成的音频指纹
        blocks_size=self.framerate//frames
        blocks_num=self.nframes/blocks_size
        for i in range(0,len(self.wave_data[0])-blocks_size,blocks_size):
            block.append(self.wave_data[0][i:i+blocks_size])
            fft_blocks.append(np.abs(np.fft.fft(self.wave_data[0][i:i+blocks_size])))
        self.high_point.append((np.argmax(fft_blocks[-1][0:40]),np.argmax(fft_blocks[-1][40:80])+40,
                                np.argmax(fft_blocks[-1][80:120])+40,
                                np.argmax(fft_blocks[-1][120:180])+120,))
        song_fp="{'songname'"+":'"+SoundProcessing.SongName+"','fingerprint'"+":"+str(self.high_point[20:25])+"}"
        song_fp=eval(song_fp)
        SoundProcessing.document.append(song_fp)
        print (SoundProcessing.document)
if __name__=="__main__":
    a=SoundProcessing()
    a.DataLoad('F:\人工智能算法')
    a.GenerateFingerPrint(frames=40)


结果展示:


[{'songname': 'test.wav', 'fingerprint': []}] [{'songname': 'test.wav', 'fingerprint': []}, {'songname': 'test.wav', 'fingerprint': []}]


在构造指纹的时候,我们需要注意的是,用户所除的环境的复杂,所以录制的音乐可能会有所杂音,于是,我建议在使用音频指纹的时候引入模糊化操作等手段来提高算法的抗噪能力。否则会影响最终检索质量。


语音克隆技术简介


语音合成,是指文本到音频的人工转换,或给定一段文字让计算机自动生成对应的人类读音。通过AI语音技术,在极短的时间内“克隆”出目标人物的声音。相信喜欢看碟战片的小伙伴比较了解,里面各个国家的特工,利用语音合成,模仿别人的声音,获取情报。在计算机技术发展迅速的今天,这些都已经能够实现。


合成自然语音,需要对大量高质量的语音转录进行训练。若要支持多人语音通常需要对每个人的语音数据集进行数十分钟的训练,而为多人记录大量高质量的数据不太现实。该项目所采用的方法是,通过独立训练一个捕捉说话人特征空间(Space of Speaker Characterstics)语音识别嵌入网络(Speaker-Descriminative Embedding Network),并在一个较小的数据集上训练一个高质量的TTS模型,从而将说话人建模与语音合成分离。解耦合网络使他们能够在独立的数据上进行训练,从而减少获得高质量多峰训练数据的需要。


该语音克隆系统由3个独立训练的神经网络组成。如图:


7884e9fa8a8eb866de5a313b253fce5d_f89b23087aac434abec07635922fb45f.png


1.说话人语音编码器(Speaker Encoder)


它先从说话人那里获取一段参考语音信号(Speaker Reference Waveform),亦即说话人的音频小样本,然后从中计算出一个固定维矢量(Fixed Dimensional Vector)。


2.序列合成器(Synthesizer)


它基于说话人嵌入矢量,根据一系列字素(Grapheme)或音素输入,预测出一个对数梅尔频谱(Log-Mel Spectrum)。也就是给定一段文本,将其编码为向量表示,然后,将语音与文本这两个向量结合起来解码成声谱图(Spectrogram)。


3.声码器(Vocoder)


它将对数梅尔频谱转换成时域波形(Waveform)。也就是将声谱图转换成我们可以听到的音频波形。


由于博主对机器学习知识还不掌握,这里只能稍做介绍。语音篇的学习就到此结束了,后面就是自然语言处理技术的分享。期待大家的关注,点赞,收藏。

相关实践学习
达摩院智能语音交互 - 声纹识别技术
声纹识别是基于每个发音人的发音器官构造不同,识别当前发音人的身份。按照任务具体分为两种: 声纹辨认:从说话人集合中判别出测试语音所属的说话人,为多选一的问题 声纹确认:判断测试语音是否由目标说话人所说,是二选一的问题(是或者不是) 按照应用具体分为两种: 文本相关:要求使用者重复指定的话语,通常包含与训练信息相同的文本(精度较高,适合当前应用模式) 文本无关:对使用者发音内容和语言没有要求,受信道环境影响比较大,精度不高 本课程主要介绍声纹识别的原型技术、系统架构及应用案例等。 讲师介绍: 郑斯奇,达摩院算法专家,毕业于美国哈佛大学,研究方向包括声纹识别、性别、年龄、语种识别等。致力于推动端侧声纹与个性化技术的研究和大规模应用。
相关文章
|
2月前
|
机器学习/深度学习 算法 TensorFlow
【深度学习】深度学习语音识别算法的详细解析
深度学习语音识别算法是一种基于人工神经网络的语音识别技术,其核心在于利用深度神经网络(Deep Neural Network,DNN)自动从语音信号中学习有意义的特征,并生成高效的语音识别模型。以下是对深度学习语音识别算法的详细解析
83 5
|
2月前
|
机器学习/深度学习 人工智能 算法
【语音识别算法】深度学习语音识别算法与传统语音识别算法的区别、对比及联系
深度学习语音识别算法与传统语音识别算法在理论基础、实现方式、性能表现等方面存在显著区别,同时也有一些联系。下面将从几个方面详细比较这两种方法,并给出应用实例和代码示例
36 4
|
2月前
|
机器学习/深度学习 人工智能 算法
【人工智能】传统语音识别算法概述,应用场景,项目实践及案例分析,附带代码示例
传统语音识别算法是将语音信号转化为文本形式的技术,它主要基于模式识别理论和数学统计学方法。以下是传统语音识别算法的基本概述
66 2
|
3月前
|
机器学习/深度学习 算法 数据可视化
Python基于librosa和人工神经网络实现语音识别分类模型(ANN算法)项目实战
Python基于librosa和人工神经网络实现语音识别分类模型(ANN算法)项目实战
|
5月前
|
机器学习/深度学习 自然语言处理 算法
基于深度学习的语音识别技术应用与发展
在当今数字化时代,语音识别技术已经成为人机交互领域的重要组成部分。本文将介绍基于深度学习的语音识别技术在智能助手、智能家居和医疗健康等领域的应用与发展,同时探讨该技术在未来的潜在应用和发展方向。
187 4
|
2月前
|
机器学习/深度学习 人工智能 语音技术
使用深度学习进行语音识别:技术探索与实践
【8月更文挑战第12天】深度学习技术的快速发展为语音识别领域带来了革命性的变化。通过不断优化模型架构和算法,我们可以期待更加准确、高效和智能的语音识别系统的出现。未来,随着技术的不断进步和应用场景的不断拓展,语音识别技术将在更多领域发挥重要作用,为人类带来更加便捷和智能的生活体验。
|
2月前
|
人工智能 算法 人机交互
FunAudioLLM技术深度测评:重塑语音交互的未来
在人工智能的浪潮中,语音技术作为人机交互的重要桥梁,正以前所未有的速度发展。近期,FunAudioLLM以其独特的魅力吸引了业界的广泛关注。本文将以SenseVoice大模型为例,深入探索FunAudioLLM在性能、功能及技术先进性方面的表现,并与国际知名语音大模型进行对比分析,同时邀请各位开发者共同参与,为开源项目贡献一份力量。
76 4
|
3月前
|
人工智能 API 语音技术
PHP对接百度语音识别技术
PHP对接百度语音识别技术
88 1
|
3月前
|
机器学习/深度学习 自然语言处理 大数据
语音识别和语音合成技术
语音识别和语音生成是人工智能的重要分支,旨在实现计算机对人类语音的理解和生成。随着深度学习技术的快速发展,语音识别和生成技术在近年来取得了显著进展,并在多个领域实现了广泛应用。本文将介绍语音识别和生成的基本原理、关键技术及其应用,并探讨其未来的发展趋势。
134 3
|
2月前
|
机器学习/深度学习 自然语言处理 算法
尖叫!FunAudioLLM 技术掀起狂潮,开启语音交互的惊天巨变之门!
【8月更文挑战第8天】随着科技的进步,语音交互已成为日常不可或缺的部分。FunAudioLLM凭借其先进的自然语言处理和深度学习技术,在语音理解和生成方面实现了突破。相较于传统技术,它提升了理解和响应速度。通过简单的Python代码示例,我们可以测试其对如天气查询等指令的快速准确反馈。FunAudioLLM不仅适用于日常交流,还在医疗、教育等领域展现出应用潜力。尽管存在多语言环境下的准确性挑战,其为语音交互领域带来的革新仍值得期待。随着技术的持续发展,FunAudioLLM将为更多领域带来便利和效率。
57 0

热门文章

最新文章