注释
本文主要介绍 Windows 10(版本 1909 及更早版本)中交付的使用者体验。 有关详细信息,请参阅 Cortana 的支持结束。
Cortana(Windows 语音平台)为 Windows 10 中的所有语音体验提供支持,例如 Cortana 和听写。 语音激活是一项功能,允许用户通过说出特定短语“你好 Cortana”,从各种设备电源状态调用语音识别引擎。若要创建支持语音激活技术的硬件,请查看本文中的信息。
注释
实现语音激活是一项重要项目,是 SoC 供应商完成的任务。 OEM 可以联系其 SoC 供应商,了解有关其 SoC 实现语音激活的信息。
Cortana 最终用户体验
若要了解 Windows 中提供的语音交互体验,请查看以下文章。
| Article | Description |
|---|---|
| 什么是 Cortana? | 提供 Cortana 的概述和使用方向 |
“Hey Cortana” 语音激活和“学习我的声音”简介
Hey Cortana“语音激活
“你好 Cortana”语音激活(VA)功能允许用户使用其语音在活动上下文(即当前屏幕上的内容)之外快速参与 Cortana 体验。 用户通常希望能够即时访问体验,而无需物理交互或触摸设备。 电话用户可能在开车,注意力和双手都在操作车辆。 Xbox 用户可能不想查找和连接控制器。 电脑用户可能希望迅速获得体验,而无需执行多次鼠标、触摸或键盘操作。 例如,在厨房中一边烹饪一边使用计算机。
语音激活始终通过预定义的关键短语或激活短语提供语音输入。 关键短语可以单独发出(“Hey Cortana”)作为阶段性命令,或后接语音操作,例如,“你好 Cortana,我的下一个会议在哪里?”,这是一个连锁命令。
术语 关键字检测 描述通过硬件或软件检测关键字。
仅凭关键词 激活发生在仅说出 Cortana 的关键词时,Cortana 将启动并播放 EarCon 声音以表明它已进入侦听模式。
链式命令指的是在关键字(例如“你好小娜,请拨打 John”)之后立即发出命令的能力,此时 Cortana 会启动(如果尚未启动)并执行该命令(开始拨打 John 的电话)。
此图演示了链式激活和仅关键字激活。
Microsoft提供了 OS 默认关键字发现器(软件关键字发现器),用于确保硬件关键字检测的质量,并在硬件关键字检测不存在或不可用的情况下提供 Hey Cortana 体验。
“了解我的声音”功能
“了解我的声音”功能允许用户训练 Cortana 来识别其独特的语音。 用户通过在 Cortana 设置屏幕中选择“了解如何说‘你好 Cortana’”来实现这一操作。 然后,用户重复六个精心选择的短语,这些短语提供了足够的各种拼音模式,以识别用户语音的唯一属性。
当语音激活与“了解我的声音”配对时,这两种算法协同工作以减少误激活。 这对于会议室场景特别有价值,其中一个人在充满设备的房间里说“你好 Cortana”。 此功能仅适用于 Windows 10 版本 1903 及更早版本。
语音激活由关键字发现器(KWS)提供支持,当检测到关键短语时会做出反应。 如果 KWS 从低功率状态唤醒设备,则解决方案称为语音唤醒(WoV)。 有关详细信息,请参阅 “语音唤醒”。
术语词汇表
此术语表汇总了与语音激活相关的术语。
| 术语 | 示例/定义 |
|---|---|
| 准备好的命令 | 示例:嘿,Cortana <暂停,等待 EarCon 声音> 天气怎么样? 这有时称为“双步操作命令”或“仅限关键字模式” |
| 链式命令 | 嘿,小娜,天气怎么样? 这有时称为“一次性命令” |
| 语音激活 | 提供预定义激活密钥短语的关键字检测的方案。 例如,“Hey Cortana” 是 Microsoft 语音激活场景。 |
| WoV | 语音唤醒技术——使设备从屏幕关闭、低功耗状态转为屏幕开启、全功耗状态的技术。 |
| WoV 来自现代待机 | 从新式待机(S0ix)屏幕关闭状态到全电源(S0)状态的屏幕的唤醒语音。 |
| 新式待机 | Windows 低功率空闲基础结构 - Windows 10 中连接待机(CS)的继任者。 新式待机的第一种状态是屏幕关闭时。 最深的睡眠状态是处于 DRIPS/弹性状态。 有关详细信息,请参阅 新式待机 |
| KWS | 关键字发现器 - 提供检测“你好 Cortana”的算法 |
| SW KWS | 软件关键字发现器 - 在主机上运行的 KWS 实现(CPU)。 在 Windows 中,“你好小娜” 的 SW KWS 功能已包含在内。 |
| HW KWS | 硬件卸载关键字发现器 – 在硬件上运行卸载的 KWS 的实现。 |
| 突发缓冲区 | 用于存储可在 KWS 检测上“突发”的 PCM 数据的循环缓冲区,以便包括触发 KWS 检测的所有音频。 |
| 关键字检测器 OEM 适配器 | 驱动程序级填充码,使已启用 WoV 的 HW 能够与 Windows 和 Cortana 堆栈通信。 |
| 型号 | KWS 算法使用的声学模型数据文件。 数据文件是静态的。 模型已本地化,每个区域设置一个。 |
集成硬件关键词识别器
若要实现硬件关键字发现器(HW KWS),请完成以下任务。
- 基于本文后面所述的 SYSVAD 示例创建自定义关键字检测器。 你将在 COM DLL 中实现这些方法,如 关键字检测器 OEM 适配器接口中所述。
- 实现 WAVERT 增强中介绍的 WAVE RT 增强功能。
- 提供 INF 文件条目来描述用于关键字检测的任何自定义 API。
- PKEY_FX_KeywordDetector_StreamEffectClsid
- PKEY_FX_KeywordDetector_ModeEffectClsid
- PKEY_FX_KeywordDetector_EndpointEffectClsid
- PKEY_SFX_KeywordDetector_ProcessingModes_Supported_For_Streaming
- PKEY_MFX_KeywordDetector_ProcessingModes_Supported_For_Streaming(支持流处理的关键词检测器处理模式)
- PKEY_EFX_KeywordDetector_ProcessingModes_Supported_For_Streaming
- 查看 音频设备建议中的硬件建议和测试指南。 本文提供有关用于Microsoft语音平台的音频输入设备的设计和开发的指导和建议。
- 支持分阶段命令和串联命令。
- 支持所有受支持的 Cortana 语言区域的“Hey Cortana”。
- APOS(音频处理对象)必须提供以下效果:
- AEC
- AGC
- NS
- 语音处理模式的效果必须由 MFX APO 报告。
- APO 可以将格式转换以 MFX 的方式执行。
- APO 必须输出以下格式:
- 16 kHz,单声道,FLOAT。
- (可选)设计任何自定义 API 以增强音频捕获过程。 有关详细信息,请参阅 Windows 音频处理对象。
硬件卸载关键字发现器 (HW KWS) WoV 要求
- HW KWS WoV 在 S0 工作状态和 S0 睡眠状态(也称为现代待机)时被支持。
- S3 不支持 HW KWS WoV。
HW KWS 的 AEC 要求
对于 Windows 版本 1709
- 要支持 S0 睡眠状态(现代待机)的 HW KWS WoV,不需要 AEC。
- Windows 版本 1709 不支持 HW KWS WoV 的 S0 工作状态。
对于 Windows 版本 1803
- HW KWS WoV 支持 S0 工作状态。
- 若要在 S0 工作状态下启用硬件 KWS WoV,APO 必须支持 AEC。
示例代码概述
GitHub 上实现语音激活的音频驱动程序的示例代码是 SYSVAD 虚拟音频适配器示例的一部分。 建议将此代码用作起点。 代码在此位置可用。
https://github.com/Microsoft/Windows-driver-samples/tree/main/audio/sysvad/
有关 SYSVAD 示例音频驱动程序的详细信息,请参阅 示例音频驱动程序。
关键字识别系统信息
语音激活音频堆栈支持
用于启用语音激活的音频堆栈外部接口充当语音平台和音频驱动程序的通信管道。 外部接口分为三个部分。
- 关键字检测器设备驱动程序接口(DDI)。 关键字检测器设备驱动接口负责配置和启动 HW 关键字检测器(KWS)。 驱动程序还使用它来通知系统检测事件。
- 关键字检测器 OEM 适配器 DLL。 此 DLL 实现 COM 接口,以调整驱动程序特定的不透明数据,使其能够被操作系统使用,从而帮助进行关键字检测。
- WaveRT 流媒体增强功能。 增强功能使音频驱动程序能够突发流式传输来自关键字检测的缓冲音频数据。
音频终结点属性
音频终结点图形生成通常发生。 系统已准备好以比实时捕获更快的速度处理数据。 捕获缓冲区上的时间戳保持准确。 具体而言,时间戳正确反映了过去捕获并缓冲的数据,并且这些数据现在正被释放。
蓝牙音频直通流理论。
驱动程序会像往常一样公开其捕获设备的 KS 筛选器。 此筛选器支持多个 KS 属性和 KS 事件来配置、启用和发出检测事件的信号。 该过滤器还包括另一个被标识为关键字识别器(KWS)引脚的引脚工厂。 此引脚用于从关键字检测器流式传输音频。
这些属性包括:
- 支持的关键字类型 - KSPROPERTY_SOUNDDETECTOR_PATTERNS。 作系统设置此属性以配置要检测的关键字。
- 关键字模式 GUID 列表 - KSPROPERTY_SOUNDDETECTOR_SUPPORTEDPATTERNS。 此属性用于获取标识受支持模式类型的 GUID 列表。
- 武装 - KSPROPERTY_SOUNDDETECTOR_ARMED。 此读/写属性是一个布尔值,用于指示探测器是否已激活。 OS 将设置此以启用关键字检测器。 OS 可以清除此状态以终止操作。 当设置关键字模式并在检测到关键字后,驱动程序会自动清除此模式。 (操作系统必须重新激活。)
- 匹配结果 - KSPROPERTY_SOUNDDETECTOR_MATCHRESULT。 发生检测后,此读取属性保存结果数据。
检测到关键字时触发的事件是 KSEVENT_SOUNDDETECTOR_MATCHDETECTED 事件。
操作顺序
系统启动
- OS 读取支持的关键字类型,以验证它是否具有该格式的关键字。
- 操作系统注册检测器状态更改事件。
- OS 设置关键字模式。
- 操作系统激活探测器。
接收 KS 事件时
- 驱动程序解除检测器的武装。
- OS 读取关键字检测器状态、分析返回的数据并确定检测到的模式。
- 操作系统重新启用检测器。
内部驱动程序和硬件操作
当检测器被激活时,硬件可以持续在一个小型 FIFO 缓冲区中捕获和缓冲音频数据。 (此 FIFO 缓冲区的大小由本文档以外的要求决定,但通常在几百毫秒到几秒之间。检测算法在通过该缓冲区的流数据上运行。) 驱动程序和硬件的设计在处于激活状态时,使驱动程序与硬件之间没有任何交互,也不会中断“应用程序”处理器,直到检测到关键字为止。 这允许系统在没有其他活动的情况下达到较低的电源状态。
当硬件检测到关键字时,它会生成中断。 在等待驱动程序服务中断时,硬件会继续将音频捕获到缓冲区中,确保关键字丢失后不会丢失任何数据(在缓冲限制内)。
关键字时间戳
检测关键字后,所有语音激活解决方案都必须缓冲所有的语音关键字,包括关键字开始前的250毫秒。 音频驱动程序必须提供时间戳,用于标识流中关键短语的开始和结尾。
为了支持关键字开始/结束时间戳,DSP 软件可能需要基于 DSP 时钟在内部对事件进行时间戳。 检测到关键字后,DSP 软件与驱动程序交互以准备 KS 事件。 驱动程序和 DSP 软件需要将 DSP 时间戳映射到 Windows 性能计数器值。 实现这一方法的方式取决于硬件设计。 一种可能的解决方案是让驱动程序读取当前性能计数器,查询当前的 DSP 时间戳,再次读取当前性能计数器,然后估计性能计数器与 DSP 时间之间的关联。 然后,鉴于相关性,驱动程序可以将关键字 DSP 时间戳映射到 Windows 性能计数器时间戳。
关键字检测器 OEM 适配器接口
OEM 提供一个 COM 对象实现,该实现充当 OS 和驱动程序之间的中介,帮助计算或分析通过 KSPROPERTY_SOUNDDETECTOR_PATTERNS 和 KSPROPERTY_SOUNDDETECTOR_MATCHRESULT写入和读取音频驱动程序的不透明数据。
COM 对象的 CLSID 是由 KSPROPERTY_SOUNDDETECTOR_SUPPORTEDPATTERNS返回的检测模式类型 GUID。 OS 调用 CoCreateInstance 传递模式类型 GUID 来实例化与关键字模式类型兼容的相应 COM 对象,并在对象的 IKeywordDetectorOemAdapter 接口上调用方法。
COM 线程模型要求
OEM 的实现可以选择任何 COM 线程模型。
IKeywordDetectorOemAdapter
接口设计尝试使对象实现保持无状态。 换句话说,实现不应要求在方法调用之间存储任何状态。 事实上,内部C++类可能不需要除实现 COM 对象所需的成员变量之外的任何成员变量。
Methods
实现以下方法。
- IKeywordDetectorOemAdapter::BuildArmingPatternData
- IKeywordDetectorOemAdapter::ComputeAndAddUserModelData
- IKeywordDetectorOemAdapter::GetCapabilities
- IKeywordDetectorOemAdapter::ParseDetectionResultData
- IKeywordDetectorOemAdapter:VerifyUserKeyword
KEYWORDID
KEYWORDID 枚举标识关键字的短语文本/函数,并在 Windows 生物识别服务适配器中使用。 有关详细信息,请参阅 生物识别框架概述 - 核心平台组件
typedef enum {
KwInvalid = 0,
KwHeyCortana = 1,
KwSelect = 2
} KEYWORDID;
KEYWORDSELECTOR
KEYWORDSELECTOR 结构是一组唯一选择特定关键字和语言的 ID。
typedef struct
{
KEYWORDID KeywordId;
LANGID LangId;
} KEYWORDSELECTOR;
处理模型数据
静态用户独立模型 - OEM DLL 通常包括一些内置于 DLL 中的静态用户独立模型数据,或包含在 DLL 中包含的单独数据文件中。 GetCapabilities 例程返回的受支持关键字 ID 集将取决于此数据。 例如,如果 GetCapabilities 返回的受支持关键字 ID 列表包括 KwHeyCortana,则静态用户独立模型数据将包括所有受支持语言的“Hey Cortana”(或其翻译)的数据。
动态用户依赖模型 - IStream 提供随机访问存储模型。 OS 将 IStream 接口指针传递给 IKeywordDetectorOemAdapter 接口上的许多方法。 OS 提供适当的存储支持 IStream 实现,可存储最多 1MB 的数据。
此存储中的数据的内容和结构由 OEM 定义。 目的是持久存储由 OEM DLL 计算或检索的用户依赖模型数据。
OS 可以使用空的 IStream 调用接口方法,尤其是在用户从未训练关键字的情况下。 OS 为每个用户创建单独的 IStream 存储。 换句话说,一个给定的 IStream 仅存储单个用户的模型数据。
OEM DLL 开发人员决定如何管理用户独立数据和用户依赖数据。 但是,它永远不会在 IStream 之外的任何位置存储用户数据。 一种可能的 OEM DLL 设计将在访问 IStream 和静态用户独立数据之间内部切换,具体取决于当前方法的参数。 备用设计可能会在每个方法调用开始时检查 IStream,并在 IStream 中添加静态、与用户无关的数据(如果尚不存在),从而允许该方法的其余部分仅需访问 IStream 来获取所有模型数据。
训练和操作音频处理
如前所述,训练的用户界面流程会导致音频流中生成完整的发音丰富句子。 每个句子分别传递给 IKeywordDetectorOemAdapter::VerifyUserKeyword ,以验证它是否包含预期的关键字并具有可接受的质量。 在 UI 收集并验证所有句子后,它们都会在对 IKeywordDetectorOemAdapter::ComputeAndAddUserModelData 的一次调用中传递。
音频以独特的方式处理语音激活训练。 下表总结了语音激活训练与常规语音识别用法之间的差异。
| 语音培训 | 语音识别 | |
|---|---|---|
| 模式 | 原始 | 未处理或语音 |
| 引脚 | Normal | KWS |
| 音频格式 | 32-bit 浮点数(类型 = 音频,子类型 = IEEE_FLOAT,采样率 = 16 kHz,位数 = 32) | 由 OS 音频堆栈管理 |
| 麦克风 | 麦克风 0 | 麦克风阵列中或单声道的所有麦克风 |
关键字识别系统概述
此图概述了关键字识别系统。
关键字识别序列图
在这些关系图中,语音运行时模块显示为语音平台。 如前所述,Windows 语音平台用于支持 Windows 10 中的所有语音体验,例如 Cortana 和听写。
在启动期间,使用 IKeywordDetectorOemAdapter::GetCapabilities 收集能力。
稍后当用户选择“了解我的声音”时,将调用训练流。
此图介绍关键字检测的设置过程。
WAVERT 改进
微型端口接口定义为由 WaveRT 微型端口驱动程序实现。 这些接口提供了简化音频驱动程序、提高 OS 音频管道性能和可靠性或支持新方案的方法。 定义了新的 PnP 设备接口属性,允许驱动程序向 OS 提供其缓冲区大小约束的静态表达式。
缓冲区大小
驱动程序在 OS、驱动程序和硬件之间移动音频数据时,在各种约束下运行。 这些约束可能是由于在内存和硬件之间移动数据的物理硬件传输,以及/或由于硬件或关联的 DSP 中的信号处理模块所致。
HW-KWS 解决方案必须支持至少 100 毫秒和高达 200 毫秒的音频捕获大小。
驱动程序通过在具有 KS 流式处理引脚的 KS 筛选器的 KSCATEGORY_AUDIO PnP 设备接口上设置DEVPKEY_KsAudio_PacketSize_Constraints设备属性来表达缓冲区大小约束。 启用 KS 筛选器接口时,此属性应保持有效且稳定。 OS 可以随时读取此值,而无需打开驱动程序的句柄并调用驱动程序。
DEVPKEY_KsAudio_PacketSize_Constraints
DEVPKEY_KsAudio_PacketSize_Constraints属性值包含一个KSAUDIO_PACKETSIZE_CONSTRAINTS结构,该结构描述了物理硬件约束(即由于将数据从WaveRT缓冲区传输到音频硬件的机制)。 该结构包括一个由 0 个或更多 个KSAUDIO_PACKETSIZE_PROCESSINGMODE_CONSTRAINT 结构构成的数组,描述特定于任何信号处理模式的约束。 驱动程序在调用 PcRegisterSubdevice 之前设置此属性,或者以其他方式启用其流式传输引脚的 KS 筛选器接口。
IMiniportWaveRTInputStream
驱动程序实现此接口,以便更好地协调从驱动程序到 OS 的音频数据流。 如果此接口在捕获流上可用,则 OS 使用此接口上的方法访问 WaveRT 缓冲区中的数据。 有关详细信息,请参阅 IMiniportWaveRTInputStream::GetReadPacket
IMiniportWaveRTOutputStream
WaveRT 微型端口可以选择实现此接口,以便获得来自操作系统的写入进度通知并返回精确的流位置。 有关详细信息,请参阅 IMiniportWaveRTOutputStream::SetWritePacket、 IMiniportWaveRTOutputStream::GetOutputStreamPresentationPosition 和 IMiniportWaveRTOutputStream::GetPacketCount。
性能计数器时间戳
多个驱动程序例程返回 Windows 性能计数器时间戳,反映设备捕获或显示样本的时间。
在具有复杂 DSP 管道和信号处理的设备中,计算准确的时间戳可能很有挑战性,应该深思熟虑地完成。 时间戳不应反映样本传输到 OS 或从 OS 传输到 DSP 的时间。
- 在 DSP 中,使用一些内部 DSP 时钟跟踪样本时间戳。
- 在驱动程序与 DSP 之间,计算 Windows 性能计数器与 DSP 时钟之间的关联。 此过程的过程可以是简单(但不太精确)到相当复杂或新颖(但更精确)。
- 考虑由于信号处理算法、管道或硬件传输而导致的任何固定延迟,除非这些延迟已在其他方面进行考虑。
突发读取操作
本部分介绍操作系统与驱动程序在突发读取中的交互。 只要驱动程序支持基于数据包的流式处理 WaveRT 模型(包括 IMiniportWaveRTInputStream::GetReadPacket 函数),突发读取就可以在语音激活方案之外发生。
我们将讨论两种突发访问读取场景示例。 在某种情境中,如果微型端口支持具有引脚类别为KSNODETYPE_AUDIO_KEYWORDDETECTOR的引脚,则当检测到关键字时,驱动程序将开始捕获并在内部缓冲数据。 在另一种方案中,如果 OS 无法通过调用 IMiniportWaveRTInputStream::GetReadPacket 来快速读取数据,驱动程序可以在 WaveRT 缓冲区外部内部缓冲数据。
要处理在转换到KSSTATE_RUN之前捕获的突发数据,驱动程序必须保留准确的样本时间戳信息以及缓冲的捕获数据。 时间戳标识捕获的样本的采样即时。
流转换为KSSTATE_RUN后,驱动程序会立即设置缓冲区通知事件,因为它已有数据可用。
在此事件中,OS 调用 GetReadPacket(),以获取有关可用数据的信息。
驱动程序返回有效捕获数据的数据包数(从KSSTATE_STOP转换到KSSTATE_RUN后的第一个数据包的 0),OS 可以从中派生 WaveRT 缓冲区中的数据包位置以及相对于流开始的数据包位置。
驱动程序还会返回与数据包中第一个样本的采样即时相对应的性能计数器值。 此性能计数器值可能相对较旧,具体取决于硬件或驱动程序(在 WaveRT 缓冲区外部)中缓冲了多少捕获数据。
如果有更多未读缓冲的数据可用,驱动程序要么:
- 立即将该数据传输到 WaveRT 缓冲区的可用空间(即 GetReadPacket 返回的数据包未使用的空间),对于 MoreData 返回 true,并在从此例程返回之前设置缓冲区通知事件。 或者,
- 将硬件进行编程以快速将下一个数据包发送到 WaveRT 缓冲区的可用空间,并对 "MoreData" 返回 false;传输完成后设置缓冲区事件。
OS 使用 GetReadPacket(返回的信息)从 WaveRT 缓冲区读取数据。
OS 等待下一个缓冲区通知事件。 如果驱动程序在步骤 (2c) 中设置缓冲区通知,则等待可能会立即终止。
如果驱动程序未在步骤 (2c) 中立即设置事件,驱动程序在将更多捕获的数据传输到 WaveRT 缓冲区并使其可供 OS 读取后设置事件
转到 (2)。 对于 KSNODETYPE_AUDIO_KEYWORDDETECTOR 关键字检测器引脚,驱动程序应为至少 5000 毫秒的音频数据分配足够的内部突发缓冲。 如果 OS 在缓冲区溢出之前无法在引脚上创建流,驱动程序可以结束内部缓冲活动并释放关联的资源。
语音唤醒
唤醒语音(WoV)使用户能够通过说出特定的关键字(如“你好 Cortana”),从屏幕关闭、低功耗状态激活语音识别引擎,进而切换到屏幕打开、全功率状态进行查询。
此功能允许设备在设备处于低功率状态时始终侦听用户的语音,包括屏幕关闭且设备处于空闲状态。 它通过使用侦听模式来实现,与麦克风常规录制过程中较高的功耗相比,该模式的功耗更低。 低功耗语音识别允许用户先说一个预定义的关键词短语,比如“你好,Cortana”,然后说出连续的语音指令,例如“我的下一个约会是什么时候”,以免提方式激活语音功能。 无论设备是处于使用中还是空闲状态,功能都能正常工作,即使屏幕关闭。
音频堆栈负责传达唤醒数据(说话人 ID、关键字触发器、置信度),并通知感兴趣的客户端检测到该关键字。
新式待机系统上的验证
可以在新式待机系统上使用现代待机语音唤醒基本测试(交流电源)和现代待机语音唤醒基本测试(直流电源)在HLK中对系统空闲状态的 WoV 进行验证。 这些测试检查系统是否具有硬件关键字检测(HW-KWS),能够进入最深层运行时空闲平台状态(DRIPS),并且能够通过语音命令从现代待机状态唤醒,系统恢复延迟不超过一秒。