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