VolumeShaper で振幅を制御する

オーディオ アプリで VolumeShaper を使用すると、フェードイン、フェードアウト、クロスフェード、ダッキングなどの短い自動音量遷移を実行できます。VolumeShaper クラスは Android 8.0(API レベル 26)以降で使用できます。

VolumeShaper を作成するには、AudioTrack または MediaPlayer のインスタンスで createVolumeShaper() を呼び出します。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] で指定します。

補間タイプ

音量カーブは指定されたコントロール ポイントを必ず通ります。コントロール ポイント間の値は、構成の interpolator タイプに応じてスプラインによって導出されます。使用可能な 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()

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})

再生とこのシェイパーを同時に開始します。これにより、無音状態から再生が開始され、最大音量になるまで音量が上がります。これについては次のセクションで説明します。

VolumeShaper を実行する

シェイパーが作成されるとすぐに、最初のコントロール ポイントの音量レベルが音声パスに適用されますが、VolumeShaper.Operation.PLAY を指定して apply() メソッドを呼び出すまで、シェイパーはカーブに沿って進行しません。シェイパーの作成後、apply() の最初の呼び出しで、シェイパーを開始するために PLAY オペレーションを指定する必要があります。これにより、最初のコントロール ポイントから最後のコントロール ポイントまで曲線が実行されます。

Kotlin

schemar.apply(VolumeShaper.Operation.PLAY)

Java

Shaper.apply(VolumeShaper.Operation.PLAY);

シェイパーの実行中に、REVERSE オペレーションと PLAY オペレーションを指定して apply() 呼び出しを交互に発行できます。これにより、コントロール ポイントの読み出しの方向が毎回変わります。

シェイパーは音量を継続的に調整し、期限が切れるまですべてのコントロール ポイントを通過します。これは、シェイパーが曲線の最終(PLAY オペレーションの場合)または最初のコントロール ポイント(REVERSE オペレーションの場合)に到達したときに発生します。

シェイパーが期限切れになると、音量は最後の設定(最初または最後のコントロール ポイント)に戻ります。いつでも VolumeShaper.getVolume() を呼び出して現在の音量レベルを取得できます。

シェイパーが期限切れになったら、別の apply() 呼び出しを発行して、カーブを反対方向に実行できます。たとえば、PLAY の実行中にシェイパーが期限切れになった場合、次の apply()REVERSE にする必要があります。PLAY の期限が切れた後、または REVERSE の期限が切れた後に REVERSE を呼び出しても、効果はありません。PLAY

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)
        .PLAY, shaper.Configuration.INTERPOLATOR_TYPE_LINEAR)
PLAY, replace()
val.join. = true

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.

シェイパーの実行中に replace() を呼び出すと、音量の変更が停止され、現在の値のままとなります。次に、シェイパーは最初のコントロール ポイントから新しい曲線を開始しようとします。つまり、オペレーション引数は、呼び出し後にシェーパーを実行するかどうかを制御します。新しいカーブをすぐに開始するには PLAY を指定します。新しいカーブの最初のコントロール ポイントの音量でシェイパーを一時停止したままにするには、REVERSE を指定します。シェイパーは後で apply(VolumeShaper.Operation.PLAY) で開始できます。

join = false を指定して replace() を呼び出すと、シェイパーは最初のコントロール ポイントで指定されたレベルで曲線を開始します。これにより、音量が不連続になる可能性があります。これを回避するには、join = true を指定して replace() を呼び出します。これにより、新しいカーブの最初のコントロール ポイントをシェイパーの現在のレベルに設定し、最初と最後の間のすべてのコントロール ポイントのボリュームをスケーリングして、新しいカーブの相対的な形状を維持します(最後のコントロール ポイントは変更されません)。スケーリング オペレーションにより、シェーパーの新しい曲線のコントロール ポイントは永続的に変更されます。

VolumeShaper を削除する

AudioTrack または MediaPlayer が解放されるか使用されなくなると、システムは VolumeShaper を閉じ、ガベージ コレクションを実行します。シェーパーで close() メソッドを呼び出すと、すぐに破棄できます。システムは、約 20 ミリ秒以内にオーディオ パイプラインからシェイパーを削除します。オーディオの再生中に VolumeShaper を閉じる場合は注意が必要です。close() を呼び出したときにシェイパーの音量が 1.0 未満の場合、シェイパーの音量スケールは 1.0 に変更されます。これにより、音量が突然増加することがあります。