CirrusLogic / tinyhal

Configurable audio HAL for Android
Apache License 2.0
31 stars 17 forks source link

====================================================================== TINYHAL README Copyright (C) 2015, 2019 Cirrus Logic, Inc. and Cirrus Logic International Semiconductor Ltd. All rights reserved.

TinyHAL is an audio HAL for Android systems aimed at providing an improved basis for doing audio system integration in the Android application layer.

Traditionally the use-case logic has been hardcoded into HALs, which means that to edit use-cases or add new ones the code has to be changed and rebuilt. Typically any configuration files have been restricted to listing the ALSA control settings to be applied for a use-case but have no control over the actual use-case decisions.

A major aim of TinyHAL is for the configuration file to also control the logic of decision making about which use-cases to apply.

Key features include:

================== BUILD DEPENDENCIES

Requires:

TinyHAL can build against the upstream (mainline) versions of tinyalsa and tinycompress, or the versions shipped with Android. When building against the Android versions, see section below "BUILDING AGAINST OLD LIBRARY VERSIONS".

The upstream versions are available from: tinyalsa: https://github.com/tinyalsa tinycompress: http://git.alsa-project.org/?p=tinycompress.git;a=summary

========================================================= BUILDING AGAINST OLD LIBRARY VERSIONS (including Android)

The version of tinyalsa and tinycompress shipped with Android source is not usually the latest mainline so some functionality might be missing or different. By default TinyHAL builds against the upstream versions.

There are build flags that you can define to disable or modify features if you are building against an older version of a library:

TINYALSA_NO_ADD_NEW_CTRLS define if your version of tinyalsa does not have mixer_add_new_ctls()

TINYALSA_NO_CTL_GET_ID define if your version of tinyalsa does not have mixer_ctl_get_id()

TINYCOMPRESS_TSTAMP_IS_LONG define if your version of tinycompress takes an unsigned long* argument to compress_get_tstamp()

================= HOW TINYHAL WORKS

TinyHAL is based on the idea of audio streams connected to one or more "devices" (in Android terminology, that is speakers, microphones, or other transducers)


Pseudo-logic view

In general the control logic that TinyHAL uses to invoke ALSA settings works like this:

Stream opened=> if (stream defines "enable path" label) if ("global" device defines this label) invoke ALSA settings from "global" stream label

Stream connected to device=> if (device currently not in use) if (device defines "on" label) invoke ALSA settings from device "on" label

if (stream defines "enable path" label)
    if (device defines this label)
        invoke ALSA settings from device label

Stream custom use-case issued=> if (stream defines this use-case) if (use-case list includes the given value) invoke ALSA controls listed for this use-case value

Stream disconnected from device=> if (stream defines "disable path" label) if (device defines this label) invoke ALSA settings from device label

if (device not connected to any other streams)
    if (device defines "off" label)
        invoke ALSA settings from device "off" label

Stream closed=> if (deviced currently connected) disconnect each device

if (disable path label defined)
    if ("global" stream defines this label)
        invoke ALSA settings from "global" stream label

=========================== Auto-detecting the hardware

The simplest mode of auto-detection is to specify the ALSA card by name instead of by number. Tinyhal will search all /proc/asound/card*/id files for one that matches the given name. This abstracts from the actual card number, which isn't guaranteed to be the same between boots or across different devices using the same ALSA sound card.

A more sophisticated mechanism is to auto-select which configuration file to load. This is based on having a file or pseudo-file that contains as its first line a string identifying the hardware. TinyHAL doesn't care how this file is generated. A typical use is to point it at the pseudo-file /sys/class/sound/card0/id, which contains a single line giving the name of the audio card (as defined by the kernel audio card driver or codec driver.) But it could just as well be any readable pseudo-file, or a real file created on startup by the init script.

The first line from the given file is stripped of leading and trailing whitespace and then compared against a list of strings provided in the initial XML file that TinyHAL loads on startup. For each string an alternate XML filename is given.

If one of these strings matches, TinyHAL will abandon processing of the current XML file and instead start processing the alternate XML file. If none of the strings match, TinyHAL will continue to process the current XML file.

The syntax for this is shown in audio.example.xml (see the codec_probe block)