Điều khiển độ lớn bằng VolumeShaper

Bạn có thể dùng VolumeShaper trong ứng dụng âm thanh để thực hiện hiệu ứng mờ dần, mờ dần, làm mờ dần, giảm âm thanh và các hiệu ứng chuyển đổi âm lượng tự động ngắn khác. Lớp VolumeShaper có trong Android 8.0 (API cấp 26) trở lên.

Bạn tạo VolumeShaper bằng cách gọi createVolumeShaper() trên bản sao của AudioTrack hoặc MediaPlayer. VolumeShaper chỉ hoạt động trên âm thanh do AudioTrack hoặc MediaPlayer tạo ra âm thanh đó.

VolumeShaper.Configuration

Hành vi của VolumeShaper được xác định bởi VolumeShaper.Configuration. Cấu hình chỉ định một *đường cong âm lượng, loại bộ nội suy thời lượng.*

Đường cong âm lượng

Đường cong âm lượng thể hiện sự thay đổi biên độ theo thời gian. Nó được xác định bằng một cặp mảng dấu phẩy động, x[] và y[] xác định một loạt các điểm điều khiển. Mỗi cặp (x, y) lần lượt biểu thị thời gian và âm lượng. Các mảng phải có độ dài bằng nhau, chứa tối thiểu 2 và không quá 16 giá trị. (Độ dài đường cong tối đa được xác định trong getMaximumCurvePoints().)

Toạ độ thời gian được cho trong khoảng [0.0, 1.0]. Điểm thời gian đầu tiên phải là 0, điểm cuối cùng phải là 1 và thời gian phải tăng đơn điệu.

Các toạ độ âm lượng được chỉ định theo thang đo tuyến tính trong khoảng [0.0, 1.0].

Loại bộ nội suy

Đường cong âm lượng luôn đi qua các điểm điều khiển được chỉ định. Giá trị giữa các điểm điều khiển được lấy bằng một spline theo loại bộ nội suy của cấu hình. Có 4 hằng số cho các loại bộ nội suy VolumeShaper hiện có:

  • VolumeShaper.Configuration.interPOLATOR_TYPE_STEP
  • VolumeShaper.Configuration.InterPOLATOR_TYPE_LINEAR
  • VolumeShaper.Configuration.interPOLATOR_TYPE_CUBIC
  • VolumeShaper.Configuration.interPOLATOR_TYPE_CUBIC_MONOTONIC

Thời lượng

Các toạ độ thời gian được chỉ định trong khoảng [0.0, 1.0] sẽ được điều chỉnh theo tỷ lệ theo thời lượng mà bạn chỉ định bằng mili giây. Thuộc tính này xác định thời lượng thực tế theo thời gian của đường cong âm lượng khi trình tạo hình đang chạy và áp dụng đường cong đó cho đầu ra âm thanh.

Sử dụng VolumeShaper

Tạo cấu hình

Trước khi tạo VolumeShaper, bạn phải tạo một thực thể của VolumeShaper.Configuration. Bạn có thể thực hiện việc này bằng cách sử dụng 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})

Bắt đầu phát và tạo hình cùng lúc. Điều này đảm bảo quá trình phát sẽ bắt đầu trong chế độ im lặng và âm lượng sẽ tăng lên mức âm lượng tối đa. Điều này được giải thích trong phần tiếp theo.

Chạy VolumeShaper

Mặc dù mức âm lượng của điểm điều khiển đầu tiên được áp dụng cho đường dẫn âm thanh ngay khi tạo hình dạng, nhưng trình tạo hình sẽ không tiến triển dọc theo đường cong cho đến khi bạn gọi phương thức apply() bằng VolumeShaper.Operation.PLAY. Sau khi tạo chương trình tạo hình, lệnh gọi đầu tiên của apply() phải chỉ định thao tác PLAY để khởi động chương trình tạo hình. Thao tác này sẽ chạy đường cong từ điểm điều khiển đầu tiên đến điểm điều khiển cuối cùng:

Kotlin

shaper.apply(VolumeShaper.Operation.PLAY)

Java

shaper.apply(VolumeShaper.Operation.PLAY);

Trong khi chương trình tạo hình đang chạy, bạn có thể phát lệnh gọi apply() xen kẽ chỉ định các thao tác REVERSE và PLAY. Việc này sẽ thay đổi hướng đọc của các điểm điều khiển mỗi lần đọc.

