音频会话

音频会话 是 WASAPI 客户端可以共同管理的相关音频流组。 客户端可以控制每个会话的音量级别和静音状态。 系统将客户端指定的卷和静音设置统一应用于会话中的所有流。

当客户端初始化音频流时,它将音频流分配给音频会话。 有关详细信息,请参阅 IAudioClient::Initialize

音频会话包含呈现流或捕获流,但不包含两者。 默认情况下,呈现会话的卷和静音设置在系统重启时是永久性的。 捕获会话的卷和静音设置不持久。 (包含在环回模式下运行的流的会话被视为与捕获会话相同。也就是说,会话设置不是永久性的。有关环回模式的详细信息,请参阅 环回录制。)

每个音频流都属于一个会话。 客户端在初始化流对象时将音频流分配给特定会话。 该流在流的生存期内将其成员身份保留在会话中。 创建流对象后,该对象将存在,直到客户端释放对对象的上次计数引用,然后删除该对象。

尽管客户端无法更改现有流的分配会话,但它可以通过删除流(通过释放对其的所有引用)、创建新流来替换已删除的流并将新流分配给另一个会话来实现类似的效果。

每个呈现会话表示构成通过特定 音频终结点设备播放的全局混合的流的子集。 全局组合将共享设备的所有应用程序中的所有会话组合在一起。

通常,具有多个流的应用程序会将其所有流分配给同一会话。 但是,应用程序可以选择将不同的流分配给不同的会话。 应用程序未显式分配给会话的任何流都属于默认会话。

典型的音频应用程序应避免修改会话的音量和静音设置。 相反,用户通过控件程序的用户界面控制这些设置。 例如,在 Windows Vista 中,系统提供的程序 Sndvol.exe显示卷控件,并为系统中每个活动或最近处于活动状态的呈现会话显示音量控件和静音控件。 通过这些控件,用户可以调整系统中所有会话的音量和静音设置。

Sndvol 程序当前仅显示音频呈现终结点设备的音量控制。 它不显示音频捕获设备的音量控件。

如果会话包含一个或多个活动流,则会话处于活动状态。 活动流处于运行状态 。 非活动流处于 停止状态。 会话在第一个流处于活动状态时变为活动状态。 会话在最后一个活动流变为非活动流时变为非活动状态。 会话在一段时间内处于非活动状态后,系统将会话的状态从非活动更改为过期。

Sndvol 显示所有活动和非活动呈现会话的卷和静音控件。 当会话状态从非活动更改为过期或会话终止时,Sndvol 将删除会话的卷和静音控制。 (会话在删除其最后一个流时终止;也就是说,当客户端释放会话中最后剩余的流对象的最终引用计数时)。此规则的一个例外是系统通知声音。 无论这些声音的会话状态如何,Sndvol 始终显示系统通知声音的音量和静音控件。

通常,流属于仅包含创建流的应用程序的进程的会话。 但是,应用程序可以选择定义将流从两个或多个进程合并的跨进程会话。

WASAPI 主要支持跨进程会话,以便:

  • Sndvol 程序可以向用户提供单个音量控制,以在所有应用程序中管理系统通知声音。
  • 在一个进程中运行的媒体播放器可以将受保护的内容流式传输到在另一进程中运行的解密程序。

与进程特定的呈现会话的控件设置类似,默认情况下,跨进程呈现会话的控件设置在系统重启时永久存在。 WASAPI 主要针对系统通知声音的好处提供此行为,因为随着应用程序组合的变化,系统通知声音必须保留用户的音量和静音设置。

Sndvol 程序使用显示名称和图标标记每个会话的音量控件。 客户端可以选择向会话显式分配显示名称和图标。 如果客户端未提供这些项目,则 Sndvol 会改为显示默认名称和默认图标。 默认名称包含应用程序窗口的标题等信息。 默认图标是应用程序窗口的图标。 只有在进程特定的会话的情况下,这些默认值才会向用户提供有意义的信息。 请注意,跨进程会话可以与多个应用程序相关联。 在这种情况下,只有客户端提供的显示名称和图标有意义。

