您可以在音频应用中使用 VolumeShaper
来执行
淡入、淡出、淡入淡出、降低音量以及其他简短的自动音量
过渡效果。Android 8.0(API 级别 26)中提供了 VolumeShaper
类。
和后续版本。
您可以通过对以下对象的实例调用 createVolumeShaper()
来创建 VolumeShaper
:
AudioTrack
或 MediaPlayer
。通过
VolumeShaper
仅对 AudioTrack 或 MediaPlayer 生成的音频起作用
创建它的过程。
VolumeShaper.Configuration
VolumeShaper
的行为由其
VolumeShaper.Configuration
。该配置指定
*音量曲线、插值器类型和时长。
音量曲线
音量曲线表示振幅随时间的变化。它由一对
由浮点型数组 x[] 和 y[] 组成,这些数组定义了一系列控制点。每个 (x, y)
对分别表示时间和音量。数组的长度必须相等
且包含 2 到 16 个值。(曲线长度上限为
在 getMaximumCurvePoints()
中定义。)
时间坐标在 [0.0, 1.0] 的区间内指定。第一次 点必须为 0.0,最后一个点必须为 1.0,并且时间必须是单调的 不断增加。
音量坐标以线性刻度的形式指定时间间隔内 [0.0, 1.0]。
插值器类型
音量曲线始终会通过指定的控制点。值
它们会根据
配置的插值器类型。可用的
VolumeShaper
插值器类型:
- VolumeShaper.Configuration.INTERPOLATOR_TYPE_STEP
- VolumeShaper.Configuration.INTERPOLATOR_TYPE_LINEAR
- VolumeShaper.Configuration.INTERPOLATOR_TYPE_CUBIC
- VolumeShaper.Configuration.INTERPOLATOR_TYPE_CUBIC_MONOTONIC
时长
范围 [0.0, 1.0] 内的指定时间坐标将调整为 指定持续时间(以毫秒为单位)。这决定了 音量曲线在变形过程中运行并将曲线应用到 音频输出。
使用 VolumeShaper
创建配置
在构建 VolumeShaper
之前,您必须创建 VolumeShaper.Configuration
的实例。为此,请使用
VolumeShaper.Configuration.Builder()
:
Kotlin
val config: VolumeShaper.Configuration = VolumeShaper.Configuration.Builder() .setDuration(3000) .setCurve(floatArrayOf(0f, 1f), floatArrayOf(0f, 1f)) .setInterpolatorType(VolumeShaper.Configuration.INTERPOLATOR_TYPE_LINEAR) .build()
Java
VolumeShaper.Configuration config = new VolumeShaper.Configuration.Builder() .setDuration(3000) .setCurve(new float[] {0.f, 1.f}, new float[] {0.f, 1.f}) .setInterpolatorType(VolumeShaper.Configuration.INTERPOLATOR_TYPE_LINEAR) .build();
With no arguments the VolumeShaper.Configuration.Builder
constructor returns a
builder that creates a configuration with default settings:
INTERPOLATOR_TYPE_CUBIC, a one second duration, and no curve. You must add a
curve to the builder before calling build()
.
The framework provides constants for configurations with pre-built curves, each with one second duration:
VolumeShaper.Configuration.LINEAR_RAMP
VolumeShaper.Configuration.CUBIC_RAMP
VolumeShaper.Configuration.SINE_RAMP
VolumeShaper.Configuration.SCURVE_RAMP
Creating a VolumeShaper
To create a VolumeShaper
, call createVolumeShaper()
on an instance of the
appropriate class, passing in a VolumeShaper.Configuration
:
Kotlin
volumeShaper = myMediaPlayer.createVolumeShaper(config) volumeShaper = myAudioTrack.createVolumeShaper(config)
Java
volumeShaper = myMediaPlayer.createVolumeShaper(config); volumeShaper = myAudioTrack.createVolumeShaper(config);
A single track or media player can have many shapers attached to it, and you can
control each shaper separately. The outputs of all the shapers on a track or
player are multiplied together. A VolumeShaper
cannot be shared between
AudioTracks
or MediaPlayers
, but you can use the same configuration in calls
to createVolumeShaper
to build identical shapers on multiple AudioTracks
or
MediaPlayers
.
When you create the shaper, its first control point (at t = 0) is applied to the
audio stream. If the initial volume is not 1.0 and your app is playing material
at create time, your audio might have an abrupt change in volume. Best practice
is to start playing audio from silence and use a VolumeShaper
to implement a
fade-in when playback starts. Create a VolumeShaper
that starts at 0 volume
and fades up. For example:
setCurve(new float[] {0.f, 1.f}, new float[] {0.f, 1.f})
同时启动播放和 shaper。这样可以确保 从静音开始,然后音量逐渐上升至最大音量。具体说明请参阅 下一部分。
运行 VolumeShaper
尽管第一个控制点的音量会应用于音频路径
创建 Shaper 后,Shaper 不会沿着曲线前进
直到您使用 VolumeShaper.Operation.PLAY
调用 apply()
方法为止。更新后
创建 Shaper,第一次调用apply()
时必须指定PLAY
操作来启动 Shaper。这样该曲线会从第一个到
最后一个控制点:
Kotlin
Shaper.apply(VolumeShaper.Operation.PLAY)
Java
Shaper.apply(VolumeShaper.Operation.PLAY);
当 Shaper 运行时,您可以发出交替的apply()
调用,指定
REVERSE 和 PLAY 操作。这会改变
控制点。
Shaper 会不断调节音量并通过所有控制点 直至过期。当 Shaper 到达最后一个(对于 PLAY)时,就会发生这种情况 操作)或曲线中的第一个(对于 REVERSE 操作)控制点。
Shaper 过期后,音量会保持为最后的设置,可能是
第一个或最后一个控制点您可以拨打 VolumeShaper.getVolume()
随时保持当前音量
在 Shaper 过期后,您可以发出另一个apply()
调用来运行曲线
就会反过来例如,如果 Shaper 在运行过程中过期
PLAY
,下一个 apply()
必须是 REVERSE
。在 PLAY
之后呼叫 PLAY
已过期,或者在 REVERSE
过期后 REVERSE
没有任何作用。
您必须交替执行 PLAY
操作和 REVERSE
操作。
从第一个控制点到最后一个控制点 然后重新打开它
第一个控制点您可以使用 replace()
方法,如下文所述
部分,将曲线替换为其自身的副本。这将重置 shaper,
需要 PLAY
操作重新启动它。
更改曲线
使用 replace()
方法可以更改 VolumeShaper
的曲线。此方法采用
一个配置、一个操作和一个联接参数。您可以调用
replace()
方法随时调用:
Kotlin
val newConfig = VolumeShaper.Configuration.Builder() .setDuration(1000) .setCurve(floatArrayOf(0f, 0.5f), floatArrayOf(0f, 1f)) .setInterpolatorType(VolumeShaper.Configuration.INTERPOLATOR_TYPE_LINEAR) .build() val join = true shaper.Replace(newConfig, VolumeShaper.Operation.PLAY, 联接)
Java
VolumeShaper.Configuration newConfig = 新的 VolumeShaper.Configuration.Builder() .setDuration(1000) .setCurve(new float[] {0.f, 0.5f}, new float[] {0.f, 1.f}) .setInterpolatorType(VolumeShaper.Configuration.INTERPOLATOR_TYPE_LINEAR) .build(); 布尔值 join = true; Shaper.Replace(newConfig, VolumeShaper.Operation.PLAY, join);
当您在形状运行期间调用 replace()
时,它会停止更改
并且保持当前值不变然后,Shaper 尝试
从第一个控制点开始绘制。这意味着,操作参数
控制 Shaper 在调用之后是否运行。将 PLAY
指定为
立即启动新曲线,指定 REVERSE
以让 Shaper 暂停在
新曲线中第一个控制点的音量。您可以启动 Shaper
稍后与 apply(VolumeShaper.Operation.PLAY)
共享。
当您使用 join = false
调用 replace()
时,Shaper 会在
第一个控制点所指定的级别这样会导致不连续
您可以通过使用 join = true
调用 replace()
来避免此问题。
此操作会将新曲线的第一个控制点设为
并调整第一个和第一个控制点之间的所有控制点的音量,
最后,保持新曲线的相对形状(最后一个控制点为
未做更改)。扩缩操作会永久性地改变
和 Shaper 的新曲线
移除 VolumeShaper
系统会在 VolumeShaper
的 AudioTrack
或
MediaPlayer
已发布或不再使用。您可以调用 close()
方法
就能立即销毁它系统会从
在大约 20 毫秒内运行完成。关闭 VolumeShaper
时要小心
。在您调用 Shaper 时,音量小于 1.0
close()
时,Shaper 的音量缩放会更改为 1.0。这可能会导致