OpenSL ES per Android

Questa pagina fornisce dettagli su come Implementazione di OpenSL da parte di NDK ESTM differisce dalle specifiche di riferimento per OpenSL ES 1.0.1. Quando utilizzi il codice campione potrebbe essere necessario modificarla per funzionare su Android.

Se non diversamente indicato, tutte le funzionalità sono disponibili su Android 2.3 (livello API 9) e versioni successive. Alcune funzionalità sono disponibili solo per Android 4.0 (livello API 14); vengono annotati.

Nota: Il Compatibility Definition Document (CDD) di Android elenca le risorse hardware e software i requisiti di un dispositivo Android compatibile. Consulta Compatibilità con Android per ulteriori informazioni sul programma di compatibilità generale. . CDD per il documento CDD effettivo.

OpenSL ES offre una classe C accessibile anche tramite C++. Espone funzionalità simili all'audio di queste API Java per Android:

Come per tutti gli Android Native Development Kit (NDK), lo scopo principale di OpenSL ES per Android ha lo scopo di facilitare l'implementazione delle librerie condivise da chiamare utilizzando il linguaggio nativo Java dell'interfaccia (JNI ). NDK non è destinato alla scrittura di applicazioni C/C++ pure. Tuttavia, OpenSL ES è un un'API completa e ci aspettiamo che tu sia in grado di soddisfare la maggior parte delle tue esigenze audio. utilizzando solo questa API, senza up-call al codice eseguito nel runtime Android.

Nota: Sebbene basata su OpenSL ES, l'API Android Native Audio (audio ad alte prestazioni) non è una implementazione conforme di qualsiasi profilo OpenSL ES 1.0.1 (gioco, musica o telefono). Questo perché Android non implementa tutte le funzionalità richieste da nessun profilo. Tutti i casi noti in cui Android si comporta in modo diverso rispetto alle specifiche descritte nel Pagina Estensioni Android.

Funzionalità ereditate dalla specifica di riferimento

L'implementazione Android NDK di OpenSL ES eredita gran parte dell'insieme di funzionalità la specifica di riferimento, con alcune limitazioni.

Punti di ingresso globali

OpenSL ES per Android supporta tutti gli entry point globali nella specifica Android. Questi punti di ingresso includono:

  • slCreateEngine
  • slQueryNumSupportedEngineInterfaces
  • slQuerySupportedEngineInterfaces

Oggetti e interfacce

La tabella seguente mostra gli oggetti e le interfacce di cui l'implementazione Android NDK OpenSL ES supporta. Se nella cella compare , la funzione è disponibile in questa implementazione.

Supporto di Android NDK per oggetti e interfacce.

Funzionalità Lettore audio Registratore audio Motore Mix di output
Amplificazione dei bassi No No
Coda buffer No No No
Localizzatore dati coda buffer Sì: origine No No No
Gestione dinamica dell'interfaccia
Invio dell'effetto No No No
Motore No No No
Riverbero ambientale No No No
Equalizzatore No No
Localizzatore dati dispositivo I/O No Sì: origine No No
Estrazione di metadati Sì: decodifica in PCM No No No
Disattiva l'audio in solitaria No No No
Oggetto
Localizzatore mix output Sì: sink No No No
Riproduci No No No
Velocità di riproduzione No No No
Stato precaricamento No No No
Riverbero preimpostato No No No
Registra No No No
Cerca No No No
Localizzatore dati URI Sì: origine No No No
Virtualizzatore No No
Volume No No No

La sezione successiva illustra le limitazioni di alcune di queste funzionalità.

Limitazioni

Alle caratteristiche nella tabella 1 si applicano alcune limitazioni. Queste limitazioni per rappresentare le differenze rispetto alla specifica di riferimento. Il resto di questa sezione fornisce informazioni su queste differenze.

Gestione dinamica dell'interfaccia

OpenSL ES per Android non supporta RemoveInterface o ResumeInterface.

Combinazioni di effetti: riverbero di ambiente e riverbero preimpostato

Non puoi avere sia il riverbero ambientale sia il riverbero preimpostato nello stesso mix di output.

La piattaforma potrebbe ignorare le richieste di effetti se stima che Il carico della CPU sarebbe troppo elevato.

Invio dell'effetto

SetSendLevel() supporta un singolo livello di invio per ciascun lettore audio.

Riverbero ambientale

Il riverbero ambientale non supporta reflectionsDelay, reflectionsLevel o reverbDelay campi di lo struct SLEnvironmentalReverbSettings.

Formato dei dati MIME

Puoi utilizzare il formato dei dati MIME solo con il localizzatore dei dati URI e solo per un servizio audio un player. Non puoi utilizzare questo formato dei dati per un registratore audio.

