Extensions Android

OpenSL ES pour Android étend la spécification OpenSL ES de référence afin de la rendre compatible avec Android et d'exploiter ainsi toute la puissance et la flexibilité de cette plate-forme.

La définition de l'API pour les extensions Android se trouve dans OpenSLES_Android.h et dans les fichiers d'en-tête qu'il contient. Pour en savoir plus sur ces extensions, consultez OpenSLES_Android.h. Ce fichier se trouve à la racine de votre installation, dans le répertoire sysroot/usr/include/SLES. Sauf indication contraire, toutes les interfaces sont explicites.

Ces extensions limitent la portabilité de votre application à d'autres implémentations d'OpenSL ES, car elles sont propres à Android. Vous pouvez atténuer ce problème en évitant de recourir à ces extensions ou en utilisant #ifdef pour les exclure au moment de la compilation.

Le tableau suivant présente les interfaces et les localisateurs de données propres à Android qui sont compatibles avec Android OpenSL ES pour chaque type d'objet. Les valeurs Oui dans les cellules signalent les interfaces et les localisateurs de données qui sont disponibles pour chaque type d'objet.

Fonctionnalité Lecteur audio Enregistreur audio Moteur Mix de sortie
File d'attente de tampon Android Oui : source (décodage) Non Non Non
Configuration Android Oui Oui Non Non
Effet Android Oui Non Non Oui
Fonctionnalités d'effet Android Non Non Oui Non
Envoi d'effet Android Oui Non Non Non
File d'attente de tampon simple Android Oui : source (lecture) ou récepteur (décodage) Oui Non Non
Localisateur de données de file d'attente de tampon Android Oui : source (décodage) Non Non Non
Localisateur de données de descripteur de fichier Android Oui : source Non Non Non
Localisateur de données de file d'attente de tampon simple Android Oui : source (lecture) ou récepteur (décodage) Oui : récepteur Non Non

Interface de configuration Android

L'interface de configuration Android permet de définir des paramètres propres à la plate-forme pour les objets. Elle est différente des autres interfaces OpenSL ES 1.0.1 en ce sens que votre application peut l'utiliser avant d'instancier l'objet correspondant. Ainsi, vous pouvez configurer l'objet avant de l'instancier. Le fichier d'en-tête OpenSLES_AndroidConfiguration.h, qui se trouve dans /sysroot/usr/include/SLES, recense les clés et les valeurs de configuration disponibles suivantes :

  • Type de flux pour les lecteurs audio (SL_ANDROID_STREAM_MEDIA par défaut)
  • Profil d'enregistrement pour les enregistreurs audio (SL_ANDROID_RECORDING_PRESET_GENERIC par défaut)

L'extrait de code suivant montre comment définir le type de flux audio Android dans un lecteur audio :

// CreateAudioPlayer and specify SL_IID_ANDROIDCONFIGURATION
// in the required interface ID array. Do not realize player yet.
// ...
SLAndroidConfigurationItf playerConfig;
result = (*playerObject)->GetInterface(playerObject,
    SL_IID_ANDROIDCONFIGURATION, &playerConfig);
assert(SL_RESULT_SUCCESS == result);
SLint32 streamType = SL_ANDROID_STREAM_ALARM;
result = (*playerConfig)->SetConfiguration(playerConfig,
    SL_ANDROID_KEY_STREAM_TYPE, &streamType, sizeof(SLint32));
assert(SL_RESULT_SUCCESS == result);
// ...
// Now realize the player here.

Vous pouvez utiliser un code similaire pour configurer le préréglage d'un enregistreur audio :

// ... obtain the configuration interface as the first four lines above, then:
SLuint32 presetValue = SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION;
result = (*playerConfig)->SetConfiguration(playerConfig,
    RECORDING_PRESET, &presetValue, sizeof(SLuint32));

Interfaces d'effet Android

Les interfaces d'effet, d'envoi d'effet et de fonctionnalités d'effet Android fournissent un mécanisme générique permettant à une application d'interroger et d'utiliser des effets audio propres à l'appareil. Les fabricants d'appareils doivent documenter tous les effets audio spécifiques qu'ils fournissent.

Les applications portables doivent utiliser les API OpenSL ES 1.0.1 pour les effets audio au lieu des extensions d'effet Android.

Localisateur de données de descripteur de fichier Android

