会话卷控件

如前所述,WASAPI 客户端可以单独控制每个 音频会话的音量级别。 WASAPI 将会话的卷设置统一应用于会话中的所有流。 每个音量级别都是 0.0 到 1.0 范围内的值,其中 0.0 表示静音,1.0 表示完整音量(无衰减)。

客户端通过将第一个流分配给该会话来隐式创建会话。 新会话的默认卷级别为 1.0。 如前所述,用户可以通过作为 WASAPI 客户端的控制程序的用户界面(例如 Sndvol)调整会话的音量级别。 控件设置是永久性的。

除了客户端控制的卷设置外,系统还会将自己的卷设置应用于会话。 这些设置基于音频策略,并动态更改以响应构成全局音频混合的流中的更改。 有关音频策略的详细信息,请参阅 User-Mode 音频组件

实现每个流的音量控制的系统软件将流中的 PCM 样本乘以有效卷级别。 有效卷级别是将客户端和系统卷设置相乘的结果。 因此,信号振幅的结果变化是客户端和系统音量级别的线性组合。 例如,如果客户端卷级别为 0.8,并且系统卷级别为 0.5,则有效卷级别为 (0.8)(0.5) = 0.4。

请注意,在信号振幅方面,感知到的音量不是线性的。 相反,音量级别 v 的对数大致变化:

分贝的响度 = 20log₁₀(v)

因此,设置 v = 0.5 会衰减原始信号(应用音量前的信号)的响度(音量级别前的信号),设置 v = 0.25 将信号衰减 12 分贝等。 卷级别 v = 1.0,对应于 0 分贝,不会改变原始信号级别。

具有用户界面的音频应用程序,用于控制音量级别通常显示滑块,这些滑块会生成感知到的响度的变化,这些变化与滑块位置的变化成线性比例。 若要在感知的音量和滑块位置之间生成线性关系,应用程序必须在音量级别 v 和滑块位置之间定义非线性关系。 有关详细信息,请参阅 Audio-Tapered 卷控件

如前所述,系统音量控制程序 Sndvol 显示在每个音频呈现设备上播放的音频会话的音量滑块。 这些滑块显示在 SndVol 窗口中标记为 应用程序 的组框中。 通常,每个会话都包含特定应用程序窗口中的所有播放流。 通过 Sndvol 窗口中的滑块,用户控制单个音频应用程序的音量级别。

一般情况下,应用程序应将其所有播放流分配给同一音频会话。 WASAPI 不会阻止应用程序在多个会话之间分发其播放流。 但是,Sndvol 中卷滑块产生的激增可能会使用户感到困惑。

作为选项,应用程序窗口可以显示音量滑块。 应用程序滑块应随时反映相应 Sndvol 滑块的状态。 因此,如果用户通过在应用程序窗口中移动滑块来更改音量级别,则 Sndvol 窗口中的相应滑块应与应用程序滑块一起移动。 同样,如果用户移动 Sndvol 滑块,则应用程序滑块应与 Sndvol 滑块一起移动。

为了支持此行为,WASAPI 实现 ISimpleAudioVolume 接口。 当用户移动应用程序滑块时,应用程序调用 ISimpleAudioVolume::SetMasterVolume 方法来相应地调整会话音量级别。 Sndvol 监视通过此方法进行的卷更改,并反映其显示的卷滑块中的更改。 此外,应用程序还可以接收用户通过 Sndvol 进行的会话卷更改通知。 为此,应用程序实现 IAudioSessionEvents 接口,并将该接口注册到 WASAPI。 此后,每当用户通过 Sndvol 更改会话卷级别时,应用程序都会通过 IAudioSessionEvents::OnSimpleVolumeChanged 方法接收通知调用。 有关实现 IAudioSessionEvents 接口的代码示例,请参阅 音频会话事件。 有关注册 IAudioSessionEvents 接口的代码示例,请参阅 旧版音频应用程序的音频事件

ISimpleAudioVolume 接口将相同的音量级别统一应用于音频会话中的所有通道。 尽管此接口应满足大多数应用程序的卷控制要求,但一些应用程序可能需要更专用的卷控制功能。 IAudioStreamVolume 接口控制会话中单个流的卷相对于会话中的其他流。 IAudioStreamVolume 还允许客户端单独控制流中所有通道的卷级别。 例如,应用程序可以使用此功能通过从左到右平移来模拟音频源的空间移动等音频效果。 另一个专用接口(IChannelAudioVolume)控制会话中各个通道的音量级别。 例如,应用程序可能使用 IChannelAudioVolume 为立体声音响系统实现平衡控制。

Sndvol 应用程序 框中的卷滑块仅反映通过 ISimpleAudioVolume 接口进行的卷更改。 它们不反映通过 IAudioStreamVolumeIChannelAudioVolume 接口进行的卷更改。 尽管某些应用程序可能使用户能够通过 IAudioStreamVolumeIChannelAudioVolume直接或间接控制卷设置,但开发人员应避免为这些卷设置显示应用程序滑块,用户可能会与 Sndvol 中的卷滑块混淆。 否则,用户可能会移动应用程序滑块,希望看到 Sndvol 滑块中反映的更改,并在未发生此类更改时感到困惑。 开发人员可以通过仔细的用户界面设计来避免此问题。

会话子混合中任何通道的有效音量级别(如演讲者听到)是以下四个音量级别因素的产物:

  • 会话中流的每个通道卷级别,客户端可以通过 IAudioStreamVolume 接口中的方法来控制这些级别。
  • 会话的每个通道卷级别,客户端可以通过 IChannelAudioVolume 接口中的方法来控制这些级别。
  • 会话的主卷级别,客户端可以通过 ISimpleAudioVolume 接口中的方法控制该会话的主卷级别。
  • 会话的基于策略的卷级别,系统在全局混合更改时动态修改该级别。

上述列表中的四个音量级别因素中的每一个都是介于 0.0 到 1.0 之间的值,其中 0.0 表示静音,1.0 表示完整音量(无衰减)。 有效卷级别也是 0.0 到 1.0 范围内的值。

音频引擎将每个通道的有效音量级别应用于流中的通道,然后再将流与其他流混合在音频会话中。 如果音频引擎将音频引擎乘以有效音量级别后通道中的任何样本值超过 0 分贝,则引擎会先剪辑样本,然后再将它们添加到会话子混合。

卷控件