summaryrefslogtreecommitdiffstats
path: root/docs/4_APIs_and_Services/4.6_Audio_Framework
diff options
context:
space:
mode:
Diffstat (limited to 'docs/4_APIs_and_Services/4.6_Audio_Framework')
-rw-r--r--docs/4_APIs_and_Services/4.6_Audio_Framework/4.6.1_Overview.md167
-rw-r--r--docs/4_APIs_and_Services/4.6_Audio_Framework/4.6.2_Session_Manager_Configuration.md450
-rw-r--r--docs/4_APIs_and_Services/4.6_Audio_Framework/4.6.3_Bluetooth.md122
3 files changed, 739 insertions, 0 deletions
diff --git a/docs/4_APIs_and_Services/4.6_Audio_Framework/4.6.1_Overview.md b/docs/4_APIs_and_Services/4.6_Audio_Framework/4.6.1_Overview.md
new file mode 100644
index 0000000..672f6da
--- /dev/null
+++ b/docs/4_APIs_and_Services/4.6_Audio_Framework/4.6.1_Overview.md
@@ -0,0 +1,167 @@
+---
+edit_link: ''
+title: Overview
+origin_url: >-
+ https://raw.githubusercontent.com/automotive-grade-linux/docs-sources/master/docs/audio/pipewire.md
+---
+
+<!-- WARNING: This file is generated by fetch_docs.js using /home/boron/Documents/AGL/docs-webtemplate/site/_data/tocs/apis_services/master/audio-developer-guides-audio-book.yml -->
+
+# PipeWire Audio System Overview
+
+## Overview
+
+AGL uses the PipeWire daemon service to provide audio playback and capture
+capabilities. PipeWire is accompanied by a secondary service, WirePlumber
+(also referred to as the *session manager*), which provides policy management,
+device discovery, configuration and more.
+
+Applications can connect to the PipeWire service through its UNIX socket, by
+using the *libpipewire* library as a front-end to that socket.
+
+## Configuration
+
+The Audio System's configuration is mainly done in the session manager.
+The session manager is the service that dictates policy, therefore this is
+the place to configure options such as device properties, device priorities
+and application linking policy.
+
+An extensive listing of configuration options for the session manager,
+WirePlumber, is available in the next chapter,
+[Session Manager Configuration](./wireplumber_configuration.md)
+
+### wireplumber-cli
+
+WirePlumber supports runtime configuration of devices, through the
+`wireplumber-cli` tool. This tool supports the following sub-commands:
+
+* `wireplumber-cli ls-endpoints`:
+ This lists all the known audio endpoints, including devices and applications
+ that are streaming. In front of the devices, there is a `*` (star) character
+ on the "default" device, i.e. the device that is chosen by default to link
+ applications to. The volume and mute status of the devices is also shown.
+* `wireplumber-cli set-default [id]`:
+ Changes the default endpoint of a specific category (capture or playback,
+ determined automatically by the endpoint's type)
+ and sets it to be the endpoint with the specified `[id]`. The id is the
+ number shown in front of each endpoint's name in `ls-endpoints`.
+* `wireplumber-cli set-volume [id] [vol]`:
+ Sets the volume of `[id]` to `[vol]`. `[vol]` must be a floating point
+ number between 0.0 (0%) and 1.0 (100%).
+* `wireplumber-cli device-node-props`:
+ Lists all the properties of the device nodes, useful for writing `.endpoint`
+ configuration files, as discussed in the _Session Management Configuration_
+ chapter.
+
+Due to a system limitation, before running this tool on the command line,
+you need to export the `XDG_RUNTIME_DIR` environment variable, like this:
+
+```
+export XDG_RUNTIME_DIR=/run/user/1001
+```
+
+### pipewire.conf
+
+PipeWire also ships with **/etc/pipewire/pipewire.conf**, which can be used to
+configure which pipewire modules are being loaded in the PipeWire deamon. You
+should normally not need to modify anything there, unless you understand what
+you are doing.
+
+## APIs
+
+### Native API - libpipewire
+
+The main entry point for applications to access the audio system is the API
+offered by *libpipewire*. The functionality offered by *libpipewire* is vast
+and it is beyond the scope of this document to describe it all.
+
+For playback and capture, applications should use *struct pw_stream* and its
+associated methods. There are usage examples for it in the PipeWire
+[source code](https://gitlab.freedesktop.org/pipewire/pipewire).
+
+### Native API - GStreamer (Recommended)
+
+For convenience, applications that use GStreamer can use the PipeWire GStreamer
+elements to plug the functionality offered by *struct pw_stream* directly in
+the GStreamer pipeline. These elements are called *pwaudiosrc* and *pwaudiosink*
+
+Example:
+```
+gst-launch-1.0 audiotestsrc ! pwaudiosink
+```
+
+Through these elements, it is possible to specify the application role by setting
+it in the *stream-properties* property of the element, as shown below:
+
+```
+gst-launch-1.0 audiotestsrc ! pwaudiosink stream-properties=p,media.role=Multimedia
+```
+
+or, in the C API:
+
+```
+gst_util_set_object_arg (sink, "stream-properties", "p,media.role=Multimedia");
+```
+
+When using these GStreamer elements, applications **should** handle the
+**GST_MESSAGE_REQUEST_STATE** message on the bus and change their state accordingly.
+This message will be sent when the *session manager* requests a change in the state
+due to a higher priority stream taking over.
+
+### ALSA Compatibility
+
+AGL offers a virtual ALSA device that redirects audio to PipeWire
+through an ALSA PCM plugin. This device is the default one, so unless you
+explicitly specify a device in your ALSA client application, audio will go
+through PipeWire instead.
+
+This mode has limitations, however.
+* There is no way to specify the role of the application. WirePlumber will
+always assume it is a "Multimedia" application
+* There is no way for the application to be notified when another stream
+takes over. When this happens, the audio clock will simply stop progressing and
+the ALSA API will likely block.
+
+### Audiomixer service
+
+See the separate
+[agl-service-audiomixer](https://git.automotivelinux.org/apps/agl-service-audiomixer/about/)
+documentation.
+
+## Runtime mechanics
+
+The PipeWire service is activated on demand, via systemd socket activation.
+The WirePlumber service is always started and stopped together with the PipeWire
+service.
+
+If you wish to manually start/stop/restart the service, you can do so by using
+*systemctl*:
+```
+systemctl start/stop/restart pipewire@1001.service
+```
+
+## Debugging
+
+When something is wrong with the audio setup, it is useful to know how to debug
+it...
+
+### PipeWire & WirePlumber
+
+The PipeWire and WirePlumber daemons can be configured to be more verbose
+by editing **/etc/pipewire/environment**
+
+* Set `G_MESSAGES_DEBUG=all` to enable WirePlumber's debug output.
+* Set `PIPEWIRE_DEBUG=n` (n=1-5) to enable PipeWire's debug output.
+
+All messages will be available in the systemd journal, inspectable with
+journalctl.
+
+`PIPEWIRE_DEBUG` can be set to a value between 1 and 5, with 5 being the
+most verbose and 1 the least verbose.
+
+### AGL applications & services (AppFW)
+
+For AGL applications and services that are installed by the app framework,
+you can set the *PIPEWIRE_DEBUG* environment variable in **/etc/afm/unit.env.d/pipewire**.
+This will enable the debug messages that are printed by *libpipewire* and will
+make them available also in the systemd journal.
diff --git a/docs/4_APIs_and_Services/4.6_Audio_Framework/4.6.2_Session_Manager_Configuration.md b/docs/4_APIs_and_Services/4.6_Audio_Framework/4.6.2_Session_Manager_Configuration.md
new file mode 100644
index 0000000..e53a449
--- /dev/null
+++ b/docs/4_APIs_and_Services/4.6_Audio_Framework/4.6.2_Session_Manager_Configuration.md
@@ -0,0 +1,450 @@
+---
+edit_link: ''
+title: Session Manager Configuration
+origin_url: >-
+ https://raw.githubusercontent.com/automotive-grade-linux/docs-sources/master/docs/audio/wireplumber_configuration.md
+---
+
+<!-- WARNING: This file is generated by fetch_docs.js using /home/boron/Documents/AGL/docs-webtemplate/site/_data/tocs/apis_services/master/audio-developer-guides-audio-book.yml -->
+
+# WirePlumber Configuration
+
+WirePlumber is a heavily modular daemon. By itself, it doesn't do anything
+except load the configured modules. All the rest of the logic is implemented
+inside those modules.
+
+Modular design ensures that it is possible to swap the implementation of
+specific functionality without having to re-implement the rest of it, allowing
+flexibility on target-sensitive parts, such as policy management and
+making use of non-standard hardware.
+
+## `wireplumber.conf`
+
+This is WirePlumber's main configuration file. It is read at startup, before
+connecting to the PipeWire daemon. Its purpose is to list all the modules
+that need to be loaded by WirePlumber.
+
+The format of this file is custom and resembles a script with commands:
+
+```
+# comment
+command parameter1 parameter2 ...
+```
+
+Lines are executed in the order they appear and each of them executes an
+action defined by the command. Lines starting with `#` are treated as comments
+and ignored. Possible commands are:
+
+* `add-spa-lib`
+
+ Associates SPA plugin names with the names of the SPA modules that they
+ can be loaded from. This takes 2 parameters: a name pattern and a library name.
+
+ This actually does not load the SPA plugin, it only calls `pw_core_add_spa_lib`
+ with the 2 paramteres given as arguments. As a consequence, it is safe to
+ call this even if the SPA module is not actually installed on the system.
+
+ Example:
+ ```
+ add-spa-lib api.alsa.* alsa/libspa-alsa
+ ```
+
+ In this example, we let `libpipewire` know that any SPA plugin whose name
+ starts with `api.alsa.` can be loaded from the SPA module
+ `alsa/libspa-alsa.so` (relative to the standard SPA modules directory).
+
+* `load-pipewire-module`
+
+ Loads a `libpipewire` module. This is similar to the `load-module` commands
+ that would appear on `pipewire.conf`, the configuration file of the PipeWire
+ daemon.
+
+ This takes at least 1 parameter, the module name, and optionally any module
+ arguments, in the format that they would be given in `pipewire.conf`
+
+ Format:
+ ```
+ load-pipewire-module module-name some-argument some-property=value
+ ```
+ Example:
+ ```
+ load-pipewire-module libpipewire-module-client-device
+ ```
+
+ This command does not affect the PipeWire daemon by any means. It exists
+ simply to allow loading `libpipewire` modules in the pipewire core that
+ runs inside WirePlumber. This is usually useful to load pipewire protocol
+ extensions, so that you can export custom objects to PipeWire and other
+ clients.
+
+* `load-module`
+
+ Loads a WirePlumber module. This takes 2 arguments and an optional parameter
+ block.
+
+ Format:
+ ```
+ load-module ABI module-name {
+ "parameter": <"value">
+ }
+ ```
+
+ The `ABI` parameter specifies the binary interface that WirePlumber shall use
+ to load this module. Currently, the only supported ABI is `C`. It exists to
+ allow future expansion, writing modules in other languages.
+
+ The `module-name` should be the name of the `.so` file without the `.so`
+ extension.
+
+ Optionally, if the `load-module` line ends with a `{`, the next lines up to
+ and including the next matching `}` are treated as a parameter block.
+ This block essentially is a
+ [GVariant](https://developer.gnome.org/glib/stable/glib-GVariant.html)
+ of type
+ [`a{sv}`](https://developer.gnome.org/glib/stable/gvariant-format-strings.html)
+ in the
+ [GVariant Text Format](https://developer.gnome.org/glib/stable/gvariant-text.html).
+ As a rule of thumb, parameter names in this block must always be strings
+ enclosed in double quotes, the separation between names and values is done
+ with the `:` character and values, regardless of their inner type, must always
+ be enclosed in `<` `>`.
+
+ Note that starting the parameter block on the next line is an error. The
+ starting brace (`{`) must always be on the `load-module` line.
+
+ Example:
+ ```
+ load-module C libwireplumber-module-monitor {
+ "factory": <"api.alsa.enum.udev">,
+ "flags": <["use-adapter", "activate-devices"]>
+ }
+ ```
+
+ Parameters are module-dependent. They are passed as a GVariant in the
+ module's initialization function and it is up to the module to interpret
+ their meaning. WirePlumber does not have any reserved parameters.
+
+## Location of configuration files
+
+WirePlumber's default location of its configuration files is determined at
+compile time by the build system. Typically, it ends up being `/etc/wireplumber`.
+
+In more detail, this is controlled by the `--sysconfdir` meson option. When
+this is set to an absolute path, such as `/etc`, the location of the
+configuration files is set to be `$sysconfdir/wireplumber`. When this is set
+to a relative path, such as `etc`, then the installation prefix (`--prefix`)
+is prepended to the path: `$prefix/$sysconfdir/wireplumber`
+
+WirePlumber expects its `wireplumber.conf` to reside in that directory.
+It is possible to override that at runtime by setting the
+`WIREPLUMBER_CONFIG_FILE` environment variable:
+
+```
+WIREPLUMBER_CONFIG_FILE=src/config/wireplumber.conf wireplumber
+```
+
+It is also possible to override the whole configuration directory, so that
+all other configuration files are being read from a different location as well,
+by setting the `WIREPLUMBER_CONFIG_DIR` environment variable:
+```
+WIREPLUMBER_CONFIG_DIR=src/config wireplumber
+```
+
+## Location of modules
+
+### WirePlumber modules
+
+Like with configuration files, WirePlumber's default location of its modules is
+determined at compile time by the build system. Typically, it ends up being
+`/usr/lib/wireplumber-0.1` (or `/usr/lib/<arch-triplet>/wireplumber-0.1` on
+multiarch systems)
+
+In more detail, this is controlled by the `--libdir` meson option. When
+this is set to an absolute path, such as `/lib`, the location of the
+modules is set to be `$libdir/wireplumber-$abi_version`. When this is set
+to a relative path, such as `lib`, then the installation prefix (`--prefix`)
+is prepended to the path: `$prefix/$libdir/wireplumber-$abi_version`.
+
+It is possible to override this directory at runtime by setting the
+`WIREPLUMBER_MODULE_DIR` environment variable:
+```
+WIREPLUMBER_MODULE_DIR=build/modules wireplumber
+```
+
+### PipeWire and SPA modules
+
+PipeWire and SPA modules are not loaded from the same location as WirePlumber's
+modules. They are loaded from the location that PipeWire loads them.
+
+It is also possible to override these locations by using environment variables:
+`SPA_PLUGIN_DIR` and `PIPEWIRE_MODULE_DIR`. For more details, refer to
+PipeWire's documentation.
+
+# module-monitor
+
+This module internally loads a SPA "device" object which enumerates all the
+devices of a certain subsystem. Then it listens for "node" objects that are
+being created by this device and exports them to PipeWire, after adjusting
+their properties to provide enough context.
+
+`module-monitor` does not read any configuration files, however, it supports
+configuration through parameters defined in the main `wireplumber.conf`.
+Possible parameters are:
+
+* `factory`
+
+ A string that specifies the name of the SPA factory that loads the intial
+ "device" object.
+
+ Well-known factories are:
+
+ * "api.alsa.enum.udev" - Discovers ALSA devices via udev
+ * "api.v4l2.enum.udev" - Discovers V4L2 devices via udev
+ * "api.bluez5.enum.dbus" - Discovers bluetooth devices by calling bluez5 API via D-Bus
+
+ * `flags`
+
+ An array of strings that enable specific functionality in the monitor.
+ Possible flags include:
+
+ * "use-adapter"
+
+ Instructs the monitor to wrap all the created nodes in an "adapter"
+ SPA node, which provides automatic port splitting/merging and format/rate
+ conversion. This should be always enabled for audio device nodes.
+
+ * "local-nodes"
+
+ Instructs the monitor to run all the created nodes locally in in the
+ WirePlumber process, instead of the default behavior which is to create
+ the nodes in the PipeWire process. This is useful for bluetooth nodes,
+ which should run outside of the main PipeWire process for performance
+ reasons.
+
+ * "activate-devices"
+
+ Instructs the monitor to automatically set the device profile to "On",
+ so that the nodes are created. If not specified, the profile must be
+ set externally by the user before any nodes appear.
+
+# module-config-endpoint
+
+This module creates endpoints when WirePlumber detects new nodes in the
+pipewire graph. Nodes themselves can be created in two ways:
+Device modes are being created by "monitors" that watch a specific subsystem
+(udev, bluez, etc...) for devices. Client nodes are being created by client
+applications that try to stream to/from pipewire. As soon as a node is created,
+the `module-config-endpoint` iterates through all the `.endpoint` configuration
+files, in the order that is determined by the `match-node.priority` field,
+and tries to match the node to the node description in the `[match-node]` table.
+Upon a successful match, a new endpoint that follows the description in the
+`[endpoint]` table is created.
+
+## `*.endpoint` configuration files
+
+These files are TOML v0.5 files. At the top-level, they must contain exactly
+2 tables: `[match-node]` and `[endpoint]`
+
+The `[match-node]` table contains properties that match a pipewire node that
+exists on the graph. Possible fields of this table are:
+
+* `priority`
+
+ Specifies the order in which the `.endpoint` files are being searched for a
+ match with a node. If a node matches the description of more than one
+ `.endpoint` file, the one with the highest priority wins.
+
+ The type of this field is unsigned integer. Bigger numbers mean higher
+ priority.
+
+* `properties`
+
+ This is a TOML array of tables, where each table must contain two fields:
+ `name` and `value`, both being strings. Each table describes a match against
+ one of the pipewire properties of the node. For a successful node match, all
+ the described properties must match with the node.
+
+ The value of the `name` field must match exactly the name of the pipewire
+ property, while the value of the `value` field can contain '*' (wildcard)
+ and '?' (joker), adhering to the rules of the
+ [GLib g_pattern_match() function](https://developer.gnome.org/glib/stable/glib-Glob-style-pattern-matching.html).
+
+ When writing `.endpoint` files, a useful utility that you can use to list
+ device node properties is:
+
+ ```
+ $ wireplumber-cli device-node-props
+ ```
+
+ Another way to figure out some of these properties *for ALSA nodes* is
+ by parsing the aplay/arecord output. For example, this line from `aplay -l`
+ is interpreted as follows:
+
+ ```
+ card 0: PCH [HDA Intel PCH], device 2: ALC3246 [ALC3246 Analog]
+ ```
+
+ ```
+ { name = "api.alsa.path", value = "hw:0,2" },
+ { name = "api.alsa.card", value = "0" },
+ { name = "api.alsa.card.id", value = "PCH" },
+ { name = "api.alsa.card.name", value = "HDA Intel PCH" },
+ { name = "api.alsa.pcm.device", value = "2" },
+ { name = "api.alsa.pcm.id", value = "ALC3246" },
+ { name = "api.alsa.pcm.name", value = "ALC3246 Analog" },
+ ```
+
+The `[endpoint]` table contains a description of the endpoint to be created.
+Possible fields of this table are:
+
+* `type`
+
+ Required. Specifies the factory to be used for construction.
+ The only well-known factory at the moment of writing is: `pw-audio-softdsp-endpoint`
+
+* `direction`
+
+ Required. Can be set to either `"sink"` or `"source"`. Specifies the
+ direction of the media flow of this endpoint. A `source` is an endpoint that
+ produces data (i.e. an audio capture device or a playback application) and
+ a `sink` is an endpoint that consumes data (audio playback device or
+ capture application).
+
+* `name`
+
+ Optional. The name of the newly created endpoint. If not specified,
+ the endpoint is named after the node (from the `node.name` property of the node).
+
+* `media_class`
+
+ Optional. A string that specifies an override for the `media.class` property
+ of the node. It can be used in special circumstances to declare that an
+ endpoint is dealing with a different type of data. This is only useful in
+ combination with a policy implementation that is aware of this media class.
+
+* `priority`
+
+ Optional. An unsigned integer that specifies the order in which endpoints are
+ chosen to be the default of a specific device group. Possible device groups
+ are (determined by the endpoint's `media.class`):
+
+ * Audio/Sink
+ * Audio/Source
+ * Video/Source
+
+ Every time a new device endpoint is created, wireplumber picks the "default"
+ of the group that it belongs to, based on this priority number: the endpoint
+ with the biggest priority number wins.
+
+ If not specified, the default priority of an endpoint is equal to zero
+ (i.e. the lowest priority).
+
+* `streams`
+
+ Optional. Specifies the name of a `.streams` file that contains the
+ descriptions of the streams to create for this endpoint. This currently
+ specific to the implementation of the `pw-audio-softdsp-endpoint` and might
+ change in the future.
+
+## `*.streams` configuration files
+
+These files contain lists of streams with their names and priorities.
+They are TOML v0.5 files.
+
+Each `.streams` file must contain exactly one top-level array of tables,
+called `streams`. Every table must contain exactly two fields:
+`name` and `priority`.
+
+The `name` of each stream is used to create the streams on new endpoints.
+
+The `priority` of each stream is being interpreted by the policy module to
+apply restrictions on which app can use the stream at a given time.
+
+# module-config-policy
+
+This module implements demo-quality policy management that is partly driven
+by configuration files. The configuration files that this module reads are
+described below:
+
+## `*.endpoint-link`
+
+These files contain rules to link endpoints with each other.
+They are TOML v0.5 files.
+
+Endpoints are normally created by another module, such
+as `module-config-endpoint` which is described above.
+As soon as an endpoint is created, the `module-config-policy` uses the
+information gathered from the `.endpoint-link` files in order to create a
+link to another endpoint.
+
+`.endpoint-link` files can contain 3 top-level tables:
+* `[match-endpoint]`, required
+* `[target-endpoint]`, optional
+* `[endpoint-link]`, required
+
+The `[match-endpoint]` table contains properties that match an endpoint that
+exists on the graph. Possible fields of this table are:
+
+* `priority`
+
+ Specifies the order in which the `.endpoint-link` files are being searched
+ for a match with an endpoint. If an endpoint matches the description of more
+ than one `.endpoint-link` file, the one with the highest priority wins.
+
+ The type of this field is unsigned integer. Bigger numbers mean higher
+ priority.
+
+* `direction`
+
+ Required. Can be set to either `"sink"` or `"source"`. Specifies the
+ direction of the media flow of this endpoint. A `source` is an endpoint that
+ produces data (i.e. an audio capture device or a playback application) and
+ a `sink` is an endpoint that consumes data (audio playback device or
+ capture application).
+
+* `name`
+
+ Optional. The name of the endpoint. It is possible to use wildcards here to
+ match only parts of the name.
+
+* `media_class`
+
+ Optional. A string that specifies the `media.class` that the endpoint
+ must have in order to match.
+
+* `properties`
+
+ This is a TOML array of tables, where each table must contain two fields:
+ `name` and `value`, both being strings. Each table describes a match against
+ one of the pipewire properties of the endpoint. For a successful endpoint
+ match, all the described properties must match with the endpoint.
+
+The `[target-endpoint]` table contains properties that match an endpoint that
+exists on the graph. The purpose of this table is to match a second endpoint
+that the original matching endpoint from `[match-endpoint]` will be linked to.
+If not specified, `module-config-policy` will look for the session "default"
+endpoint for the type of media that the matching endpoint produces or consumes
+and will use that as a target. Possible fields of this table are:
+
+* `direction`, `name`, `media_class`, `properties`
+
+ All these fields are permitted and behave exactly as described above for the
+ `[match-endpoint]` table.
+
+* `stream`
+
+ This field specifies a stream name that the link will use on the target
+ endpoint. If it is not specified, the stream name is acquired from the
+ `media.role` property of the matching endpoint. If specified, the value of
+ this field overrides the `media.role`.
+
+The `[endpoint-link]` table specifies properties of the link. Possible fields
+of this table are:
+
+* `keep`
+
+ A boolean field. If set to true, the link is always kept active and ignores
+ policy rules regarding corking or stream priority. This link will also not
+ affect the rules for other links. For example, if a keep=true link is
+ activating a high priority stream, lower priority streams can still work on
+ the same target endpoint for links with keep=false.
diff --git a/docs/4_APIs_and_Services/4.6_Audio_Framework/4.6.3_Bluetooth.md b/docs/4_APIs_and_Services/4.6_Audio_Framework/4.6.3_Bluetooth.md
new file mode 100644
index 0000000..668b2f3
--- /dev/null
+++ b/docs/4_APIs_and_Services/4.6_Audio_Framework/4.6.3_Bluetooth.md
@@ -0,0 +1,122 @@
+---
+edit_link: ''
+title: Bluetooth
+origin_url: >-
+ https://raw.githubusercontent.com/automotive-grade-linux/docs-sources/master/docs/audio/bluez-alsa.md
+---
+
+<!-- WARNING: This file is generated by fetch_docs.js using /home/boron/Documents/AGL/docs-webtemplate/site/_data/tocs/apis_services/master/audio-developer-guides-audio-book.yml -->
+
+# bluez-alsa
+
+## Introduction
+
+Bluetooth Audio ALSA Backend allow bluetooth audio without PulseAudio.
+
+This project is a rebirth of a direct integration between Bluez and ALSA. Since Bluez >= 5, the build-in integration has been removed in favor of 3rd party audio applications. From now on, Bluez acts as a middleware between an audio application, which implements Bluetooth audio profile, and a Bluetooth audio device.
+
+github source : [bluez-alsa](https://github.com/Arkq/bluez-alsa)
+
+## Add bluez-alsa to an AGL image
+
+You can add bluez-alsa to your image
+
+```yocto
+IMAGE_INSTALL_append = "bluez-alsa"
+```
+
+## Check bluez-alsa status
+
+You can check the bluez-alsa status by running:
+
+```bash
+systemctl status bluez-alsa.service
+```
+
+## Stop pulseaudio
+
+You must disable pulseaudio if you want to use bluez-alsa
+
+```bash
+systemctl --user stop pulseaudio
+```
+
+or disable pulseaudio bluetooth support
+
+```bash
+vi /etc/pulse/default.pa
+#.ifexists module-bluetooth-policy.so
+#load-module module-bluetooth-policy
+#.endif
+
+#.ifexists module-bluetooth-discover.so
+#load-module module-bluetooth-discover
+#.endif
+```
+
+## Connect your Bluetooth device
+
+You need to connect a bluetooth device
+
+```bash
+$ bluetoothctl
+[bluetooth]# pair ${BT_ADDR}
+[bluetooth]# connect ${BT_ADDR}
+[bluetooth]# info ${BT_ADDR}
+```
+
+Here somes documentation links:
+
+* [Bluetooth headset from archlinux](https://wiki.archlinux.org/index.php/Bluetooth_headset)
+* [Bluetooth Headset from gentoo](https://wiki.gentoo.org/wiki/Bluetooth_Headset)
+* [Bluez A2DP AudioSink for ALSA](http://www.lightofdawn.org/blog/?viewDetailed=00032)
+* [Bluez A2DP](http://www.lightofdawn.org/wiki/wiki.cgi/BluezA2DP)
+
+## Test bluez-alsa speacker
+
+```bash
+wget http://www.kozco.com/tech/piano2.wav
+
+aplay -D bluealsa:HCI=hci0,DEV=${BT_ADDR},PROFILE=a2dp ./piano2.wav
+```
+
+## Add bluez-alsa pcm config to alsa
+
+```bash
+vi /etc/asound.conf
+# Bluetooth headset
+pcm.btheadset {
+ type plug
+ slave.pcm {
+ type bluealsa
+ device "${BT_ADDR}"
+ profile "a2dp"
+ }
+ hint {
+ show on
+ description "Bluetooth Audio ALSA Backend"
+ }
+}
+```
+
+Doc [asoundrc](https://alsa.opensrc.org/Asoundrc)
+
+Test bluez-alsa pcm
+
+```bash
+aplay -D btheadset ./piano2.wav
+```
+
+## Test gstreamer player
+
+```bash
+gst-launch-1.0 uridecodebin uri=file:///mnt/Holy-Mountain.mp3 ! alsasink device=btheadset
+```
+
+## Test bluez-alsa phone
+
+After connected your phone with bluez:
+
+```bash
+bluealsa-aplay ${BT_ADDR}
+```