Le localisateur de données de descripteur de fichier Android vous permet de spécifier la source d'un lecteur audio sous forme de descripteur de fichier ouvert avec accès en lecture. Les données doivent être au format MIME.

Cette extension est particulièrement utile lorsqu'elle est associée au gestionnaire d'éléments natif, car l'application lit les éléments de l'APK via un descripteur de fichier.

Localisateur de données et interface de file d'attente de tampon simple Android

Dans la spécification de référence OpenSL ES 1.0.1, les files d'attente de tampon ne peuvent être utilisées que pour les lecteurs audio et sont compatibles avec PCM et d'autres formats de données. Les spécifications du localisateur de données et de l'interface de file d'attente de tampon simple Android sont identiques à la spécification de référence, à deux exceptions près :

  • Vous pouvez utiliser les files d'attente de tampon simples Android avec des enregistreurs et des lecteurs audio.
  • Vous ne pouvez utiliser que le format de données PCM avec ces files d'attente.

Pour l'enregistrement, votre application doit placer des tampons vides en file d'attente. Lorsqu'un rappel enregistré envoie une notification indiquant que le système a fini d'écrire les données dans un tampon, l'application peut lire les données de ce tampon.

La lecture fonctionne de la même manière. Pour des raisons de compatibilité ultérieure du code source, nous recommandons cependant que les applications utilisent des files d'attente de tampon simples Android au lieu de files d'attente de tampon OpenSL ES 1.0.1.

Comportement de la file d'attente de tampon

L'implémentation Android n'inclut pas l'exigence de la spécification de référence selon laquelle le curseur de lecture doit revenir au début du tampon en cours de lecture lors du passage à l'état SL_PLAYSTATE_STOPPED. L'implémentation peut adopter ce comportement ou au contraire conserver l'emplacement du curseur de lecture. Par conséquent, votre application ne peut pas supposer que l'un ou l'autre de ces comportements se produit. C'est pourquoi vous devez appeler la méthode BufferQueue::Clear() de manière explicite après une transition vers SL_PLAYSTATE_STOPPED. La file d'attente de tampon est ainsi définie sur un état connu.

De même, il n'existe aucune spécification indiquant si le déclencheur d'un rappel de file d'attente de tampon doit être une transition vers SL_PLAYSTATE_STOPPED ou une exécution de BufferQueue::Clear(). Par conséquent, nous recommandons que votre application ne dépende pas de l'un ou de l'autre de ces événements, mais plutôt qu'elle sache gérer les deux.

Interfaces dynamiques lors de la création d'objets

Pour plus de commodité, l'implémentation Android d'OpenSL ES 1.0.1 permet à votre application de spécifier des interfaces dynamiques lorsqu'elle instancie un objet. Il s'agit d'une alternative à l'utilisation de DynamicInterfaceManagement::AddInterface() pour ajouter ces interfaces après instanciation.

Rapports sur les extensions

Il existe trois méthodes permettant de déterminer si la plate-forme est compatible avec les extensions Android. Ces méthodes sont les suivantes :

  • Engine::QueryNumSupportedExtensions()
  • Engine::QuerySupportedExtension()
  • Engine::IsExtensionSupported()

Toutes ces méthodes renvoient ANDROID_SDK_LEVEL_<API-level>, où API-level est le niveau d'API de la plate-forme, par exemple ANDROID_SDK_LEVEL_23. Si le niveau d'API est supérieur ou égal à 9, cela signifie que la plate-forme accepte les extensions.

Décoder l'audio vers le format PCM

Cette section décrit une extension OpenSL ES 1.0.1 propre à Android et désormais obsolète permettant de décoder un flux encodé vers le format PCM sans lecture immédiate. Le tableau ci-dessous fournit des recommandations d'utilisation de cette extension et propose d'autres solutions.

Niveau d'API Autres solutions
15 ou moins Codec Open Source avec une licence appropriée
16 à 20 Classe MediaCodec ou codec Open Source avec une licence appropriée
21 ou plus NDK MediaCodec dans les fichiers d'en-tête <media/NdkMedia*.h>, classe MediaCodec ou codec Open Source avec une licence appropriée

Remarque : Il n'existe actuellement aucune documentation sur la version NDK de l'API MediaCodec. Vous pouvez toutefois consulter l'exemple de code native-codec.

