会话音量控件

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

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

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

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

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

响度(以分贝为单位)= 20.log₁₀(v)

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

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

如前所述,系统音量控制程序 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 分贝,则引擎会先剪辑样本,然后再将它们添加到会话子混合。

音量控件