오디오 앱에서 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()
자바
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();
인수가 없으면 VolumeShaper.Configuration.Builder
생성자는 INTERPOLATOR_TYPE_CUBIC, 지속 시간 1초, 곡선 없음을 기본 설정으로 한 구성을 만드는 빌더를 반환합니다. build()
를 호출하기 전에 빌더에 곡선을 추가해야 합니다.
프레임워크는 사전 제작된 곡선(지속 시간이 각각 1초)이 있는 구성에 사용할 수 있는 상수를 제공합니다.
VolumeShaper.Configuration.LINEAR_RAMP
VolumeShaper.Configuration.CUBIC_RAMP
VolumeShaper.Configuration.SINE_RAMP
VolumeShaper.Configuration.SCURVE_RAMP
VolumeShaper 만들기
VolumeShaper
를 만들려면 관련 클래스의 인스턴스에 createVolumeShaper()
를 호출하고 VolumeShaper.Configuration
을 전달합니다.
Kotlin
volumeShaper = myMediaPlayer.createVolumeShaper(config) volumeShaper = myAudioTrack.createVolumeShaper(config)
자바
volumeShaper = myMediaPlayer.createVolumeShaper(config); volumeShaper = myAudioTrack.createVolumeShaper(config);
단일 트랙 또는 미디어 플레이어에 셰이퍼를 여러 개 연결할 수 있고 각 셰이퍼를 따로따로 조정할 수 있습니다. 트랙 또는 플레이어의 모든 셰이퍼 출력은 함께 곱해집니다. AudioTracks
간에 또는 MediaPlayers
간에 VolumeShaper
를 공유할 수는 없지만 createVolumeShaper
호출에 동일한 구성을 사용하여 여러 개의 AudioTracks
또는 MediaPlayers
에 동일한 셰이퍼를 빌드할 수 있습니다.
셰이프를 생성하면 t = 0에서의 첫 번째 제어점이 오디오 스트림에 적용됩니다. 생성 시 초기 볼륨이 1.0이 아니고 앱에서 콘텐츠를 재생하는 경우 오디오 볼륨이 갑자기 변할 수 있습니다. 가장 좋은 방법은 처음에 무음으로 오디오를 재생하고 재생이 시작되면 VolumeShaper
를 사용하여 페이드 인을 구현하는 것입니다. 볼륨 0에서 시작하다가 페이드 업하는 VolumeShaper
를 만듭니다. 예:
setCurve(new float[] {0.f, 1.f}, new float[] {0.f, 1.f})
재생과 셰이퍼를 동시에 시작합니다. 이렇게 하면 재생이 무음에서 시작되다가 볼륨이 최대 볼륨으로 올라갑니다. 자세한 내용은 다음 섹션에 설명되어 있습니다.
VolumeShaper 실행
셰이프가 생성되는 즉시 첫 번째 제어점의 볼륨 수준이 오디오 경로에 적용되지만, VolumeShaper.Operation.PLAY
가 포함된 apply()
메서드를 호출할 때까지 셰이프는 곡선을 따라 진행되지 않습니다. 셰이퍼를 만든 후 셰이퍼를 시작하려면 첫 번째 PLAY
호출에 apply()
연산을 지정해야 합니다. 그러면 첫 번째 제어점에서 마지막 제어점까지 곡선이 실행됩니다.
Kotlin
shaper.apply(VolumeShaper.Operation.PLAY)
자바
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 = true shaper.replace(newConfig, VolumeShaper.Operation.PLAY, join)
자바
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)
를 사용하여 셰이퍼를 시작할 수 있습니다.
join = false
로 설정된 replace()
를 호출하면 셰이프는 첫 번째 제어점으로 지정된 수준에서 곡선을 시작합니다. 이로 인해 볼륨이 불연속적일 수 있습니다. 이를 방지하려면 replace()
로 설정한 상태에서 join = true
를 호출하면 됩니다.
그러면 새 곡선의 첫 번째 제어점이 셰이퍼의 현재 수준으로 설정되고, 첫 번째 제어점과 마지막 제어점 사이의 모든 제어점의 볼륨이 새 곡선의 상대적인 형태를 유지하도록 조정됩니다(마지막 제어점은 변하지 않음). 조정 연산으로 셰이퍼의 새 곡선에 있는 제어점이 영구히 변경됩니다.
VolumeShaper 제거
AudioTrack
또는 MediaPlayer
가 해제되거나 더 이상 사용되지 않으면 시스템이 종료되고 가비지가 VolumeShaper
를 수집합니다. 셰이퍼에 close()
메서드를 호출하여 셰이퍼를 즉시 제거할 수 있습니다. 셰이퍼는 약 20밀리초 이내에 오디오 파이프라인에서 삭제됩니다. 오디오 재생 중에 VolumeShaper
를 닫을 때는 유의하세요. 셰이퍼의 볼륨이 1.0 미만일 때 close()
를 호출하면 셰이퍼의 볼륨 스케일이 1.0으로 변경됩니다. 따라서 볼륨이 갑자기 커질 수 있습니다.