尽管呈现会话的卷和静音设置默认在系统重启时持续,但客户端提供的显示名称和图标不是。 为了确保 Sndvol 显示客户端提供的名称和图标,客户端必须在客户端向会话分配第一个流时显式分配名称和图标。 系统仅在会话终止前保留会话的显示名称和图标。

每个会话由会话 GUID 标识。 在客户端打开流时,客户端将该流分配给特定会话。 客户端提供以下两条信息来标识该会话:

  • 会话 GUID。
  • 会话是跨进程会话还是进程特定的会话,特定于进程的会话仅包含来自客户端进程的流。

此信息足以区分同一台计算机中所有其他会话的特定会话。 特定于进程的会话的会话 GUID 仅在拥有会话的进程范围内唯一标识会话。 相比之下,跨进程会话的会话 GUID 在计算机上运行的所有进程范围内是唯一的。

对于特定于进程的会话,系统使用会话 GUID 和进程 ID 的组合来唯一标识计算机范围内的会话。 因此,如果两个不同进程中的客户端将各自的流分配给具有相同会话 GUID 的两个进程特定的会话,则系统会将会话视为单独的会话,因为它们的进程 ID 不同。 此外,如果跨进程会话使用与一个或多个进程特定的会话相同的会话 GUID,则系统会将跨进程会话视为不同于特定于进程的会话,即使它们共享相同的会话 GUID。

例如,在 Windows Vista 中,更高级别的 API(例如 Windows 多媒体 waveOutXxx 函数和 DirectSound)通常会将创建的音频流分配给会话 GUID 值GUID_NULL标识的默认进程特定的会话。 对于这些 API 的客户端,每个客户端进程的默认会话与其他客户端进程的默认会话分开,即使会话具有相同的会话 GUID。 此外,如果一个或多个应用程序将流分配给会话 GUID 值GUID_NULL标识的跨进程会话,则系统会将此跨进程会话视为独立于共享同一会话 GUID 的默认进程特定会话。 因此,Sndvol 程序为每个客户端的默认进程特定的会话显示单独的卷控件,如果会话存在,则会为会话 GUID 值GUID_NULL标识的跨进程会话显示额外的卷控件。

每个会话仅与一个音频终结点设备相关联。 如果两个会话具有相同的会话 GUID 和进程 ID,但与不同的设备相关联,则系统将这两个会话视为单独的会话。 会话永远不能同时包含捕获和呈现流,因为捕获流只能与捕获设备关联,而呈现流只能与呈现设备相关联。

如前所述,会话的卷和静音设置在系统重启时是永久性的。 应用程序的两个或多个实例可以使用相同的会话 GUID 创建特定于进程的会话。 通过 Sndvol 程序,用户可以为每个会话选择不同的音量和静音设置。 这些会话终止后,系统只保留其中一个会话的控制设置,即要终止的最后一个会话。 稍后,如果应用程序的新实例创建与以前相同的会话 GUID 的进程特定会话,该会话将继承以前保存的卷和静音设置。

应用程序不应尝试向某个会话添加流或控制由另一个不相关的应用程序拥有的会话的卷级别。 此外,应用程序不应尝试控制系统管理的会话的音量级别以获取通知声音。 但是,应用程序可以通过系统会话播放声音,以便通过调用 PlaySound 函数来播放通知声音。 有关详细信息,请参阅 旧版音频应用程序的通知声音

当会话状态发生更改时,应用程序可以注册以接收通知。 有关详细信息,请参阅 音频会话事件

在极少数情况下,创建特定于进程的会话的应用程序可能需要在 Sndvol 中的单个卷控件下合并对两个或多个应用程序实例的进程特定会话的控制。 有关详细信息,请参阅 分组参数

编程指南