Un lecteur audio standard diffuse le contenu sur un appareil audio en spécifiant le mix de sortie en tant que récepteur de données. L'extension Android est différente en ce sens qu'un lecteur audio joue plutôt le rôle d'un décodeur si l'application a spécifié la source de données sous forme d'URI ou de localisateur de données de descripteur de fichier Android décrit au format de données MIME. Dans ce cas, le récepteur de données est un localisateur de données de file d'attente de tampon simple Android qui utilise le format de données PCM.

Cette fonctionnalité est principalement destinée aux jeux qui doivent précharger leurs éléments audio à chaque changement de niveau, un comportement semblable à celui fourni par la classe SoundPool.

L'application doit d'abord placer un ensemble de tampons vides dans la file d'attente de tampon simple Android. Elle remplit ensuite les tampons avec des données PCM. Le rappel de file d'attente de tampon simple Android se déclenche chaque fois qu'un tampon est rempli. Le gestionnaire de rappel traite les données PCM, remet en file d'attente le tampon désormais vide, puis retourne au programme appelant. L'application doit effectuer le suivi des tampons décodés. En effet, la liste des paramètres de rappel n'inclut pas suffisamment d'informations pour identifier le tampon qui contient des données ou celui qui doit être placé en file d'attente.

La source de données signale la fin du flux (EOS, End of Stream) de manière implicite en générant alors un événement SL_PLAYEVENT_HEADATEND. Une fois que l'application a décodé toutes les données qu'elle a reçues, elle n'effectue plus d'appels destinés au rappel de file d'attente de tampon simple Android.

Le format de données PCM du récepteur correspond généralement à celui de la source de données encodée en ce qui concerne le taux d'échantillonnage, le nombre de canaux et la profondeur de bits. Cependant, vous pouvez effectuer le décodage en fonction d'un taux d'échantillonnage, d'un nombre de canaux ou d'une profondeur de bits différents. Pour savoir comment détecter le format PCM réel, consultez Déterminer le format des données PCM décodées à l'aide des métadonnées.

La fonctionnalité de décodage PCM d'OpenSL ES pour Android est compatible avec la mise en pause et la recherche initiale. Elle n'est pas compatible avec le contrôle du volume, les effets, la lecture en boucle ni la vitesse de lecture.

Selon l'implémentation de la plate-forme, le décodage peut nécessiter des ressources qui ne peuvent pas être laissées inactives. Par conséquent, nous vous recommandons de fournir un nombre suffisant de tampons PCM vides, faute de quoi le décodeur est sous-alimenté. Cela peut se produire, par exemple, si votre application retourne au programme appelant après le rappel de file d'attente de tampon simple Android sans mettre en file d'attente un autre tampon vide. Le résultat de la sous-alimentation du décodeur n'est pas spécifié, mais peut inclure la perte des données PCM décodées, la suspension du processus de décodage ou l'arrêt total du décodeur.

Remarque : Pour décoder un flux encodé vers le format PCM sans lecture immédiate dans le cas d'applications fonctionnant sous Android 4.x (niveaux d'API 16 à 20), nous vous recommandons d'utiliser la classe MediaCodec. Pour les nouvelles applications fonctionnant sous Android 5.0 (niveau d'API 21) ou version ultérieure, nous vous recommandons d'utiliser l'équivalent NDK, <NdkMedia*.h>. Ces fichiers d'en-tête se trouvent dans le répertoire media/ à la racine de votre installation.

Décoder les flux ADTS AAC vers le format PCM

Un lecteur audio joue le rôle d'un décodeur de flux si la source de données est un localisateur de données de file d'attente de tampon Android qui utilise le format de données MIME, et si le récepteur de données est un localisateur de données de file d'attente de tampon simple Android qui utilise le format de données PCM. Configurez le format de données MIME comme suit :

  • Conteneur : SL_CONTAINERTYPE_RAW
  • Chaîne de type MIME : SL_ANDROID_MIME_AACADTS

Cette fonctionnalité est principalement destinée aux applications multimédias de streaming qui traitent des contenus audio AAC, mais doivent effectuer un traitement audio personnalisé avant la lecture. La plupart des applications qui doivent décoder des éléments audio vers le format PCM doivent utiliser la méthode décrite dans Décoder l'audio vers le format PCM, car elle est plus simple et gère davantage de formats audio. La technique décrite ici est une approche plus spécialisée, à utiliser uniquement si les deux conditions suivantes sont réunies :

  • La source audio compressée est un flux de trames AAC contenues dans des en-têtes ADTS.
  • L'application gère ce flux. Les données ne sont pas situées dans une ressource réseau dont l'identifiant est un URI, ni dans un fichier local dont l'identifiant est un descripteur de fichier.

