Contrôler l'amplitude avec VolumeShaper

Vous pouvez utiliser un VolumeShaper dans une application audio pour effectuer Fondus à l'ouverture, fondu enchaîné, fondu enchaîné, atténuation et autres volumes courts automatisés les transitions. La classe VolumeShaper est disponible dans Android 8.0 (niveau d'API 26). et plus tard.

Vous créez un VolumeShaper en appelant createVolumeShaper() sur une instance de AudioTrack ou MediaPlayer. La VolumeShaper n'agit que sur le contenu audio produit par AudioTrack ou MediaPlayer. qui l'a créé.

VolumeShaper.Configuration

Le comportement d'un VolumeShaper est défini par ses VolumeShaper.Configuration La configuration spécifie *Courbe de volume, type d'interpolateur et durée*.

Courbe de volume

La courbe de volume représente l'évolution de l'amplitude au fil du temps. Il est défini par une paire de tableaux à virgule flottante, x[] et y[], qui définissent une série de points de contrôle. Chaque (x, y) représente respectivement l'heure et le volume. Les tableaux doivent être de longueur égale et contenir entre 2 et 16 valeurs. (La longueur maximale d'une courbe est de défini dans getMaximumCurvePoints().)

Les coordonnées temporelles sont données sur l'intervalle [0,0, 1,0]. La première fois le point doit être 0.0, le dernier doit être 1.0 et les heures doivent être monotones augmenter.

Les coordonnées du volume sont spécifiées sous forme d'échelle linéaire sur l'intervalle [0,0, 1,0].

Type d'interpolateur

La courbe de volume passe toujours par les points de contrôle spécifiés. Valeurs entre les points de contrôle sont dérivées d'une spline le type d'interpolateur de la configuration. Il existe quatre constantes pour la valeur Types d'interpolateurs VolumeShaper:

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

Durée

Les coordonnées temporelles spécifiées dans l'intervalle [0.0, 1.0] sont mises à l'échelle que vous spécifiez en millisecondes. Cela détermine la longueur réelle en l'heure de la courbe de volume lorsque le profileur s'exécute et applique la courbe la sortie audio.

Utiliser un VolumeShaper

Créer une configuration

Avant de créer un VolumeShaper, vous devez créer une instance de VolumeShaper.Configuration. Pour ce faire, utilisez un 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})

Lancez simultanément la lecture et le formateur. Ainsi, la lecture démarre après le son coupé et le volume atteint le volume maximal. Cela est expliqué dans la section suivante.

Exécuter un VolumeShaper

Toutefois, le niveau de volume du premier point de contrôle est appliqué à la voie audio Dès qu'il est créé, il ne progresse pas le long de la courbe. jusqu'à ce que vous appelez la méthode apply() avec VolumeShaper.Operation.PLAY. Après créant le formateur, le premier appel de apply() doit spécifier l'PLAY pour démarrer le formateur. Cela permet d'exécuter la courbe de sa première à Derniers points de contrôle:

Kotlin

shaper.apply(VolumeShaper.Operation.PLAY)

Java

shaper.apply(VolumeShaper.Operation.PLAY);

Pendant que le profileur est en cours d'exécution, vous pouvez émettre des appels apply() alternés en spécifiant Opérations REVERSE et PLAY. Cela change le sens de lecture ces points de contrôle à chaque fois.

Le profileur ajuste continuellement le volume et passe par tous les points de contrôle jusqu'à son expiration. C'est le cas lorsque le formateur atteint le dernier élément opération) ou le premier point de contrôle (pour un fonctionnement INVERSE) de la courbe.

Lorsque le traceur arrive à expiration, le volume reste au dernier réglage, qui peut être le premier ou le dernier point de contrôle. Vous pouvez appeler VolumeShaper.getVolume() pour le niveau de volume actuel à tout moment.

Une fois le shaper expiré, vous pouvez émettre un autre appel apply() pour exécuter la courbe dans le sens opposé. Par exemple, si le formateur a expiré pendant l'exécution PLAY, la apply() suivante doit être REVERSE. Si vous appelez PLAY après PLAY, ou REVERSE après l'expiration du REVERSE n'a aucun effet.

Vous devez alterner les opérations PLAY et REVERSE. Il n'y a aucun moyen de jouer la courbe du premier au dernier point de contrôle, puis la redémarrer premier point de contrôle. Vous pouvez utiliser la méthode replace(), décrite à la section pour remplacer la courbe par une copie de la courbe. Cela réinitialise le profileur, nécessitant l'opération PLAY pour le redémarrer.

Modifier la courbe

Utilisez la méthode replace() pour modifier la courbe d'une VolumeShaper. Cette méthode prend une configuration, une opération et un paramètre de jointure. Vous pouvez appeler la méthode replace() à tout moment, pendant que le formateur est en cours d'exécution ou après son expiration:

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.remplacer(newConfig, VolumeShaper.Operation.PLAY, rejoindre)

Java

VolumeShaper.Configuration newConfig =
  Nouveau VolumeShaper.Configuration.Builder()
    .setDuration(1000)
    .setCurve(nouveau float[] {0.f, 0.5f}, nouveau float[] {0.f, 1.f})
    .setInterpolatorType(VolumeShaper.Configuration.INTERPOLATOR_TYPE_LINEAR)
    build
boolean join = true;
shaper.remplacer(newConfig, VolumeShaper.Operation.PLAY, join);

Lorsque vous appelez replace() pendant que le profileur est en cours d'exécution, la modification de la valeur et reste à sa valeur actuelle. Il essaie ensuite de créer à partir du premier point de contrôle. Cela signifie que l'argument "operation" détermine si le formateur s'exécute ou non après l'appel. Spécifiez PLAY pour démarrer immédiatement la nouvelle courbe, spécifier REVERSE pour laisser le formateur en pause à le volume du premier point de contrôle sur la nouvelle courbe. Vous pouvez démarrer le avec apply(VolumeShaper.Operation.PLAY).

Lorsque vous appelez replace() avec join = false, le profileur commence sa courbe à au niveau spécifié par son premier point de contrôle. Cela peut entraîner une discontinuité du volume. Pour éviter cela, appelez replace() avec join = true. Le premier point de contrôle de la nouvelle courbe est alors défini sur le niveau actuel de la et adapte le volume de tous les points de contrôle entre le premier afin de conserver la forme relative de la nouvelle courbe (le dernier point de contrôle est inchangée). L'opération de scaling modifie définitivement les points de contrôle dans le la nouvelle courbe du shaper.

Supprimer un VolumeShaper

Le système se ferme et la récupération de mémoire VolumeShaper se produit lorsque son AudioTrack ou MediaPlayer est publié ou n'est plus utilisé. Vous pouvez appeler la méthode close() pour le détruire immédiatement. Le système supprime le profileur du pipeline audio en moins de 20 ms. Soyez prudent lorsque vous fermez une VolumeShaper lorsque l'audio est en cours de lecture. Si le volume du profileur est inférieur à 1,0 lorsque vous l'appelez close(), l'échelle de volume du profileur passe à 1.0. Cela peut provoquer une d'augmentation du volume.