Collega un dispositivo di input nell'AAOS

Per riprodurre l'audio su Android puoi utilizzare questi meccanismi:

Ogni meccanismo consente di riprodurre l'audio in Android. Per la riproduzione radio o da dispositivi di input, queste opzioni potrebbero non essere sufficienti, anche se ciascuna potrebbe essere accoppiata con l'acquisizione audio o la classe MediaRecorder per acquisire prima l'audio e poi riprodurlo da Android. Per le app di sistema in particolare, le seguenti informazioni possono essere utilizzate per collegare un dispositivo di input a un mixer di output in AAOS.

Lettore HwAudioSource

HwAudioSource collega il dispositivo di sorgente audio direttamente a un mixer Android.

Motivazioni

Quando utilizzi un patch audio da dispositivo a dispositivo o hardware con Android, potrebbero verificarsi diverse limitazioni. Ogni opzione non è in grado di ricevere eventi chiave multimediali come PLAY, PAUSE e STOP e, poiché aggira lo stack audio di Android, ciascuna richiede hardware per mixare la patch con altro audio di Android.

Utilizzare HwAudioSource

HwAudioSource è un nuovo tipo di player progettato come patch software. In questo modo, le app che utilizzano questo player possono ricevere eventi chiave multimediali e lo stream di output da mixare e instradare da Android.

mHwAudioSource = new HwAudioSource.Builder()
                .setAudioDeviceInfo(AudioDeviceInfo: info)
                .setAudioAttributes(new AudioAttributes.Builder()
                        .setUsage(AudioAttributes.USAGE_MEDIA)
                        .build())
                .build();
mHwAudioSource.play();
mHwAudioSource.stop();

Modifiche all'HAL audio

Con questo nuovo player, tieni conto di queste aspettative per l'HAL audio. Ad esempio, device/generic/car/emulator/audio/driver/audio_hw.c.

  • adev_create_audio_patch si aspetta che la richiesta stabilisca un patch audio da un dispositivo a un mixer.

  • adev_open_input_stream prevede che audio_source sia AUDIO_SOURCE_FM_TUNER.

  • in_read riempie il buffer audio con i dati audio della radio trasmessa.

Ti consigliamo di configurare un dispositivo di sintonizzazione di tipo AUDIO_DEVICE_IN_FM_TUNER in audio_policy_configuration.xml:

<devicePort
    tagName="Tuner_source"
    type="AUDIO_DEVICE_IN_FM_TUNER"
    role="source"
    address="tuner0">
    <profile
        name=""
        format="AUDIO_FORMAT_PCM_16_BIT"
        samplingRates="48000"
        channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
</devicePort>

Con questa configurazione del dispositivo, puoi facilitare la ricerca del dispositivo di input radio FM utilizzando AudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS in combinazione con AudioDeviceInfo.TYPE_FM_TUNER.

Creare patch audio

Puoi creare una patch audio tra due porte audio, una porta di mix o una porta del dispositivo. In genere, un patch audio dalla porta di mix alla porta del dispositivo è per la riproduzione, mentre la direzione inversa è per l'acquisizione.

Ad esempio, un patch audio che instrada i campioni audio dalla sorgente FM_TUNER direttamente all'obiettivo multimediale aggira il mixer software. Devi quindi utilizzare un mixer hardware per mixare i sample audio di Android e FM_TUNER per la destinazione. Quando crei una patch audio direttamente dall'origine FM_TUNER all'output media:

  • Il controllo del volume si applica al sink multimediale e dovrebbe influire sia sull'audio di Android sia su quello di FM_TUNER.

  • Gli utenti possono passare dall'audio di Android a quello di FM_TUNER tramite un semplice cambio di app (non è necessaria la scelta esplicita della sorgente multimediale).

