Mengontrol amplitudo dengan VolumeShaper

Anda dapat menggunakan VolumeShaper pada aplikasi audio untuk memperjelas, memudarkan, menghilangkan jeda, mengecilkan volume, dan transisi volume otomatis singkat lainnya. Class VolumeShaper tersedia di Android 8.0 (API level 26) dan yang lebih baru.

Buat VolumeShaper dengan memanggil createVolumeShaper() di instance AudioTrack atau MediaPlayer. VolumeShaper hanya memproses audio yang dihasilkan oleh AudioTrack atau MediaPlayer yang membuatnya.

VolumeShaper.Configuration

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

Kurva volume

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

Koordinat waktu ditentukan pada interval [0,0, 1,0]. Poin waktu pertama harus dimulai dari 0,0, sedangkan yang terakhir harus 1,0, dan waktu harus meningkat secara monoton.

Koordinat volume ditentukan dalam skala linier pada interval [0,0, 1,0].

Jenis interpolator

Kurva volume selalu melewati titik kontrol yang ditentukan. Nilai antara titik kontrol diperoleh dari spline sesuai dengan jenis interpolator konfigurasinya. Terdapat 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 pada interval [0,0, 1,0] diskalakan pada durasi yang Anda tentukan dalam milidetik. Hal ini menentukan durasi sebenarnya kurva volume saat shaper berjalan dan menerapkan kurva tersebut ke keluaran audio.

Menggunakan VolumeShaper

Membuat konfigurasi

Sebelum membuat VolumeShaper, Anda harus membuat instance VolumeShaper.Configuration. Lakukan 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();
    

Tanpa argumen, constructor VolumeShaper.Configuration.Builder akan menampilkan builder yang membuat konfigurasi dengan setelan default: INTERPOLATOR_TYPE_CUBIC, berdurasi satu detik, dan tanpa kurva. Anda harus menambahkan kurva ke builder sebelum memanggil build().

Framework menyediakan konstanta untuk konfigurasi dengan kurva bawaan, masing-masing berdurasi satu detik:

  • VolumeShaper.Configuration.LINEAR_RAMP
  • VolumeShaper.Configuration.CUBIC_RAMP
  • VolumeShaper.Configuration.SINE_RAMP
  • VolumeShaper.Configuration.SCURVE_RAMP

Membuat VolumeShaper

Untuk membuat VolumeShaper, panggil createVolumeShaper() pada instance class yang sesuai, dengan meneruskan VolumeShaper.Configuration:

Kotlin

    volumeShaper = myMediaPlayer.createVolumeShaper(config)
    volumeShaper = myAudioTrack.createVolumeShaper(config)
    

Java

    volumeShaper = myMediaPlayer.createVolumeShaper(config);
    volumeShaper = myAudioTrack.createVolumeShaper(config);
    

Satu trek atau pemutar media dapat memiliki banyak shaper yang disertakan pada pemutar media, dan Anda dapat mengontrol setiap shaper secara terpisah. Keluaran dari semua shaper pada trek atau pemutar dilipatgandakan secara bersamaan. VolumeShaper tidak dapat dibagikan di antara AudioTracks atau MediaPlayers, tetapi Anda dapat menggunakan konfigurasi yang sama pada panggilan ke createVolumeShaper untuk membuat shaper yang identik pada beberapa AudioTracks atau MediaPlayers.

Saat shaper dibuat, titik kontrol pertamanya (pada t = 0) diterapkan pada streaming audio. Jika volume awal bukan 1,0 dan aplikasi Anda memutar trek pada waktu pembuatan, audio Anda mungkin mengalami perubahan volume yang mendadak. Praktik terbaiknya adalah memulai pemutaran audio dari keadaaan senyap dan menggunakan VolumeShaper untuk menerapkan fade-in saat pemutaran dimulai. Buat VolumeShaper yang dimulai dari volume 0 dan memudar. Contoh:

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 keadaan senyap dan volume akan meningkat hingga penuh. Hal ini dijelaskan di bagian berikutnya.

Menjalankan VolumeShaper

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

Kotlin

    shaper.apply(VolumeShaper.Operation.PLAY)
    

Java

    shaper.apply(VolumeShaper.Operation.PLAY);
    

Selagi shaper berjalan, Anda dapat melakukan panggilan apply() alternatif yang menetapkan operasi REVERSE dan PLAY. Setiap kali dipanggil, tindakan ini akan 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 seperti pada setelan terakhirnya, yang mungkin merupakan titik kontrol pertama atau terakhirnya. Anda dapat memanggil VolumeShaper.getVolume() untuk level volume saat ini kapan saja.

Setelah shaper berakhir, Anda dapat melakukan panggilan apply() lainnya untuk menjalankan kurva ke arah yang berlawanan. Misalnya, jika shaper berakhir saat menjalankan PLAY, apply() berikutnya harus berupa REVERSE. Memanggil PLAY setelah PLAY berakhir, atau REVERSE setelah REVERSE berakhir tidak berpengaruh apa pun.

Anda harus menjalankan operasi PLAY dan REVERSE secara bergantian. Anda tidak dapat menjalankan kurva dari titik kontrol pertama hingga terakhir, lalu memulainya kembali dari titik kontrol pertama. Anda dapat menggunakan metode replace() untuk mengganti kurva dengan salinannya sebagaimana dijelaskan di bagian berikutnya. Metode ini akan menyetel ulang shaper, mengharuskan operasi PLAY untuk memulai prosesnya kembali.

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.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);
    

Jika Anda memanggil replace() selagi shaper berjalan, shaper akan berhenti mengubah volume dan tetap pada nilainya saat ini. Kemudian shaper akan mencoba untuk memulai kurva baru dari titik kontrol pertama. Ini berarti argumen operasi mengontrol shaper, baik dijalankan atau tidak setelah panggilan. Tentukan PLAY untuk segera memulai kurva baru, tentukan REVERSE untuk menjeda shaper 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 memulai kurvanya pada level yang ditentukan oleh titik kontrol pertamanya. Hal ini dapat menyebabkan volume berhenti disesuaikan. Anda dapat menghindarinya dengan memanggil replace() dengan join = true. Tindakan ini menetapkan titik kontrol pertama kurva baru ke level shaper saat ini dan menskalakan volume dari semua titik kontrol antara yang pertama dan terakhir untuk mempertahankan bentuk relatif kurva baru (titik kontrol terakhir tidak berubah). Operasi penskalaan mengubah titik kontrol di kurva baru shaper secara permanen.

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 menghapusnya dengan segera. Sistem akan menghapus shaper dari pipeline audio dalam waktu sekitar 20 mdtk. Berhati-hatilah saat menutup VolumeShaper selagi audio diputar. Jika volume shaper kurang dari 1,0 saat Anda memanggil close(), skala volume shaper akan diubah menjadi 1,0. Hal ini dapat menyebabkan peningkatan volume secara tiba-tiba.