L'implementazione Android di OpenSL ES richiede l'inizializzazione di mimeType in NULL o in una stringa UTF-8 valida. Devi inoltre inizializzare containerType in un valore valido. In assenza di altre considerazioni, come la portabilità implementazioni o formati dei contenuti che un'app non può identificare tramite l'intestazione ti consigliamo imposta mimeType su NULL e containerType a SL_CONTAINERTYPE_UNSPECIFIED.

OpenSL ES per Android supporta i seguenti formati audio, a condizione che sono supportate anche dalla piattaforma Android:

  • WAV PCM.
  • WAV alaw.
  • WAV.
  • MP3 Ogg Vorbis.
  • LC AAC
  • HE-AACv1 (AAC+).
  • HE-AACv2 (AAC+ migliorato).
  • AMG
  • FLAC.

Nota: Per un elenco dei formati audio supportati da Android, vedi Formati multimediali supportati.

Le seguenti limitazioni si applicano alla gestione di questi e di altri formati in questa implementazione di OpenSL ES:

  • AAC devono trovarsi all'interno di un contenitore MP4 o ADTS.
  • OpenSL ES per Android non supporta MIDI
  • WMA non fa parte di AOSP e noi non ha verificato la compatibilità con OpenSL ES per Android.
  • L'implementazione Android NDK di OpenSL ES non supporta la riproduzione di contenuti DRM o criptati. Per riprodurre contenuti audio protetti, devi: decriptarlo nell'applicazione prima di giocare, facendo in modo che l'app applichi qualsiasi DRM limitazioni.

OpenSL ES per Android non supporta i seguenti metodi per la manipolazione di oggetti:

  • Resume()
  • RegisterCallback()
  • AbortAsyncOperation()
  • SetPriority()
  • GetPriority()
  • SetLossOfControlInterfaces()

Formato dei dati PCM

PCM è l'unico formato dati che puoi utilizzare con le code del buffer. PCM supportati configurazioni di riproduzione hanno le seguenti caratteristiche:

  • 8-bit non firmato o 16-bit firmato.
  • Mono o stereo.
  • Ordinamento dei byte Little-endian.
  • Frequenze di campionamento di:
    • 8000 Hz.
    • 11.025 Hz.
    • 12.000 Hz.
    • 16.000 Hz.
    • 22.050 Hz.
    • 24.000 Hz.
    • 32.000 Hz.
    • 44.100 Hz.
    • 48.000 Hz.

Le configurazioni supportate da OpenSL ES per Android per la registrazione sono: a seconda del dispositivo. di solito, 16.000 Hz mono/16-bit con segno è disponibile indipendentemente dal dispositivo.

Il valore del campo samplesPerSec è in unità di milliHz, nonostante il messaggio fuorviante nome. Per evitare di utilizzare per errore un valore errato, ti consigliamo di inizializzare questo campo utilizzando una delle costanti simboliche definite per questo scopo, ad esempio SL_SAMPLINGRATE_44_1.

Supporto per Android 5.0 (livello API 21) e versioni successive dati con rappresentazione in virgola mobile.

Velocità di riproduzione

Una frequenza di riproduzione OpenSL ES indica la velocità con cui una presenta i dati, espressi in millesimi di velocità normale, o per mille. Ad esempio: una velocità di riproduzione di 1.000 per mille è 1.000/1.000, o velocità normale. Un intervallo di frequenza è un intervallo chiuso che esprime una serie di possibili velocità di riproduzione.

Il supporto degli intervalli di velocità di riproduzione e di altre funzionalità può variare a seconda sulla versione e sull'implementazione della piattaforma. La tua app può determinare queste funzionalità in fase di runtime usando PlaybackRate::GetRateRange() o PlaybackRate::GetCapabilitiesOfRate() per inviare una query al dispositivo.

In genere un dispositivo supporta lo stesso intervallo di frequenza per un'origine dati in formato PCM e un tasso di unità. intervallo compreso tra 1000 per mille e 1000 per mille per gli altri formati; cioè l'intervallo di tasso di unità un singolo valore.

Registra

OpenSL ES per Android non supporta SL_RECORDEVENT_HEADATLIMIT o SL_RECORDEVENT_HEADMOVING eventi.

Cerca

Il metodo SetLoop() consente il loop dell'intero file. Per attivare il loop, imposta il parametro startPos su 0 e il parametro endPos a SL_TIME_UNKNOWN.

Localizzatore dati coda buffer

Un lettore audio o un registratore audio con un localizzatore di dati per una coda del buffer supporta solo il formato dati PCM.

