aboutsummaryrefslogtreecommitdiffstats

4a-hal-generic for 4A (AGL Advance Audio Architecture)


  • Object : Use a new api to centralize call to hals, automatically create hal api from configuration files
  • Status : Working, improvements still expected (master)
  • Author : Jonathan Aillet (jonathan.aillet@iot.bzh)
  • Date : July-2019

Cloning needed repositories for current version

Cloning 4a-hal-generic repository

git clone https://gerrit.automotivelinux.org/gerrit/src/4a-hal-generic

Cloning 4a-softmixer repository

git clone https://gerrit.automotivelinux.org/gerrit/src/4a-softmixer

Cloning 4a-alsacore repository

git clone https://gerrit.automotivelinux.org/gerrit/src/4a-alsa-core

Quick introduction to how hal are handled with 4a-hal-generic

  • At the startup of the 4a-hal binding, a new api called 4a-hal-manager will be created. This api is meant to provide verbs to list the loaded hals in your system and to know their current status.
  • The 4a-hal-manager api will also create a new hal for each audio configuration file found.\ These configuration files are handled by the controller for standard sections (metadata, ressources, ...), and by internals-hal code for hal specific sections (haldependencies, halmap, ...). If hal audio device(s) is/are found, the halmixer section is sent to the selected mixer (with haldependencies resolution added to the call).
  • External hal (e.g. another binding) can be registered/unregistered into 4a-hal-manager by calling it within the external hal. It must provide information such as api and uid at loading. It must also provide a subscription to an event that the 4a-hal-manager will use to know this hal status.\ To be used by the 4a-hl-api, external hals must provide same verbs and same response formats as internal hals (see verb descriptions above).\ WARNING : external hal handling is working but not fully implemented yet.

Preparation

Mandatory packages

  • Regular packages to execute application framework binder, and to load bindings with it (see Download Packages for Binder and Installing the Binder Daemon).

  • Requested packages to compile the binding :

  • agl-cmake-apps-module
  • json-c
  • libsystemd
  • afb-daemon
  • libmicrohttpd
  • uuid
  • alsa
  • afb-helpers
  • ctl-utilities
  • lua

If you use an SDK to cross-compile this binding for your target, all packages should already be found after sourcing the SDK.\ Alsa Loopback should also already be installed on your target.\ So, you're not concerned by the three next steps.\

Example command for installation on ubuntu (18.04)

sudo apt install agl-app-framework-binder-dev cmake agl-cmake-apps-module-bin libjson-c-dev agl-libmicrohttpd-devlibsdl2-dev liblua5.3-dev agl-libafb-helpers-dev agl-libappcontroller-dev

Example command for installation on fedora (29)

sudo dnf install agl-app-framework-binder-devel cmake agl-cmake-apps-module libjson-c-dev libmicrohttpd-devel uuid-devel alsa-lib-devel agl-libafb-helpers-devel agl-libappcontroller-devel lua-devel

Install Alsa Loopback (for native execution)

You must have snd-aloop enabled as a module in the running kernel.\ Run this command to be sure you have snd-aloop running on your target :

zcat /proc/config.gz | grep CONFIG_SND_ALOOP
CONFIG_SND_ALOOP=m

If it is not the case, run menuconfig and enable it under :

Device Drivers > Sound card support > Advanced Linux Sound Architecture > Generic sound device

sudo modprobe snd-aloop

Create a new hal json configuration corresponding to your audio hardware configuration

Information about audio json configuration files

  • All audio hardware configuration files are a json description of your audio devices.
  • Official hals are available in 4a-hal-configs repository.
  • You can find examples of these configurations in this repository 4a-hal-cfg-example folder.
  • Each configuration file found at startup will create a new hal with its own api.
  • If all mandatory haldependencies devices are found at hal api startup, halmixer section will automatically be sent to the selected mixer.\ However, haldependencies resolution will be added at mixer call. This is done for the mixer to be able to get the required audio device card number(s) without having to search for them.

