Mengontrol amplitudo dengan VolumeShaper

Anda dapat menggunakan VolumeShaper pada aplikasi audio untuk melakukan fade-in, fade-out, cross fade, pengecilan volume, dan transisi volume otomatis singkat lainnya. Class VolumeShaper tersedia di Android 8.0 (API level 26) dan yang lebih baru.

Anda membuat VolumeShaper dengan memanggil createVolumeShaper() pada instance AudioTrack atau MediaPlayer. VolumeShaper hanya memproses audio yang dihasilkan oleh AudioTrack atau MediaPlayer yang membuatnya.

VolumeShaper.Configuration

Perilaku VolumeShaper ditentukan oleh VolumeShaper.Configuration-nya. Konfigurasi tersebut menentukan *kurva volume, jenis interpolator, dan durasi.*

Kurva volume

Kurva volume merepresentasikan perubahan amplitudo dari waktu ke waktu. Kurva ini ditentukan oleh sepasang array float, x[] dan y[] yang menentukan serangkaian titik kontrol. Setiap pasangan (x, y) mewakili waktu dan volume. Array harus memiliki panjang yang sama dan berisi minimal 2 nilai dan tidak lebih dari 16 nilai. (Panjang kurva maksimum ditentukan dalam getMaximumCurvePoints().)

Koordinat waktu ditentukan pada interval [0,0, 1,0]. Titik waktu pertama harus 0,0, yang terakhir harus 1,0, dan waktu harus meningkat secara monoton.

Koordinat volume ditentukan dalam skala linear pada interval [0.0, 1.0].

Jenis interpolator

Kurva volume selalu melewati titik kontrol yang ditentukan. Nilai antara titik kontrol diperoleh oleh spline sesuai dengan jenis interpolator konfigurasi. Ada empat konstanta untuk jenis interpolator VolumeShaper yang tersedia:

  • VolumeShaper.Configuration.INTERPOLATOR_TYPE_STEP
  • VolumeShaper.Configuration.INTERPOLATOR_TYPE_LINEAR
  • VolumeShaper.Configuration.INTERPOLATOR_TYPE_CUBIC
  • VolumeShaper.Configuration.INTERPOLATOR_TYPE_CUBIC_MONOTONIC

Durasi

Koordinat waktu yang ditentukan dalam interval [0.0, 1.0] diskalakan ke durasi yang Anda tentukan dalam milidetik. Tindakan ini menentukan durasi sebenarnya kurva volume saat shaper berjalan dan menerapkan kurva tersebut ke output audio.

Menggunakan VolumeShaper

Membuat konfigurasi

Sebelum membuat VolumeShaper, Anda harus membuat instance VolumeShaper.Configuration. Lakukan hal ini menggunakan 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})

Mulai pemutaran dan shaper secara bersamaan. Hal ini memastikan bahwa pemutaran dimulai dari senyap dan volume akan meningkat hingga volume penuh. Hal ini dijelaskan di bagian berikutnya.

Menjalankan VolumeShaper

Meskipun level volume titik kontrol pertama diterapkan ke jalur audio segera setelah shaper dibuat, shaper tidak akan bergerak di sepanjang kurva sampai Anda memanggil metode apply() dengan VolumeShaper.Operation.PLAY. Setelah membuat shaper, pemanggilan apply() pertama harus menentukan operasi PLAY untuk memulai shaper. Fungsi ini menjalankan kurva dari titik kontrol pertama hingga terakhir:

Kotlin

shaper.apply(VolumeShaper.Operation.PLAY)

Java

shaper.apply(VolumeShaper.Operation.PLAY);

Saat shaper berjalan, Anda dapat melakukan panggilan apply() alternatif yang menetapkan operasi REVERSE dan PLAY. Setiap waktu, hal ini mengubah arah pembacaan titik kontrol.

Shaper secara terus-menerus menyesuaikan volume dan melewati semua titik kontrol hingga berakhir. Hal ini terjadi saat shaper mencapai titik kontrol terakhir (untuk operasi PLAY) atau pertama (untuk operasi REVERSE) pada kurva.

Jika shaper berakhir, volume tetap pada setelan terakhir, yang mungkin merupakan titik kontrol pertama atau terakhir. Anda dapat memanggil VolumeShaper.getVolume() untuk level volume saat ini kapan saja.

Setelah shaper berakhir, Anda dapat melakukan panggilan apply() lain untuk menjalankan kurva ke arah yang berlawanan. Misalnya, jika shaper berakhir saat menjalankan PLAY, apply() berikutnya harus berupa REVERSE. Memanggil PLAY setelah PLAY telah berakhir, atau REVERSE setelah REVERSE tidak berlaku lagi.

Anda harus menjalankan operasi PLAY dan REVERSE secara bergantian. Tidak ada cara untuk memutar kurva dari titik kontrol pertama hingga terakhir, lalu memulai ulang kurva tersebut dari titik kontrol pertama. Anda dapat menggunakan metode replace(), yang dijelaskan di bagian berikutnya, untuk mengganti kurva dengan salinannya sendiri. Tindakan ini akan mereset shaper, yang memerlukan operasi PLAY untuk memulainya lagi.

Mengubah kurva

Gunakan metode replace() untuk mengubah kurva VolumeShaper. Metode ini menggunakan konfigurasi, operasi, dan parameter gabungan. Anda dapat memanggil metode replace() kapan saja, selagi shaper berjalan atau setelah shaper berakhir:

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, VolumeConfig
val join = true
shaper.

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_LINE()AR;

Jika Anda memanggil replace() saat shaper berjalan, shaper akan berhenti mengubah volume dan tetap pada nilainya saat ini. Kemudian shaper akan mencoba memulai kurva baru dari titik kontrol pertama. Ini berarti argumen operasi mengontrol apakah shaper berjalan setelah panggilan atau tidak. Tentukan PLAY untuk segera memulai kurva baru, tentukan REVERSE agar shaper dijeda pada volume titik kontrol pertama di kurva baru. Anda dapat memulai shaper nanti dengan apply(VolumeShaper.Operation.PLAY).

Saat Anda memanggil replace() dengan join = false, shaper akan memulai kurvanya pada tingkat yang ditentukan oleh titik kontrol pertamanya. Hal ini dapat menyebabkan volume berhenti. Anda dapat menghindarinya dengan memanggil replace() dengan join = true. Tindakan ini menetapkan titik kontrol pertama kurva baru ke level pembentuk saat ini dan menskalakan volume semua titik kontrol antara titik kontrol pertama dan terakhir untuk mempertahankan bentuk relatif kurva baru (titik kontrol terakhir tidak berubah). Operasi penskalaan mengubah titik kontrol secara permanen di kurva baru pembentuk.

Menghapus VolumeShaper

Sistem menutup dan membersihkan sampah memori VolumeShaper saat AudioTrack atau MediaPlayer-nya dirilis atau tidak lagi digunakan. Anda dapat memanggil metode close() pada shaper untuk segera menghancurkannya. Sistem akan menghapus shaper dari pipeline audio dalam waktu sekitar 20 milidetik. Berhati-hatilah saat menutup VolumeShaper saat audio diputar. Jika volume shaper kurang dari 1,0 saat Anda memanggil close(), skala volume shaper akan berubah menjadi 1,0. Hal ini dapat menyebabkan peningkatan volume secara tiba-tiba.