Mengontrol amplitudo dengan VolumeShaper

Anda dapat menggunakan VolumeShaper di aplikasi audio untuk melakukan memudar, memudar, memudar bersilang, mengecilkan volume, dan volume otomatis pendek lainnya transisi. Class VolumeShaper tersedia di Android 8.0 (API level 26) dan kemudian.

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

VolumeShaper.Configuration

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

Kurva volume

Kurva volume merepresentasikan perubahan amplitudo dari waktu ke waktu. Hal ini ditentukan oleh pasangan dari array float, x[] dan y[] yang menentukan serangkaian titik kontrol. Masing-masing (x, y) pasangan mewakili waktu dan volume masing-masing. Array harus sama panjangnya dan berisi sedikitnya 2 dan tidak lebih dari 16 nilai. (Panjang kurva maksimum adalah ditentukan di getMaximumCurvePoints().)

Koordinat waktu ditentukan pada interval [0,0, 1,0]. Pertama kali poin harus 0.0, yang terakhir harus 1.0, dan waktu harus secara monoton meningkat.

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

Jenis interpolator

Kurva volume selalu melewati titik kontrol yang ditentukan. Nilai-nilai di antara titik kontrol diperoleh oleh {i>spline<i} sesuai dengan jenis interpolator konfigurasi Anda. Ada empat konstanta untuk atribut VolumeShaper jenis interpolator:

  • 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 yang Anda tetapkan dalam milidetik. {i>Function<i} ini menentukan panjang sebenarnya di waktu kurva volume saat shaper berjalan dan menerapkan kurva ke output audio.

Menggunakan VolumeShaper

Membuat konfigurasi

Sebelum membuat VolumeShaper, Anda harus membuat instance VolumeShaper.Configuration. Lakukan ini dengan 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 meningkat hingga volume penuh. Hal ini dijelaskan dalam bagian berikutnya.

Menjalankan VolumeShaper

Meskipun tingkat 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. Sesudah membuat shaper, pemanggilan apply() pertama harus menentukan PLAY untuk memulai shaper. Sistem ini menjalankan kurva dari titik kontrol terakhir:

Kotlin

shaper.apply(VolumeShaper.Operation.PLAY)

Java

shaper.apply(VolumeShaper.Operation.PLAY);

Saat shaper berjalan, Anda dapat melakukan panggilan apply() alternatif yang menentukan Operasi REVERSE dan PLAY. Ini mengubah arah pembacaan titik kontrol setiap saat.

Pembentuk terus menyesuaikan volume dan melewati semua titik kontrol hingga berakhir. Ini terjadi saat shaper mencapai yang terakhir (untuk PLAY operasi) atau titik kontrol pertama (untuk operasi REVERSE) dalam kurva.

Saat shaper kedaluwarsa, volume akan tetap pada pengaturan terakhir, yang mungkin 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() lagi untuk menjalankan kurva dalam arah yang berlawanan. Misalnya, jika shaper berakhir saat berjalan PLAY, apply() berikutnya harus REVERSE. Menelepon PLAY setelah PLAY masa berlakunya telah berakhir, atau REVERSE setelah masa berlaku REVERSE berakhir tidak akan berpengaruh.

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

Mengubah kurva

Gunakan metode replace() untuk mengubah kurva VolumeShaper. Metode ini memerlukan konfigurasi, operasi, dan parameter gabungan. Anda dapat memanggil Metode replace() kapan saja, saat 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)
        {i>.build()<i}
val join = true
shaper.override(newConfig, VolumeShaper.Operation.PLAY, bergabung)

Java

VolumeShaper.Configuration newConfig =
  VolumeShaper.Configuration.Builder() baru
    .setDuration(1000)
    .setCurve(float baru[] {0.f, 0.5f}, float baru[] {0.f, 1.f})
    .setInterpolatorType(VolumeShaper.Configuration.INTERPOLATOR_TYPE_LINEAR)
    {i>.build()<i};
gabungan boolean = true;
shaper.override(newConfig, VolumeShaper.Operation.PLAY, bergabung);

Saat Anda memanggil replace() saat shaper berjalan, shaper akan berhenti mengubah volume dan tetap pada nilai saat ini. Kemudian shaper akan mencoba memulai dari titik kontrol pertama. Ini berarti bahwa argumen operasi mengontrol apakah shaper akan dijalankan 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 di level yang ditentukan oleh titik kontrol pertamanya. Hal ini dapat menyebabkan diskontinuitas dalam volume. Anda dapat menghindarinya dengan memanggil replace() dengan join = true. Tindakan ini akan menetapkan titik kontrol pertama kurva baru ke tingkat harga saat ini shaper dan menskalakan volume semua titik kontrol antara titik terakhir untuk mempertahankan bentuk relatif kurva baru (titik kontrol terakhir adalah tidak berubah). Operasi penskalaan mengubah titik kontrol secara permanen di kurva baru shaper.

Menghapus VolumeShaper

Sistem menutup dan membersihkan sampah memori VolumeShaper saat AudioTrack atau MediaPlayer dirilis atau tidak lagi digunakan. Anda dapat memanggil metode close() pada {i>shaper<i} untuk menghancurkannya segera. Sistem 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.