Вы можете использовать VolumeShaper
в аудиоприложении для выполнения постепенного появления, затухания, перекрестного затухания, приглушения и других коротких автоматических переходов громкости. Класс VolumeShaper
доступен в Android 8.0 (уровень API 26) и более поздних версиях.
Вы создаете VolumeShaper
, вызывая createVolumeShaper()
в экземпляре AudioTrack
или MediaPlayer
. VolumeShaper
воздействует только на звук, созданный AudioTrack или MediaPlayer, который его создал.
VolumeShaper.Конфигурация
Поведение 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()
:
Котлин
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})
Запустите воспроизведение и формирователь одновременно. Это гарантирует, что воспроизведение начнется с тишины, а громкость увеличится до полной. Это объясняется в следующем разделе.
Запуск VolumeShaper
Хотя уровень громкости первой контрольной точки применяется к аудиотракту сразу после создания формирователя, формирователь не продвигается по кривой, пока вы не вызовете метод apply()
с VolumeShaper.Operation.PLAY
. После создания формирователя первый вызов apply()
должен указать операцию PLAY
, чтобы запустить формирователь. Это проведет кривую от первой до последней контрольной точки:
Котлин
shaper.apply(VolumeShaper.Operation.PLAY)
Java
shaper.apply(VolumeShaper.Operation.PLAY);
Во время работы формирователя вы можете поочередно выполнять вызовы apply()
, определяющие операции REVERSE и PLAY. При этом каждый раз меняется направление считывания контрольных точек.
Шейпер непрерывно регулирует громкость и проходит через все контрольные точки, пока не истечет . Это происходит, когда формирователь достигает последней (для операции PLAY) или первой (для операции REVERSE) контрольной точки кривой.
По истечении срока действия шейпера громкость остается на последней настройке, которая может быть первой или последней контрольной точкой. Вы можете вызвать VolumeShaper.getVolume()
для текущего уровня громкости в любое время.
После истечения срока действия формирователя вы можете выполнить еще один вызов apply()
, чтобы запустить кривую в противоположном направлении. Например, если срок действия формирователя истек во время выполнения PLAY
, следующий apply()
должен быть REVERSE
. Вызов PLAY
после истечения срока действия PLAY
или REVERSE
после истечения срока действия REVERSE
не имеет никакого эффекта.
Вы должны чередовать операции PLAY
и REVERSE
. Невозможно воспроизвести кривую от первой до последней контрольной точки, а затем перезапустить ее снова с первой контрольной точки. Вы можете использовать метод replace()
, описанный в следующем разделе, чтобы заменить кривую ее копией. Это сбрасывает формирователь, требуя, чтобы операция PLAY
запустила его снова.
Изменение кривой
Используйте метод replace()
, чтобы изменить кривую VolumeShaper
. Этот метод принимает конфигурацию, операцию и параметр соединения. Вы можете вызвать метод replace()
в любое время во время работы формирователя или после его истечения:
Котлин
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, join)
Java
VolumeShaper.Configuration newConfig = new 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(); boolean join = true; shaper.replace(newConfig, VolumeShaper.Operation.PLAY, join);
Когда вы вызываете replace()
во время работы формирователя, он перестает изменять громкость и остается с текущим значением. Затем формирователь пытается начать новую кривую с первой контрольной точки. Это означает, что аргумент операции определяет, запускается ли формирователь после вызова. Укажите PLAY
, чтобы немедленно начать новую кривую, укажите REVERSE
, чтобы оставить формирователь на паузе на громкости первой контрольной точки новой кривой. Вы можете запустить формирователь позже с помощью apply(VolumeShaper.Operation.PLAY)
.
Когда вы вызываете replace()
с join = false
, формирователь начинает свою кривую на уровне, указанном его первой контрольной точкой. Это может привести к нарушению непрерывности объема. Вы можете избежать этого, вызвав replace()
с join = true
. Это устанавливает первую контрольную точку новой кривой на текущий уровень формирователя и масштабирует громкость всех контрольных точек между первой и последней, чтобы сохранить относительную форму новой кривой (последняя контрольная точка остается неизменной). Операция масштабирования навсегда изменяет контрольные точки на новой кривой формирователя.
Удаление VolumeShaper
Система закрывается, и VolumeShaper
собирает мусор, когда его AudioTrack
или MediaPlayer
освобождается или больше не используется. Вы можете вызвать метод close()
для формирователя, чтобы немедленно его уничтожить. Система удаляет формирователь из аудиоконвейера примерно за 20 мс. Будьте осторожны при закрытии VolumeShaper
во время воспроизведения звука. Если объем формирователя меньше 1,0 при вызове close()
, масштаб объема формирователя изменится на 1,0. Это может вызвать внезапное увеличение громкости.