Localizzatore dati dispositivo I/O

OpenSL ES per Android supporta l'utilizzo di un data locator di dispositivi I/O se disponi specificato il locator come origine dati per Engine::CreateAudioRecorder(). Inizializza il localizzatore dei dati del dispositivo utilizzando i valori contenuti nel seguente snippet di codice:

SLDataLocator_IODevice loc_dev =
  {SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT,
  SL_DEFAULTDEVICEID_AUDIOINPUT, NULL};

Localizzatore dati URI

OpenSL ES per Android può utilizzare solo il localizzatore di dati URI con il formato dei dati MIME, e solo per un audio player. Non puoi utilizzare un localizzatore di dati URI per un registratore audio. L'URI può solo usano gli schemi http: e file:. Altri schemi, ad esempio https:, ftp:, oppure Non sono consentiti content:.

Non abbiamo verificato il supporto di rtsp: con audio sulla piattaforma Android.

Strutture di dati

Android supporta le seguenti strutture di dati OpenSL ES 1.0.1:

  • SLDataFormat_MIME
  • SLDataFormat_PCM
  • SLDataLocator_BufferQueue
  • SLDataLocator_IODevice
  • SLDataLocator_OutputMix
  • SLDataLocator_URI
  • SLDataSink
  • SLDataSource
  • SLEngineOption
  • SLEnvironmentalReverbSettings
  • SLInterfaceID

Configurazione della piattaforma

OpenSL ES per Android è progettato per applicazioni multi-thread ed è sicuro per i thread. Supporta motore singolo per applicazione e fino a 32 oggetti per motore. La memoria e la CPU del dispositivo disponibili potrebbero per limitare ulteriormente il numero utilizzabile di oggetti.

Queste opzioni del motore sono riconosciute, ma vengono ignorate da slCreateEngine:

  • SL_ENGINEOPTION_THREADSAFE
  • SL_ENGINEOPTION_LOSSOFCONTROL

OpenMAX AL e OpenSL ES possono essere utilizzati insieme nella stessa applicazione. In questo caso, un singolo oggetto motore condiviso internamente e il limite di 32 oggetti è condiviso tra OpenMAX AL e OpenSL ES. L'applicazione deve creare entrambi i motori, utilizzarli e infine distruggere entrambi i motori. L'implementazione mantiene un conteggio dei riferimenti sul motore condiviso in modo che viene eliminato correttamente durante la seconda operazione di eliminazione.

Note di programmazione

Note di programmazione di OpenSL ES fornisce informazioni supplementari per garantire la corretta implementazione di OpenSL ES.

Nota: Per praticità, abbiamo incluso una copia della specifica OpenSL ES 1.0.1 con l'NDK in docs/opensles/OpenSL_ES_Specification_1.0.1.pdf.

Problemi relativi alla piattaforma

Questa sezione descrive i problemi noti nella release iniziale della piattaforma che supporta queste API.

Gestione dinamica dell'interfaccia

DynamicInterfaceManagement::AddInterface non funziona. Specifica invece l'interfaccia in l'array che viene passato a Create(), come mostrato nel codice di esempio per il riverbero ambientale.

Pianifica le versioni future di OpenSL ES

Le API audio ad alte prestazioni di Android si basano su Khronos Group OpenSL ES 1.0.1. Khronos ha rilasciato una versione rivista 1.1 dello standard. La versione rivista include nuove funzionalità, chiarimenti, correzioni di errori tipografici e alcune incompatibilità. La maggior parte delle incompatibilità previste è relativamente minore o aree di OpenSL ES non supportate da Android.

Un'applicazione sviluppati con questa versione dovrebbero funzionare su versioni future della piattaforma Android, a condizione seguire le linee guida descritte nella sezione Piano d'azione per i file compatibilità di seguito.

Nota: La compatibilità con fonti future non è un obiettivo. Vale a dire che se esegui l'upgrade a una versione più recente dell'NDK, potresti dover modificare il codice sorgente dell'applicazione per renderlo conforme alla nuova API. Ci aspettiamo che la maggior parte tali cambiamenti saranno di lieve entità; vedi i dettagli di seguito.

Pianifica la compatibilità binaria