Trình tạo hình liên tục điều chỉnh âm lượng và truyền qua tất cả các điểm điều khiển cho đến khi hết hạn. Điều này xảy ra khi trình định hình đến điểm điều khiển cuối cùng (đối với thao tác PLAY) hoặc đầu tiên (đối với thao tác REVERSE) trên đường cong.

Khi trình tạo hình hết hạn, âm lượng vẫn ở chế độ cài đặt cuối cùng, có thể là điểm điều khiển đầu tiên hoặc cuối cùng. Bạn có thể gọi VolumeShaper.getVolume() cho mức âm lượng hiện tại bất cứ lúc nào.

Sau khi chương trình tạo hình hết hạn, bạn có thể thực hiện một lệnh gọi apply() khác để chạy đường cong theo hướng ngược lại. Ví dụ: nếu trình định hình đã hết hạn trong khi chạy PLAY, thì apply() tiếp theo phải là REVERSE. Việc gọi PLAY sau khi PLAY hết hạn hoặc REVERSE sau khi REVERSE hết hạn sẽ không có hiệu lực.

Bạn phải thay thế các thao tác PLAYREVERSE. Bạn không thể phát một đường cong từ điểm điều khiển đầu tiên đến điểm điều khiển cuối cùng, rồi bắt đầu lại từ điểm điều khiển đầu tiên. Bạn có thể sử dụng phương thức replace(), được mô tả trong phần tiếp theo, để thay thế đường cong bằng bản sao của chính đường cong đó. Thao tác này sẽ đặt lại trình tạo hình, yêu cầu thao tác PLAY để bắt đầu lại.

Thay đổi đường cong

Sử dụng phương thức replace() để thay đổi đường cong của VolumeShaper. Phương thức này sẽ nhận một cấu hình, một thao tác và một thông số kết hợp. Bạn có thể gọi phương thức replace() bất cứ lúc nào, trong khi trình tạo hình đang chạy hoặc sau khi hết hạn:

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 = new
shar

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)

Khi bạn gọi replace() trong khi chương trình tạo hình đang chạy, âm lượng sẽ ngừng thay đổi và giữ nguyên ở giá trị hiện tại. Sau đó, trình tạo hình sẽ cố gắng bắt đầu đường cong mới từ điểm điều khiển đầu tiên. Điều này có nghĩa là đối số thao tác sẽ kiểm soát việc chương trình tạo hình có chạy sau lệnh gọi hay không. Chỉ định PLAY để bắt đầu đường cong mới ngay lập tức, chỉ định REVERSE để tạm dừng trình tạo hình tại âm lượng của điểm điều khiển đầu tiên trong đường cong mới. Sau này, bạn có thể bắt đầu chương trình tạo hình bằng apply(VolumeShaper.Operation.PLAY).

Khi bạn gọi replace() bằng join = false, trình tạo hình sẽ bắt đầu đường cong ở cấp do điểm điều khiển đầu tiên chỉ định. Điều này có thể gây ra sự gián đoạn trong lượng dữ liệu. Bạn có thể tránh điều này bằng cách gọi replace() bằng join = true. Thao tác này sẽ đặt điểm điều khiển đầu tiên của đường cong mới theo cấp độ hiện tại của biểu đồ và điều chỉnh âm lượng của tất cả điểm điều khiển giữa điểm đầu tiên và điểm điều khiển cuối cùng để duy trì hình dạng tương đối của đường cong mới (điểm điều khiển cuối cùng không thay đổi). Thao tác điều chỉnh theo tỷ lệ sẽ thay đổi vĩnh viễn các điểm điều khiển trong đường cong mới của trình đổ bóng.

Xoá VolumeShaper

Hệ thống sẽ đóng và thu thập rác để thu thập VolumeShaper khi AudioTrack hoặc MediaPlayer của nó được giải phóng hoặc không còn được sử dụng. Bạn có thể gọi phương thức close() trên trình tạo hình để huỷ phương thức đó ngay lập tức. Hệ thống sẽ xoá bộ định hình khỏi quy trình âm thanh trong vòng khoảng 20 mili giây. Hãy cẩn thận khi đóng VolumeShaper trong khi âm thanh đang phát. Nếu chương trình tạo hình có âm lượng nhỏ hơn 1.0 khi bạn gọi close(), tỷ lệ âm lượng của chương trình tạo hình sẽ thay đổi thành 1.0. Điều này có thể khiến lưu lượng truy cập tăng đột biến.