오디오 앱에서 VolumeShaper
를 사용하여 페이드 인, 페이드 아웃, 크로스 페이드, 볼륨 낮추기 및 기타 짧은 자동 볼륨 전환을 실행할 수 있습니다. VolumeShaper
클래스는 Android 8.0 (API 수준 26) 이상에서 사용할 수 있습니다.
AudioTrack
또는 MediaPlayer
인스턴스에서 createVolumeShaper()
를 호출하여 VolumeShaper
를 만듭니다. 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
보간기 유형에는 4개의 상수가 있습니다.
- 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})
재생과 셰이퍼를 동시에 시작합니다. 이렇게 하면 재생이 무음에서 시작되며 볼륨이 최대 볼륨으로 올라갑니다. 이에 대해서는 다음 섹션에서 설명합니다.
VolumeShaper 실행
첫 번째 컨트롤 포인트의 볼륨 수준은 셰이퍼가 생성되는 즉시 오디오 경로에 적용되지만 셰이퍼는 VolumeShaper.Operation.PLAY
로 apply()
메서드를 호출할 때까지 곡선을 따라 진행되지 않습니다. 셰이퍼를 만든 후 셰이퍼를 시작하려면 첫 번째 apply()
호출에서 PLAY
작업을 지정해야 합니다. 이렇게 하면 첫 번째 제어점에서 마지막 제어점까지 곡선이 실행됩니다.
Kotlin
shaper.apply(VolumeShaper.Operation.PLAY)
Java
shaper.apply(VolumeShaper.Operation.PLAY);
셰이퍼가 실행되는 동안 REVERSE 연산과 PLAY 연산을 지정하는 apply()
호출을 번갈아 실행할 수 있습니다. 이렇게 하면 매번 기준점의 판독 방향이 변경됩니다.
셰이퍼는 계속 볼륨을 조정하고 만료될 때까지 모든 컨트롤 포인트를 통과합니다. 이는 셰이퍼가 곡선의 마지막 제어점 (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.ShaperOperation
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_joinr.Shaper; joinper.Shaper.sha
셰이퍼가 실행되는 동안 replace()
를 호출하면 셰이퍼가 볼륨 변경을 중지하고 현재 값으로 유지됩니다. 그런 다음 셰이퍼는 첫 번째 제어점에서 새 곡선을 시작하려고 합니다. 즉, 연산 인수는 호출 후 셰이퍼의 실행 여부를 제어합니다. PLAY
를 지정하면 새 곡선을 즉시 시작하고 REVERSE
를 지정하면 셰이퍼가 새 곡선의 첫 번째 제어점 볼륨에서 일시중지된 상태로 유지됩니다. 나중에 apply(VolumeShaper.Operation.PLAY)
를 사용하여 셰이퍼를 시작할 수 있습니다.
join = false
로 replace()
를 호출하면 셰이퍼는 첫 번째 제어점으로 지정된 수준에서 곡선을 시작합니다. 이는 볼륨의 불연속성을 야기할 수 있습니다. 이를 방지하려면 replace()
로 설정한 상태에서 join = true
를 호출하면 됩니다.
이렇게 하면 새 곡선의 첫 번째 제어점이 셰이퍼의 현재 수준으로 설정되고 첫 번째 제어점과 마지막 제어점 사이의 모든 제어점의 볼륨이 조정되어 새 곡선의 상대적 형태가 유지됩니다 (마지막 제어점은 변경되지 않음). 확장 작업은 셰이퍼의 새 곡선에서 제어점을 영구적으로 변경합니다.
VolumeShaper 제거
AudioTrack
또는 MediaPlayer
가 해제되거나 더 이상 사용되지 않으면 시스템이 종료되고 가비지가 VolumeShaper
를 수집합니다. 셰이퍼에서 close()
메서드를 호출하여 셰이퍼를 즉시 제거할 수 있습니다. 시스템은 약 20밀리초 이내에 오디오 파이프라인에서 셰이퍼를 삭제합니다. 오디오 재생 중에 VolumeShaper
를 닫을 때는 주의해야 합니다. close()
를 호출할 때 셰이퍼의 볼륨이 1.0 미만인 경우 셰이퍼의 볼륨 배율은 1.0으로 변경됩니다. 이로 인해 볼륨이 갑자기 증가할 수 있습니다.