What you need to set in this configuration file to make your audio work

  • For information about metadata, ressources, onload, controls, and events sections, please look at controller documentation
  • haldependencies section :\ This section is used to look for a/some specific audio devices(s). Each found device will be saved with its corresponding (ALSA) card number.\ halmap and halmixer sections (described above) use these dependencies to get the (ALSA) audio card number(s).\ haldependencies section can contain one dependency object, or an array of dependency objects. A dependency (one object) is resolved if only one audio card is found using specified search keys (it can be : cardNb, cardPath, cardId, cardShortName, cardLongName, cardDriver, cardMixerName, cardComponents, playbackDeviceId, playbackDeviceName, AnyOf).\ Most of these keys can have an array as a value. If so, it will behave as an XOR condition, and multiple searches will be performed to find an audio card. However, remember that a dependency is validated if only one audio card is found.\ Available keys :
  • uid key is the name of the dependency (it's a mandatory key). If the dependecy is resolved, halmap and halmixer sections will be able to use this key value to get corresponding (ALSA) card number.
  • class key is an optional key that defines the class of the dependency (If no class key is specified, dependency will be considered as a static class).\ Three classes are available :
    • mandatory class means that if the dependency is not resolved at hal startup, hal will stop and send back an error.
    • static class means that no error will be thrown if the dependency is not resolved at startup and the dependency will be considered as not available.\ If halmap or halmixer sections refer to a not available dependency, associated halmap/halmixer parts will be ignored without returning any errors.
    • dynamic class means that the dependency can be resolved dynamically (at startup or later). If the device is found while the binding is runing, a new resolution for halmap and halmixer sections will be triggered to use newly resolved dependency.\ dynamic class is NOT YET IMPLEMENTED, it is working like a static class for now.
  • cardNb key is an optional key used to search for an audio card using an (ALSA) card number (e.g. '1' in 'hw:1', '2' in 'hw:2'), value should be an integer or an array of integers.
  • cardPath key is an optional key used to search for an audio card using the audio card linux path (e.g. '/dev/snd/by-path/...'), value should be a string or an array of strings.
  • cardId key is an optional key used to search for an audio card using (ALSA) card id (e.g. 'Loopback' in 'hw:Loopback', 'PCH' in 'hw:PCH'), value should be a string or an array of strings.
  • cardShortName key is an optional key used to search for an audio card using (ALSA) card shortname (e.g. 'HDA Intel PCH', 'USB Audio Device'), value should be a string or an array of strings.
  • cardLongName key is an optional key used to search for an audio card using (ALSA) card longname (e.g. 'HDA Intel PCH at 0xdc248000 irq 159', 'C-Media Electronics Inc. USB Audio Device at usb-0000:00:14.0-2.1, full speed'), value should be a string or an array of strings.
  • cardDriver key is an optional key used to search for an audio card using (ALSA) card driver (e.g. 'HDA-Intel', 'USB-Audio'), value should be a string or an array of strings.
  • cardMixerName key is an optional key used to search for an audio card using (ALSA) card mixer name (e.g. 'Realtek ALC257', 'USB Mixer'), value should be a string or an array of strings.
  • cardComponents key is an optional key used to search for an audio card using (ALSA) card components (e.g. 'HDA:10ec0257,17aa225d,00100001 HDA:8086280b,80860101,00100000', 'USB0d8c:0014'), value should be a string or an array of strings.
  • playbackDeviceNb key is an optional key used to search for an audio card playback device using (ALSA) playback device number (e.g. '2' in 'hw:0,2', '4' in 'hw:1,4'), value should be an integer or an array of integers.
  • playbackDeviceId key is an optional key used to search for an audio card playback device using (ALSA) playback device id (e.g 'HDMI 1', 'HDMI 2'), value should be a string or an array of strings.
  • playbackDeviceName key is an optional key used to search for an audio card playback device using (ALSA) playback device name (e.g 'HDMI 1', 'HDMI 2'), value should be a string or an array of strings.
  • AnyOf key is an optional key that can contain an object of properties. An object allows the combination of several of the keys previously described, however, these keys cannot contain arrays as a value. Each property in the object will be considered as an input of an XOR condition.
  • halmap section :\ This section is meant to map ALSA device controls to application framework verbs.\ When you use ALSA, the control names are not standardized (i.e. control to get/set master volume are not named the same way for different audio cards).\ Using halmap, it is possbile to provide a standardized verb to get/set control values in each hal.\ Verbs created by halmap will also standardize control value ranges, i.e., a verb mapped to an integer ALSA control will only take a percentage as a value (conversion is done by 4a-hal binding).\ That means that you can abstract which audio device you are using by calling hal halmap verbs. Also, these verbs are meant to be used by higher level applications.\ It is possible to call another binding or a specific code (c or lua) using controller action fonctionnality when a control is get/set.\ In combination with create key in halmap, it is possible to create an ALSA audio control (not handled by ALSA driver) that will use controller action fonctionnality to perform an action when this ALSA audio control is set/get.\ halmap section can contain only one halmap object, or an array of halmap objects.\ Available keys :
  • uid key is a mandatory key to identify halmap controls related to a specific audio device.
  • info key is an optional key to provide information about halmap controls related to a specific audio device.
  • target key is a mandatory key that is used to get ALSA audio card number, this key must correspond to a hal-dependency uid key to be resolved.
  • controls section is one or several hal verbs that can be used to call ALSA controls (mandatory, can be an object or an array of objects).
    • uid key is a mandatory key to identify a halmap control.
    • info key is an optional key to provide information about a halmap control.
    • alsa section is a mandatory object that describes the ALSA control to map. If create key is provided in this section, it will create an ALSA control instead of searching for it.
    • name key is the name of the ALSA control to map. If it is an ALSA control creation, this name will be used for ALSA control registration (name key is optional for search, but mandatory for control creation).
    • numid key is an optional key that can only be used to search for the id of the control to map.
    • value key is an optional key to set a default value to the mapped control.
    • create section is an optional object that is used to describe ALSA control to create.
      • type key is a mandatory key to specify ALSA control type for ALSA control creation.
      • count key is a mandatory key to specify ALSA control number of value(s) for ALSA control creation.
      • minval key is a mandatory key to specify ALSA control minimum value for ALSA control creation.
      • maxval key is a mandatory key to specify ALSA control maximum value for ALSA control creation.
      • step key is a mandatory key to specify ALSA control value step for ALSA control creation.
    • action key is using controller action fonctionnality to specificy an action to call each time the ALSA control is set/get.
  • halmixer section is a section that is transfered to the mixer, for full description of this section, please look at mixer documentation.

N.B. : Examples of configuration files are provided in this repository 4a-hal-cfg-example directory to illustrate these functionalities.

Note about using a USB device

Dynamic handling of devices is not yet implemented.\ To have a working USB hal, you will need to modify the 'hal-4a-2ch-generic-usb.json' (in 4a-hal-cfg-example directory) to change key values in haldependencies section and path values in playbacks and captures sections.\ All these values should be replaced by the alsa information of your usb device.\ The usb device should also be plugged in at binder startup.

Compile (natively)

mkdir build
cd build
cmake -DWITHOUT_BLUEALSA=1 ..
make

Compile (using a sdk)

mkdir build
cd build
cmake ..
make

Using 4a-hal binder

Selection of the hal loaded at binding launch

Currently, the 4a-hal binding will try to create a hal api for each json audio configuration file found in the path specified with CONTROL_CONFIG_PATH environment variable (an audio configuration file should begin with 4a-hal-).\ If you don't want a hal to be launched with the binding, you can just rename/remove the corresponding audio json configuration file.

Be aware that every hal which finds its associated audio device will attach to the mixer. So, if you work on Renesas R-Car M3 and want to use an external usb audio device, be sure to rename the m3 configuration file to prevent it from being selected (on target, loaded hal configuration files are stored in /usr/libexec/agl/4a-hal/etc)

Run your binder from shell (native execution)

afb-daemon --name=afb-4a --workdir=$PATH_TO_4a_softmixer/build --binding=$PATH_TO_4a_alsa_core/build/alsa-binding/afb-alsa-4a.so --binding=$PATH_TO_4a_softmixer/build/package/lib/softmixer-binding.so --binding=$PATH_TO_4a_hal_generic/build/4a-hal/4a-hal.so --roothttp=$PATH_TO_4a_softmixer/build/package/htdocs --no-ldpaths --port=1234 --token= -vvv

4A service running on target

If 4A is available on your AGL version, 4A service should run at target startup, you can get its service name by using command

systemctl | grep agl-service-audio-4a

Using this service name, it is possible to get service logs (using journalctl -u $4A_SERVICE_NAME command), and start/stop/restart this service (using systemctl start $4A_SERVICE_NAME / systemctl stop $4A_SERVICE_NAME / systemctl restart $4A_SERVICE_NAME commands).

To update the cross-compiled binding, you can replace target remote '/usr/libexec/agl/4a-hal/lib/4a-hal.so' binding by your local './package/lib/4a-hal.so' binding using scp. This also should be done if you want to update 4a-hal plugin(s) (by transferring the corresponding plugin(s) on target).

Note that 4A 'systemd' service file is available at /var/local/lib/systemd/system/afm-service-agl-service-audio-4a*.

You can also have information about 4a service status using 4a-status command on your target.

Connect to 4A binder

Connect to 4A binder using afb-client-demo

afb-client-demo -H ws://localhost:1234/api?token=

N.B. : You can change the ip/port/token to connect to a remote binding

afb-client-demo -H ws://minnow03:31002/api?token='HELLO'

List ready hals

In the connected client command line, try to list the ready hal :

4a-hal-manager loaded

Output example :

ON-REPLY 1:4a-hal-manager/loaded: OK
{
  "response":[
    "4a-hal-csl-cm106-8ch-usb"
  ],
  "jtype":"afb-reply",
  "request":{
    "status":"success",
    "info":"Requested data"
  }
}

And now with more information :

4a-hal-manager loaded { "verbose" : true, "all" : true }

Output example :

ON-REPLY 1:4a-hal-manager/loaded: OK
{
  "response":[
    {
      "api":"4a-hal-csl-cm106-8ch-usb",
      "status":2,
      "internal":1,
      "uid":"CSL-CM106-USB-4A-HAL",
      "info":"4a hal for CSL CM106 8ch USB device",
      "author":"Jonathan Aillet",
      "version":"1.0",
      "date":"2018-06-09",
      "dependencies":[
        {
          "uid":"dependency-csl-cm106-8ch-usb",
          "cardNb":"hw:3"
        }
      ]
    }
  ],
  "jtype":"afb-reply",
  "request":{
    "status":"success",
    "info":"Requested data"
  }
}

Play with an 'internal' hal (described in a json configuration file)

Get hal information

Now, you can obtain information about your initialized internal hal :

$HAL_API_NAME info

Output example :

ON-REPLY 1:4a-hal-csl-cm106-8ch-usb/info: OK
{
  "response":{
    "streams":[
      {
        "name":"multimedia",
        "cardId":"hw:0,0,2"
      },
      {
        "name":"navigation",
        "cardId":"hw:0,0,3"
      },
      {
        "name":"emergency",
        "cardId":"hw:0,0,4"
      },
      {
        "name":"legacy",
        "cardId":"hw:0,0,0"
      },
      {
        "name":"radio_stream",
        "cardId":"hw:0,0,5"
      }
    ],
    "controls":[
      {
        "name":"agl-master-capture-volume",
        "info":"none",
        "target":"dependency-csl-cm106-8ch-usb",
        "available":true,
        "cardNb":3,
        "cardControlName":"Mic Capture Volume",
        "halmap-uid":"halmap-csl-cm106-8ch-usb",
        "halmap-info":"none"
      },
      {
        "name":"agl-master-playback-volume",
        "info":"none",
        "target":"dependency-csl-cm106-8ch-usb",
        "available":true,
        "cardNb":3,
        "cardControlName":"Speaker Playback Volume",
        "halmap-uid":"halmap-csl-cm106-8ch-usb",
        "halmap-info":"none"
      },
      {
        "name":"hal-ping",
        "info":"ping this hal through alsa",
        "target":"dependency-csl-cm106-8ch-usb",
        "available":true,
        "cardNb":3,
        "cardControlName":"Hal-Ping",
        "halmap-uid":"halmap-csl-cm106-8ch-usb",
        "halmap-info":"none"
      }
    ],
    "dependencies":[
      {
        "uid":"dependency-csl-cm106-8ch-usb",
        "class":"mandatory",
        "available":true,
        "cardNb":3,
        "cardId":"Device",
        "cardShortName":"USB Sound Device",
        "cardLongName":"USB Sound Device at usb-0000:00:14.0-1.1, full speed",
        "cardDriver":"USB-Audio",
        "cardMixerName":"USB Mixer",
        "cardComponents":"USB0d8c:0102",
        "extendedCardNb":"hw:3"
      }
    ]
  },
  "jtype":"afb-reply",
  "request":{
    "status":"success",
    "info":"Requested data"
  }
}

Firstly, you can get the audio device(s) used by your hal in dependencies section. That way you can have correspondance between uid and ALSA extendedCardNb.\ FYI, halmap and halmixer sections are able to dynamically get extendedCardNb by using dependency uid key value as target key value.

All the streams/controls listed are available as verbs of the hal api using name key value.

For streams, you can get the corresponding ALSA card id of the stream in cardId key value. The card id stream format is hw:X,X,X and can be used to play music.

For controls, you can find the targetted ALSA audio device using cardNb key and the targetted ALSA control name using cardControlName key.

Play some music into a stream (natively)

Use the previously obtained card id (hw:X,X,X) to play audio in the selected stream :

gst123 --audio-output alsa=$AUDIO_HW_ENDPOINT your_audio_file.mp3

Play some music into a stream (on target)

This will request to 4a-hl api for multimedia role endpoint and play music into it :

4a-play /usr/share/4a/media/Happy_MBB_75.ogg

Set stream volume during playing

During playing, try the stream commands to change/ramp volume

Now you can use your hal api to send commands to the mixer. This way, you can change/ramp volume :

$HAL_API_NAME $SELECTED_STREAM { "volume" : "+10" }
$HAL_API_NAME $SELECTED_STREAM { "volume" : 70 }
$HAL_API_NAME $SELECTED_STREAM { "ramp" : { "uid" : $RAMP_UID, "volume" : "-10" } }
$HAL_API_NAME $SELECTED_STREAM { "ramp" : { "uid" : $RAMP_UID, "volume" : 100 } }

Example :

4a-hal-csl-cm106-8ch-usb multimedia { "volume" : "+10" }

ON-REPLY 1:4a-hal-csl-cm106-8ch-usb/multimedia: OK
{
  "response":{
    "volnew":70,
    "volold":60
  },
  "jtype":"afb-reply",
  "request":{
    "status":"success",
    "info":"Action cm106-usb#multimedia correctly transferred to smixer without any error raised"
  }
}

N.B. : Values are normalized to a 0-100 range

all_streams verb

all_streams verb should also be available to send a command to all available streams :

4a-hal-csl-cm106-8ch-usb all-streams { "volume" : "+10" }

ON-REPLY 1:4a-hal-csl-cm106-8ch-usb/all-streams: OK
{
  "response":{
    "multimedia":{
      "volnew":80,
      "volold":70
    },
    "navigation":{
      "volnew":80,
      "volold":70
    },
    "emergency":{
      "volnew":70,
      "volold":60
    },
    "legacy":{
      "volnew":60,
      "volold":50
    },
    "radio_stream":{
      "volnew":80,
      "volold":70
    }
  },
  "jtype":"afb-reply",
  "request":{
    "status":"success",
    "info":"Actions correctly transferred to all streams without any error raised"
  }
}

Set control value during playing

If a hal control to set/get master volume on your audio device is defined, you can set value using :

$HAL_API_NAME $SELECTED_CONTROL { "value" : "60" }
$HAL_API_NAME $SELECTED_CONTROL { "value" : "-10" }

Example :

4a-hal-csl-cm106-8ch-usb agl-master-playback-volume { "value" : "-10" }

ON-REPLY 1:4a-hal-csl-cm106-8ch-usb/agl-master-playback-volume: OK
{
  "response":{
    "previous":[
      70,
      70,
      70,
      70,
      70,
      70,
      70,
      70
    ],
    "current":[
      60,
      60,
      60,
      60,
      60,
      60,
      60,
      60
    ]
  },
  "jtype":"afb-reply",
  "request":{
    "status":"success",
    "info":"Values correctly applied on alsa control"
  }
}

N.B. :

  • Values are normalized to a 0-100 range.
  • The number of values in the reponse depends on the number of values of the ALSA control.

Subscribe / Unsubscribe to 'internal' hal events

It is possible to register to hal events in order to be notified when an action is performed.\ Muliple events are provided by an 'internal' hal, such as events when a stream volume is set or events when a halmap alsa control is set.

In order to subscribe / unsubscribe to events, you need to call subscribe / unsubscribe verbs on the hal with a json to specify which event(s) you want to subscribe to.\ Here is the json format :

{
  "events " : "$STREAM_TO_SUBSCRIBE"
}

You can also subscribe / unsubscribe to multiple events in one call using this json format :

{
  "events " : [
    "$STREAM1_TO_SUBSCRIBE",
    "$STREAM2_TO_SUBSCRIBE",
    "$CONTROL1_TO_SUBSCRIBE",
    "$CONTROL2_TO_SUBSCRIBE"
  ]
}

Subscribe example :

4a-hal-csl-cm106-8ch-usb subscribe { "events" : [ "multimedia", "agl-master-playback-volume" ] }

ON-REPLY 1:4a-hal-csl-cm106-8ch-usb/subscribe: OK
{
  "response":2,
  "jtype":"afb-reply",
  "request":{
    "status":"success",
    "info":"Subscription succeed for all the 2 events requested"
  }
}

Received events examples :

ON-EVENT 4a-hal-csl-cm106-8ch-usb/multimedia:
{
  "event":"4a-hal-csl-cm106-8ch-usb/multimedia",
  "data":{
    "volnew":70,
    "volold":60
  },
  "jtype":"afb-event"
}
ON-EVENT 4a-hal-csl-cm106-8ch-usb/agl-master-playback-volume:
{
  "event":"4a-hal-csl-cm106-8ch-usb/agl-master-playback-volume",
  "data":[
    90,
    90,
    90,
    90,
    90,
    90,
    90,
    90
  ],
  "jtype":"afb-event"
}

Unsubscribe example :

4a-hal-csl-cm106-8ch-usb unsubscribe { "events" : [ "multimedia", "agl-master-playback-volume" ] }

ON-REPLY 4:4a-hal-csl-cm106-8ch-usb/unsubscribe: OK
{
  "response":2,
  "jtype":"afb-reply",
  "request":{
    "status":"success",
    "info":"Unsubscription succeed for all the 2 events requested"
  }
}

Provided 'internal' hal events

Here is the list of events provided by an internal hal :

  • Each stream listed by info verb provides an event.
  • Looking at 'Get hal information' section, we can see that 'multimedia', 'navigation', 'emergency', 'legacy', 'radio_stream' stream events are provided.
  • These events are generated when an event volume set is done using hals.
  • Each halmap listed by info verb provides an event.
  • Looking at 'Get hal information' section, we can see that 'agl-master-capture-volume', 'agl-master-playback-volume', 'hal-ping' halmap events are provided.
  • These events are generated when an halmap value set is done from anywhere (using alsa control commands, hals, etc.).
  • A 'stream-updates' event to be notified when a stream is added/removed (e.g. for bluetooth streams) to/from the hal.

Load an 'external' hal

Register your external hal

To load an external hal to 4a-hal-manager, you need to use an api call to load verb of 4a-hal-manager api from your external hal.\ Within this call you must provide a json description of your api, corresponding to the following description :

"metadata" : {
  "api" : "mandatory, string that is your hal binding api",
  "uid" : "mandatory, string that specifies your hal uid (usually the device used by your hal)",
  "info" : "optional, string that describes your hal",
  "author" : "optional, string that says who is the author of your hal",
  "version" : "optional, string that says what is the version of your hal",
  "date" : "optional, string that says the date of your hal",
}

Verbs to provide and json response formats recognized by 4a-hal-manager

subscribe/unsubscribe verb (mandatory)

Verbs used to subscribe to your 'external' hal events

Input Json formats :

{
  "events " : "$EVENT_TO_SUBSCRIBE"
}
{
  "events " : [
    "$EVENT1_TO_SUBSCRIBE",
    "$EVENT2_TO_SUBSCRIBE"
  ]
}
get-status verb (mandatory)

Verb to get your 'external' hal status.

At external hal loading, the 4a-hal-manager will call this verb to get you hal current status.

Here are the possible status (integer value) :

  • Unavailable = 0
  • Available = 1
  • Ready = 2

Response format :

{
  "response":2,
  "jtype":"afb-reply",
  "request":{
    "status":"success"
  }
}

Events to provide and json formats recognized by 4a-hal-manager

Provide a status event to share you hal status

Using you hal subscribe verb, 4a-hal-manager will subscribe to a status event to be notified each time you hal status changes.\ Within your hal, you must generate an event each time the status of your hal changes.

See 'get-status verb (mandatory)' section for more information about 'external' hal status event.

Verbs to provide and json response formats recognized by 4a-hl-api

Be aware that only subscribe/unsubscribe/info/streams verbs are mandatory, controls verbs can also be implemented but they are optional.

subscribe/unsubscribe verb (mandatory)

Verbs used to subscribe to your 'external' hal events

Input Json formats :

{
  "events " : "$EVENT_TO_SUBSCRIBE"
}
{
  "events " : [
    "$EVENT1_TO_SUBSCRIBE",
    "$EVENT2_TO_SUBSCRIBE"
  ]
}
info verb (mandatory)

Response format :

"response":{
  "streams":[
    {
      "name":"multimedia",
      "cardId":"hw:0,0,2"
    },
    {
      "name":"navigation",
      "cardId":"hw:0,0,3"
    },
    {
      "name":"emergency",
      "cardId":"hw:0,0,4"
    },
    {
      "name":"legacy",
      "cardId":"hw:0,0,0"
    },
    {
      "name":"radio_stream",
      "cardId":"hw:0,0,5"
    }
  ],
  "controls":[
    {
      "name":"agl-master-capture-volume",
      "info":"none",
      "target":"dependency-csl-cm106-8ch-usb",
      "available":true,
      "cardNb":3,
      "cardControlName":"Mic Capture Volume",
      "halmap-uid":"halmap-csl-cm106-8ch-usb",
      "halmap-info":"none"
    },
    {
      "name":"agl-master-playback-volume",
      "info":"none",
      "target":"dependency-csl-cm106-8ch-usb",
      "available":true,
      "cardNb":3,
      "cardControlName":"Speaker Playback Volume",
      "halmap-uid":"halmap-csl-cm106-8ch-usb",
      "halmap-info":"none"
    },
    {
      "name":"hal-ping",
      "info":"ping this hal through alsa",
      "target":"dependency-csl-cm106-8ch-usb",
      "available":true,
      "cardNb":3,
      "cardControlName":"Hal-Ping",
      "halmap-uid":"halmap-csl-cm106-8ch-usb",
      "halmap-info":"none"
    }
  ],
  "dependencies":[
    {
      "uid":"dependency-csl-cm106-8ch-usb",
      "class":"mandatory",
      "available":true,
      "cardNb":3,
      "cardId":"Device",
      "cardShortName":"USB Sound Device",
      "cardLongName":"USB Sound Device at usb-0000:00:14.0-1.1, full speed",
      "cardDriver":"USB-Audio",
      "cardMixerName":"USB Mixer",
      "cardComponents":"USB0d8c:0102",
      "extendedCardNb":"hw:3"
    }
  ]
}

Note that, for 4a-hl-api, only streams section is mandatory.

stream verbs (mandatory)

E.g. in some standard hals, available streams can be multimedia, navigation, or emergency.

Response format :

"response":{
  "volnew":70,
  "volold":60
}
all-streams verb (mandatory)

all-streams verb transfers an action to perform to all hal streams, so, its response is a concatenation of all stream reponses.

Response format :

"response":{
  "multimedia":{
    "volnew":80,
    "volold":70
  },
  "navigation":{
    "volnew":80,
    "volold":70
  },
  "emergency":{
    "volnew":70,
    "volold":60
  },
  "legacy":{
    "volnew":60,
    "volold":50
  },
  "radio_stream":{
    "volnew":80,
    "volold":70
  }
},
control verbs (optional)

Response format :

"response":{
  "previous":[
    70,
    70,
    70,
    70,
    70,
    70,
    70,
    70
  ],
  "current":[
    60,
    60,
    60,
    60,
    60,
    60,
    60,
    60
  ]
},

N.B. : The number of values sent back by verb depends on the number of ALSA control values.

Events to provide and json response formats recognized by 4a-hl-api

streams events (mandatory)

E.g. in some standard hals, available streams events can be multimedia, navigation, or emergency.

Event data format :

"data": {
  "volnew":70,
  "volold":60
}
controls events (optional)

Event data format :

"data":[
  90,
  90,
  90,
  90,
  90,
  90,
  90,
  90
],

N.B. : The number of values sent back by event depends on the number of ALSA control values.

Known issues

Fail to find json configuration files

When compiling and executing 4a-hal-generic and 4a-softmixer for a specific target using an sdk, some bindings won't find their json configuration files. This issue does not appear when compiling and deploying the 4a-hal-generic/4a-softmixer with yocto because a recipe is taking charge of these issues.

Nevertheless, to make the bindings find their configuration files, you can export the CONTROL_CONFIG_PATH environment variable to the directories where the configuration files are stored.

Example on a target where the 4a-hal and 4a-softmixer are deployed into /home/root/4a directory :

export CONTROL_CONFIG_PATH=/home/root/4a/smixer/etc:/home/root/4a/4a-hal/etc

What is missing in this version

  • Check that the external hals really exist at loading.
  • Handling external hal status events.
  • Generation of a '4a-hal-manager' events when a hal status changes.
  • Dynamic handling of USB devices.