L'application doit d'abord placer un ensemble de tampons remplis dans la file d'attente de tampon Android. Chaque tampon contient une ou plusieurs trames ADTS AAC complètes. Le rappel de file d'attente de tampon Android se déclenche chaque fois qu'un tampon est vidé. Le gestionnaire de rappel doit remplir et remettre en file d'attente le tampon, puis retourner au programme appelant. L'application n'a pas besoin d'effectuer un suivi des tampons encodés. La liste des paramètres de rappel inclut suffisamment d'informations pour identifier le prochain tampon à placer en file d'attente. La fin du flux est signalée de manière explicite via la mise en file d'attente d'un élément EOS. Après cette opération, la mise en file d'attente n'est plus autorisée.

Nous vous recommandons de fournir des tampons ADTS AAC pleins pour éviter de sous-alimenter le décodeur. Cela peut se produire, par exemple, si votre application retourne au programme appelant après le rappel de file d'attente de tampon Android sans mettre en file d'attente un autre tampon plein. Le résultat de la sous-alimentation du décodeur n'est pas spécifié.

À l'exception de la source de données, la méthode de décodage de flux est identique à celle décrite dans Décoder l'audio vers le format PCM.

Bien que ces termes se ressemblent, une file d'attente de tampon Android est différente d'une file d'attente de tampon simple Android. Le décodeur de flux utilise les deux types de files d'attente de tampon : une file d'attente Android pour la source de données ADTS AAC et une file d'attente simple Android pour le récepteur de données PCM. Pour en savoir plus sur l'API de file d'attente de tampon simple Android, consultez Localisateur de données et interface de file d'attente de tampon simple Android. Pour en savoir plus sur l'API de file d'attente de tampon Android, consultez le fichier index.html dans le répertoire docs/Additional_library_docs/openmaxal/ à la racine de l'installation.

Déterminer le format des données PCM décodées à l'aide des métadonnées

L'interface SLMetadataExtractionItf fait partie de la spécification de référence. Cependant, les clés de métadonnées qui indiquent le format réel des données PCM décodées sont propres à Android. Le fichier d'en-tête OpenSLES_AndroidMetadata.h définit ces clés de métadonnées. Il se trouve à la racine de votre installation, dans le répertoire /sysroot/usr/include/SLES.

Les index de clé de métadonnées sont disponibles immédiatement après l'exécution de la méthode Object::Realize(). Toutefois, les valeurs associées ne sont disponibles qu'une fois que l'application a décodé les premières données encodées. Une bonne pratique consiste à interroger les index de clé du thread principal après avoir appelé la méthode Object::Realize et à lire les valeurs de métadonnées au format PCM dans le gestionnaire de rappel de file d'attente de tampon simple Android lors du premier appel de cette méthode. Pour en savoir plus sur l'utilisation de cette interface, consultez l'exemple de code du package NDK.

Les noms des clés de métadonnées sont stables, mais les index de clé ne sont pas documentés et sont susceptibles de changer. L'application ne doit pas supposer que les index sont persistants d'une exécution à une autre, ni que plusieurs instances d'objet partagent les mêmes index au cours d'une même exécution.

Données à virgule flottante

Une application fonctionnant sous Android 5.0 (niveau d'API 21) ou version ultérieure peut fournir des données à un lecteur audio au format à virgule flottante à simple précision.

Dans l'exemple de code suivant, la méthode Engine::CreateAudioPlayer() crée un lecteur audio utilisant des données à virgule flottante :

#include <SLES/OpenSLES_Android.h>
...
SLAndroidDataFormat_PCM_EX pcm;
pcm.formatType = SL_ANDROID_DATAFORMAT_PCM_EX;
pcm.numChannels = 2;
pcm.sampleRate = SL_SAMPLINGRATE_44_1;
pcm.bitsPerSample = 32;
pcm.containerSize = 32;
pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
pcm.representation = SL_ANDROID_PCM_REPRESENTATION_FLOAT;
...
SLDataSource audiosrc;
audiosrc.pLocator = ...
audiosrc.pFormat = &pcm;
Pour en savoir plus sur l'audio à virgule flottante, consultez la page "Échantillonnage audio".