OpenSL ES per Android estende la specifica OpenSL ES di riferimento per renderlo compatibile con e per sfruttare la potenza e la flessibilità della piattaforma Android.
La definizione dell'API per le estensioni Android si trova in OpenSLES_Android.h
e i file di intestazione che include. Consulta OpenSLES_Android.h
per informazioni dettagliate su queste estensioni. Questo file si trova nella radice di installazione, nella
Directory sysroot/usr/include/SLES
. Salvo diversa indicazione
tutte le interfacce sono esplicite.
Queste estensioni limitano la portabilità della tua applicazione
altre implementazioni OpenSL ES, in quanto sono specifiche per Android. Per limitare il problema, puoi
evitando di utilizzare estensioni o utilizzando #ifdef
per escluderle al momento della compilazione.
La tabella seguente mostra le interfacce e i localizzatori di dati specifici di Android supportati da Android OpenSL ES per ciascun tipo di oggetto. I valori Sì nelle celle indicano le interfacce e i dati disponibili per ogni tipo di oggetto.
Funzionalità | Lettore audio | Registratore audio | Motore | Mix di output |
---|---|---|---|---|
Coda buffer Android | Sì: sorgente (decodifica) | No | No | No |
Configurazione Android | Sì | Sì | No | No |
Effetto Android | Sì | No | No | Sì |
Funzionalità degli effetti Android | No | No | Sì | No |
Invio effetto Android | Sì | No | No | No |
Coda del buffer semplice di Android | Sì: origine (riproduzione) o sink (decodifica) | Sì | No | No |
Localizzatore dati coda buffer Android | Sì: sorgente (decodifica) | No | No | No |
Localizzatore dati descrittore file Android | Sì: origine | No | No | No |
Localizzatore di dati coda buffer semplice Android | Sì: origine (riproduzione) o sink (decodifica) | Sì: sink | No | No |
Interfaccia di configurazione Android
L'interfaccia di configurazione di Android offre un mezzo per impostare
e parametri specifici della piattaforma per gli oggetti. Questa interfaccia è diversa dalle altre OpenSL ES
1.0.1 si interfacciano in quanto la tua app può usarla prima di creare un'istanza dell'oggetto corrispondente; quindi
puoi configurare l'oggetto prima di creare un'istanza. La
OpenSLES_AndroidConfiguration.h
file di intestazione, che si trova all'indirizzo
/sysroot/usr/include/SLES
,
documenta le seguenti chiavi e valori di configurazione disponibili:
- Tipo di stream per i lettori audio (valore predefinito:
SL_ANDROID_STREAM_MEDIA
). - Registra profilo per registratori audio (valore predefinito:
SL_ANDROID_RECORDING_PRESET_GENERIC
).
Il seguente snippet di codice mostra un esempio di come impostare il tipo di stream audio Android su un audio giocatore:
// 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.
Puoi utilizzare un codice simile per configurare la preimpostazione per un registratore 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));
Interfacce degli effetti Android
Le interfacce di Android per gli effetti, l'invio di effetti e le funzionalità degli effetti un meccanismo generico che consente a un'applicazione di eseguire query e usare criteri effetti audio. I produttori di dispositivi devono documentare tutti gli effetti audio disponibili specifici per i dispositivi che forniscono.
Le applicazioni portatili dovrebbero utilizzare le API OpenSL ES 1.0.1 per gli effetti audio anziché le API estensioni degli effetti.
Localizzatore dati descrittore file Android
Il localizzatore dei dati del descrittore dei file Android consente di specificare l'origine di un come descrittore di file aperto con accesso in lettura. Il formato dei dati deve essere MIME.
Questa estensione è particolarmente utile insieme al gestore di asset nativi, perché l'app legge gli asset dall'APK tramite un descrittore del file.
Localizzatore di dati e interfaccia della coda del buffer semplice di Android
Nella specifica di riferimento OpenSL ES 1.0.1, le code buffer possono essere usate solo per i lettori audio e sono compatibili con PCM e altri formati di dati. Le specifiche dell'interfaccia e del localizzatore dei dati della coda del buffer semplice di Android identico alla specifica di riferimento, con due eccezioni:
- Puoi usare code di buffer semplici di Android con i registratori audio e i lettori audio.
- Con queste code puoi utilizzare solo il formato di dati PCM.
Per la registrazione, la tua app dovrebbe accodare i buffer vuoti. Quando viene inviato un callback registrato una notifica che informa che il sistema ha terminato di scrivere i dati in un buffer, l'app può leggere dal buffer.
La riproduzione funziona allo stesso modo. Per il codice sorgente futuro compatibilità, tuttavia, suggeriamo che le applicazioni utilizzino Android semplici code di buffer invece di code di buffer OpenSL ES 1.0.1.
Comportamento coda buffer
L'implementazione di Android non include
il requisito della specifica di riferimento che il cursore di riproduzione ritorni all'inizio
del buffer attualmente in riproduzione quando la riproduzione entra nel valore SL_PLAYSTATE_STOPPED
stato. Questa implementazione può adattarsi a questo comportamento oppure può lasciare la posizione in cui si svolge la riproduzione.
cursore invariato.
Di conseguenza, la tua app non può presupporre che si verifichi uno dei due comportamenti. Pertanto,
devi chiamare esplicitamente il metodo BufferQueue::Clear()
dopo una transizione a
SL_PLAYSTATE_STOPPED
. In questo modo, la coda del buffer viene impostata su uno stato noto.
Allo stesso modo, non esiste una specifica che stabilisca se il trigger per un callback di coda di buffer debba
una transizione a SL_PLAYSTATE_STOPPED
o l'esecuzione di
BufferQueue::Clear()
. Pertanto, ti consigliamo di non creare una dipendenza
l'uno o l'altro; la tua app dovrebbe
essere in grado di gestire entrambe le cose.
Interfacce dinamiche alla creazione degli oggetti
Per praticità, l'implementazione Android di OpenSL ES 1.0.1
Consente alla tua app di specificare interfacce dinamiche quando crea un'istanza di un oggetto.
Questa è un'alternativa all'utilizzo di DynamicInterfaceManagement::AddInterface()
per aggiungere queste interfacce dopo la creazione dell'istanza.
Report sulle estensioni
Esistono tre metodi per chiedere se la piattaforma supporta le estensioni Android. Questi sono:
Engine::QueryNumSupportedExtensions()
Engine::QuerySupportedExtension()
Engine::IsExtensionSupported()
Uno di questi metodi restituisce ANDROID_SDK_LEVEL_<API-level>
,
dove API-level
è il livello API della piattaforma; ad esempio ANDROID_SDK_LEVEL_23
.
Un livello API della piattaforma pari o superiore a 9 significa che la piattaforma supporta le estensioni.
Decodifica l'audio in PCM
Questa sezione descrive un'estensione deprecata specifica di Android a OpenSL ES 1.0.1 per decodificare uno stream codificato in PCM senza riproduzione immediata. La seguente tabella fornisce consigli per l'uso di questa estensione e delle alternative.
Livello API | Alternative |
---|---|
Fino a 15 anni | Un codec open source con una licenza appropriata. |
Da 16 a 20 |
La classe MediaCodec o un codec open source con una licenza appropriata
|
21 e successive |
NDK MediaCodec nei file di intestazione <media/NdkMedia*.h> ,
MediaCodec o un codec open source con una licenza appropriata
|
Nota:
Al momento non esiste alcuna documentazione per la versione NDK dell'API MediaCodec
. Tuttavia,
puoi fare riferimento
native-codec, ad esempio.
Un lettore audio standard viene riprodotto su un dispositivo audio e specifica il mix di output come sink di dati. L'estensione per Android è diversa per il fatto che un audio player agisce da decoder se l'app ha specificato l'origine dati come URI o come Android del descrittore di file, descritto utilizzando il formato dei dati MIME. In tal caso, il data sink viene un localizzatore di dati su una coda di buffer semplice Android che utilizza il formato di dati PCM.
Questa funzionalità è pensata principalmente per consentire ai giochi di precaricare gli asset audio quando passano a una
un nuovo livello di gioco, simile alla funzionalità SoundPool
offerti dal corso.
Inizialmente, l'applicazione dovrebbe accodare un set di buffer vuoti in una coda di buffer. Dopodiché, l'app riempie i buffer con dati PCM. La semplicità di Android Il callback della coda di buffer viene attivato dopo che ogni buffer è stato riempito. Il gestore del callback elabora i dati PCM, ripete la coda del buffer ora vuoto e quindi restituisce. L'applicazione è responsabile il mantenimento di traccia dei buffer decodificati; l'elenco dei parametri di callback non include informazioni sufficienti per indicare il buffer che contiene i dati o il buffer che deve in coda.
L'origine dati segnala implicitamente la fine del flusso (EOS) fornendo un
SL_PLAYEVENT_HEADATEND
evento alla fine dello stream. Dopo che l'app è stata decodificata
tutti i dati ricevuti, non effettua altre chiamate al semplice callback della coda del buffer di Android.
Il formato dei dati PCM del sink in genere corrisponde a quello dell'origine dati codificata in termini di frequenza di campionamento, numero di canali e profondità in bit. Tuttavia, puoi decodificare in un altro frequenza di campionamento, numero di canali o profondità di bit. Per informazioni su un provisioning per rilevare l'effettivo formato PCM, consulta Determinare il formato dei dati PCM decodificati tramite i metadati.
La funzione di decodifica PCM di OpenSL ES per Android supporta la messa in pausa e la ricerca iniziale; non supporta controllo del volume, effetti, loop o velocità di riproduzione.
A seconda dell'implementazione della piattaforma, la decodifica potrebbe richiedere risorse che non possono essere lasciati inattivi. Pertanto, ti consigliamo di fornire un numero sufficiente di buffer PCM vuoti; altrimenti il decoder smette di fame. Ciò può accadere Ad esempio, se la tua app restituisce il callback della coda del buffer di Android senza accoda un altro buffer vuoto. Il risultato dell'inerzia dei decoder è non specificato, ma può includere: eliminazione del valore decodificato dati PCM, messa in pausa del processo di decodifica o terminazione del decoder.
Nota:
Decodificare uno stream codificato in PCM senza però riprodurlo immediatamente, per le app in esecuzione
Android 4.x (livelli API 16-20), è consigliabile utilizzare la classe MediaCodec
.
Per le nuove app con Android 5.0 (livello API 21) o versioni successive, ti consigliamo di usare l'NDK
equivalente, <NdkMedia*.h>
. Questi file di intestazione risiedono
nella directory media/
nella directory radice di installazione.
Decodifica lo streaming da ADTS AAC in PCM
Un lettore audio agisce da decoder per lo streaming se l'origine dati è un Localizzatore di dati della coda del buffer Android che utilizza il formato dei dati MIME e i dati il sink è un semplice localizzatore di dati di coda del buffer Android che utilizza il formato di dati PCM. Configura il formato dei dati MIME come segue:
- Contenitore:
SL_CONTAINERTYPE_RAW
- Stringa di tipo MIME:
SL_ANDROID_MIME_AACADTS
Questa funzionalità è destinata principalmente alle applicazioni multimediali di streaming che gestire l'audio AAC, ma dover eseguire l'elaborazione audio personalizzata prima della riproduzione. La maggior parte delle applicazioni che devono decodificare l'audio in PCM deve utilizzare il metodo descritto in Decodifica dell'audio in PCM, poiché questo metodo è più semplice e gestisce più formati audio. La tecnica descritta qui c'è un approccio più specializzato, da usare solo se entrambi si applicano le seguenti condizioni:
- La sorgente audio compressa è uno stream di frame AAC contenuti nelle intestazioni ADTS.
- L'applicazione gestisce questo flusso. I dati non si trovano in una risorsa di rete il cui identificatore è un URI o all'interno di un file locale il cui identificatore è descrittore di un file.
Inizialmente, l'applicazione deve accodare un insieme di buffer pieni nella coda di buffer Android. Ogni buffer contiene uno o più frame ADTS AAC completi. Il callback della coda del buffer Android viene attivato dopo che ogni buffer è stato svuotato. Il gestore di callback deve riempire e aggiungere nuovamente il buffer, per poi tornare. L'applicazione non deve tenere traccia dei buffer codificati; il parametro callback include informazioni sufficienti per indicare il buffer che dovrebbe essere accodato successivamente. La fine dello stream è contrassegnata esplicitamente accodando un elemento EOS. Dopo la versione EOS, non sono più consentite le code.
Ti consigliamo di assicurarti di fornire ADTS AAC buffer, per evitare di esaurire il decoder. Questo può accadere, ad esempio, se la tua app restituisce il callback della coda del buffer Android senza accodare un altro buffer pieno. Il risultato dell'abbandono del decoder non è specificato.
Sotto tutti gli aspetti tranne che per l'origine dati, il metodo di decodifica in modalità flusso è lo stesso quella descritta nello strumento Decodifica dell'audio in PCM.
Nonostante la somiglianza tra i nomi, una coda di buffer Android non
equivale a una coda di buffer semplice di Android. Il decoder per lo streaming
utilizza entrambi i tipi di code di buffer: una coda di buffer Android per il
origine dati AAC e una coda di buffer semplice di Android per i dati PCM
un po' di tempo. Per ulteriori informazioni sull'API Simple buffer Queue di Android, consulta Android
semplice localizzatore di dati e interfaccia della coda di buffer.
Per ulteriori informazioni sull'API Android buffer Queue, consulta il file index.html
in
nella directory docs/Additional_library_docs/openmaxal/
nella directory radice di installazione.
Determinare il formato dei dati PCM decodificati mediante metadati
L'interfaccia SLMetadataExtractionItf
fa parte della specifica di riferimento.
Tuttavia, le chiavi dei metadati che indicano il formato effettivo dei dati PCM decodificati sono specifiche per
Android. Il file di intestazione OpenSLES_AndroidMetadata.h
definisce queste chiavi dei metadati.
Questo file di intestazione si trova nella radice di installazione, nella
Directory /sysroot/usr/include/SLES
.
Gli indici chiave dei metadati sono disponibili subito dopo
termina l'esecuzione del metodo Object::Realize()
. Tuttavia, i valori associati non sono
disponibili finché l'app non ha decodificato i primi dati codificati. Un buon
è eseguire una query per gli indici chiave nel thread principale dopo aver chiamato il metodo Object::Realize
e leggere i valori dei metadati in formato PCM nel semplice
gestore di callback della coda del buffer quando lo chiami per la prima volta. Consulta il
di codice di esempio
Pacchetto NDK per esempi sull'utilizzo di questa interfaccia.
I nomi delle chiavi dei metadati sono stabili, ma gli indici dei tasti non sono documentati. e sono soggetti a modifica. Un'applicazione non deve presupporre che gli indici sono permanenti tra diverse esecuzioni e non si devono dare per scontato che più istanze di oggetto condividono gli indici nella stessa esecuzione.
Dati in virgola mobile
Un'app eseguita su Android 5.0 (livello API 21) e versioni successive può fornire dati a un AudioPlayer in a precisione singola e con rappresentazione in virgola mobile.
Nel seguente codice di esempio, il metodo Engine::CreateAudioPlayer()
crea un lettore audio
che utilizza dati con rappresentazione in virgola mobile:
#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;