Le implementazioni per i veicoli potrebbero anche richiedere la creazione di un patch audio tra due porte del dispositivo. Per farlo, devi prima dichiarare le porte del dispositivo e i possibili percorsi in audio_policy_configuration.xml e poi associare le mixport alle porte del dispositivo.

Configurazione di esempio

Consulta questa configurazione di esempio, device/generic/car/emulator/audio/audio_policy_configuration.xml.

<audioPolicyConfiguration>
    <modules>
        <module name="primary" halVersion="3.0">
            <attachedDevices>
                <item>bus0_media_out</item>
                <item>bus1_audio_patch_test_in</item>
            </attachedDevices>
            <mixPorts>
                <mixPort name="mixport_bus0_media_out" role="source"
                        flags="AUDIO_OUTPUT_FLAG_PRIMARY">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                            samplingRates="48000"
                            channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                </mixPort>
                <mixPort name="mixport_audio_patch_in" role="sink">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                           samplingRates="48000"
                           channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
                </mixPort>
            </mixPorts>
            <devicePorts>
                <devicePort tagName="bus0_media_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
                        address="bus0_media_out">
                    <profile balance="" format="AUDIO_FORMAT_PCM_16_BIT"
                            samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                    <gains>
                        <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
                                minValueMB="-8400" maxValueMB="4000" defaultValueMB="0" stepValueMB="100"/>
                    </gains>
                </devicePort>
                <devicePort tagName="bus1_audio_patch_test_in" type="AUDIO_DEVICE_IN_BUS" role="source"
                        address="bus1_audio_patch_test_in">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                            samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
                    <gains>
                        <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
                                minValueMB="-8400" maxValueMB="4000" defaultValueMB="0" stepValueMB="100"/>
                    </gains>
                </devicePort>
            </devicePorts>
            <routes>
                <route type="mix" sink="bus0_media_out" sources="mixport_bus0_media_out,bus1_audio_patch_test_in"/>
                <route type="mix" sink="mixport_audio_patch_in" sources="bus1_audio_patch_test_in"/>
            </routes>
        </module>
    </modules>
</audioPolicyConfiguration>

API Audio Driver

Puoi utilizzare getExternalSources() per recuperare un elenco di sorgenti disponibili (identificate dall'indirizzo), quindi creare patch audio tra queste sorgenti e le porte di destinazione in base agli utilizzi audio. I punti di contatto corrispondenti nell'HAL audio vengono visualizzati in IDevice.hal:

Interface IDevice {
...
/
*   Creates an audio patch between several source and sink ports.  The handle
*   is allocated by the HAL and must be unique for this audio HAL module.
*
*   @param sources patch sources.
*   @param sinks patch sinks.
*   @return retval operation completion status.
*   @return patch created patch handle.
*/
createAudioPatch(vec<AudioPortConfig> sources, vec<AudioPortConfig> sinks)
       generates (Result retval, AudioPatchHandle patch);

*   Release an audio patch.
*
*   @param patch patch handle.
*   @return retval operation completion status.
*/
releaseAudioPatch(AudioPatchHandle patch) generates (Result retval);
...
}

Sintonizzatore radio

Quando crei un'app radio, ti consigliamo di utilizzare HwAudioSource perché gestisce sia la creazione della patch sia una sessione multimediale per gestire gli eventi relativi alle chiavi multimediali. È possibile creare più sorgenti audio per gli stessi attributi di fonte e audio. È possibile averne uno per l'uso regolare della radio e un altro per gli annunci di traffico.

Se registri FM_TUNER, in Android 11 l'autorizzazione per farlo è stata modificata in android.permission.CAPTURE_AUDIO_OUTPUT. Non viene più eseguito il controllo dell'autorizzazione OP_RECORD_AUDIO, che si applica solo ai microfoni. Ciò non dovrebbe influire sulle app, poiché FM_TUNER richiede già l'autorizzazione SYSTEM_API per l'accesso.

Per informazioni dettagliate sulla creazione di un'app radio, consulta Implementare la radio.