diff --git a/README.md b/README.md index 53bc1ac..3988a39 100644 --- a/README.md +++ b/README.md @@ -4,33 +4,33 @@ LipSync是一个基于Unity的独立、轻量化口型匹配解决方案。它 不过LipSync并不是万能的。为了能够愉快而有效地使用LipSync,你需要知道它目前做得到的事情有: -* 实时地分析语音数据,运用语音识别的一些理论,识别出某一时间帧中这段语音在日语或汉语 __元音__ 是什么,如果有的话。 -* 事先分析好语音数据,把声学特征识别结果(也就是元音)作为资源文件存储在项目中,运行时直接读取这些数据。也就是烘焙功能。 -* 根据识别结果,生成动画权重数值,并把它们赋到目标对象上。 -* 让你的角色看起来真的像在说话一样。 +* 实时地分析语音数据,运用语音识别的一些理论,识别出某一时间帧中这段语音在日语或汉语 __元音__ +* 事先分析好语音数据,把声学特征识别结果(也就是元音)作为资源文件存储在项目中,运行时直接读取这些数据 +* 根据识别结果,生成动画权重数值,并把它们赋到目标对象上 +* 让你的角色看起来真的像在说话一样 它目前做不到的事情有: -* 无中生有,在没有BlendShape的目标对象上实现口型匹配。 -* 识别出语音中的辅音。 -* 分析噪声过于严重的语音数据。 -* 分辨某一段声音是语音还是和语音不相关的其他声音。 +* 无中生有,在没有BlendShape的目标对象上实现口型匹配 +* 识别出语音中的辅音 +* 分析噪声过于严重的语音数据 +* 分辨某一段声音是语音还是和语音不相关的其他声音 LipSync文件夹中的内容是本插件的主体部分,而UnityChan文件夹中的内容并不是本插件的一部分,它是为了演示LipSync的效果而附带的一套模型资源。她其实是Unity Technology Japan为Unity开发的一个官方形象。如果你想进一步了解UnityChan,可以在[这里][i2]获得她的信息。 -查看实现的效果展示视频, 点击[这里][i1]。 +查看实现效果的展示视频, 点击[这里][i1], 笔者已经上传到B站。 ## 使用LipSync前需要做什么准备? LipSync需要你提供以下资源: -__1) 语音文件。__ +__1) 语音文件__ 角色使用的语音文件。 为了保证语音识别方面的可靠性,语音中的噪音不能特别大。些许的噪音可以接受,LipSync一定程度上可以帮助剔除。 语音中也不能包含其他非语音的声音,例如背景音乐,环境音效等等。 除此之外没有其他的强制要求,只要是语音都可以使用。日语和汉语的语音可以得到最佳的匹配效果,其他语言的语音也可以使用。对于文件资源的摆放位置,有一个非强制的推荐性要求,即把每一个人的所有语音放置在各自的一个文件夹中。这有利于提高烘焙功能的使用效率。 如果你的开发工程是基于fmod环境的,步骤参见[install.md](install.md) -__2) 带有口型BlendShape的3D模型。__ +__2) 带有口型BlendShape的3D模型__ 角色的3D模型,并且需要包括口型的BlendShape。至少每一个元音要对应一个BlendShape属性值,也就是说,在对应日语的情况下,你需要5个BlendShape属性值,对应汉语则需要6个。如果你的语音是这两种语言以外的,可以使用汉语元音的标准。如果你不知道BlendShape是什么,可以结合演示场景参考UnityChan的模型。 @@ -49,9 +49,7 @@ WindowSize的含义是窗口大小,它决定一次性从整个语音数据中 AmplitudeThreshold的含义是能量阈值,它决定一个数据帧中所有值的总和要大于多少,才会被判断为一个有语音信息的帧。这一设计的作用是剔除无声帧,以减少不必要的识别操作。对于有少量噪音的语音,如果将这个值设得稍大一点,一定程度上就可以起到降噪的作用。 MoveTowardsSpeed的含义是平滑过渡的速度。语音帧与语音帧之间的识别结果,并不是直接就赋予到BlendShape属性值上的,而是经过了平滑过渡操作,实际赋予的属性值是经过插值的。从效果上看,这个速度越低,角色的嘴巴就动得越慢,给人的感觉是不太灵活;反之则越快,给人感觉移动非常夸张。一般来说,这个值可以取在6到10之间。 -完成了这些设置值之后,尝试运行一下,你应该就可以看到UnityChan随着语音的播放动起了她的嘴巴。 - -在这个例子中,所识别的语音是日语,正如RecognizerLanguage所示的Japanese。如果你需要识别汉语,可以把RecognizerLanguage项切换成Chinese,此时VowelPropertyNames中会多出一个“v”的元音。除此之外没有其他变化。 +完成了这些设置值之后,尝试运行一下,你应该就可以看到UnityChan随着语音的播放动起了她的嘴巴。例子中,所识别的语音是日语,正如RecognizerLanguage所示的Japanese。如果你需要识别汉语,可以把RecognizerLanguage项切换成Chinese,此时VowelPropertyNames中会多出一个“v”的元音。除此之外没有其他变化。 以上介绍的都是在运行时即时地进行口型匹配。而在这一类动画相关的技术中,有一个很常用的处理方式——烘焙。以一定的灵活性为代价,把动画信息在开发阶段全部准备好,在运行时直接读取,这样便可在运行时省去所有的识别运算,从而大幅提高性能。LipSync也提供了这样的功能。 @@ -63,22 +61,19 @@ MoveTowardsSpeed的含义是平滑过渡的速度。语音帧与语音帧之间

