Вы можете использовать VolumeShaper в аудиоприложении, чтобы выполнять постепенное увеличение и уменьшение громкости, перекрестное затухание, приглушение и другие короткие автоматические переходы громкости. Класс VolumeShaper доступен в Android 8.0 (уровень API 26) и более поздних версиях.
Чтобы создать VolumeShaper, вызовите createVolumeShaper() в экземпляре 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_RAMPVolumeShaper.Configuration.CUBIC_RAMPVolumeShaper.Configuration.SINE_RAMPVolumeShaper.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, чтобы запустить шейпер. Это запускает кривую от первой до последней контрольной точки:
Kotlin
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, чтобы запустить его снова.
Изменение кривой
Чтобы изменить кривую VolumeShaper, используйте метод replace(). Этот метод принимает конфигурацию, операцию и параметр объединения. Вы можете вызвать метод 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, 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 во время воспроизведения аудио. Если при вызове close() громкость шейпера меньше 1,0, она увеличивается до 1,0. Это может привести к внезапному увеличению громкости.