Per migliorare la futura compatibilità binaria, ti consigliamo di seguire queste linee guida per la tua applicazione:

  • Utilizza solo il sottoinsieme documentato di funzionalità supportate da Android di OpenSL ES 1.0.1.
  • Non dipendere da un particolare codice risultato per un'operazione non riuscita. preparati a trattare con un codice risultato diverso.
  • I gestori di callback delle applicazioni generalmente vengono eseguiti in un contesto limitato. Dovrebbero essere scritti di svolgere il proprio lavoro rapidamente per poi tornare il prima possibile. Non eseguire operazioni complesse all'interno di un gestore di callback. Ad esempio, all'interno di un callback di completamento di una coda di buffer, puoi accoda un altro buffer, ma non crea un lettore audio.
  • I gestori dei callback devono essere preparati per essere chiamati più o meno spesso, per ricevere tipi di eventi aggiuntivi e dovrebbero ignorare quelli che non riconoscono. Callback che sono configurati con una maschera di eventi composta da tipi di eventi attivati devono essere preparati per essere chiamati con più bit di tipi di evento impostati contemporaneamente. Utilizza "&" di testare ogni parte dell'evento invece che una custodia per l'interruttore.
  • Utilizza lo stato di precaricamento e i callback come indicazioni generali dell'avanzamento, ma non dipendono sequenze di callback o livelli di riempimento hardcoded specifici. Significato del riempimento dello stato di precaricamento e il comportamento per gli errori rilevati durante il precaricamento potrebbe cambiare.

Nota: consulta la sezione Comportamento della coda del buffer di seguito per ulteriori dettagli.

Pianifica la compatibilità dell'origine

Come già detto, sono previste incompatibilità del codice sorgente nella prossima versione di OpenSL ES da Gruppo Khronos. Le possibili aree di cambiamento includono:

  • Si prevede che l'interfaccia della coda del buffer presenti modifiche significative, soprattutto nelle aree di BufferQueue::Enqueue, l'elenco dei parametri per slBufferQueueCallback e nome del campo SLBufferQueueState.playIndex. Ti consigliamo di utilizzare il codice dell'applicazione Android li inserisce nel buffer. Nell'esempio: fornito con l'NDK, abbiamo usato semplici code di buffer di Android per la riproduzione per questo motivo. Usiamo anche una semplice coda di buffer di Android per la registrazione e la decodifica in PCM, ma è perché OpenSL ES 1.0.1 standard non supporta il record o la decodifica in una coda di buffer un lavandino.
  • Ci sarà un'aggiunta di const ai parametri di input passati per riferimento e a SLchar * campi struct utilizzati come valori di input. Non dovrebbe essere necessario modificare il tuo codice.
  • Sarà disponibile una sostituzione dei tipi non firmati per alcuni parametri attualmente firmati. Potrebbe essere necessario modificare un tipo di parametro da SLint32 a SLuint32 o simile oppure aggiungi una trasmissione.
  • Equalizer::GetPresetName copia la stringa nella memoria dell'applicazione anziché restituire un puntatore alla memoria di implementazione. Si tratta di un cambiamento significativo, quindi ti consigliamo di evitare di chiamare questo metodo o isolarne l'uso.
  • Nei tipi di struct saranno presenti campi aggiuntivi. Per i parametri di output, questi nuovi campi può essere ignorato, ma per i parametri di input dovrà essere inizializzato i nuovi campi. Per fortuna tutti questi campi dovrebbero trovarsi in aree non supportate da Android.
  • Interfaccia GUID cambieranno. Fai riferimento alle interfacce in base al nome simbolico anziché al GUID per evitare un la dipendenza.
  • Il valore di SLchar cambierà da unsigned char a char. Ciò influisce principalmente il localizzatore dei dati URI e il formato dei dati MIME.
  • SLDataFormat_MIME.mimeType sarà rinominata pMimeType e SLDataLocator_URI.URI verrà rinominato in pURI. Ti consigliamo di inizializzare le strutture dati SLDataFormat_MIME e SLDataLocator_URI utilizzando un elenco di valori separati da virgole, racchiusi da parentesi graffe, anziché in base al nome del campo, per isolare il codice da questa modifica. Questa tecnica viene utilizzata nel codice di esempio.
  • SL_DATAFORMAT_PCM non consente all'applicazione di specificare la rappresentazione di come numeri interi firmati, numeri interi senza segno o numeri in virgola mobile. L'implementazione di Android presuppone che i dati a 8 bit siano un numero intero senza segno e che a 16 bit sia un numero intero con segno. Inoltre, il campo samplesPerSec è un termine errato, poiché le unità effettive sono milliHz. Questi problemi sono previsti che verrà trattata nella prossima versione OpenSL ES, che introdurrà una nuova estensione di dati PCM che consenta all'applicazione di specificare esplicitamente la rappresentazione e di correggere il nome del campo. Poiché si tratta di un nuovo formato dati e l'attuale formato dei dati PCM continuerà a essere disponibile (sebbene deprecato), non dovrebbe richiedere modifiche immediate al codice.