-在这里,你可以导入一个文件夹里的语音文件,并把它们的口型匹配数据烘焙到本地文件上。这里利用了Unity的动画系统,输出的文件就是AnimationClip与AnimatorController。 +你可以导入一个文件夹里的语音文件,并把它们的口型匹配数据烘焙到本地文件上。这里利用了Unity的动画系统,输出的文件就是AnimationClip与AnimatorController。 先从AudioClipInputFolderPath开始,这里点击“Browse...”按钮可以选择一个路径。当然,你只能选择位于Assets文件夹内的路径。之后,LipSync会搜索该文件夹内所有的音频文件,并记录到AudioClipList中。AnimatorName是烘焙完毕后,生成的Animator的名称。你可以自行进行指定。TargetRelativePath是为了应对特殊情况,一般来说生成的Animator会被挂载在目标对象上,但是可能会因为某些原因,导致只能挂载在它的某一个父级GameObject。这个TargetRelativePath就是用来指定相对路径用的。通常情况下不会用到它,这里我们选择不填写。 + 另外,AdvancedOptions里也多出了一项ShiftStepSize,这决定了采样时数据帧与数据帧之间的间隔。在实时匹配时,由于LipSync可以直接采样当前帧(渲染意义上)正在播放的声音片段,所以不需要这一个属性,而烘焙时声音并没有被真正播放,所以需要指定这个值。一般来说,取窗口长度的一半可以得到非常精确的结果,小于这个值的意义不大,烘焙时间却会增长。 全部设置完毕后,你可以点击“Bake”按钮。选择一个Assets文件夹内的路径,即可开始烘焙工作。烘焙工作需要的时间比较长,限于目前采用的计算方法,可能会长于语音文件本身的时间长度,请耐心等待一下。经过漫长的等待后,你可以在刚才指定的路径中找到烘焙结果。 - 然后,在目标对象上新建一个Animator组件,并把生成的AnimatorController赋予到上面。回到LipSync组件上,将目标对象赋予到TargetAnimator上。最后应该像下图这样。

-尝试运行一下,你应该可以看到UnityChan的嘴巴又动了起来。 -至此,你应该已经会使用LipSync几乎所有的功能了。接下来,就看你如何运用LipSync带给你的口型匹配功能了。 +尝试运行一下,你应该可以看到UnityChan的嘴巴又动了起来。至此,你应该已经会使用LipSync几乎所有的功能了。 ## LipSync的原理是什么? -LipSync主要涉及到的是信号处理与语音识别领域的理论知识。这一部分将进行简单的解说,如果想深入了解,可以自行查阅相关概念。 -它的基本工作流程如下: #### 1、从AudioSource或者AudioClip处获取语音数据 @@ -92,8 +87,7 @@ LipSync主要涉及到的是信号处理与语音识别领域的理论知识。 #### 3、获取语音数据的频域信息 -你在使用一些音乐播放器时,有时候会看到一根根跳动的长条,这就是“频谱”的一种表现方式,频域信息指的就是频谱。这对于语音识别来说是非常重要的信息。 -实时匹配时,AudioSource的GetSpecturmData函数带来了极大的帮助,这个函数本身可以高效地获取当前播放的语音数据频谱。 +你在使用一些音乐播放器时,有时候会看到一根根跳动的长条,这就是“频谱”的一种表现方式,频域信息指的就是频谱。这对于语音识别来说是非常重要的信息。实时匹配时,AudioSource的GetSpecturmData函数带来了极大的帮助,这个函数本身可以高效地获取当前播放的语音数据频谱。 然而在烘焙时,并没有这样便利的函数可以用。所以,LipSync借助了一个数学工具——离散余弦变换(DCT),它可以用来获取一个时域信息段的频域信息。它与另一个著名的数学工具——傅里叶变换是等价的,所不同的是余弦变换只获取频率信息,而舍弃了相位信息。实际上这就够了,我们并不需要相位信息。这个数学工具的实现可以在MathToolBox.DiscreteCosineTransform中找到。 diff --git a/install.md b/install.md index c6f13f6..edd7df5 100644 --- a/install.md +++ b/install.md @@ -1,26 +1,26 @@ -##FMOD LipSync +## FMOD LipSync -1. Download fmod unitypackage +#### 1. Download fmod unitypackage 链接: https://pan.baidu.com/s/1dWuKDKMh1MDsnbN73h9xVw 提取码: 7z8v -2. Import unitypackage to unity project +#### 2. Import unitypackage to unity project -3. Import fmod asset (.bank) +#### 3. Import fmod asset (.bank) -4. Add macro in buildsettings +#### 4. Add macro in buildsettings macro: FMOD_LIVEUPDATE -

+

-5. Open Scene named FmodScene +#### 5. Open Scene named FmodScene path: Assets/LipSync/Demo/Scenes/FmodScene -6. Config fmod events in FmodLipSync +#### 6. Config fmod events in FmodLipSync -

+

-7. Start Game and run \ No newline at end of file +#### 7. Start Game and run \ No newline at end of file